{"id":4567,"date":"2024-01-28T12:00:12","date_gmt":"2024-01-28T20:00:12","guid":{"rendered":"https:\/\/www.cloudacm.com\/?p=4567"},"modified":"2024-01-25T21:24:32","modified_gmt":"2024-01-26T05:24:32","slug":"wemos-in-a-pelonis","status":"publish","type":"post","link":"https:\/\/www.cloudacm.com\/?p=4567","title":{"rendered":"Wemos in a Pelonis"},"content":{"rendered":"<p>This post will cover the use of the ESP8266 clone form factor of the more popular Wemos D1 Mini. This clone development module has the same pinout and interfaces as the Wemos D1 Mini. The Arduino IDE was set to use the NodeMCU 1.0 ESP12E Module for the code below, although the LOLIN(WEMOS) D1 mini (clone) was avaliable. This board selection didn&#8217;t present any issues when loading the firmware.<\/p>\n<p>The board is inexpensive, a 10 pack can run around $25. It doesn&#8217;t have all of the GPIOs of a full ESP32 dev board, or some of the peripherals of the ESP32-Cam board. But the low cost and targeted use make it a viable option.<\/p>\n<p>This post is intended as a demonstration only, please do not repeat these steps on any heating equipment you have at your disposal. The work done here is intended to provide a foundation for further work unrelated to space heating. I can&#8217;t stress enough the dangers of mishandling mains appliances, you stand a serious risk to you or someone you know if you carelessly attempt this, so don&#8217;t. You have been warned.<\/p>\n<p>In this post, the module was installed in a space heater. It monitors the space heater control buttons. The module can also mimic input to the space heater to operate it. Based on the space heater operating state, the module monitors the energy use of the space heater. The module interfaces with a wireless network and communicates with a MQTT broker. Node-Red is used to interface with the module through the MQTT broker. Node-Red has flows that track the module readings and presents an interface for user control.<\/p>\n<p>Here is the pinout of the module, it should be pointed out that the silk screening on the module is misleading. This can present issues for developers that aren&#8217;t aware of the GPIO to digital and analog pin numbering scheme.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/wemos_mini_d1_pinout_esp8266_esp12.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4569 size-full\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/wemos_mini_d1_pinout_esp8266_esp12.png\" alt=\"\" width=\"1024\" height=\"576\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/wemos_mini_d1_pinout_esp8266_esp12.png 1024w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/wemos_mini_d1_pinout_esp8266_esp12-300x169.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/wemos_mini_d1_pinout_esp8266_esp12-768x432.png 768w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/wemos_mini_d1_pinout_esp8266_esp12-480x270.png 480w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a>Since the space heater inputs operated at a 5 volt logic, a level shifter was placed between the module and space heater controller. Since the space heater provided an adequate 5 volt supply, this was fed to the module. Here is a pinout of the connections.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Untitled-Sketch_bb.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4572 size-full\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Untitled-Sketch_bb.png\" alt=\"\" width=\"791\" height=\"611\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Untitled-Sketch_bb.png 791w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Untitled-Sketch_bb-300x232.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Untitled-Sketch_bb-768x593.png 768w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Untitled-Sketch_bb-350x270.png 350w\" sizes=\"auto, (max-width: 791px) 100vw, 791px\" \/><\/a>The green line connects the module D1 pin (GPIO 5) to the space heater on\/off button. The yellow line connects the module D6 pin (GPIO 12) to the space heater mode button. Again, these traverse a level shifter to keep the module GPIO pins at 3.3 volts and the space heater pins at 5 volts. Here is a photo of the components installed in the space heater control panel.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4658.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-4575\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4658-1024x576.png\" alt=\"\" width=\"640\" height=\"360\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4658-1024x576.png 1024w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4658-300x169.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4658-768x432.png 768w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4658-480x270.png 480w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4658.png 1334w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/a><\/p>\n<p>After reassembly, the space heater appears the same as it had before the modification.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4659.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-4577\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4659-576x1024.png\" alt=\"\" width=\"576\" height=\"1024\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4659-576x1024.png 576w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4659-169x300.png 169w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4659-152x270.png 152w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/IMG_4659.png 750w\" sizes=\"auto, (max-width: 576px) 100vw, 576px\" \/><\/a><\/p>\n<p>Here is the Arduino code that was programmed on the module.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\">\/**\r\n\r\n  Header\r\n\r\n  Title: Wemos ESP8266 with MQTT interfaced Pelonis Space Heater Controller\r\n  Version: 11\r\n  Filename: Wemos-184_MQTT_Pelonis-Space-Heater-Controller_ver11.ino\r\n  Wemos draws 80mA ~ 400mW\r\n\r\n  Date: 10\/14\/2023\r\n  \r\n  Author: Patrick Gilfeather - CloudACM\r\n  \r\n\r\n*\/\r\n\r\n\r\n\r\n\r\n\/\/ Libraries and Declarations\r\n#include &lt;Arduino.h&gt;\r\n#include &lt;ESP8266WiFi.h&gt;\r\n#include &lt;PubSubClient.h&gt;\r\nWiFiClient espClient;\r\nPubSubClient MQTTclient(espClient);\r\nlong laststats = 0;\r\nint programflag = 0;\r\n\r\n\r\n\r\n\/\/ NTP Libraries, Declarations, and Variables\r\n#include &lt;NTPClient.h&gt;\r\n#include &lt;WiFiUdp.h&gt;\r\nWiFiUDP ntpUDP;\r\nNTPClient timeClient(ntpUDP, \"pool.ntp.org\");\r\n\/\/Week Days\r\nString weekDays[7]={\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"};\r\n\/\/Month names\r\nString months[12]={\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"};\r\n\r\n\r\n\r\n\r\n\r\n\/\/ Variables\r\n\r\n\/\/ MQTT Broker\r\nconst char* mqtt_server = \"&lt;ip_of_mqtt_broker&gt;\";     \/\/ Put your MQTT Broker here\r\n\r\n\/\/ Your WiFi credentials\r\nconst char* ssid =     \"&lt;wifi_network&gt;\";               \/\/ Put your SSID here\r\nconst char* password = \"&lt;wifi_password&gt;\";           \/\/ Put your PASSWORD here\r\n\r\nunsigned long lasttimeupdate = 0; \/\/ Time counter for periodic NTP time checks\r\nunsigned long lasttimereboot = 0; \/\/ Time counter for periodic reboots to avoid millis rollover\r\n\r\nADC_MODE(ADC_VCC);  \/\/ See comment block below for more details\r\n\/*\r\n  see - http:\/\/arduino.esp8266.com\/Arduino\/versions\/2.0.0-rc2\/doc\/libraries.html\r\n\r\n  ESP.getVcc() may be used to measure supply voltage. ESP needs to reconfigure the ADC at \r\n  startup in order for this feature to be available. Add the following line to the top of \r\n  your sketch to use getVcc:\r\n\r\n  ADC_MODE(ADC_VCC);\r\n\r\n  TOUT pin has to be disconnected in this mode.\r\n\r\n  Note that by default ADC is configured to read from TOUT pin using analogRead(A0), and \r\n  ESP.getVCC() is not available.\r\n\r\n *\/\r\n\r\n\/\/ Pelonis Space Heater Button Interfaces \r\nint OnOff = 5;\r\nint Mode = 12;\r\n\r\n\/\/ State of Pelonis Space Heater Buttons \r\nint OnOffState = 0;\r\nint ModeState = 0;\r\n\r\n\/\/ Reference State of Pelonis Space Heater Buttons \r\nint LastOnOffState = 0;\r\nint LastModeState = 0;\r\n\r\n\/\/ Pelonis Space Heater Counters, Variables, and Constants\r\nint DeBounceDelay = 250;\r\nunsigned long PanelCountdown = 0;\r\nunsigned long PanelClock = millis();\r\nint PowerState = 0;\r\nint OperationState = 0;\r\nint PanelState = 0;\r\n\r\n\r\n\/**\r\n\r\n  Wattage Usage Calculations \r\n  Based on Amp meter readings\r\n  High Mode = 12.5 Amps with 120 Volt AC Source\r\n  Low Mode = 7 Amps with 120 Volt AC Source\r\n\r\n  MQTT Status message are sent every 5 seconds\r\n\r\n  To cacluate watt hours used the mode amp value is multiplied by the source voltage\r\n  ie. 7 * 120 = 840 Watts\r\n  The result is then devided by the amount of time that has passed since the last reading\r\n  ie. 840 \/ (60 * 12) = 1.1667 Watts used in 5 seconds\r\n\r\n  The Watts used in 5 seconds becomes the factor to add to the variable WattsUsed\r\n\r\n  High Mode = 2.08\r\n  Low Mode = 1.17\r\n  \r\n*\/\r\n\r\nfloat WattsUsed = 0;\r\n\r\n\r\n\r\n\/\/ MQTT Functions\r\n\r\nvoid callback(char* topic, byte* message, unsigned int length) {\r\n  \r\n  String messageTemp;\r\n  \r\n  for (int i = 0; i &lt; length; i++) {\r\n    messageTemp += (char)message[i];\r\n  }\r\n\r\n  if (String(topic) == \"Wemos-184\/UpdateTime\") {\r\n    if(messageTemp == \"CheckTime\"){\r\n          timeClient.update();\r\n    }\r\n  }  \r\n\r\n  if (String(topic) == \"Wemos-184\/Reboot\") {\r\n    if(messageTemp == \"Reboot\"){\r\n      ESP.restart();\r\n    }\r\n  }\r\n\r\n  if (String(topic) == \"Wemos-184\/OnOff\") {\r\n    if(messageTemp == \"Pushed\"){\r\n      pinMode(OnOff, OUTPUT);\r\n      digitalWrite(Mode, LOW);   \r\n      delay(DeBounceDelay);                       \r\n      digitalWrite(Mode, HIGH);  \r\n      pinMode(OnOff, INPUT);\r\n      if (PowerState == 1) {\r\n        PowerState = 0;\r\n        PanelState = 0;\r\n      } else {\r\n        PowerState = PowerState + 1;\r\n        PanelState = 1;\r\n        PanelClock = millis();\r\n        PanelCountdown = PanelClock;\r\n      }\r\n    }\r\n  }\r\n\r\n  if (String(topic) == \"Wemos-184\/Mode\") {\r\n    if (PowerState == 1) {\r\n      if(messageTemp == \"Pushed\"){\r\n        if (PanelState == 1) {\r\n          PanelClock = millis();\r\n          PanelCountdown = PanelClock;\r\n          pinMode(Mode, OUTPUT);\r\n          digitalWrite(Mode, LOW);   \r\n          delay(DeBounceDelay);                       \r\n          digitalWrite(Mode, HIGH);  \r\n          pinMode(Mode, INPUT);\r\n          if (OperationState == 3) {\r\n            OperationState = 0;\r\n          } else {\r\n            OperationState = OperationState + 1;\r\n          }\r\n        } else {\r\n          PanelState = 1;\r\n          PanelClock = millis();\r\n          PanelCountdown = PanelClock;\r\n          pinMode(Mode, OUTPUT);\r\n          digitalWrite(Mode, LOW);   \r\n          delay(DeBounceDelay);                       \r\n          digitalWrite(Mode, HIGH);  \r\n          pinMode(Mode, INPUT);\r\n        }\r\n      } else {\r\n        \/\/ Ignore If Power State Is Off\r\n      }\r\n    }\r\n  }\r\n  \r\n}\r\n\r\n\r\n\r\nvoid reconnect() {\r\n  \/\/ Loop until we're reconnected\r\n  while (!MQTTclient.connected()) {\r\n    \/\/ Attempt to connect\r\n    if (MQTTclient.connect(\"Wemos-184\")) {\r\n      \/\/ Subscribe\r\n      \/\/ Do you not subscribe to my methods?\r\n      \/\/ Wemos-184\/# for everything, or Wemos-184\/Uptime for just the Uptime\r\n      MQTTclient.subscribe(\"Wemos-184\/#\");\r\n    } else {\r\n      \/\/ Wait 5 seconds before retrying\r\n      delay(5000);\r\n    }\r\n  }\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nvoid UpdateStats() {\r\n  \r\n  long stats = millis();\r\n  if (stats - laststats &gt; 5000) {\r\n    laststats = stats;\r\n\r\n    MQTTclient.publish(\"Wemos-184\/Firmware\", \"Wemos-184_MQTT_Pelonis-Space-Heater-Controller_ver11\");     \r\n    String StringUptime = String(millis());\r\n    MQTTclient.publish(\"Wemos-184\/Uptime\", StringUptime.c_str());\r\n    String StringHWAddress = String(WiFi.macAddress());\r\n    MQTTclient.publish(\"Wemos-184\/HWAddress\", StringHWAddress.c_str());   \r\n    String StringWifiSignal = String(WiFi.RSSI());\r\n    MQTTclient.publish(\"Wemos-184\/WifiSignal\",StringWifiSignal.c_str());  \r\n\r\n    String StringPowerState = String(PowerState);\r\n    MQTTclient.publish(\"Wemos-184\/PowerState\",StringPowerState.c_str());  \r\n    String StringOperationState = String(OperationState);\r\n    MQTTclient.publish(\"Wemos-184\/OperationState\",StringOperationState.c_str());  \r\n    String StringPanelState = String(PanelState);\r\n    MQTTclient.publish(\"Wemos-184\/PanelState\",StringPanelState.c_str());  \r\n\r\n    if ((OperationState == 0) &amp;&amp; (PowerState == 1)) {\r\n      WattsUsed = WattsUsed + 2.08;\r\n      } else if ((OperationState == 1) &amp;&amp; (PowerState == 1)) {\r\n      WattsUsed = WattsUsed + 1.17;\r\n      } else {\r\n    }  WattsUsed = WattsUsed;\r\n    String StringWattsUsed = String(WattsUsed);\r\n    MQTTclient.publish(\"Wemos-184\/WattsUsed\",StringWattsUsed.c_str());      \r\n    \r\n    String StringFreeHeapSize = String(ESP.getFreeHeap());\r\n    MQTTclient.publish(\"Wemos-184\/FreeHeapSize\",StringFreeHeapSize.c_str());  \r\n    String StringHeapFragmentation = String(ESP.getHeapFragmentation());\r\n    MQTTclient.publish(\"Wemos-184\/HeapFragmentation\",StringHeapFragmentation.c_str());  \r\n    String StringMaxFreeBlockSize = String(ESP.getMaxFreeBlockSize());\r\n    MQTTclient.publish(\"Wemos-184\/MaxFreeBlockSize\",StringMaxFreeBlockSize.c_str());  \r\n    String StringSketchSize = String(ESP.getSketchSize());\r\n    MQTTclient.publish(\"Wemos-184\/SketchSize\",StringSketchSize.c_str());  \r\n    String StringFreeSketchSpace = String(ESP.getFreeSketchSpace());\r\n    MQTTclient.publish(\"Wemos-184\/FreeSketchSpace\",StringFreeSketchSpace.c_str());  \r\n    String StringCpuFreqMHz = String(ESP.getCpuFreqMHz());\r\n    MQTTclient.publish(\"Wemos-184\/CpuFreqMHz\",StringCpuFreqMHz.c_str());\r\n    String StringChipId = String(ESP.getChipId());\r\n    MQTTclient.publish(\"Wemos-184\/ChipId\",StringChipId.c_str());  \r\n    String StringVcc = String(ESP.getVcc());\r\n    MQTTclient.publish(\"Wemos-184\/Vcc\",StringVcc.c_str());  \r\n\r\n    \/\/Get a Time Structure\r\n    String formattedTime = timeClient.getFormattedTime();\r\n    String StringformattedTime = String(formattedTime);\r\n    MQTTclient.publish(\"Wemos-184\/Time\",StringformattedTime.c_str());  \r\n\r\n    \/\/Get a Date Structure\r\n    time_t epochTime = timeClient.getEpochTime();\r\n    struct tm *ptm = gmtime ((time_t *)&amp;epochTime); \r\n    int monthDay = ptm-&gt;tm_mday;\r\n    int currentMonth = ptm-&gt;tm_mon+1;\r\n    String currentMonthName = months[currentMonth-1];\r\n    int currentYear = ptm-&gt;tm_year+1900;\r\n    \r\n    \/\/Publish complete date:\r\n    String StringcurrentDate = String(currentMonth) + \"\/\" + String(monthDay) + \"\/\" + String(currentYear);\r\n    MQTTclient.publish(\"Wemos-184\/Date\",StringcurrentDate.c_str());  \r\n    \r\n    \/\/Publish Epoch:\r\n    String StringEpochTime = String(timeClient.getEpochTime());\r\n    MQTTclient.publish(\"Wemos-184\/EpochTime\",StringEpochTime.c_str());  \r\n\r\n  }\r\n  \r\n}\r\n\r\n\r\n\r\n\r\nvoid InputCondition() {\r\n\r\n  OnOffState = digitalRead(OnOff);\r\n  if (OnOffState != LastOnOffState) {\r\n    if (OnOffState == HIGH) {\r\n      MQTTclient.publish(\"Wemos-184\/OnOffState\", \"0\");   \r\n      LastOnOffState = OnOffState; \r\n      PanelClock = millis();\r\n      PanelCountdown = PanelClock;\r\n    } else {\r\n      MQTTclient.publish(\"Wemos-184\/OnOffState\", \"1\");   \r\n      LastOnOffState = OnOffState;\r\n      if (PowerState == 1) {\r\n        PowerState = 0;\r\n        PanelState = 0;\r\n      } else {\r\n        PowerState = PowerState + 1;\r\n        PanelState = 1;\r\n        PanelClock = millis();\r\n        PanelCountdown = PanelClock;\r\n      }\r\n    }   \r\n    delay(DeBounceDelay);\r\n  }\r\n\r\n  ModeState = digitalRead(Mode);  \r\n  if (PowerState == 1) {\r\n    if (ModeState != LastModeState) {\r\n      if (PanelState == 1) {\r\n        PanelClock = millis();\r\n        PanelCountdown = PanelClock;\r\n        if (ModeState == HIGH) {\r\n          MQTTclient.publish(\"Wemos-184\/ModeState\", \"0\");   \r\n          LastModeState = ModeState;\r\n        } else {\r\n          MQTTclient.publish(\"Wemos-184\/ModeState\", \"1\");   \r\n          LastModeState = ModeState;\r\n          if (OperationState == 3) {\r\n            OperationState = 0;\r\n          } else {\r\n            OperationState = OperationState + 1;\r\n          }\r\n        }\r\n      } else {\r\n        PanelState = 1;\r\n        PanelClock = millis();\r\n        PanelCountdown = PanelClock;\r\n        if (ModeState == HIGH) {\r\n          MQTTclient.publish(\"Wemos-184\/ModeState\", \"0\");   \r\n          LastModeState = ModeState;\r\n        } else {\r\n          MQTTclient.publish(\"Wemos-184\/ModeState\", \"1\");   \r\n          LastModeState = ModeState;\r\n        }\r\n      }\r\n      delay(DeBounceDelay);\r\n    }\r\n  }\r\n  \r\n}\r\n\r\n\r\n\r\n\/\/ Setup Function\r\nvoid setup() {\r\n\r\n  \/\/ Iinitialize the Pelonis Space Heater Button pins as inputs\r\n  pinMode(OnOff, INPUT);\r\n  pinMode(Mode, INPUT);\r\n\r\n  delay(1000);\r\n  \r\n  WiFi.mode(WIFI_STA);\r\n  WiFi.begin(ssid, password);\r\n  while (WiFi.status() != WL_CONNECTED)\r\n    {\r\n      \/\/ Just wait it out\r\n      delay(250);\r\n    }\r\n  \r\n  MQTTclient.setServer(mqtt_server, 1883);\r\n  MQTTclient.setCallback(callback);\r\n\r\n  timeClient.begin(); \/\/ Initialize a NTPClient to get time\r\n  timeClient.setTimeOffset(-25200);\r\n  \/\/ Set offset time in seconds to adjust for your timezone, for example:\r\n  \/\/ GMT -7 = -25200 (see - https:\/\/time.gov\/)\r\n  delay(1000);\r\n  timeClient.update();\r\n  \r\n}\r\n\r\n\r\n\/\/ Main Loop Function\r\nvoid loop() {\r\n  \r\n  if (!MQTTclient.connected()) {\r\n    reconnect();\r\n  } \r\n  MQTTclient.loop();\r\n  UpdateStats();\r\n  InputCondition();\r\n\r\n  PanelClock = millis();\r\n  if (PanelClock - PanelCountdown &gt; 60000) {\r\n    PanelCountdown = PanelClock;\r\n    PanelState = 0;\r\n  }\r\n\r\n  \/\/ Update time from NTP source every 1 day (24 * 60 * 60 * 1000 = 86400000 milli-seconds)\r\n  unsigned long timeupdate = millis();\r\n  if (timeupdate - lasttimeupdate &gt; 86400000) {\r\n    lasttimeupdate = timeupdate;\r\n    timeClient.update(); \r\n  }\r\n\r\n  \/\/ Reboot microcontroller every 30 day to avoid millis() rollover (30 * 24 * 60 * 60 * 1000 = 2592000000 milli-seconds)\r\n  unsigned long timereboot = millis();\r\n  if (timereboot - lasttimereboot &gt; 2592000000) {\r\n      \/\/ Reboot command\r\n      ESP.restart();\r\n  }\r\n\r\n\r\n}\r\n\r\n\r\n\/**\r\n\r\n  Footer\r\n  \r\n*\/<\/pre>\n<p>The Node-Red flows are similar to earlier posting on this blog. However, the energy usage flows use a math function to provide a daily average of watt hours used.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Flow.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-4579\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Flow.png\" alt=\"\" width=\"968\" height=\"603\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Flow.png 968w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Flow-300x187.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Flow-768x478.png 768w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Flow-433x270.png 433w\" sizes=\"auto, (max-width: 968px) 100vw, 968px\" \/><\/a><\/p>\n<p>Here are the details for the watt usage flows.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">[\r\n    {\r\n        \"id\": \"417952fce84bb17d\",\r\n        \"type\": \"ui_text\",\r\n        \"z\": \"4d44da15033849c8\",\r\n        \"group\": \"6d9b77eeca28b65c\",\r\n        \"order\": 13,\r\n        \"width\": 0,\r\n        \"height\": 0,\r\n        \"name\": \"\",\r\n        \"label\": \"Watts Used\",\r\n        \"format\": \"{{msg.payload}}\",\r\n        \"layout\": \"row-spread\",\r\n        \"className\": \"\",\r\n        \"x\": 2570,\r\n        \"y\": 660,\r\n        \"wires\": []\r\n    },\r\n    {\r\n        \"id\": \"308bdda3b45f03b1\",\r\n        \"type\": \"ui_text\",\r\n        \"z\": \"4d44da15033849c8\",\r\n        \"group\": \"6d9b77eeca28b65c\",\r\n        \"order\": 14,\r\n        \"width\": 0,\r\n        \"height\": 0,\r\n        \"name\": \"\",\r\n        \"label\": \"Daily Ave Watt Hour Used\",\r\n        \"format\": \"{{msg.payload}}\",\r\n        \"layout\": \"row-spread\",\r\n        \"className\": \"\",\r\n        \"x\": 2610,\r\n        \"y\": 700,\r\n        \"wires\": []\r\n    },\r\n    {\r\n        \"id\": \"de1f326ceb1b70f8\",\r\n        \"type\": \"function\",\r\n        \"z\": \"4d44da15033849c8\",\r\n        \"name\": \"Daily Ave Math\",\r\n        \"func\": \"totalwatts=msg.payload;\\nmsg.payload = (totalwatts \/ 24).toFixed(2);\\nreturn msg;\",\r\n        \"outputs\": 1,\r\n        \"noerr\": 0,\r\n        \"initialize\": \"\",\r\n        \"finalize\": \"\",\r\n        \"libs\": [],\r\n        \"x\": 2320,\r\n        \"y\": 700,\r\n        \"wires\": [\r\n            [\r\n                \"308bdda3b45f03b1\"\r\n            ]\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"b172fdf0e41a9c07\",\r\n        \"type\": \"mqtt in\",\r\n        \"z\": \"4d44da15033849c8\",\r\n        \"name\": \"\",\r\n        \"topic\": \"Wemos-184\/WattsUsed\",\r\n        \"qos\": \"0\",\r\n        \"datatype\": \"auto\",\r\n        \"broker\": \"54b01280.e7076c\",\r\n        \"nl\": false,\r\n        \"rap\": false,\r\n        \"inputs\": 0,\r\n        \"x\": 1880,\r\n        \"y\": 660,\r\n        \"wires\": [\r\n            [\r\n                \"417952fce84bb17d\",\r\n                \"de1f326ceb1b70f8\",\r\n                \"dc6a31b914cc4228\"\r\n            ]\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"6d9b77eeca28b65c\",\r\n        \"type\": \"ui_group\",\r\n        \"name\": \"Pelonis Space Heater\",\r\n        \"tab\": \"6135d078965eafde\",\r\n        \"order\": 3,\r\n        \"disp\": true,\r\n        \"width\": \"7\",\r\n        \"collapse\": false,\r\n        \"className\": \"\"\r\n    },\r\n    {\r\n        \"id\": \"54b01280.e7076c\",\r\n        \"type\": \"mqtt-broker\",\r\n        \"name\": \"MQTT-BROKER-NAME\",\r\n        \"broker\": \"MQTT-BROKER-IP\",\r\n        \"port\": \"MQTT-BROKER-PORT\",\r\n        \"clientid\": \"\",\r\n        \"autoConnect\": true,\r\n        \"usetls\": false,\r\n        \"protocolVersion\": \"3\",\r\n        \"keepalive\": \"60\",\r\n        \"cleansession\": true,\r\n        \"birthTopic\": \"\",\r\n        \"birthQos\": \"0\",\r\n        \"birthPayload\": \"\",\r\n        \"birthMsg\": {},\r\n        \"closeTopic\": \"\",\r\n        \"closePayload\": \"\",\r\n        \"closeMsg\": {},\r\n        \"willTopic\": \"\",\r\n        \"willQos\": \"0\",\r\n        \"willPayload\": \"\",\r\n        \"willMsg\": {},\r\n        \"sessionExpiry\": \"\"\r\n    },\r\n    {\r\n        \"id\": \"6135d078965eafde\",\r\n        \"type\": \"ui_tab\",\r\n        \"name\": \"Space Heater\",\r\n        \"icon\": \"dashboard\",\r\n        \"order\": 5,\r\n        \"disabled\": false,\r\n        \"hidden\": false\r\n    }\r\n]<\/pre>\n<p>Some of the other features handled by Node-Red are storing the values published by the module to the MQTT broker. These variables are referenced in functions to control the heater and store readings into a log file.<\/p>\n<p><a href=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Function-Flow.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4580 size-full\" src=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Function-Flow.png\" alt=\"\" width=\"1087\" height=\"409\" srcset=\"https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Function-Flow.png 1087w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Function-Flow-300x113.png 300w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Function-Flow-1024x385.png 1024w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Function-Flow-768x289.png 768w, https:\/\/www.cloudacm.com\/wp-content\/uploads\/2024\/01\/Node-Red-Pelonis-Space-Heater-Function-Flow-604x227.png 604w\" sizes=\"auto, (max-width: 1087px) 100vw, 1087px\" \/><\/a><\/p>\n<p>Here are the details for the variable flows.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"js\">[\r\n    {\r\n        \"id\": \"dcdba04f.d1f238\",\r\n        \"type\": \"tab\",\r\n        \"label\": \"Flow 1\",\r\n        \"disabled\": false,\r\n        \"info\": \"\"\r\n    },\r\n    {\r\n        \"id\": \"b14d4720.902cb\",\r\n        \"type\": \"mqtt out\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Wemos-184 OnOff\",\r\n        \"topic\": \"Wemos-184\/OnOff\",\r\n        \"qos\": \"0\",\r\n        \"retain\": \"\",\r\n        \"broker\": \"5e4afd44.ddb3d4\",\r\n        \"x\": 790,\r\n        \"y\": 140,\r\n        \"wires\": []\r\n    },\r\n    {\r\n        \"id\": \"889ecbae.8d1748\",\r\n        \"type\": \"ui_button\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"On \/ Off\",\r\n        \"group\": \"700e09da.cbb21\",\r\n        \"order\": 6,\r\n        \"width\": \"2\",\r\n        \"height\": \"1\",\r\n        \"passthru\": true,\r\n        \"label\": \"On \/ Off\",\r\n        \"tooltip\": \"\",\r\n        \"color\": \"#585858\",\r\n        \"bgcolor\": \"#242424\",\r\n        \"icon\": \"\",\r\n        \"payload\": \"Pushed\",\r\n        \"payloadType\": \"str\",\r\n        \"topic\": \"Wemos-184\/OnOff\",\r\n        \"x\": 600,\r\n        \"y\": 140,\r\n        \"wires\": [\r\n            [\r\n                \"b14d4720.902cb\"\r\n            ]\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"484aa462.962d6c\",\r\n        \"type\": \"link in\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Pelonis Power Control In\",\r\n        \"links\": [\r\n            \"bf40758e.dda6d8\"\r\n        ],\r\n        \"x\": 395,\r\n        \"y\": 140,\r\n        \"wires\": [\r\n            [\r\n                \"889ecbae.8d1748\"\r\n            ]\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"f9755330.554a2\",\r\n        \"type\": \"change\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Set Flow Variable PorchTemp\",\r\n        \"rules\": [\r\n            {\r\n                \"t\": \"set\",\r\n                \"p\": \"PorchTemp\",\r\n                \"pt\": \"flow\",\r\n                \"to\": \"payload\",\r\n                \"tot\": \"msg\"\r\n            }\r\n        ],\r\n        \"action\": \"\",\r\n        \"property\": \"\",\r\n        \"from\": \"\",\r\n        \"to\": \"\",\r\n        \"reg\": false,\r\n        \"x\": 480,\r\n        \"y\": 240,\r\n        \"wires\": [\r\n            []\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"dedebb81.bb3958\",\r\n        \"type\": \"change\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Set Flow Variable OfficeTemp\",\r\n        \"rules\": [\r\n            {\r\n                \"t\": \"set\",\r\n                \"p\": \"OfficeTemp\",\r\n                \"pt\": \"flow\",\r\n                \"to\": \"payload\",\r\n                \"tot\": \"msg\"\r\n            }\r\n        ],\r\n        \"action\": \"\",\r\n        \"property\": \"\",\r\n        \"from\": \"\",\r\n        \"to\": \"\",\r\n        \"reg\": false,\r\n        \"x\": 480,\r\n        \"y\": 280,\r\n        \"wires\": [\r\n            []\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"8cf66698.e9d418\",\r\n        \"type\": \"change\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Set Flow Variable PelonisOnlineStatus\",\r\n        \"rules\": [\r\n            {\r\n                \"t\": \"set\",\r\n                \"p\": \"PelonisOnlineStatus\",\r\n                \"pt\": \"flow\",\r\n                \"to\": \"payload\",\r\n                \"tot\": \"msg\"\r\n            }\r\n        ],\r\n        \"action\": \"\",\r\n        \"property\": \"\",\r\n        \"from\": \"\",\r\n        \"to\": \"\",\r\n        \"reg\": false,\r\n        \"x\": 510,\r\n        \"y\": 320,\r\n        \"wires\": [\r\n            []\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"b7a38c6.47a637\",\r\n        \"type\": \"change\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Set Flow Variable PelonisLatency\",\r\n        \"rules\": [\r\n            {\r\n                \"t\": \"set\",\r\n                \"p\": \"PelonisLatency\",\r\n                \"pt\": \"flow\",\r\n                \"to\": \"payload\",\r\n                \"tot\": \"msg\"\r\n            }\r\n        ],\r\n        \"action\": \"\",\r\n        \"property\": \"\",\r\n        \"from\": \"\",\r\n        \"to\": \"\",\r\n        \"reg\": false,\r\n        \"x\": 500,\r\n        \"y\": 360,\r\n        \"wires\": [\r\n            []\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"2ee2eb14.7c50fc\",\r\n        \"type\": \"change\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Set Flow Variable PelonisPowerState\",\r\n        \"rules\": [\r\n            {\r\n                \"t\": \"set\",\r\n                \"p\": \"PelonisPowerState\",\r\n                \"pt\": \"flow\",\r\n                \"to\": \"payload\",\r\n                \"tot\": \"msg\"\r\n            }\r\n        ],\r\n        \"action\": \"\",\r\n        \"property\": \"\",\r\n        \"from\": \"\",\r\n        \"to\": \"\",\r\n        \"reg\": false,\r\n        \"x\": 510,\r\n        \"y\": 400,\r\n        \"wires\": [\r\n            []\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"8459827c.117da8\",\r\n        \"type\": \"change\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Set Flow Variable PelonisPanelState\",\r\n        \"rules\": [\r\n            {\r\n                \"t\": \"set\",\r\n                \"p\": \"PelonisPanelState\",\r\n                \"pt\": \"flow\",\r\n                \"to\": \"payload\",\r\n                \"tot\": \"msg\"\r\n            }\r\n        ],\r\n        \"action\": \"\",\r\n        \"property\": \"\",\r\n        \"from\": \"\",\r\n        \"to\": \"\",\r\n        \"reg\": false,\r\n        \"x\": 510,\r\n        \"y\": 440,\r\n        \"wires\": [\r\n            []\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"ccfce7c6.d8bd4\",\r\n        \"type\": \"change\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Set Flow Variable PelonisOpState\",\r\n        \"rules\": [\r\n            {\r\n                \"t\": \"set\",\r\n                \"p\": \"PelonisOpState\",\r\n                \"pt\": \"flow\",\r\n                \"to\": \"payload\",\r\n                \"tot\": \"msg\"\r\n            }\r\n        ],\r\n        \"action\": \"\",\r\n        \"property\": \"\",\r\n        \"from\": \"\",\r\n        \"to\": \"\",\r\n        \"reg\": false,\r\n        \"x\": 500,\r\n        \"y\": 480,\r\n        \"wires\": [\r\n            []\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"8deb0a5f.cd36d8\",\r\n        \"type\": \"change\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Set Flow Variable PelonisWattsUsed\",\r\n        \"rules\": [\r\n            {\r\n                \"t\": \"set\",\r\n                \"p\": \"PelonisWattsUsed\",\r\n                \"pt\": \"flow\",\r\n                \"to\": \"payload\",\r\n                \"tot\": \"msg\"\r\n            }\r\n        ],\r\n        \"action\": \"\",\r\n        \"property\": \"\",\r\n        \"from\": \"\",\r\n        \"to\": \"\",\r\n        \"reg\": false,\r\n        \"x\": 510,\r\n        \"y\": 520,\r\n        \"wires\": [\r\n            []\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"daf35ed2.e24558\",\r\n        \"type\": \"change\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Set Flow Variable PelonisBypass\",\r\n        \"rules\": [\r\n            {\r\n                \"t\": \"set\",\r\n                \"p\": \"PelonisBypass\",\r\n                \"pt\": \"flow\",\r\n                \"to\": \"payload\",\r\n                \"tot\": \"msg\"\r\n            }\r\n        ],\r\n        \"action\": \"\",\r\n        \"property\": \"\",\r\n        \"from\": \"\",\r\n        \"to\": \"\",\r\n        \"reg\": false,\r\n        \"x\": 500,\r\n        \"y\": 560,\r\n        \"wires\": [\r\n            []\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"9d87ef2c.3d452\",\r\n        \"type\": \"inject\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Trigger Every 1 Minute\",\r\n        \"topic\": \"\",\r\n        \"payloadType\": \"date\",\r\n        \"repeat\": \"60\",\r\n        \"crontab\": \"\",\r\n        \"once\": false,\r\n        \"onceDelay\": 0.1,\r\n        \"x\": 270,\r\n        \"y\": 640,\r\n        \"wires\": [\r\n            [\r\n                \"48fa77c2.35eff\",\r\n                \"856c8c1d.4ff598\"\r\n            ]\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"48fa77c2.35eff\",\r\n        \"type\": \"function\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Gather Variables and Format Row\",\r\n        \"func\": \"var d = new Date();\\nvar pt = flow.get('PorchTemp');\\nvar ot = flow.get('OfficeTemp');\\nvar pos = flow.get('PelonisOnlineStatus');\\nvar plt = flow.get('PelonisLatency');\\nvar pps = flow.get('PelonisPowerState');\\nvar ppa = flow.get('PelonisPanelState');\\nvar pop = flow.get('PelonisOpState');\\nvar pwu = flow.get('PelonisWattsUsed');\\nvar row = {d, pt, ot, pos, plt, pps, ppa, pop, pwu};\\nmsg.payload = row;\\nreturn msg;\",\r\n        \"outputs\": 1,\r\n        \"noerr\": 0,\r\n        \"x\": 620,\r\n        \"y\": 640,\r\n        \"wires\": [\r\n            [\r\n                \"ca89c83f.63f318\"\r\n            ]\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"856c8c1d.4ff598\",\r\n        \"type\": \"function\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Gather Variables and Determine Action Rev 7\",\r\n        \"func\": \"\/\/ Working With Time- Node-Red Programming\\n\/\/ See https:\/\/stevesnoderedguide.com\/working-with-time\\n\\nvar TimeNow = new Date();\\nvar HourNow = TimeNow.getHours(); \\nvar NumHour = Number(HourNow);\\nvar DayNow = TimeNow.getDay();\\nvar Sunday = 0;\\nvar Monday = 1;\\nvar Tuesday = 2;\\nvar Wednesday = 3;\\nvar Thursday = 4;\\nvar Friday = 5;\\nvar Saturday = 6;\\n\\nvar WeekdayMorningHour = 4;\\nvar WeekendMorningHour = 6;\\nvar EveningHour = 22;\\n\\n\/\/ Day Time Operation with median at 71 ( hysteresis is 70 to 72 )\\n\/\/      68 is the typical recommended baseline for cost savings\\nvar DayThermo = 71;\\nvar HysteresisDayHigh = DayThermo + 1;\\nvar HysteresisDayLow = DayThermo - 1;\\n\\n\/\/ Night Time Operation with median at 65 ( hysteresis is 64 to 66 )\\n\/\/      58 is the typical recommended baseline for cost savings\\nvar NightThermo = 65;\\nvar HysteresisNightHigh = NightThermo + 1;\\nvar HysteresisNightLow = NightThermo - 1;\\n\\nvar TempOffice = flow.get('OfficeTemp');\\nvar NumOfficeTemp = Number(TempOffice);\\nvar OnlineStatus = flow.get('PelonisOnlineStatus');\\nvar PowerState = flow.get('PelonisPowerState');\\n\\n\\nif (\\n    OnlineStatus == \\\"On\\\" \\n    &amp;&amp; PowerState == \\\"1\\\" \\n    &amp;&amp; NumOfficeTemp &gt;= HysteresisDayHigh \\n    &amp;&amp; NumHour &gt;= WeekdayMorningHour \\n    &amp;&amp; NumHour &lt; EveningHour \\n    &amp;&amp; (DayNow &lt; Saturday &amp;&amp; DayNow &gt; Sunday))\\n    NewPowerState = \\\"Off\\\";\\n\\nif (\\n    OnlineStatus == \\\"On\\\" \\n    &amp;&amp; PowerState == \\\"0\\\" \\n    &amp;&amp; NumOfficeTemp &lt; HysteresisDayLow \\n    &amp;&amp; NumHour &gt;= WeekdayMorningHour \\n    &amp;&amp; NumHour &lt; EveningHour \\n    &amp;&amp; (DayNow &lt; Saturday &amp;&amp; DayNow &gt; Sunday))\\n    NewPowerState = \\\"On\\\";\\n    \\n\\nif (\\n    OnlineStatus == \\\"On\\\" \\n    &amp;&amp; PowerState == \\\"1\\\" \\n    &amp;&amp;  NumOfficeTemp &gt;= HysteresisNightHigh \\n    &amp;&amp; (NumHour &lt; WeekdayMorningHour || NumHour &gt;= EveningHour) \\n    &amp;&amp; (DayNow &lt; Saturday &amp;&amp; DayNow &gt; Sunday))\\n    NewPowerState = \\\"Off\\\";\\n\\nif (\\n    OnlineStatus == \\\"On\\\" \\n    &amp;&amp; PowerState == \\\"0\\\" \\n    &amp;&amp; NumOfficeTemp &lt; HysteresisNightLow \\n    &amp;&amp; (NumHour &lt; WeekdayMorningHour || NumHour &gt;= EveningHour) \\n    &amp;&amp; (DayNow &lt; Saturday &amp;&amp; DayNow &gt; Sunday))\\n    NewPowerState = \\\"On\\\";\\n\\n\\nif (\\n    OnlineStatus == \\\"On\\\" \\n    &amp;&amp; PowerState == \\\"1\\\" \\n    &amp;&amp; NumOfficeTemp &gt;= HysteresisDayHigh \\n    &amp;&amp; NumHour &gt;= WeekendMorningHour \\n    &amp;&amp; NumHour &lt; EveningHour \\n    &amp;&amp; (DayNow &lt; Monday || DayNow &gt; Friday))\\n    NewPowerState = \\\"Off\\\";\\n\\nif (\\n    OnlineStatus == \\\"On\\\" \\n    &amp;&amp; PowerState == \\\"0\\\" \\n    &amp;&amp; NumOfficeTemp &lt; HysteresisDayLow \\n    &amp;&amp; NumHour &gt;= WeekendMorningHour \\n    &amp;&amp; NumHour &lt; EveningHour \\n    &amp;&amp; (DayNow &lt; Monday || DayNow &gt; Friday))\\n    NewPowerState = \\\"On\\\";\\n    \\n\\nif (\\n    OnlineStatus == \\\"On\\\" \\n    &amp;&amp; PowerState == \\\"1\\\" \\n    &amp;&amp;  NumOfficeTemp &gt;= HysteresisNightHigh \\n    &amp;&amp; (NumHour &lt; WeekendMorningHour || NumHour &gt;= EveningHour) \\n    &amp;&amp; (DayNow &lt; Monday || DayNow &gt; Friday))\\n    NewPowerState = \\\"Off\\\";\\n\\nif (\\n    OnlineStatus == \\\"On\\\" \\n    &amp;&amp; PowerState == \\\"0\\\" \\n    &amp;&amp; NumOfficeTemp &lt; HysteresisNightLow \\n    &amp;&amp; (NumHour &lt; WeekendMorningHour || NumHour &gt;= EveningHour) \\n    &amp;&amp; (DayNow &lt; Monday || DayNow &gt; Friday))\\n    NewPowerState = \\\"On\\\";\\n\\nmsg.payload = NewPowerState;\\nreturn msg;\",\r\n        \"outputs\": 1,\r\n        \"noerr\": 0,\r\n        \"x\": 650,\r\n        \"y\": 680,\r\n        \"wires\": [\r\n            [\r\n                \"5d6c2db8.a6f28c\"\r\n            ]\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"5d6c2db8.a6f28c\",\r\n        \"type\": \"rbe\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"State Changes Only\",\r\n        \"func\": \"rbe\",\r\n        \"gap\": \"\",\r\n        \"start\": \"\",\r\n        \"inout\": \"out\",\r\n        \"property\": \"payload\",\r\n        \"x\": 980,\r\n        \"y\": 680,\r\n        \"wires\": [\r\n            [\r\n                \"756e1fd.279966\"\r\n            ]\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"756e1fd.279966\",\r\n        \"type\": \"change\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Chnage to Pushed Message\",\r\n        \"rules\": [\r\n            {\r\n                \"t\": \"change\",\r\n                \"p\": \"payload\",\r\n                \"pt\": \"msg\",\r\n                \"from\": \"On\",\r\n                \"fromt\": \"str\",\r\n                \"to\": \"Pushed\",\r\n                \"tot\": \"str\"\r\n            },\r\n            {\r\n                \"t\": \"change\",\r\n                \"p\": \"payload\",\r\n                \"pt\": \"msg\",\r\n                \"from\": \"Off\",\r\n                \"fromt\": \"str\",\r\n                \"to\": \"Pushed\",\r\n                \"tot\": \"str\"\r\n            }\r\n        ],\r\n        \"action\": \"\",\r\n        \"property\": \"\",\r\n        \"from\": \"\",\r\n        \"to\": \"\",\r\n        \"reg\": false,\r\n        \"x\": 1240,\r\n        \"y\": 680,\r\n        \"wires\": [\r\n            [\r\n                \"bf40758e.dda6d8\"\r\n            ]\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"ca89c83f.63f318\",\r\n        \"type\": \"file\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"\",\r\n        \"filename\": \"\/home\/user\/Node-Red Data Log\/TempLog.csv\",\r\n        \"appendNewline\": true,\r\n        \"createDir\": false,\r\n        \"overwriteFile\": \"false\",\r\n        \"encoding\": \"none\",\r\n        \"x\": 1170,\r\n        \"y\": 640,\r\n        \"wires\": [\r\n            []\r\n        ]\r\n    },\r\n    {\r\n        \"id\": \"bf40758e.dda6d8\",\r\n        \"type\": \"link out\",\r\n        \"z\": \"dcdba04f.d1f238\",\r\n        \"name\": \"Pelonis Power Control Out\",\r\n        \"links\": [\r\n            \"484aa462.962d6c\"\r\n        ],\r\n        \"x\": 1435,\r\n        \"y\": 680,\r\n        \"wires\": []\r\n    },\r\n    {\r\n        \"id\": \"5e4afd44.ddb3d4\",\r\n        \"type\": \"mqtt-broker\",\r\n        \"name\": \"MQTT-BROKER-NAME\",\r\n        \"broker\": \"MQTT-BROKER-IP\",\r\n        \"port\": \"MQTT-BROKER-PORT\",\r\n        \"clientid\": \"\",\r\n        \"usetls\": false,\r\n        \"compatmode\": false,\r\n        \"keepalive\": \"60\",\r\n        \"cleansession\": true,\r\n        \"birthTopic\": \"\",\r\n        \"birthQos\": \"0\",\r\n        \"birthPayload\": \"\",\r\n        \"closeTopic\": \"\",\r\n        \"closePayload\": \"\",\r\n        \"willTopic\": \"\",\r\n        \"willQos\": \"0\",\r\n        \"willPayload\": \"\"\r\n    },\r\n    {\r\n        \"id\": \"700e09da.cbb21\",\r\n        \"type\": \"ui_group\",\r\n        \"name\": \"Pelonis Space Heater\",\r\n        \"tab\": \"af2ff0ee.cec43\",\r\n        \"order\": 3,\r\n        \"disp\": true,\r\n        \"width\": \"7\",\r\n        \"collapse\": false\r\n    },\r\n    {\r\n        \"id\": \"af2ff0ee.cec43\",\r\n        \"type\": \"ui_tab\",\r\n        \"name\": \"Space Heater\",\r\n        \"icon\": \"dashboard\",\r\n        \"order\": 5,\r\n        \"disabled\": false,\r\n        \"hidden\": false\r\n    }\r\n]<\/pre>\n<p>Stay warm, just not too warm.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post will cover the use of the ESP8266 clone form factor of the more popular Wemos D1 Mini. This clone development module has the same pinout and interfaces as the Wemos D1 Mini. The Arduino IDE was set to use the NodeMCU 1.0 ESP12E Module for the code below, although the LOLIN(WEMOS) D1 mini (clone) was avaliable. This board selection didn&#8217;t present any issues when loading the firmware. The board is inexpensive, a 10 pack can run around $25&#8230;.<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"https:\/\/www.cloudacm.com\/?p=4567\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4567","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/4567","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4567"}],"version-history":[{"count":10,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/4567\/revisions"}],"predecessor-version":[{"id":4583,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=\/wp\/v2\/posts\/4567\/revisions\/4583"}],"wp:attachment":[{"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4567"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4567"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cloudacm.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4567"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}