├── sdr2mqtt ├── icon.png ├── logo.png ├── LICENSE ├── Dockerfile ├── config.json ├── entry.sh ├── README.md ├── CHANGELOG.md ├── PROTOCOLS.md └── rtl_433_mqtt_hass.py ├── acurite2mqtt ├── icon.png ├── logo.png ├── LICENSE ├── Dockerfile ├── config.json ├── entry.sh ├── README.md ├── CHANGELOG.md ├── PROTOCOLS.md └── rtl_433_mqtt_hass.py ├── images └── slacker_labs.png ├── repository.json ├── README.md ├── .gitignore └── LICENSE /sdr2mqtt/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/hassio_addons/HEAD/sdr2mqtt/icon.png -------------------------------------------------------------------------------- /sdr2mqtt/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/hassio_addons/HEAD/sdr2mqtt/logo.png -------------------------------------------------------------------------------- /acurite2mqtt/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/hassio_addons/HEAD/acurite2mqtt/icon.png -------------------------------------------------------------------------------- /acurite2mqtt/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/hassio_addons/HEAD/acurite2mqtt/logo.png -------------------------------------------------------------------------------- /images/slacker_labs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/hassio_addons/HEAD/images/slacker_labs.png -------------------------------------------------------------------------------- /repository.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Home Assistant Add-ons: Slacker Labs", 3 | "url": "https://github.com/thejeffreystone/hassio-addons", 4 | "maintainer": "Jeffrey Stone" 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 |

Home Assistant Add-ons

4 |
5 | 6 | ## Installation 7 | 8 | Add the repository URL under **Supervisor → Add-on store → ⋮ → Manage add-on repositories**: 9 | 10 | https://github.com/thejeffreystone/hassio_addons 11 | 12 | The repository includes two add-ons: 13 | 14 | - **acurite2mqtt** is a beta release that uses uses a SDR to connect Acurite Weather Sensors to Home Assistant 15 | 16 | - **sdr2mqtt** is a beta release that uses SDR to connect any RF device that is supported by the RTL_433 project and push them to Home Assistant 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # ignore any of these files no matter where they are using double * 3 | acurite2mqtt-beta/ 4 | .devcontainer/ 5 | **.DS_Store 6 | **._* 7 | **.HA_VERSION 8 | **.pyc 9 | **.conf 10 | **.uuid 11 | **.txt 12 | **.log 13 | **.db 14 | **.sqlite 15 | **.xml 16 | **secrets* 17 | **known_devices.yaml 18 | **google_calendars.yaml 19 | **ip_bans.yaml 20 | **.spotify-token-cache 21 | **zones.yaml 22 | **test.yaml 23 | **testing.yaml 24 | **.homekit* 25 | **.vscode 26 | **.pid 27 | **.xml 28 | **.csr 29 | **.crt 30 | **.key 31 | **core.* 32 | **OZW_Log.txt 33 | **home-assistant.log 34 | **home-assistant_v2.db 35 | **.db-journal 36 | **.db-shm 37 | **.db-wal 38 | **.sqlite 39 | **__pycache__ 40 | **phue.conf 41 | **ios.conf 42 | **pyozw.sqlite 43 | **ipchange.yaml 44 | **production_auth.json -------------------------------------------------------------------------------- /sdr2mqtt/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Slacker Labs / Jeffrey Stone 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /acurite2mqtt/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Slacker Labs / Jeffrey Stone 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /acurite2mqtt/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BUILD_FROM 2 | FROM $BUILD_FROM 3 | 4 | # Define environment variables 5 | # Use this variable when creating a container to specify the MQTT broker host. 6 | ENV MQTT_HOST=127.0.0.1 \ 7 | MQTT_PORT=1883 \ 8 | MQTT_USERNAME="" \ 9 | MQTT_PASSWORD="" \ 10 | MQTT_RETAIN=True \ 11 | MQTT_TOPIC=rtl_433 \ 12 | PROTOCOL="" \ 13 | WHITELIST_ENABLE=False \ 14 | EXPIRE_AFTER=0 \ 15 | WHITELIST="" \ 16 | DISCOVERY_PREFIX=homeassistant \ 17 | DISCOVERY_INTERVAL=600 \ 18 | AUTO_DISCOVERY=True \ 19 | DEBUG=False \ 20 | LANG=C.UTF-8 21 | 22 | LABEL Maintainer="Jeffrey Stone" \ 23 | Description="This image is used to start the RTL433 to HASS script that will monitor for 433Mhz devices and send the data to an MQTT server" 24 | 25 | WORKDIR /data 26 | 27 | # Copy scripts 28 | COPY entry.sh rtl_433_mqtt_hass.py /scripts/ 29 | # install rtl_433, rtl-sdr, libusb, mosquitto-clients, python3 py3-paho-mqtt; and deps of rtl_433_mqtt_hass.py. 30 | # make entry.sh and rtl_433_mqtt_hass.py executable. 31 | RUN apk add --no-cache rtl-sdr rtl_433 libusb mosquitto-clients python3 py3-paho-mqtt && \ 32 | chmod +x /scripts/entry.sh && \ 33 | chmod +x /scripts/rtl_433_mqtt_hass.py 34 | 35 | # Execute entry script 36 | ENTRYPOINT [ "/scripts/entry.sh" ] -------------------------------------------------------------------------------- /sdr2mqtt/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BUILD_FROM 2 | FROM $BUILD_FROM 3 | 4 | # Define environment variables 5 | # Use this variable when creating a container to specify the MQTT broker host. 6 | ENV MQTT_HOST=127.0.0.1 \ 7 | MQTT_PORT=1883 \ 8 | MQTT_USERNAME="" \ 9 | MQTT_PASSWORD="" \ 10 | MQTT_RETAIN=True \ 11 | MQTT_TOPIC=rtl_433 \ 12 | FREQUENCY=433.92M \ 13 | PROTOCOL="" \ 14 | WHITELIST_ENABLE=False \ 15 | EXPIRE_AFTER=0 \ 16 | WHITELIST="" \ 17 | DISCOVERY_PREFIX=homeassistant \ 18 | DISCOVERY_INTERVAL=600 \ 19 | AUTO_DISCOVERY=False \ 20 | DEBUG=False \ 21 | LANG=C.UTF-8 22 | 23 | LABEL Maintainer="Jeffrey Stone" \ 24 | Description="This image is used to start the RTL433 to HASS script that will monitor for 433Mhz devices and send the data to an MQTT server" 25 | 26 | WORKDIR /data 27 | 28 | # Copy scripts 29 | COPY entry.sh rtl_433_mqtt_hass.py /scripts/ 30 | # install rtl_433, rtl-sdr, libusb, mosquitto-clients, python3 py3-paho-mqtt; and deps of rtl_433_mqtt_hass.py. 31 | # make entry.sh and rtl_433_mqtt_hass.py executable. 32 | RUN apk add --no-cache rtl-sdr rtl_433 libusb mosquitto-clients python3 py3-paho-mqtt && \ 33 | chmod +x /scripts/entry.sh && \ 34 | chmod +x /scripts/rtl_433_mqtt_hass.py 35 | 36 | # Execute entry script 37 | ENTRYPOINT [ "/scripts/entry.sh" ] -------------------------------------------------------------------------------- /acurite2mqtt/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Acurite to Home Assistant", 3 | "version": "0.3.26", 4 | "slug": "acurite2mqtt", 5 | "description": "Acurite Sensors to Home Assistant via MQTT with Autodiscovery", 6 | "url": "https://github.com/thejeffreystone/hassio_addons", 7 | 8 | "startup": "services", 9 | "arch": ["aarch64", "amd64", "armhf", "armv7", "i386"], 10 | "usb": true, 11 | "options": 12 | { 13 | "mqtt_host": "192.168.1.100", 14 | "mqtt_port": 1883, 15 | "mqtt_user": "user", 16 | "mqtt_password": "pass", 17 | "mqtt_topic": "rtl_433", 18 | "mqtt_retain" : "true", 19 | "protocol": "-R 11 -R 40 -R 41 -R 55 -R 74", 20 | "whitelist_enable": "false", 21 | "whitelist": "", 22 | "expire_after": 0, 23 | "units": "si", 24 | "discovery_prefix": "homeassistant", 25 | "discovery_interval": 600, 26 | "auto_discovery": "true", 27 | "debug": "false" 28 | }, 29 | "schema": 30 | { 31 | "mqtt_host": "str", 32 | "mqtt_port": "int", 33 | "mqtt_user": "str", 34 | "mqtt_password": "str", 35 | "mqtt_topic": "str", 36 | "mqtt_retain" : "bool", 37 | "protocol": "str", 38 | "whitelist_enable": "bool", 39 | "whitelist": "str", 40 | "expire_after": "int", 41 | "units": "str", 42 | "discovery_prefix": "str", 43 | "discovery_interval": "int", 44 | "auto_discovery": "bool", 45 | "debug": "bool" 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /sdr2mqtt/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SDR to Home Assistant", 3 | "version": "0.1.24", 4 | "slug": "sdr2mqtt", 5 | "description": "SDR/RTL Sensors to Home Assistant via MQTT with Autodiscovery", 6 | "url": "https://github.com/thejeffreystone/hassio_addons", 7 | 8 | "startup": "services", 9 | "arch": ["aarch64", "amd64", "armhf", "armv7", "i386"], 10 | "usb": true, 11 | "options": 12 | { 13 | "mqtt_host": "192.168.1.100", 14 | "mqtt_port": 1883, 15 | "mqtt_user": "user", 16 | "mqtt_password": "pass", 17 | "mqtt_topic": "rtl_433", 18 | "mqtt_retain" : "true", 19 | "frequency" : "-f 433.92M", 20 | "protocol" : "-R 40", 21 | "whitelist_enable": "false", 22 | "whitelist": "", 23 | "expire_after": 0, 24 | "units": "si", 25 | "discovery_prefix": "homeassistant", 26 | "discovery_interval": 600, 27 | "auto_discovery": "true", 28 | "debug": "false" 29 | }, 30 | "schema": 31 | { 32 | "mqtt_host": "str", 33 | "mqtt_port": "int", 34 | "mqtt_user": "str", 35 | "mqtt_password": "str", 36 | "mqtt_topic": "str", 37 | "mqtt_retain" : "str", 38 | "frequency" : "str", 39 | "protocol": "str", 40 | "whitelist_enable": "bool", 41 | "whitelist": "str", 42 | "expire_after": "int", 43 | "units": "str", 44 | "discovery_prefix": "str", 45 | "discovery_interval": "int", 46 | "auto_discovery": "bool", 47 | "debug": "bool" 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /acurite2mqtt/entry.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bashio 2 | CONFIG_PATH=/data/options.json 3 | 4 | MQTT_HOST="$(bashio::config 'mqtt_host')" 5 | MQTT_PORT="$(bashio::config 'mqtt_port')" 6 | MQTT_USERNAME="$(bashio::config 'mqtt_user')" 7 | MQTT_PASSWORD="$(bashio::config 'mqtt_password')" 8 | MQTT_TOPIC="$(bashio::config 'mqtt_topic')" 9 | MQTT_RETAIN="$(bashio::config 'mqtt_retain')" 10 | PROTOCOL="$(bashio::config 'protocol')" 11 | UNITS="$(bashio::config 'units')" 12 | DISCOVERY_PREFIX="$(bashio::config 'discovery_prefix')" 13 | DISCOVERY_INTERVAL="$(bashio::config 'discovery_interval')" 14 | WHITELIST_ENABLE="$(bashio::config 'whitelist_enable')" 15 | WHITELIST="$(bashio::config 'whitelist')" 16 | AUTO_DISCOVERY="$(bashio::config 'auto_discovery')" 17 | DEBUG="$(bashio::config 'debug')" 18 | EXPIRE_AFTER="$(bashio::config 'expire_after')" 19 | 20 | # Exit immediately if a command exits with a non-zero status: 21 | set -e 22 | 23 | export LANG=C 24 | PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin" 25 | export LD_LIBRARY_PATH=/usr/local/lib64 26 | 27 | # Start the listener and enter an endless loop 28 | bashio::log.blue "::::::::Starting RTL_433 with parameters::::::::" 29 | bashio::log.info "MQTT Host =" $MQTT_HOST 30 | bashio::log.info "MQTT port =" $MQTT_PORT 31 | bashio::log.info "MQTT User =" $MQTT_USERNAME 32 | bashio::log.info "MQTT Password =" $(echo $MQTT_PASSWORD | sha256sum | cut -f1 -d' ') 33 | bashio::log.info "MQTT Topic =" $MQTT_TOPIC 34 | bashio::log.info "MQTT Retain =" $MQTT_RETAIN 35 | bashio::log.info "PROTOCOL =" $PROTOCOL 36 | bashio::log.info "Whitelist Enabled =" $WHITELIST_ENABLE 37 | bashio::log.info "Whitelist =" $WHITELIST 38 | bashio::log.info "Expire After =" $EXPIRE_AFTER 39 | bashio::log.info "UNITS =" $UNITS 40 | bashio::log.info "DISCOVERY_PREFIX =" $DISCOVERY_PREFIX 41 | bashio::log.info "DISCOVERY_INTERVAL =" $DISCOVERY_INTERVAL 42 | bashio::log.info "AUTO_DISCOVERY =" $AUTO_DISCOVERY 43 | bashio::log.info "DEBUG =" $DEBUG 44 | bashio::log.blue "::::::::rtl_433 running output::::::::" 45 | 46 | rtl_433 $PROTOCOL -C $UNITS -F mqtt://$MQTT_HOST:$MQTT_PORT,user=$MQTT_USERNAME,pass=$MQTT_PASSWORD,retain=$MQTT_RETAIN,events=$MQTT_TOPIC/events,states=$MQTT_TOPIC/states,devices=$MQTT_TOPIC[/model][/id][/channel:A] -M time:tz:local -M protocol -M level | /scripts/rtl_433_mqtt_hass.py -------------------------------------------------------------------------------- /sdr2mqtt/entry.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bashio 2 | CONFIG_PATH=/data/options.json 3 | 4 | MQTT_HOST="$(bashio::config 'mqtt_host')" 5 | MQTT_PORT="$(bashio::config 'mqtt_port')" 6 | MQTT_USERNAME="$(bashio::config 'mqtt_user')" 7 | MQTT_PASSWORD="$(bashio::config 'mqtt_password')" 8 | MQTT_TOPIC="$(bashio::config 'mqtt_topic')" 9 | MQTT_RETAIN="$(bashio::config 'mqtt_retain')" 10 | PROTOCOL="$(bashio::config 'protocol')" 11 | FREQUENCY="$(bashio::config 'frequency')" 12 | UNITS="$(bashio::config 'units')" 13 | DISCOVERY_PREFIX="$(bashio::config 'discovery_prefix')" 14 | DISCOVERY_INTERVAL="$(bashio::config 'discovery_interval')" 15 | WHITELIST_ENABLE="$(bashio::config 'whitelist_enable')" 16 | WHITELIST="$(bashio::config 'whitelist')" 17 | AUTO_DISCOVERY="$(bashio::config 'auto_discovery')" 18 | DEBUG="$(bashio::config 'debug')" 19 | EXPIRE_AFTER="$(bashio::config 'expire_after')" 20 | 21 | # Exit immediately if a command exits with a non-zero status: 22 | set -e 23 | 24 | export LANG=C 25 | PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin" 26 | export LD_LIBRARY_PATH=/usr/local/lib64 27 | 28 | # Start the listener and enter an endless loop 29 | bashio::log.blue "::::::::Starting RTL_433 with parameters::::::::" 30 | bashio::log.info "MQTT Host =" $MQTT_HOST 31 | bashio::log.info "MQTT port =" $MQTT_PORT 32 | bashio::log.info "MQTT User =" $MQTT_USERNAME 33 | bashio::log.info "MQTT Password =" $(echo $MQTT_PASSWORD | sha256sum | cut -f1 -d' ') 34 | bashio::log.info "MQTT Topic =" $MQTT_TOPIC 35 | bashio::log.info "MQTT Retain =" $MQTT_RETAIN 36 | bashio::log.info "PROTOCOL =" $PROTOCOL 37 | bashio::log.info "FREQUENCY =" $FREQUENCY 38 | bashio::log.info "Whitelist Enabled =" $WHITELIST_ENABLE 39 | bashio::log.info "Whitelist =" $WHITELIST 40 | bashio::log.info "Expire After =" $EXPIRE_AFTER 41 | bashio::log.info "UNITS =" $UNITS 42 | bashio::log.info "DISCOVERY_PREFIX =" $DISCOVERY_PREFIX 43 | bashio::log.info "DISCOVERY_INTERVAL =" $DISCOVERY_INTERVAL 44 | bashio::log.info "AUTO_DISCOVERY =" $AUTO_DISCOVERY 45 | bashio::log.info "DEBUG =" $DEBUG 46 | bashio::log.blue "::::::::rtl_433 running output::::::::" 47 | 48 | rtl_433 $FREQUENCY $PROTOCOL -C $UNITS -F mqtt://$MQTT_HOST:$MQTT_PORT,user=$MQTT_USERNAME,pass=$MQTT_PASSWORD,retain=$MQTT_RETAIN,events=$MQTT_TOPIC/events,states=$MQTT_TOPIC/states,devices=$MQTT_TOPIC[/model][/id][/channel:A] -M time:tz:local -M protocol -M level | /scripts/rtl_433_mqtt_hass.py 49 | -------------------------------------------------------------------------------- /sdr2mqtt/README.md: -------------------------------------------------------------------------------- 1 | # Home Assistant Add-on: SDR2mqtt 2 | 3 | A Home Assistant addon for a software defined radio tuned to listen for RF transmissions from SDR/RTL Sensors and republish the data via MQTT. 4 | 5 | ## Installation 6 | 7 | Add the repository URL under **Supervisor → Add-on store → ⋮ → Manage add-on repositories**: 8 | 9 | https://github.com/thejeffreystone/hassio-addons 10 | 11 | Then search for `SDR to home Assistant` and install it. 12 | 13 | ## Configuration 14 | 15 | Example add-on configuration: 16 | 17 | ```yaml 18 | mqtt_host: 192.168.7.100 19 | mqtt_user: mqtt_user 20 | mqtt_password: mqtt_pass 21 | mqtt_topic: rtl_433 22 | mqtt_retain: 'true' 23 | frequency: '-f 433.92M' 24 | protocol: '' 25 | units: 'si' 26 | discovery_prefix: homeassistant 27 | discovery_interval: 600 28 | debug: false 29 | ``` 30 | 31 | ### Option: `mqtt_host` 32 | 33 | The `mqtt_host` option is the ip address of your mqtt server. If you are using the embeded server in Home Assistant just use your instances ip address. 34 | 35 | ### Option: `mqtt_user` 36 | 37 | This is the username required to access your mqtt server. 38 | 39 | ### Option: `mqtt_password` 40 | 41 | The password of the mqtt user account. 42 | 43 | ### Option: `mqtt_topic` 44 | 45 | This si the topic your devices will use. 46 | 47 | ### Option: `mqtt_retain` 48 | 49 | Setting this to `true` means the mqtt server will keep your last value 50 | until it is changed. Setting it to `false` means the server will forget values after a period of time, 51 | so you will onyl see a valus it one has been sent recently. 52 | 53 | ### Option: `frequency` 54 | 55 | This sets the frequecy your SDR will listen for. Default is '-f 433.92M' but you could use '-f 915M' or '-f 868M' 56 | of you could use mutliples like '-f 433.92M f 915M' 57 | 58 | ### Option: `protocol` 59 | 60 | This determines what devices the software listens to. `-R 11 -R 40 -R 41 -R 55 -R 74` 61 | is the Accurite sensors. If the protocol is blank it will listen for all devices 62 | which may be noisy. Blank is the default with this addon. Consult the following readme for protocols. 63 | 64 | For all possible protocols visit 65 | 66 | ### Option: `expire_after` 67 | 68 | This is a `integer` value that will set an individual sensor entity to `unknown` if no payload is received within the specified seconds. The default value of 0 disables this feature. 69 | 70 | ### Option: `units` 71 | 72 | Sets the meansurement units. 73 | - `si` = Metric 74 | - `customary` = Imperial / Customary 75 | 76 | ### Option: `discovery_prefix` 77 | 78 | The mqtt prefix for autodiscovery. `homeassistant` should work. If you use another autodiscovery may not work. 79 | 80 | ### Option: `discovery_interval` 81 | 82 | `600` means Home Assisatnt will check for new devices every 600 seconds. 83 | 84 | ### Option: 'debug' 85 | 86 | Set debug to `true` if you want to see extra logging. This is noisy though, so I would only run it when actively troubleshooting. Leave at false all other times. 87 | 88 | ## Known issues and limitations 89 | 90 | - This add-on is totally beta. 91 | 92 | ## Changelog & Releases 93 | 94 | This repository keeps a change log using [GitHub's releases][releases] 95 | functionality. The format of the log is based on 96 | [Keep a Changelog][keepchangelog]. 97 | 98 | Releases are based on [Semantic Versioning][semver], and use the format 99 | of ``MAJOR.MINOR.PATCH``. In a nutshell, the version will be incremented 100 | based on the following: 101 | 102 | - ``MAJOR``: Incompatible or major changes. 103 | - ``MINOR``: Backwards-compatible new features and enhancements. 104 | - ``PATCH``: Backwards-compatible bugfixes and package updates. 105 | -------------------------------------------------------------------------------- /sdr2mqtt/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [0.1.24] 8 | - Pulling in latest RTL_433 changes 9 | 10 | ## [0.1.23] 11 | - Nothing to see here, previous update was good, but some changes upstream happened. 12 | - verbosity of the rtl_433 messages changed, so not everything you are use to seeing at startup in the log are happening. 13 | 14 | ## [0.1.22] - Borked - Maybe 15 | ROLLED THIS BACK 16 | - Bump the version to update 433 Library to grab all the new protocols 17 | - Setting rain guages back to total_increasing to fix issue with my rain guages. 18 | 19 | ## [0.1.21] 20 | - Updating default Channel at init. Thanks @slappare and @th3dll for spotting it 21 | 22 | ## [0.1.20] 23 | - Fixing Wind speed unit of measurement 24 | - Fixing Rain sensor unit of measurement 25 | 26 | ## [0.1.18b] 27 | - Fixed issue where debug and whitelist_enable are incorrectly marked as being on when they are off. 28 | - When whitelist_enabled is on, any Device ID and Models not in whitelist will be listed in the log. This will 29 | only be listed once, until the add-on is restarted. Debug not required. 30 | * whitelist only prevents Home Assistant Auto Discovery - devices will still show up in MQTT * 31 | - If no instance is found, device will be assigned an instance of 0 to try and fix that 32 | add-on crash when no instance is found. 33 | - Fix bug where whitelist_enabled is sometimes ignored. 34 | - Switch to an actual logger for log messages. 35 | - Added device class to sensors 36 | - Removed any "unit of measurement" that was empty to prevent errors after 2023.5 update 37 | - state_class is now defined for each device instead of globally set to measurement to reduce errors after 2023.5 update. 38 | - auto discovery can now be turned off in the configuration for anyone that doesn't want devices to be auto added to home assistant 39 | - Some bug fixes by @doozers-do 40 | - Channel now defaults to A instead of 0 41 | - Channel sensor now defined as a enum device with options as A, B, or C 42 | 43 | 44 | ## [0.1.17b] 45 | - Bug fix with expire that didn't get caught in my local test 46 | 47 | ## [0.1.16b] 48 | - Bump to make sure latest 433_rtl is grabbed. 49 | - Brings in parity with Acurite Version 50 | 51 | ## [0.1.14b] 52 | - Bump to make sure latest 433_rtl is grabbed. 53 | 54 | ## [0.1.13b] 55 | ### Bug fixing 56 | - Removed null device ID from new channel definition 57 | 58 | ## [0.1.12b] 59 | ### Changed 60 | - Added Definition for Temp from Thermopro TP12 61 | 62 | ## [0.1.11] 63 | ### Changed 64 | - Adding back in frequnecey And adding Whitelist 65 | 66 | ## [0.1.9] 67 | ### Changed 68 | - Updated Autodiscovery to handle model values that were not in manufacturer-model format. 69 | 70 | 71 | ## [0.1.8] 72 | ### Added 73 | - Added last_seen enity which should be the last time Home Assistant saw an update from 74 | rtl_433. 75 | - Added Freq definition to autodiscovery which reports device frequency 76 | - Added channel definition to autodiscovery which report device channel 77 | - Added wind_max_km_h definition to autodiscovery 78 | 79 | ## [0.1.7] 80 | ### Added 81 | - Added consumption definition for gas meters 82 | - Update rtl_433 to version 21.12-63-g2d041b5d 83 | 84 | ## [0.1.6] 85 | ### Added 86 | - Added port to the config so you can use mwtt ports other than 1883 87 | 88 | ## [0.1.5] 89 | ### Added 90 | - Added new definition for light_klx value from Brersser 7in1 91 | 92 | ## [0.1.4] 93 | ### Changed 94 | - More Rain gauge bug fixes. 95 | 96 | ## [0.1.3] 97 | ### Changed 98 | - Updated Rain Gauge unit of measurements in device definition. 99 | 100 | ## [0.1.2] 101 | ### Added 102 | - Units to the config so you can set to metric or customary/imperial 103 | 104 | ## [0.1.0] 105 | ### Added 106 | - Initial Release - Testing a multipurpose add-on... 107 | -------------------------------------------------------------------------------- /acurite2mqtt/README.md: -------------------------------------------------------------------------------- 1 | # Home Assistant Add-on: Acurite2mqtt 2 | 3 | A Home Assistant addon for a software defined radio tuned to listen for 433MHz RF transmissions from Acurite Weather Sensors and republish the data via MQTT. 4 | 5 | ## Installation 6 | 7 | Add the repository URL under **Supervisor → Add-on store → ⋮ → Manage add-on repositories**: 8 | 9 | https://github.com/thejeffreystone/hassio_addons 10 | 11 | Then search for `Accurite to home Assistant` and install it. 12 | 13 | ## Configuration 14 | 15 | Example add-on configuration: 16 | 17 | ```yaml 18 | mqtt_host: 192.168.7.100 19 | mqtt_port: 1883 20 | mqtt_user: mqtt_user 21 | mqtt_password: mqtt_pass 22 | mqtt_topic: rtl_433 23 | mqtt_retain: 'true' 24 | protocol: '-R 11 -R 40 -R 41 -R 55 -R 74' 25 | whitelist_enable: true 26 | whitelist: 2169 6417 9143 6449 6000 3125 27 | expire_after: 60 28 | units: 'si' 29 | discovery_prefix: homeassistant 30 | discovery_interval: 600 31 | debug: false 32 | ``` 33 | 34 | ### Option: `mqtt_host` 35 | 36 | The `mqtt_host` option is the ip address of your mqtt server. If you are using the embeded server in Home Assistant just use your instances ip address. 37 | 38 | ### Option: `mqtt_port` 39 | 40 | The `mqtt_port` option is the port of your mqtt server. If you are using the embeded server in Home Assistant just leave this as 1883. 41 | 42 | ### Option: `mqtt_user` 43 | 44 | This is the username required to access your mqtt server. 45 | 46 | ### Option: `mqtt_password` 47 | 48 | The password of the mqtt user account. 49 | 50 | ### Option: `mqtt_topic` 51 | 52 | This si the topic your devices will use. 53 | 54 | ### Option: `mqtt_retain` 55 | 56 | Setting this to `true` means the mqtt server will keep your last value 57 | until it is changed. Setting it to `false` means the server will forget values after a period of time, 58 | so you will onyl see a valus it one has been sent recently. 59 | 60 | ### Option: `protocol` 61 | 62 | This determines what devices the software listens to. `-R 11 -R 40 -R 41 -R 55 -R 74` 63 | is the Accurite sensors. If the protocol is blank it will listen for all devices 64 | which may be noisy. 65 | 66 | For all possible protocols visit 67 | 68 | ### Option: `whitelist_enable` 69 | 70 | Set to `true` to enable filtering to allow only the delcared device id's to be processed. You may turn this off periodically 71 | to scan/acquire new device id's. But be cautious... any undesirable devices will need to be deleted from your configuration. 72 | 73 | ### Option: `whitelist` 74 | 75 | This is a `space separated` list of device id's that are desired to be received and processed. Any devices that are not in this 76 | list will be ignored (if whitelist_enables is set to true). 77 | 78 | ### Option: `expire_after` 79 | 80 | This is a `integer` value that will set an individual sensor entity to `unknown` if no payload is received within the specified seconds. The default value of 0 disables this feature. 81 | 82 | ### Option: `units` 83 | 84 | Sets the meansurement units. 85 | - `si` = Metric 86 | - `customary` = Imperial / Customary 87 | 88 | ### Option: `discovery_prefix` 89 | 90 | The mqtt prefix for autodiscovery. `homeassistant` should work. If you use another autodiscovery may not work. 91 | 92 | ### Option: `discovery_interval` 93 | 94 | `600` means Home Assisatnt will check for new devices every 600 seconds. 95 | 96 | ### Option: 'debug' 97 | 98 | Set debug to `true` if you want to see extra logging. This is noisy though, so I would only run it when actively troubleshooting. Leave at false all other times. 99 | 100 | ## Known issues and limitations 101 | 102 | - This add-on is totally beta. 103 | 104 | ## Changelog & Releases 105 | 106 | This repository keeps a change log using [GitHub's releases][releases] 107 | functionality. The format of the log is based on 108 | [Keep a Changelog][keepchangelog]. 109 | 110 | Releases are based on [Semantic Versioning][semver], and use the format 111 | of ``MAJOR.MINOR.PATCH``. In a nutshell, the version will be incremented 112 | based on the following: 113 | 114 | - ``MAJOR``: Incompatible or major changes. 115 | - ``MINOR``: Backwards-compatible new features and enhancements. 116 | - ``PATCH``: Backwards-compatible bugfixes and package updates. 117 | -------------------------------------------------------------------------------- /acurite2mqtt/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [0.3.26] 8 | - Pulling in latest RTL_433 changes 9 | 10 | ## [0.3.25] 11 | - Nothing to see here, previous update was good, but some changes upstream happened. 12 | - verbosity of the rtl_433 messages changed, so not everything you are use to seeing at startup in the log are happening. 13 | 14 | ## [0.3.24] - Borked...Maybe.... 15 | ROLLED THIS BACK 16 | - Bump the version to update 433 Library to grab all the new protocols 17 | - Setting rain guages back to total_increasing to fix issue with my rain guages. 18 | 19 | ## [0.3.23] 20 | - Updating default Channel at init. 21 | 22 | ## [0.3.22] 23 | - Fixing wind speed unit of measurement 24 | - Fixing Rain sensor unit of measurement 25 | 26 | 27 | ## [0.3.20b] 28 | - Fixed issue where debug and whitelist_enable are incorrectly marked as being on when they are off. 29 | - When whitelist_enabled is on, any Device ID and Models not in whitelist will be listed in the log. This will 30 | only be listed once, until the add-on is restarted. Debug not required. 31 | * whitelist only prevents Home Assistant Auto Discovery - devices will still show up in MQTT * 32 | - If no instance is found, device will be assigned an instance of 0 to try and fix that 33 | add-on crash when no instance is found. 34 | - Fix bug where whitelist_enabled is sometimes ignored. 35 | - Switch to an actual logger for log messages. 36 | - Added device class to sensors 37 | - Removed any "unit of measurement" that was empty to prevent errors after 2023.5 update 38 | - state_class is now defined for each device instead of globally set to measurement to reduce errors after 2023.5 update. 39 | - auto discovery can now be turned off in the configuration for anyone that doesn't want devices to be auto added to home assistant 40 | - Some bug fixes by @doozers-do 41 | - Channel now defaults to A instead of 0 42 | - Channel sensor now defined as a enum device with options as A, B, or C 43 | 44 | ## [0.3.19b] 45 | - Bump to make sure latest 433_rtl is grabbed. 46 | - New Statistic Attributes from @curtismuntz 47 | 48 | ## [0.3.18b] 49 | - Some major improvements/security enhancements thanks to @HalideGlow 50 | - Updated battery percentage value...thanks @TomWS1 51 | 52 | ## [0.3.16b] 53 | - Bump to make sure latest 433_rtl is grabbed. 54 | 55 | ## [0.3.15b] 56 | ### Bug fixing 57 | - Typo...I swear 58 | 59 | ## [0.3.14b] 60 | ### Bug fixing 61 | - Removed null device ID from new channel definition 62 | 63 | ## [0.3.13b] 64 | ### Added 65 | - Added Definition for Temp from Thermopro TP12 66 | 67 | ## [0.3.12b] 68 | ### Changed 69 | - Updated Autodiscovery to handle model values that were not in manufacturer-model format. 70 | 71 | ## [0.3.11b] 72 | ### Added 73 | - Added last_seen enity which should be the last time Home Assistant saw an update from 74 | rtl_433. 75 | - Added Freq definition to autodiscovery which reports device frequency 76 | - Added channel definition to autodiscovery which report device channel 77 | - Added wind_max_km_h definition to autodiscovery 78 | 79 | ## [0.3.10b] 80 | ### Added 81 | - Added consumption definition for gas meters 82 | - Update rtl_433 to version 21.12-63-g2d041b5d 83 | 84 | ## [0.3.9b] 85 | ### Added 86 | - Added port option in the config so now you can use other ports than the default 1883 87 | 88 | ## [0.3.8b] 89 | ### Added 90 | - Added new definition for light_klx value from Brersser 7in1 91 | 92 | ## [0.3.7b] 93 | ### Added 94 | - Added new whitelist option. Thanks to [@pdhruska](https://github.com/pdhruska) for the code. 95 | 96 | ## [0.3.6b] 97 | ### Added 98 | - Added a definition for pressure in inHG 99 | 100 | ## [0.3.5b] 101 | ### Changed 102 | - More Rain gauge bug fixes. 103 | 104 | ## [0.3.4b] 105 | ### Changed 106 | - Updated Rain Gauge unit of measurements in device definition. 107 | 108 | ## [0.3.3b] 109 | ### Added 110 | - Units to the config so you can set to metric or customary/imperial 111 | 112 | ## [0.3.2b] 113 | ### Added 114 | - Brightness defintion to attempt fix for #10. 115 | - KPa definition to auto discovery. 116 | 117 | ## [0.3.1b] 118 | ### Changed 119 | - Updated USB Condif to correct usb error. 120 | - Modified startup config 121 | - Thanks @staniel1881 for the assist! 122 | 123 | ## [0.3.1] 124 | ### Changed 125 | - Added Debug option to print messages to log 126 | - Reverted back to old method of naming devices 127 | 128 | ## [0.3.0] 129 | ### Added 130 | - this change log 131 | ### Changed 132 | - Removed the weather device classes from mappings 133 | - Switched Moisture mapping to humidity device class 134 | - Added support for Subtypes in an attempt to fix the issue with not reading all the 5n1 sensors. 135 | 136 | 137 | ## [0.2.0] 138 | ### Changed 139 | - Updated repro url to fix Add-on store links 140 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2024 Jeffrey Stone 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /sdr2mqtt/PROTOCOLS.md: -------------------------------------------------------------------------------- 1 | ## Supported device protocols 2 | 3 | [01] Silvercrest Remote Control 4 | [02] Rubicson, TFA 30.3197 or InFactory PT-310 Temperature Sensor 5 | [03] Prologue, FreeTec NC-7104, NC-7159-675 temperature sensor 6 | [04] Waveman Switch Transmitter 7 | [06]* ELV EM 1000 8 | [07]* ELV WS 2000 9 | [08] LaCrosse TX Temperature / Humidity Sensor 10 | [10] Acurite 896 Rain Gauge 11 | [11] Acurite 609TXC Temperature and Humidity Sensor 12 | [12] Oregon Scientific Weather Sensor 13 | [13]* Mebus 433 14 | [14]* Intertechno 433 15 | [15] KlikAanKlikUit Wireless Switch 16 | [16] AlectoV1 Weather Sensor (Alecto WS3500 WS4500 Ventus W155/W044 Oregon) 17 | [17] Cardin S466-TX2 18 | [18] Fine Offset Electronics, WH2, WH5, Telldus Temperature/Humidity/Rain Sensor 19 | [19] Nexus, FreeTec NC-7345, NX-3980, Solight TE82S, TFA 30.3209 temperature/humidity sensor 20 | [20] Ambient Weather F007TH, TFA 30.3208.02, SwitchDocLabs F016TH temperature sensor 21 | [21] Calibeur RF-104 Sensor 22 | [22] X10 RF 23 | [23] DSC Security Contact 24 | [24]* Brennenstuhl RCS 2044 25 | [25] Globaltronics GT-WT-02 Sensor 26 | [26] Danfoss CFR Thermostat 27 | [29] Chuango Security Technology 28 | [30] Generic Remote SC226x EV1527 29 | [31] TFA-Twin-Plus-30.3049, Conrad KW9010, Ea2 BL999 30 | [32] Fine Offset Electronics WH1080/WH3080 Weather Station 31 | [33] WT450, WT260H, WT405H 32 | [34] LaCrosse WS-2310 / WS-3600 Weather Station 33 | [35] Esperanza EWS 34 | [36] Efergy e2 classic 35 | [37]* Inovalley kw9015b, TFA Dostmann 30.3161 (Rain and temperature sensor) 36 | [38] Generic temperature sensor 1 37 | [39] WG-PB12V1 Temperature Sensor 38 | [40] Acurite 592TXR temp/humidity, 592TX temp, 5n1, 3n1, Atlas weather station, 515 fridge/freezer, 6045 lightning, 899 rain, 1190/1192 leak 39 | [41] Acurite 986 Refrigerator / Freezer Thermometer 40 | [42] HIDEKI TS04 Temperature, Humidity, Wind and Rain Sensor 41 | [43] Watchman Sonic / Apollo Ultrasonic / Beckett Rocket oil tank monitor 42 | [44] CurrentCost Current Sensor 43 | [45] emonTx OpenEnergyMonitor 44 | [46] HT680 Remote control 45 | [47] Conrad S3318P, FreeTec NC-5849-913 temperature humidity sensor 46 | [48] Akhan 100F14 remote keyless entry 47 | [49] Quhwa 48 | [50] OSv1 Temperature Sensor 49 | [51] Proove / Nexa / KlikAanKlikUit Wireless Switch 50 | [52] Bresser Thermo-/Hygro-Sensor 3CH 51 | [53] Springfield Temperature and Soil Moisture 52 | [54] Oregon Scientific SL109H Remote Thermal Hygro Sensor 53 | [55] Acurite 606TX Temperature Sensor 54 | [56] TFA pool temperature sensor 55 | [57] Kedsum Temperature & Humidity Sensor, Pearl NC-7415 56 | [58] Blyss DC5-UK-WH 57 | [59] Steelmate TPMS 58 | [60] Schrader TPMS 59 | [61]* LightwaveRF 60 | [62]* Elro DB286A Doorbell 61 | [63] Efergy Optical 62 | [64]* Honda Car Key 63 | [67] Radiohead ASK 64 | [68] Kerui PIR / Contact Sensor 65 | [69] Fine Offset WH1050 Weather Station 66 | [70] Honeywell Door/Window Sensor, 2Gig DW10/DW11, RE208 repeater 67 | [71] Maverick ET-732/733 BBQ Sensor 68 | [72]* RF-tech 69 | [73] LaCrosse TX141-Bv2, TX141TH-Bv2, TX141-Bv3, TX141W, TX145wsdth, (TFA, ORIA) sensor 70 | [74] Acurite 00275rm,00276rm Temp/Humidity with optional probe 71 | [75] LaCrosse TX35DTH-IT, TFA Dostmann 30.3155 Temperature/Humidity sensor 72 | [76] LaCrosse TX29IT, TFA Dostmann 30.3159.IT Temperature sensor 73 | [77] Vaillant calorMatic VRT340f Central Heating Control 74 | [78] Fine Offset Electronics, WH25, WH32, WH32B, WN32B, WH24, WH65B, HP1000, Misol WS2320 Temperature/Humidity/Pressure Sensor 75 | [79] Fine Offset Electronics, WH0530 Temperature/Rain Sensor 76 | [80] IBIS beacon 77 | [81] Oil Ultrasonic STANDARD FSK 78 | [82] Citroen TPMS 79 | [83] Oil Ultrasonic STANDARD ASK 80 | [84] Thermopro TP11 Thermometer 81 | [85] Solight TE44/TE66, EMOS E0107T, NX-6876-917 82 | [86] Wireless Smoke and Heat Detector GS 558 83 | [87] Generic wireless motion sensor 84 | [88] Toyota TPMS 85 | [89] Ford TPMS 86 | [90] Renault TPMS 87 | [91] inFactory, nor-tec, FreeTec NC-3982-913 temperature humidity sensor 88 | [92] FT-004-B Temperature Sensor 89 | [93] Ford Car Key 90 | [94] Philips outdoor temperature sensor (type AJ3650) 91 | [95] Schrader TPMS EG53MA4, PA66GF35 92 | [96] Nexa 93 | [97] ThermoPro TP08/TP12/TP20 thermometer 94 | [98] GE Color Effects 95 | [99] X10 Security 96 | [100] Interlogix GE UTC Security Devices 97 | [101]* Dish remote 6.3 98 | [102] SimpliSafe Home Security System (May require disabling automatic gain for KeyPad decodes) 99 | [103] Sensible Living Mini-Plant Moisture Sensor 100 | [104] Wireless M-Bus, Mode C&T, 100kbps (-f 868.95M -s 1200k) 101 | [105] Wireless M-Bus, Mode S, 32.768kbps (-f 868.3M -s 1000k) 102 | [106]* Wireless M-Bus, Mode R, 4.8kbps (-f 868.33M) 103 | [107]* Wireless M-Bus, Mode F, 2.4kbps 104 | [108] Hyundai WS SENZOR Remote Temperature Sensor 105 | [109] WT0124 Pool Thermometer 106 | [110] PMV-107J (Toyota) TPMS 107 | [111] Emos TTX201 Temperature Sensor 108 | [112] Ambient Weather TX-8300 Temperature/Humidity Sensor 109 | [113] Ambient Weather WH31E Thermo-Hygrometer Sensor, EcoWitt WH40 rain gauge, WS68 weather station 110 | [114] Maverick et73 111 | [115] Honeywell ActivLink, Wireless Doorbell 112 | [116] Honeywell ActivLink, Wireless Doorbell (FSK) 113 | [117]* ESA1000 / ESA2000 Energy Monitor 114 | [118]* Biltema rain gauge 115 | [119] Bresser Weather Center 5-in-1 116 | [120] Digitech XC-0324 / AmbientWeather FT005TH temp/hum sensor 117 | [121] Opus/Imagintronix XT300 Soil Moisture 118 | [122] FS20 / FHT 119 | [123]* Jansite TPMS Model TY02S 120 | [124] LaCrosse/ELV/Conrad WS7000/WS2500 weather sensors 121 | [125] TS-FT002 Wireless Ultrasonic Tank Liquid Level Meter With Temperature Sensor 122 | [126] Companion WTR001 Temperature Sensor 123 | [127] Ecowitt Wireless Outdoor Thermometer WH53/WH0280/WH0281A 124 | [128] DirecTV RC66RX Remote Control 125 | [129]* Eurochron temperature and humidity sensor 126 | [130] IKEA Sparsnas Energy Meter Monitor 127 | [131] Microchip HCS200/HCS300 KeeLoq Hopping Encoder based remotes 128 | [132] TFA Dostmann 30.3196 T/H outdoor sensor 129 | [133] Rubicson 48659 Thermometer 130 | [134] AOK Weather Station rebrand Holman Industries iWeather WS5029, Conrad AOK-5056, Optex 990018 131 | [135] Philips outdoor temperature sensor (type AJ7010) 132 | [136] ESIC EMT7110 power meter 133 | [137] Globaltronics QUIGG GT-TMBBQ-05 134 | [138] Globaltronics GT-WT-03 Sensor 135 | [139] Norgo NGE101 136 | [140] Elantra2012 TPMS 137 | [141] Auriol HG02832, HG05124A-DCF, Rubicson 48957 temperature/humidity sensor 138 | [142] Fine Offset Electronics/ECOWITT WH51, SwitchDoc Labs SM23 Soil Moisture Sensor 139 | [143] Holman Industries iWeather WS5029 weather station (older PWM) 140 | [144] TBH weather sensor 141 | [145] WS2032 weather station 142 | [146] Auriol AFW2A1 temperature/humidity sensor 143 | [147] TFA Drop Rain Gauge 30.3233.01 144 | [148] DSC Security Contact (WS4945) 145 | [149] ERT Standard Consumption Message (SCM) 146 | [150]* Klimalogg 147 | [151] Visonic powercode 148 | [152] Eurochron EFTH-800 temperature and humidity sensor 149 | [153] Cotech 36-7959, SwitchDocLabs FT020T wireless weather station with USB 150 | [154] Standard Consumption Message Plus (SCMplus) 151 | [155] Fine Offset Electronics WH1080/WH3080 Weather Station (FSK) 152 | [156] Abarth 124 Spider TPMS 153 | [157] Missil ML0757 weather station 154 | [158] Sharp SPC775 weather station 155 | [159] Insteon 156 | [160] ERT Interval Data Message (IDM) 157 | [161] ERT Interval Data Message (IDM) for Net Meters 158 | [162]* ThermoPro-TX2 temperature sensor 159 | [163] Acurite 590TX Temperature with optional Humidity 160 | [164] Security+ 2.0 (Keyfob) 161 | [165] TFA Dostmann 30.3221.02 T/H Outdoor Sensor 162 | [166] LaCrosse Technology View LTV-WSDTH01 Breeze Pro Wind Sensor 163 | [167] Somfy RTS 164 | [168] Schrader TPMS SMD3MA4 (Subaru) 3039 (Infiniti, Nissan, Renault) 165 | [169]* Nice Flor-s remote control for gates 166 | [170] LaCrosse Technology View LTV-WR1 Multi Sensor 167 | [171] LaCrosse Technology View LTV-TH Thermo/Hygro Sensor 168 | [172] Bresser Weather Center 6-in-1, 7-in-1 indoor, soil, new 5-in-1, 3-in-1 wind gauge, Froggit WH6000, Ventus C8488A 169 | [173] Bresser Weather Center 7-in-1, Air Quality PM2.5/PM10 7009970, CO2 7009977, HCHO/VOC 7009978 sensors 170 | [174] EcoDHOME Smart Socket and MCEE Solar monitor 171 | [175] LaCrosse Technology View LTV-R1, LTV-R3 Rainfall Gauge, LTV-W1/W2 Wind Sensor 172 | [176] BlueLine Innovations Power Cost Monitor 173 | [177] Burnhard BBQ thermometer 174 | [178] Security+ (Keyfob) 175 | [179] Cavius smoke, heat and water detector 176 | [180] Jansite TPMS Model Solar 177 | [181] Amazon Basics Meat Thermometer 178 | [182] TFA Marbella Pool Thermometer 179 | [183] Auriol AHFL temperature/humidity sensor 180 | [184] Auriol AFT 77 B2 temperature sensor 181 | [185] Honeywell CM921 Wireless Programmable Room Thermostat 182 | [186] Hyundai TPMS (VDO) 183 | [187] RojaFlex shutter and remote devices 184 | [188] Marlec Solar iBoost+ sensors 185 | [189] Somfy io-homecontrol 186 | [190] Ambient Weather WH31L (FineOffset WH57) Lightning-Strike sensor 187 | [191] Markisol, E-Motion, BOFU, Rollerhouse, BF-30x, BF-415 curtain remote 188 | [192] Govee Water Leak Detector H5054, Door Contact Sensor B5023 189 | [193] Clipsal CMR113 Cent-a-meter power meter 190 | [194] Inkbird ITH-20R temperature humidity sensor 191 | [195] RainPoint soil temperature and moisture sensor 192 | [196] Atech-WS308 temperature sensor 193 | [197] Acurite Grill/Meat Thermometer 01185M 194 | [198]* EnOcean ERP1 195 | [199] Linear Megacode Garage/Gate Remotes 196 | [200]* Auriol 4-LD5661/4-LD5972/4-LD6313 temperature/rain sensors 197 | [201] Unbranded SolarTPMS for trucks 198 | [202] Funkbus / Instafunk (Berker, Gira, Jung) 199 | [203] Porsche Boxster/Cayman TPMS 200 | [204] Jasco/GE Choice Alert Security Devices 201 | [205] Telldus weather station FT0385R sensors 202 | [206] LaCrosse TX34-IT rain gauge 203 | [207] SmartFire Proflame 2 remote control 204 | [208] AVE TPMS 205 | [209] SimpliSafe Gen 3 Home Security System 206 | [210] Yale HSA (Home Security Alarm), YES-Alarmkit 207 | [211] Regency Ceiling Fan Remote (-f 303.75M to 303.96M) 208 | [212] Renault 0435R TPMS 209 | [213] Fine Offset Electronics WS80 weather station 210 | [214] EMOS E6016 weatherstation with DCF77 211 | [215] Emax W6, rebrand Altronics x7063/4, Optex 990040/50/51, Orium 13093/13123, Infactory FWS-1200, Newentor Q9, Otio 810025, Protmex PT3390A, Jula Marquant 014331/32, TechniSat IMETEO X6 76-4924-00, Weather Station or temperature/humidity sensor 212 | [216]* ANT and ANT+ devices 213 | [217] EMOS E6016 rain gauge 214 | [218] Microchip HCS200/HCS300 KeeLoq Hopping Encoder based remotes (FSK) 215 | [219] Fine Offset Electronics WH45 air quality sensor 216 | [220] Maverick XR-30 BBQ Sensor 217 | [221] Fine Offset Electronics WN34 temperature sensor 218 | [222] Rubicson Pool Thermometer 48942 219 | [223] Badger ORION water meter, 100kbps (-f 916.45M -s 1200k) 220 | [224] GEO minim+ energy monitor 221 | [225] TyreGuard 400 TPMS 222 | [226] Kia TPMS (-s 1000k) 223 | [227] SRSmith Pool Light Remote Control SRS-2C-TX (-f 915M) 224 | [228] Neptune R900 flow meters 225 | [229] WEC-2103 temperature/humidity sensor 226 | [230] Vauno EN8822C 227 | [231] Govee Water Leak Detector H5054 228 | [232] TFA Dostmann 14.1504.V2 Radio-controlled grill and meat thermometer 229 | [233]* CED7000 Shot Timer 230 | [234] Watchman Sonic Advanced / Plus, Tekelek 231 | [235] Oil Ultrasonic SMART FSK 232 | [236] Gasmate BA1008 meat thermometer 233 | [237] Flowis flow meters 234 | [238] Wireless M-Bus, Mode T, 32.768kbps (-f 868.3M -s 1000k) 235 | [239] Revolt NC-5642 Energy Meter 236 | [240] LaCrosse TX31U-IT, The Weather Channel WS-1910TWC-IT 237 | [241] EezTire E618, Carchet TPMS, TST-507 TPMS 238 | [242]* Baldr / RainPoint rain gauge. 239 | [243] Celsia CZC1 Thermostat 240 | [244] Fine Offset Electronics WS90 weather station 241 | [245]* ThermoPro TX-2C Thermometer and Humidity sensor 242 | [246] TFA 30.3151 Weather Station 243 | [247] Bresser water leakage 244 | [248]* Nissan TPMS 245 | [249] Bresser lightning 246 | [250] Schou 72543 Day Rain Gauge, Motonet MTX Rain, MarQuant Rain Gauge 247 | [251] Fine Offset / Ecowitt WH55 water leak sensor 248 | [252] BMW Gen5 TPMS, multi-brand HUF, Continental, Schrader/Sensata 249 | [253] Watts WFHT-RF Thermostat -------------------------------------------------------------------------------- /acurite2mqtt/PROTOCOLS.md: -------------------------------------------------------------------------------- 1 | ## Supported device protocols 2 | 3 | [01] Silvercrest Remote Control 4 | [02] Rubicson, TFA 30.3197 or InFactory PT-310 Temperature Sensor 5 | [03] Prologue, FreeTec NC-7104, NC-7159-675 temperature sensor 6 | [04] Waveman Switch Transmitter 7 | [06]* ELV EM 1000 8 | [07]* ELV WS 2000 9 | [08] LaCrosse TX Temperature / Humidity Sensor 10 | [10] Acurite 896 Rain Gauge 11 | [11] Acurite 609TXC Temperature and Humidity Sensor 12 | [12] Oregon Scientific Weather Sensor 13 | [13]* Mebus 433 14 | [14]* Intertechno 433 15 | [15] KlikAanKlikUit Wireless Switch 16 | [16] AlectoV1 Weather Sensor (Alecto WS3500 WS4500 Ventus W155/W044 Oregon) 17 | [17] Cardin S466-TX2 18 | [18] Fine Offset Electronics, WH2, WH5, Telldus Temperature/Humidity/Rain Sensor 19 | [19] Nexus, FreeTec NC-7345, NX-3980, Solight TE82S, TFA 30.3209 temperature/humidity sensor 20 | [20] Ambient Weather F007TH, TFA 30.3208.02, SwitchDocLabs F016TH temperature sensor 21 | [21] Calibeur RF-104 Sensor 22 | [22] X10 RF 23 | [23] DSC Security Contact 24 | [24]* Brennenstuhl RCS 2044 25 | [25] Globaltronics GT-WT-02 Sensor 26 | [26] Danfoss CFR Thermostat 27 | [29] Chuango Security Technology 28 | [30] Generic Remote SC226x EV1527 29 | [31] TFA-Twin-Plus-30.3049, Conrad KW9010, Ea2 BL999 30 | [32] Fine Offset Electronics WH1080/WH3080 Weather Station 31 | [33] WT450, WT260H, WT405H 32 | [34] LaCrosse WS-2310 / WS-3600 Weather Station 33 | [35] Esperanza EWS 34 | [36] Efergy e2 classic 35 | [37]* Inovalley kw9015b, TFA Dostmann 30.3161 (Rain and temperature sensor) 36 | [38] Generic temperature sensor 1 37 | [39] WG-PB12V1 Temperature Sensor 38 | [40] Acurite 592TXR temp/humidity, 592TX temp, 5n1, 3n1, Atlas weather station, 515 fridge/freezer, 6045 lightning, 899 rain, 1190/1192 leak 39 | [41] Acurite 986 Refrigerator / Freezer Thermometer 40 | [42] HIDEKI TS04 Temperature, Humidity, Wind and Rain Sensor 41 | [43] Watchman Sonic / Apollo Ultrasonic / Beckett Rocket oil tank monitor 42 | [44] CurrentCost Current Sensor 43 | [45] emonTx OpenEnergyMonitor 44 | [46] HT680 Remote control 45 | [47] Conrad S3318P, FreeTec NC-5849-913 temperature humidity sensor 46 | [48] Akhan 100F14 remote keyless entry 47 | [49] Quhwa 48 | [50] OSv1 Temperature Sensor 49 | [51] Proove / Nexa / KlikAanKlikUit Wireless Switch 50 | [52] Bresser Thermo-/Hygro-Sensor 3CH 51 | [53] Springfield Temperature and Soil Moisture 52 | [54] Oregon Scientific SL109H Remote Thermal Hygro Sensor 53 | [55] Acurite 606TX Temperature Sensor 54 | [56] TFA pool temperature sensor 55 | [57] Kedsum Temperature & Humidity Sensor, Pearl NC-7415 56 | [58] Blyss DC5-UK-WH 57 | [59] Steelmate TPMS 58 | [60] Schrader TPMS 59 | [61]* LightwaveRF 60 | [62]* Elro DB286A Doorbell 61 | [63] Efergy Optical 62 | [64]* Honda Car Key 63 | [67] Radiohead ASK 64 | [68] Kerui PIR / Contact Sensor 65 | [69] Fine Offset WH1050 Weather Station 66 | [70] Honeywell Door/Window Sensor, 2Gig DW10/DW11, RE208 repeater 67 | [71] Maverick ET-732/733 BBQ Sensor 68 | [72]* RF-tech 69 | [73] LaCrosse TX141-Bv2, TX141TH-Bv2, TX141-Bv3, TX141W, TX145wsdth, (TFA, ORIA) sensor 70 | [74] Acurite 00275rm,00276rm Temp/Humidity with optional probe 71 | [75] LaCrosse TX35DTH-IT, TFA Dostmann 30.3155 Temperature/Humidity sensor 72 | [76] LaCrosse TX29IT, TFA Dostmann 30.3159.IT Temperature sensor 73 | [77] Vaillant calorMatic VRT340f Central Heating Control 74 | [78] Fine Offset Electronics, WH25, WH32, WH32B, WN32B, WH24, WH65B, HP1000, Misol WS2320 Temperature/Humidity/Pressure Sensor 75 | [79] Fine Offset Electronics, WH0530 Temperature/Rain Sensor 76 | [80] IBIS beacon 77 | [81] Oil Ultrasonic STANDARD FSK 78 | [82] Citroen TPMS 79 | [83] Oil Ultrasonic STANDARD ASK 80 | [84] Thermopro TP11 Thermometer 81 | [85] Solight TE44/TE66, EMOS E0107T, NX-6876-917 82 | [86] Wireless Smoke and Heat Detector GS 558 83 | [87] Generic wireless motion sensor 84 | [88] Toyota TPMS 85 | [89] Ford TPMS 86 | [90] Renault TPMS 87 | [91] inFactory, nor-tec, FreeTec NC-3982-913 temperature humidity sensor 88 | [92] FT-004-B Temperature Sensor 89 | [93] Ford Car Key 90 | [94] Philips outdoor temperature sensor (type AJ3650) 91 | [95] Schrader TPMS EG53MA4, PA66GF35 92 | [96] Nexa 93 | [97] ThermoPro TP08/TP12/TP20 thermometer 94 | [98] GE Color Effects 95 | [99] X10 Security 96 | [100] Interlogix GE UTC Security Devices 97 | [101]* Dish remote 6.3 98 | [102] SimpliSafe Home Security System (May require disabling automatic gain for KeyPad decodes) 99 | [103] Sensible Living Mini-Plant Moisture Sensor 100 | [104] Wireless M-Bus, Mode C&T, 100kbps (-f 868.95M -s 1200k) 101 | [105] Wireless M-Bus, Mode S, 32.768kbps (-f 868.3M -s 1000k) 102 | [106]* Wireless M-Bus, Mode R, 4.8kbps (-f 868.33M) 103 | [107]* Wireless M-Bus, Mode F, 2.4kbps 104 | [108] Hyundai WS SENZOR Remote Temperature Sensor 105 | [109] WT0124 Pool Thermometer 106 | [110] PMV-107J (Toyota) TPMS 107 | [111] Emos TTX201 Temperature Sensor 108 | [112] Ambient Weather TX-8300 Temperature/Humidity Sensor 109 | [113] Ambient Weather WH31E Thermo-Hygrometer Sensor, EcoWitt WH40 rain gauge, WS68 weather station 110 | [114] Maverick et73 111 | [115] Honeywell ActivLink, Wireless Doorbell 112 | [116] Honeywell ActivLink, Wireless Doorbell (FSK) 113 | [117]* ESA1000 / ESA2000 Energy Monitor 114 | [118]* Biltema rain gauge 115 | [119] Bresser Weather Center 5-in-1 116 | [120] Digitech XC-0324 / AmbientWeather FT005TH temp/hum sensor 117 | [121] Opus/Imagintronix XT300 Soil Moisture 118 | [122] FS20 / FHT 119 | [123]* Jansite TPMS Model TY02S 120 | [124] LaCrosse/ELV/Conrad WS7000/WS2500 weather sensors 121 | [125] TS-FT002 Wireless Ultrasonic Tank Liquid Level Meter With Temperature Sensor 122 | [126] Companion WTR001 Temperature Sensor 123 | [127] Ecowitt Wireless Outdoor Thermometer WH53/WH0280/WH0281A 124 | [128] DirecTV RC66RX Remote Control 125 | [129]* Eurochron temperature and humidity sensor 126 | [130] IKEA Sparsnas Energy Meter Monitor 127 | [131] Microchip HCS200/HCS300 KeeLoq Hopping Encoder based remotes 128 | [132] TFA Dostmann 30.3196 T/H outdoor sensor 129 | [133] Rubicson 48659 Thermometer 130 | [134] AOK Weather Station rebrand Holman Industries iWeather WS5029, Conrad AOK-5056, Optex 990018 131 | [135] Philips outdoor temperature sensor (type AJ7010) 132 | [136] ESIC EMT7110 power meter 133 | [137] Globaltronics QUIGG GT-TMBBQ-05 134 | [138] Globaltronics GT-WT-03 Sensor 135 | [139] Norgo NGE101 136 | [140] Elantra2012 TPMS 137 | [141] Auriol HG02832, HG05124A-DCF, Rubicson 48957 temperature/humidity sensor 138 | [142] Fine Offset Electronics/ECOWITT WH51, SwitchDoc Labs SM23 Soil Moisture Sensor 139 | [143] Holman Industries iWeather WS5029 weather station (older PWM) 140 | [144] TBH weather sensor 141 | [145] WS2032 weather station 142 | [146] Auriol AFW2A1 temperature/humidity sensor 143 | [147] TFA Drop Rain Gauge 30.3233.01 144 | [148] DSC Security Contact (WS4945) 145 | [149] ERT Standard Consumption Message (SCM) 146 | [150]* Klimalogg 147 | [151] Visonic powercode 148 | [152] Eurochron EFTH-800 temperature and humidity sensor 149 | [153] Cotech 36-7959, SwitchDocLabs FT020T wireless weather station with USB 150 | [154] Standard Consumption Message Plus (SCMplus) 151 | [155] Fine Offset Electronics WH1080/WH3080 Weather Station (FSK) 152 | [156] Abarth 124 Spider TPMS 153 | [157] Missil ML0757 weather station 154 | [158] Sharp SPC775 weather station 155 | [159] Insteon 156 | [160] ERT Interval Data Message (IDM) 157 | [161] ERT Interval Data Message (IDM) for Net Meters 158 | [162]* ThermoPro-TX2 temperature sensor 159 | [163] Acurite 590TX Temperature with optional Humidity 160 | [164] Security+ 2.0 (Keyfob) 161 | [165] TFA Dostmann 30.3221.02 T/H Outdoor Sensor 162 | [166] LaCrosse Technology View LTV-WSDTH01 Breeze Pro Wind Sensor 163 | [167] Somfy RTS 164 | [168] Schrader TPMS SMD3MA4 (Subaru) 3039 (Infiniti, Nissan, Renault) 165 | [169]* Nice Flor-s remote control for gates 166 | [170] LaCrosse Technology View LTV-WR1 Multi Sensor 167 | [171] LaCrosse Technology View LTV-TH Thermo/Hygro Sensor 168 | [172] Bresser Weather Center 6-in-1, 7-in-1 indoor, soil, new 5-in-1, 3-in-1 wind gauge, Froggit WH6000, Ventus C8488A 169 | [173] Bresser Weather Center 7-in-1, Air Quality PM2.5/PM10 7009970, CO2 7009977, HCHO/VOC 7009978 sensors 170 | [174] EcoDHOME Smart Socket and MCEE Solar monitor 171 | [175] LaCrosse Technology View LTV-R1, LTV-R3 Rainfall Gauge, LTV-W1/W2 Wind Sensor 172 | [176] BlueLine Innovations Power Cost Monitor 173 | [177] Burnhard BBQ thermometer 174 | [178] Security+ (Keyfob) 175 | [179] Cavius smoke, heat and water detector 176 | [180] Jansite TPMS Model Solar 177 | [181] Amazon Basics Meat Thermometer 178 | [182] TFA Marbella Pool Thermometer 179 | [183] Auriol AHFL temperature/humidity sensor 180 | [184] Auriol AFT 77 B2 temperature sensor 181 | [185] Honeywell CM921 Wireless Programmable Room Thermostat 182 | [186] Hyundai TPMS (VDO) 183 | [187] RojaFlex shutter and remote devices 184 | [188] Marlec Solar iBoost+ sensors 185 | [189] Somfy io-homecontrol 186 | [190] Ambient Weather WH31L (FineOffset WH57) Lightning-Strike sensor 187 | [191] Markisol, E-Motion, BOFU, Rollerhouse, BF-30x, BF-415 curtain remote 188 | [192] Govee Water Leak Detector H5054, Door Contact Sensor B5023 189 | [193] Clipsal CMR113 Cent-a-meter power meter 190 | [194] Inkbird ITH-20R temperature humidity sensor 191 | [195] RainPoint soil temperature and moisture sensor 192 | [196] Atech-WS308 temperature sensor 193 | [197] Acurite Grill/Meat Thermometer 01185M 194 | [198]* EnOcean ERP1 195 | [199] Linear Megacode Garage/Gate Remotes 196 | [200]* Auriol 4-LD5661/4-LD5972/4-LD6313 temperature/rain sensors 197 | [201] Unbranded SolarTPMS for trucks 198 | [202] Funkbus / Instafunk (Berker, Gira, Jung) 199 | [203] Porsche Boxster/Cayman TPMS 200 | [204] Jasco/GE Choice Alert Security Devices 201 | [205] Telldus weather station FT0385R sensors 202 | [206] LaCrosse TX34-IT rain gauge 203 | [207] SmartFire Proflame 2 remote control 204 | [208] AVE TPMS 205 | [209] SimpliSafe Gen 3 Home Security System 206 | [210] Yale HSA (Home Security Alarm), YES-Alarmkit 207 | [211] Regency Ceiling Fan Remote (-f 303.75M to 303.96M) 208 | [212] Renault 0435R TPMS 209 | [213] Fine Offset Electronics WS80 weather station 210 | [214] EMOS E6016 weatherstation with DCF77 211 | [215] Emax W6, rebrand Altronics x7063/4, Optex 990040/50/51, Orium 13093/13123, Infactory FWS-1200, Newentor Q9, Otio 810025, Protmex PT3390A, Jula Marquant 014331/32, TechniSat IMETEO X6 76-4924-00, Weather Station or temperature/humidity sensor 212 | [216]* ANT and ANT+ devices 213 | [217] EMOS E6016 rain gauge 214 | [218] Microchip HCS200/HCS300 KeeLoq Hopping Encoder based remotes (FSK) 215 | [219] Fine Offset Electronics WH45 air quality sensor 216 | [220] Maverick XR-30 BBQ Sensor 217 | [221] Fine Offset Electronics WN34 temperature sensor 218 | [222] Rubicson Pool Thermometer 48942 219 | [223] Badger ORION water meter, 100kbps (-f 916.45M -s 1200k) 220 | [224] GEO minim+ energy monitor 221 | [225] TyreGuard 400 TPMS 222 | [226] Kia TPMS (-s 1000k) 223 | [227] SRSmith Pool Light Remote Control SRS-2C-TX (-f 915M) 224 | [228] Neptune R900 flow meters 225 | [229] WEC-2103 temperature/humidity sensor 226 | [230] Vauno EN8822C 227 | [231] Govee Water Leak Detector H5054 228 | [232] TFA Dostmann 14.1504.V2 Radio-controlled grill and meat thermometer 229 | [233]* CED7000 Shot Timer 230 | [234] Watchman Sonic Advanced / Plus, Tekelek 231 | [235] Oil Ultrasonic SMART FSK 232 | [236] Gasmate BA1008 meat thermometer 233 | [237] Flowis flow meters 234 | [238] Wireless M-Bus, Mode T, 32.768kbps (-f 868.3M -s 1000k) 235 | [239] Revolt NC-5642 Energy Meter 236 | [240] LaCrosse TX31U-IT, The Weather Channel WS-1910TWC-IT 237 | [241] EezTire E618, Carchet TPMS, TST-507 TPMS 238 | [242]* Baldr / RainPoint rain gauge. 239 | [243] Celsia CZC1 Thermostat 240 | [244] Fine Offset Electronics WS90 weather station 241 | [245]* ThermoPro TX-2C Thermometer and Humidity sensor 242 | [246] TFA 30.3151 Weather Station 243 | [247] Bresser water leakage 244 | [248]* Nissan TPMS 245 | [249] Bresser lightning 246 | [250] Schou 72543 Day Rain Gauge, Motonet MTX Rain, MarQuant Rain Gauge 247 | [251] Fine Offset / Ecowitt WH55 water leak sensor 248 | [252] BMW Gen5 TPMS, multi-brand HUF, Continental, Schrader/Sensata 249 | [253] Watts WFHT-RF Thermostat -------------------------------------------------------------------------------- /acurite2mqtt/rtl_433_mqtt_hass.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | """MQTT Home Assistant auto discovery for rtl_433 events.""" 5 | 6 | # It is strongly recommended to run rtl_433 with "-C si" and "-M newmodel". 7 | 8 | # Needs Paho-MQTT https://pypi.python.org/pypi/paho-mqtt 9 | 10 | # Option: PEP 3143 - Standard daemon process library 11 | # (use Python 3.x or pip install python-daemon) 12 | # import daemon 13 | 14 | from __future__ import print_function, with_statement 15 | 16 | import json 17 | import os 18 | import time 19 | import paho.mqtt.client as mqtt 20 | import logging 21 | from datetime import datetime 22 | 23 | MQTT_HOST = os.environ['MQTT_HOST'] 24 | MQTT_PORT = os.environ['MQTT_PORT'] 25 | MQTT_USERNAME = os.environ['MQTT_USERNAME'] 26 | MQTT_PASSWORD = os.environ['MQTT_PASSWORD'] 27 | MQTT_TOPIC = os.environ['MQTT_TOPIC'] 28 | DISCOVERY_PREFIX = os.environ['DISCOVERY_PREFIX'] 29 | WHITELIST_ENABLE = os.environ['WHITELIST_ENABLE'] 30 | WHITELIST = os.environ['WHITELIST'] 31 | DISCOVERY_INTERVAL = os.environ['DISCOVERY_INTERVAL'] 32 | AUTO_DISCOVERY = os.environ['AUTO_DISCOVERY'] 33 | DEBUG = os.environ['DEBUG'] 34 | EXPIRE_AFTER = os.environ['EXPIRE_AFTER'] 35 | MQTT_RETAIN = os.environ['MQTT_RETAIN'] 36 | # Convert number environment variables to int 37 | MQTT_PORT = int(MQTT_PORT) 38 | DISCOVERY_INTERVAL = int(DISCOVERY_INTERVAL) 39 | 40 | discovery_timeouts = {} 41 | 42 | whitelist_list = WHITELIST.split() 43 | blocked = [] 44 | rate_limited = {} 45 | 46 | if DEBUG == "true": 47 | LOGLEVEL = os.environ.get('LOGLEVEL', 'DEBUG').upper() 48 | else: 49 | LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper() 50 | 51 | if WHITELIST_ENABLE == "true": 52 | whitelist_on = True 53 | else: 54 | whitelist_on = False 55 | 56 | if AUTO_DISCOVERY == "true": 57 | auto_discovery = True 58 | else: 59 | auto_discovery = False 60 | 61 | mappings = { 62 | "time": { 63 | "device_type": "sensor", 64 | "object_suffix": "last_seen", 65 | "config": { 66 | "device_class": "timestamp", 67 | "entity_category": "diagnostic", 68 | "name": "last_seen", 69 | "value_template": "{{ value }}" 70 | } 71 | }, 72 | "freq": { 73 | "device_type": "sensor", 74 | "object_suffix": "freq", 75 | "config": { 76 | "device_class": "frequency", 77 | "entity_category": "diagnostic", 78 | "name": "frequency", 79 | "unit_of_measurement": "MHz", 80 | "value_template": "{{ value }}" 81 | } 82 | }, 83 | "channel": { 84 | "device_type": "sensor", 85 | "object_suffix": "channel", 86 | "config": { 87 | "device_class": "enum", 88 | "name": "device_channel", 89 | "options": ["A", "B", "C"], 90 | "entity_category": "diagnostic", 91 | "value_template": "{{ value }}" 92 | } 93 | }, 94 | "temperature_C": { 95 | "device_type": "sensor", 96 | "object_suffix": "T", 97 | "config": { 98 | "device_class": "temperature", 99 | "state_class":"measurement", 100 | "name": "Temperature", 101 | "unit_of_measurement": "°C", 102 | "value_template": "{{ value|float }}" 103 | } 104 | }, 105 | "temperature_1_C": { 106 | "device_type": "sensor", 107 | "object_suffix": "T1", 108 | "config": { 109 | "device_class": "temperature", 110 | "state_class":"measurement", 111 | "name": "Temperature 1", 112 | "unit_of_measurement": "°C", 113 | "value_template": "{{ value|float }}" 114 | } 115 | }, 116 | "temperature_2_C": { 117 | "device_type": "sensor", 118 | "object_suffix": "T2", 119 | "config": { 120 | "device_class": "temperature", 121 | "state_class":"measurement", 122 | "name": "Temperature 2", 123 | "unit_of_measurement": "°C", 124 | "value_template": "{{ value|float }}" 125 | } 126 | }, 127 | "temperature_F": { 128 | "device_type": "sensor", 129 | "object_suffix": "F", 130 | "config": { 131 | "device_class": "temperature", 132 | "state_class":"measurement", 133 | "name": "Temperature", 134 | "unit_of_measurement": "°F", 135 | "assumed_state" : "True", 136 | "value_template": "{{ value|float }}" 137 | } 138 | }, 139 | "temperature_1_F": { 140 | "device_type": "sensor", 141 | "object_suffix": "F", 142 | "config": { 143 | "device_class": "temperature", 144 | "name": "Temperature 1", 145 | "unit_of_measurement": "°F", 146 | "assumed_state" : "True", 147 | "value_template": "{{ value|float }}" 148 | } 149 | }, 150 | "temperature_2_F": { 151 | "device_type": "sensor", 152 | "object_suffix": "F", 153 | "config": { 154 | "device_class": "temperature", 155 | "state_class":"measurement", 156 | "name": "Temperature 2", 157 | "unit_of_measurement": "°F", 158 | "assumed_state" : "True", 159 | "value_template": "{{ value|float }}" 160 | } 161 | }, 162 | 163 | "battery_ok": { 164 | "device_type": "sensor", 165 | "object_suffix": "B", 166 | "config": { 167 | "device_class": "battery", 168 | "name": "Battery", 169 | "unit_of_measurement": "%", 170 | "value_template": "{{ float(value) * 99 + 1 | int }}" 171 | } 172 | }, 173 | 174 | "humidity": { 175 | "device_type": "sensor", 176 | "object_suffix": "H", 177 | "config": { 178 | "device_class": "humidity", 179 | "state_class":"measurement", 180 | "name": "Humidity", 181 | "unit_of_measurement": "%", 182 | "value_template": "{{ value|float }}" 183 | } 184 | }, 185 | 186 | "moisture": { 187 | "device_type": "sensor", 188 | "object_suffix": "H", 189 | "config": { 190 | "device_class": "humidity", 191 | "state_class":"measurement", 192 | "name": "Moisture", 193 | "unit_of_measurement": "%", 194 | "value_template": "{{ value|float }}" 195 | } 196 | }, 197 | 198 | "pressure_hPa": { 199 | "device_type": "sensor", 200 | "object_suffix": "P", 201 | "config": { 202 | "device_class": "pressure", 203 | "state_class":"measurement", 204 | "name": "Pressure", 205 | "unit_of_measurement": "hPa", 206 | "value_template": "{{ value|float }}" 207 | } 208 | }, 209 | 210 | "pressure_kPa": { 211 | "device_type": "sensor", 212 | "object_suffix": "P", 213 | "config": { 214 | "device_class": "pressure", 215 | "state_class":"measurement", 216 | "name": "Pressure", 217 | "unit_of_measurement": "kPa", 218 | "value_template": "{{ value|float }}" 219 | } 220 | }, 221 | 222 | "pressure_inHg": { 223 | "device_type": "sensor", 224 | "object_suffix": "P", 225 | "config": { 226 | "device_class": "pressure", 227 | "state_class":"measurement", 228 | "name": "Pressure", 229 | "unit_of_measurement": "inHg", 230 | "value_template": "{{ value|float }}" 231 | } 232 | }, 233 | 234 | "wind_speed_km_h": { 235 | "device_type": "sensor", 236 | "object_suffix": "WS", 237 | "config": { 238 | "device_class": "wind_speed", 239 | "state_class":"measurement", 240 | "name": "Wind Speed", 241 | "unit_of_measurement": "km/h", 242 | "value_template": "{{ value|float }}" 243 | } 244 | }, 245 | 246 | "wind_avg_km_h": { 247 | "device_type": "sensor", 248 | "object_suffix": "WS", 249 | "config": { 250 | "device_class": "wind_speed", 251 | "name": "Wind Speed", 252 | "unit_of_measurement": "km/h", 253 | "value_template": "{{ value|float }}" 254 | } 255 | }, 256 | 257 | "wind_avg_mi_h": { 258 | "device_type": "sensor", 259 | "object_suffix": "WS", 260 | "config": { 261 | "device_class": "wind_speed", 262 | "state_class":"measurement", 263 | "name": "Wind Speed", 264 | "unit_of_measurement": "mph", 265 | "value_template": "{{ value|float }}" 266 | } 267 | }, 268 | 269 | "wind_avg_m_s": { 270 | "device_type": "sensor", 271 | "object_suffix": "WS", 272 | "config": { 273 | "device_class": "wind_speed", 274 | "state_class":"measurement", 275 | "name": "Wind Average", 276 | "unit_of_measurement": "km/h", 277 | "value_template": "{{ float(value|float) * 3.6 | round(2) }}" 278 | } 279 | }, 280 | 281 | "wind_speed_m_s": { 282 | "device_type": "sensor", 283 | "object_suffix": "WS", 284 | "config": { 285 | "device_class": "wind_speed", 286 | "name": "Wind Speed", 287 | "unit_of_measurement": "km/h", 288 | "value_template": "{{ float(value|float) * 3.6 }}" 289 | } 290 | }, 291 | 292 | "gust_speed_km_h": { 293 | "device_type": "sensor", 294 | "object_suffix": "GS", 295 | "config": { 296 | "name": "Gust Speed", 297 | "device_class": "wind_speed", 298 | "state_class":"measurement", 299 | "unit_of_measurement": "km/h", 300 | "value_template": "{{ value|float }}" 301 | } 302 | }, 303 | 304 | "wind_max_km_h": { 305 | "device_type": "sensor", 306 | "object_suffix": "GS", 307 | "config": { 308 | "name": "Wind max", 309 | "device_class": "wind_speed", 310 | "state_class":"measurement", 311 | "unit_of_measurement": "km/h", 312 | "value_template": "{{ value|float }}" 313 | } 314 | }, 315 | 316 | "wind_max_m_s": { 317 | "device_type": "sensor", 318 | "object_suffix": "GS", 319 | "config": { 320 | "device_class": "wind_speed", 321 | "state_class":"measurement", 322 | "name": "Wind max", 323 | "unit_of_measurement": "m/s", 324 | "value_template": "{{ float(value|float) * 3.6 | round(2) }}" 325 | } 326 | }, 327 | 328 | "gust_speed_m_s": { 329 | "device_type": "sensor", 330 | "object_suffix": "GS", 331 | "config": { 332 | "device_class": "wind_speed", 333 | "state_class":"measurement", 334 | "name": "Gust Speed", 335 | "unit_of_measurement": "km/h", 336 | "value_template": "{{ float(value|float) * 3.6 }}" 337 | } 338 | }, 339 | 340 | "wind_dir_deg": { 341 | "device_type": "sensor", 342 | "object_suffix": "WD", 343 | "config": { 344 | "name": "Wind Direction", 345 | "unit_of_measurement": "°", 346 | "value_template": "{{ value|float }}" 347 | } 348 | }, 349 | 350 | "rain_mm": { 351 | "device_type": "sensor", 352 | "object_suffix": "RT", 353 | "config": { 354 | "device_class": "precipitation", 355 | "state_class":"total_increasing", 356 | "name": "Rain Total", 357 | "unit_of_measurement": "mm", 358 | "value_template": "{{ value|float }}" 359 | } 360 | }, 361 | 362 | "rain_mm_h": { 363 | "device_type": "sensor", 364 | "object_suffix": "RR", 365 | "config": { 366 | "device_class": "precipitation_intensity", 367 | "state_class":"measurement", 368 | "name": "Rain Rate", 369 | "unit_of_measurement": "mm/h", 370 | "value_template": "{{ value|float }}" 371 | } 372 | }, 373 | 374 | "rain_in": { 375 | "device_type": "sensor", 376 | "object_suffix": "RT", 377 | "config": { 378 | "device_class": "precipitation", 379 | "state_class":"total_increasing", 380 | "name": "Rain Total", 381 | "unit_of_measurement": "in", 382 | "value_template": "{{ value|float }}" 383 | } 384 | }, 385 | 386 | "rain_rate_in_h": { 387 | "device_type": "sensor", 388 | "object_suffix": "RR", 389 | "config": { 390 | "device_class": "precipitation_intensity", 391 | "state_class":"measurement", 392 | "name": "Rain Rate", 393 | "unit_of_measurement": "in/h", 394 | "value_template": "{{ value|float }}" 395 | } 396 | }, 397 | 398 | "tamper": { 399 | "device_type": "binary_sensor", 400 | "object_suffix": "tamper", 401 | "config": { 402 | "device_class": "safety", 403 | "entity_category": "diagnostic", 404 | "force_update": "true", 405 | "payload_on": "1", 406 | "payload_off": "0" 407 | } 408 | }, 409 | 410 | "alarm": { 411 | "device_type": "binary_sensor", 412 | "object_suffix": "alarm", 413 | "config": { 414 | "device_class": "safety", 415 | "force_update": "true", 416 | "payload_on": "1", 417 | "payload_off": "0" 418 | } 419 | }, 420 | 421 | "rssi": { 422 | "device_type": "sensor", 423 | "object_suffix": "rssi", 424 | "config": { 425 | "device_class": "signal_strength", 426 | "state_class":"measurement", 427 | "unit_of_measurement": "dB", 428 | "entity_category": "diagnostic", 429 | "value_template": "{{ value|float|round(2) }}" 430 | } 431 | }, 432 | 433 | "snr": { 434 | "device_type": "sensor", 435 | "object_suffix": "snr", 436 | "config": { 437 | "device_class": "signal_strength", 438 | "state_class":"measurement", 439 | "entity_category": "diagnostic", 440 | "unit_of_measurement": "dB", 441 | "value_template": "{{ value|float|round(2) }}" 442 | } 443 | }, 444 | 445 | "noise": { 446 | "device_type": "sensor", 447 | "object_suffix": "noise", 448 | "config": { 449 | "device_class": "signal_strength", 450 | "state_class":"measurement", 451 | "unit_of_measurement": "dB", 452 | "value_template": "{{ value|float|round(2) }}" 453 | } 454 | }, 455 | 456 | "depth_cm": { 457 | "device_type": "sensor", 458 | "object_suffix": "D", 459 | "config": { 460 | "state_class":"measurement", 461 | "name": "Depth", 462 | "unit_of_measurement": "cm", 463 | "value_template": "{{ value|float }}" 464 | } 465 | }, 466 | 467 | "power_W": { 468 | "device_type": "sensor", 469 | "object_suffix": "watts", 470 | "config": { 471 | "device_class": "power", 472 | "state_class":"measurement", 473 | "name": "Power", 474 | "unit_of_measurement": "W", 475 | "value_template": "{{ value|float }}" 476 | } 477 | }, 478 | 479 | "lux": { 480 | "device_type": "sensor", 481 | "object_suffix": "lux", 482 | "config": { 483 | "device_class": "illuminance", 484 | "state_class":"measurement", 485 | "name": "Outside Luminancee", 486 | "unit_of_measurement": "lux", 487 | "value_template": "{{ value|int }}" 488 | } 489 | }, 490 | 491 | "light_klx": { 492 | "device_type": "sensor", 493 | "object_suffix": "light_klx", 494 | "config": { 495 | "device_class": "illuminance", 496 | "name": "Outside Luminancee", 497 | "unit_of_measurement": "lux", 498 | "value_template": "{{ value|int }}" 499 | } 500 | }, 501 | 502 | "brightness": { 503 | "device_type": "sensor", 504 | "object_suffix": "lux", 505 | "config": { 506 | "device_class": "illuminance", 507 | "state_class":"measurement", 508 | "name": "Brightness", 509 | "unit_of_measurement": "lux", 510 | "value_template": "{{ value|int }}" 511 | } 512 | }, 513 | 514 | "uv": { 515 | "device_type": "sensor", 516 | "object_suffix": "uv", 517 | "config": { 518 | "device_class": "irradiance", 519 | "state_class":"measurement", 520 | "name": "UV Index", 521 | "unit_of_measurement": "UV Index", 522 | "value_template": "{{ value|int }}" 523 | } 524 | }, 525 | 526 | "storm_dist": { 527 | "device_type": "sensor", 528 | "object_suffix": "stdist", 529 | "config": { 530 | "device_class":"distance", 531 | "state_class":"measurement", 532 | "name": "Lightning Distance", 533 | "unit_of_measurement": "mi", 534 | "value_template": "{{ value|int }}" 535 | } 536 | }, 537 | 538 | "strike_distance": { 539 | "device_type": "sensor", 540 | "object_suffix": "stdist", 541 | "config": { 542 | "device_class":"distance", 543 | "state_class":"measurement", 544 | "name": "Lightning Distance", 545 | "unit_of_measurement": "mi", 546 | "value_template": "{{ value|int }}" 547 | } 548 | 549 | }, 550 | "consumption": { 551 | "device_type": "meter", 552 | "object_suffix": "meter", 553 | "config": { 554 | "device_class": "gas", 555 | "name": "meter", 556 | "unit_of_measurement": "ft³", 557 | "value_template": "{{ value|float }}" 558 | } 559 | }, 560 | "strike_count": { 561 | "device_type": "sensor", 562 | "object_suffix": "strcnt", 563 | "config": { 564 | "name": "Lightning Strike Count", 565 | "state_class":"total_increasing", 566 | "value_template": "{{ value|int }}" 567 | } 568 | }, 569 | } 570 | 571 | 572 | def mqtt_connect(client, userdata, flags, rc): 573 | """Callback for MQTT connects.""" 574 | print("MQTT connected: " + mqtt.connack_string(rc)) 575 | client.publish("/".join([MQTT_TOPIC, "status"]), payload="online", qos=0, retain=True) 576 | if rc != 0: 577 | logging.critical("Could not connect. Error: " + str(rc)) 578 | else: 579 | client.subscribe("/".join([MQTT_TOPIC, "events"])) 580 | 581 | 582 | def mqtt_disconnect(client, userdata, rc): 583 | """Callback for MQTT disconnects.""" 584 | logging.critical("MQTT disconnected: " + mqtt.connack_string(rc)) 585 | 586 | 587 | def mqtt_message(client, userdata, msg): 588 | """Callback for MQTT message PUBLISH.""" 589 | try: 590 | # Decode JSON payload 591 | data = json.loads(msg.payload.decode()) 592 | logging.debug("Received Device Data from SDR and sent to MQTT: {} : {}".format(msg.topic, json.dumps(data))) 593 | bridge_event_to_hass(client, msg.topic, data) 594 | 595 | except json.decoder.JSONDecodeError: 596 | logging.warning("JSON decode error: " + msg.payload.decode()) 597 | return 598 | 599 | 600 | def sanitize(text): 601 | """Sanitize a name for Graphite/MQTT use.""" 602 | return (text 603 | .replace(" ", "_") 604 | .replace("/", "_") 605 | .replace(".", "_") 606 | .replace("&", "")) 607 | 608 | 609 | def publish_config(mqttc, topic, model, instance, channel, mapping): 610 | """Publish Home Assistant auto discovery data.""" 611 | global discovery_timeouts 612 | 613 | device_type = mapping["device_type"] 614 | object_id = "_".join([model.replace("-", "_"), instance]) 615 | object_suffix = mapping["object_suffix"] 616 | 617 | path = "/".join([DISCOVERY_PREFIX, device_type, object_id, object_suffix, "config"]) 618 | 619 | # check timeout 620 | now = time.time() 621 | if path in discovery_timeouts: 622 | if discovery_timeouts[path] > now: 623 | return 624 | 625 | discovery_timeouts[path] = now + DISCOVERY_INTERVAL 626 | 627 | config = mapping["config"].copy() 628 | config["state_topic"] = "/".join([MQTT_TOPIC, model, instance, channel, topic]) 629 | config["name"] = " ".join([model.replace("-", " "), instance, object_suffix]) 630 | config["unique_id"] = "".join(["rtl433", device_type, instance, object_suffix]) 631 | config["availability_topic"] = "/".join([MQTT_TOPIC, "status"]) 632 | config["expire_after"] = EXPIRE_AFTER 633 | 634 | # add Home Assistant device info 635 | 636 | # Check for missing manufacturer info 637 | if '-' in model: 638 | manufacturer, model = model.split("-", 1) 639 | else: 640 | manufacturer = 'Unknown' 641 | 642 | device = {} 643 | device["identifiers"] = instance 644 | device["name"] = instance 645 | device["model"] = model 646 | device["manufacturer"] = manufacturer 647 | config["device"] = device 648 | 649 | mqttc.publish(path, json.dumps(config), qos=0, retain=True) 650 | logging.debug("Device Config was saved to {} : {}".format(path,json.dumps(config))) 651 | 652 | 653 | def bridge_event_to_hass(mqttc, topic, data): 654 | """Translate some rtl_433 sensor data to Home Assistant auto discovery.""" 655 | 656 | if "model" not in data: 657 | # not a device event 658 | return 659 | model = sanitize(data["model"]) 660 | 661 | if "id" in data: 662 | instance = str(data["id"]) 663 | else: 664 | instance = 0 665 | 666 | if instance == 0: 667 | logging.warning("Device Id:{} doesn't appear to be a actual device. Skipping..".format(data['id'])) 668 | return 669 | 670 | if "channel" in data: 671 | channel = str(data["channel"]) 672 | else: 673 | channel = 'A' 674 | 675 | device = '{}-{}'.format(data['id'],data['model']) 676 | 677 | if (whitelist_on == True) and (instance not in whitelist_list): 678 | # Let's reduce the noise in the log and hide the duplicate notifications. 679 | if (instance not in blocked): 680 | logging.info("Device Id:{} Model: {} not in whitelist. Add to the Whitelist to create device in Home Assistant.".format(data['id'],data['model'])) 681 | blocked.append('{}'.format(data['id'])) 682 | return 683 | 684 | if (auto_discovery == True): 685 | # Let's reduce the noise in the log and hide the duplicate notifications. 686 | if (device not in rate_limited) or ( (datetime.now() - rate_limited[device]).seconds > 30 ): 687 | logging.debug('Device: {} - Creating/Updating device config in Home Assistant for Auto discovery.'.format(device)) 688 | rate_limited[device] = datetime.now() 689 | # detect known attributes 690 | for key in data.keys(): 691 | if key in mappings: 692 | publish_config(mqttc, key, model, instance, channel, mappings[key]) 693 | 694 | 695 | 696 | def rtl_433_bridge(): 697 | """Run a MQTT Home Assistant auto discovery bridge for rtl_433.""" 698 | logging.basicConfig(format='%(levelname)s:%(message)s', level=LOGLEVEL) 699 | 700 | mqttc = mqtt.Client() 701 | mqttc.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD) 702 | mqttc.on_connect = mqtt_connect 703 | mqttc.on_disconnect = mqtt_disconnect 704 | mqttc.on_message = mqtt_message 705 | 706 | mqttc.will_set("/".join([MQTT_TOPIC, "status"]), payload="offline", qos=0, retain=True) 707 | mqttc.connect_async(MQTT_HOST, MQTT_PORT, 60) 708 | mqttc.loop_start() 709 | 710 | logging.info('Started') 711 | 712 | while True: 713 | time.sleep(1) 714 | 715 | 716 | def run(): 717 | """Run main or daemon.""" 718 | # with daemon.DaemonContext(files_preserve=[sock]): 719 | # detach_process=True 720 | # uid 721 | # gid 722 | # working_directory 723 | rtl_433_bridge() 724 | 725 | 726 | if __name__ == "__main__": 727 | 728 | run() 729 | -------------------------------------------------------------------------------- /sdr2mqtt/rtl_433_mqtt_hass.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # coding=utf-8 3 | 4 | """MQTT Home Assistant auto discovery for rtl_433 events.""" 5 | 6 | # It is strongly recommended to run rtl_433 with "-C si" and "-M newmodel". 7 | 8 | # Needs Paho-MQTT https://pypi.python.org/pypi/paho-mqtt 9 | 10 | # Option: PEP 3143 - Standard daemon process library 11 | # (use Python 3.x or pip install python-daemon) 12 | # import daemon 13 | 14 | from __future__ import print_function, with_statement 15 | 16 | import json 17 | import os 18 | import time 19 | import paho.mqtt.client as mqtt 20 | import logging 21 | from datetime import datetime 22 | 23 | MQTT_HOST = os.environ['MQTT_HOST'] 24 | MQTT_PORT = os.environ['MQTT_PORT'] 25 | MQTT_USERNAME = os.environ['MQTT_USERNAME'] 26 | MQTT_PASSWORD = os.environ['MQTT_PASSWORD'] 27 | MQTT_TOPIC = os.environ['MQTT_TOPIC'] 28 | DISCOVERY_PREFIX = os.environ['DISCOVERY_PREFIX'] 29 | WHITELIST_ENABLE = os.environ['WHITELIST_ENABLE'] 30 | WHITELIST = os.environ['WHITELIST'] 31 | DISCOVERY_INTERVAL = os.environ['DISCOVERY_INTERVAL'] 32 | AUTO_DISCOVERY = os.environ['AUTO_DISCOVERY'] 33 | DEBUG = os.environ['DEBUG'] 34 | EXPIRE_AFTER = os.environ['EXPIRE_AFTER'] 35 | MQTT_RETAIN = os.environ['MQTT_RETAIN'] 36 | # Convert number environment variables to int 37 | MQTT_PORT = int(MQTT_PORT) 38 | DISCOVERY_INTERVAL = int(DISCOVERY_INTERVAL) 39 | 40 | discovery_timeouts = {} 41 | 42 | whitelist_list = WHITELIST.split() 43 | blocked = [] 44 | rate_limited = {} 45 | 46 | if DEBUG == "true": 47 | LOGLEVEL = os.environ.get('LOGLEVEL', 'DEBUG').upper() 48 | else: 49 | LOGLEVEL = os.environ.get('LOGLEVEL', 'INFO').upper() 50 | 51 | if WHITELIST_ENABLE == "true": 52 | whitelist_on = True 53 | else: 54 | whitelist_on = False 55 | 56 | if AUTO_DISCOVERY == "true": 57 | auto_discovery = True 58 | else: 59 | auto_discovery = False 60 | 61 | mappings = { 62 | "time": { 63 | "device_type": "sensor", 64 | "object_suffix": "last_seen", 65 | "config": { 66 | "device_class": "timestamp", 67 | "entity_category": "diagnostic", 68 | "name": "last_seen", 69 | "value_template": "{{ value }}" 70 | } 71 | }, 72 | "freq": { 73 | "device_type": "sensor", 74 | "object_suffix": "freq", 75 | "config": { 76 | "device_class": "frequency", 77 | "entity_category": "diagnostic", 78 | "name": "frequency", 79 | "unit_of_measurement": "MHz", 80 | "value_template": "{{ value }}" 81 | } 82 | }, 83 | "channel": { 84 | "device_type": "sensor", 85 | "object_suffix": "channel", 86 | "config": { 87 | "device_class": "enum", 88 | "name": "device_channel", 89 | "options": ["A", "B", "C"], 90 | "entity_category": "diagnostic", 91 | "value_template": "{{ value }}" 92 | } 93 | }, 94 | "temperature_C": { 95 | "device_type": "sensor", 96 | "object_suffix": "T", 97 | "config": { 98 | "device_class": "temperature", 99 | "state_class":"measurement", 100 | "name": "Temperature", 101 | "unit_of_measurement": "°C", 102 | "value_template": "{{ value|float }}" 103 | } 104 | }, 105 | "temperature_1_C": { 106 | "device_type": "sensor", 107 | "object_suffix": "T1", 108 | "config": { 109 | "device_class": "temperature", 110 | "state_class":"measurement", 111 | "name": "Temperature 1", 112 | "unit_of_measurement": "°C", 113 | "value_template": "{{ value|float }}" 114 | } 115 | }, 116 | "temperature_2_C": { 117 | "device_type": "sensor", 118 | "object_suffix": "T2", 119 | "config": { 120 | "device_class": "temperature", 121 | "state_class":"measurement", 122 | "name": "Temperature 2", 123 | "unit_of_measurement": "°C", 124 | "value_template": "{{ value|float }}" 125 | } 126 | }, 127 | "temperature_F": { 128 | "device_type": "sensor", 129 | "object_suffix": "F", 130 | "config": { 131 | "device_class": "temperature", 132 | "state_class":"measurement", 133 | "name": "Temperature", 134 | "unit_of_measurement": "°F", 135 | "assumed_state" : "True", 136 | "value_template": "{{ value|float }}" 137 | } 138 | }, 139 | "temperature_1_F": { 140 | "device_type": "sensor", 141 | "object_suffix": "F", 142 | "config": { 143 | "device_class": "temperature", 144 | "name": "Temperature 1", 145 | "unit_of_measurement": "°F", 146 | "assumed_state" : "True", 147 | "value_template": "{{ value|float }}" 148 | } 149 | }, 150 | "temperature_2_F": { 151 | "device_type": "sensor", 152 | "object_suffix": "F", 153 | "config": { 154 | "device_class": "temperature", 155 | "state_class":"measurement", 156 | "name": "Temperature 2", 157 | "unit_of_measurement": "°F", 158 | "assumed_state" : "True", 159 | "value_template": "{{ value|float }}" 160 | } 161 | }, 162 | 163 | "battery_ok": { 164 | "device_type": "sensor", 165 | "object_suffix": "B", 166 | "config": { 167 | "device_class": "battery", 168 | "name": "Battery", 169 | "unit_of_measurement": "%", 170 | "value_template": "{{ float(value) * 99 + 1 | int }}" 171 | } 172 | }, 173 | 174 | "humidity": { 175 | "device_type": "sensor", 176 | "object_suffix": "H", 177 | "config": { 178 | "device_class": "humidity", 179 | "state_class":"measurement", 180 | "name": "Humidity", 181 | "unit_of_measurement": "%", 182 | "value_template": "{{ value|float }}" 183 | } 184 | }, 185 | 186 | "moisture": { 187 | "device_type": "sensor", 188 | "object_suffix": "H", 189 | "config": { 190 | "device_class": "humidity", 191 | "state_class":"measurement", 192 | "name": "Moisture", 193 | "unit_of_measurement": "%", 194 | "value_template": "{{ value|float }}" 195 | } 196 | }, 197 | 198 | "pressure_hPa": { 199 | "device_type": "sensor", 200 | "object_suffix": "P", 201 | "config": { 202 | "device_class": "pressure", 203 | "state_class":"measurement", 204 | "name": "Pressure", 205 | "unit_of_measurement": "hPa", 206 | "value_template": "{{ value|float }}" 207 | } 208 | }, 209 | 210 | "pressure_kPa": { 211 | "device_type": "sensor", 212 | "object_suffix": "P", 213 | "config": { 214 | "device_class": "pressure", 215 | "state_class":"measurement", 216 | "name": "Pressure", 217 | "unit_of_measurement": "kPa", 218 | "value_template": "{{ value|float }}" 219 | } 220 | }, 221 | 222 | "pressure_inHg": { 223 | "device_type": "sensor", 224 | "object_suffix": "P", 225 | "config": { 226 | "device_class": "pressure", 227 | "state_class":"measurement", 228 | "name": "Pressure", 229 | "unit_of_measurement": "inHg", 230 | "value_template": "{{ value|float }}" 231 | } 232 | }, 233 | 234 | "wind_speed_km_h": { 235 | "device_type": "sensor", 236 | "object_suffix": "WS", 237 | "config": { 238 | "device_class": "wind_speed", 239 | "state_class":"measurement", 240 | "name": "Wind Speed", 241 | "unit_of_measurement": "km/h", 242 | "value_template": "{{ value|float }}" 243 | } 244 | }, 245 | 246 | "wind_avg_km_h": { 247 | "device_type": "sensor", 248 | "object_suffix": "WS", 249 | "config": { 250 | "device_class": "wind_speed", 251 | "name": "Wind Speed", 252 | "unit_of_measurement": "km/h", 253 | "value_template": "{{ value|float }}" 254 | } 255 | }, 256 | 257 | "wind_avg_mi_h": { 258 | "device_type": "sensor", 259 | "object_suffix": "WS", 260 | "config": { 261 | "device_class": "wind_speed", 262 | "state_class":"measurement", 263 | "name": "Wind Speed", 264 | "unit_of_measurement": "mph", 265 | "value_template": "{{ value|float }}" 266 | } 267 | }, 268 | 269 | "wind_avg_m_s": { 270 | "device_type": "sensor", 271 | "object_suffix": "WS", 272 | "config": { 273 | "device_class": "wind_speed", 274 | "state_class":"measurement", 275 | "name": "Wind Average", 276 | "unit_of_measurement": "km/h", 277 | "value_template": "{{ float(value|float) * 3.6 | round(2) }}" 278 | } 279 | }, 280 | 281 | "wind_speed_m_s": { 282 | "device_type": "sensor", 283 | "object_suffix": "WS", 284 | "config": { 285 | "device_class": "wind_speed", 286 | "name": "Wind Speed", 287 | "unit_of_measurement": "km/h", 288 | "value_template": "{{ float(value|float) * 3.6 }}" 289 | } 290 | }, 291 | 292 | "gust_speed_km_h": { 293 | "device_type": "sensor", 294 | "object_suffix": "GS", 295 | "config": { 296 | "name": "Gust Speed", 297 | "device_class": "wind_speed", 298 | "state_class":"measurement", 299 | "unit_of_measurement": "km/h", 300 | "value_template": "{{ value|float }}" 301 | } 302 | }, 303 | 304 | "wind_max_km_h": { 305 | "device_type": "sensor", 306 | "object_suffix": "GS", 307 | "config": { 308 | "name": "Wind max", 309 | "device_class": "wind_speed", 310 | "state_class":"measurement", 311 | "unit_of_measurement": "km/h", 312 | "value_template": "{{ value|float }}" 313 | } 314 | }, 315 | 316 | "wind_max_m_s": { 317 | "device_type": "sensor", 318 | "object_suffix": "GS", 319 | "config": { 320 | "device_class": "wind_speed", 321 | "state_class":"measurement", 322 | "name": "Wind max", 323 | "unit_of_measurement": "m/s", 324 | "value_template": "{{ float(value|float) * 3.6 | round(2) }}" 325 | } 326 | }, 327 | 328 | "gust_speed_m_s": { 329 | "device_type": "sensor", 330 | "object_suffix": "GS", 331 | "config": { 332 | "device_class": "wind_speed", 333 | "state_class":"measurement", 334 | "name": "Gust Speed", 335 | "unit_of_measurement": "km/h", 336 | "value_template": "{{ float(value|float) * 3.6 }}" 337 | } 338 | }, 339 | 340 | "wind_dir_deg": { 341 | "device_type": "sensor", 342 | "object_suffix": "WD", 343 | "config": { 344 | "name": "Wind Direction", 345 | "unit_of_measurement": "°", 346 | "value_template": "{{ value|float }}" 347 | } 348 | }, 349 | 350 | "rain_mm": { 351 | "device_type": "sensor", 352 | "object_suffix": "RT", 353 | "config": { 354 | "device_class": "precipitation", 355 | "state_class":"total_increasing", 356 | "name": "Rain Total", 357 | "unit_of_measurement": "mm", 358 | "value_template": "{{ value|float }}" 359 | } 360 | }, 361 | 362 | "rain_mm_h": { 363 | "device_type": "sensor", 364 | "object_suffix": "RR", 365 | "config": { 366 | "device_class": "precipitation_intensity", 367 | "state_class":"measurement", 368 | "name": "Rain Rate", 369 | "unit_of_measurement": "mm/h", 370 | "value_template": "{{ value|float }}" 371 | } 372 | }, 373 | 374 | "rain_in": { 375 | "device_type": "sensor", 376 | "object_suffix": "RT", 377 | "config": { 378 | "device_class": "precipitation", 379 | "state_class":"total_increasing", 380 | "name": "Rain Total", 381 | "unit_of_measurement": "in", 382 | "value_template": "{{ value|float }}" 383 | } 384 | }, 385 | 386 | "rain_rate_in_h": { 387 | "device_type": "sensor", 388 | "object_suffix": "RR", 389 | "config": { 390 | "device_class": "precipitation_intensity", 391 | "state_class":"measurement", 392 | "name": "Rain Rate", 393 | "unit_of_measurement": "in/h", 394 | "value_template": "{{ value|float }}" 395 | } 396 | }, 397 | 398 | "tamper": { 399 | "device_type": "binary_sensor", 400 | "object_suffix": "tamper", 401 | "config": { 402 | "device_class": "safety", 403 | "entity_category": "diagnostic", 404 | "force_update": "true", 405 | "payload_on": "1", 406 | "payload_off": "0" 407 | } 408 | }, 409 | 410 | "alarm": { 411 | "device_type": "binary_sensor", 412 | "object_suffix": "alarm", 413 | "config": { 414 | "device_class": "safety", 415 | "force_update": "true", 416 | "payload_on": "1", 417 | "payload_off": "0" 418 | } 419 | }, 420 | 421 | "rssi": { 422 | "device_type": "sensor", 423 | "object_suffix": "rssi", 424 | "config": { 425 | "device_class": "signal_strength", 426 | "state_class":"measurement", 427 | "unit_of_measurement": "dB", 428 | "entity_category": "diagnostic", 429 | "value_template": "{{ value|float|round(2) }}" 430 | } 431 | }, 432 | 433 | "snr": { 434 | "device_type": "sensor", 435 | "object_suffix": "snr", 436 | "config": { 437 | "device_class": "signal_strength", 438 | "state_class":"measurement", 439 | "entity_category": "diagnostic", 440 | "unit_of_measurement": "dB", 441 | "value_template": "{{ value|float|round(2) }}" 442 | } 443 | }, 444 | 445 | "noise": { 446 | "device_type": "sensor", 447 | "object_suffix": "noise", 448 | "config": { 449 | "device_class": "signal_strength", 450 | "state_class":"measurement", 451 | "unit_of_measurement": "dB", 452 | "value_template": "{{ value|float|round(2) }}" 453 | } 454 | }, 455 | 456 | "depth_cm": { 457 | "device_type": "sensor", 458 | "object_suffix": "D", 459 | "config": { 460 | "state_class":"measurement", 461 | "name": "Depth", 462 | "unit_of_measurement": "cm", 463 | "value_template": "{{ value|float }}" 464 | } 465 | }, 466 | 467 | "power_W": { 468 | "device_type": "sensor", 469 | "object_suffix": "watts", 470 | "config": { 471 | "device_class": "power", 472 | "state_class":"measurement", 473 | "name": "Power", 474 | "unit_of_measurement": "W", 475 | "value_template": "{{ value|float }}" 476 | } 477 | }, 478 | 479 | "lux": { 480 | "device_type": "sensor", 481 | "object_suffix": "lux", 482 | "config": { 483 | "device_class": "illuminance", 484 | "state_class":"measurement", 485 | "name": "Outside Luminancee", 486 | "unit_of_measurement": "lux", 487 | "value_template": "{{ value|int }}" 488 | } 489 | }, 490 | 491 | "light_klx": { 492 | "device_type": "sensor", 493 | "object_suffix": "light_klx", 494 | "config": { 495 | "device_class": "illuminance", 496 | "name": "Outside Luminancee", 497 | "unit_of_measurement": "lux", 498 | "value_template": "{{ value|int }}" 499 | } 500 | }, 501 | 502 | "brightness": { 503 | "device_type": "sensor", 504 | "object_suffix": "lux", 505 | "config": { 506 | "device_class": "illuminance", 507 | "state_class":"measurement", 508 | "name": "Brightness", 509 | "unit_of_measurement": "lux", 510 | "value_template": "{{ value|int }}" 511 | } 512 | }, 513 | 514 | "uv": { 515 | "device_type": "sensor", 516 | "object_suffix": "uv", 517 | "config": { 518 | "device_class": "irradiance", 519 | "state_class":"measurement", 520 | "name": "UV Index", 521 | "unit_of_measurement": "UV Index", 522 | "value_template": "{{ value|int }}" 523 | } 524 | }, 525 | 526 | "storm_dist": { 527 | "device_type": "sensor", 528 | "object_suffix": "stdist", 529 | "config": { 530 | "device_class":"distance", 531 | "state_class":"measurement", 532 | "name": "Lightning Distance", 533 | "unit_of_measurement": "mi", 534 | "value_template": "{{ value|int }}" 535 | } 536 | }, 537 | 538 | "strike_distance": { 539 | "device_type": "sensor", 540 | "object_suffix": "stdist", 541 | "config": { 542 | "device_class":"distance", 543 | "state_class":"measurement", 544 | "name": "Lightning Distance", 545 | "unit_of_measurement": "mi", 546 | "value_template": "{{ value|int }}" 547 | } 548 | 549 | }, 550 | "consumption": { 551 | "device_type": "meter", 552 | "object_suffix": "meter", 553 | "config": { 554 | "device_class": "gas", 555 | "name": "meter", 556 | "unit_of_measurement": "ft³", 557 | "value_template": "{{ value|float }}" 558 | } 559 | }, 560 | "strike_count": { 561 | "device_type": "sensor", 562 | "object_suffix": "strcnt", 563 | "config": { 564 | "name": "Lightning Strike Count", 565 | "state_class":"total_increasing", 566 | "value_template": "{{ value|int }}" 567 | } 568 | }, 569 | } 570 | 571 | 572 | def mqtt_connect(client, userdata, flags, rc): 573 | """Callback for MQTT connects.""" 574 | print("MQTT connected: " + mqtt.connack_string(rc)) 575 | client.publish("/".join([MQTT_TOPIC, "status"]), payload="online", qos=0, retain=True) 576 | if rc != 0: 577 | logging.critical("Could not connect. Error: " + str(rc)) 578 | else: 579 | client.subscribe("/".join([MQTT_TOPIC, "events"])) 580 | 581 | 582 | def mqtt_disconnect(client, userdata, rc): 583 | """Callback for MQTT disconnects.""" 584 | logging.critical("MQTT disconnected: " + mqtt.connack_string(rc)) 585 | 586 | 587 | def mqtt_message(client, userdata, msg): 588 | """Callback for MQTT message PUBLISH.""" 589 | try: 590 | # Decode JSON payload 591 | data = json.loads(msg.payload.decode()) 592 | logging.debug("Received Device Data from SDR and sent to MQTT: {} : {}".format(msg.topic, json.dumps(data))) 593 | bridge_event_to_hass(client, msg.topic, data) 594 | 595 | except json.decoder.JSONDecodeError: 596 | logging.warning("JSON decode error: " + msg.payload.decode()) 597 | return 598 | 599 | 600 | def sanitize(text): 601 | """Sanitize a name for Graphite/MQTT use.""" 602 | return (text 603 | .replace(" ", "_") 604 | .replace("/", "_") 605 | .replace(".", "_") 606 | .replace("&", "")) 607 | 608 | 609 | def publish_config(mqttc, topic, model, instance, channel, mapping): 610 | """Publish Home Assistant auto discovery data.""" 611 | global discovery_timeouts 612 | 613 | device_type = mapping["device_type"] 614 | object_id = "_".join([model.replace("-", "_"), instance]) 615 | object_suffix = mapping["object_suffix"] 616 | 617 | path = "/".join([DISCOVERY_PREFIX, device_type, object_id, object_suffix, "config"]) 618 | 619 | # check timeout 620 | now = time.time() 621 | if path in discovery_timeouts: 622 | if discovery_timeouts[path] > now: 623 | return 624 | 625 | discovery_timeouts[path] = now + DISCOVERY_INTERVAL 626 | 627 | config = mapping["config"].copy() 628 | config["state_topic"] = "/".join([MQTT_TOPIC, model, instance, channel, topic]) 629 | config["name"] = " ".join([model.replace("-", " "), instance, object_suffix]) 630 | config["unique_id"] = "".join(["rtl433", device_type, instance, object_suffix]) 631 | config["availability_topic"] = "/".join([MQTT_TOPIC, "status"]) 632 | config["expire_after"] = EXPIRE_AFTER 633 | 634 | # add Home Assistant device info 635 | 636 | # Check for missing manufacturer info 637 | if '-' in model: 638 | manufacturer, model = model.split("-", 1) 639 | else: 640 | manufacturer = 'Unknown' 641 | 642 | device = {} 643 | device["identifiers"] = instance 644 | device["name"] = instance 645 | device["model"] = model 646 | device["manufacturer"] = manufacturer 647 | config["device"] = device 648 | 649 | mqttc.publish(path, json.dumps(config), qos=0, retain=True) 650 | logging.debug("Device Config was saved to {} : {}".format(path,json.dumps(config))) 651 | 652 | 653 | def bridge_event_to_hass(mqttc, topic, data): 654 | """Translate some rtl_433 sensor data to Home Assistant auto discovery.""" 655 | 656 | if "model" not in data: 657 | # not a device event 658 | return 659 | model = sanitize(data["model"]) 660 | 661 | if "id" in data: 662 | instance = str(data["id"]) 663 | else: 664 | instance = 0 665 | 666 | if instance == 0: 667 | logging.warning("Device Id:{} doesn't appear to be a actual device. Skipping..".format(data['id'])) 668 | return 669 | 670 | if "channel" in data: 671 | channel = str(data["channel"]) 672 | else: 673 | channel = 'A' 674 | 675 | device = '{}-{}'.format(data['id'],data['model']) 676 | 677 | if (whitelist_on == True) and (instance not in whitelist_list): 678 | # Let's reduce the noise in the log and hide the duplicate notifications. 679 | if (instance not in blocked): 680 | logging.info("Device Id:{} Model: {} not in whitelist. Add to the Whitelist to create device in Home Assistant.".format(data['id'],data['model'])) 681 | blocked.append('{}'.format(data['id'])) 682 | return 683 | 684 | if (auto_discovery == True): 685 | # Let's reduce the noise in the log and hide the duplicate notifications. 686 | if (device not in rate_limited) or ( (datetime.now() - rate_limited[device]).seconds > 30 ): 687 | logging.debug('Device: {} - Creating/Updating device config in Home Assistant for Auto discovery.'.format(device)) 688 | rate_limited[device] = datetime.now() 689 | # detect known attributes 690 | for key in data.keys(): 691 | if key in mappings: 692 | publish_config(mqttc, key, model, instance, channel, mappings[key]) 693 | 694 | 695 | 696 | def rtl_433_bridge(): 697 | """Run a MQTT Home Assistant auto discovery bridge for rtl_433.""" 698 | logging.basicConfig(format='%(levelname)s:%(message)s', level=LOGLEVEL) 699 | 700 | mqttc = mqtt.Client() 701 | mqttc.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD) 702 | mqttc.on_connect = mqtt_connect 703 | mqttc.on_disconnect = mqtt_disconnect 704 | mqttc.on_message = mqtt_message 705 | 706 | mqttc.will_set("/".join([MQTT_TOPIC, "status"]), payload="offline", qos=0, retain=True) 707 | mqttc.connect_async(MQTT_HOST, MQTT_PORT, 60) 708 | mqttc.loop_start() 709 | 710 | logging.info('Started') 711 | 712 | while True: 713 | time.sleep(1) 714 | 715 | 716 | def run(): 717 | """Run main or daemon.""" 718 | # with daemon.DaemonContext(files_preserve=[sock]): 719 | # detach_process=True 720 | # uid 721 | # gid 722 | # working_directory 723 | rtl_433_bridge() 724 | 725 | 726 | if __name__ == "__main__": 727 | 728 | run() 729 | --------------------------------------------------------------------------------