Snippets

Peter Scargill Node-Red Stat 4

Updated by Peter Scargill

File snippet.txt Modified

  • Ignore whitespace
  • Hide word diff
-[{"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":"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"}]
Updated by Peter Scargill

File snippet.txt Modified

  • Ignore whitespace
  • Hide word diff
-[{"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.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\" class=\"smallheadings\">Status:</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":960,"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    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":970,"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 settings","func":"msg.payload=\"Showing actual\";\nreturn msg;","outputs":1,"noerr":0,"x":850,"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"}]
+[{"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"]]}]
Updated by Peter Scargill

File snippet.txt Modified

  • Ignore whitespace
  • Hide word diff
-[{"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.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\" class=\"smallheadings\">Status:</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":960,"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    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":970,"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=\"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=\"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 settings","func":"msg.payload=\"Showing actual\";\nreturn msg;","outputs":1,"noerr":0,"x":850,"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"}]
+[{"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.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\" class=\"smallheadings\">Status:</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":960,"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    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":970,"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 settings","func":"msg.payload=\"Showing actual\";\nreturn msg;","outputs":1,"noerr":0,"x":850,"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"}]
Updated by Peter Scargill

File snippet.txt Modified

  • Ignore whitespace
  • Hide word diff
-[{"id":"8be635ca.03e038","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"css etc","order":11,"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.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    \nfunction gettime()\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    return days[d.getDay()]+' '+months[d.getMonth()]+' '+d.getDate()+' '+d.getFullYear()+' '+hours+':'+minutes+ampm;\n}\n</script>","storeOutMessages":true,"fwdInMessages":true,"x":580,"y":40,"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{\nif (val==14) { $(mm).height(\"12%\"); $(mm).css('background-color', '#6666ff'); } //blue\nif (val==15) { $(mm).height(\"16%\"); $(mm).css('background-color', '#5577ff'); }\nif (val==16) { $(mm).height(\"20%\"); $(mm).css('background-color', '#5599ff'); } \nif (val==17) { $(mm).height(\"24%\"); $(mm).css('background-color', '#55ccdd'); } // cyan\nif (val==18) { $(mm).height(\"28%\"); $(mm).css('background-color', '#55ddaa'); }\nif (val==19) { $(mm).height(\"32%\"); $(mm).css('background-color', '#55dd55'); } \nif (val==20) { $(mm).height(\"36%\"); $(mm).css('background-color', '#55dd55'); } // green\nif (val==21) { $(mm).height(\"40%\"); $(mm).css('background-color', '#55dd55'); }\nif (val==22) { $(mm).height(\"44%\"); $(mm).css('background-color', '#aadd55'); }\nif (val==23) { $(mm).height(\"48%\"); $(mm).css('background-color', '#dddd55'); } // yellow\nif (val==24) { $(mm).height(\"52%\"); $(mm).css('background-color', '#ffaa55'); }\nif (val==25) { $(mm).height(\"56%\"); $(mm).css('background-color', '#ff8855'); }\nif (val==26) { $(mm).height(\"60%\"); $(mm).css('background-color', '#ff7777'); } // red\n    \n}\n\nfunction stat(text)\n{\n$(\"#info\").text(text);\nvar tm=setTimeout(function(){ $(\"#info\").text(\"Ok\"); clearTimeout(tm);}, 3000);\n}\n\nfunction selec(val,sta)\n{\nvar w=\"#td\"+val;\n if (sta) $(w).css('background-color','magenta'); else $(w).css('background-color','black');\n}\n\n    (function(scope){\n        scope.$watch('msg', function(msg) {\n            selec(last,0); last=msg.selector; selec(last,1);\n            for (var x=0; x<24; x++) \n                { \n                    var w=\"#t\"+x; bar(w,msg.timing[((msg.days-1)*24)+x]); \n                    var v=\"#v\"+x; $(v).text(msg.timing[((msg.days-1)*24)+x]+\"C\")\n                } \n            for (var x=0; x<2; x++) { var w=\"#s\"+x; $(w).text(msg.timing[168+x]+\"C\"); }\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!=\"\") { stat(msg.foryou);  }\n            \n             \n        });\n \n    })(scope);\n      \n\n</script>\n<table width=\"100%\">\n    \n    \n    \n    \n     <tr style=\"height:2px\">\n        <td colspan=12 style=\"background-color:black;height:5px;\"></td>        \n \n    </tr>  \n\n    <tr>\n        <td colspan=6><center><span class=\"smallheadings\" >Day</span></center></td>\n        <td colspan=3><center><span class=\"smallheadings\">Frost</span></center></td>\n        <td colspan=3><center><span class=\"smallheadings\">Away</span></center></td>\n    </tr>\n   \n    <tr>\n        <td ng-click=\"send({payload: '29'})\" colspan=6><center><span id=\"d0\" style=\"color:blue;font-size:120%\">MONDAY</span></center></td>\n        <td ng-click=\"send({payload: '1'})\" colspan=3><center><span id=\"s0\" style=\"color:blue;font-size:120%\">14</span></center></td>\n        <td ng-click=\"send({payload: '2'})\" colspan=3><center><span id=\"s1\" style=\"color:blue;font-size:120%\">20</span></center></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><div id=\"t0\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '6'})\" class=\"thedays\"><span id=\"v1\" class=\"thetemps\"></span><div id=\"t1\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '7'})\" class=\"thedays\"><span id=\"v2\" class=\"thetemps\"></span><div id=\"t2\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '8'})\" class=\"thedays\"><span id=\"v3\" class=\"thetemps\"></span><div id=\"t3\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '9'})\" class=\"thedays\"><span id=\"v4\" class=\"thetemps\"></span><div id=\"t4\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '10'})\" class=\"thedays\"><span id=\"v5\" class=\"thetemps\"></span><div id=\"t5\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '11'})\" class=\"thedays\"><span id=\"v6\" class=\"thetemps\"></span><div id=\"t6\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '12'})\" class=\"thedays\"><span id=\"v7\" class=\"thetemps\"></span><div id=\"t7\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '13'})\" class=\"thedays\"><span id=\"v8\" class=\"thetemps\"></span><div id=\"t8\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '14'})\" class=\"thedays\"><span id=\"v9\" class=\"thetemps\"></span><div id=\"t9\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '15'})\" class=\"thedays\"><span id=\"v10\" class=\"thetemps\"></span><div id=\"t10\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '16'})\" class=\"thedays\"><span id=\"v11\" class=\"thetemps\"></span><div id=\"t11\" class=\"theblocks\"></div></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><div id=\"t12\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '18'})\" class=\"thedays\"><span id=\"v13\" class=\"thetemps\"></span><div id=\"t13\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '19'})\" class=\"thedays\"><span id=\"v14\" class=\"thetemps\"></span><div id=\"t14\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '20'})\" class=\"thedays\"><span id=\"v15\" class=\"thetemps\"></span><div id=\"t15\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '21'})\" class=\"thedays\"><span id=\"v16\" class=\"thetemps\"></span><div id=\"t16\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '22'})\" class=\"thedays\"><span id=\"v17\" class=\"thetemps\"></span><div id=\"t17\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '23'})\" class=\"thedays\"><span id=\"v18\" class=\"thetemps\"></span><div id=\"t18\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '24'})\" class=\"thedays\"><span id=\"v19\" class=\"thetemps\"></span><div id=\"t19\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '25'})\" class=\"thedays\"><span id=\"v20\" class=\"thetemps\"></span><div id=\"t20\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '26'})\" class=\"thedays\"><span id=\"v21\" class=\"thetemps\"></span><div id=\"t21\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '27'})\" class=\"thedays\"><span id=\"v22\" class=\"thetemps\"></span><div id=\"t22\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '28'})\" class=\"thedays\"><span id=\"v23\" class=\"thetemps\"></span><div id=\"t23\" class=\"theblocks\"></div></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\" class=\"smallheadings\">Status:</td>\n\n        <td colspan=10 bgcolor=\"#dddddd\"><center><span id=\"info\" class=\"smallheadings\" >Ok</span></center></td>\n\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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/arrow-left-double-2.png':'/myicons/png/48x48/actions/arrow-left-double-2.png'}}\" \n                              height=\"36px\"\n                />\n            </md-button> \n        </td>\n        \n        <td colspan=2><center><span id=\"current\" style=\"color:black;font-size:120%\">-</span></center></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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/arrow-right-double-2.png':'/myicons/png/48x48/actions/arrow-right-double-2.png'}}\" \n                              height=\"36px\"\n                />\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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/edit-copy-4.png':'/myicons/png/48x48/actions/edit-copy-4.png'}}\" \n                              height=\"36px\"\n                />\n            </md-button> \n        </td>\n\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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/document-save-5.png':'/myicons/png/48x48/actions/document-save-5.png'}}\" \n                              height=\"36px\"\n                />\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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/dialog-cancel-5.png':'/myicons/png/48x48/actions/dialog-cancel-5.png'}}\" \n                              height=\"36px\"\n                />\n            </md-button> \n        </td>\n        <td colspan=1></td>\n    </tr>\n\n</table>","storeOutMessages":false,"fwdInMessages":false,"x":760,"y":40,"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":690,"y":100,"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":480,"y":160,"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":240,"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":710,"y":240,"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":920,"y":160,"wires":[]},{"id":"8421f1bf.f6286","type":"file in","z":"c552e8d2.712b48","name":"Restore","filename":"/home/pi/petesstatlog.log","format":"utf8","x":920,"y":100,"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":700,"y":180,"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":150,"y":40,"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":150,"y":80,"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":150,"y":120,"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":140,"y":160,"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":140,"y":200,"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":410,"y":80,"wires":[]},{"id":"7eebdc07.593384","type":"function","z":"c552e8d2.712b48","name":"Store humidity","func":"global.set(\"incomingHumidity\",msg.payload);","outputs":"0","noerr":0,"x":400,"y":120,"wires":[]},{"id":"af578cf3.7b3c1","type":"inject","z":"c552e8d2.712b48","name":"Test \"Away\" 2 minutes","topic":"","payload":"2","payloadType":"str","repeat":"","crontab":"","once":false,"x":140,"y":240,"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":120,"y":280,"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":140,"y":320,"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":120,"y":360,"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":390,"y":320,"wires":[]},{"id":"59872d80.b244e4","type":"function","z":"c552e8d2.712b48","name":"Store \"Away\"","func":"global.set(\"away\",msg.payload);","outputs":"0","noerr":0,"x":390,"y":280,"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":120,"y":400,"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":120,"y":440,"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":400,"y":400,"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":940,"y":200,"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":770,"y":340,"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":570,"y":300,"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":570,"y":340,"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":780,"y":420,"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":570,"y":420,"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":580,"y":460,"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    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":950,"y":260,"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=\"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":970,"y":320,"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=\"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":970,"y":380,"wires":[["4f31478.6f1dcb8","f805393e.25dbf8"]]},{"id":"143eebdc.ccb4c4","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"STATUS","order":8,"width":"3","height":"1","format":"<style>\n\n</style>\n\n<table ng-click=\"send({payload: 'a'})\" width=100% height=100% class=\"zui-table zui-table-rounded\">\n    <thead>\n        <tr>\n            <th>{{msg.topic}}</th>\n        </tr>\n    </thead>\n    <tbody>\n        <tr>\n            <td>{{msg.payload}}</td>\n    \n        </tr>\n\n    </tbody>\n</table>","storeOutMessages":false,"fwdInMessages":false,"x":1000,"y":480,"wires":[[]]},{"id":"695e047b.c1ecac","type":"function","z":"c552e8d2.712b48","name":"show humidity","func":"\nmsg.payload=\"Humidity: \" + global.get(\"incomingHumidity\") +\"%\" ;\nmsg.topic=gettime();\nreturn msg;","outputs":1,"noerr":0,"x":820,"y":480,"wires":[["143eebdc.ccb4c4"]]},{"id":"f805393e.25dbf8","type":"function","z":"c552e8d2.712b48","name":"Showing settings","func":"msg.topic=gettime();\nmsg.payload=\"Showing settings\"\nreturn msg;","outputs":1,"noerr":0,"x":830,"y":520,"wires":[["143eebdc.ccb4c4"]]},{"id":"1a90e0d1.e6e7af","type":"function","z":"c552e8d2.712b48","name":"Showing settings","func":"msg.topic=gettime();\nmsg.payload=\"Showing actual\"\nreturn msg;","outputs":1,"noerr":0,"x":830,"y":560,"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"}]
+[{"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.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\" class=\"smallheadings\">Status:</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":960,"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    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":970,"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=\"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=\"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 settings","func":"msg.payload=\"Showing actual\";\nreturn msg;","outputs":1,"noerr":0,"x":850,"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"}]
Updated by Peter Scargill

File snippet.txt Modified

  • Ignore whitespace
  • Hide word diff
-[{"id":"8be635ca.03e038","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"css etc","order":11,"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.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    \nfunction gettime()\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    return days[d.getDay()]+' '+months[d.getMonth()]+' '+d.getDate()+' '+d.getFullYear()+' '+hours+':'+minutes+ampm;\n}\n</script>","storeOutMessages":true,"fwdInMessages":true,"x":580,"y":40,"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{\n//if (val==14) { $(mm).height(\"12%\"); $(mm).css('background-color', '#0000ff'); } //blue\n//if (val==15) { $(mm).height(\"16%\"); $(mm).css('background-color', '#0055ff'); }\n//if (val==16) { $(mm).height(\"20%\"); $(mm).css('background-color', '#00aaff'); } \n//if (val==17) { $(mm).height(\"24%\"); $(mm).css('background-color', '#00dddd'); } // cyan\n//if (val==18) { $(mm).height(\"28%\"); $(mm).css('background-color', '#00ffaa'); }\n//if (val==19) { $(mm).height(\"32%\"); $(mm).css('background-color', '#00ff55'); } \n//if (val==20) { $(mm).height(\"36%\"); $(mm).css('background-color', '#00ff00'); } // green\n//if (val==21) { $(mm).height(\"40%\"); $(mm).css('background-color', '#55ff00'); }\n//if (val==22) { $(mm).height(\"44%\"); $(mm).css('background-color', '#aaff00'); }\n//if (val==23) { $(mm).height(\"48%\"); $(mm).css('background-color', '#dddd00'); } // yellow\n//if (val==24) { $(mm).height(\"52%\"); $(mm).css('background-color', '#ffaa00'); }\n//if (val==25) { $(mm).height(\"56%\"); $(mm).css('background-color', '#ff5500'); }\n//if (val==26) { $(mm).height(\"60%\"); $(mm).css('background-color','#ff0000'); } // red\n\nif (val==14) { $(mm).height(\"12%\"); $(mm).css('background-color', '#6666ff'); } //blue\nif (val==15) { $(mm).height(\"16%\"); $(mm).css('background-color', '#5577ff'); }\nif (val==16) { $(mm).height(\"20%\"); $(mm).css('background-color', '#5599ff'); } \nif (val==17) { $(mm).height(\"24%\"); $(mm).css('background-color', '#55ccdd'); } // cyan\nif (val==18) { $(mm).height(\"28%\"); $(mm).css('background-color', '#55ddaa'); }\nif (val==19) { $(mm).height(\"32%\"); $(mm).css('background-color', '#55dd55'); } \nif (val==20) { $(mm).height(\"36%\"); $(mm).css('background-color', '#55dd55'); } // green\nif (val==21) { $(mm).height(\"40%\"); $(mm).css('background-color', '#55dd55'); }\nif (val==22) { $(mm).height(\"44%\"); $(mm).css('background-color', '#aadd55'); }\nif (val==23) { $(mm).height(\"48%\"); $(mm).css('background-color', '#dddd55'); } // yellow\nif (val==24) { $(mm).height(\"52%\"); $(mm).css('background-color', '#ffaa55'); }\nif (val==25) { $(mm).height(\"56%\"); $(mm).css('background-color', '#ff8855'); }\nif (val==26) { $(mm).height(\"60%\"); $(mm).css('background-color', '#ff7777'); } // red\n    \n}\n\nfunction stat(text)\n{\n$(\"#info\").text(text);\nvar tm=setTimeout(function(){ $(\"#info\").text(\"Ok\"); clearTimeout(tm);}, 3000);\n}\n\nfunction selec(val,sta)\n{\nvar w=\"#td\"+val;\n if (sta) $(w).css('background-color','magenta'); else $(w).css('background-color','black');\n}\n\n    (function(scope){\n        scope.$watch('msg', function(msg) {\n            selec(last,0); last=msg.selector; selec(last,1);\n            for (var x=0; x<24; x++) \n                { \n                    var w=\"#t\"+x; bar(w,msg.timing[((msg.days-1)*24)+x]); \n                    var v=\"#v\"+x; $(v).text(msg.timing[((msg.days-1)*24)+x]+\"c\")\n                } \n            for (var x=0; x<2; x++) { var w=\"#s\"+x; $(w).text(msg.timing[168+x]); }\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!=\"\") { stat(msg.foryou);  }\n            \n             \n        });\n \n    })(scope);\n      \n\n</script>\n<table width=\"100%\">\n    \n    \n    \n    \n     <tr style=\"height:2px\">\n        <td colspan=12 style=\"background-color:black;height:5px;\"></td>        \n \n    </tr>  \n\n    <tr>\n        <td colspan=6><center><span class=\"smallheadings\" >Day</span></center></td>\n        <td colspan=3><center><span class=\"smallheadings\">Frost</span></center></td>\n        <td colspan=3><center><span class=\"smallheadings\">Away</span></center></td>\n    </tr>\n   \n    <tr>\n        <td ng-click=\"send({payload: '29'})\" colspan=6><center><span id=\"d0\" style=\"color:blue;font-size:120%\">MONDAY</span></center></td>\n        <td ng-click=\"send({payload: '1'})\" colspan=3><center><span id=\"s0\" style=\"color:blue;font-size:120%\">14</span></center></td>\n        <td ng-click=\"send({payload: '2'})\" colspan=3><center><span id=\"s1\" style=\"color:blue;font-size:120%\">20</span></center></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><div id=\"t0\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '6'})\" class=\"thedays\"><span id=\"v1\" class=\"thetemps\"></span><div id=\"t1\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '7'})\" class=\"thedays\"><span id=\"v2\" class=\"thetemps\"></span><div id=\"t2\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '8'})\" class=\"thedays\"><span id=\"v3\" class=\"thetemps\"></span><div id=\"t3\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '9'})\" class=\"thedays\"><span id=\"v4\" class=\"thetemps\"></span><div id=\"t4\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '10'})\" class=\"thedays\"><span id=\"v5\" class=\"thetemps\"></span><div id=\"t5\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '11'})\" class=\"thedays\"><span id=\"v6\" class=\"thetemps\"></span><div id=\"t6\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '12'})\" class=\"thedays\"><span id=\"v7\" class=\"thetemps\"></span><div id=\"t7\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '13'})\" class=\"thedays\"><span id=\"v8\" class=\"thetemps\"></span><div id=\"t8\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '14'})\" class=\"thedays\"><span id=\"v9\" class=\"thetemps\"></span><div id=\"t9\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '15'})\" class=\"thedays\"><span id=\"v10\" class=\"thetemps\"></span><div id=\"t10\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '16'})\" class=\"thedays\"><span id=\"v11\" class=\"thetemps\"></span><div id=\"t11\" class=\"theblocks\"></div></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><div id=\"t12\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '18'})\" class=\"thedays\"><span id=\"v13\" class=\"thetemps\"></span><div id=\"t13\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '19'})\" class=\"thedays\"><span id=\"v14\" class=\"thetemps\"></span><div id=\"t14\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '20'})\" class=\"thedays\"><span id=\"v15\" class=\"thetemps\"></span><div id=\"t15\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '21'})\" class=\"thedays\"><span id=\"v16\" class=\"thetemps\"></span><div id=\"t16\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '22'})\" class=\"thedays\"><span id=\"v17\" class=\"thetemps\"></span><div id=\"t17\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '23'})\" class=\"thedays\"><span id=\"v18\" class=\"thetemps\"></span><div id=\"t18\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '24'})\" class=\"thedays\"><span id=\"v19\" class=\"thetemps\"></span><div id=\"t19\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '25'})\" class=\"thedays\"><span id=\"v20\" class=\"thetemps\"></span><div id=\"t20\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '26'})\" class=\"thedays\"><span id=\"v21\" class=\"thetemps\"></span><div id=\"t21\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '27'})\" class=\"thedays\"><span id=\"v22\" class=\"thetemps\"></span><div id=\"t22\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '28'})\" class=\"thedays\"><span id=\"v23\" class=\"thetemps\"></span><div id=\"t23\" class=\"theblocks\"></div></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\" class=\"smallheadings\">Status:</td>\n\n        <td colspan=10 bgcolor=\"#dddddd\"><center><span id=\"info\" class=\"smallheadings\" >Ok</span></center></td>\n\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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/arrow-left-double-2.png':'/myicons/png/48x48/actions/arrow-left-double-2.png'}}\" \n                              height=\"36px\"\n                />\n            </md-button> \n        </td>\n        \n        <td colspan=2><center><span id=\"current\" style=\"color:black;font-size:120%\">-</span></center></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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/arrow-right-double-2.png':'/myicons/png/48x48/actions/arrow-right-double-2.png'}}\" \n                              height=\"36px\"\n                />\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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/edit-copy-4.png':'/myicons/png/48x48/actions/edit-copy-4.png'}}\" \n                              height=\"36px\"\n                />\n            </md-button> \n        </td>\n\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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/document-save-5.png':'/myicons/png/48x48/actions/document-save-5.png'}}\" \n                              height=\"36px\"\n                />\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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/dialog-cancel-5.png':'/myicons/png/48x48/actions/dialog-cancel-5.png'}}\" \n                              height=\"36px\"\n                />\n            </md-button> \n        </td>\n        <td colspan=1></td>\n    </tr>\n\n</table>","storeOutMessages":false,"fwdInMessages":false,"x":760,"y":40,"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":690,"y":100,"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":480,"y":160,"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":240,"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":710,"y":240,"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":920,"y":160,"wires":[]},{"id":"8421f1bf.f6286","type":"file in","z":"c552e8d2.712b48","name":"Restore","filename":"/home/pi/petesstatlog.log","format":"utf8","x":920,"y":100,"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":700,"y":180,"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":150,"y":40,"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":150,"y":80,"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":150,"y":120,"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":140,"y":160,"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":140,"y":200,"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":410,"y":80,"wires":[]},{"id":"7eebdc07.593384","type":"function","z":"c552e8d2.712b48","name":"Store humidity","func":"global.set(\"incomingHumidity\",msg.payload);","outputs":"0","noerr":0,"x":400,"y":120,"wires":[]},{"id":"af578cf3.7b3c1","type":"inject","z":"c552e8d2.712b48","name":"Test \"Away\" 2 minutes","topic":"","payload":"2","payloadType":"str","repeat":"","crontab":"","once":false,"x":140,"y":240,"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":120,"y":280,"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":140,"y":320,"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":120,"y":360,"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":390,"y":320,"wires":[]},{"id":"59872d80.b244e4","type":"function","z":"c552e8d2.712b48","name":"Store \"Away\"","func":"global.set(\"away\",msg.payload);","outputs":"0","noerr":0,"x":390,"y":280,"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":120,"y":400,"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":120,"y":440,"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":400,"y":400,"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":940,"y":200,"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":770,"y":340,"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":570,"y":300,"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":570,"y":340,"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":780,"y":420,"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":570,"y":420,"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":580,"y":460,"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    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":950,"y":260,"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);\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=\"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":970,"y":320,"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=\"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":970,"y":380,"wires":[["4f31478.6f1dcb8","f805393e.25dbf8"]]},{"id":"143eebdc.ccb4c4","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"STATUS","order":8,"width":"3","height":"1","format":"<style>\n\n</style>\n\n<table ng-click=\"send({payload: 'a'})\" width=100% height=100% class=\"zui-table zui-table-rounded\">\n    <thead>\n        <tr>\n            <th>{{msg.topic}}</th>\n        </tr>\n    </thead>\n    <tbody>\n        <tr>\n            <td>{{msg.payload}}</td>\n    \n        </tr>\n\n    </tbody>\n</table>","storeOutMessages":false,"fwdInMessages":false,"x":1000,"y":480,"wires":[[]]},{"id":"695e047b.c1ecac","type":"function","z":"c552e8d2.712b48","name":"show humidity","func":"\nmsg.payload=\"Humidity: \" + global.get(\"incomingHumidity\") +\"%\" ;\nmsg.topic=gettime();\nreturn msg;","outputs":1,"noerr":0,"x":820,"y":480,"wires":[["143eebdc.ccb4c4"]]},{"id":"f805393e.25dbf8","type":"function","z":"c552e8d2.712b48","name":"Showing settings","func":"msg.topic=gettime();\nmsg.payload=\"Showing settings\"\nreturn msg;","outputs":1,"noerr":0,"x":830,"y":520,"wires":[["143eebdc.ccb4c4"]]},{"id":"1a90e0d1.e6e7af","type":"function","z":"c552e8d2.712b48","name":"Showing settings","func":"msg.topic=gettime();\nmsg.payload=\"Showing actual\"\nreturn msg;","outputs":1,"noerr":0,"x":830,"y":560,"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"}]
+[{"id":"8be635ca.03e038","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"css etc","order":11,"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.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    \nfunction gettime()\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    return days[d.getDay()]+' '+months[d.getMonth()]+' '+d.getDate()+' '+d.getFullYear()+' '+hours+':'+minutes+ampm;\n}\n</script>","storeOutMessages":true,"fwdInMessages":true,"x":580,"y":40,"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{\nif (val==14) { $(mm).height(\"12%\"); $(mm).css('background-color', '#6666ff'); } //blue\nif (val==15) { $(mm).height(\"16%\"); $(mm).css('background-color', '#5577ff'); }\nif (val==16) { $(mm).height(\"20%\"); $(mm).css('background-color', '#5599ff'); } \nif (val==17) { $(mm).height(\"24%\"); $(mm).css('background-color', '#55ccdd'); } // cyan\nif (val==18) { $(mm).height(\"28%\"); $(mm).css('background-color', '#55ddaa'); }\nif (val==19) { $(mm).height(\"32%\"); $(mm).css('background-color', '#55dd55'); } \nif (val==20) { $(mm).height(\"36%\"); $(mm).css('background-color', '#55dd55'); } // green\nif (val==21) { $(mm).height(\"40%\"); $(mm).css('background-color', '#55dd55'); }\nif (val==22) { $(mm).height(\"44%\"); $(mm).css('background-color', '#aadd55'); }\nif (val==23) { $(mm).height(\"48%\"); $(mm).css('background-color', '#dddd55'); } // yellow\nif (val==24) { $(mm).height(\"52%\"); $(mm).css('background-color', '#ffaa55'); }\nif (val==25) { $(mm).height(\"56%\"); $(mm).css('background-color', '#ff8855'); }\nif (val==26) { $(mm).height(\"60%\"); $(mm).css('background-color', '#ff7777'); } // red\n    \n}\n\nfunction stat(text)\n{\n$(\"#info\").text(text);\nvar tm=setTimeout(function(){ $(\"#info\").text(\"Ok\"); clearTimeout(tm);}, 3000);\n}\n\nfunction selec(val,sta)\n{\nvar w=\"#td\"+val;\n if (sta) $(w).css('background-color','magenta'); else $(w).css('background-color','black');\n}\n\n    (function(scope){\n        scope.$watch('msg', function(msg) {\n            selec(last,0); last=msg.selector; selec(last,1);\n            for (var x=0; x<24; x++) \n                { \n                    var w=\"#t\"+x; bar(w,msg.timing[((msg.days-1)*24)+x]); \n                    var v=\"#v\"+x; $(v).text(msg.timing[((msg.days-1)*24)+x]+\"C\")\n                } \n            for (var x=0; x<2; x++) { var w=\"#s\"+x; $(w).text(msg.timing[168+x]+\"C\"); }\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!=\"\") { stat(msg.foryou);  }\n            \n             \n        });\n \n    })(scope);\n      \n\n</script>\n<table width=\"100%\">\n    \n    \n    \n    \n     <tr style=\"height:2px\">\n        <td colspan=12 style=\"background-color:black;height:5px;\"></td>        \n \n    </tr>  \n\n    <tr>\n        <td colspan=6><center><span class=\"smallheadings\" >Day</span></center></td>\n        <td colspan=3><center><span class=\"smallheadings\">Frost</span></center></td>\n        <td colspan=3><center><span class=\"smallheadings\">Away</span></center></td>\n    </tr>\n   \n    <tr>\n        <td ng-click=\"send({payload: '29'})\" colspan=6><center><span id=\"d0\" style=\"color:blue;font-size:120%\">MONDAY</span></center></td>\n        <td ng-click=\"send({payload: '1'})\" colspan=3><center><span id=\"s0\" style=\"color:blue;font-size:120%\">14</span></center></td>\n        <td ng-click=\"send({payload: '2'})\" colspan=3><center><span id=\"s1\" style=\"color:blue;font-size:120%\">20</span></center></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><div id=\"t0\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '6'})\" class=\"thedays\"><span id=\"v1\" class=\"thetemps\"></span><div id=\"t1\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '7'})\" class=\"thedays\"><span id=\"v2\" class=\"thetemps\"></span><div id=\"t2\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '8'})\" class=\"thedays\"><span id=\"v3\" class=\"thetemps\"></span><div id=\"t3\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '9'})\" class=\"thedays\"><span id=\"v4\" class=\"thetemps\"></span><div id=\"t4\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '10'})\" class=\"thedays\"><span id=\"v5\" class=\"thetemps\"></span><div id=\"t5\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '11'})\" class=\"thedays\"><span id=\"v6\" class=\"thetemps\"></span><div id=\"t6\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '12'})\" class=\"thedays\"><span id=\"v7\" class=\"thetemps\"></span><div id=\"t7\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '13'})\" class=\"thedays\"><span id=\"v8\" class=\"thetemps\"></span><div id=\"t8\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '14'})\" class=\"thedays\"><span id=\"v9\" class=\"thetemps\"></span><div id=\"t9\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '15'})\" class=\"thedays\"><span id=\"v10\" class=\"thetemps\"></span><div id=\"t10\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '16'})\" class=\"thedays\"><span id=\"v11\" class=\"thetemps\"></span><div id=\"t11\" class=\"theblocks\"></div></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><div id=\"t12\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '18'})\" class=\"thedays\"><span id=\"v13\" class=\"thetemps\"></span><div id=\"t13\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '19'})\" class=\"thedays\"><span id=\"v14\" class=\"thetemps\"></span><div id=\"t14\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '20'})\" class=\"thedays\"><span id=\"v15\" class=\"thetemps\"></span><div id=\"t15\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '21'})\" class=\"thedays\"><span id=\"v16\" class=\"thetemps\"></span><div id=\"t16\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '22'})\" class=\"thedays\"><span id=\"v17\" class=\"thetemps\"></span><div id=\"t17\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '23'})\" class=\"thedays\"><span id=\"v18\" class=\"thetemps\"></span><div id=\"t18\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '24'})\" class=\"thedays\"><span id=\"v19\" class=\"thetemps\"></span><div id=\"t19\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '25'})\" class=\"thedays\"><span id=\"v20\" class=\"thetemps\"></span><div id=\"t20\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '26'})\" class=\"thedays\"><span id=\"v21\" class=\"thetemps\"></span><div id=\"t21\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '27'})\" class=\"thedays\"><span id=\"v22\" class=\"thetemps\"></span><div id=\"t22\" class=\"theblocks\"></div></td>\n        <td ng-click=\"send({payload: '28'})\" class=\"thedays\"><span id=\"v23\" class=\"thetemps\"></span><div id=\"t23\" class=\"theblocks\"></div></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\" class=\"smallheadings\">Status:</td>\n\n        <td colspan=10 bgcolor=\"#dddddd\"><center><span id=\"info\" class=\"smallheadings\" >Ok</span></center></td>\n\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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/arrow-left-double-2.png':'/myicons/png/48x48/actions/arrow-left-double-2.png'}}\" \n                              height=\"36px\"\n                />\n            </md-button> \n        </td>\n        \n        <td colspan=2><center><span id=\"current\" style=\"color:black;font-size:120%\">-</span></center></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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/arrow-right-double-2.png':'/myicons/png/48x48/actions/arrow-right-double-2.png'}}\" \n                              height=\"36px\"\n                />\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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/edit-copy-4.png':'/myicons/png/48x48/actions/edit-copy-4.png'}}\" \n                              height=\"36px\"\n                />\n            </md-button> \n        </td>\n\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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/document-save-5.png':'/myicons/png/48x48/actions/document-save-5.png'}}\" \n                              height=\"36px\"\n                />\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;\" \n                             ng-src=\"{{(msg.payload)?'/myicons/png/48x48/actions/dialog-cancel-5.png':'/myicons/png/48x48/actions/dialog-cancel-5.png'}}\" \n                              height=\"36px\"\n                />\n            </md-button> \n        </td>\n        <td colspan=1></td>\n    </tr>\n\n</table>","storeOutMessages":false,"fwdInMessages":false,"x":760,"y":40,"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":690,"y":100,"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":480,"y":160,"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":240,"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":710,"y":240,"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":920,"y":160,"wires":[]},{"id":"8421f1bf.f6286","type":"file in","z":"c552e8d2.712b48","name":"Restore","filename":"/home/pi/petesstatlog.log","format":"utf8","x":920,"y":100,"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":700,"y":180,"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":150,"y":40,"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":150,"y":80,"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":150,"y":120,"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":140,"y":160,"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":140,"y":200,"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":410,"y":80,"wires":[]},{"id":"7eebdc07.593384","type":"function","z":"c552e8d2.712b48","name":"Store humidity","func":"global.set(\"incomingHumidity\",msg.payload);","outputs":"0","noerr":0,"x":400,"y":120,"wires":[]},{"id":"af578cf3.7b3c1","type":"inject","z":"c552e8d2.712b48","name":"Test \"Away\" 2 minutes","topic":"","payload":"2","payloadType":"str","repeat":"","crontab":"","once":false,"x":140,"y":240,"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":120,"y":280,"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":140,"y":320,"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":120,"y":360,"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":390,"y":320,"wires":[]},{"id":"59872d80.b244e4","type":"function","z":"c552e8d2.712b48","name":"Store \"Away\"","func":"global.set(\"away\",msg.payload);","outputs":"0","noerr":0,"x":390,"y":280,"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":120,"y":400,"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":120,"y":440,"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":400,"y":400,"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":940,"y":200,"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":770,"y":340,"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":570,"y":300,"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":570,"y":340,"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":780,"y":420,"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":570,"y":420,"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":580,"y":460,"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    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":950,"y":260,"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=\"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":970,"y":320,"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=\"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":970,"y":380,"wires":[["4f31478.6f1dcb8","f805393e.25dbf8"]]},{"id":"143eebdc.ccb4c4","type":"ui_template","z":"c552e8d2.712b48","group":"37f2a2e2.88cc6e","name":"STATUS","order":8,"width":"3","height":"1","format":"<style>\n\n</style>\n\n<table ng-click=\"send({payload: 'a'})\" width=100% height=100% class=\"zui-table zui-table-rounded\">\n    <thead>\n        <tr>\n            <th>{{msg.topic}}</th>\n        </tr>\n    </thead>\n    <tbody>\n        <tr>\n            <td>{{msg.payload}}</td>\n    \n        </tr>\n\n    </tbody>\n</table>","storeOutMessages":false,"fwdInMessages":false,"x":1000,"y":480,"wires":[[]]},{"id":"695e047b.c1ecac","type":"function","z":"c552e8d2.712b48","name":"show humidity","func":"\nmsg.payload=\"Humidity: \" + global.get(\"incomingHumidity\") +\"%\" ;\nmsg.topic=gettime();\nreturn msg;","outputs":1,"noerr":0,"x":820,"y":480,"wires":[["143eebdc.ccb4c4"]]},{"id":"f805393e.25dbf8","type":"function","z":"c552e8d2.712b48","name":"Showing settings","func":"msg.topic=gettime();\nmsg.payload=\"Showing settings\"\nreturn msg;","outputs":1,"noerr":0,"x":830,"y":520,"wires":[["143eebdc.ccb4c4"]]},{"id":"1a90e0d1.e6e7af","type":"function","z":"c552e8d2.712b48","name":"Showing settings","func":"msg.topic=gettime();\nmsg.payload=\"Showing actual\"\nreturn msg;","outputs":1,"noerr":0,"x":830,"y":560,"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"}]
  1. 1
  2. 2
HTTPS SSH

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