Snippets

Peter Scargill Node-Red Stat 4

Created by Peter Scargill last modified
[{"id":"8be635ca.03e038","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"css etc","order":10,"width":"0","height":"0","format":"<style>\n\n.cellGreen \n{\nbackground-color: #ffdddd !important;\n}\n\n  .filled { \n      height: 100% !important;\n\n      padding: 0 !important;\n      margin: 0 !important;\n  }\n  .nr-dashboard-template {\n      padding: 0;\n      margin: 0;\n  }\n  \n  .rounded {\n  border-radius: 12px 12px 12px 12px;\n}\n \n   .bigfont {\n  font-size: 18px;\n}\n\n   .smallfont {\n  font-size: 12px;\n}\n \n\n  \n.zui-table {\n    border: solid 1px #DDEEEE;\n    border-collapse: collapse;\n    border-spacing: 0;\n    font: normal 10px Arial, sans-serif;\n    outline: none;\n}\n.zui-table thead th {\n    width: 100%;\n    height:50%;\n    background-color: #99bbff;\n    border: solid 1px #DDEEEE;\n    color: #336B6B;\n    padding: 7px 3px 5px 3px;\n    text-align: center;\n    text-shadow: 1px 1px 1px #fff;\n}\n.zui-table tbody td {\n    width: 100%;\n    height:50%;\n    border: solid 1px #333;\n    color: #333;\n    text-align: center;\n    padding: 6px 3px 9px 3px;\n    text-shadow: 1px 1px 1px #fff;\n}\n.zui-table-rounded {\n    border: none;\n}\n.zui-table-rounded thead th {\n    background-color: #77aaff;\n    border: none;\n    text-shadow: 1px 1px 1px #ccc;\n    color: #333;\n}\n.zui-table-rounded thead th:first-child {\n    border-radius: 10px 0 0 0;\n}\n.zui-table-rounded thead th:last-child {\n    border-radius: 10px 10px 0px 0px;\n}\n.zui-table-rounded tbody td {\n    border: none;\n    border-top: solid 1px #957030;\n    background-color: #aaddff;\n}\n.zui-table-rounded tbody tr:last-child td:first-child {\n    border-radius: 10px 10px 0 0;\n}\n.zui-table-rounded tbody tr:last-child td:last-child {\n    border-radius: 0 0 10px 10px;\n}  \n</style>\n\n<script>\nvar current=1;\n\n$('.vibrate').on('click', function() {\n  navigator.vibrate(100);\n});\n\nfunction restore_bg(x) {\n            $(this).css(\"background-color\", x);\n    };\n\n$('.touched').on('mousedown', function() {\n    \n    var x= $(this).css(\"background-color\");\n    $(this).css(\"background-color\", \"yellow\");\n    \n    setTimeout(restore_bg.bind(this,x),50);\n    navigator.vibrate(80);\n    });\n    \n</script>","storeOutMessages":true,"fwdInMessages":true,"x":600,"y":80,"wires":[[]]},{"id":"8815a1ed.fca9b","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"Settings page","order":2,"width":"6","height":"6","format":"<style>\n.thedays { vertical-align:bottom; height:48px; }\n.the2px  { background-color:black; height:2px; }\n.theblocks {width:100%; height:0%; background-color:green; }\n.greybuttons { background-color:#dddddd !important; width:48px; }\n.thetemps { font-size:70%; color:#888888 !important; }\n.smallheadings { color:black; font-size:80%; }\n\n</style>\n\n<script>\nvar thedays = [\"SUNDAY\", \"MONDAY\", \"TUESDAY\", \"WEDNESDAY\", \"THURSDAY\", \"FRIDAY\", \"SATURDAY\"];\n\nvar last = 1;\n\nfunction bar(mm, val) {\n  if (val == 14) {\n    $(mm).height(\"12%\");\n    $(mm).css('background-color', '#6666ff');\n  } //blue\n  if (val == 15) {\n    $(mm).height(\"16%\");\n    $(mm).css('background-color', '#5577ff');\n  }\n  if (val == 16) {\n    $(mm).height(\"20%\");\n    $(mm).css('background-color', '#5599ff');\n  }\n  if (val == 17) {\n    $(mm).height(\"24%\");\n    $(mm).css('background-color', '#55ccdd');\n  } // cyan\n  if (val == 18) {\n    $(mm).height(\"28%\");\n    $(mm).css('background-color', '#55ddaa');\n  }\n  if (val == 19) {\n    $(mm).height(\"32%\");\n    $(mm).css('background-color', '#55dd55');\n  }\n  if (val == 20) {\n    $(mm).height(\"36%\");\n    $(mm).css('background-color', '#55dd55');\n  } // green\n  if (val == 21) {\n    $(mm).height(\"40%\");\n    $(mm).css('background-color', '#55dd55');\n  }\n  if (val == 22) {\n    $(mm).height(\"44%\");\n    $(mm).css('background-color', '#aadd55');\n  }\n  if (val == 23) {\n    $(mm).height(\"48%\");\n    $(mm).css('background-color', '#dddd55');\n  } // yellow\n  if (val == 24) {\n    $(mm).height(\"52%\");\n    $(mm).css('background-color', '#ffaa55');\n  }\n  if (val == 25) {\n    $(mm).height(\"56%\");\n    $(mm).css('background-color', '#ff8855');\n  }\n  if (val == 26) {\n    $(mm).height(\"60%\");\n    $(mm).css('background-color', '#ff7777');\n  } // red\n\n}\n\nfunction stat(text) {\n  $(\"#info\").text(text);\n  var tm = setTimeout(function() {\n    $(\"#info\").text(\"Ok\");\n    clearTimeout(tm);\n  }, 3000);\n}\n\nfunction selec(val, sta) {\n  var w = \"#td\" + val;\n  if (sta) $(w).css('background-color', 'magenta');\n  else $(w).css('background-color', 'black');\n}\n\n(function(scope) {\n  scope.$watch('msg', function(msg) {\n    selec(last, 0);\n    last = msg.selector;\n    selec(last, 1);\n    for (var x = 0; x < 24; x++) {\n      var w = \"#t\" + x;\n      bar(w, msg.timing[((msg.days - 1) * 24) + x]);\n      var v = \"#v\" + x;\n      $(v).text(msg.timing[((msg.days - 1) * 24) + x] + \"C\")\n    }\n    for (var x = 0; x < 2; x++) {\n      var w = \"#s\" + x;\n      $(w).text(msg.timing[168 + x] + \"C\");\n    }\n    $(\"#d0\").text(thedays[msg.days - 1]);\n    if ((last > 4) && (last < 29))\n      $(\"#current\").text(msg.timing[((msg.days - 1) * 24) + last - 5] + \"C\");\n    else\n      $(\"#current\").text(\"-\");\n\n    if (msg.foryou != \"\") {\n      stat(msg.foryou);\n    }\n\n\n  });\n\n})(scope);\n\n</script>\n<table width=\"100%\">\n  <tr style=\"height:2px\">\n    <td colspan=12 style=\"background-color:black;height:5px;\"></td>\n  </tr>\n\n  <tr>\n    <td colspan=6>\n      <center><span class=\"smallheadings\">Day</span></center>\n    </td>\n    <td colspan=3>\n      <center><span class=\"smallheadings\">Frost</span></center>\n    </td>\n    <td colspan=3>\n      <center><span class=\"smallheadings\">Away</span></center>\n    </td>\n  </tr>\n\n  <tr>\n    <td ng-click=\"send({payload: '29'})\" colspan=6>\n      <center><span id=\"d0\" style=\"color:blue;font-size:120%\">MONDAY</span></center>\n    </td>\n    <td ng-click=\"send({payload: '1'})\" colspan=3>\n      <center><span id=\"s0\" style=\"color:blue;font-size:120%\">14</span></center>\n    </td>\n    <td ng-click=\"send({payload: '2'})\" colspan=3>\n      <center><span id=\"s1\" style=\"color:blue;font-size:120%\">20</span></center>\n    </td>\n  </tr>\n\n  <tr style=\"height:2px\">\n    <td id=\"td29\" colspan=6 style=\"background-color:black;height:2px;\"></td>\n    <td id=\"td1\" colspan=3 style=\"background-color:black;height:2px;\"></td>\n    <td id=\"td2\" colspan=3 style=\"background-color:black;height:2px;\"></td>\n  </tr>\n\n  <tr>\n    <td ng-click=\"send({payload: '5'})\" class=\"thedays\"><span id=\"v0\" class=\"thetemps\"></span>\n      <div id=\"t0\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '6'})\" class=\"thedays\"><span id=\"v1\" class=\"thetemps\"></span>\n      <div id=\"t1\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '7'})\" class=\"thedays\"><span id=\"v2\" class=\"thetemps\"></span>\n      <div id=\"t2\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '8'})\" class=\"thedays\"><span id=\"v3\" class=\"thetemps\"></span>\n      <div id=\"t3\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '9'})\" class=\"thedays\"><span id=\"v4\" class=\"thetemps\"></span>\n      <div id=\"t4\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '10'})\" class=\"thedays\"><span id=\"v5\" class=\"thetemps\"></span>\n      <div id=\"t5\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '11'})\" class=\"thedays\"><span id=\"v6\" class=\"thetemps\"></span>\n      <div id=\"t6\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '12'})\" class=\"thedays\"><span id=\"v7\" class=\"thetemps\"></span>\n      <div id=\"t7\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '13'})\" class=\"thedays\"><span id=\"v8\" class=\"thetemps\"></span>\n      <div id=\"t8\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '14'})\" class=\"thedays\"><span id=\"v9\" class=\"thetemps\"></span>\n      <div id=\"t9\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '15'})\" class=\"thedays\"><span id=\"v10\" class=\"thetemps\"></span>\n      <div id=\"t10\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '16'})\" class=\"thedays\"><span id=\"v11\" class=\"thetemps\"></span>\n      <div id=\"t11\" class=\"theblocks\"></div>\n    </td>\n  </tr>\n\n  <tr style=\"height:2px\">\n    <td id=\"td5\" class=\"the2px\"></td>\n    <td id=\"td6\" class=\"the2px\"></td>\n    <td id=\"td7\" class=\"the2px\"></td>\n    <td id=\"td8\" class=\"the2px\"></td>\n    <td id=\"td9\" class=\"the2px\"></td>\n    <td id=\"td10\" class=\"the2px\"></td>\n    <td id=\"td11\" class=\"the2px\"></td>\n    <td id=\"td12\" class=\"the2px\"></td>\n    <td id=\"td13\" class=\"the2px\"></td>\n    <td id=\"td14\" class=\"the2px\"></td>\n    <td id=\"td15\" class=\"the2px\"></td>\n    <td id=\"td16\" class=\"the2px\"></td>\n  </tr>\n\n  <tr>\n    <td>0</td>\n    <td>1</td>\n    <td>2</td>\n    <td>3</td>\n    <td>4</td>\n    <td>5</td>\n    <td>6</td>\n    <td>7</td>\n    <td>8</td>\n    <td>9</td>\n    <td>10</td>\n    <td>11</td>\n  </tr>\n\n  <tr>\n    <td ng-click=\"send({payload: '17'})\" class=\"thedays\"><span id=\"v12\" class=\"thetemps\"></span>\n      <div id=\"t12\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '18'})\" class=\"thedays\"><span id=\"v13\" class=\"thetemps\"></span>\n      <div id=\"t13\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '19'})\" class=\"thedays\"><span id=\"v14\" class=\"thetemps\"></span>\n      <div id=\"t14\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '20'})\" class=\"thedays\"><span id=\"v15\" class=\"thetemps\"></span>\n      <div id=\"t15\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '21'})\" class=\"thedays\"><span id=\"v16\" class=\"thetemps\"></span>\n      <div id=\"t16\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '22'})\" class=\"thedays\"><span id=\"v17\" class=\"thetemps\"></span>\n      <div id=\"t17\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '23'})\" class=\"thedays\"><span id=\"v18\" class=\"thetemps\"></span>\n      <div id=\"t18\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '24'})\" class=\"thedays\"><span id=\"v19\" class=\"thetemps\"></span>\n      <div id=\"t19\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '25'})\" class=\"thedays\"><span id=\"v20\" class=\"thetemps\"></span>\n      <div id=\"t20\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '26'})\" class=\"thedays\"><span id=\"v21\" class=\"thetemps\"></span>\n      <div id=\"t21\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '27'})\" class=\"thedays\"><span id=\"v22\" class=\"thetemps\"></span>\n      <div id=\"t22\" class=\"theblocks\"></div>\n    </td>\n    <td ng-click=\"send({payload: '28'})\" class=\"thedays\"><span id=\"v23\" class=\"thetemps\"></span>\n      <div id=\"t23\" class=\"theblocks\"></div>\n    </td>\n  </tr>\n\n  <tr style=\"height:2px\">\n    <td id=\"td17\" class=\"the2px\"></td>\n    <td id=\"td18\" class=\"the2px\"></td>\n    <td id=\"td19\" class=\"the2px\"></td>\n    <td id=\"td20\" class=\"the2px\"></td>\n    <td id=\"td21\" class=\"the2px\"></td>\n    <td id=\"td22\" class=\"the2px\"></td>\n    <td id=\"td23\" class=\"the2px\"></td>\n    <td id=\"td24\" class=\"the2px\"></td>\n    <td id=\"td25\" class=\"the2px\"></td>\n    <td id=\"td26\" class=\"the2px\"></td>\n    <td id=\"td27\" class=\"the2px\"></td>\n    <td id=\"td28\" class=\"the2px\"></td>\n  </tr>\n\n  <tr>\n    <td>12</td>\n    <td>13</td>\n    <td>14</td>\n    <td>15</td>\n    <td>16</td>\n    <td>17</td>\n    <td>18</td>\n    <td>19</td>\n    <td>20</td>\n    <td>21</td>\n    <td>22</td>\n    <td>23</td>\n  </tr>\n\n  <tr height=\"20px\">\n    <td colspan=2 bgcolor=\"#dddddd\"><span class=\"smallheadings\">&nbsp;Status:</span></td>\n\n    <td colspan=10 bgcolor=\"#dddddd\">\n      <center><span id=\"info\" class=\"smallheadings\">OK</span></center>\n    </td>\n  </tr>\n\n  <tr height=\"10px\">\n    <td colspan=\"12\"></td>\n  </tr>\n\n  <tr style=\"height:48px\">\n    <td colspan=2>\n      <md-button class=\"vibrate filled touched smallfont rounded greybuttons\" ng-click=\"send({payload: 'd'})\">\n        <img style=\"outline : none;\" ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/arrow-left-double-2.png':'/myicons/png/48x48/actions/arrow-left-double-2.png'}}\" height=\"36px\" />\n      </md-button>\n    </td>\n\n    <td colspan=2>\n      <center><span id=\"current\" style=\"color:black;font-size:120%\">-</span></center>\n    </td>\n\n    <td colspan=2>\n      <md-button class=\"vibrate filled touched smallfont rounded greybuttons\" ng-click=\"send({payload: 'u'})\">\n        <img style=\"outline : none;\" ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/arrow-right-double-2.png':'/myicons/png/48x48/actions/arrow-right-double-2.png'}}\" height=\"36px\" />\n      </md-button>\n    </td>\n\n    <td colspan=2>\n      <md-button class=\"vibrate filled touched smallfont rounded greybuttons\" ng-click=\"send({payload: 'r'})\">\n        <img style=\"outline : none;\" ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/edit-copy-4.png':'/myicons/png/48x48/actions/edit-copy-4.png'}}\" height=\"36px\" />\n      </md-button>\n    </td>\n\n    <td colspan=2>\n      <md-button class=\"vibrate filled touched smallfont rounded greybuttons\" ng-click=\"send({payload: 's'})\">\n        <img style=\"outline : none;\" ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/document-save-5.png':'/myicons/png/48x48/actions/document-save-5.png'}}\" height=\"36px\" />\n      </md-button>\n    </td>\n\n    <td colspan=2>\n      <md-button class=\"vibrate filled touched smallfont rounded greybuttons\" ng-click=\"send({payload: 'c'})\">\n        <img style=\"outline : none;\" ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/dialog-cancel-5.png':'/myicons/png/48x48/actions/dialog-cancel-5.png'}}\" height=\"36px\" />\n      </md-button>\n    </td>\n    <td colspan=1></td>\n  </tr>\n\n</table>\n","storeOutMessages":false,"fwdInMessages":false,"x":780,"y":80,"wires":[["aba7c9ce.0b6c28"]]},{"id":"aba7c9ce.0b6c28","type":"function","z":"c552e8d2.712b48","name":"Process controls","func":"if ( typeof context.days == 'undefined' ) context.days=1;\nif ( typeof context.selector == 'undefined' ) context.selector=1;\nif ( typeof context.saving == 'undefined' ) context.saving=0;\nif ( typeof context.global.incomingTemperature == 'undefined' ) context.global.incomingTemperature=0;\nif ( typeof context.global.incomingHumidity == 'undefined' ) context.global.incomingHumidity=0;\nif ( typeof context.global.hold == 'undefined' ) context.global.hold=0;\nif ( typeof context.global.away == 'undefined' ) context.global.away=0;\nif ( typeof context.global.manual == 'undefined' ) context.global.manual=0;\nif ( typeof context.global.setTemperature == 'undefined' ) context.global.setTemperature=0;\nif ( typeof context.global.manualTimer == 'undefined' ) context.global.manualTimer=0;\nif ( typeof context.global.timing == 'undefined' ) \n    {\n        context.global.timing=[\n                        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,\n                        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,\n                        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,\n                        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,\n                        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,\n                        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,\n                        14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,\n                        8,14\n                        ];\n        context.saving=0;  \n        msg.payload=\"anything\";  msg.foryou=\"Restoring\"; return([null,null,msg]);\n    }\nvar timing=global.get(\"timing\");\n\nswitch (msg.payload)\n    {\n    case \"u\" :  if ((context.selector>4)&&(context.selector<29))\n                {\n                    timing[((context.days-1)*24)+context.selector-5]++; \n                    if (timing[((context.days-1)*24)+context.selector-5]>26) timing[((context.days-1)*24)+context.selector-5]=26;\n                    msg.foryou=\"Incremented temperature\";\n                }\n                if (context.selector==1) { if (timing[168+(context.selector-1)]<26) {  timing[168+(context.selector-1)]++; msg.foryou=\"Incremented frost setting 1 degree\"; } else msg.foryou=\"Hit limit\"; }\n                if (context.selector==2) { if (timing[168+(context.selector-1)]<26) {  timing[168+(context.selector-1)]++; msg.foryou=\"Incremented away setting 1 degree\"; } else msg.foryou=\"Hit limit\"; }\n                if (context.selector==29) { if (context.days<7) { context.days++; msg.foryou=\"Forward one day\";} else msg.foryou=\"End of days!!\"; }\n                break;\n    case \"d\" :  if ((context.selector>4)&&(context.selector<29))\n                {\n                    timing[((context.days-1)*24)+context.selector-5]--; \n                    if (timing[((context.days-1)*24)+context.selector-5]<14) timing[((context.days-1)*24)+context.selector-5]=14;\n                    msg.foryou=\"Decremented temperature\";\n                }\n                if (context.selector==1) { if (timing[168+(context.selector-1)]>8) { timing[168+(context.selector-1)]--; msg.foryou=\"Decremented frost setting 1 degree\"; } else msg.foryou=\"Hit limit\"; }\n                if (context.selector==2) { if (timing[168+(context.selector-1)]>8) { timing[168+(context.selector-1)]--; msg.foryou=\"Decremented away setting 1 degree\"; } else msg.foryou=\"Hit limit\"; }\n                if (context.selector==29) { if (context.days>1) { context.days--;  msg.foryou=\"Backward one day\";} else msg.foryou=\"Beginning of days!!\";  }\n                break;\n    case 'r' :  if ((context.selector>=5)&&(context.selector<28))\n                        {\n                         timing[((context.days-1)*24)+context.selector-4]=timing[((context.days-1)*24)+context.selector-5];   \n                         context.selector++;\n                         msg.foryou=\"Copied settings to the next hour slot\";\n                        }\n                if ((context.selector==29)&&(context.days<7))\n                        {\n                         for (var a=0;a<24;a++)\n                            {\n                             timing[((context.days)*24)+a]=timing[((context.days-1)*24)+a];   \n                            }\n                         context.days++;\n                         msg.foryou=\"Copied a complete day's settings\";\n                        }\n                break;\n    case 's': context.saving=0;  msg.foryou=\"Settings saved to disk\"; break;\n    case '1':\n    case '2':\n    case '3':\n    case '4':\n    case '5':\n    case '6':\n    case '7':\n    case '8':\n    case '9':\n    case '10':\n    case '11':\n    case '12':\n    case '13':\n    case '14':\n    case '15':\n    case '16':\n    case '17':\n    case '18':\n    case '19':\n    case '20':\n    case '21':\n    case '22':\n    case '23':\n    case '24':\n    case '25':\n    case '26':\n    case '27':\n    case '28':\n    case '29': context.selector=parseInt(msg.payload);\n               if (msg.payload=='1') msg.foryou=\"Frost temperature selection\"; \n               else if (msg.payload=='2') msg.foryou=\"Away temperature selection\";\n               else if (msg.payload=='29') msg.foryou=\"Day selection\";\n               else  msg.foryou=\"Selected hour period \" + (parseInt(msg.payload)-4);\n    break;\n    case 'c' : msg.payload=\"anything\";  msg.foryou=\"Changes cancelled\"; node.send([null,null,msg]);\n    }\n\nmsg.temperatures=context.temperatures;\nmsg.timing=timing;\nmsg.days=context.days;\nmsg.selector=context.selector;\n\nnode.send([msg,null,null]);\n\nif (context.saving===0) \n    { \n       msg.topic=\"\";\n        msg.timing=\"\";\n        msg.payload=JSON.stringify(timing);\n        node.send([null,msg,null]); \n        context.saving=1;\n    }\n    msg.foryou=\"\"","outputs":"3","noerr":0,"x":710,"y":140,"wires":[["8815a1ed.fca9b"],["9f13095d.38ba18"],["8421f1bf.f6286"]]},{"id":"945f3b38.6cc9c8","type":"inject","z":"c552e8d2.712b48","name":"Once only","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":true,"x":500,"y":200,"wires":[["aba7c9ce.0b6c28","8421f1bf.f6286"]]},{"id":"13c303be.55f94c","type":"inject","z":"c552e8d2.712b48","name":"Every minute","topic":"","payload":"","payloadType":"str","repeat":"60","crontab":"","once":false,"x":500,"y":260,"wires":[["7f0331f4.5b289","695e047b.c1ecac"]]},{"id":"7f0331f4.5b289","type":"function","z":"c552e8d2.712b48","name":"Process heat","func":"var timing=global.get(\"timing\");\nvar now = new Date();\nmsg.payload=timing[(now.getDay()*24)+now.getHours()];\nmsg.frost=timing[168];\nmsg.away=timing[169];\n\nmsg.temperature=global.get(\"incomingTemperature\");\nmsg.humidity=global.get(\"incomingHumidity\");\nmsg.set=msg.payload;\nif (global.get(\"manualTimer\")) global.set(\"manualTimer\",global.get(\"manualTimer\")-1);\nelse global.set(\"manual\",0);\nmsg.desired=msg.set;\nglobal.set(\"setTemperature\",msg.desired);\nmsg.desired+=global.get(\"manual\");\nif (global.get(\"frost\")) { msg.desired=global.get(\"timing\")[168]; global.set(\"frost\",global.get(\"frost\")-1); }\nif (global.get(\"away\")) { msg.desired=global.get(\"timing\")[169]; global.set(\"away\",global.get(\"away\")-1); }\nif (msg.desired>msg.temperature) msg.relay=1; else msg.relay=0;\n\nmsg.payload=global.get(\"incomingTemperature\");\n\nnode.status({fill:\"blue\",shape:\"dot\",text:\"Set point \" + msg.desired + \"c - Actual \" + msg.temperature +\"c\"});\n\nnode.send([msg,null]);\nmsg.payload=msg.relay;\nnode.send([null,msg]);\n\n\n\n\n","outputs":"2","noerr":0,"x":730,"y":280,"wires":[["66e21166.7fada","7cd73a4e.8b2214"],["8152db3c.058368"]]},{"id":"9f13095d.38ba18","type":"file","z":"c552e8d2.712b48","name":"backup","filename":"/home/pi/petesstatlog.log","appendNewline":true,"createDir":true,"overwriteFile":"true","x":940,"y":200,"wires":[]},{"id":"8421f1bf.f6286","type":"file in","z":"c552e8d2.712b48","name":"Restore","filename":"/home/pi/petesstatlog.log","format":"utf8","x":940,"y":140,"wires":[["5efea5f0.dec25c"]]},{"id":"5efea5f0.dec25c","type":"function","z":"c552e8d2.712b48","name":"Restore data from SD","func":"context.global.timing=JSON.parse(msg.payload);\nmsg.payload=\"\";\nreturn msg;","outputs":1,"noerr":0,"x":720,"y":220,"wires":[["aba7c9ce.0b6c28"]]},{"id":"dbfea475.ca5438","type":"inject","z":"c552e8d2.712b48","name":"incoming temperature 18c","topic":"","payload":"18","payloadType":"str","repeat":"","crontab":"","once":false,"x":170,"y":80,"wires":[["5c120e63.28f36"]]},{"id":"c61fdaa7.e80b08","type":"inject","z":"c552e8d2.712b48","name":"incoming temperature 20c","topic":"","payload":"20","payloadType":"str","repeat":"","crontab":"","once":false,"x":170,"y":120,"wires":[["5c120e63.28f36"]]},{"id":"48220f38.43af9","type":"inject","z":"c552e8d2.712b48","name":"incoming temperature 26c","topic":"","payload":"26","payloadType":"str","repeat":"","crontab":"","once":false,"x":170,"y":160,"wires":[["5c120e63.28f36"]]},{"id":"994e52ef.3e505","type":"inject","z":"c552e8d2.712b48","name":"incoming humidity 40%","topic":"","payload":"40","payloadType":"str","repeat":"","crontab":"","once":false,"x":160,"y":200,"wires":[["7eebdc07.593384"]]},{"id":"12a4998b.429e26","type":"inject","z":"c552e8d2.712b48","name":"incoming humidity 50%","topic":"","payload":"50","payloadType":"str","repeat":"","crontab":"","once":false,"x":160,"y":240,"wires":[["7eebdc07.593384"]]},{"id":"5c120e63.28f36","type":"function","z":"c552e8d2.712b48","name":"Store temperature","func":"global.set(\"incomingTemperature\",msg.payload);","outputs":"0","noerr":0,"x":430,"y":120,"wires":[]},{"id":"7eebdc07.593384","type":"function","z":"c552e8d2.712b48","name":"Store humidity","func":"global.set(\"incomingHumidity\",msg.payload);","outputs":"0","noerr":0,"x":420,"y":160,"wires":[]},{"id":"af578cf3.7b3c1","type":"inject","z":"c552e8d2.712b48","name":"Test \"Away\" 2 minutes","topic":"","payload":"2","payloadType":"str","repeat":"","crontab":"","once":false,"x":160,"y":280,"wires":[["59872d80.b244e4"]]},{"id":"10996dc6.8d5d82","type":"inject","z":"c552e8d2.712b48","name":"Test \"Away\" clear","topic":"","payload":"0","payloadType":"str","repeat":"","crontab":"","once":false,"x":140,"y":320,"wires":[["59872d80.b244e4"]]},{"id":"678411fc.5d32b","type":"inject","z":"c552e8d2.712b48","name":"Test \"Frost\" 2 minutes","topic":"","payload":"2","payloadType":"str","repeat":"","crontab":"","once":false,"x":160,"y":360,"wires":[["2b79500.97c95b"]]},{"id":"ea2fdaeb.38db08","type":"inject","z":"c552e8d2.712b48","name":"Test \"Frost\" clear","topic":"","payload":"0","payloadType":"str","repeat":"","crontab":"","once":false,"x":140,"y":400,"wires":[["2b79500.97c95b"]]},{"id":"2b79500.97c95b","type":"function","z":"c552e8d2.712b48","name":"Store \"Hold\"","func":"global.set(\"frost\",msg.payload);","outputs":"0","noerr":0,"x":410,"y":360,"wires":[]},{"id":"59872d80.b244e4","type":"function","z":"c552e8d2.712b48","name":"Store \"Away\"","func":"global.set(\"away\",msg.payload);","outputs":"0","noerr":0,"x":410,"y":320,"wires":[]},{"id":"c3165cd0.aaa8b","type":"inject","z":"c552e8d2.712b48","name":"sample forecast","topic":"","payload":"Dry, 2c with chance of snow","payloadType":"str","repeat":"","crontab":"","once":false,"x":140,"y":440,"wires":[["47a3d01f.504ae"]]},{"id":"116f01b3.e45b0e","type":"inject","z":"c552e8d2.712b48","name":"Sample forecast","topic":"","payload":"Wet, 12c, possibly rain tonight","payloadType":"str","repeat":"","crontab":"","once":false,"x":140,"y":480,"wires":[["47a3d01f.504ae"]]},{"id":"47a3d01f.504ae","type":"function","z":"c552e8d2.712b48","name":"Store forecast","func":"global.set(\"forecast\",msg.payload);","outputs":"0","noerr":0,"x":420,"y":440,"wires":[]},{"id":"8152db3c.058368","type":"function","z":"c552e8d2.712b48","name":"Pretend relay","func":"if (msg.payload==1)\nnode.status({fill:\"red\",shape:\"dot\",text:\"Relay ON\"});\nelse\nnode.status({fill:\"black\",shape:\"dot\",text:\"Relay OFF\"});\n","outputs":"0","noerr":0,"x":980,"y":240,"wires":[]},{"id":"3168e55f.bdf29a","type":"function","z":"c552e8d2.712b48","name":"Handle SET","func":"// here we set manual override controls - valid for 60 minutes after last change.\n\n\nif (global.get(\"away\")===0)\n{\n    if (msg.payload==\"u\") { global.set(\"manualTimer\",60); if (global.get(\"manual\")<12) global.set(\"manual\",global.get(\"manual\")+1); }\n    if (msg.payload==\"d\") { global.set(\"manualTimer\",60); if (global.get(\"manual\")>-12) global.set(\"manual\",global.get(\"manual\")-1); }\n    if (msg.payload==\"a\") { global.set(\"manualTimer\",0); global.set(\"manual\",0); }\n}\n\nvar x= msg.desired=global.get(\"setTemperature\") + global.get(\"manual\");\nmsg.desired=x;\n\nif (global.get(\"manual\")===0) msg.colour=\"#aaddff\"; else msg.colour=\"#aaffaa\";\n\nif (global.get(\"frost\")) { msg.desired=global.get(\"timing\")[168]; msg.colour=\"#ffbbbb\"; }\nif (global.get(\"away\"))  { msg.desired=global.get(\"timing\")[169];msg.colour=\"#ffbbbb\";  }\n\nmsg.payload=msg.desired;\nreturn msg;","outputs":1,"noerr":0,"x":790,"y":380,"wires":[["7cd73a4e.8b2214","66e21166.7fada"]]},{"id":"62da9d50.ffd1e4","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"up","order":4,"width":"1","height":"1","format":"  <md-button  class=\"vibrate filled touched smallfont rounded greybuttons\" ng-click=\"send({payload: 'u'})\"> \n                <img style=\"outline : none;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/arrow-right-2.png':'/myicons/png/48x48/actions/arrow-right-2.png'}}\" \n                              height=\"36px\"\n                />\n</md-button> ","storeOutMessages":false,"fwdInMessages":false,"x":590,"y":340,"wires":[["3168e55f.bdf29a","f805393e.25dbf8"]]},{"id":"a033d106.7d68e","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"down","order":3,"width":"1","height":"1","format":"  <md-button  class=\"vibrate filled touched smallfont rounded greybuttons\" ng-click=\"send({payload: 'd'})\"> \n                <img style=\"outline : none;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/arrow-down-2.png':'/myicons/png/48x48/actions/arrow-left-2.png'}}\" \n                              height=\"36px\"\n                />\n</md-button> ","storeOutMessages":false,"fwdInMessages":false,"x":590,"y":380,"wires":[["3168e55f.bdf29a","f805393e.25dbf8"]]},{"id":"4f31478.6f1dcb8","type":"function","z":"c552e8d2.712b48","name":"Handle AWAY","func":"// here we set manual override controls - valid for 60 minutes after last change.\nif (msg.payload==\"u\") {  global.set(\"away\",global.get(\"away\")+1); }\nif (msg.payload==\"uu\") { global.set(\"away\",global.get(\"away\")+24); }\nif (msg.payload==\"a\") { global.set(\"away\",0);  }\nmsg.away=global.get(\"away\");\n\nif (global.get(\"away\")===0) msg.colour=\"#aaddff\"; else msg.colour=\"#aaffaa\";\n\nvar t=parseInt(msg.away);\nif (t>23) t=((t/24).toFixed(1))+\"d\"; else t=t+\"h\";\nmsg.away=t;\n  \nmsg.payload=\"\";\nreturn msg;","outputs":1,"noerr":0,"x":800,"y":460,"wires":[["3168e55f.bdf29a","6aee2782.4a6768"]]},{"id":"110a1fe5.53545","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"more","order":6,"width":"1","height":"1","format":"  <md-button  class=\"vibrate filled touched smallfont rounded greybuttons\" ng-click=\"send({payload: 'u'})\"> \n                <img style=\"outline : none;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/arrow-right-2.png':'/myicons/png/48x48/actions/arrow-right-2.png'}}\" \n                              height=\"36px\"\n                />\n</md-button> ","storeOutMessages":false,"fwdInMessages":false,"x":590,"y":460,"wires":[["4f31478.6f1dcb8","f805393e.25dbf8"]]},{"id":"6a665b46.ac7374","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"mmore","order":7,"width":"1","height":"1","format":"  <md-button  class=\"vibrate filled touched smallfont rounded greybuttons\" ng-click=\"send({payload: 'uu'})\"> \n                <img style=\"outline : none;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/arrow-left-double-2.png':'/myicons/png/48x48/actions/arrow-right-double-2.png'}}\" \n                              height=\"36px\"\n                />\n</md-button> ","storeOutMessages":false,"fwdInMessages":false,"x":600,"y":500,"wires":[["4f31478.6f1dcb8","f805393e.25dbf8"]]},{"id":"66e21166.7fada","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"newergauge","order":1,"width":"3","height":"3","format":"<script type=\"text/javascript\" src=\"/myjs/gauge.min.js\"></script>\n<script>\n\n   (function(scope){\n        scope.$watch('msg', function(msg) {\n           gauge.value=msg.payload;\n           // if (msg.units!=\"\") gauge.units=msg.units;\n        });\n \n    })(scope);\nvar gauge = new RadialGauge({\n    renderTo: 'canvas-id',\n    width: 160,\n    height: 160,\n    units: \"Degrees C\",\n    title: \"Thermometer\",\n    minValue: 10,\n    maxValue: 30,\n    majorTicks: [\n        '10',\n        '15',\n        '20',\n        '25',\n        '30'\n    ],\n    minorTicks: 5,\n    strokeTicks: true,\n   highlights  : [\n        { from : 10,  to : 15, color : '#8888ff' },\n        { from : 15, to : 20, color :  '#88ff88' },\n        { from : 20, to : 25, color :  '#ffff00' },\n        { from : 25, to : 30, color :  '#ff8888' }\n    ],\n\n    colorPlate: \"#fff\",\n    borderShadowWidth: 0,\n    borders: true,\n    needleType: \"arrow\",\n    valueInt: 2,\n    valueDec:0,\n    needleWidth: 2,\n    fontTitleSize: 42,\n    needleCircleSize: 14,\n    needleCircleOuter: true,\n    needleCircleInner: false,\n    animationDuration: 500,\n    animationRule: \"linear\"\n}).draw();\n\ngauge.value = 18;\n\n</script>\n<canvas style=\"outline: none;\" ng-click=\"send({payload: ' '})\" id=\"canvas-id\">\n\n</canvas>","storeOutMessages":false,"fwdInMessages":false,"x":1010,"y":300,"wires":[["7f0331f4.5b289","1a90e0d1.e6e7af"]]},{"id":"7cd73a4e.8b2214","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"SET","order":5,"width":"1","height":"1","format":"<script>\n   (function(scope){\n        scope.$watch('msg', function(msg) {\n             if (msg.desired!=\"\") $(\"#infor\").text(msg.desired+\"C\");\n             if (msg.colour!=\"\") $(\"#infor\").css(\"background-color\",msg.colour);\n        });\n \n    })(scope);\n</script>\n<table  ng-click=\"send({payload: 'a'})\" width=100% height=100% class=\"vibrate zui-table zui-table-rounded\">\n    <thead>\n        <tr>\n            <th>SET</th>\n        </tr>\n    </thead>\n    <tbody>\n        <tr >\n            <td id=\"infor\"></td>\n        </tr>\n\n    </tbody>\n</table>\n","storeOutMessages":false,"fwdInMessages":false,"x":990,"y":360,"wires":[["3168e55f.bdf29a","f805393e.25dbf8"]]},{"id":"6aee2782.4a6768","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"AWAY","order":8,"width":"1","height":"1","format":"<script>\n   (function(scope){\n        scope.$watch('msg', function(msg) {\n             if (msg.away!=\"\") $(\"#awaytable\").text(msg.away);\n             if (msg.colour!=\"\") $(\"#awaytable\").css(\"background-color\",msg.colour);\n        });\n \n    })(scope);\n</script>\n\n<table ng-click=\"send({payload: 'a'})\" width=100% height=100% class=\"vibrate zui-table zui-table-rounded\">\n    <thead>\n        <tr>\n            <th>AWAY</th>\n        </tr>\n    </thead>\n    <tbody>\n        <tr>\n            <td id=\"awaytable\"></td>\n    \n        </tr>\n\n    </tbody>\n</table>","storeOutMessages":false,"fwdInMessages":false,"x":990,"y":420,"wires":[["4f31478.6f1dcb8","f805393e.25dbf8"]]},{"id":"143eebdc.ccb4c4","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"STATUS","order":9,"width":"3","height":"1","format":"<script>\n   (function(scope){\n        scope.$watch('msg', function(msg) {\n             if (msg.topic!=\"\") $(\"#hdr1\").text(msg.topic);\n             if (msg.payload!=\"\") $(\"#bod1\").text(msg.payload);\n        });\n    })(scope);\n</script>\n\n<table ng-click=\"send({payload: 'a'})\" width=100% height=100% class=\"zui-table zui-table-rounded\">\n    <thead>\n        <tr>\n            <th id=\"hdr1\">></th>\n        </tr>\n    </thead>\n    <tbody>\n        <tr>\n            <td id=\"bod1\"></td>\n    \n        </tr>\n\n    </tbody>\n</table>","storeOutMessages":false,"fwdInMessages":false,"x":1020,"y":520,"wires":[[]]},{"id":"695e047b.c1ecac","type":"function","z":"c552e8d2.712b48","name":"show humidity","func":"function theNewDate()\n{\n   var d = new Date(),\n    minutes = d.getMinutes().toString().length == 1 ? '0'+d.getMinutes() : d.getMinutes();\n    hours = d.getHours().toString().length == 1 ? '0'+d.getHours() : d.getHours();\n    ampm = d.getHours() >= 12 ? 'pm' : 'am';\n    months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];\n    days = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];\n    var m= days[d.getDay()]+' '+months[d.getMonth()]+' '+d.getDate()+' '+d.getFullYear()+' '+hours+':'+minutes+ampm;\n    return m;\n}\n\nmsg.topic=theNewDate();\nmsg.payload=\"Humidity: \" + global.get(\"incomingHumidity\") +\"%\" ;\nreturn msg;","outputs":1,"noerr":0,"x":840,"y":520,"wires":[["143eebdc.ccb4c4"]]},{"id":"f805393e.25dbf8","type":"function","z":"c552e8d2.712b48","name":"Showing settings","func":"msg.payload=\"Showing settings\";\nreturn msg;","outputs":1,"noerr":0,"x":850,"y":560,"wires":[["143eebdc.ccb4c4"]]},{"id":"1a90e0d1.e6e7af","type":"function","z":"c552e8d2.712b48","name":"Showing actual","func":"msg.payload=\"Showing actual\";\nreturn msg;","outputs":1,"noerr":0,"x":840,"y":600,"wires":[["143eebdc.ccb4c4"]]},{"id":"37f2a2e2.88cc6e","type":"ui_group","z":"","name":"Stat","tab":"c675fdae.9cea1","disp":false,"width":"6"},{"id":"c675fdae.9cea1","type":"ui_tab","z":"","name":"Stat","icon":"dashboard"}]

Comments (3)

  1. Peter Scargill

    I've just added the VIBRATE class to the top right clear button/indicators. This is REALLY looking ok now.

  2. Peter Scargill

    More tidying up. Incidentally, this is WHITE theme. Dark theme looks naff with this.

  3. Otis Jame

    Sprunki promotes a sense of community through its sharing features, allowing players to showcase their musical creations. Players can save and share their tracks, fostering collaboration and inspiration among users.

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.