NEST Monitoring via MQTT and Email

This is a flow for dealing with NEST thermostats and Node-Red

This flow will make a periodic request to NEST via its API and convert the data as needed to MQTT and it will send an email on abnormal events.

At this time it sends Temperature, Humidity and thermostat status to MQTT (other can be added if needed), it also checks for an online/offline status of each device and it sends an email when the device status changes. It also sends an email if the house transition from away to home, and if any thermostat sees a temperature below a set limit.

Each block has a manual trigger for testing and a periodic one for normal quires of the API at NEST.

To use, you need to get an API key and code from NEST developer web page...

You will need to supply your own API keys, Email information and MQTT settings.

[{"id":"84592574.c392a8","type":"tab","label":"NEST --> MQTT","disabled":false,"info":""},{"id":"99a019f0.3b8cd","type":"debug","z":"84592574.c392a8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":630,"y":200,"wires":[]},{"id":"4ef09543.2fffc4","type":"inject","z":"84592574.c392a8","name":"Trigger every 10 min","topic":"","payload":"","payloadType":"date","repeat":"600","crontab":"","once":true,"onceDelay":0.1,"x":160,"y":220,"wires":[["afca319.6ccbd5"]]},{"id":"bbfbe519.38e15","type":"function","z":"84592574.c392a8","name":"NEST Formating to MQTT","func":"// This will decode and build a MQTT message with NEST data\n// NEST sends us data as object, one for each device.\n// Data from NEST function is in JavaScrip format. We build a JSON object for output to MQTT\n\nfor (var key in msg.payload) \n{\n    var HVAC_Status = 0;\n    \n    if (msg.payload[key].hvac_state == \"off\")       HVAC_Status = 0;\n    if (msg.payload[key].hvac_state == \"cooling\")   HVAC_Status = 10;\n    if (msg.payload[key].hvac_state == \"heating\")   HVAC_Status = 20;\n    \n    var NEST = {HVAC_State: HVAC_Status, Temp: msg.payload[key].ambient_temperature_f, Humidity: msg.payload[key].humidity};\n    topic = msg.payload[key].name;\n    \n    var tmp_msg = {payload: NEST, topic: (\"MAINE/Nest/\" + msg.payload[key].name)};\n    node.send(tmp_msg);\n}\n","outputs":1,"noerr":0,"x":810,"y":160,"wires":[["5015cc39.3e1734","e9c2497a.aefab8","c7b5262d.d11a4"]],"outputLabels":["Master Bedroom"]},{"id":"5015cc39.3e1734","type":"debug","z":"84592574.c392a8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1170,"y":160,"wires":[]},{"id":"afca319.6ccbd5","type":"nest request","z":"84592574.c392a8","account":"","devicetype":"thermostats","deviceid":"","streaming":"false","name":"Maine, Nest Thermostats","x":410,"y":160,"wires":[["bbfbe519.38e15","99a019f0.3b8cd","9e83ccbd.46772"]]},{"id":"ce40983d.cba74","type":"json","z":"84592574.c392a8","name":"","property":"payload","action":"","pretty":false,"x":250,"y":1060,"wires":[["40a6b80f.3a332"]]},{"id":"40a6b80f.3a332","type":"debug","z":"84592574.c392a8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":530,"y":1060,"wires":[]},{"id":"d218375c.7b91b","type":"debug","z":"84592574.c392a8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":530,"y":980,"wires":[]},{"id":"ea62d029.225d88","type":"mqtt in","z":"84592574.c392a8","name":"MQTT","topic":"MAINE/Nest/#","qos":"0","broker":"eae2eea0.b47","x":90,"y":980,"wires":[["d218375c.7b91b","ce40983d.cba74"]]},{"id":"e9c2497a.aefab8","type":"mqtt out","z":"84592574.c392a8","name":"MQTT","topic":"","qos":"","retain":"","broker":"eae2eea0.b47","x":1150,"y":380,"wires":[]},{"id":"34ec3d58.7f8202","type":"inject","z":"84592574.c392a8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":160,"wires":[["afca319.6ccbd5"]]},{"id":"8b29d1c5.bf98e","type":"comment","z":"84592574.c392a8","name":"This will receive data frrom NEST thermostat in decode the data and form an MQTT message for each device","info":"","x":410,"y":60,"wires":[]},{"id":"c3e9496f.9a392","type":"comment","z":"84592574.c392a8","name":"This is for debug of the above NEST flow. It received the messages from MQTT server and display the data","info":"","x":400,"y":940,"wires":[]},{"id":"56783369.c39de4","type":"comment","z":"84592574.c392a8","name":"At this time, we process only NEST: status, temperature, and humidity","info":"","x":290,"y":100,"wires":[]},{"id":"60042a27.f18a5c","type":"delay","z":"84592574.c392a8","name":"","pauseType":"rate","timeout":"2","timeoutUnits":"seconds","rate":"2","nbRateUnits":"1","rateUnits":"day","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"x":770,"y":340,"wires":[["d487730f.a19a48"]]},{"id":"d487730f.a19a48","type":"e-mail","z":"84592574.c392a8","server":"smtp.gmail.com","port":"587","secure":false,"name":"[email protected]","dname":"Email Event -->","x":1180,"y":500,"wires":[]},{"id":"c7b5262d.d11a4","type":"switch","z":"84592574.c392a8","name":"Triger alarm if temperature < 40","property":"payload.Temp","propertyType":"msg","rules":[{"t":"lte","v":"40","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":230,"y":340,"wires":[["7ea64f21.a537a"]]},{"id":"7ea64f21.a537a","type":"function","z":"84592574.c392a8","name":"Temperature Message","func":"//var value = msg.payload.Temp;\n//var topic = msg.topic;\nvar msg1 = {};\nmsg1.payload = \"Maine House Thermostat: \" + msg.topic + \" is less than: \" + msg.payload.Temp + \" deg F \";\nmsg1.topic = msg.topic;\nreturn msg1;","outputs":1,"noerr":0,"x":520,"y":340,"wires":[["60042a27.f18a5c","cea0d1d6.4c9a7"]]},{"id":"cea0d1d6.4c9a7","type":"debug","z":"84592574.c392a8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":770,"y":400,"wires":[]},{"id":"bf950cd0.c090a","type":"nest request","z":"84592574.c392a8","account":"","devicetype":"structures","deviceid":"","streaming":"false","name":"Maine, Nest Structures","x":400,"y":740,"wires":[["452d2b70.906ac4","c9193076.b0bfe8"]]},{"id":"85c64ec3.dd8a6","type":"inject","z":"84592574.c392a8","name":"Trigger every 10 min","topic":"","payload":"","payloadType":"date","repeat":"600","crontab":"","once":true,"onceDelay":0.1,"x":160,"y":800,"wires":[["bf950cd0.c090a"]]},{"id":"305de388.fcdecc","type":"inject","z":"84592574.c392a8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":740,"wires":[["bf950cd0.c090a"]]},{"id":"c9193076.b0bfe8","type":"function","z":"84592574.c392a8","name":"NEST Structure Decoding","func":"// This will decode Structures message with NEST data\n// Data from NEST function is in JavaScrip format. \n\nfor (var key in msg.payload) \n{\n    var Home_Status = 0;\n    var tmp_msg  = {payload: \"Nest Maine House Status is now: \" + msg.payload[key].away, topic: \"Maine NEST-Status\"};\n    \n    if (msg.payload[key].away == \"home\") Home_Status = 20;\n    if (msg.payload[key].away == \"away\") Home_Status = 0;\n    \n    var NEST = {Home_State: Home_Status};\n    var tmp_msg1 = {payload: NEST, topic: \"MAINE/Nest/HomeStatus\"};\n\n    node.send([tmp_msg, tmp_msg1]);\n}\n\n","outputs":2,"noerr":0,"x":650,"y":740,"wires":[["bb249299.7c8bd","7b30e8d0.587f18","60d1753f.92ce34"],["fb7751c2.43b92","453c94f6.f457cc","e9c2497a.aefab8"]],"outputLabels":["Master Bedroom",""]},{"id":"452d2b70.906ac4","type":"debug","z":"84592574.c392a8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":610,"y":800,"wires":[]},{"id":"bb249299.7c8bd","type":"debug","z":"84592574.c392a8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":930,"y":780,"wires":[]},{"id":"4dde4e0c.bb73e8","type":"comment","z":"84592574.c392a8","name":"NEST Structure API","info":"\n\"structures\": {\n\n    \"VqFabWH21nwVyd4RWgJgNb292wa7hG_dUwo2i2SG7j3-BOLY0BA4sw\": {\n        \"structure_id\" : \"VqFabWH21nwVyd4RWgJgNb292wa7hG_dUwo2i2SG7j3-BOLY0BA4sw\",\n        \"thermostats\" : [\"peyiJNo0IldT2YlIVtYaGQ\", ...],\n        \"smoke_co_alarms\" : [\"RTMTKxsQTCxzVcsySOHPxKoF4OyCifrs\", ...],\n        \"cameras\" : [\"awJo6r...\", ...],\n        \"away\" : \"home\",\n        \"name\" : \"Home\",\n        \"country_code\" : \"US\",\n        \"postal_code\" : \"94304\",\n        \"peak_period_start_time\" : \"2016-10-31T23:59:59.000Z\",\n        \"peak_period_end_time\" : \"2016-10-31T23:59:59.000Z\",\n        \"time_zone\" : \"America/Los_Angeles\",\n        \"eta\": {\n            \"trip_id\" : \"myTripHome1024\",\n            \"estimated_arrival_window_begin\" : \"2016-10-31T22:42:59.000Z\",\n            \"estimated_arrival_window_end\" : \"2016-10-31T23:59:59.000Z\"\n        },\n        \"eta_begin\" : \"2016-08-04T13:21:37-07:00\",\n        \"co_alarm_state\" : \"ok\",\n        \"smoke_alarm_state\" : \"ok\",\n        \"rhr_enrollment\" : true,\n        \"wwn_security_state\" : \"ok\",\n        \"wheres\": {\n            \"Fqp6wJI...\": {\n                \"where_id\" : \"Fqp6wJI...\",\n                \"name\" : \"Bedroom\"\n            }\n        }\n    }\n\n","x":830,"y":100,"wires":[]},{"id":"cfaa5de0.bce7b","type":"comment","z":"84592574.c392a8","name":"API Keys","info":"A place to store API Keys\n\nProduct ID:  4cdff202-b0b3-4830-89e7-f3e92e01a668\n\nSecret:  rFF22bZNxFIkGL81txeDdvFxk","x":640,"y":100,"wires":[]},{"id":"7b30e8d0.587f18","type":"debug","z":"84592574.c392a8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"topic","x":920,"y":820,"wires":[]},{"id":"ba900410.b06898","type":"debug","z":"84592574.c392a8","name":"message (as is)","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":1180,"y":740,"wires":[]},{"id":"60d1753f.92ce34","type":"rbe","z":"84592574.c392a8","name":"Change Only","func":"rbei","gap":"","start":"","inout":"out","property":"payload","x":930,"y":740,"wires":[["ba900410.b06898","d487730f.a19a48"]]},{"id":"9e83ccbd.46772","type":"function","z":"84592574.c392a8","name":"NEST offline Decoding","func":"// This will decode and build a MQTT message with NEST data\n// NEST sends us data as 6 object, one for each device.\n// Data from NEST function is in JavaScrip format.\n\nvar msg1 = {};\nvar msg2 = {};\nvar NEST = {};\n\nfor (var key in msg.payload) \n{\n    if (msg.payload[key].is_online === false)  \n    {\n      msg1.payload = \"Nest Thermostat: \" + msg.payload[key].name + \" is offline\";\n      NEST = {OfflineStatus: 20};\n    }\n    \n    if (msg.payload[key].is_online === true)  \n    {\n      msg1.payload = \"Nest Thermostat: \" + msg.payload[key].name + \" is online\";\n      NEST = {OfflineStatus: 0};\n    }\n    \n    msg1.topic = msg.payload[key].name;\n    msg2 = {payload: NEST, topic: \"MAINE/Nest/OfflineStatus/\" + msg.payload[key].name};\n    node.send([msg1, msg2]);\n}\n\n","outputs":2,"noerr":0,"x":520,"y":480,"wires":[["ba90b1ca.cee7b"],["e9c2497a.aefab8","a7b4c898.af3e9","dde3e2e3.ce5f3"]],"outputLabels":["Master Bedroom",""]},{"id":"dde3e2e3.ce5f3","type":"debug","z":"84592574.c392a8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":750,"y":600,"wires":[]},{"id":"a7b4c898.af3e9","type":"debug","z":"84592574.c392a8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"topic","x":740,"y":560,"wires":[]},{"id":"5b59ad02.823dfc","type":"comment","z":"84592574.c392a8","name":"Send an Email if a  NEST device is offline","info":"","x":200,"y":420,"wires":[]},{"id":"bfaedf30.40e3d","type":"comment","z":"84592574.c392a8","name":"Send a Email if NEST status changes from  Home or Away","info":"","x":250,"y":680,"wires":[]},{"id":"e209537d.65bdd","type":"comment","z":"84592574.c392a8","name":"Send an Email alarm if temp is to low.","info":"","x":190,"y":280,"wires":[]},{"id":"ba90b1ca.cee7b","type":"rbe","z":"84592574.c392a8","name":"Change Only","func":"rbei","gap":"","start":"","inout":"out","property":"payload","x":750,"y":500,"wires":[["d487730f.a19a48"]]},{"id":"98b815dd.dd402","type":"comment","z":"84592574.c392a8","name":"NEST Thermostats API","info":"\n\n1JPYYYikD-CLJsgBgjtjx_6CwBp1ulrM: object\nhumidity: 30\nlocale: \"en-US\"\ntemperature_scale: \"F\"\nis_using_emergency_heat: false\nhas_fan: true\nsoftware_version: \"5.9.3-6\"\nhas_leaf: true\nwhere_id: \"F2-gxe4lGV1YjYqLn9k2wJDJxzopY25M5aisvXM8VX5hQa3E_xyFkg\"\ndevice_id: \"1JPYYYikD-CLJsgBgjtjx_6CwBp1ulrM\"\nname: \"Master-Bedroom\"\ncan_heat: true\ncan_cool: true\ntarget_temperature_c: 21\ntarget_temperature_f: 70\ntarget_temperature_high_c: 24\ntarget_temperature_high_f: 75\ntarget_temperature_low_c: 20\ntarget_temperature_low_f: 68\nambient_temperature_c: 11.5\nambient_temperature_f: 53\naway_temperature_high_c: 24\naway_temperature_high_f: 76\naway_temperature_low_c: 5.5\naway_temperature_low_f: 42\neco_temperature_high_c: 24\neco_temperature_high_f: 76\neco_temperature_low_c: 5.5\neco_temperature_low_f: 42\nis_locked: false\nlocked_temp_min_c: 18\nlocked_temp_min_f: 65\nlocked_temp_max_c: 22\nlocked_temp_max_f: 72\nsunlight_correction_active: false\nsunlight_correction_enabled: true\nstructure_id: \"PaI2F60FgI4i2psdiVgJObiBNBAFyw2-GEWeKM2ulD99N_-gnJGIgg\"\nfan_timer_active: false\nfan_timer_timeout: \"1970-01-01T00:00:00.000Z\"\nfan_timer_duration: 15\nprevious_hvac_mode: \"heat\"\nhvac_mode: \"eco\"\ntime_to_target: \"~0\"\ntime_to_target_training: \"ready\"\nwhere_name: \"Master-Bedroom\"\nlabel: \"\"\nname_long: \"Master-Bedroom Thermostat\"\nis_online: true\nlast_connection: \"2019-02-14T19:52:07.567Z\"\nhvac_state: \"off\"\n\n","x":1060,"y":100,"wires":[]},{"id":"fb7751c2.43b92","type":"debug","z":"84592574.c392a8","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":930,"y":880,"wires":[]},{"id":"453c94f6.f457cc","type":"debug","z":"84592574.c392a8","name":"","active":false,"tosidebar":true,"console":true,"tostatus":true,"complete":"topic","x":930,"y":920,"wires":[]},{"id":"eae2eea0.b47","type":"mqtt-broker","z":"","name":"test-broker ","broker":"mqtt.test.xyz","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

Flow Info

Created 6 years, 8 months ago
Rating: not yet rated

Owner

Actions

Rate:

Node Types

Core
  • comment (x9)
  • debug (x13)
  • delay (x1)
  • function (x4)
  • inject (x4)
  • json (x1)
  • mqtt in (x1)
  • mqtt out (x1)
  • mqtt-broker (x1)
  • rbe (x2)
  • switch (x1)
Other

Tags

  • NEST
  • MQTT
  • Email
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option