NRCHKB / node-red-contrib-homekit-bridged

Node-RED Contribution - HomeKit Bridged : Node-RED nodes to simulate Apple HomeKit devices.
https://nrchkb.github.io
MIT License
414 stars 51 forks source link

Documentation #50

Closed crxporter closed 4 years ago

crxporter commented 5 years ago

I've been thinking of ways I can contribute to this project - and I'm wondering if there would be much benefit to have a place to keep examples.

I'm thinking to create some example flows to share either in the docs or on the wiki page. These would include an example of each service type with inject and debug nodes on either side so users can easily see how things can be put together and what the format is for things.

I know that sending {"foo":"bar"} will list options in the debug but it's not always straightforward from there to see how things actually work. Additionally there is little information on how to use characteristic properties. Eventually this will likely be helpful for the coming combined services (I.e. adding battery level to another item).

A quick example of what I'm thinking is here - I would include a screenshot and a copyable flow for the user to then adapt to their setup.

screen shot 2019-03-04 at 10 54 02 am

[{"id":"ed2d8340.e1d5d8","type":"homekit-service","z":"7b43483c.39305","bridge":"d334490b.40dac","name":"Example Switch","serviceName":"Switch","topic":"","manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":360,"y":160,"wires":[["5844674e.178708"]]},{"id":"8db975bc.c2e9d","type":"inject","z":"7b43483c.39305","name":"On","topic":"","payload":"{\"On\":\"true\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":120,"wires":[["ed2d8340.e1d5d8"]]},{"id":"5844674e.178708","type":"debug","z":"7b43483c.39305","name":"HomeKit Out","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":550,"y":160,"wires":[]},{"id":"629771.da7c409","type":"inject","z":"7b43483c.39305","name":"Off","topic":"","payload":"{\"On\":\"false\"}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":180,"wires":[["ed2d8340.e1d5d8"]]},{"id":"d334490b.40dac","type":"homekit-bridge","z":"","bridgeName":"Example Bridge","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number"}]

I don't know about everyone else but something like this would have gotten me going much quicker when I first picked up this node.

Any input about where to put this documentation or what could be added will be helpful, I'll be working on it in the coming weeks. We can use this issue as a discussion of how things should look.

Shaquu commented 5 years ago

We definitely need this. We have a wiki where you could add this.

Another thing is to add informations from official HomeKit docs. For example required and optional Characteristics and possible values.

Another thing is to write summary what you can achieve with what Service.

crxporter commented 5 years ago

Another thing is to add informations from official HomeKit docs. For example required and optional Characteristics and possible values.

Another thing is to write summary what you can achieve with what Service.

Both good ideas. I added these. They might be better off as two separate wiki pages, have one with the two tables (service and characteristics) then the other wiki page for examples. For now I'm just putting together some initial documentation.

I've just added a start to the wiki page on this. I'm not sure how to upload my screenshots - I believe they'll need to be added to a folder in the github repo then linked in the wiki page, is this correct?

Take a look here

Feel free to edit, add, rearrange, or tell me what you think should be changed. I'll be working on adding more examples over the next few days/weeks.

Shaquu commented 5 years ago

Good starting point.

Of course, it would be good to separate Servs and Chars into wiki pages.

I'm not sure if hosting everything on one bridge is a good idea. Why?

Here is example how to add images. tldr: start creating issue and add image. github will assign url which you can copy and close issue creating

Shaquu commented 5 years ago

Another idea. Make single accessory pages. For example one per Switch and another one for Fan etc. WIth that it would be easier to link one accessory in other places. And it would be more compact and readable.

Shaquu commented 5 years ago

By the way there is an outdated homekit document by apple for non-commercial use. I believe that HAP-nodejs which we depend on was created using this document.

If you found newest then please share.

crxporter commented 5 years ago

I'll get things separated out into separate pages, I think I like the idea of separate pages for each accessory. Things like "switch" will be very simple while "irrigation controller" could be more complicated.

As for putting everything in one bridge - I have been running like this for months. I can simply add/delete a homebridge-service node while not touching the rest of my nodes. For example I had a StatelessProgrammableSwitch last week that was acting up so I deleted it and added a new one with a different name. New one works great.

I do see benefit in the future possibly for having a "production bridge" and a "testing bridge" - or one for switches and one for a camera. I will try to explain this better!

I'm sure things will change and get more interesting once the multiple services -> one accessory is ready (e.g. adding battery service to a motion detector)

Yes I used that homekit document to put this together. I don't have the newest version but I believe some/all of the information is available through an apple developer account. I've tried to go through it to learn more but it's way over my head.


So at this point we will have the following pages:

The services should each have a table of required and optional characteristics. Also how to set characteristic properties so things show up properly in homekit, etc...

It's a start though!

crxporter commented 5 years ago

I think I'm getting this wiki thing figured out a little bit. For now I'm adding examples that I have used and I know work. I have several more that I've tested and will add them soon (fan, window covering, occupancy detector, smoke detector, stateless switch, and valve)

Hopefully others come in to add their own examples.

djiwondee commented 5 years ago

Hello @crxporter, I have temperature, humidity and CO2 sensor services running on my node-red implementation and can provide examples for that. All these nodes are triggered by the measures taken from the Netatmo API. I like this right now because now I can ask Siri what the temp in my garden or in a particular room is...So I the need to wait for HomeKit compatibility of Netatmo disappeared.

Shaquu commented 5 years ago

@djiwondee thanks for examples.

I think it would be good to standardise those pages.

djiwondee commented 5 years ago

@Shaquu as you may have recognized I just followed the given structure as of @crxporter assuming this is/will become the standard

crxporter commented 5 years ago

@djiwondee I just adjusted your "Details" table on the CO2 detector to show the range of accepted values.

A comment on that one - the copyable node doesn't look like it would be a "functional example" for a user to click inject nodes and see the device function in their Home app. I might suggest we add an inject node for both {"CarbonDioxideDetected":0} and {"CarbonDioxideDetected":1} so they can "trigger" the alarm. Then between the inject that you have and the rest of your setup I would put a "random" generator with a range 0 to 100,000 so the user can see "oh hey that takes numbers from 0 to 100,000".

Also - for optional/required characteristics the homekit protocol document (linked above from @Shaquu) shows only "Carbon Dioxide Detected" for "required" characteristics while others are optional. This would mean the sensor is, at a minimum, true/false carbon detected - and optionally shows current and peak levels. I'm going to update your table accordingly - please correct me if I'm mistaken!

Check out the Dimmable Light example to see how I used the random.

PS- thanks for the contribution! Sometime I need to get myself some air quality sensors...

crxporter commented 5 years ago

Just went back to the homekit spec - "Peak Level" is not an alarm threshold but instead the maximum level detected - this number would be saved so you can go back and see "how bad did it get" ... You could potentially have a reset button in nodered or program so it's a rolling 24-hour maximum or something.

But it is NOT an alarm threshold. The alarm is set by "CarbonDioxideDetected"

With this information, I'm going to update the tables again real quick. Should initial levels sent by characteristic property should be 0 so the user doesn't see levels from the start?

djiwondee commented 5 years ago

Hello @crxporter,

have applied some changes. You are right with the behavior of the peak level characteristics. I have also embedded a new flow and screen shot. Instead of using random values for injection I just chose two inject node to demonstrate the behavior of the peak level alerting as given by the Node-Red flow programming.

I struggle a little bit with the "Required" vs "Optional" characteristics. It doesn't matter how to set up this for the CO2 sensor HomeKit service. The functionality is always given and the automatically updated in Home.App. However to achieve an meaningful setup, I set only the CarbonDioxideLevel to required and have added all used characteristics of my example in the characteristic properties of the node-red node.

crxporter commented 5 years ago

Looking at your newest table - the "CarbonDioxideLevel" is not required. The "CarbonDioxideDetected" is required. This makes sense because the true/false detected is the only required item to know if there's an alarm. The current and peak levels are just bonus informations. I like your new example! That will let people see the alarm or non alarm.

While you were doing that edit I came up with this. It adds a "reset" button to bring the peak level back to 0 PPM - for after an alarm event to kind of set an "all clear"...

screen shot 2019-03-06 at 7 55 00 am

[{"id":"b49d0ee7.6e56b8","type":"change","z":"54339415.36f384","name":"Set CarbonDioxideLevel","rules":[{"t":"move","p":"payload","pt":"msg","to":"payload.CarbonDioxideLevel","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":160,"wires":[["d428227f.cefa7","4c34ea41.e2fdbc"]]},{"id":"8df967b3.f96ff8","type":"random","z":"54339415.36f384","name":"","low":"0","high":"100000","inte":"true","property":"payload","x":280,"y":160,"wires":[["b49d0ee7.6e56b8"]]},{"id":"d428227f.cefa7","type":"function","z":"54339415.36f384","name":"Detect Highest Value","func":"var co2 = context.get('co2')||0;\nvar NEWco2;\nif(msg.payload==\"RESET\"){\n    co2=0;\n    context.set('co2',co2);\n    msg.payload={\"CarbonDioxidePeakLevel\":co2};\n    return [msg,null];\n}\nvar alarm={};\nalarm.payload={\"CarbonDioxideDetected\":1};\n\nif(msg.payload.CarbonDioxideLevel){\n    NEWco2=msg.payload.CarbonDioxideLevel;\n    msg.payload={\"CarbonDioxidePeakLevel\":NEWco2};\n    if(NEWco2>co2){\n        co2=NEWco2;\n        context.set('co2',co2);\n        msg.payload={\"CarbonDioxidePeakLevel\":co2};\n    }\n    if(NEWco2>10000){\n        return [msg,alarm];\n    } else {\n        return [msg,null];\n    }\n}","outputs":2,"noerr":0,"x":360,"y":220,"wires":[["4c34ea41.e2fdbc"],["e2a31cb0.c4b918"]]},{"id":"4c34ea41.e2fdbc","type":"homekit-service","z":"54339415.36f384","bridge":"b070e578.4eca1","name":"CO2 Livingroom","serviceName":"CarbonDioxideSensor","topic":"","manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":900,"y":180,"wires":[["22d2e39c.5492ac"]]},{"id":"2822beaf.7689e2","type":"inject","z":"54339415.36f384","name":"Inject CO2","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":160,"wires":[["8df967b3.f96ff8"]]},{"id":"ad7aa107.8aa7c","type":"inject","z":"54339415.36f384","name":"Reset Peak","topic":"","payload":"RESET","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":220,"wires":[["d428227f.cefa7"]]},{"id":"e2a31cb0.c4b918","type":"trigger","z":"54339415.36f384","op1":"","op2":"{\"CarbonDioxideDetected\":0}","op1type":"pay","op2type":"json","duration":"30","extend":true,"units":"s","reset":"","bytopic":"all","name":"30 second alarm","x":650,"y":240,"wires":[["4c34ea41.e2fdbc"]]},{"id":"22d2e39c.5492ac","type":"debug","z":"54339415.36f384","name":"CO2 Debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1090,"y":180,"wires":[]},{"id":"b070e578.4eca1","type":"homekit-bridge","z":"","bridgeName":"Node-Red-Homekit-Bridge","pinCode":"270-21-969","port":"34567","allowInsecureRequest":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number"}]

It takes an "inject" button - picks a random value between 0 and 100,000 (range of accepted values) then sends it as current level. There's also a function that checks whether that level is higher than the previous - and whether it's an alarm (I set the alarm level to be over 10,000). If it's an alarm it sends the alarm to HomeKit for 30 seconds. Additionally there is a button to reset the peak level.

Edit: tweaked the function node a little.


Edit 2: changed again. Added another random so it can be sent "alarm level" or "non alarm level"

screen shot 2019-03-06 at 10 05 23 am

Copyable:

[{"id":"d428227f.cefa7","type":"function","z":"54339415.36f384","name":"Detect Highest Value","func":"var co2 = context.get('co2')||0;\nvar NEWco2;\nif(msg.payload==\"RESET\"){\n    co2=0;\n    context.set('co2',co2);\n    msg.payload={\"CarbonDioxidePeakLevel\":co2};\n    return [msg,null];\n}\nvar alarm={};\nalarm.payload={\"CarbonDioxideDetected\":1};\n\nif(msg.payload.CarbonDioxideLevel){\n    NEWco2=msg.payload.CarbonDioxideLevel;\n//    msg.payload={\"CarbonDioxidePeakLevel\":co2};\n    if(NEWco2>co2){\n        co2=NEWco2;\n        context.set('co2',co2);\n        msg.payload={\"CarbonDioxidePeakLevel\":co2};\n    }\n    if(NEWco2>10000){\n        return [msg,alarm];\n    } else {\n        return [msg,null];\n    }\n}","outputs":2,"noerr":0,"x":360,"y":220,"wires":[["4c34ea41.e2fdbc"],["e2a31cb0.c4b918"]]},{"id":"4c34ea41.e2fdbc","type":"homekit-service","z":"54339415.36f384","bridge":"b070e578.4eca1","name":"CO2 Livingroom","serviceName":"CarbonDioxideSensor","topic":"","manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":900,"y":180,"wires":[["22d2e39c.5492ac"]]},{"id":"e2a31cb0.c4b918","type":"trigger","z":"54339415.36f384","op1":"","op2":"{\"CarbonDioxideDetected\":0}","op1type":"pay","op2type":"json","duration":"30","extend":true,"units":"s","reset":"","bytopic":"all","name":"30 second alarm","x":650,"y":240,"wires":[["4c34ea41.e2fdbc"]]},{"id":"ad7aa107.8aa7c","type":"inject","z":"54339415.36f384","name":"Reset Peak","topic":"","payload":"RESET","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":220,"wires":[["d428227f.cefa7"]]},{"id":"b49d0ee7.6e56b8","type":"change","z":"54339415.36f384","name":"Set CarbonDioxideLevel","rules":[{"t":"move","p":"payload","pt":"msg","to":"payload.CarbonDioxideLevel","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":490,"y":160,"wires":[["d428227f.cefa7","4c34ea41.e2fdbc"]]},{"id":"22d2e39c.5492ac","type":"debug","z":"54339415.36f384","name":"CO2 Debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1090,"y":180,"wires":[]},{"id":"8df967b3.f96ff8","type":"random","z":"54339415.36f384","name":"Safe","low":"0","high":"10000","inte":"true","property":"payload","x":270,"y":160,"wires":[["b49d0ee7.6e56b8"]]},{"id":"6ec90967.3f9838","type":"random","z":"54339415.36f384","name":"Alarm","low":"10001","high":"100000","inte":"true","property":"payload","x":270,"y":100,"wires":[["b49d0ee7.6e56b8"]]},{"id":"2822beaf.7689e2","type":"inject","z":"54339415.36f384","name":"","topic":"","payload":"Non Alarm","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":160,"wires":[["8df967b3.f96ff8"]]},{"id":"31512ba1.ebc87c","type":"inject","z":"54339415.36f384","name":"","topic":"","payload":"Alarm","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":100,"wires":[["6ec90967.3f9838"]]},{"id":"b070e578.4eca1","type":"homekit-bridge","z":"","bridgeName":"Node-Red-Homekit-Bridge","pinCode":"270-21-969","port":"34567","allowInsecureRequest":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number"}]

Note - we don't necessarily have to change your example, I think it is pretty good as it is. I've been trying to learn more about this because the carbon monoxide detector will eventually use nearly the same code. I plan to let you do the "Full Featured" example on CO2 - but am getting ready to do the examples for CO.


Edit 3: just added Carbon Monoxide

radokristof commented 5 years ago

@Shaquu I don't know what is the best idea regarding the bridge... I have read on several forums, that the hard maximum for a bridge is 150 accessory (but due to hardware limitations - like RPi), you will experience problems much before that limit. I don't know what NODE-RED can do, but at least we have to indicate that in the Wiki pages (or add some logic to notify the user when he wants to add the 151st Item to that Bridge).

Also if you can, please update the README page to include a link to the Wiki pages. If we can solve these things out, then this will become one of the many (unrealiable) HomeKit controllers.

radokristof commented 5 years ago

Also an ever growing documentation would be great. For example, I have an AirPurifier Item in HomeKit. And I couldn't get around myself, how I should properly control it. Everything works fine, except that when I turn ON or OFF it sometimes just spins around forever that it is turning on and off. I don't know if this a bug or I just configured it incorrectly (when the Active characteristics should be changed - what does that mean if a device in HomeKit is Active or not?). So a Wiki for these would be awesome, if someone knows the answers for these kind of problems.

crxporter commented 5 years ago

Im planning to get to most of the services eventually! Carbon dioxide came up today so I tried it, adjusted some things, and then did the carbon monoxide. I was planning to knock out the ones I have first but I’ve got a few minutes now- I’ll go check out AirPurifier to see what I can do!

radokristof commented 5 years ago

Thanks! What I got so far which might help you: Active 0-1 doesn't seem to affect this Turning ON-OFF thing (it just shows the device is Active or not). Secondly, the CurrentAirPurifierState toggles the ON-OFF state of this device. I have tried to have 0 and 1 as a turned off state (no is not purifing air and the second is inactive or something like this), but neither one worked...

radokristof commented 5 years ago

For addition, SecuritySystem works as the TargetState shows what the state should be (like when you are turning on the your alarm system and you have a little turn on delay - time to leave your house) and if a CurrentState is set, then it will stop the spinning (the Characteristics are not named like this, but something similar... I'm not in front of NODE-RED so I can't provide detailed info)

crxporter commented 5 years ago

Check here you will see that there are 3 required characteristics. Check here and you will see descriptions of these 3 items.

"flipping the switch" in homekit changes active true/false.

changing between manual and auto mode in homekit changes the target state

The "current state" can't be changed from the Home app - the "current state" has to be sent from node red.

Here is a quick and dirty sample. The buttons should be labeled properly. You need to send target state FIRST then current state.

NOTE!! this is a confusing item. It almost looks like "target state" and "active" are switched for this item. Looking at your comment a few minutes ago it appears you are missing the "Active true/false"

screen shot 2019-03-06 at 3 56 33 pm
[{"id":"23658c6b.4bf7fc","type":"debug","z":"3e0d11cf.29e996","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":570,"y":220,"wires":[]},{"id":"48715e2b.edde4","type":"inject","z":"3e0d11cf.29e996","name":"Target state: on","topic":"","payload":"{\"Active\":true}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":280,"wires":[["b76a15e.cbd98e8"]]},{"id":"6c58b865.cbe098","type":"inject","z":"3e0d11cf.29e996","name":"Target state: off","topic":"","payload":"{\"Active\":false}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":320,"wires":[["b76a15e.cbd98e8"]]},{"id":"c80db304.c4e","type":"inject","z":"3e0d11cf.29e996","name":"Auto mode","topic":"","payload":"{\"TargetAirPurifierState\":1}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":440,"y":100,"wires":[["b76a15e.cbd98e8"]]},{"id":"2188d196.d711e6","type":"inject","z":"3e0d11cf.29e996","name":"Current State: ON","topic":"","payload":"{\"CurrentAirPurifierState\":2}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":410,"y":500,"wires":[["b76a15e.cbd98e8"]]},{"id":"b76a15e.cbd98e8","type":"homekit-service","z":"3e0d11cf.29e996","bridge":"f0825aeb.9064a8","name":"Pure 2","serviceName":"AirPurifier","topic":"","filter":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":430,"y":220,"wires":[["23658c6b.4bf7fc"]]},{"id":"5c80309d.22e278","type":"inject","z":"3e0d11cf.29e996","name":"Manual Mode","topic":"","payload":"{\"TargetAirPurifierState\":0}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":430,"y":140,"wires":[["b76a15e.cbd98e8"]]},{"id":"44a8a93d.b0b51","type":"inject","z":"3e0d11cf.29e996","name":"Current State: OFF","topic":"","payload":"{\"CurrentAirPurifierState\":0}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":410,"y":420,"wires":[["b76a15e.cbd98e8"]]},{"id":"e090d2b0.110df8","type":"inject","z":"3e0d11cf.29e996","name":"Current State: IDLE","topic":"","payload":"{\"CurrentAirPurifierState\":1}","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":410,"y":460,"wires":[["b76a15e.cbd98e8"]]},{"id":"633c58dd.2f2dc8","type":"comment","z":"3e0d11cf.29e996","name":"Auto/Manual mode","info":"","x":250,"y":100,"wires":[]},{"id":"9a55b755.665a2","type":"comment","z":"3e0d11cf.29e996","name":"Set target state","info":"","x":160,"y":240,"wires":[]},{"id":"6d243594.778f14","type":"comment","z":"3e0d11cf.29e996","name":"Set actual state off/idle/on","info":"","x":410,"y":380,"wires":[]},{"id":"f0825aeb.9064a8","type":"homekit-bridge","z":"","bridgeName":"Dev","pinCode":"111-11-111","port":"","allowInsecureRequest":false,"manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number"}]
radokristof commented 5 years ago

Thanks! I think I have tried this before, but now I'm trying again. What I basically did now, is connected my openHAB node to a function which will trigger the targetState when turning on, and then after 1 sec delay sending a CurrentState. And for the outcoming value I'm using the Active value here, and if the AirPurifier is turned off, I'm sending a CurrentState 0 to the AirPurifier.

This should be right?

crxporter commented 5 years ago

It seems for this item “TargetState” is for automatic/manual operation.

Whether the purifier is on or off is actually {“Active”:true/false}

radokristof commented 5 years ago

And in which order what do you think? First Active and then CurrentState?

crxporter commented 5 years ago

Yes. Active then current.

Active is what “comes out” of homekit when you flip it on or off. If you switch it on in the home app then a payload {“Active”:1} will come out of the node. The home app will then show “turning on” until you send back to homekit either {“CurrentAirPurifierState”:1} for idle or {“CurrentAirPurifierState”:2} of on.

Hopefully you get it - try it then post your node red code here if it’s not working. I should be able to look tonight.

crxporter commented 5 years ago

Here is a list of all 6 possible combinations for airpurifier.

Active value, CurrentAirPurifierState value -> Home app display

Active 0, current 0 -> Off Active 0, current 1 -> turning off Active 0, current 2 -> turning off Active 1, current 0 -> turning on Active 1, current 1 -> idle Active 1, current 2 -> on

crxporter commented 5 years ago

First edit of AirPurifier Wiki

radokristof commented 5 years ago

Thanks I’ll try this and report it. One other thing which should be in the docs: how can I control an RGBW LED from HomeKit? Because it seems if you enable brightness and hue it will only have 3 attributes. So I can’t distinguish which brightness should be changed. The brightness of the RGB LED or the White LED brightness. And also it will only give back the attributes which have changed not all 3. This adds extra complexity in the function mode. Or am I missing something?

Shaquu commented 5 years ago

@radokristof I think that way:

So Color Temperature can be a "color" of white (from yellow to white). Remember that Color Temperature should not be used together with Saturation and Hue. There are indeed many options. It depends on your needs.

By the way guys. I would be grateful for test and documentation regarding #44

radokristof commented 5 years ago

But I need a Brigtness item (0-100%) for the separate White channel. Also I think I need 3 Items for the colored LEDs (Brightness, Hue, Saturation). Or I might don’t understand your point 😕

radokristof commented 5 years ago

@crxporter The AirPurifier seems working, but it needs a further testing. Thanks!

Shaquu commented 5 years ago

@radokristof first tell me what is your set, how many lights etc. And what you would like to achieve?

radokristof commented 5 years ago

Ok, so here is one of my flow. screenshot 21

So basically I have 3 nodes, which sends it's current state to that one HomeKit Item. Switching state (through wifiled2_power) works, setting brightness (through wifiled2_white) works.

But, the color channel have 3 attribute. Hue, Saturation, Brightness (HSB). It is an RGBW LED so it has a colored LED and a White one. HomeKit only reports 3 state: Hue Saturation Brightness. But I should seperate them when just setting Brightness, or changing color. But the other problem is that HomeKit doesn't report back the full state (HSB), but just the attributes which have changed. Like if you selected a color, and you just a select a same color, but a little different in Brightness, it just only sends Brightness. So I also need to know the other 2 states, so I can send a HSB 'object' back to openHAB.

Hope now it is clear.

What I thought that might work:

Shaquu commented 5 years ago

You can always retrieve values from openHab before sending new ones: Home.app action (Brigthness:10) -> get openHab object (Brigthness:2, Hue: 5) -> merge object (Brigthness:10, Hue: 5) -> send object to openHab

Other way is to save it like you said.

I practiced naming variables in flow using node id. node-id 6115be82.9eea4

It create json array, dots are level lower

flow.set("6115be82.9eea4.Brigthness", 10);
flow.set("6115be82.9eea4.Hue", 5);

flow.get("6115be82.9eea4.Brigthness");
flow.get("6115be82.9eea4.Hue");
radokristof commented 5 years ago

Thanks. The bigger problem is that I don’t know how should I map it. If I map the white LED to the Brightness also, it will not produce the same color as you selected in HomeKit.

Shaquu commented 5 years ago

Give what you got. (raw data). What you receive from openHab and what you need to send. We will figure it out. Should we move to a new issue?

crxporter commented 5 years ago

Whatever you come up with on the bulb - let's have it end up as another example on the wiki light bulb.

I don't have any colored bulbs so I haven't tried that one.

radokristof commented 5 years ago

@crxporter Yes that's why I thought mentioning this here. @Shaquu I will create a new issue.

radokristof commented 5 years ago

Here

crxporter commented 5 years ago

@Shaquu - regarding characteristic properties and ValveType...

I'm currently using an inject node to send the payload {"ValveType":1} to my valves (change them from faucet to sprinkler). This node triggers something like 5 seconds after node red starts up.

Can you give me a quick rundown of how this would look in Characteristic Properties? Is it possible to do this?

I saw a comment around here yesterday about characteristic properties and I think I'm missing out on how that works a bit...

Shaquu commented 5 years ago

I think it should work the same like you already did.

As it is said:

Characteristic.ValveType.GENERIC_VALVE = 0;
Characteristic.ValveType.IRRIGATION = 1;
Characteristic.ValveType.SHOWER_HEAD = 2;
Characteristic.ValveType.WATER_FAUCET = 3;

So Characteristic Properties should look like this

{
    "ValveType": 1
}

You just take Charactersictic name and values from here and put it into json in Chars Properties.

If its not working then answer and I will look at this at home.

crxporter commented 5 years ago

I also thought that would work - and that's how I've tried it - but it comes up as "generic valve"

I've had to actually inject a valve type payload to get it to make the change.

It seems like the characteristic properties are telling the home app "hey you might see this property, leave a spot for it" but not actually sending the value to the item

For example: make a new dimmer item. Characteristic properties like:

{"Brightness":50}

This makes the item show in homekit as a dimmer - but never actually sets the level to 50%.

Essentially it's telling homekit which optional characteristics may be used?

Fast forware to valve type - and I'm unable to get it to show as a "sprinkler" unless I inject the {"ValveType":1} payload.

Shaquu commented 5 years ago

@crxporter I checked and Characteristic properties is not about injecting... You just set props using that. For example validValues etc.

These are props for ValveType:

format: Characteristic.Formats.UINT8,
    maxValue: 3,
    minValue: 0,
    validValues: [0,1,2,3],
    perms: [Characteristic.Perms.READ, Characteristic.Perms.NOTIFY]

While creating Service we set this to default value which is 0

 switch (this.props.format) {
    case Characteristic.Formats.BOOL: return false;
    case Characteristic.Formats.STRING: return "";
    case Characteristic.Formats.DATA: return null; // who knows!
    case Characteristic.Formats.TLV8: return null; // who knows!
    case Characteristic.Formats.DICTIONARY: return {};
    case Characteristic.Formats.ARRAY: return [];
    default: return this.props.minValue || 0;
  }

We could have add new window editor to inject values...

crxporter commented 5 years ago

Your explanation is much more concise and clear than mine. Yes.

How many items are there like this? I can only think of valve...

Essentially this would be a permanent setting then if it's in the setup. Saying something like: this valve is always a sprinkler/shower/faucet.

I just read through your link above listing all characteristics. It seems like valve type is the only thing that isn't meant to change on a regular basis...

crxporter commented 5 years ago

PS- this is the easy way that has yet to fail.

screen shot 2019-03-08 at 9 54 50 am

djiwondee commented 5 years ago

Hello @crxporter,

FYI: I'm just dealing a little bit with some of the so called General Characteristics as described in the Wiki. I tried to add BatteryLevel and StatusLowBattery on my Humidity and Temperature sensor. No effect in the Home.app. Node-red is showing the following message in the log:

HAP Warning: Characteristic 00000068-0000-1000-8000-0026BB765291 not in required or optional characteristics for service 0000008A-0000-1000-8000-0026BB765291. Adding anyway.

Think it works as designed in the HomeApp by Apple. Maybe it is worth to add a note in the Wiki.

I've found an interesting app in the app store Controller for HomeKit shows much more information in the pro-version about whats deployed in HomeKit. Interesting to see the Characteristics mentioned above appear in that app with the right values...

crxporter commented 5 years ago

@djiwondee, are you running the 0.5 release or the dev branch? Battery status is a little different (uses a linked service) and is almost ready, should be in the next release.

Wiki examples will follow shortly.

crxporter commented 5 years ago

Looking at the general characteristics table- I probably shouldn’t have put battery on there.

djiwondee commented 5 years ago

Hello @crxporter, I'm running 0.5.1 (the current official release I guess). As I wrote above, other HomeKit apps on iOS showing the battery data for my temperature, co2 and humidity sensors. The following example is from a temperature sensor:

Bildschirmfoto 2019-03-09 um 15 46 21

Same sensor in iOS Home.app:

Bildschirmfoto 2019-03-09 um 15 52 18

And this is set setup of the characteristics:

Bildschirmfoto 2019-03-09 um 15 53 42

crxporter commented 5 years ago

This is cool- I’ve known some apps support additional stuff but I’ve never tried them.

The next release will allow us to add battery level % as well as low battery alerts from homekit. It’ll show rightnin the home app!

(tried to upload a picture, it's not working)

Shaquu commented 5 years ago

@djiwondee actaully me and @crxporter figure it out few days ago that Characteristic Properties is not about initializing Characteristic itself but about their Properties. So you can make some adjustments here regarding required and optional Characteristics of a Service like validValues, minValue or maxValue.

@crxporter could you update wiki following our arrangements?

This is Characteristics Properties flow in our code:

Available Properties we can set in Characteristics Properties:

this.props = props || {
    format: null,
    unit: null,
    minValue: null,
    maxValue: null,
    minStep: null,
    perms: []
};

Plus:

validValues
validValueRanges
maxLen
maxDataLen