autoSteve / acMqtt

CBus Automation Controller: Home Assistant, MQTT, Philips Hue and more (for the SHAC/NAC/AC2/NAC2)
GNU General Public License v3.0
15 stars 6 forks source link

Support for Binary Sensors? #5

Closed pbyrne-ms closed 2 years ago

pbyrne-ms commented 2 years ago

Hey Steve, would it be possible to include the ability to create binary sensors in Homeassistant from C-Bus groups?

Use case: I have some PIR sensors (non C-Bus types) integrated via a 4ch C-Bus Aux input, configured as bell-push inputs. If the standard electrical grade PIR senses motion, it closes the contact, activating a C-Bus lighting group. I have other scripts/functions in NAC/SHAC that act on the state of this group to do 'stuff'. When motion ceases, PIR opens contact, C-Bus group goes to Zero. Pretty simple.

I can expose these kinds of groups as switches in HA, but people can then mess with their state and turn them on/off (via HA), which I don't want. It would be cool if we could expose them as binary sensors, making them effectively read-only in HA.

For bonus points, a way to configure the group state text would be very cool, e.g 0="No Motion", 255="Motion Sensed". This could open up multiple options for other integrations, door sensors, window sensors etc..basically anything u might monitor in C-Bus via Aux units...

PS - i don't know how to apply labels! but please mark this as a feature request...

autoSteve commented 2 years ago

You owe me much beer @pbyrne-ms.

pbyrne-ms commented 2 years ago

Legend! many many thanks, and also for looking into the logging issue . I will arrange something! :)

autoSteve commented 2 years ago

Give it test to validate and I'll update the readme and close this as done. Cheers.

pbyrne-ms commented 2 years ago

Hi Steve, soz for the delay in getting back. Actually having some trouble getting this to work (for bsensor). The state of the sensor object in HA never changes. It's created etc, and gets the state text of the 'on' tag initially, but then just sits there and never changes after that...I'm still looking into it to see whats going on...

Also, noticed a small semi-related issue in the MQTT Event script.

`if app ~= 202 then -- Not trigger app pre = storage.get(sKey,-1) -- pretty sure this sets it back to nil, if it does not exist / or is brand new.. causing the logging statement to error... -- it throws : attempt to concatenate global 'pre' (a nil value)...., so I have defaulted the get to -1

if tonumber(val) then comp = string.format('%.3f', val) end if comp == pre then toSet = false if logging and not toSet then log('Not setting '..event.dst..' to '..comp..', previous value is '..pre) end end else toSet = false -- Don't send trigger control. One-way from MQTT to CBus... end

-- Send an event to publish to broker if changed if toSet then if logging then log('Setting '..event.dst..' to '..comp..', previous='..pre) end -- This line will ERROR if pre is nil...

server:sendto(event.dst.."/"..val, '127.0.0.1', 5432) en`

for a brand new object, it doesn't have a value, so the storage get returns nil, which cant be concatenated... I have defaulted the get to -1, which is what you set it to when its declared... works for me, but maybe there's a better way

pbyrne-ms commented 2 years ago

Ok, found the issue I think... the value template part of the autodiscovery template config payload needs to cast the value to a float first, before checking it is equal to zero.. Here is what I changed as a test, and it worked for me:

elseif dType == 'bsensor' then dType = 'sensor' payload = { ['stat_t'] = mqttReadTopic..alias..'/state', ['val_tpl'] = '{% if value | float == 0 %} '..off..' {% else %} '..on..' {% endif %}', } bSensor[aAlias] = true

Don't think I'll do a PR for this as perhaps I'm missing something, or the original intention, but the above works for me at least, if it helps...

So with these two things, it works as I think it's supposed to:

  1. Default the storage get 'pre' value to -1 in MQTT event script, to prevent issue on a brand new object that never had a value
  2. And cast the value to a float in the value template autodiscovery.

-P

autoSteve commented 2 years ago

Setting a default of -1 i.e. "pre = storage.get(sKey,-1)" would work for everything but string-based User Parameters, but good pick-up. Should be fixed in a different way.

Updated the suggested float conversion as-is. If it works for you then it works.

pbyrne-ms commented 2 years ago

Hi - the current code works perfectly as far as I can tell. Tried a few scenarios and could not break it!