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
418 stars 52 forks source link

Awesome to see some new development! #42

Closed crxporter closed 5 years ago

crxporter commented 5 years ago

@Shaquu - it's awesome to see some new development here. I use this plugin for the bulk of my smarthome, it has been fantastic (good job all those who have come before).

I'm curious if you have a few minutes to answer a couple of questions: 1-what changes have you made (where could I find a changelog?) 2-do you have any goals or roadmap of what you're planning to do next here?

I always like to be sure I know what's changing before I put things in action at home in case I'm going to break something important. I see you put in the PR from @radokristof - I was helping him figure that out a few months ago I'm glad to see it in the production version.

The other things I've seen around are adding things like battery status to be part of all of the services and adding "official" homekit devices into node red. Battery status will be awesome. If I were in charge I would say that adding official homekit devices into node red may be better placed in a separate node red flow. Just my two cents.

Keep up the great work! I'll be watching!

radokristof commented 5 years ago

There is also a new openhab2 node!

However yes it would be great that new deviceType will included/fixed. Like FilterMaintenance, Speaker is included but HomeKit says these are not supported (I think it is deprecated). Do you plan to include these also in your fixes or just some bug fixes?

Shaquu commented 5 years ago

@crxporter thanks for a kind word :+1:

  1. Changelog is available in PR merge to master #40 - release 0.5.0
  2. I have planty of goals but will tell about them just in a minute...

First thing about breaking stuff with new versions. As ex software tester and current developer I am aware of backward compatibility. For now, I try to test everything in some way before releasing.

In short, 0.5.0 should be backward compatible. A thing which is not defined in README (yet) is that we will use semver versioning for this project. So version is MAJOR.MINOR.PATCH. MAJOR version when you make incompatible API changes, MINOR version when you add functionality in a backwards-compatible manner, and PATCH version when you make backwards-compatible bug fixes.

Time for some current goals:

@radokristof again, thanks for contribution :+1: Yes, It's important for me to fix known bugs here. But so much depend on Hap-nodejs...

I wrote it on the run. If you have any question or ideas then I am waiting for it! :100:

And Yes, for integrations with outer devices there will be new node.

crxporter commented 5 years ago

There is also a new openhab2 node!

Cool! I hadn't seen this yet I'm going to check it out.

@Shaquu - the list of goals looks awesome. Count me in as one who will be happy to use nearly all of that. Doorbell will push me to finally run that wire from my attic to my pi. Linked services will help me support "batteries" and maybe I can take "null" states and pass them to homebridge as "unavailable" or something. I can move my homebridge-camera-rpi over to node-red.

One thing I haven't been able to figure out is having a rachio-style "irrigation system". My current setup for sprinklers is to have 4 individual valves. This works fine but there is one feature I don't get which is possible on rachio 3 native homekit. This feature is the ability to say "water all zones" which will, obviously, water each zone sequentially. My current setup for sprinklers only lets me run one zone at a time so I can't do "hey siri water the whole yard" instead I have to run the front yard then later say water the back yard. Hopefully this makes sense - maybe it's already available, here is a screenshot I've seen online of what the rachio looks like:

iu

I'm very excited for all of this. Feel free to close this thread or leave it open if you'd like input on how users like me think features should work.

Shaquu commented 5 years ago

I’m very excited as well. Even more when I see that people use it :)

About the sprinklers. Can’t you just make one more button which will enable the rest of valves automatically? I mean the master valve.

Can you share what’s behind your current sprinkler setup? Plugins, configuration files?

Sent with GitHawk

crxporter commented 5 years ago

Sprinklers - perhaps I didn't explain well. I don't have a master valve but instead 4 separate zones. The rachio support allows a "water all" command where it will run the sprinkler program so when zone 1 finishes - zone 2 starts - then zone 3 and so on for N zones.

My sprinkler setup is through HTTP calls to the Skydrop API. It's something I've put together myself and works pretty well, I poll every 45 seconds and can start each zone separately which allows me to say "water front yard" then the call will be made to water the front yard for the preset number of minutes.

Current setup looks like this in homekit: img_9eb563abae1c-1

And like this in node-red (each homekit item is a valve service): screen shot 2019-02-25 at 9 52 20 am

This works great but if I understand the rachio setup properly - I could potentially have one controller with 4 zones. Then I can water individual zones but also add a separate API call to Skydrop that says "water all" - in which case it would water each zone sequentially with no further input. Currently I have to go back to the Skydrop app to get that functionality.

I have tried to use the "irrigation system" service in node-red but did not get it to work right. That might be the right way to go about it but I never figured out how to add my zones to the irrigation system.

Node-red flow:

[{"id":"d912f6b9.c834f8","type":"function","z":"ce950a3e.629368","name":"Zone 4","func":"if(msg.hap.context !== undefined){\n    OutMsg={};\nif(msg.payload.Active==1){\n    var accessT = global.get(\"AccessToken\")\n    var uri=\"https://api.skydrop.com/controllers/329992ba-8009-408d-b46a-1e4a5aee6f1b/\"\n    var command=\"zones/4/water.zone\"\n    var text=\"?access_token=\"\n    OutMsg.method=\"POST\"\n    OutMsg.url=uri.concat(command,text,accessT)\n    return OutMsg;\n}\nif(msg.payload.Active===0){\n    var accessT = global.get(\"AccessToken\")\n    var uri=\"https://api.skydrop.com/controllers/329992ba-8009-408d-b46a-1e4a5aee6f1b/\"\n    var command=\"water.stop\"\n    var text=\"?access_token=\"\n    OutMsg.method=\"POST\"\n    OutMsg.url=uri.concat(command,text,accessT)\n    return OutMsg;\n}\n}\n","outputs":1,"noerr":0,"x":660,"y":300,"wires":[["22892d5.8d79b52"]]},{"id":"d0016748.9b9ea","type":"homekit-service","z":"ce950a3e.629368","bridge":"4b4fbb6e.6cfaec","name":"Back Yard","serviceName":"Valve","manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":490,"y":300,"wires":[["d912f6b9.c834f8"]]},{"id":"22892d5.8d79b52","type":"delay","z":"ce950a3e.629368","name":"Limit","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":850,"y":240,"wires":[["f333ac89.73fa08"]]},{"id":"23523fb3.9a2d2","type":"function","z":"ce950a3e.629368","name":"Status","func":"if(msg.payload.success === true){\nvar zone1={};\nvar zone2={};\nvar zone3={};\nvar zone4={};\nvar i;\nfor (i=0;i<8;i++){\n    if (msg.payload.zone_states[i].zone_id==1){\n        zone1.payload=msg.payload.zone_states[i];\n    }\n    if (msg.payload.zone_states[i].zone_id==2){\n        zone2.payload=msg.payload.zone_states[i];\n    }\n    if (msg.payload.zone_states[i].zone_id==3){\n        zone3.payload=msg.payload.zone_states[i];\n    }\n    if (msg.payload.zone_states[i].zone_id==4){\n        zone4.payload=msg.payload.zone_states[i];\n    }\n}\nvar hk1={};\nvar hk2={};\nvar hk3={};\nvar hk4={};\nvar runningMsg={};\nif(zone1.payload.zone_watering===false){\n    hk1.payload={\"Active\":0,\"InUse\":0,\"RemainingDuration\":zone1.payload.time_left*60}\n}\nif(zone1.payload.zone_watering===true){\n    hk1.payload={\"Active\":1,\"InUse\":1,\"RemainingDuration\":zone1.payload.time_left*60}\n    runningMsg.payload=\"trigger\";\n}\nif(zone2.payload.zone_watering===false){\n    hk2.payload={\"Active\":0,\"InUse\":0,\"RemainingDuration\":zone2.payload.time_left*60}\n}\nif(zone2.payload.zone_watering===true){\n    hk2.payload={\"Active\":1,\"InUse\":1,\"RemainingDuration\":zone2.payload.time_left*60}\n    runningMsg.payload=\"trigger\";\n}\nif(zone3.payload.zone_watering===false){\n    hk3.payload={\"Active\":0,\"InUse\":0,\"RemainingDuration\":zone3.payload.time_left*60}\n}\nif(zone3.payload.zone_watering===true){\n    hk3.payload={\"Active\":1,\"InUse\":1,\"RemainingDuration\":zone3.payload.time_left*60}\n    runningMsg.payload=\"trigger\";\n}\nif(zone4.payload.zone_watering===false){\n    hk4.payload={\"Active\":0,\"InUse\":0,\"RemainingDuration\":zone4.payload.time_left*60}\n}\nif(zone4.payload.zone_watering===true){\n    hk4.payload={\"Active\":1,\"InUse\":1,\"RemainingDuration\":zone4.payload.time_left*60}\n    runningMsg.payload=\"trigger\";\n}\nif(runningMsg.payload==\"trigger\"){\n    return[hk1,hk2,hk3,hk4,runningMsg];\n}\nif(runningMsg.payload!=\"trigger\"){\n    return[hk1,hk2,hk3,hk4,null];\n}\n}\nif(msg.payload==\"type1\"){\n    msg.payload={\"ValveType\":1};\n    return[msg,msg,msg,msg,null];\n}","outputs":5,"noerr":0,"x":230,"y":140,"wires":[["43e2aaf7.8063a4"],["e20e5ad2.dced38"],["1489c83f.e4e24"],["d0016748.9b9ea"],["e5cad50b.ed7cb"]]},{"id":"5b244d25.d93ae4","type":"function","z":"ce950a3e.629368","name":"Water State","func":"OutMsg={};\nvar accessT = global.get(\"AccessToken\")\nvar uri=\"https://api.skydrop.com/controllers/329992ba-8009-408d-b46a-1e4a5aee6f1b/\"\nvar command=\"water.state\"\nvar text=\"?access_token=\"\nOutMsg.url=uri.concat(command,text,accessT)\nOutMsg.method=\"GET\"\nreturn OutMsg;\n","outputs":1,"noerr":0,"x":650,"y":360,"wires":[["22892d5.8d79b52"]]},{"id":"d5db22ca.2bad6","type":"function","z":"ce950a3e.629368","name":"Zone 2","func":"if(msg.hap.context !== undefined){\n    OutMsg={};\nif(msg.payload.Active==1){\n    var accessT = global.get(\"AccessToken\")\n    var uri=\"https://api.skydrop.com/controllers/329992ba-8009-408d-b46a-1e4a5aee6f1b/\"\n    var command=\"zones/2/water.zone\"\n    var text=\"?access_token=\"\n    OutMsg.method=\"POST\"\n    OutMsg.url=uri.concat(command,text,accessT)\n    return OutMsg;\n}\nif(msg.payload.Active===0){\n    var accessT = global.get(\"AccessToken\")\n    var uri=\"https://api.skydrop.com/controllers/329992ba-8009-408d-b46a-1e4a5aee6f1b/\"\n    var command=\"water.stop\"\n    var text=\"?access_token=\"\n    OutMsg.method=\"POST\"\n    OutMsg.url=uri.concat(command,text,accessT)\n    return OutMsg;\n}\n}","outputs":1,"noerr":0,"x":660,"y":180,"wires":[["22892d5.8d79b52"]]},{"id":"54ca21bd.bf0bc","type":"function","z":"ce950a3e.629368","name":"Zone 3","func":"if(msg.hap.context !== undefined){\n    OutMsg={};\nif(msg.payload.Active==1){\n    var accessT = global.get(\"AccessToken\")\n    var uri=\"https://api.skydrop.com/controllers/329992ba-8009-408d-b46a-1e4a5aee6f1b/\"\n    var command=\"zones/3/water.zone\"\n    var text=\"?access_token=\"\n    OutMsg.method=\"POST\"\n    OutMsg.url=uri.concat(command,text,accessT)\n    return OutMsg;\n}\nif(msg.payload.Active===0){\n    var accessT = global.get(\"AccessToken\")\n    var uri=\"https://api.skydrop.com/controllers/329992ba-8009-408d-b46a-1e4a5aee6f1b/\"\n    var command=\"water.stop\"\n    var text=\"?access_token=\"\n    OutMsg.method=\"POST\"\n    OutMsg.url=uri.concat(command,text,accessT)\n    return OutMsg;\n}\n}","outputs":1,"noerr":0,"x":660,"y":240,"wires":[["22892d5.8d79b52"]]},{"id":"4023d596.654644","type":"function","z":"ce950a3e.629368","name":"Zone 1","func":"if(msg.hap.context !== undefined){\n    OutMsg={};\nif(msg.payload.Active==1){\n    var accessT = global.get(\"AccessToken\")\n    var uri=\"https://api.skydrop.com/controllers/329992ba-8009-408d-b46a-1e4a5aee6f1b/\"\n    var command=\"zones/1/water.zone\"\n    var text=\"?access_token=\"\n    OutMsg.method=\"POST\"\n    OutMsg.url=uri.concat(command,text,accessT)\n    return OutMsg;\n}\nif(msg.payload.Active===0){\n    var accessT = global.get(\"AccessToken\")\n    var uri=\"https://api.skydrop.com/controllers/329992ba-8009-408d-b46a-1e4a5aee6f1b/\"\n    var command=\"water.stop\"\n    var text=\"?access_token=\"\n    OutMsg.method=\"POST\"\n    OutMsg.url=uri.concat(command,text,accessT)\n    return OutMsg;\n}\n}","outputs":1,"noerr":0,"x":660,"y":120,"wires":[["22892d5.8d79b52"]]},{"id":"f333ac89.73fa08","type":"http request","z":"ce950a3e.629368","name":"HTTP","method":"use","ret":"obj","url":"","tls":"","x":970,"y":240,"wires":[["3b1bfdd7.2f2fc2"]]},{"id":"43e2aaf7.8063a4","type":"homekit-service","z":"ce950a3e.629368","bridge":"4b4fbb6e.6cfaec","name":"Flowers","serviceName":"Valve","manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":480,"y":120,"wires":[["4023d596.654644"]]},{"id":"e20e5ad2.dced38","type":"homekit-service","z":"ce950a3e.629368","bridge":"4b4fbb6e.6cfaec","name":"Driveway","serviceName":"Valve","manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":480,"y":180,"wires":[["d5db22ca.2bad6"]]},{"id":"1489c83f.e4e24","type":"homekit-service","z":"ce950a3e.629368","bridge":"4b4fbb6e.6cfaec","name":"Front Yard","serviceName":"Valve","manufacturer":"Default Manufacturer","model":"Default Model","serialNo":"Default Serial Number","characteristicProperties":"{}","x":490,"y":240,"wires":[["54ca21bd.bf0bc"]]},{"id":"e5cad50b.ed7cb","type":"trigger","z":"ce950a3e.629368","op1":"","op2":"1","op1type":"nul","op2type":"str","duration":"10","extend":false,"units":"s","reset":"","bytopic":"all","name":"","x":470,"y":360,"wires":[["5b244d25.d93ae4"]]},{"id":"e3c4df23.03229","type":"link in","z":"ce950a3e.629368","name":"Status","links":["c1a9c7c9.52be5"],"x":135,"y":140,"wires":[["23523fb3.9a2d2"]]},{"id":"6d34151c.4d43a4","type":"link in","z":"ce950a3e.629368","name":"LINK","links":["6c142e38.6288f"],"x":535,"y":420,"wires":[["5b244d25.d93ae4"]]},{"id":"3b1bfdd7.2f2fc2","type":"switch","z":"ce950a3e.629368","name":"","property":"method","propertyType":"msg","rules":[{"t":"eq","v":"POST","vt":"str"},{"t":"eq","v":"GET","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1090,"y":240,"wires":[["6c142e38.6288f"],["c1a9c7c9.52be5"]]},{"id":"fe20a937.d53b88","type":"inject","z":"ce950a3e.629368","name":"45 seconds","topic":"","payload":"","payloadType":"date","repeat":"45","crontab":"","once":false,"onceDelay":0.1,"x":230,"y":400,"wires":[["e5cad50b.ed7cb"]]},{"id":"6c142e38.6288f","type":"link out","z":"ce950a3e.629368","name":"LINK","links":["6d34151c.4d43a4"],"x":1195,"y":220,"wires":[]},{"id":"c1a9c7c9.52be5","type":"link out","z":"ce950a3e.629368","name":"Status","links":["e3c4df23.03229"],"x":1195,"y":260,"wires":[]},{"id":"7fd2a94c.5055d","type":"inject","z":"ce950a3e.629368","name":"Valve Type","topic":"","payload":"type1","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":"1","x":1070,"y":300,"wires":[["c1a9c7c9.52be5"]]},{"id":"4b4fbb6e.6cfaec","type":"homekit-bridge","z":"","bridgeName":"Node Red","pinCode":"514-02-658","port":"","manufacturer":"Garrett Porter","model":"Pi3","serialNo":"Rev.1"}]
Shaquu commented 5 years ago

Maybe make something like this? I didn't test it but I think it should work after some adjustments.

There is pseudo flow unknown

Get Next Zone:

var active = flow.get("active") || false;
var lastZone = flow.get("zoneNumber") || 0;

if (!active) {
    lastZone = 0;
} else if (lastZone < 4) {
    lastZone++;
    msg.payload.zone_states[I] //there make a thing that Status block enable zone==lastZone and disable the rest
} else {
    flow.set("active", false);
    lastZone = 0;
}

flow.set("zoneNumber", lastZone);

msg.lastZone = lastZone;

return msg;

Active:

    flow.set("active", true);
} else {
    flow.set("active", false);
}

return msg;

Check If Running All (by checking flow.get(active) and if so then assign ALL to method. Then switch send you back to Get Next Zone if msg.method is ALL

crxporter commented 5 years ago

Thanks for looking! That would probably work but there is a much easier way if I want to run all... I can just send the HTTP post command to water all. Looks like:

https://api.skydrop.com/controllers/{controller-id}/water.all

I may as well just put a switch that says "water all" then when I turn it on - well you can guess what happens.

The improvement I'm looking for is based on the screenshot I sent earlier about rachio - the valves are all part of one homekit accessory but with multiple zones. I've tried to find the setup in the homekit accessory protocol document but there is nothing about irrigation systems (the document is old). I don't know where to find newer information on the apple webpage.

Don't worry too much about it! If during your work you find the homekit protocol method to combine multiple valves into one irrigation controller - let me know I'll be your first tester!

radokristof commented 5 years ago

I'm sure that if Valves looks like as on your screenshot, then rachio uses the IrrigationSystem. I also looked the document I have for you, but that doesn't include this. I have found a pretty useful website a few months ago with details regarding characteristics and etc. I will try to find them (but I think that doesn't include new HomeKit things as well).

Shaquu commented 5 years ago

@crxporter I do worry as I really want to make it work for you the way you want this :) I will think more about this issue.

@radokristof I would like to see this website!

By the way, if you like this module then please rate it on the node-red site: https://flows.nodered.org/node/node-red-contrib-homekit-bridged

Thanks!

PS. Published 0.5.1 with fix for a bug I made (module stopped working on nodejs7 in 0.5.0).

crxporter commented 5 years ago

I'm sure that if Valves looks like as on your screenshot, then rachio uses the IrrigationSystem.

Yes I agree. I tried to figure out the irrigation system - but I never could get it to show any valves (zones?) as in the rachio screenshot. I may fiddle with this again tonight and get back to you.

The difference with the irrigation system seems to be that you could do like "run the whole program" (I.e. water all zones). My hold up point is in getting the valves combined into the system.

If I remember correctly, sending {"foo":"bar"} into the irrigation system service didn't provide any results that looked helpful. Just tried it again and see:

Characteristic one cannot be written.
Try one of these: Name, Active, ProgramMode, InUse, Name, RemainingDuration, StatusFault

No mention of zone or hint about how to add a zone to the system...

crxporter commented 5 years ago

rate it on the node-red site

Done!

Shaquu commented 5 years ago

@crxporter give me some time

img_0351

radokristof commented 5 years ago

I have also rated this node! You are insane! :) Please share also how you manage to setup this... Also maybe if you can have a look at some deviceType which should be great to have for me (like Speaker, FilterMaintenance, etc..)

Shaquu commented 5 years ago

@crxporter linked services landed on dev branch

Shaquu commented 5 years ago

@radokristof I will get to your ideas soon I hope :)

crxporter commented 5 years ago

linked services landed on dev branch

You're killing me - I had work to do today!! So much for that!

This is awesome.

radokristof commented 5 years ago

Thanks! I might be missing something but what does this linket services supposed to do in general?

crxporter commented 5 years ago

@Shaquu - Can I get a quick refresher on how to update using the dev branch? I've been just downloading the zip file and copying it to my pi - but that doesn't appear to be working with this.

That or I'm missing how to set up a linked service.

Edit: found it. Had to run sudo apt-get install libavahi-compat-libdnssd-dev

crxporter commented 5 years ago

The good news: linked services is amazing.

img_fc8ef6037100-1

The sad news: clicking on irrigation system doesn't turn on everything.

I'll program the irrigation controller with 5 valves - my 4 zones plus a "run schedule" or something. I will set up the node red flow to respond with a "water all" command to the controller if I turn on that 5th valve - which will stay on until watering is completed. Easy.

@Shaquu - I've tested the irrigation controller and the battery level/charge status/low battery warning. Linked services are the future! So good.

Shaquu commented 5 years ago

Stop node-red Copy and overwrite Start node-red

There should be a new node on the list on the left called HomeKit Linked.

Wiadomość napisana przez crxporter notifications@github.com w dniu 06.03.2019, o godz. 18:40:

@Shaquu - Can I get a quick refresher on how to update using the dev branch? I've been just downloading the zip file and copying it to my pi - but that doesn't appear to be working with this.

That or I'm missing how to set up a linked service.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

Shaquu commented 5 years ago

Okay. I am closing this issue for now :) Thanks for all kind words! I am glad you are there. You are welcome to give more ideas and contribute with code or with examples at #50 .

41 is about linked services. If you have problem with it then you can comment there.

Shaquu commented 5 years ago

PS. @crxporter try experimenting with Characteristics to make it work better. Let's continue this talk at new Issue to #41 - your choice.

crxporter commented 5 years ago

I tried all of the valid characteristics on irrigation system - none made anything “come out” of homekit when pressing the icon in a room.

I’ll be cranking through and discussing documentation at #50

Shaquu commented 5 years ago

@crxporter

linked services landed on dev branch

You're killing me - I had work to do today!! So much for that!

This is awesome.

By the way. I took a day off to finish this :)