Giter Club home page Giter Club logo

flora's Introduction

ARCHIVED

This repository has been archived due to lack of time to properly maintain the code.

flora

This arduino sketch implements an ESP32 BLE client for XIaomi Mi Flora Plant sensors, pushing the meaasurements to an MQTT server.

Technical requirements

Hardware:

  • ESP32
  • Xiaomi Mi Plant Sensor (firmware revision >= 2.6.6)

Software:

  • MQTT server

Setup instructions

  1. Copy config.h.example into config.h and update seetings according to your environment:
  • WLAN SSID and password
  • MQTT Server address
  • MAC address(es) of your Xiaomi Mi Plant sensor(s)
  1. Open ino sketch in Arduino, compile & upload.

Measuring interval

The ESP32 will perform a single connection attempt to the Xiaomi Mi Plant sensor, read the sensor data & push it to the MQTT server. The ESP32 will enter deep sleep mode after all sensors have been read and sleep for X minutes before repeating the exercise... Battery level is read every Xth wakeup. Up to X attempst per sensor are performed when reading the data fails.

Configuration

  • SLEEP_DURATION - how long should the device sleep between sensor reads?
  • EMERGENCY_HIBERNATE - how long after wakeup should the device forcefully go to sleep (e.g. when something gets stuck)?
  • BATTERY_INTERVAL - how ofter should the battery status be read?
  • RETRY - how ofter should a single device be tried on each run?

Constraints

Some "nice to have" features are not yet implemented or cannot be implemented:

  • OTA updates: I didn't manage to implement OTA update capabilities due to program size constraints: BLE and WLAN brings the sketch up to 90% of the size limit, so I decided to use the remaining 10% for something more useful than OTA...

Sketch size issues

The sketch does not fit into the default arduino parition size of around 1.3MB. You'll need to change your default parition table and increase maximum build size to at least 1.6MB. On Arduino IDE this can be achieved using "Tools -> Partition Scheme -> No OTA"

Credits

Many thanks go to the guys at https://github.com/open-homeautomation/miflora for figuring out the sensor protocol.

flora's People

Contributors

agvxov avatar lociii avatar sidddy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flora's Issues

keeps crashing

  • Connected to Flora
    abort() was called at PC 0x401a7813 on core 1

Backtrace: 0x40095324:0x3ffdab30 0x40095527:0x3ffdab50 0x401a7813:0x3ffdab70 0x401a785a:0x3ffdab90 0x4019513f:0x3ffdabb0 0x400d31b1:0x3ffdabd0 0x400d1627:0x3ffdac30 0x400d1d91:0x3ffdad00 0x401af3ca:0x3ffdad50

Rebooting...
ets Jun 8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:952
load:0x40078000,len:6084
load:0x40080000,len:7936
entry 0x40080310
Starting Flora client...
Connecting WiFi...
....
WiFi connected
Attempting MQTT connection...connected
Forming a connection to Flora device at xx:xx:xx:xx:xx:xx

  • Connected to Flora
    abort() was called at PC 0x401a7813 on core 1

Backtrace: 0x40095324:0x3ffdaaa0 0x40095527:0x3ffdaac0 0x401a7813:0x3ffdaae0 0x401a785a:0x3ffdab00 0x4019513f:0x3ffdab20 0x400d31b1:0x3ffdab40 0x400d1627:0x3ffdaba0 0x400d1d91:0x3ffdac70 0x401af3ca:0x3ffdacc0

Rebooting...
ets Jun 8 2016 00:22:57

Any plans to add retrieving the battery level?

I tried this, but I am new to BLE. You included in your code the characteristic BLEUUID uuid_version_battery("00001a02-0000-1000-8000-00805f9b34fb"); and I checked for this one but I am unsure what to do with the HEX Result.
Any help would be great.

Moisture spikes with ESP32

Hi!
I have uploaded the sketch on an esp32 board (wroom32), but i have strange spikes only for moisture. It often drop 7-8% down.
Miflora Firmware 3.1.9

2020-01-08 11_02_32-Window

Previously I've directly monitored with Rpi using BLE, but I'vent seen this kind of beahaviour.

Better label multiple devices

Hello, super sketch! I have already solved the problem with the wrong values. Since I read 12 sensors, a better naming in Mqtt would be an advantage.
I did that too, but now the battery only has strange drawings in MQTT.
Does anyone have a solution?

`/**
A BLE client for the Xiaomi Mi Plant Sensor, pushing measurements to an MQTT server.

See https://github.com/nkolban/esp32-snippets/blob/master/Documentation/BLE%20C%2B%2B%20Guide.pdf
on how bluetooth low energy and the library used are working.

See https://github.com/ChrisScheffler/miflora/wiki/The-Basics for details on how the
protocol is working.

MIT License

Copyright (c) 2017 Sven Henkel
Multiple units reading by Grega Lebar 2018

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#include "BLEDevice.h"
#include <WiFi.h>
#include <PubSubClient.h>

#include "config.h"

// boot count used to check if battery status should be read
RTC_DATA_ATTR int bootCount = 0;

char* deviceName;// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// device count
static int deviceCount = sizeof FLORA_DEVICES / sizeof FLORA_DEVICES[0];

// the remote service we wish to connect to
static BLEUUID serviceUUID("00001204-0000-1000-8000-00805f9b34fb");

// the characteristic of the remote service we are interested in
static BLEUUID uuid_version_battery("00001a02-0000-1000-8000-00805f9b34fb");
static BLEUUID uuid_sensor_data("00001a01-0000-1000-8000-00805f9b34fb");
static BLEUUID uuid_write_mode("00001a00-0000-1000-8000-00805f9b34fb");

TaskHandle_t hibernateTaskHandle = NULL;

WiFiClient espClient;
PubSubClient client(espClient);

void connectWifi() {
Serial.println("Connecting to WiFi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

Serial.println("");
Serial.println("WiFi connected");
Serial.println("");
}

void disconnectWifi() {
WiFi.disconnect(true);
Serial.println("WiFi disonnected");
}

void connectMqtt() {
Serial.println("Connecting to MQTT...");
client.setServer(MQTT_HOST, MQTT_PORT);

while (!client.connected()) {
if (!client.connect(MQTT_CLIENTID, MQTT_USERNAME, MQTT_PASSWORD)) {
Serial.print("MQTT connection failed:");
Serial.print(client.state());
Serial.println("Retrying...");
delay(MQTT_RETRY_WAIT);
}
}

Serial.println("MQTT connected");
Serial.println("");
}

void disconnectMqtt() {
client.disconnect();
Serial.println("MQTT disconnected");
}

BLEClient* getFloraClient(BLEAddress floraAddress) {
BLEClient* floraClient = BLEDevice::createClient();

if (!floraClient->connect(floraAddress)) {
Serial.println("- Connection failed, skipping");
return nullptr;
}

Serial.println("- Connection successful");
return floraClient;
}

BLERemoteService* getFloraService(BLEClient* floraClient) {
BLERemoteService* floraService = nullptr;

try {
floraService = floraClient->getService(serviceUUID);
}
catch (...) {
// something went wrong
}
if (floraService == nullptr) {
Serial.println("- Failed to find data service");
}
else {
Serial.println("- Found data service");
}

return floraService;
}

bool forceFloraServiceDataMode(BLERemoteService* floraService) {
BLERemoteCharacteristic* floraCharacteristic;

// get device mode characteristic, needs to be changed to read data
Serial.println("- Force device in data mode");
floraCharacteristic = nullptr;
try {
floraCharacteristic = floraService->getCharacteristic(uuid_write_mode);
}
catch (...) {
// something went wrong
}
if (floraCharacteristic == nullptr) {
Serial.println("-- Failed, skipping device");
return false;
}

// write the magic data
uint8_t buf[2] = {0xA0, 0x1F};
floraCharacteristic->writeValue(buf, 2, true);

delay(500);
return true;
}

bool readFloraDataCharacteristic(BLERemoteService* floraService, String baseTopic) {
BLERemoteCharacteristic* floraCharacteristic = nullptr;

// get the main device data characteristic
Serial.println("- Access characteristic from device");
try {
floraCharacteristic = floraService->getCharacteristic(uuid_sensor_data);
}
catch (...) {
// something went wrong
}
if (floraCharacteristic == nullptr) {
Serial.println("-- Failed, skipping device");
return false;
}

// read characteristic value
Serial.println("- Read value from characteristic");
std::string value;
try{
value = floraCharacteristic->readValue();
}
catch (...) {
// something went wrong
Serial.println("-- Failed, skipping device");
return false;
}
const char *val = value.c_str();

Serial.print("Hex: ");
for (int i = 0; i < 16; i++) {
Serial.print((int)val[i], HEX);
Serial.print(" ");
}
Serial.println(" ");

int16_t* temp_raw = (int16_t*)val;
float temperature = (*temp_raw) / ((float)10.0);
Serial.print("-- Temperature: ");
Serial.println(temperature);

int moisture = val[7];
Serial.print("-- Moisture: ");
Serial.println(moisture);

int light = val[3] + val[4] * 256;
Serial.print("-- Light: ");
Serial.println(light);

int conductivity = val[8] + val[9] * 256;
Serial.print("-- Conductivity: ");
Serial.println(conductivity);

if (temperature > 200 || temperature < -30 || conductivity > 2000) { //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Serial.println("-- Unreasonable values received, skip publish");
return false;
}

char buffer[64];

snprintf(buffer, 64, "%f", temperature);
client.publish((baseTopic + "temperature").c_str(), buffer);
snprintf(buffer, 64, "%d", moisture);
client.publish((baseTopic + "moisture").c_str(), buffer);
snprintf(buffer, 64, "%d", light);
client.publish((baseTopic + "light").c_str(), buffer);
snprintf(buffer, 64, "%d", conductivity);
client.publish((baseTopic + "conductivity").c_str(), buffer);

return true;
}

bool readFloraBatteryCharacteristic(BLERemoteService* floraService, String baseTopic) {
BLERemoteCharacteristic* floraCharacteristic = nullptr;

// get the device battery characteristic
Serial.println("- Access battery characteristic from device");
try {
floraCharacteristic = floraService->getCharacteristic(uuid_version_battery);
}
catch (...) {
// something went wrong
}
if (floraCharacteristic == nullptr) {
Serial.println("-- Failed, skipping battery level");
return false;
}

// read characteristic value
Serial.println("- Read value from characteristic");
std::string value;
try{
value = floraCharacteristic->readValue();
}
catch (...) {
// something went wrong
Serial.println("-- Failed, skipping battery level");
return false;
}
const char *val2 = value.c_str();
int battery = val2[0];

char buffer[64];

Serial.print("-- Battery: ");
Serial.println(battery);
if (battery = 0 ) { //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Serial.println("-- Unreasonable battery values received, skip publish");
return false;

snprintf(buffer, 64, "%d", battery);
Serial.println(buffer);
}

Serial.println("-- Batteriewert ist:");

client.publish((baseTopic + "battery").c_str(), buffer);
return true;
}
//###############################################################################################################################################

bool processFloraService(BLERemoteService* floraService, char* deviceMacAddress, bool readBattery, char* deviceName) {
// set device in data mode

if (!forceFloraServiceDataMode(floraService)) {
return false;
}
// #################################################################################################################################################################
// String baseTopic = MQTT_BASE_TOPIC + "/" + deviceMacAddress + "/";

  String baseTopic = MQTT_BASE_TOPIC + "/" + deviceMacAddress +  "/" + deviceName + "/";

bool dataSuccess = readFloraDataCharacteristic(floraService, baseTopic);

bool batterySuccess = true;
if (readBattery) {
batterySuccess = readFloraBatteryCharacteristic(floraService, baseTopic);
}

return dataSuccess && batterySuccess;
}

bool processFloraDevice(BLEAddress floraAddress, char* deviceMacAddress, bool getBattery, int tryCount, char* deviceName) {
Serial.print("Processing Flora device at " );
Serial.print (deviceName);
Serial.print(floraAddress.toString().c_str());
Serial.print(" (try ");
Serial.print(tryCount);
Serial.println(")");

// connect to flora ble server
BLEClient* floraClient = getFloraClient(floraAddress);
if (floraClient == nullptr) {
return false;
}

// connect data service
BLERemoteService* floraService = getFloraService(floraClient);
if (floraService == nullptr) {
floraClient->disconnect();
return false;
}

// process devices data
//***********************************************************************************************************************************************************************************
bool success = processFloraService(floraService, deviceMacAddress, getBattery, deviceName );
// bool success = processFloraService(floraService, deviceMacAddress, getBattery);
// disconnect from device
floraClient->disconnect();

return success;
}

void hibernate() {
esp_sleep_enable_timer_wakeup(SLEEP_DURATION * 1000000ll);
Serial.println("Going to sleep now.");
delay(100);
esp_deep_sleep_start();
}

void delayedHibernate(void parameter) {
delay(EMERGENCY_HIBERNATE
1000); // delay for five minutes
Serial.println("Something got stuck, entering emergency hibernate...");
hibernate();
}

void setup() {
// all action is done when device is woken up
Serial.begin(115200);
delay(1000);

// increase boot count
bootCount++;

// create a hibernate task in case something gets stuck
xTaskCreate(delayedHibernate, "hibernate", 4096, NULL, 1, &hibernateTaskHandle);

Serial.println("Initialize BLE client...");
BLEDevice::init("");
BLEDevice::setPower(ESP_PWR_LVL_P7);

// connecting wifi and mqtt server
connectWifi();
connectMqtt();

// check if battery status should be read - based on boot count
bool readBattery = ((bootCount % BATTERY_INTERVAL) == 0);

// process devices
for (int i=0; i<deviceCount; i++) {
int tryCount = 0;
//********************************************************************************************************************************************************************
char* deviceMacAddress = FLORA_DEVICES[i];
char* deviceName = FLORA_DEVICES_NAME[i];
//************************************************************************************************************************************************************************
BLEAddress floraAddress(deviceMacAddress);

while (tryCount < RETRY) {
  tryCount++;
  if (processFloraDevice(floraAddress, deviceMacAddress, readBattery, tryCount, deviceName)) {
    break;
  }
  delay(1000);
}
delay(1500); // (vorher 1500)

}
//delay(8500);//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// disconnect wifi and mqtt (original war zuerst WIFI, dann MQTT)

disconnectMqtt();
delay(1500); // (vorher 0)

disconnectWifi();
delay(1500);

// delete emergency hibernate task
vTaskDelete(hibernateTaskHandle);

// go to sleep now
hibernate();
}

void loop() {
/// we're not doing anything in the loop, only on device wakeup
delay(10000);
}`

and her the configuration:

`
// array of different xiaomi flora MAC addresses
char* FLORA_DEVICES[] = {"C4:7C:8D:66:CA:C2","c4:7c:8d:66:b1:fe"}; // FLORA_DEVICES_Adresses

char* FLORA_DEVICES_NAME[] = {"FLORA_0","FLORA_1"}; // FLORA_DEVICES_Names
//char* deviceName;// //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// sleep between to runs in seconds
#define SLEEP_DURATION 20
// emergency hibernate countdown in seconds
#define EMERGENCY_HIBERNATE 60
// how often should the battery be read - in run count
#define BATTERY_INTERVAL 6
// how often should a device be retried in a run when something fails
#define RETRY 5

const char* WIFI_SSID = "xxxxxxxxxxxxxxxxxxxxxxxxx";
const char* WIFI_PASSWORD = "xxxxxxxxxxxxxxxxxxx";

// MQTT topic gets defined by "<MQTT_BASE_TOPIC>/<MAC_ADDRESS>/"
// where MAC_ADDRESS is one of the values from FLORA_DEVICES array
// property is either temperature, moisture, conductivity, light or battery

const char* MQTT_HOST = "192.168.178.85";
const int MQTT_PORT = 1883;
const char* MQTT_CLIENTID = "miflora";
const char* MQTT_USERNAME = "xxxxxxxxxxxxxxx";
const char* MQTT_PASSWORD = "xxxxxxxxxxxxxx";
const String MQTT_BASE_TOPIC = "flora";
const int MQTT_RETRY_WAIT = 5000;

`

App stalled when failing to connect to flora ble device

Hello,

This may relate to #9 .
As BLEClient::connect is a blocking call, "floraClient->connect(floraAddress)" never returns if the device can't be reached.
The application therefore goes in hibernate but doesn't operate.

To workaround this, one could scan the network when initializing the bluetooth and then ignore the devices that could not be found at scan time. What do you think ?

esp goes to hibernating if sensor is not rechable?

i recognizes some other topic.
if a sensor is not reachable by 2 attempts the program goes to hibernate. Even if there are other sensors in the list to be read.
excample:
sensor 1 reachable,
sensor 2 not rechable,
sensor 3 skipped.

This should be changed into a check if there are more sensors in the list and read them as well.
What do you think?

Regards,
Gernot

get stuck if device can not be found / no retry is used

If one of my sensors is not responding the complete process gets stuck, seems BLE Client has no valid working timeout for a connection, did anyone else faced this issue or can retest this while removing one client from your setup ?

Thank you very much :)

Sketch works but no data to MQTT

Hello. First time using esp32 but think I got it working.

Downloaded your folder, opened config.h.example and added my mac address, ip address of MQTT (synology nas package) and wifi id and password.

Saved this file in the folder as config.h
loaded this and flora.ino into arduino, checked and uploaded it to esp32.

Pressing the reload button and watching the serial monitor I see it connecting to flora mac address, force device in data mode, access characteristic from device, read them and display them
It then says:
wifi disconnected
mqtt disconnected
going to sleep now

Seems successful but I am subscriped to topic flora on mqtt and get no updated information?

I notice your code has username and password fields, I have no username or password for my MQTT (not even seen a way to set one in synology) so wondering if this is the problem.

I get no errors, but I get no data arriving at MQTT. Not really sure what to do now. Running an mqtt client on mac and iphone I can publish topics and see them so the mqtt broker is working.

Only other thing to note, quite often (almost every time) the first time I run the code on the esp32 if "works" but all the data is blank, the next time I press reload on the esp32 I get data.

Sorry for the long thread, wondering if you can help.

ps, I am using a Vegtrug sensor which is made by Xaiomi and works on Xaiomi app but thought I would mention this.

MQTT server received no message

I use an esp32 to communicate with the host of HomeAssistant. I can receive the message from another esp8266, but not from this esp32. It seems everything is correct, but I can't figure out why. I'm pretty sure the info of my MQTT server is filled in correctly. Could you please help me with this? Thank you very much!

Below is the message from serial monitor:

`Initialize BLE client...
Connecting to WiFi...
...
WiFi connected

Connecting to MQTT...
MQTT connected

Processing Flora device at c4:7c:8d:62:37:e9 (try 1)

  • Connection successful

  • Found data service

  • Force device in data mode

  • Access characteristic from device

  • Read value from characteristic
    Hex: EC 0 0 D9 0 0 0 2E 3E 2 0 0 0 0 0 0
    -- Temperature: 23.60
    -- Moisture: 46
    -- Light: 217
    -- Conductivity: 574
    WiFi disonnected
    MQTT disconnected
    Going to sleep now.`

Cannot handle more than 7 devices

Everything works great except number of devices to proceed.
I have 9 mi flora sensors, first 7 are handled ok and then no data is received from any left (and rotated), sometimes sketch hangs until emergency hibernate, than after wakeup - works fine again but again with only 7 sensors...

SW_RESET and SPI_FAST_FLASH_BOOT

I'm trying to make this work with an ESP32 (wroom), but something is not OK.
I can compile the sketch, as well I can upload it, but the board keeps resetting itself.
Serial output looks like this:

configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1496
load:0x40078000,len:8596
load:0x40080400,len:6980
entry 0x400806f4
ets Jun  8 2016 00:22:57

Adding multiple plant sensors

Hey. I found your awesome project and was wondering how to add multiple plant sensors u were referring in the readme ..

Do you have an example?

MQTT gives socket error

Im having this error in my mosquitto broker on home assistant

1543960126: New client connected from 192.168.1.61 as xiaomiflora-client (c1, k15, u'peke').
1543960148: Client xiaomiflora-client has exceeded timeout, disconnecting.
1543960148: Socket error on client xiaomiflora-client, disconnecting.

My config:
// sleep between to runs in seconds
#define SLEEP_DURATION 60 * 60
// emergency hibernate countdown in seconds
#define EMERGENCY_HIBERNATE 1 * 60
// how often should the battery be read - in run count
#define BATTERY_INTERVAL 2
// how often should a device be retried in a run when something fails
#define RETRY 5

and for mqtt:
const int MQTT_RETRY_WAIT = 5000;

Can someone point me in the right direction

platformio support

Hi, would you be open to consider platformio support?

Platformio is a build system like the Arduino IDE, except it runs from the command line, downloads the tool chain, libraries, tools, etc for you and compiles the code. Settings like which hardware you use, which libraries is contained in a single platformio.ini file.

If you want, I can add this for you.

Domoticz idx

Hi
Can I ask for instructions on how to add idx for domoticz to read values.
Thank you in advance

Sensor have no value in HA after restart (no retain)

Thank you very much for this piece of software, this is awesome!
Just to understand, if it is possible to send the MQTT with the retian flag so after a Home Assistant restart, it'll show the last value instead of waiting half an hour in order to retrieve the new one. Is that possible?

Thank you

No Sleep / Restart. Need Live Data

Hello is that possible to disable the restart of Wifi / MQT,??? I need the Live Data from the Flower Sensor, because i shower my Flowers with a Pump. If there Arrived Moisseture then will be off. I Can set the Time from restart down, but its not ok for my logs, to many restart to MQT and Wifi Router.
My Question is, is that possible to restart only the Bluetooth modul ? or any else.

'BLEClient' does not name a type

"C:\Users\XXX\AppData\Local\Temp\arduino_build_558469\sketch\config.h.cpp.o"
weatherbot:71:1: error: 'BLEClient' does not name a type

BLEClient* getFloraClient(BLEAddress floraAddress) {

^

weatherbot:83:1: error: 'BLERemoteService' does not name a type

BLERemoteService* getFloraService(BLEClient* floraClient) {

^

weatherbot:102:32: error: 'BLERemoteService' was not declared in this scope

bool forceFloraServiceDataMode(BLERemoteService* floraService) {

                            ^

weatherbot:102:50: error: 'floraService' was not declared in this scope

bool forceFloraServiceDataMode(BLERemoteService* floraService) {

                                              ^

weatherbot:127:34: error: 'BLERemoteService' was not declared in this scope

bool readFloraDataCharacteristic(BLERemoteService* floraService, String baseTopic) {

                              ^

weatherbot:127:52: error: 'floraService' was not declared in this scope

bool readFloraDataCharacteristic(BLERemoteService* floraService, String baseTopic) {

                                                ^

weatherbot:127:73: error: expected primary-expression before 'baseTopic'

bool readFloraDataCharacteristic(BLERemoteService* floraService, String baseTopic) {

                                                                     ^

weatherbot:127:82: error: expression list treated as compound expression in initializer [-fpermissive]

bool readFloraDataCharacteristic(BLERemoteService* floraService, String baseTopic) {

                                                                              ^

weatherbot:211:37: error: 'BLERemoteService' was not declared in this scope

bool readFloraBatteryCharacteristic(BLERemoteService* floraService, String baseTopic) {

                                 ^

weatherbot:211:55: error: 'floraService' was not declared in this scope

bool readFloraBatteryCharacteristic(BLERemoteService* floraService, String baseTopic) {

                                                   ^

weatherbot:211:76: error: expected primary-expression before 'baseTopic'

bool readFloraBatteryCharacteristic(BLERemoteService* floraService, String baseTopic) {

                                                                        ^

weatherbot:211:85: error: expression list treated as compound expression in initializer [-fpermissive]

bool readFloraBatteryCharacteristic(BLERemoteService* floraService, String baseTopic) {

                                                                                 ^

weatherbot:251:26: error: 'BLERemoteService' was not declared in this scope

bool processFloraService(BLERemoteService* floraService, char* deviceMacAddress, bool readBattery) {

                      ^

weatherbot:251:44: error: 'floraService' was not declared in this scope

bool processFloraService(BLERemoteService* floraService, char* deviceMacAddress, bool readBattery) {

                                        ^

weatherbot:251:58: error: expected primary-expression before 'char'

bool processFloraService(BLERemoteService* floraService, char* deviceMacAddress, bool readBattery) {

                                                      ^

weatherbot:251:82: error: expected primary-expression before 'bool'

bool processFloraService(BLERemoteService* floraService, char* deviceMacAddress, bool readBattery) {

                                                                              ^

weatherbot:251:98: error: expression list treated as compound expression in initializer [-fpermissive]

bool processFloraService(BLERemoteService* floraService, char* deviceMacAddress, bool readBattery) {

                                                                                              ^

weatherbot:268:25: error: 'BLEAddress' was not declared in this scope

bool processFloraDevice(BLEAddress floraAddress, char* deviceMacAddress, bool getBattery, int tryCount) {

                     ^

weatherbot:268:50: error: expected primary-expression before 'char'

bool processFloraDevice(BLEAddress floraAddress, char* deviceMacAddress, bool getBattery, int tryCount) {

                                              ^

weatherbot:268:74: error: expected primary-expression before 'bool'

bool processFloraDevice(BLEAddress floraAddress, char* deviceMacAddress, bool getBattery, int tryCount) {

                                                                      ^

weatherbot:268:91: error: expected primary-expression before 'int'

bool processFloraDevice(BLEAddress floraAddress, char* deviceMacAddress, bool getBattery, int tryCount) {

                                                                                       ^

weatherbot:268:103: error: expression list treated as compound expression in initializer [-fpermissive]

bool processFloraDevice(BLEAddress floraAddress, char* deviceMacAddress, bool getBattery, int tryCount) {

                                                                                                   ^

C:\Users\XXX\Desktop\Weatherbot\config.h:11:1: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

};

^

C:\Users\XXX\Desktop\Weatherbot\config.h:11:1: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]

C:\Users\XXX\Desktop\Weatherbot\weatherbot.ino: In function 'bool forceFloraServiceDataMode(BLERemoteService*)':

weatherbot:102:62: error: 'bool forceFloraServiceDataMode(BLERemoteService*)' redeclared as different kind of symbol

bool forceFloraServiceDataMode(BLERemoteService* floraService) {

                                                          ^

C:\Users\XXX\Desktop\Weatherbot\weatherbot.ino:102:6: note: previous declaration 'bool forceFloraServiceDataMode'

bool forceFloraServiceDataMode(BLERemoteService* floraService) {

  ^

C:\Users\XXX\Desktop\Weatherbot\weatherbot.ino: In function 'bool readFloraDataCharacteristic(BLERemoteService*, String)':

weatherbot:127:82: error: 'bool readFloraDataCharacteristic(BLERemoteService*, String)' redeclared as different kind of symbol

bool readFloraDataCharacteristic(BLERemoteService* floraService, String baseTopic) {

                                                                              ^

C:\Users\XXX\Desktop\Weatherbot\weatherbot.ino:127:6: note: previous declaration 'bool readFloraDataCharacteristic'

bool readFloraDataCharacteristic(BLERemoteService* floraService, String baseTopic) {

  ^

C:\Users\XXX\Desktop\Weatherbot\weatherbot.ino: In function 'bool readFloraBatteryCharacteristic(BLERemoteService*, String)':

weatherbot:211:85: error: 'bool readFloraBatteryCharacteristic(BLERemoteService*, String)' redeclared as different kind of symbol

bool readFloraBatteryCharacteristic(BLERemoteService* floraService, String baseTopic) {

                                                                                 ^

C:\Users\XXX\Desktop\Weatherbot\weatherbot.ino:211:6: note: previous declaration 'bool readFloraBatteryCharacteristic'

bool readFloraBatteryCharacteristic(BLERemoteService* floraService, String baseTopic) {

  ^

C:\Users\XXX\Desktop\Weatherbot\weatherbot.ino: In function 'bool processFloraService(BLERemoteService*, char*, bool)':

weatherbot:251:98: error: 'bool processFloraService(BLERemoteService*, char*, bool)' redeclared as different kind of symbol

bool processFloraService(BLERemoteService* floraService, char* deviceMacAddress, bool readBattery) {

                                                                                              ^

C:\Users\XXX\Desktop\Weatherbot\weatherbot.ino:251:6: note: previous declaration 'bool processFloraService'

bool processFloraService(BLERemoteService* floraService, char* deviceMacAddress, bool readBattery) {

  ^

weatherbot:253:46: error: 'forceFloraServiceDataMode' cannot be used as a function

if (!forceFloraServiceDataMode(floraService)) {

                                          ^

weatherbot:258:73: error: 'readFloraDataCharacteristic' cannot be used as a function

bool dataSuccess = readFloraDataCharacteristic(floraService, baseTopic);

                                                                     ^

weatherbot:262:76: error: 'readFloraBatteryCharacteristic' cannot be used as a function

 batterySuccess = readFloraBatteryCharacteristic(floraService, baseTopic);

                                                                        ^

C:\Users\XXX\Desktop\Weatherbot\weatherbot.ino: In function 'bool processFloraDevice(BLEAddress, char*, bool, int)':

weatherbot:268:103: error: 'bool processFloraDevice(BLEAddress, char*, bool, int)' redeclared as different kind of symbol

bool processFloraDevice(BLEAddress floraAddress, char* deviceMacAddress, bool getBattery, int tryCount) {

                                                                                                   ^

C:\Users\XXX\Desktop\Weatherbot\weatherbot.ino:268:6: note: previous declaration 'bool processFloraDevice'

bool processFloraDevice(BLEAddress floraAddress, char* deviceMacAddress, bool getBattery, int tryCount) {

  ^

weatherbot:289:80: error: 'processFloraService' cannot be used as a function

bool success = processFloraService(floraService, deviceMacAddress, getBattery);

                                                                            ^

C:\Users\XXX\Desktop\Weatherbot\weatherbot.ino: In function 'void setup()':

weatherbot:343:83: error: 'processFloraDevice' cannot be used as a function

   if (processFloraDevice(floraAddress, deviceMacAddress, readBattery, tryCount)) {

                                                                               ^

Mehrere Bibliotheken wurden für "BLEDevice.h" gefunden
Benutzt: C:\Users\XXX\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.3-rc1\libraries\BLE
Nicht benutzt: C:\Users\XXX\Documents\Arduino\libraries\ESP32_BLE_Arduino
Mehrere Bibliotheken wurden für "WiFi.h" gefunden
Benutzt: C:\Users\XXX\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.3-rc1\libraries\WiFi
Nicht benutzt: C:\Program Files (x86)\Arduino\libraries\WiFi
Bibliothek BLE in Version 1.0.1 im Ordner: C:\Users\XXX\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.3-rc1\libraries\BLE wird verwendet
Bibliothek WiFi in Version 1.0 im Ordner: C:\Users\XXX\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.3-rc1\libraries\WiFi wird verwendet
Bibliothek PubSubClient in Version 2.7 im Ordner: C:\Users\XXX\Documents\Arduino\libraries\PubSubClient wird verwendet
exit status 1
'BLEClient' does not name a type

Maybe someone have same issue. First build worked the other not anymore.

Support for Xiaomi Mijia Bluetooth Temperature Humidity Sensor LCD Screen Digital Thermometer Hygrometer

Hi,

great work for the flora client!

Would you be interessted to implement or write a separate version for the Xiaomi Mijia Bluetooth Temperature Humidity Sensor LCD Screen Digital Thermometer Hygrometer?
(https://www.banggood.com/de/Xiaomi-Mijia-Bluetooth-Thermometer-Hygrometer-with-LCD-Screen-Magnetic-Suction-Wall-Stickers-p-1232396.html)

I have a few of them. Here are some relevant information.

$ gatttool -b $mac --primary

attr handle = 0x0001, end grp handle = 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle = 0x0008, end grp handle = 0x000b uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle = 0x000c, end grp handle = 0x0015 uuid: 226c0000-6476-4566-7562-66734470666d (service for sensor_data)
attr handle = 0x0016, end grp handle = 0x0019 uuid: 0000180f-0000-1000-8000-00805f9b34fb (service for battery_data)
attr handle = 0x001a, end grp handle = 0x0024 uuid: 0000180a-0000-1000-8000-00805f9b34fb
attr handle = 0x0025, end grp handle = 0x002c uuid: 00001530-1212-efde-1523-785feabcd123
attr handle = 0x002d, end grp handle = 0xffff uuid: 0000fe95-0000-1000-8000-00805f9b34fb

$ gatttool -b $mac --characteristics

handle: 0x0002, char properties: 0x0a, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, char properties: 0x02, char value handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb
handle: 0x0009, char properties: 0x20, char value handle: 0x000a, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x000d, char properties: 0x10, char value handle: 0x000e, uuid: 226caa55-6476-4566-7562-66734470666d  (sensor_data)
handle: 0x0012, char properties: 0x18, char value handle: 0x0013, uuid: 226cbb55-6476-4566-7562-66734470666d
handle: 0x0017, char properties: 0x12, char value handle: 0x0018, uuid: 00002a19-0000-1000-8000-00805f9b34fb  (battery_data)
handle: 0x001b, char properties: 0x02, char value handle: 0x001c, uuid: 00002a29-0000-1000-8000-00805f9b34fb
handle: 0x001d, char properties: 0x02, char value handle: 0x001e, uuid: 00002a24-0000-1000-8000-00805f9b34fb
handle: 0x001f, char properties: 0x02, char value handle: 0x0020, uuid: 00002a25-0000-1000-8000-00805f9b34fb
handle: 0x0021, char properties: 0x02, char value handle: 0x0022, uuid: 00002a27-0000-1000-8000-00805f9b34fb
handle: 0x0023, char properties: 0x02, char value handle: 0x0024, uuid: 00002a26-0000-1000-8000-00805f9b34fb
handle: 0x0026, char properties: 0x04, char value handle: 0x0027, uuid: 00001532-1212-efde-1523-785feabcd123
handle: 0x0028, char properties: 0x18, char value handle: 0x0029, uuid: 00001531-1212-efde-1523-785feabcd123
handle: 0x002b, char properties: 0x02, char value handle: 0x002c, uuid: 00001534-1212-efde-1523-785feabcd123
handle: 0x002e, char properties: 0x18, char value handle: 0x002f, uuid: 00000001-0000-1000-8000-00805f9b34fb
handle: 0x0031, char properties: 0x02, char value handle: 0x0032, uuid: 00000002-0000-1000-8000-00805f9b34fb
handle: 0x0033, char properties: 0x02, char value handle: 0x0034, uuid: 00000004-0000-1000-8000-00805f9b34fb
handle: 0x0035, char properties: 0x08, char value handle: 0x0036, uuid: 00000010-0000-1000-8000-00805f9b34fb
handle: 0x0037, char properties: 0x0a, char value handle: 0x0038, uuid: 00000013-0000-1000-8000-00805f9b34fb
handle: 0x0039, char properties: 0x0a, char value handle: 0x003a, uuid: 00000014-0000-1000-8000-00805f9b34fb

$ gatttool -b $mac --char-desc

...
handle: 0x0010, uuid: 00002902-0000-1000-8000-00805f9b34fb (sensor_write value 0100)
...

Get information with gatttool:
Temperature & Humidity
$ gatttool -b $mac --char-write-req --handle 0x10 --value=0100 --listen

Characteristic value was written successfully
Notification handle = 0x000e value: 54 3d 32 33 2e 39 20 48 3d 35 32 2e 34 00
Notification handle = 0x000e value: 54 3d 32 34 2e 30 20 48 3d 35 32 2e 33 00
Notification handle = 0x000e value: 54 3d 32 33 2e 39 20 48 3d 35 32 2e 33 00

$ echo "54 3d 32 33 2e 39 20 48 3d 35 32 2e 34 00" | xxd -r -p
T=23.9 H=52.4

Battery:
$ gatttool -b $mac --char-read --handle 0x18

Characteristic value/descriptor: 64

$ echo "ibase=16; 64" | bc

100

No output, except "user code done"

Hi,

i 've changed the partition size, compiled the sketch and uploaded it successfully, but there is nothing more than "user code done" in the serial monitor.

Any hints are appreciated, how to fix this.

Chris

Additional help needed for setup

Hi, I've been trying to set this scipt up on Arduino IDE according to your instructions. It seems as though something is missing:

BLEDevice.h: No such file or directory

Is there any additional step or library/libraries required for Arduino IDE? If yes, could you add the url of the library in the README?

I'm using a ESP32-WROOM-32 on my Board.
Thanks in advance

Using WiFiManager for specifying config.h properties?

Have you considered using WiFiManager for specifying the things that are currently configured in config.h?

WiFiManager creates a web server with a captive portal. You can connect to this using (for example) a mobile phone and enter the WiFi properties (AP name + password).
Along with the WiFi properties, you can also add a set of 'custom' fields, containing the MQTT properties for example. I can build an example for this, if you're interested.

help

hello
can you help?
i cannot find where to put mac, ssid and password ..

Failed to find data service

Hi,

I have been testing both the sidddy / Flora and Lociii / Flora but I runt into issues.
With the Lociii fork I get this after it connects to the flora:

  • Failed to find data service

Anyone that got a clue on what to do?

Thanks

Sketch Size

Hey there, thanks for everything so far...

I still just don't get the changing partition table size.
All i found is the make menuconfig, but there is no menuconfig file at all...

Maybe you could help out.

Thanks alot

Crashes for first try, then stuck at connecting

Hi there,

after changing the partition table, I got the sketch successfully uploaded to my ESP32 dev board.

However, it fails to read any miflora data. Often it crashes a few time before performing a connection, but even then nothing else happens before it goes to sleeo mode:

`Starting Flora client...
Connecting WiFi...
.....
WiFi connected
Attempting MQTT connection...connected
Forming a connection to Flora device at c4:7c:8d:66:51:40

  • Connected to Flora
    abort() was called at PC 0x401a780f on core 1

Backtrace: 0x40095324:0x3ffdaaa0 0x40095527:0x3ffdaac0 0x401a780f:0x3ffdaae0 0x401a7856:0x3ffdab00 0x4019513b:0x3ffdab20 0x400d31b1:0x3ffdab40 0x400d1627:0x3ffdaba0 0x400d1d91:0x3ffdac70 0x401af3c6:0x3ffdacc0

Rebooting...
ets Jun 8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:952
load:0x40078000,len:6084
load:0x40080000,len:7936
entry 0x40080310
Starting Flora client...
Connecting WiFi...
.....
WiFi connected
Attempting MQTT connection...connected
Forming a connection to Flora device at c4:7c:8d:66:51:40
Goi`

I tried two miflora devices (that work in the official app) and also changed the sleep wait to 120.

Any ideas?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.