Delayed homekit start

I have create a node-red flow for my Hassio instance to start my homekit after all the available homekit entities are available. It copies the the homekit configuration.yaml file (I use !includes, you may need to modify this to match your config) to a folder node-red can see then node-red checks HA to see it they return valid states. The pass/fail response is then sent to my ios notification.

Why I did this is I have some LIFX bulbs that can take a while to show on HA. These would then be dropped from ios homekit. when they are added again later they do not have the room settings etc se in the app. Also when if i broke the config then i would loose all my homekit config.

This could be adapted to other uses as well. For instance i was having issues with my hue hub connecting on previous version but if i restarted HA it would come back (usually within a few goes). This could easily be modified to do this.

To do:

  • Better error handling. it currently fails to do or tell anything if the file is missing.
  • Include ios notification actions to override etc.

shell command
homekit_share: "cp /config/include/components/homekit.yaml /share/nodered/homekit.yaml"

Node red flow
[{"id":"53f2d578.beff2c","type":"comment","z":"54c570eb.08d58","name":"check homekit, start service and notify if pass/fail","info":"","x":240,"y":60,"wires":[]},{"id":"e1f53fda.45afc","type":"yaml","z":"54c570eb.08d58","property":"payload","name":"","x":810,"y":180,"wires":[["43787665.329098"]]},{"id":"b78073e2.572d2","type":"file in","z":"54c570eb.08d58","name":"homekit.yaml","filename":"/share/nodered/homekit.yaml","format":"utf8","chunk":false,"sendError":true,"encoding":"none","x":650,"y":180,"wires":[["e1f53fda.45afc"]]},{"id":"a1ce313e.1fa1c","type":"inject","z":"54c570eb.08d58","name":"","topic":"on","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":100,"wires":[["b78073e2.572d2"]]},{"id":"84c4974c.22b6d8","type":"debug","z":"54c570eb.08d58","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":1490,"y":280,"wires":[]},{"id":"43787665.329098","type":"function","z":"54c570eb.08d58","name":"check entities","func":"const globalHomeAssistant = global.get('homeassistant');\nconst ha = globalHomeAssistant.homeAssistant;\n\nvar entities_pass = [];\nvar entities_fail = []; \nvar message;\nvar subtitle;\nvar entities_homekit = msg.payload.filter.include_entities;\nmsg.entities = {};\n\n\nvar i;\nfor (i = 0; i < entities_homekit.length; i++) {\n \n // get the state for each entity\n entities_pass.push(ha.states[entities_homekit[i]]);\n\n // if the entity is undefined then add it to the fail list\n if(typeof(ha.states[entities_homekit[i]]) === \"undefined\" ) {\n entities_fail.push(entities_homekit[i]);\n }\n}\n\n// remove any null values from entities_pass\nentities_pass = entities_pass.filter(Boolean);\n\n// move the payload\nmsg.entities.homekityaml = entities_homekit;\n\n// create the ios notification payload\nmsg.payload = {};\nmsg.payload.data = {};\nmsg.payload.data.title = \"homekit\"\n\n\nmsg.payload.fail_count = entities_fail.length;\n\n// set the status if the homekit check\n// homekit array is empty\nif(entities_homekit.length === 0 ) {\n subtitle = \"failed to start\"\n message = entities_fail.join(\"\\r\\n\"); \n message = \"no entities in the homekit file\"\n msg.entities.status = \"fail\";\n\n// homekit has missing entities \n} else if(entities_fail.length !== 0 ) {\n subtitle = \"failed to start\"\n message = entities_fail.join(\"\\r\\n\"); \n message = entities_fail.length + \" entities failed to connect\\r\\n\" + message\n msg.entities.status = \"fail\";\n\n// homekit is good to go\n} else {\n subtitle = \"pass\"\n message = \"all homekit entities available. homekit starting\";\n msg.entities.status = \"pass\";\n}\n\n\n// create the msg package\nmsg.payload.data.data = {};\nmsg.payload.data.data.subtitle = subtitle;\nmsg.payload.data.message = message; \nmsg.entities.pass = entities_pass;\nmsg.entities.fail = entities_fail;\n\nreturn msg;","outputs":1,"noerr":0,"x":980,"y":180,"wires":[["97cc749b.399178"]]},{"id":"e04f7273.7ab81","type":"api-call-service","z":"54c570eb.08d58","name":"homekit start","server":"f41510c7.a2386","service_domain":"homekit","service":"start","data":"","mergecontext":"","output_location":"","output_location_type":"none","x":1330,"y":160,"wires":[["84c4974c.22b6d8","60431de4.706754"]]},{"id":"aea84f1f.f58fd","type":"api-call-service","z":"54c570eb.08d58","name":"homekit yaml copy","server":"f41510c7.a2386","service_domain":"shell_command","service":"homekit_share","data":"","mergecontext":"","output_location":"","output_location_type":"none","x":310,"y":180,"wires":[["b5b6d449.16c048"]]},{"id":"b5b6d449.16c048","type":"delay","z":"54c570eb.08d58","name":"5s","pauseType":"delay","timeout":"15","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":490,"y":180,"wires":[["b78073e2.572d2"]]},{"id":"3ac37387.ca09fc","type":"rbe","z":"54c570eb.08d58","name":"","func":"rbe","gap":"","start":"","inout":"out","property":"payload","x":1310,"y":220,"wires":[["84c4974c.22b6d8","826b4a4f.965078"]]},{"id":"826b4a4f.965078","type":"api-call-service","z":"54c570eb.08d58","name":"notify tim","server":"f41510c7.a2386","service_domain":"notify","service":"ios_tims_iphone","data":"","mergecontext":"","output_location":"payload","output_location_type":"msg","x":1500,"y":220,"wires":[["84c4974c.22b6d8"]]},{"id":"97cc749b.399178","type":"switch","z":"54c570eb.08d58","name":"pass fail","property":"entities.status","propertyType":"msg","rules":[{"t":"eq","v":"pass","vt":"str"},{"t":"neq","v":"pass","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":1160,"y":180,"wires":[["3ac37387.ca09fc","e04f7273.7ab81"],["e2a161bb.2288d","3ac37387.ca09fc"]]},{"id":"e2a161bb.2288d","type":"delay","z":"54c570eb.08d58","name":"","pauseType":"delay","timeout":"15","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":280,"y":240,"wires":[["aea84f1f.f58fd"]]},{"id":"6d7861db.03897","type":"mqtt in","z":"54c570eb.08d58","name":"HASS start","topic":"homeassistant/system/start","qos":"2","datatype":"auto","broker":"bbb21a40.57c1c8","x":120,"y":180,"wires":[["aea84f1f.f58fd"]]},{"id":"bd59525.ff3c7b","type":"inject","z":"54c570eb.08d58","name":"","topic":"on","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":130,"y":140,"wires":[["aea84f1f.f58fd"]]},{"id":"b8d979d4.24b128","type":"api-call-service","z":"54c570eb.08d58","name":"logbook","server":"f41510c7.a2386","service_domain":"logbook","service":"log","data":"","mergecontext":"","output_location":"","output_location_type":"none","x":1640,"y":160,"wires":[[]]},{"id":"60431de4.706754","type":"change","z":"54c570eb.08d58","name":"details","rules":[{"t":"delete","p":"payload","pt":"msg"},{"t":"set","p":"payload.data.name","pt":"msg","to":"Node Red","tot":"str"},{"t":"set","p":"payload.data.message","pt":"msg","to":"Homekit starting","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":1490,"y":160,"wires":[["b8d979d4.24b128"]]},{"id":"f41510c7.a2386","type":"server","z":"","name":"Home Assistant","legacy":false,"hassio":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true},{"id":"bbb21a40.57c1c8","type":"mqtt-broker","z":"","name":"mosquitto","broker":"192.168.2.114","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]