dracoqcca / TCPLightingWebInterface-MQTT

Web App interface with MQTT: to control the "Connected by TCP" bulbs
0 stars 0 forks source link

how to publish status update to mqtt #1

Closed dracoqcca closed 5 years ago

dracoqcca commented 5 years ago

@sktaylortrash I deploy your solution I just wondering how can I publish a status to MQTT topic so your web app will take it and turn on light from Home assistant? Sorry for the newb question but i'm not programmer and trying to reverse engineering your php but my knowledge of the laguage is to low to understand how I can do it.

sktaylortrash commented 5 years ago

@dracoqcca it's understandable you can't figure it out. I never really documented this project as I actually hadn't thought anyone would use it.
As far as the subscriber side of this project goes there is a python script that runs to catch the MQTT messages and trigger the actions. You will need to have paho.mqtt.client installed in python. Then to generate the script you open the web page /MQTTGenerator.php this will create or update a script called mqtt_sub.py
You can run it however you like. I generally create a service for scripts like this so they always run on restart. https://tecadmin.net/setup-autorun-python-script-using-systemd/ My service definition looks like this.

[Unit] Description=MQTT Sub After=multi-user.target Conflicts=getty@tty1.service

[Service] Type=simple ExecStart=/usr/bin/python3 /home/pi/mqtt_sub.py StandardInput=tty-force

[Install] WantedBy=multi-user.target

sktaylortrash commented 5 years ago

For the publishing of state changes. As long as you have configured the MQTT section in config.inc.php any states changed by MQTT should be published. Additionally the state topic is set to retained so that if the web interface is restarted the state of the bulbs should be retained as well.

Additionally there is a php page called mqttstate.php that will double check the current state of a bulb and update MQTT accordingly. I use this because I still sometimes control the bulbs with the Android app and it doesn't automatically publish changes to MQTT. I run it as a cron job every 5 minutes
*/5 * * * * lynx -dump https://lighting.taylortrash.com/mqttstate.php

dracoqcca commented 5 years ago

Thanks for this precious information. I've try to publish a state change using either MQTT client and Home assistant. i'm seeing it in MQTT but no status change occur to my light. I'm using tasmota on sonoff basic and to publish a status change we have to use a different topic. that's why I though I may need something different to have your app pick it up.

so in ordre to have it pick it up I need the client paho.mqtt.client right? it's able to publish state whitout it but need thie to subscripe and see the status change if I understand well?

sktaylortrash commented 5 years ago

Correct paho.mqtt.client needs to be installed for you to push changes to the lights. The topics unfortunately can't have much in the way of customization on my end. They basically follow the format of light/<room-name>/<light-name>/<UniqueBulbID>/ So for example my light at the back door is the room BackEntrance and has a unique ID of 216773570733040739 so the state topic looks like: light/RearEntrance/BackDoor/216773570733040739/status

There's 4 topics that are used

On/Off State: light/<room-name>/<light-name>/<UniqueBulbID>/status
On/Off Command: light/<room-name>/<light-name>/<UniqueBulbID>/switch
Brightness State: light/<room-name>/<light-name>/<UniqueBulbID>/brightness
Brightness Command: light/<room-name>/<light-name>/<UniqueBulbID>/brightness/set

so my Home Assistant YAML for a light looks like:

  - platform: mqtt
    name: "Back Entry"
    state_topic: "light/RearEntrance/BackDoor/216773570733040739/status"
    command_topic: "light/RearEntrance/BackDoor/216773570733040739/switch"
    brightness_state_topic: "light/RearEntrance/BackDoor/216773570733040739/brightness"
    brightness_command_topic: "light/RearEntrance/BackDoor/216773570733040739/brightness/set"
    brightness_scale: 100
    qos: 0
    payload_on: "1"
    payload_off: "0"
    optimistic: false

As I said I sort of only wrote this for my implementation. So other than the unique bulb ID some of the hardcoded topic stuff could definitely be changed in the code. Mostly that would need to be changed in the MQTTGenerator.php file as that's where the topic definition takes place. That being said I've been using the code as is with Home Assistant and Node-Red for almost 2 years without issue.

Definitely if there were interest I could look into making some of that more end user configurable.

dracoqcca commented 5 years ago

Thanks for all those usefull answer I will check what I can do I'm running your app in a docker so I will check to add the paho.mqtt.client.

I've try to use the Greewave component in Home assistant and i'm not able to make it work. With MQTT I think it will be easier. Thank you for your time I will check that and let you know if i'm able to customized for me

dracoqcca commented 5 years ago

I've managed to generate the mqtt_sub.py but for some reason it's still not picking up the status change of the topics light/RearEntrance/BackDoor/216773570733040739/switch and light/RearEntrance/BackDoor/216773570733040739/brightness/set. Quickly like this I didn't find any hard coded link to your lights or URL in the code but as I said I'm not a programmer maybe I miss something. I'm a sys admin so I have some basic knowledge of programming languages more scripting I do understand the logic behind it and able to find things in it but I sometime it's to much for my basic knowledge.

sktaylortrash commented 5 years ago

you need to look in mqtt_sub.py to see what your unique topics are the one I posted is just an example of one of my bulbs

dracoqcca commented 5 years ago

yes I've understand that and in my mqtt_sub.py i've got like this light/Salon/Plafond/216507407315584551/switch and light/Salon/Plafond/216507407315584551/brightness/set so to me it has detected it. I just relalised that i've forgot to set as a service the python script. Now it is working thank you so much for all your support. by the way you need requests also as python module if you want to document it.

sktaylortrash commented 5 years ago

@dracoqcca just a heads up I pushed a rather large update to my main repository. It allows some customization of the topics. Additionally it provides a new script that works with Home Assistant's Auto Discovery feature so you don't have to mess with YAML

dracoqcca commented 5 years ago

Thanks for the head's up and thanks for all the hard work done on this.

dracoqcca commented 5 years ago

@sktaylortrash I've try it works fine. Only thing I'm running the web server as a docker so it create the URL with localhost. If you can add to the configuration file a way to set the URL of the web interface that could help other to create it more easily. I've done the manual modification for me it's fine but since you are modifying it it could be something nice to have. The other thing that I have is some of my scene/light have space in it so the name of the function in python is not working. I've manage to replace the space with _ and everything is working as expected. You may want to check that also if you want some other users to use it. Last thing maybe add links to the main page so users can click on links to generate the python scripts and see the pages that you've added. Thanks a lot to have take times to help me understand your script and modifying it's really appreciate.

sktaylortrash commented 5 years ago

@dracoqcca the url of the web interface is already configurable using the LOCAL_URL and EXTERNAL_DDNS_URL variables in config.inc.php Does it not work to set those for you?

I can definitely add the links and will look into stripping the spaces. Thanks for the input

dracoqcca commented 5 years ago

Hooo my bad I don't use runSchedule so I over look this settings. should be fine now. thanks

sktaylortrash commented 5 years ago

@dracoqcca per your recommendation, spaces in names are now removed for all instances except the Device Name provided to Home Assistant in the discovery module. Additionally I have added links to the header for MQTT Generation and State publishing. Thanks for the valuable input.

dracoqcca commented 5 years ago

Thanks I've created a pull request as there still have a space in the scene name at the bottom of the script. Thanks to you for all your time on this. I wasn't expect you to modify the code that was working for over 2 years now thank you so much.

Last nice to have would be to publish the unavailable stat maybe in MQTT? So if a light is close using the switch in the house you will know it in Home assistant.

sktaylortrash commented 5 years ago

@dracoqcca good catch I'm not surprised I missed one. That was a lot of variables to update. For a light unavailable I believe the Last Will and Testament topic is the one I need but I haven't quite figured out how that works yet

sktaylortrash commented 5 years ago

@dracoqcca figured out the availability thing if you grab the newest code mqttstate.php and mqttdiscovery.php now reference a new topic availability_topic ending in LWT. So if you add a line to your YAML like availability_topic: "light/RearEntrance/BackDoor/216773570733040739/LWT"

mqttstate will publish a payload of offline if the hub can't see the device or online if it can. The delay on changes will be affected by how long the hub takes to see that change in availability and then how long you go between running mqttstate.

dracoqcca commented 5 years ago

@sktaylortrash Thanks for the quick trun around you're awsome.

I have a bug though for some reason it's publishing the 3 topics but only for one of my devices the other one it's only publishing two topics. I've change the order of the topics in mqttstate.php and the LWT appeare which I move first in the list but the last one which is now the brightness is no longer publishing. I though it was maybe something with the length that my device name so i've rename it for shorter name but got same result. Any idea? Thanks again

dracoqcca commented 5 years ago

image

There is a screen shot of the topics that I've see. One of the difference is that it is a group of 5 light bulbs if that could help you

sktaylortrash commented 5 years ago

Just to confirm is the one with only 2 the group(virtual device)? I just grouped a couple extra lights to test on mine and all 3 topics were created for the new group, old ones were fine. I know that the brightness topic doesn't always publish if a bulb is offline. Any chance that is happening. Another random thing to try would be turning on all the bulbs and running mqttstate just in case a bulb has to be turned on for the topic to be created. Brightness is kind of a weird one in that the bridge returns not only 1-100 but also NULL as a value I currently have 20 bulbs and 3 groups and they're all publishing without issue so I'm kind of at a loss. They won't all fit on the screen but you can see most of my output in the image below. Topics

dracoqcca commented 5 years ago

that's weird then it is now the brightness because i've moved the LWT in the code at the top like this: foreach($DEVICES as $device){ $DeviceName = str_replace(' ', '_', $device['name']); if( isset($device['offline']) && $device['offline'] == 1){ $LWT = "offline"; } else {$LWT = "online";} $mqtt->publish($MQTT_prefix.'/'.$RoomName.'/'.$DeviceName.'/'.$device['did'].'/LWT', $LWT); $mqtt->publish($MQTT_prefix.'/'.$RoomName.'/'.$DeviceName.'/'.$device['did'].'/status', $device['state']); $mqtt->publish($MQTT_prefix.'/'.$RoomName.'/'.$DeviceName.'/'.$device['did'].'/brightness', $device['level']); echo $DeviceName.': On-Off State: '.$device["state"].', Brightness: '.$device["level"].', Online Status: '.$LWT.'<br/>'; but if I tested it the way you've put it at first it is the LWT that is not publishing like this: image

but i'm seeing everything on the webpage though

image as you can see it is not the offline one that i'm not seeing the topics. I've try to restart my mosquitto servic to see if it was my broker for some reason but no I've got the same result. I've just try it again like this: if( isset($device['offline']) && $device['offline'] == 1){ $LWT = "offline"; } else {$LWT = "online";} $mqtt->publish($MQTT_prefix.'/'.$RoomName.'/'.$DeviceName.'/'.$device['did'].'/LWT', $LWT); $mqtt->publish($MQTT_prefix.'/'.$RoomName.'/'.$DeviceName.'/'.$device['did'].'/brightness', $device['level']); $mqtt->publish($MQTT_prefix.'/'.$RoomName.'/'.$DeviceName.'/'.$device['did'].'/status', $device['state']); echo $DeviceName.': On-Off State: '.$device["state"].' Brightness:'.$device["level"].' Online Status '.$LWT.'<br/>'; ans then it is the Status that is not showing image I don'T get what I'm doing wrong.

dracoqcca commented 5 years ago

I've try to clone your repo to see if it's something that I've done and got the same result

sktaylortrash commented 5 years ago

hmm do me a favour and try adding a sleep command to mqttstate like

$mqtt->publish($MQTT_prefix.'/'.$RoomName.'/'.$DeviceName.'/'.$device['did'].'/status', $device['state']);
$mqtt->publish($MQTT_prefix.'/'.$RoomName.'/'.$DeviceName.'/'.$device['did'].'/brightness', $device['level']);
$mqtt->publish($MQTT_prefix.'/'.$RoomName.'/'.$DeviceName.'/'.$device['did'].'/LWT', $LWT);
sleep(1);

I wonder if we're overloading your broker with too many topics to fast. This will add a 1 second delay between each light

dracoqcca commented 5 years ago

Hi Paul, You seems to be right with the sleep I'm seeing all tropics now I'll check my broker then thanks a lot to pointing me this out.

sktaylortrash commented 5 years ago

Awesome I'll merge that as other may have slower brokers as well.

dracoqcca commented 5 years ago

Thanks a lot again. I'm modifying mine to have the strreplace replace the space by an instead of nothing it's more readable like this but it's only me you can leave it like this if you like. I will close the issue then you've answer/fix everithing now I can use my lights with homeassitant.