Replacing MQTT and python Logic with Home Assistant

Hello,

Thanks for all your help.

I think I might like appdaemon better it gives me the flexibility of been able to perform some complex tasks better and easier.

Please can you kindly show me how to pass the payload and title of MQTT sensor trigger to an appdaemon so that I perform a lookup in a dictionary and then publish another from within the appdaemon.

Try
https://home-assistant.io/docs/ecosystem/appdaemon/

and
http://appdaemon.readthedocs.io/en/stable/

This is an excerpt of an app I have for decoding 433Mhz remote buttons

$ cat Four33MHz.py 


import appdaemon.appapi  as appapi

#
# App to set items on and off if corresponding 433MHz RF control received

class four33MHz(appapi.LoggedApp):

    def initialize(self):
        self.log("initialize", level="DEBUG")
        self.listen_state(self.remote2_buttonC,
                "sensor.received_433mhz", new="13071009")
        self.listen_state(self.remote2_buttonD,
                "sensor.received_433mhz", new="13071010")
        # Other states listened for here


    def remote2_buttonC(self, entity, attribute, old, new, kwargs):
        self.log("remote2_buttonC", level="DEBUG")
        self.turn_on("switch.computer_peripherals")

    def remote2_buttonD(self, entity, attribute, old, new, kwargs):
        self.log("remote2_buttonD", level="DEBUG")
        self.turn_off("switch.computer_peripherals")
        self.turn_off("group.office_lights")
# Other callbacks here

Obviously, you would set the new= to the payload of your mqtt message (which by now is the sensor state), and the callback would contain whatever logic you would like to decide which light to turn on.

I have been doing some reading of the link that you sent to me and I have set up my appdaemon thanks, I just have some questions on the above code

The listen_state callback function is listening to entity (sensor.received_433mhz), and if the new state value it received is (13071009) then call the remote2_buttonC function, I hope I’m right with this understanding?

Is it possible to set new=(sensor.received_433mhz state value [mqtt_message])? if it’s possible kindly share the syntax to use or I should use if like you did in the below quote for another solution but in this case it will be (self.sensor.received_433MHZ) instead of (self.input_select)?

I also have an issue, I realised that if I press my external button in succession, the sensor does not record the 2nd press this I attribute to the fact that the sensor is receiving the same button address does not see it as a state change, this now clarifies why you initially advised that I treat my button press as trigger. I have learnt and thanks so very much. Just for curiosity sake if there a way to reset the sensor values after every call?

Normally if I am to create a trigger automation the procedure is you create the

a) Trigger

b) Condition (optional)

c) Action.

But now if I want to use appdaemon to handle the action, I recon I should not create ACTION so as not to create a conflict in the flow am I right with this?

In the appdaemon for this case of the trigger what callback function should I use is it listen_state or listen_event?

This is now becoming very interesting, I really look forward to hearing from you.

That is correct.

Unfortunately not directly. Someone looked at creating an event from an MQTT message a few weeks ago and came to the conclusion that you couldn’t transfer the payload. So the only way at the moment is to have the MQTT payload stored in the state of a sensor, and then trigger off the sensor state.

There is a limitation in that the state can only be 255 characters, but that doesn’t seem to be a problem here.

You can use self.listen_state for any HA component, so an input_select will work fine too.

I think receiving an MQTT message to an MQTT sensor will trigger a state change callback, even if the state is the same. But if it doesn’t, then you can always set the state of the sensor back to an unknown value at the end of your callback using self.set_state()

Correct, If you use appdaemon, you are not using yaml automations at all, so there is no need for any automations in configuration.yaml.

As above, there is no way at the moment to transfer the payload from an MQTT message to an HA Event, so the message payload will need to be stored in the state of a sensor, and you will need a self.listen_state(...) call.

Hello, thanks so very much for your response it’s giving me the courage to keep going on.

I’m so sorry if I’ve been a bother but then for me understanding the basics is key, just a comment to your observation that you raised for the other fellow, did he look at the option of reading the mqtt topic, if you remember to help my case I had to read off instructions from the cmd_topic which is the not normal way of doing things but then it worked so if he can read the topic then he should go to the source of the mqtt and concatenate the information that he wants to read off the payload with the topic and then in the appdaemon he extracts his information and discards the payload info.

Just another question if I intend to use appdaemon for the mqtt publisher in the mqtt_light component I recon that I will not specify a cmd_topic in the yaml I will just create appdaemon to listen on this and if there is a change in the state the appdaemon can then call the mqtt call service to publish the message is this right?

One key note I also need to confirm from you is from appdaemon do I have access to all my python libraries?

I was just looking back at the thread, and somebody did solve the problem of passing the payload from the MQTT message. See

You could do it this way, but I’m not sure why. It is far easier, more readable, and future proof, to say self.turn_on("light.bedroom_table") than manage the mqtt message directly in the appdaemon callback. In that way, you could have any other kind of light that HA supports as your light.bedroom_table, and your script would still work.

Just an observation for you and someone else that might be reading this thread in future I took a critical look at the call, receiving the same message does not trigger the call back, I was able to set the state with

self.set_state(entity_id, state = “”)

I felt that resetting the state might not be the best idea as this I might clear out the instruction of another button so i decided to go back to the arduino to append the time (millis) of the call to the payload though it will be discarded but then it definitely confirms a change of state.