Git Product home page Git Product logo

Comments (13)

rct avatar rct commented on July 18, 2024 1

@gdt @digitaltopo - your interest/questions motivated me to put my script up in a repo as a proof of concept:

from rtl_433.

gdt avatar gdt commented on July 18, 2024

You have filed an issue in the rtl_433 repo. for that, you should be reading rtl_433_mqtt_relay and rtl4_433_mqtt_hass in examples. You may wish to modify them.

If a hass addon is not doing what you want, and you don't want to start reading python code here and using your own version, that should be addressed to that addons tracker.

from rtl_433.

gdt avatar gdt commented on July 18, 2024

I set the feedback tag to ask you to convert this into an issue that is about the contents of the rtl_433 repo. (if that's what you want to do vs closing and bringing it up with the addon).

from rtl_433.

rct avatar rct commented on July 18, 2024

That looks somewhat like the Honeywell/2GIG/etc. family of security sensors. You probably want to define a binary_sensor based off of contact_open.

My advice is not to use autodiscovery but to instead use manual MQTT configuration. There are two many things that autodiscovery doesn't know. Some sensors may use reed_open or alarm for the bit you are interested in, so the decoded state won't match. The autodiscovery script does have definitions for contact_open, reed_open, but they don't seem to get processed. I never tried to figure out why.

I like being able to set the device class to door, window, motion, etc. but have it defined as data someplace outside of home assistant's config_json files. There is more I could be doing to monitor availability like Zigbee2MQTT does.

I wound up defining all my sensors in a YAML file and then defined a Jinja2 template (same templating as home assistant) for the MQTT configuration. I process about 30 security sensors this way. If I need to update something I usually just need to change the template and run my script.

honeywell_sensors:
- esn: 123456
  name: "Front Door"
  type: "door"
  model: "Honeywell 5800mini"
  area: "Foyer"
  description: "Main Entrance Active Door"
  model_comment: "4th 5800mini"
  zone: 1


- esn: 654321
  name: "Guest Bedroom Window"
  type: "Window"
  model: "Versa Mini"
  manufacturer: "Versa"
  area: "Guest Bedroom"
  description: "Guest Bedroom East Window"
  model_comment: "Versa Mini, 1st from 2nd batch"
  channel: 10
  rtl_433_contact_field: "reed_open"
  zone: 18

This is what the template file looks like. It's quick and dirty so it defined everything for 1 sensor in 1 file.

---
#
# Test Honeywell Security 5800 jinja template.

mqtt:
  binary_sensor:
    - name: "{{ contact_short_name | title }}"  # TODO "Door"
      object_id: "{{ device_name_safe + '_' + contact_short_name }}" # TODO "front_door_contact" 
      unique_id: "{{ device_unique_id + '_' + contact_short_name }}" # "rtl_433_honeywell_123456_contact"
      state_topic: "{{ device_topic + '/' + contact_sub_topic }}"    # "rtl_433/+/devices/Honeywell-Security/8/123456/contact_open"
      payload_on: 1 # open
      payload_off: 0 # closed
      device_class: "{{ device_primary_class }}"
      force_update: true # Needed?
      expire_after: "{{ device_unavailable_seconds }}"
      device:
        name: "{{ device_name_pretty }}" # "Front Door Sensor"
        model: "{{ device_model }}"     # "5800 Mini"
        manufacturer: "{{ device_manufacturer }}"   # "Honeywell"
        identifiers: "{{ device_unique_id }}" # "rtl_433_honeywell_123456"
        suggested_area: "{{ device_area }}"   # "Foyer"

    - name: "Tamper"
      object_id: "{{ device_name_safe + '_tamper' }}" # "front_door_sensor_tamper"
      unique_id: "{{ device_unique_id + '_tamper' }}" # "rtl_433_honeywell_123456_tamper"
      state_topic: "{{ device_topic + '/tamper' }}"   # "rtl_433/+/devices/Honeywell-Security/8/123456/tamper"
      payload_on: 1 # open
      payload_off: 0 # closed
      device_class: safety
      force_update: true # Needed?
      expire_after: "{{ device_unavailable_seconds }}"
      device:
        identifiers: "{{ device_unique_id }}"

    # Event or Heartbeat, inverted to make event == True
    # TODO - should this be considered a diagnostic entity?
    - name: "Event"
      object_id: "{{ device_name_safe + '_event' }}" # "front_door_sensor_event"
      unique_id: "{{ device_unique_id + '_event' }}" #"rtl_433_honeywell_123456_event"
      state_topic: "{{ device_topic + '/heartbeat' }}"   # "rtl_433/+/devices/Honeywell-Security/8/123456/heartbeat"
      payload_on: 0 # 0 == event
      payload_off: 1 # 1 == heartbeat
      force_update: true # Needed?
      expire_after: "{{ device_unavailable_seconds }}"
      device:
        identifiers: "{{ device_unique_id }}"

  sensor:
    # Device undecoded status byte for diagnostic purposes
    # Honeywell-Security misnamed as "event", should be renamed in decoder
    - name: "Status"
      object_id: "{{ device_name_safe + '_status' }}" # "front_door_sensor_status"
      unique_id: "{{ device_unique_id + '_status' }}" # "rtl_433_honeywell_123456_event" 
      state_topic: "{{ device_topic + '/event' }}"   # "rtl_433/+/devices/Honeywell-Security/8/123456/event"
      force_update: true # Needed?
      expire_after: "{{ device_unavailable_seconds }}"
      entity_category: diagnostic
      # todo eventually should be disabled by default?
      device:
        identifiers: "{{ device_unique_id }}"

# TODO Everything below this line are generic rtl_433 sensors
    - name: "Battery"
      object_id: "{{ device_name_safe + '_battery' }}" # "front_door_sensor_battery"
      unique_id: "{{ device_unique_id + '_battery' }}" # "rtl_433_honeywell_123456_battery"
      state_topic: "{{ device_topic + '/battery_ok' }}"   # "rtl_433/+/devices/Honeywell-Security/8/123456/battery_ok"
      value_template: "{{ '{{' }} float(value|int) * 99 + 1 }}"
      device_class: battery
      unit_of_measurement: "%"
      force_update: true # Needed?
      expire_after: "{{ device_unavailable_seconds }}"
      entity_category: diagnostic
      device:
        identifiers: "{{ device_unique_id }}"

    - name: "RSSI"
      object_id: "{{ device_name_safe + '_rssi' }}" # "front_door_sensor_rssi"
      unique_id: "{{ device_unique_id + '_rssi' }}" # "rtl_433_honeywell_123456_rssi"
      state_topic: "{{ device_topic + '/rssi' }}" # "rtl_433/+/devices/Honeywell-Security/8/123456/rssi"
      value_template: "{{ '{{' }} value|float|round(2) }}"
      unit_of_measurement: "dB"
      device_class: signal_strength
      force_update: true # Needed?
      expire_after: "{{ device_unavailable_seconds }}"
      entity_category: diagnostic
      # todo eventually should be disabled by default?
      device:
        identifiers: "{{ device_unique_id }}"

    - name: "SNR"
      object_id: "{{ device_name_safe + '_snr' }}" # "front_door_sensor_snr"
      unique_id: "{{ device_unique_id + '_snr' }}" # "rtl_433_honeywell_123456_snr"
      state_topic: "{{ device_topic + '/snr' }}"   # "rtl_433/+/devices/Honeywell-Security/8/123456/snr"
      value_template: "{{ '{{' }} value|float|round(2) }}"
      unit_of_measurement: "dB"
      device_class: signal_strength
      force_update: true # Needed?
      expire_after: "{{ device_unavailable_seconds }}"
      entity_category: diagnostic
      # todo eventually should be disabled by default?
      device:
        identifiers: "{{ device_unique_id }}"

    - name: "noise"
      object_id: "{{ device_name_safe + '_noise' }}" # "front_door_sensor_noise"
      unique_id: "{{ device_unique_id + '_noise' }}" # "rtl_433_honeywell_123456_noise"
      state_topic: "{{ device_topic + '/noise' }}"   # "rtl_433/+/devices/Honeywell-Security/8/123456/noise"
      value_template: "{{ '{{' }} value|float|round(2) }}"
      unit_of_measurement: "dB"
      device_class: signal_strength
      force_update: true # Needed?
      expire_after: "{{ device_unavailable_seconds }}"
      entity_category: diagnostic
      enabled_by_default: false
      # todo eventually should be disabled by default?
      device:
        identifiers: "{{ device_unique_id }}"

from rtl_433.

rct avatar rct commented on July 18, 2024

Regarding the autodiscovery script in this repo (mqtt_hass), I had a note that for the Honeywell security sensors it was only generating binary_sensors for 'alarm' and 'tamper' fields. As I said above, the autodiscovery script does have definitions for contact_open, reed_open, but they don't seem to get processed. I never tried to figure out why.

from rtl_433.

gdt avatar gdt commented on July 18, 2024

very cool jinja2 stuff. can you post the command line to make a yaml from it (presumably you !include it). do you have to worry about having all mqtt in the same generated file?

Also, if you have wisdom about why you chose jinja2 instead of m4, I'd like to hear it. Yes, I know m4 is wicked old school.

from rtl_433.

rct avatar rct commented on July 18, 2024

I didn't post the script that runs Jinja2 because was a quick first pass at getting it working. It was good enough for me, but would be a bit embarrassing to post. I will put something together. I have some aspirations at building something to replace the autodiscovery stuff, but I get stuff that works well enough for me and don't get back to it.

As far as the code goes, it's one of those 98% scaffolding things. You load all the variables in a dict, and then call jinja2 to process the template. You get a string back and write it to a file. The interesting work is done in 2 lines.

The Home Assistant MQTT configuration doesn't have any real interdependencies. I like to have all the config for one sensor (or one integration) in one file. It works well with source code control. It also lets me fall back on old habits--If one sensor (on integration) needs to be disabled mv sensor1.yaml sensor1.yaml-

Yes, I know m4 from the old days, particularly when I wound up responsible for all the sendmail configs for my company because I was the one that did the internet firewall.

For this Jinja2 really makes sense because it is what Home Assistant uses and you have to climb that learning curve for Home Assistant (especially if you don't want to be an appliance operator). So anything I did there would be eaiser for Hass users to pick up. I've also adopted Ansible for configuration management, which uses YAML + Jinja2 templating.

Another bonus, if you have a Home Assistant install handy, you have easy access to a sort of REPL for Jinja2 in Developer Tools -> Templates.

from rtl_433.

rct avatar rct commented on July 18, 2024

Until I get around to cleaning up my script, see this blog & code I found for something close in terms of using Jinja2 to generate config files:

This looks like an updated version of the Jinja2 tutorial I found a few years back. It was also generating some router config files.

Same repo, this looks useful for defining custom Jinja2 functions (filters): This could be useful for simplifying the templates.

from rtl_433.

digitaltopo avatar digitaltopo commented on July 18, 2024

@rct that's a cool approach, thanks for the tips. What does the script look like to run populate the config from your sensors list yml (and how do you run it)?

Thanks @gdt for your feedback as well!

from rtl_433.

gdt avatar gdt commented on July 18, 2024

@digitaltopo I am also using manual config, more because I started that way, but I think @rct's approach is wise given the ability to customize.

Thanks for the pointers; that helps enough to point me on the right track. Writing a bit of code is fine, but I wasn't sure if there was already a program. My remaining worry is that I'd like (probably) to have some things in regular config and some generated. It seems like HA is not ok with mqtt:/sensor: in one place and in another, unioning the included lists/maps. But that's an HA problem, not an rtl_433 problem.

from rtl_433.

rct avatar rct commented on July 18, 2024

@digitaltopo - the script can be run anywhere that Python is installed with the YAML and Jinja2 modules, so windows, Linux, Mac.

I think you should be able run it on Home Assistant using Frenck's ssh/web terminal add-on (the community ssh, not the core one). Then you wouldn't have to copy any files over.

The add-on's Python doesn't have the Jinja2 module installed by default, but it could be added with apk add py3-jinja2

If I turn this into a little more of an app, rather than go the add-on route, I'd probably make it an AppDaemon package. AppDaemon has somewhat fallen out of favor as functionality in Home Assistant has increased. But AppDaemon would take care of a bit of the scaffolding and provide a sort of UI. I've got a toy app that subscribes to rtl_433 via MQTT and and publishing some stats to help me track the health of the RF environment.

from rtl_433.

rct avatar rct commented on July 18, 2024

It also occurred to me that PyScript (which I haven't used yet) could be another way to integrate something like this. I don't think it is sandboxed from the filesystem. You could define a service in PyScript and then use Home Assistant's developer tools to call it.

from rtl_433.

rct avatar rct commented on July 18, 2024

Thanks for the pointers; that helps enough to point me on the right track. Writing a bit of code is fine, but I wasn't sure if there was already a program.

Give me a bit, I'll put what I have up in a scratch repo as a PoC.

It seems like HA is not ok with mqtt:/sensor: in one place and in another, unioning the included lists/maps. But that's an HA problem, not an rtl_433 problem.

Ah, it sounds like you are tripping over Home Assistant's various !include_* directives and/or hitting the issue where those YAML blocks need a distinct key because they are going to get merged in a big dict (or whatever key value structure).

When I tried to follow Frenck's split config file guidance from a number of years ago I kept banging my head against stuff like that. It used a merged list for sensors.

sensor: !include_dir_list ../entities/sensors
binary_sensor: !include_dir_list ../entities/binary_sensors

I gave up on that and just use packages which avoids (most if not all) of the conflicts. This is also from Frenck's split config, but now I just put stuff in a file in integrations and don't use the entitles lists.

homeassistant:
  # load packages
  packages: !include_dir_named integrations

I think some of the changes they've made in the past few years that resulted in some legacy config styles (like template sensors) changing which domain things are defined under in which order have improved things. In the past I sometimes needed to stick in some throwaway identifier like sensor foo_package:

from rtl_433.

Related Issues (20)

Recommend Projects

  • React photo React

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

  • Vue.js photo Vue.js

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

  • Typescript photo Typescript

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

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

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

Recommend Topics

  • javascript

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

  • web

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

  • server

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

  • Machine learning

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

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

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

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.