1technophile / OpenMQTTGateway

MQTT gateway for ESP8266 or ESP32 with bidirectional 433mhz/315mhz/868mhz, Infrared communications, BLE, Bluetooth, beacons detection, mi flora, mi jia, LYWSD02, LYWSD03MMC, Mi Scale, TPMS, BBQ thermometer compatibility & LoRa.
https://docs.openmqttgateway.com
GNU General Public License v3.0
3.54k stars 781 forks source link

Battery percentage not reported properly to Home Assistant #1563

Closed mwolter805 closed 1 year ago

mwolter805 commented 1 year ago

Describe the bug Home Assistant expects the battery to be a percentage, where openMQTTgateway provides binary.

Built a custom environment for the Olimex ESP32-POE and an AI-Thinker Ra-02 SX1278 433mhz LoRa Module using the config below.

esp32-olimex-poe-rtl_433_env.ini ```ini [platformio] default_envs = esp32-olimex-poe-rtl_433-ota [env:esp32-olimex-poe-rtl_433] platform = ${com.esp32_platform} board = esp32-poe board_build.partitions = min_spiffs.csv lib_deps = ${com-esp.lib_deps} ${libraries.rtl_433_ESP} ; when disabled loads custom library in lib/rtl_433_ESP with disabled decoders in src/decoders.cpp ${libraries.wifimanager32} build_flags = ${com-esp.build_flags} ; *** Main Gateway Options *** '-DGateway_Name="OpenMQTTGateway"' ; host name and gateway mqtt topic name '-DNTP_SERVER="10.10.10.12"' ; set local NTP server '-DESP32_ETHERNET=true' ; enabling ethernet disables wifi ; '-DESPWifiManualSetup=true' ; *** MQTT Options *** '-DMQTT_SERVER="10.10.10.12"' '-DMQTT_USER="username"' '-DMQTT_PASS="password"' '-Dota_password="password"' ; ota password for espota.py '-Dsensor_Retain=true' ; retain mqtt sensor value (sensor values survive HA reboot) '-DvalueAsATopic=true' ; MQTT topic includes model and device ; *** OpenMQTTGateway Modules *** '-DZgatewayRTL_433="rtl_433"' ; set RTL_433 module mqtt topic name '-DZradioSX127x="SX127x"' ; *** rtl_433_ESP Options *** ; '-DRTL_DEBUG=4' ; rtl_433 verbose mode ; '-DRTL_VERBOSE=58' ; LaCrosse TX141-Bv2, TX141TH-Bv2, TX141-Bv3, TX141W, TX145wsdth sensor ; '-DRAW_SIGNAL_DEBUG=true' ; display raw received messages ; '-DMEMORY_DEBUG=true' ; display memory usage information ; '-DDEMOD_DEBUG=true' ; display signal debug info ; '-DMY_DEVICES=true' ; subset of devices ; '-DPUBLISH_UNPARSED=true' ; publish unparsed signal details ; '-DRSSI_THRESHOLD=12' ; Apply a delta of 12 (default 9) ; '-DOOK_FIXED_THRESHOLD=0x50' ; Inital OOK Threhold - Only for SX127X (default 15, old default 5A) ; '-DAVERAGE_RSSI=5000' ; Display RSSI floor ( Average of 5000 samples ) ; '-DSIGNAL_RSSI=true' ; Display during signal receive ; '-DRF_MODULE_INIT_STATUS=true' ; Display transceiver config during startup ; '-DMINRSSI=-102' ; default is -82 ; *** RF Module Pins *** '-DRF_SX1278="SX1278"' ; '-DRF_MODULE_DIO0=15' ; SX1278 pin DIO0 '-DRF_MODULE_DIO1=4' ; SX1278 pin DIO1 '-DRF_MODULE_DIO2=16' ; SX1278 pin DIO2 '-DRF_MODULE_RST=14' ; SX1278 pin RST ; *** Used non-standard SPI pins due to ethernet module *** '-DRF_MODULE_CS=13' ; SX1278 pin NSS '-DRF_MODULE_MOSI=2' ; SX1278 pin MOSI '-DRF_MODULE_MISO=5' ; SX1278 pin MISO '-DRF_MODULE_SCK=32' ; SX1278 pin SCK ; *** RadioLib Options *** ; '-DRADIOLIB_DEBUG=true' ; '-DRADIOLIB_VERBOSE=true' custom_description = RTL_433 gateway using ethernet and AI-Thinker Ra-02 SX1278 LoRa Module custom_hardware = OLIMEX ESP32-POE with SX1278 board_upload.speed = 460800 ; board_monitor.speed = 460800 [env:esp32-olimex-poe-rtl_433-ota] extends = env:esp32-olimex-poe-rtl_433 ; load main environment above ; *** OTA Options *** upload_protocol = espota ; use espota.py upload_port = 10.10.21.51 ; IP address or hostname of esp32 upload_flags = --auth=password ; ota_password entered above --port=8266 --host_port=40000 ; custom port allowed through firewall from ESP32 to host performing upload ; monitor_port = socket://10.10.21.51:23 ; Serial upload: pio run --target upload --environment esp32-olimex-poe-rtl_433 ; OTA upload: pio run --target upload ```

Most everything works except battery status in Home Assistant. Appears openMQTTgateway sends a binary battery status, when Home Assistant expects percentage which causes Home Assistant to believe the battery percentage is 1%.

Screenshot 2023-03-22 at 10 44 39 AM

Below is an example sensor topic and battery auto discovery topic.

MQTT Topic: home/OpenMQTTGateway/RTL_433toMQTT/Oregon-THGR810/1/169 ```json { "model": "Oregon-THGR810", "id": 169, "channel": 1, "battery_ok": 1, "temperature_C": 18.5, "humidity": 53, "protocol": "Oregon Scientific Weather Sensor", "rssi": -83, "duration": 98996 } ```
HA Discovery Topic: homeassistant/sensor/Oregon-THGR810-1-169-battery_ok ```json { "stat_t": "+/+/RTL_433toMQTT/Oregon-THGR810/1/169", "dev_cla": "battery", "name": "battery", "uniq_id": "Oregon-THGR810-1-169-battery_ok", "val_tpl": "{{ value_json.battery_ok | is_defined }}", "state_class": "measurement", "device": { "identifiers": [ "Oregon-THGR810-1-169" ], "connections": [ [ "mac", "Oregon-THGR810-1-169" ] ], "model": "Oregon-THGR810", "name": "Oregon-THGR810-1-169", "via_device": "OpenMQTTGateway" } } ```

Expected behavior Battery to be reported as as percentage. Possibly map 1 to 100.

DigiH commented 1 year ago

This comes from RTL_433 where many/most devices only send a boolean for the battery status, with 1 = OK, 0 = very low/empty.

The discovery for these battery_ok needs to be differentiated as a bool form other batt/battery reportings in percentage.

mwolter805 commented 1 year ago

Please correct me if I’m wrong, but I believe what you’re saying are a few things.

  1. This needs to be corrected in rtl_433_ESP.
  2. They need to change the output to be bool and report true/false.
  3. Once they do this, within openMQTTgareway, they can translate this with the HAdiscovery from true to 100 and false to 0.

Does this look right?

Once they do this will openMQTTgateway translate this natively, or will changes need to be made there also?

DigiH commented 1 year ago
  1. This needs to be corrected in rtl_433_ESP.
  2. They need to change the output to be bool and report true/false.

I don't think any correction is needed in rtl_433_ESP or rtl_433 for that matter, as this topic seems to have been discussed and decided upon a while back, with issues like https://github.com/merbanan/rtl_433/issues/710

3. Once they do this, within openMQTTgareway, they can translate this with the HAdiscovery from true to 100 and false to 0.

Converting the boolean values 1 and 0 to 100% and 0%I think is not a good idea at all, as it would give the false impression of an actual percentage level, which it isn't. But possibly changing the auto-discovery in OpenMQTTGateway to something like

Battery   ok
Battery   low

could be a clearer representation. Something we are looking at and discussing currently.

mwolter805 commented 1 year ago

Thank you for the reply. How do you recommend handling this when Home Assistant expects an entity with "device_class: battery" to be an integer between 0 and 100? Currently Home Assistant believes the device has 1% battery remaining.

Please see Sensor Device Class and Sensor Entity.

DigiH commented 1 year ago

From what I can see in your screenshot it might not be the usual expected 0-100%, but it also doesn't seem to display the percentage sign. Only having started looking into HA myself I don't know how other rtl_433 device users handle the common rtl_433 battery_ok reporting - either they just know and accept the fact that for their rtl_433 devices the battery is displaying 1/0 as its binary state without the %, but I have also seen

json_attributes_template: "{{ {'time': value_json.time, 'batt': 'ok' if value_json.battery_ok == 1 else '?'} | tojson }}

in

https://community.home-assistant.io/t/temperature-humidity-and-rain-for-under-10-eur/200443/10

Ideally HA could also introduce a battery_ok/battery_state property which would take 1/0, true/false, ok/low.

Please see Sensor Device Class and Sensor Entity.

I am well aware, but to me that only shows the shortcoming of not having an option for the binary battery_ok state of virtually all the rtl_433 devices.

NorthernMan54 commented 1 year ago

As the sensor only supports a 0 or 1 value, we will need to change the OMG homeassistant discovery message value template for the battery, to return either 0 or 100.

DigiH commented 1 year ago

Then at least use the battery_ok as the double it is, multiply it by 100, round it for display and then it'll be at least correct for the few devices which send the battery_ok status as a double, like the Fineoffset-WH51.

For all other I still think it's a very misleading option - going away for a longer period and checking the battery status for all your devices beforehand, all showing 100 when some of them might actually be closer to 20%, but not yet switched over to 0 ;)

https://triq.org/rtl_433/DATA_FORMAT.html#message-data

mwolter805 commented 1 year ago

Adding this due to its relation to the topic. Rebooted Home Assistant and received this log entry. There was an additional log for each sensor, five total.

2023-03-27 14:15:04.524 WARNING (MainThread) [homeassistant.components.sensor] Entity sensor.front_patio_thgr810_3_battery (<class 'homeassistant.components.mqtt.sensor.MqttSensor'>) is using native unit of measurement 'None' which is not a valid unit for the device class ('battery') it is using; expected one of ['%']; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+mqtt%22

Snuffy2 commented 1 year ago

The other option could be to change the autodiscovery of the boolean battery from a sensor to a binary_sensor. There is a binary_sensor device class of battery as well. It uses True for Low and False for Normal. This is obviously opposite of what OMG is current reporting but I'm sure could be handled.

https://developers.home-assistant.io/docs/core/entity/binary-sensor/

NorthernMan54 commented 1 year ago

After spending some time looking at the issue, and what other packages are doing, stumbled on this

https://github.com/merbanan/rtl_433/blob/93f0f30c28cfb6b82b8cc3753415b01a85bee91d/examples/rtl_433_mqtt_hass.py#L180

Which looks like a almost perfect solution, for sensors that send a % and for sensors that send a 0/1. The only challenge is that the section of code that creates the discovery message will need work to implement it. Currently it uses the same value_template for all sensors / fields - https://github.com/1technophile/OpenMQTTGateway/blob/479ac5d3439112e548a5e164989be012f3a224d1/main/ZgatewayRTL_433.ino#L133

mwolter805 commented 1 year ago

@NorthernMan54 Had that script running in a container and it worked well with Home Assistant.

mwolter805 commented 1 year ago

This works perfectly, thank you.