Skip to content

Instantly share code, notes, and snippets.

@vigonotion
Created June 25, 2020 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vigonotion/72eb8b2a40901291dc3db671174625e2 to your computer and use it in GitHub Desktop.
Save vigonotion/72eb8b2a40901291dc3db671174625e2 to your computer and use it in GitHub Desktop.
[{"id":"6e393969.673f5","type":"server-state-changed","z":"974a0bef.a0e068","name":"Someone comes 🏠","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"person\\..*","entityidfiltertype":"regex","outputinitially":false,"state_type":"str","haltifstate":"home","halt_if_type":"str","halt_if_compare":"is","outputs":2,"output_only_on_state_change":true,"x":110,"y":620,"wires":[["49d067bc.f7f448"],[]]},{"id":"49d067bc.f7f448","type":"delay","z":"974a0bef.a0e068","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":235,"y":620,"wires":[["e01bf48d.d8b98"]],"l":false},{"id":"e01bf48d.d8b98","type":"function","z":"974a0bef.a0e068","name":"Filter family","func":"let family = ['person.alice', 'person.bob', 'person.celine', 'person.dylan'];\n\nif(family.includes(msg.topic)) {\n node.status({fill:\"green\",shape:\"dot\",text:\"Family\"});\n return [msg, null];\n}\nnode.status({fill:\"green\",shape:\"dot\",text:\"Guest\"});\nreturn [null, msg];","outputs":2,"noerr":0,"x":350,"y":620,"wires":[["9dff5589.c12218"],[]],"outputLabels":["Familie","Gäste"]},{"id":"9dff5589.c12218","type":"ha-wait-until","z":"974a0bef.a0e068","name":"Front door opened","outputs":2,"entityId":"binary_sensor.eg_tre_door","entityIdFilterType":"exact","property":"state","comparator":"is","value":"on","valueType":"str","timeout":"60","timeoutType":"num","timeoutUnits":"seconds","entityLocation":"","entityLocationType":"none","checkCurrentState":true,"blockInputOverrides":true,"x":530,"y":620,"wires":[["caef02e7.7fe64"],[]]},{"id":"caef02e7.7fe64","type":"ha-get-entities","z":"974a0bef.a0e068","name":"🔎 Get all persons","rules":[{"property":"entity_id","logic":"is","value":"person\\..*","valueType":"re"}],"output_type":"array","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":750,"y":660,"wires":[["43b98a51.b5e6e4"]]},{"id":"43b98a51.b5e6e4","type":"deduplicate","z":"974a0bef.a0e068","name":"","keyproperty":"payload","expirypolicy":"keep","registryclass":"","noderole":"standalone","expiry":"120","x":895,"y":660,"wires":[["f2c5ca0e.349a7"],[]],"l":false},{"id":"f2c5ca0e.349a7","type":"function","z":"974a0bef.a0e068","name":"Create message","func":"/** CONFIGURATION **/\n\n// These are the persons you want to include in the greeting.\nlet persons_whitelist = ['person.alice', 'person.bob', 'person.celine', 'person.dylan'];\n\n// A random greeting will be played every time.\nlet r_greet = [\"Welcome home, \", \"It's nice to see you, \", \"Welcome back, \", \"Hey \", \"Howdy, \"];\n\n/** Optional: Localization\n * If you create a new localization, you can share it in the comments! **/\nlet l10n = {\n \"is\": \"is\",\n \"are\": \"are\",\n \"and\": \"and\",\n \"xyz_is_also_home\": (others, is_are) => others + \" \" + is_are + \" also at home. \",\n \"since\": \"since\",\n \"just_now\": \"just now\",\n \"one_minute\": \"one minute\",\n \"x_minutes\": (minutes) => minutes + \" minutes\",\n \"one_hour\": \"one hour\",\n \"x_hours\": (hours) => hours + \" hours\",\n \"one_day\": \"one day\",\n \"x_days\": (days) => days + \" days\",\n \"away_text\": (persons_with_time) => smart_join(persons_with_time.map(pwt => pwt[0] + \" left \" + pwt[1] + \" ago\")),\n \"final_text\": (text) => hour >= 0 && hour < 6 ? \"<amazon:effect name='whispered'>\" + text + \"</amazon:effect>\" : text \n}\n\n// // Below you find my template for German.\n// // You may also like my r_greet: let r_greet = [\"Willkommen zu Hause, \", \"Schön, dass du da bist, \", \"Willkommen zurück, \", \"Hallo \", \"Moin, \"];\n// let l10n = {\n// \"is\": \"ist\",\n// \"are\": \"sind\",\n// \"and\": \"und\",\n// \"xyz_is_also_home\": (others, is_are) => others + \" \" + is_are + \" auch zu Hause. \",\n// \"since\": \"seit\",\n// \"just_now\": \"gerade eben\",\n// \"one_minute\": \"einer Minute\",\n// \"x_minutes\": (minutes) => minutes + \" Minuten\",\n// \"one_hour\": \"einer Stunde\",\n// \"x_hours\": (hours) => hours + \" Stunden\",\n// \"one_day\": \"einem Tag\",\n// \"x_days\": (days) => days + \" Tagen\",\n// \"away_text\": (persons_with_time) => smart_join(persons_with_time.map(pwt => pwt[0] + \" ist seit \" + pwt[1])) + \" unterwegs.\",\n// \"final_text\": (text) => hour >= 0 && hour < 6 ? \"<amazon:effect name='whispered'>\" + text + \"</amazon:effect>\" : text \n// }\n\n/** Optional: Relations. Replace a name for a person. E.g.: Call Peter \"Dad\" for the kids */\nlet relations = {\n \"person.celine\": {\n \"person.alice\": \"Mom\",\n \"person.bob\": \"Dad\",\n },\n \"person.dylan\": {\n \"person.alice\": \"Mom\",\n \"person.bob\": \"Dad\",\n }\n}\n\n/** END CONFIGURATION.\n * You don't have to change anything below, but if you have a great idea on\n * how to improve this, please write a comment to share it with us! */\n\n// Join the array to a string separated by commas except the last, which gets replaced by \"and\".\nfunction smart_join(arr) { return arr.join(', ').replace(/, ([^,]*)$/, ' ' + l10n[\"and\"] + ' $1'); }\n\n// convert a Date object into a relative time\nfunction relative_time(time_value) {\n var parsed_date = Date.parse(time_value);\n var relative_to = (arguments.length > 1) ? arguments[1] : new Date();\n var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);\n\n if (delta < 60) {\n return l10n[\"just_now\"];\n } else if(delta < 120) {\n return l10n[\"one_minute\"];\n } else if(delta < (60*60)) {\n return l10n[\"x_minutes\"](parseInt(delta / 60).toString());\n } else if(delta < (120*60)) {\n return l10n[\"one_hour\"];\n } else if(delta < (24*60*60)) {\n return l10n[\"x_hours\"](parseInt(delta / 3600).toString());\n } else if(delta < (48*60*60)) {\n return l10n[\"one_day\"]\n } else {\n return l10n[\"x_days\"](parseInt(delta / 86400).toString());\n }\n}\n\n// The arriver is the person that just came home\nlet arriver = msg.data.entity_id;\nlet arriver_name = msg.data.new_state.attributes.friendly_name;\n\nlet hour = new Date().getHours();\nlet home = [];\nlet away = [];\n\n// Get all persons that are home excluding the arriver\nfor(var i=0; i<msg.payload.length; i++) {\n let current = msg.payload[i];\n if(current.entity_id != arriver) {\n\n // Rewrite names for special relations\n var other_name = (relations[arriver] || {})[current.entity_id] || current.attributes.friendly_name;\n\n if(current.state == \"home\") {\n home.push(other_name);\n } else if(persons_whitelist.includes(current.entity_id)) {\n away.push([other_name, relative_time(current.last_changed), current.last_changed]);\n }\n }\n}\n\n// Sort by away time (untested)\naway = away.sort(a => a[2]);\n\n// Create the message\n\n// Get a random greeting from r_greet\nlet greet = r_greet[Math.floor(Math.random()*r_greet.length)];\nlet is_are = home.length == 1 ? l10n[\"is\"] : l10n[\"are\"];\nlet others = smart_join(home);\n\nlet text = greet + arriver_name + \". \";\n\n// Just tell who is home when there is actually someone home\nif(home.length > 0) {\n text += l10n[\"xyz_is_also_home\"](others, is_are);\n}\n\n// Just tell who is away when there is actually someone away\nif(away.length > 0) {\n text += l10n[\"away_text\"](away);\n}\n\nmsg.payload.data = {\n message: l10n[\"final_text\"](text) \n};\n\nreturn msg;","outputs":1,"noerr":0,"x":1040,"y":660,"wires":[["5f00952f.0a657c"]]},{"id":"5f00952f.0a657c","type":"api-call-service","z":"974a0bef.a0e068","name":"📢 Alexa","version":1,"debugenabled":false,"service_domain":"notify","service":"alexa_media","entityId":"","data":"{\"data\":{\"type\":\"announce\",\"method\":\"all\"},\"target\":\"media_player.treppenhaus_echo_dot\"}","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":1280,"y":660,"wires":[[]]}]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment