├── .gitignore ├── SmartPlug-Dashboard.png ├── SmartPlug-Dashboard-flow.png ├── SensorTagWiFi-SmartPlug-flow.png ├── package.json ├── README.md ├── LICENSE └── flow.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.backup -------------------------------------------------------------------------------- /SmartPlug-Dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnwalicki/Node-RED-Contrib-SmartPlug-Example/master/SmartPlug-Dashboard.png -------------------------------------------------------------------------------- /SmartPlug-Dashboard-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnwalicki/Node-RED-Contrib-SmartPlug-Example/master/SmartPlug-Dashboard-flow.png -------------------------------------------------------------------------------- /SensorTagWiFi-SmartPlug-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnwalicki/Node-RED-Contrib-SmartPlug-Example/master/SensorTagWiFi-SmartPlug-flow.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SmartPlug", 3 | "description": "EdiMax SmartPlug Samples", 4 | "version": "0.0.1", 5 | "dependencies": {}, 6 | "node-red": { 7 | "settings": { 8 | "flowFile": "flow.json", 9 | "credentialsFile": "flow_cred.json" 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## EdiMax SmartPlug / TI SensorTag 3200 WiFi Example 2 | --- 3 | This example uses a 4 | [WiFi connected TI SensorTag 3200](https://developer.ibm.com/recipes/tutorials/texas-instruments-cc3200-simplelink-wifi-sensortag/) 5 | to control an 6 | [EdiMax SmartPlug](http://www.edimax.com/edimax/merchandise/merchandise_detail/data/edimax/global/home_automation_smart_plug/sp-2101w/) 7 | that turns on and off a space heater in my home office. I only want the heater to be on when 8 | the lights are on and the temperature is low. If I'm not working and the lights are off, 9 | I don't need to heat the basement room that I use as my home office. 10 | 11 | I created some Node-RED [flows](flow.json) that query the temperature and luminosity from the TI SensorTag once a minute. 12 | The flow uses the [node-red-contrib-smartplug nodes](https://flows.nodered.org/node/node-red-contrib-smartplug) to turn on/off the SmartPlug. 13 | 14 | I also created a simple Node-RED Dashboard to display power consumption and adjust the "thermostat". 15 | ![Node-RED Dashboard SmartPlug SensorTag](SmartPlug-Dashboard.png?raw=true "Node-RED Dashboard SmartPlug SensorTag") 16 | 17 | I should mention that I run this Node-RED flow on a Raspberry Pi that controls a variety of home automation tasks. 18 | 19 | Here are the two Node-RED flows: 20 | ![Node-RED SmartPlug flow](SmartPlug-Dashboard-flow.png?raw=true "Node-RED SmartPlug flow") 21 | ![Node-RED SensorTag WiFi](SensorTagWiFi-SmartPlug-flow.png?raw=true "Node-RED SensorTag SmartPlug flow") 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /flow.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "2a9757da.00a358", 4 | "type": "tab", 5 | "label": "SensorTag WiFi", 6 | "disabled": false, 7 | "info": "" 8 | }, 9 | { 10 | "id": "76259739.2b009", 11 | "type": "tab", 12 | "label": "SmartPlug", 13 | "disabled": false, 14 | "info": "" 15 | }, 16 | { 17 | "id": "9db9679f.43f6b8", 18 | "type": "ui_base", 19 | "theme": { 20 | "name": "theme-light", 21 | "lightTheme": { 22 | "default": "#0094CE", 23 | "baseColor": "#0094CE", 24 | "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", 25 | "edited": true, 26 | "reset": false 27 | }, 28 | "darkTheme": { 29 | "default": "#097479", 30 | "baseColor": "#097479", 31 | "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif", 32 | "edited": false 33 | }, 34 | "customTheme": { 35 | "name": "Untitled Theme 1", 36 | "default": "#4B7930", 37 | "baseColor": "#4B7930", 38 | "baseFont": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif" 39 | }, 40 | "themeState": { 41 | "base-color": { 42 | "default": "#0094CE", 43 | "value": "#0094CE", 44 | "edited": false 45 | }, 46 | "page-titlebar-backgroundColor": { 47 | "value": "#0094CE", 48 | "edited": false 49 | }, 50 | "page-backgroundColor": { 51 | "value": "#fafafa", 52 | "edited": false 53 | }, 54 | "page-sidebar-backgroundColor": { 55 | "value": "#ffffff", 56 | "edited": false 57 | }, 58 | "group-textColor": { 59 | "value": "#1bbfff", 60 | "edited": false 61 | }, 62 | "group-borderColor": { 63 | "value": "#ffffff", 64 | "edited": false 65 | }, 66 | "group-backgroundColor": { 67 | "value": "#ffffff", 68 | "edited": false 69 | }, 70 | "widget-textColor": { 71 | "value": "#111111", 72 | "edited": false 73 | }, 74 | "widget-backgroundColor": { 75 | "value": "#0094ce", 76 | "edited": false 77 | }, 78 | "widget-borderColor": { 79 | "value": "#ffffff", 80 | "edited": false 81 | }, 82 | "base-font": { 83 | "value": "-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif" 84 | } 85 | }, 86 | "angularTheme": { 87 | "primary": "indigo", 88 | "accents": "blue", 89 | "warn": "red", 90 | "background": "grey" 91 | } 92 | }, 93 | "site": { 94 | "name": "Node-RED Dashboard", 95 | "hideToolbar": "false", 96 | "allowSwipe": "false", 97 | "dateFormat": "DD/MM/YYYY", 98 | "sizes": { 99 | "sx": 48, 100 | "sy": 48, 101 | "gx": 6, 102 | "gy": 6, 103 | "cx": 6, 104 | "cy": 6, 105 | "px": 0, 106 | "py": 0 107 | } 108 | } 109 | }, 110 | { 111 | "id": "1b227b5c.bfe23d", 112 | "type": "ui_group", 113 | "z": "", 114 | "name": "SmartPlug Switch", 115 | "tab": "d237a06d.7b85", 116 | "order": 1, 117 | "disp": true, 118 | "width": "4" 119 | }, 120 | { 121 | "id": "f809ef74.a1c1b", 122 | "type": "ui_group", 123 | "z": "", 124 | "name": "SmartPlug Power Usage Chart", 125 | "tab": "d237a06d.7b85", 126 | "order": 2, 127 | "disp": true, 128 | "width": "8" 129 | }, 130 | { 131 | "id": "80f4c6a4.b4b338", 132 | "type": "ui_group", 133 | "z": "", 134 | "name": "SmartPlug Current Usage Chart", 135 | "tab": "d237a06d.7b85", 136 | "order": 3, 137 | "disp": true, 138 | "width": "8" 139 | }, 140 | { 141 | "id": "d237a06d.7b85", 142 | "type": "ui_tab", 143 | "z": "", 144 | "name": "SmartPlug", 145 | "icon": "dashboard", 146 | "order": 1 147 | }, 148 | { 149 | "id": "5980bd4a.72497c", 150 | "type": "http request", 151 | "z": "2a9757da.00a358", 152 | "name": "", 153 | "method": "GET", 154 | "ret": "txt", 155 | "paytoqs": false, 156 | "url": "http://192.168.1.xxx/param_sensortag_poll.html", 157 | "tls": "", 158 | "proxy": "", 159 | "x": 270, 160 | "y": 160, 161 | "wires": [ 162 | [ 163 | "f7d6af85.345c6", 164 | "d9fd79dd.8dd0c" 165 | ] 166 | ] 167 | }, 168 | { 169 | "id": "44aa7a87.723cac", 170 | "type": "inject", 171 | "z": "2a9757da.00a358", 172 | "name": "", 173 | "topic": "", 174 | "payload": "true", 175 | "payloadType": "bool", 176 | "repeat": "60", 177 | "crontab": "", 178 | "once": true, 179 | "x": 100, 180 | "y": 160, 181 | "wires": [ 182 | [ 183 | "5980bd4a.72497c" 184 | ] 185 | ] 186 | }, 187 | { 188 | "id": "3effa246.2a9b76", 189 | "type": "debug", 190 | "z": "2a9757da.00a358", 191 | "name": "", 192 | "active": true, 193 | "console": "false", 194 | "complete": "false", 195 | "x": 410, 196 | "y": 280, 197 | "wires": [] 198 | }, 199 | { 200 | "id": "39734624.9e327a", 201 | "type": "function", 202 | "z": "2a9757da.00a358", 203 | "name": "Extract SensorTag data", 204 | "func": "var sensortagdata = msg.payload.split(/\\r?\\n/);\nvar temperature = -1;\nvar lux = -1;\nvar bar ;\nvar hum ;\nvar gyr = {};\nvar acc = {};\nvar mag = {};\n\nfor( i=0; i < sensortagdata.length; i++ ) {\n if( sensortagdata[i].indexOf(\"tmp\") >=0 ) {\n // Get the Temperature\n // \"

09C8 1170 19.56 34.88

\"\n // Grab the 4th substring\n var t = sensortagdata[i].split(\" \");\n //temperature = parseInt( t[4].substring(0,4) );\n temperature = parseFloat( t[4] );\n } else if (sensortagdata[i].indexOf(\"hum\") >=0 ) {\n // Get the humidity\n //

57D8 7558 34.31 35.63

\n // Grab the 4th substring\n var h = sensortagdata[i].split(\" \");\n hum = parseFloat( h[4] );\n } else if (sensortagdata[i].indexOf(\"opt\") >=0 ) {\n // Get the Light lux\n //

2E9B 149.56

\n // Grab the 3nd substring\n var l = sensortagdata[i].split(\" \");\n var n = l[2].indexOf(\"<\");\n lux = parseInt( l[2].substring(0,n-1) );\n } else if (sensortagdata[i].indexOf(\"gyr\") >=0 ) {\n // Get the gyroscope data\n //

FEFE 000C FFA1 -1.97 0.09 -0.73

\n var g = sensortagdata[i].split(\" \");\n gyr.x = parseFloat( g[4] );\n gyr.y = parseFloat( g[5] );\n gyr.z = parseFloat( g[6] );\n } else if (sensortagdata[i].indexOf(\"acc\") >=0 ) {\n // Get the Accelerometer data\n //

000C 0144 EEED 0.00 0.08 -1.07

\n var a = sensortagdata[i].split(\" \");\n acc.x = parseFloat( a[4] );\n acc.y = parseFloat( a[5] );\n acc.z = parseFloat( a[6] );\n } else if (sensortagdata[i].indexOf(\"mag\") >=0 ) {\n // Get the magnetometer data\n //

FF14 FFD7 FDB2 -236 -41 -590

\n var m = sensortagdata[i].split(\" \");\n mag.x = parseFloat( m[4] );\n mag.y = parseFloat( m[5] );\n mag.z = parseFloat( m[6] );\n } else if (sensortagdata[i].indexOf(\"bar\") >=0 ) {\n // Get the Barometer data\n //

564860 86B200 36.10 1016.34

\n // Grab the 5th substring\n var b = sensortagdata[i].split(\" \");\n bar = parseFloat( b[4] );\n }\n}\nmsg.payload = { \"temperature\": temperature, \n \"lux\" : lux,\n \"humidity\" : hum,\n \"barometer\" : bar,\n \"gyroscope\" : gyr,\n \"accelometer\" : acc,\n \"magnetometer\": mag\n} ;\nreturn msg;", 205 | "outputs": 1, 206 | "noerr": 0, 207 | "x": 170, 208 | "y": 320, 209 | "wires": [ 210 | [ 211 | "3effa246.2a9b76", 212 | "4cd35186.d23008", 213 | "c0e83223.d815e", 214 | "332a03f5.08e634" 215 | ] 216 | ] 217 | }, 218 | { 219 | "id": "64086ba7.aac58c", 220 | "type": "comment", 221 | "z": "2a9757da.00a358", 222 | "name": "http://192.168.1.x/sensortag.html", 223 | "info": "", 224 | "x": 150, 225 | "y": 60, 226 | "wires": [] 227 | }, 228 | { 229 | "id": "c5ef53c.21151b", 230 | "type": "comment", 231 | "z": "2a9757da.00a358", 232 | "name": "http://192.168.1.x/param_sensortag_poll.html", 233 | "info": "", 234 | "x": 190, 235 | "y": 100, 236 | "wires": [] 237 | }, 238 | { 239 | "id": "f7d6af85.345c6", 240 | "type": "debug", 241 | "z": "2a9757da.00a358", 242 | "name": "", 243 | "active": true, 244 | "console": "false", 245 | "complete": "true", 246 | "x": 470, 247 | "y": 120, 248 | "wires": [] 249 | }, 250 | { 251 | "id": "4cd35186.d23008", 252 | "type": "switch", 253 | "z": "2a9757da.00a358", 254 | "name": "Lights on?", 255 | "property": "payload.lux", 256 | "propertyType": "msg", 257 | "rules": [ 258 | { 259 | "t": "gt", 260 | "v": "50", 261 | "vt": "num" 262 | }, 263 | { 264 | "t": "else" 265 | } 266 | ], 267 | "checkall": "true", 268 | "outputs": 2, 269 | "x": 410, 270 | "y": 400, 271 | "wires": [ 272 | [ 273 | "11529d8e.9b8682" 274 | ], 275 | [ 276 | "9dbfce0c.813c8" 277 | ] 278 | ] 279 | }, 280 | { 281 | "id": "11529d8e.9b8682", 282 | "type": "switch", 283 | "z": "2a9757da.00a358", 284 | "name": "What's the temp", 285 | "property": "payload.temperature", 286 | "propertyType": "msg", 287 | "rules": [ 288 | { 289 | "t": "lt", 290 | "v": "settemp", 291 | "vt": "flow" 292 | }, 293 | { 294 | "t": "else" 295 | } 296 | ], 297 | "checkall": "true", 298 | "outputs": 2, 299 | "x": 620, 300 | "y": 360, 301 | "wires": [ 302 | [ 303 | "54511011.7fa668" 304 | ], 305 | [ 306 | "9dbfce0c.813c8" 307 | ] 308 | ] 309 | }, 310 | { 311 | "id": "4736031.06240fc", 312 | "type": "comment", 313 | "z": "2a9757da.00a358", 314 | "name": "Light is on, temp is cool", 315 | "info": "", 316 | "x": 840, 317 | "y": 440, 318 | "wires": [] 319 | }, 320 | { 321 | "id": "201aa5fe.f9bac2", 322 | "type": "debug", 323 | "z": "2a9757da.00a358", 324 | "name": "Heater Status", 325 | "active": true, 326 | "console": "false", 327 | "complete": "payload", 328 | "x": 1020, 329 | "y": 360, 330 | "wires": [] 331 | }, 332 | { 333 | "id": "c1053a96.7f99d8", 334 | "type": "smartplug-out", 335 | "z": "2a9757da.00a358", 336 | "name": "", 337 | "topic": "", 338 | "device": "3d0507df.842c58", 339 | "response": true, 340 | "x": 1030, 341 | "y": 400, 342 | "wires": [ 343 | [] 344 | ] 345 | }, 346 | { 347 | "id": "9dbfce0c.813c8", 348 | "type": "change", 349 | "z": "2a9757da.00a358", 350 | "name": "Heat Off", 351 | "rules": [ 352 | { 353 | "t": "set", 354 | "p": "payload", 355 | "pt": "msg", 356 | "to": "false", 357 | "tot": "bool" 358 | } 359 | ], 360 | "action": "", 361 | "property": "", 362 | "from": "", 363 | "to": "", 364 | "reg": false, 365 | "x": 820, 366 | "y": 400, 367 | "wires": [ 368 | [ 369 | "c1053a96.7f99d8", 370 | "201aa5fe.f9bac2" 371 | ] 372 | ] 373 | }, 374 | { 375 | "id": "54511011.7fa668", 376 | "type": "change", 377 | "z": "2a9757da.00a358", 378 | "name": "Heat On", 379 | "rules": [ 380 | { 381 | "t": "set", 382 | "p": "payload", 383 | "pt": "msg", 384 | "to": "true", 385 | "tot": "bool" 386 | } 387 | ], 388 | "action": "", 389 | "property": "", 390 | "from": "", 391 | "to": "", 392 | "reg": false, 393 | "x": 820, 394 | "y": 360, 395 | "wires": [ 396 | [ 397 | "c1053a96.7f99d8", 398 | "201aa5fe.f9bac2" 399 | ] 400 | ] 401 | }, 402 | { 403 | "id": "8f3610f8.e13dc", 404 | "type": "inject", 405 | "z": "2a9757da.00a358", 406 | "name": "Override", 407 | "topic": "", 408 | "payload": "false", 409 | "payloadType": "bool", 410 | "repeat": "", 411 | "crontab": "", 412 | "once": false, 413 | "x": 640, 414 | "y": 440, 415 | "wires": [ 416 | [ 417 | "9dbfce0c.813c8" 418 | ] 419 | ] 420 | }, 421 | { 422 | "id": "232efc19.94d184", 423 | "type": "smartplug-in", 424 | "z": "76259739.2b009", 425 | "name": "", 426 | "topic": "", 427 | "device": "3d0507df.842c58", 428 | "interval": "10000", 429 | "deviceinfo": true, 430 | "schedule": true, 431 | "status": { 432 | "text": "connected", 433 | "fill": "green", 434 | "shape": "dot" 435 | }, 436 | "cost": true, 437 | "costFactor": 0.2, 438 | "costUnit": "$", 439 | "x": 110, 440 | "y": 100, 441 | "wires": [ 442 | [ 443 | "ea34cb47.e7527", 444 | "770323b5.2d313c", 445 | "9867d0e3.ffdd8" 446 | ] 447 | ] 448 | }, 449 | { 450 | "id": "1807c7e1.fde698", 451 | "type": "smartplug-out", 452 | "z": "76259739.2b009", 453 | "name": "", 454 | "topic": "", 455 | "device": "3d0507df.842c58", 456 | "response": true, 457 | "x": 330, 458 | "y": 240, 459 | "wires": [ 460 | [ 461 | "1aa6c9e6.6ca4a6" 462 | ] 463 | ] 464 | }, 465 | { 466 | "id": "ea34cb47.e7527", 467 | "type": "debug", 468 | "z": "76259739.2b009", 469 | "name": "", 470 | "active": false, 471 | "console": "false", 472 | "complete": "false", 473 | "x": 310, 474 | "y": 60, 475 | "wires": [] 476 | }, 477 | { 478 | "id": "2cce57a.528f5a8", 479 | "type": "inject", 480 | "z": "76259739.2b009", 481 | "name": "On", 482 | "topic": "", 483 | "payload": "true", 484 | "payloadType": "bool", 485 | "repeat": "", 486 | "crontab": "", 487 | "once": false, 488 | "x": 110, 489 | "y": 200, 490 | "wires": [ 491 | [ 492 | "1807c7e1.fde698" 493 | ] 494 | ] 495 | }, 496 | { 497 | "id": "79999de0.3dcea4", 498 | "type": "inject", 499 | "z": "76259739.2b009", 500 | "name": "Off", 501 | "topic": "", 502 | "payload": "false", 503 | "payloadType": "bool", 504 | "repeat": "", 505 | "crontab": "", 506 | "once": false, 507 | "x": 110, 508 | "y": 240, 509 | "wires": [ 510 | [ 511 | "1807c7e1.fde698" 512 | ] 513 | ] 514 | }, 515 | { 516 | "id": "b4112037.b56f88", 517 | "type": "ui_switch", 518 | "z": "76259739.2b009", 519 | "name": "", 520 | "label": "On/Off", 521 | "group": "1b227b5c.bfe23d", 522 | "order": 1, 523 | "width": 0, 524 | "height": 0, 525 | "passthru": true, 526 | "decouple": "false", 527 | "topic": "", 528 | "style": "", 529 | "onvalue": "true", 530 | "onvalueType": "bool", 531 | "onicon": "", 532 | "oncolor": "", 533 | "offvalue": "false", 534 | "offvalueType": "bool", 535 | "officon": "", 536 | "offcolor": "", 537 | "x": 110, 538 | "y": 280, 539 | "wires": [ 540 | [ 541 | "1807c7e1.fde698" 542 | ] 543 | ] 544 | }, 545 | { 546 | "id": "29b26dcf.3afeda", 547 | "type": "ui_chart", 548 | "z": "76259739.2b009", 549 | "name": "", 550 | "group": "f809ef74.a1c1b", 551 | "order": 1, 552 | "width": 0, 553 | "height": 0, 554 | "label": "Power Consumption", 555 | "chartType": "line", 556 | "legend": "true", 557 | "xformat": "HH:mm:ss", 558 | "interpolate": "step", 559 | "nodata": "", 560 | "dot": false, 561 | "ymin": "0", 562 | "ymax": "2000", 563 | "removeOlder": "10", 564 | "removeOlderPoints": "", 565 | "removeOlderUnit": "60", 566 | "cutout": 0, 567 | "useOneColor": false, 568 | "colors": [ 569 | "#1f77b4", 570 | "#aec7e8", 571 | "#ff7f0e", 572 | "#2ca02c", 573 | "#98df8a", 574 | "#d62728", 575 | "#ff9896", 576 | "#9467bd", 577 | "#c5b0d5" 578 | ], 579 | "useOldStyle": false, 580 | "outputs": 2, 581 | "x": 560, 582 | "y": 100, 583 | "wires": [ 584 | [], 585 | [] 586 | ] 587 | }, 588 | { 589 | "id": "9867d0e3.ffdd8", 590 | "type": "change", 591 | "z": "76259739.2b009", 592 | "name": "Extract Current", 593 | "rules": [ 594 | { 595 | "t": "set", 596 | "p": "payload", 597 | "pt": "msg", 598 | "to": "payload.status.nowCurrent", 599 | "tot": "msg" 600 | }, 601 | { 602 | "t": "set", 603 | "p": "topic", 604 | "pt": "msg", 605 | "to": "Current (A)", 606 | "tot": "str" 607 | } 608 | ], 609 | "action": "", 610 | "property": "", 611 | "from": "", 612 | "to": "", 613 | "reg": false, 614 | "x": 320, 615 | "y": 140, 616 | "wires": [ 617 | [ 618 | "6a72fb4a.7002f4", 619 | "bf331ae8.7acd08" 620 | ] 621 | ] 622 | }, 623 | { 624 | "id": "770323b5.2d313c", 625 | "type": "change", 626 | "z": "76259739.2b009", 627 | "name": "Extract Power", 628 | "rules": [ 629 | { 630 | "t": "set", 631 | "p": "payload", 632 | "pt": "msg", 633 | "to": "payload.status.nowPower", 634 | "tot": "msg" 635 | }, 636 | { 637 | "t": "set", 638 | "p": "topic", 639 | "pt": "msg", 640 | "to": "Power (W)", 641 | "tot": "str" 642 | } 643 | ], 644 | "action": "", 645 | "property": "", 646 | "from": "", 647 | "to": "", 648 | "reg": false, 649 | "x": 320, 650 | "y": 100, 651 | "wires": [ 652 | [ 653 | "29b26dcf.3afeda" 654 | ] 655 | ] 656 | }, 657 | { 658 | "id": "6a72fb4a.7002f4", 659 | "type": "ui_chart", 660 | "z": "76259739.2b009", 661 | "name": "", 662 | "group": "80f4c6a4.b4b338", 663 | "order": 0, 664 | "width": 0, 665 | "height": 0, 666 | "label": "Current Usage", 667 | "chartType": "line", 668 | "legend": "true", 669 | "xformat": "HH:mm:ss", 670 | "interpolate": "step", 671 | "nodata": "", 672 | "dot": false, 673 | "ymin": "0", 674 | "ymax": "18", 675 | "removeOlder": "10", 676 | "removeOlderPoints": "", 677 | "removeOlderUnit": "60", 678 | "cutout": 0, 679 | "useOneColor": false, 680 | "colors": [ 681 | "#1f77b4", 682 | "#aec7e8", 683 | "#ff7f0e", 684 | "#2ca02c", 685 | "#98df8a", 686 | "#d62728", 687 | "#ff9896", 688 | "#9467bd", 689 | "#c5b0d5" 690 | ], 691 | "useOldStyle": false, 692 | "outputs": 2, 693 | "x": 540, 694 | "y": 140, 695 | "wires": [ 696 | [], 697 | [] 698 | ] 699 | }, 700 | { 701 | "id": "bf331ae8.7acd08", 702 | "type": "ui_gauge", 703 | "z": "76259739.2b009", 704 | "name": "", 705 | "group": "80f4c6a4.b4b338", 706 | "order": 0, 707 | "width": 0, 708 | "height": 0, 709 | "gtype": "gage", 710 | "title": "Current (A)", 711 | "label": "Amps", 712 | "format": "{{value}}", 713 | "min": 0, 714 | "max": "15", 715 | "colors": [ 716 | "#00b500", 717 | "#e6e600", 718 | "#ca3838" 719 | ], 720 | "seg1": "", 721 | "seg2": "", 722 | "x": 530, 723 | "y": 180, 724 | "wires": [] 725 | }, 726 | { 727 | "id": "2f2eca1c.c83496", 728 | "type": "comment", 729 | "z": "76259739.2b009", 730 | "name": "How To", 731 | "info": "username is admin\npassword is 1234\n\nInstall the Android/iOS app \nhttps://play.google.com/store/apps/details?id=com.edimax.smartplugin&hl=en\n\n$28 EdiMax WiFi enabled smartplug :\nhttp://www.edimax.com/edimax/merchandise/merchandise_detail/data/edimax/global/home_automation_smart_plug/sp-2101w/\n\nNode package that allows it to be discovered and controlled over WiFi\nhttps://github.com/mwittig/edimax-smartplug\n\nNode-RED node that can be integrated into our flows.\nhttps://flows.nodered.org/node/node-red-contrib-smartplug ", 732 | "x": 90, 733 | "y": 40, 734 | "wires": [] 735 | }, 736 | { 737 | "id": "1aa6c9e6.6ca4a6", 738 | "type": "debug", 739 | "z": "76259739.2b009", 740 | "name": "", 741 | "active": true, 742 | "console": "false", 743 | "complete": "false", 744 | "x": 530, 745 | "y": 240, 746 | "wires": [] 747 | }, 748 | { 749 | "id": "d9fd79dd.8dd0c", 750 | "type": "switch", 751 | "z": "2a9757da.00a358", 752 | "name": "Fail on Error", 753 | "property": "payload", 754 | "propertyType": "msg", 755 | "rules": [ 756 | { 757 | "t": "cont", 758 | "v": "Error: connect EHOSTUNREACH ", 759 | "vt": "str" 760 | }, 761 | { 762 | "t": "else" 763 | } 764 | ], 765 | "checkall": "true", 766 | "outputs": 2, 767 | "x": 490, 768 | "y": 160, 769 | "wires": [ 770 | [], 771 | [ 772 | "39734624.9e327a" 773 | ] 774 | ] 775 | }, 776 | { 777 | "id": "c0e83223.d815e", 778 | "type": "change", 779 | "z": "2a9757da.00a358", 780 | "name": "SensorTag Temp", 781 | "rules": [ 782 | { 783 | "t": "set", 784 | "p": "payload", 785 | "pt": "msg", 786 | "to": "payload.temperature", 787 | "tot": "msg" 788 | } 789 | ], 790 | "action": "", 791 | "property": "", 792 | "from": "", 793 | "to": "", 794 | "reg": false, 795 | "x": 430, 796 | "y": 320, 797 | "wires": [ 798 | [ 799 | "f659bd43.4365a", 800 | "802cc3da.8124" 801 | ] 802 | ] 803 | }, 804 | { 805 | "id": "f659bd43.4365a", 806 | "type": "ui_text", 807 | "z": "2a9757da.00a358", 808 | "group": "1b227b5c.bfe23d", 809 | "order": 2, 810 | "width": 0, 811 | "height": 0, 812 | "name": "", 813 | "label": "Current Temp", 814 | "format": "{{msg.payload}}", 815 | "layout": "row-spread", 816 | "x": 640, 817 | "y": 320, 818 | "wires": [] 819 | }, 820 | { 821 | "id": "3e43f0c4.5e96e8", 822 | "type": "ui_slider", 823 | "z": "2a9757da.00a358", 824 | "name": "", 825 | "label": "Set Temp", 826 | "group": "1b227b5c.bfe23d", 827 | "order": 4, 828 | "width": 0, 829 | "height": 0, 830 | "passthru": true, 831 | "topic": "", 832 | "min": "25", 833 | "max": "40", 834 | "step": 1, 835 | "x": 500, 836 | "y": 580, 837 | "wires": [ 838 | [ 839 | "a3571bf7.6401f8", 840 | "88f6c605.e1b608", 841 | "1d26e22a.08ac86" 842 | ] 843 | ] 844 | }, 845 | { 846 | "id": "a3571bf7.6401f8", 847 | "type": "debug", 848 | "z": "2a9757da.00a358", 849 | "name": "", 850 | "active": true, 851 | "console": "false", 852 | "complete": "false", 853 | "x": 670, 854 | "y": 540, 855 | "wires": [] 856 | }, 857 | { 858 | "id": "88f6c605.e1b608", 859 | "type": "change", 860 | "z": "2a9757da.00a358", 861 | "name": "", 862 | "rules": [ 863 | { 864 | "t": "set", 865 | "p": "settemp", 866 | "pt": "flow", 867 | "to": "payload", 868 | "tot": "msg" 869 | } 870 | ], 871 | "action": "", 872 | "property": "", 873 | "from": "", 874 | "to": "", 875 | "reg": false, 876 | "x": 680, 877 | "y": 580, 878 | "wires": [ 879 | [] 880 | ] 881 | }, 882 | { 883 | "id": "d9b7b1be.0bd48", 884 | "type": "change", 885 | "z": "2a9757da.00a358", 886 | "name": "", 887 | "rules": [ 888 | { 889 | "t": "set", 890 | "p": "payload", 891 | "pt": "msg", 892 | "to": "31", 893 | "tot": "num" 894 | } 895 | ], 896 | "action": "", 897 | "property": "", 898 | "from": "", 899 | "to": "", 900 | "reg": false, 901 | "x": 320, 902 | "y": 580, 903 | "wires": [ 904 | [ 905 | "3e43f0c4.5e96e8" 906 | ] 907 | ] 908 | }, 909 | { 910 | "id": "51ee8750.4cf26", 911 | "type": "inject", 912 | "z": "2a9757da.00a358", 913 | "name": "Startup", 914 | "topic": "", 915 | "payload": "true", 916 | "payloadType": "bool", 917 | "repeat": "", 918 | "crontab": "", 919 | "once": true, 920 | "x": 140, 921 | "y": 580, 922 | "wires": [ 923 | [ 924 | "d9b7b1be.0bd48" 925 | ] 926 | ] 927 | }, 928 | { 929 | "id": "1d26e22a.08ac86", 930 | "type": "ui_text", 931 | "z": "2a9757da.00a358", 932 | "group": "1b227b5c.bfe23d", 933 | "order": 3, 934 | "width": 0, 935 | "height": 0, 936 | "name": "", 937 | "label": "Thermostat", 938 | "format": "{{msg.payload}}", 939 | "layout": "row-spread", 940 | "x": 670, 941 | "y": 620, 942 | "wires": [] 943 | }, 944 | { 945 | "id": "332a03f5.08e634", 946 | "type": "change", 947 | "z": "2a9757da.00a358", 948 | "name": "SensorTag Lux", 949 | "rules": [ 950 | { 951 | "t": "set", 952 | "p": "payload", 953 | "pt": "msg", 954 | "to": "payload.lux", 955 | "tot": "msg" 956 | } 957 | ], 958 | "action": "", 959 | "property": "", 960 | "from": "", 961 | "to": "", 962 | "reg": false, 963 | "x": 420, 964 | "y": 240, 965 | "wires": [ 966 | [ 967 | "2af2affc.c82028" 968 | ] 969 | ] 970 | }, 971 | { 972 | "id": "2af2affc.c82028", 973 | "type": "ui_text", 974 | "z": "2a9757da.00a358", 975 | "group": "1b227b5c.bfe23d", 976 | "order": 0, 977 | "width": 0, 978 | "height": 0, 979 | "name": "", 980 | "label": "Light", 981 | "format": "{{msg.payload}}", 982 | "layout": "row-spread", 983 | "x": 610, 984 | "y": 240, 985 | "wires": [] 986 | }, 987 | { 988 | "id": "802cc3da.8124", 989 | "type": "ui_chart", 990 | "z": "2a9757da.00a358", 991 | "name": "", 992 | "group": "f809ef74.a1c1b", 993 | "order": 2, 994 | "width": 0, 995 | "height": 0, 996 | "label": "Temperature History", 997 | "chartType": "line", 998 | "legend": "false", 999 | "xformat": "HH:mm:ss", 1000 | "interpolate": "linear", 1001 | "nodata": "", 1002 | "dot": false, 1003 | "ymin": "0", 1004 | "ymax": "40", 1005 | "removeOlder": 1, 1006 | "removeOlderPoints": "", 1007 | "removeOlderUnit": "86400", 1008 | "cutout": 0, 1009 | "useOneColor": false, 1010 | "colors": [ 1011 | "#1f77b4", 1012 | "#aec7e8", 1013 | "#ff7f0e", 1014 | "#2ca02c", 1015 | "#98df8a", 1016 | "#d62728", 1017 | "#ff9896", 1018 | "#9467bd", 1019 | "#c5b0d5" 1020 | ], 1021 | "useOldStyle": false, 1022 | "outputs": 2, 1023 | "x": 660, 1024 | "y": 280, 1025 | "wires": [ 1026 | [], 1027 | [] 1028 | ] 1029 | } 1030 | ] 1031 | --------------------------------------------------------------------------------