Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sensor not found #1

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.pio
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/ipch
include/config.h
.vscode/extensions.json
43 changes: 43 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Continuous Integration (CI) is the practice, in software
# engineering, of merging all developer working copies with a shared mainline
# several times a day < https://docs.platformio.org/page/ci/index.html >
#
# Documentation:
#
# * Travis CI Embedded Builds with PlatformIO
# < https://docs.travis-ci.com/user/integration/platformio/ >
#
# * PlatformIO integration with Travis CI
# < https://docs.platformio.org/page/ci/travis.html >
#
# * User Guide for `platformio ci` command
# < https://docs.platformio.org/page/userguide/cmd_ci.html >
#
#
# Please choose one of the following templates (proposed below) and uncomment
# it (remove "# " before each line) or use own configuration according to the
# Travis CI documentation (see above).
#


#
# Template #1: General project. Test it using existing `platformio.ini`.
#

language: python
python:
- "3.7"

sudo: false
cache: false

install:
- pip install -U platformio
- platformio upgrade --dev
- platformio update

before_script:
- cp example/config.h.example include/config.h

script:
- platformio run
7 changes: 7 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
]
}
164 changes: 140 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,39 +1,154 @@
## flora
# Xiaomi Flora Plant sensors [![Build Status](https://travis-ci.com/RaymondMouthaan/miflora-esp32.svg?branch=master)](https://travis-ci.com/github/RaymondMouthaan/miflora-esp32)

This arduino sketch implements an ESP32 BLE client for XIaomi Mi Flora Plant sensors, pushing the meaasurements to an MQTT server.
This [PlatformIO](https://platformio.org) project implements an ESP32 BLE client for Xiaomi Flora Plant sensors, pushing the measurements in json format to a MQTT broker.

## Technical requirements
![xiaomi-flora](xiaomi-miflora.png)

## Features

Base on the great work of @sidddy and @jvyoralek (and all other contributors), this project adds:

- Support for multiple Miflora sensors with friendly named topics
- Payloads in json format
- Device (Wifi) status and lwt (last will and testament)
- Seperate configurable (sub) topics
- Measurement levels (configurable by min, max values)
- Battery low status and battery level (configurable by thresholds)

__Note : tested with a maximum of 8 Miflora sensors configured, however the ESP32 for some unknown reason get's stuck sometimes. With 4 Miflora sensors configured the ESP32 looks stable and therefore it's advisable to configure a maximum of 4 Miflora sensors per ESP32.__

## Technical Requirements

Hardware:
- ESP32
- Xiaomi Mi Plant Sensor (firmware revision >= 2.6.6)
- ESP32 device ([ESP32 at AliExpress](https://nl.aliexpress.com/wholesale?catId=0&initiative_id=SB_20200408062838&SearchText=MH-ET+Live+ESP32))
- Xiaomi Flora Plant Sensor (firmware revision >= 2.6.6) ([Xiaomi flora at AliExpress](https://nl.aliexpress.com/wholesale?catId=0&initiative_id=SB_20200408063038&SearchText=xiaomi+flora))

Software:
- MQTT server

## Setup instructions
- MQTT broker (e.g. [Mosquitto](https://mosquitto.org))

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)
## Quick Setup Instructions

2) Open Arduino, Sketch -> Include Library -> Manage Libraries... and install ESP32 BLE library by Neil Kolban / Version 1.0.1
Assumed you are familiar with [Visual Studo Code](https://code.visualstudio.com) and [PlatformIO](https://platformio.org).

3) Open ino sketch in Arduino, compile & upload.
1) Open the project in Visual Studio Code with PlatformIO installed
2) Copy `example/config.h.example` to `include/config.h` and update settings according to your environment:
- MAC address(es), location(s), plant id(s) and min and max values of your Xiaomi Flora Plant sensor(s)
- Device id
- WLAN Settings
- MQTT Settings
3) Modify platform.ini according to your environment:
- upload_port
- monitor_port

## Measuring interval
## 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.
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 n minutes before repeating the exercise...
Battery level is read every nth wakeup.
Up to n 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?
- `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 often should the battery status be read?
- `BATTERY_THRESHOLD` - when is the battery on low power?
- `SENSOR_RETRY` - how ofter should a single sensor be tried on each run?

## Topics

The ESP32 will publish payload in json format on two base topics and are divided in two categories:

### Device topic

This topic is used to publish payload related to the esp32 device status and lwt (last will and testament).

#### Last will and testament

When the ESP32 connects to the MQTT broker a `online` message will be published to the `/device/lwt` subtopic to indicate the ESP32 is online.

Topic format: `<base_topic>/<device_id>/device/lwt`

Example plain text payload:
```
online
```

When the ESP32 disconnects from the MQTT broker an `offline` message is published to the `/device/lwt` subtopic to indicate the ESP32 is offline and in sleep mode.

Example plain text payload:
```
offline
```

#### Status

The subtopic `/device/status` is used to publish payload related to ESP32 (WiFi) status.

Topic format: `<base_topic>/<device_id>/device/status`

Example json payload:
```
{
"id": "esp32-1",
"ipaddress": "10.40.1.1",
"mac": "24:62:AB:CA:F6:40",
"channel": 10,
"rssi": -51
}
```

- `id` - the id of the ESP32 as defined in `config.h`
- `ipaddress` - the ip address of the ESP32 given by the DHCP server
- `mac` - the MAC address of the ESP32
- `channel` - the channel of the WiFi network
- `rssi` - the WiFi Received Signal Strength Indicator

### Sensor topic

This topic is used to publish payload related to the Miflora sensor measurements. Each Miflora sensor has its own subtopic.

Topic format: `<base_topic>/<device_id>/sensor/<location>/<plant_id>`

Example json payload:
```
{
"id": "calathea-1",
"location": "livingroom",
"mac": "C4:7C:8D:67:57:07",
"retryCount": 1,
"rssi": -75,
"temperature": 21.2,
"temperatureLevel": 1,
"moisture": 4,
"moistureLevel": 0,
"light": 1203,
"lightLevel": 1,
"conductivity": 72,
"conductivityLevel": 0,
"battery": 98,
"batteryLow": false,
"batteryLevel": 2
}
```

- `id` - the id of the plant
- `location` - the location where the Miflora is placed
- `mac` - the MAC address of the Miflora
- `retryCount` - number of retry attempts to retreive valid data from the Miflora
- `rssi` - the BLE Received Signal Strength Indicator
- `temperature` - the measured temperature in degree Celsius
- `temperatureLevel` - indicates if the temperature is 0=low, 1=medium or 2=high, configurable by minTemperature and maxTemperature
- `moisture` - the measured moisture in percentage
- `moistureLevel` - indicates if the moisture is 0=low, 1=medium or 2=high, configurable by minMoisture and maxMoisture
- `light` - the measured light in lux
- `lightLevel` - indicates if the light is 0=low, 1=medium or 2=high, configurable by minLight and maxLight
- `conductivity` - the measured conductivity in uS/cm
- `conductivityLevel` - indicates if the conductivity is 0=low, 1=medium or 2=high, configurable by minConductivity and maxConductivity
- `battery` - the measured battery level in percentage
- `batteryLow` - indicates if the battery is low (true or false), based on the battery low threshold
- `batteryLevel` - indicates if the battery is 0=low, 1=medium or 2=high, based on the battery low and mediun thresholds

__Note: the min and max values for each measurement can be found in the Flower Care app for [IOS](https://apps.apple.com/us/app/flower-care/id1095274672)__ or [Android](https://play.google.com/store/apps/details?id=com.huahuacaocao.flowercare&hl=en).

## Constraints

Expand All @@ -43,8 +158,9 @@ Some "nice to have" features are not yet implemented or cannot be implemented:
## 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"
On Arduino IDE this can be achieved using "Tools -> Partition Scheme -> No OTA".
For this platform.io project this is achieved using `board_build.partitions = no_ota.csv` in `platformio.ini`.

## Credits

Many thanks go to @sidddy and @jvyoralek for most of the work of the project and improvements!
Many thanks go to the guys at https://github.com/open-homeautomation/miflora for figuring out the sensor protocol.
34 changes: 34 additions & 0 deletions example/config.h.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Array of different Xiaomi Flora MAC addresses, their location, plant id and min, max values
// <mac_address>, <location>, <plant_id>, <min_temperature>, <max_temperature>, <min_moisture>, <max_moisture>, <min_light>, <max_light>, <min_conductivity>, <max_conductivity>
String FLORA_DEVICES[][11] = {
{"C4:7C:8D:67:57:07", "livingroom", "calathea-1", "12", "32", "15", "65", "800", "20000", "350", "1000"},
{"C4:7C:8D:67:58:A0", "livingroom", "ficus-1", "8", "32", "20", "60", "2500", "35000", "350", "2000"},
{"C4:7C:8D:6A:0D:2F", "livingroom", "palm-1", "10", "35", "15", "60", "2500", "35000", "350", "2000"},
{"C4:7C:8D:6A:0F:9B", "livingroom", "orchid-1", "15", "32", "15", "65", "2000", "30000", "350", "2000"},
// {"C4:7C:8D:6A:0C:36", "livingroom", "orchid-2", "15", "32", "15", "65", "2000", "30000", "350", "2000"},
// {"C4:7C:8D:6A:11:65", "livingroom", "orchid-3", "15", "32", "15", "65", "2000", "30000", "350", "2000"},
// {"C4:7C:8D:6A:0C:8A", "diningroom", "orchid-4", "15", "32", "15", "65", "2000", "30000", "350", "2000"},
// {"C4:7C:8D:6A:10:36", "diningroom", "orchid-5", "15", "32", "15", "65", "2000", "30000", "350", "2000"},
};

// Device settings
#define DEVICE_ID "esp32-1" // Identifier of the esp32 device
#define SLEEP_DURATION 15 * 60 // Sleep between to runs in seconds
#define EMERGENCY_HIBERNATE 1 * 60 // Emergency hibernate countdown in seconds
#define BATTERY_INTERVAL 1 // How often should the battery be read - in run count
#define BATTERY_THRESHOLD_LOW 20 // Battery threshold when battery gets low
#define BATTERY_THRESHOLD_MED 80 // Battery threshold when battery gets medium
#define SENSOR_RETRY 5 // How often should a sensor be retried in a run when something fails

// Wifi settings
#define WIFI_SSID "your_wifi_ssdi" // SSID of your WiFi network
#define WIFI_PASSWORD "<your_wifi_password>" // Password of your WiFi network

// Mqtt settings
#define MQTT_HOST "<your_mqtt_broker_ipaddress>" // Mqtt broker ip address or hostname
#define MQTT_PORT 1883 // Mqqt port (default: 1883)
#define MQTT_USERNAME "miflora" // Mqtt username [optional]
#define MQTT_PASSWORD "miflora" // Mqtt username [optional]
#define MQTT_BASE_TOPIC "miflora" // The Miflora base topic
#define MQTT_RETRY_WAIT 5000 // Retry delay between attempts to connect to the Mqtt broker
#define MQTT_RETAIN false // Retain Mqtt messages (default: false)
7 changes: 7 additions & 0 deletions example/device.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"id": "esp32-1",
"ipaddress": "10.40.1.1",
"mac": "24:62:AB:CA:F6:40",
"channel": 10,
"rssi": -51
}
18 changes: 18 additions & 0 deletions example/sensor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"id": "calathea-1",
"location": "livingroom",
"mac": "C4:7C:8D:67:57:07",
"retryCount": 1,
"rssi": -75,
"temperature": 21.2,
"temperatureLevel": 1,
"moisture": 4,
"moistureLevel": 0,
"light": 1203,
"lightLevel": 1,
"conductivity": 72,
"conductivityLevel": 0,
"battery": 98,
"batteryLow": false,
"batteryLevel": 2
}
1 change: 0 additions & 1 deletion flora/.gitignore

This file was deleted.

31 changes: 0 additions & 31 deletions flora/config.h.example

This file was deleted.

Loading