Author |
|
Handman Senior Member
Joined: February 02 2009 Location: United States
Online Status: Offline Posts: 229
|
Posted: October 06 2022 at 00:00 | IP Logged
|
|
|
I have followed the instructions for installing the zigbee2mqtt bridge (https://www.zigbee2mqtt.io/) in conjunction with a recently flashed Sonoff Zigbee 3.0 dongle and was finally able to get the controller running (on a Windows 10 machine, but not a W7 machine . . . I think that many of the dependency programs didn't or wouldn't load; it seems similar to the Zwave2mqtt project and it is not for the timid). I only have one Zigbee device at this point, a $20 Aqara temp, pressure and humidity sensor. The sensor reports changes to several environmental conditions and also reports its signal strength and battery state. These end up in TEMP4 and I am wondering how to extract the individual conditions out? For example, the device will ultimately open a skylight vent in a bathroom, so I need to extract the humidity from TEMP4 to trigger an output. My first through was to create a global variable (since this is a trigger), but I still need to update the global variable as the mqtt subscription topic amends with new parameters. Below is an example of what is recording as conditions update.
| TEMP1 = ZIGBEE2MQTT
| TEMP2 = zigbee2mqtt/MasterBathHumidity/#
| TEMP3 = zigbee2mqtt/MasterBathHumidity
| TEMP4 = {"battery":100,"humidity":58.45,"linkquality":225,"power_out age_count":6,"pressure":1009.3,"temperature":24.22,"voltage" :3175}
| TEMP5 = 0
| TEMP6 = 0
| TEMP7 = 0
| TEMP8 =
| TEMP9 =
| TEMP10 =
From the log:
Does anyone know how to extract this information (humidity) and store it in a global variable? Dave, you mentioned that you had compiled a list of commands for zigbee2mqtt, so anything you can post or send me is appreciated.
|
Back to Top |
|
|
dhoward Admin Group
Joined: June 29 2001 Location: United States
Online Status: Offline Posts: 4447
|
Posted: October 06 2022 at 16:05 | IP Logged
|
|
|
Hey Jeff,
Glad you asked on the forum so I can document for all .
I create a Subscribe statement in the MQTT Subscribe screen. My Topic Filter looks like this:
zigbee2mqtt/0x00158d0007f01d1a/#
My formula is:
ph_formulabtn_n("AQARA_TEMPHUMD")
This just keeps the formula short in the screen and calls the AQARA_TEMPHUMD formula in the "Formulas" screen where longer formulas can be created. That formula looks like
this:
ph_setvar_s(1,1,ph_flattenjson(ph_getvar_s(2,4),":",0,2)) + ph_setanalogout("DWHTEMP",string(number(ph_extractval(ph_get var_s(1,1),"temperature",":")) * 9 / 5 + 32.0)) +
ph_setanalogout("DWHHUMD",ph_extractval(ph_getvar_s(1,1),"hu midity",":")) + ph_setanalogout("DWHPRESS",ph_extractval(ph_getvar_s(1,1),"p ressure",":")) +
ph_setanalogout("DWHBATT",ph_extractval(ph_getvar_s(1,1),"ba ttery",":"))
In the AnalogIO screen, Ive created a DWHTEMP, DWHHUMD, DWHPRESS, and DWHBATT analog devices that are all I/O type "Input" with a controller type of "Virtual". You do have
to pay attention fo the Unit and Point columns and make sure that you use unique values within the controller and I/O type. I think I have all temperature values with a
Point value of 1, humidity gets a 2, etc. I then set the Unit value to signify a room or device so for this one device, I will have something like 9,1 and 9,2, and 9,3
etc. A different sensor would be like 10,1 and 10,2 etc.
This would be pretty much all you need on the AnalogIO screen but I also like to add a "Raw to Calculated formula" to adjust the background device status color based upon
the value. For my battery device, I use the following formula:
ph_getvar_s(4,2) + "%" + ph_rtne(ph_formulabtn_n("ANALOGBATTERYCOLOR"))
The ANALOGBATTERYCOLOR formula in the Formulas table looks like this:
ph_setvar_a(4,6,ph_colorcalc(rgb(255,0,0),rgb(0,255,0),10,10 0,ph_getvar_n(4,2))) + ph_setvar_a(4,5,ph_highestcontrast(12,rgb(0,0,0),rgb(255,255 ,255),ph_getvar_n(4,6)))
If you want to understand better what is going on in the formulas, I'll explain that below:
The AQARA_TEMPHUMD formula first takes the raw JSON from the MQTT subscribe and flattens it with the ph_flattenjson function. I save this flattened JSON to LOCAL1 so I
only have to flatten it once. I then use the ph_extractval function to extract the individual values and then assign that value to the Analog device using the
ph_setanalogout function. In the case of temperature, since the Aqara is in celcius, I do a farenheight conversion. Humidity, pressure, and battery are used as is. From
that, you should see that the formula is pretty simple to follow.
The Raw to Calcluated formula is pretty simple with the first part of the formula primarily adding a "%" sign to the display value which is the ph_getvar_s(4,2) (the raw
value) plus the "%" sign and then calling the ANALOGBATTERYCOLOR formula.
The ANALOGBATTERYCOLOR formula looks complicated but really isnt. The background display color is the 4,6 variable so we're going to set that value with the
ph_setvar_a(4,6,...) function. The ph_colorcalc formula calculates a color between 2 supplied color values based upon another value. So the first parameter Im supplying
rgb(255,0,0) which is Red. The second parameter is rgb(0,255,0) which is green. Those are my two color values so the actual color will be either Red, Green, or somewhere
in between. The next two parameters are my set ranges with 10 (10%) being my low or Red range, and 100 (100%) being my high or Green range. The remaining parameter is the
value that can change, in this case the raw percentage which is in variable 4,2. So when my battery is at 100%, the background color will be Green and as the percentage
decreases, it will gradually color shift into Red being full Red at 10% (or below). The other half of the formula is to set the foreground color (variable 4,5). It uses
the ph_highestcontrast function to determine which of two supplied colors (black and white in my case) provides the highest contrast for the background color that was
previously calculated in variable 4,6.
Hope this helps,
Dave.
|
Back to Top |
|
|
Handman Senior Member
Joined: February 02 2009 Location: United States
Online Status: Offline Posts: 229
|
Posted: October 06 2022 at 18:53 | IP Logged
|
|
|
Thanks Dave. It worked beautifully. One little glitch was with the added spaces the forum adds in the AQARA_TEMPHUMD formula you pasted which produced syntax errors, but I used a text editor to clean it up.
Here's the result in Device Status:
BTW, you might know this, but you can assign a more user friendly name to the Zigbee devices at the subscription level by adding a line to the configuration.yaml file:
Thanks also for the brief tutorial on the background coloring. I may play around with that a bit after I find my RBG color wheel.
Any suggestions for how to trigger a macro with a high humidity? I tried with the value from the analog device, but the boolean value is giving me a syntax error even though ph_getanalog("MBHUMD") returns the correct stored value. The analog input trigger value defaulted to "Changed" and the trigger ID number defaulted to "0." I'm not sure what trigger ID number refers to in this case, the Point number? Unit number? In any case, it can't be changed, so I am assuming there is something bad about the Boolean formula.
Thanks again for the Zigbee2MQTT suggestions and fixes. This will hopefully open up a whole line of cheap devices to add to bolster my thin Zigbee network.
|
Back to Top |
|
|
dhoward Admin Group
Joined: June 29 2001 Location: United States
Online Status: Offline Posts: 4447
|
Posted: October 06 2022 at 21:10 | IP Logged
|
|
|
Jeff,
No problem, happy to help.
Your trigger is close. The problem is that ph_getanalog returns the calculated value for the device which is a string. You would need to change it to:
if(integer(ph_getanalog("MBHUMD") > 90,1,0)
However, the TEMP variables will contain the raw and calculated values...both the incoming (new) value and the previous value it is being changed from. Useful
if you only want the trigger to fire once. The TEMP5 variable has the new calculated value, the TEMP10 variable holds the old calc value. TEMP4 holds the new
raw value and TEMP3 (and TEMP2) holds the old raw value. You could thus use:
if(ph_getvar_n(2,4) > 90,1,0)
If you want to trigger only one time, you could use this:
if(ph_getvar_n(2,3) <= 90 and ph_getvar_n(2,4) > 90,1,0)
The Trigger ID Number is the amount the raw value of an analog in has to change in order for the trigger to fire. By using 0, you essentially cause the trigger
to be checked everytime the Analog In device is updated. If you wanted to only check when the value has changed, I would use a value of 1 (the raw value is an
integer so the minimum amount of change would be by a value of 1). With the MQTT devices, by leaving at 0, even though the value may not change, everytime the
MQTT controller updates the value (even if it is the same value), you check the trigger but the Boolean will determine if the action actually fires or not.
Also, I forgot to mention that you may want to update the "Message" column in the Analog IO screen. For example, on my Humidity device, I have a Message value
of "%RH" and "degrees F" on my temperature device. This value is just added to the calc value (it does not become a part of the calc value) for Device status
display purposes.
Appreciate the tip on updating the Zigbee to a friendly name. I knew it could be done, just wasnt sure where I needed to go .
Hope this helps,
Dave.
|
Back to Top |
|
|
Handman Senior Member
Joined: February 02 2009 Location: United States
Online Status: Offline Posts: 229
|
Posted: October 07 2022 at 00:32 | IP Logged
|
|
|
Thanks Dave. I opted to use the longer "trigger one time" formula. That got it all working. Hopefully this will prove to be helpful to others as well who are interested in the Zigbee2MQTT option.
BTW, your information is very complete and informative, as always, but is it written down anywhere? Like is that tidbit about the trigger ID number being the raw value of an "analog in" that has to change in order to fire the trigger located somewhere in a help file? Also, is there some place which lists where all the variables are mapped out? I understand that 1-3 are LOCAL/TEMP/GLOBAL and 4 is the special case for AIO formulas, but where does one look to find out that the TEMP5 variable is "new calculated value" and TEMP10 the "old calculated value," or that TEMP4 is the "new raw value," etc.? Is it written down somewhere, or is it based on an instantaneous log of the variables when the analog input updates somehow? I'm okay with it either way, but I feel bad about constantly asking all these questions that might have documented answers elsewhere.
Anyway, thanks for your assistance with this latest, especially the Zigbee help.
|
Back to Top |
|
|
|
|