Monitor for central heating system (e.g. 2zones+hw) Supports up to 15 temp probes (DS18B20/DS18S20) 3 valve monitors Gas pulse meter recording Use stand-alone or with nodeEnergyServer See http://robdobson.com/2015/09/central-heating-monitor
Dependencies: EthernetInterfacePlusHostname NTPClient Onewire RdWebServer SDFileSystem-RTOS mbed-rtos mbed-src
Diff: main.cpp
- Revision:
- 10:72eb217def1f
- Parent:
- 9:0e103c2f869a
- Child:
- 11:30182b9aa833
--- a/main.cpp Sun Feb 22 11:57:12 2015 +0000 +++ b/main.cpp Sun Feb 22 20:23:43 2015 +0000 @@ -4,6 +4,7 @@ #include "RdWebServer.h" #include "GasUseCounter.h" #include "Thermometers.h" +#include "VoltAlerter.h" #include <stdarg.h> // Web and UDB ports @@ -12,22 +13,25 @@ // Ticker collects data //Ticker ticker; -//const int TICK_MS = 250; +//const int TICK_MS = 50; const int LOOP_DELAY_IN_MS = 250; // Debugging and status RawSerial pc(USBTX, USBRX); DigitalOut led1(LED1); //ticking (flashes) -DigitalOut led2(LED2); //server listning status (flashes) +DigitalOut led2(LED2); // DigitalOut led3(LED3); //socket connecting status DigitalOut led4(LED4); //server status // Web server EthernetInterface eth; -NTPClient ntp; UDPSocket sendUDPSocket; Endpoint broadcastEndpoint; +// Network Time Protocol (NTP) +NTPClient ntp; +const int NTP_REFRESH_INTERVAL_HOURS = 1; + // File system for SD card SDFileSystem sd(p5, p6, p7, p8, "sd"); @@ -41,6 +45,28 @@ const PinName tempSensorPins[] = { p22 }; Thermometers thermometers(sizeof(tempSensorPins)/sizeof(PinName), tempSensorPins, LOOP_DELAY_IN_MS); +// Voltage Sensors / Alerters +const int NUM_VOLT_ALERTERS = 3; +VoltAlerter voltAlerter1(p23); +VoltAlerter voltAlerter2(p24); +VoltAlerter voltAlerter3(p25); + +// Broadcast message +const char broadcastMsgPrefix[] = "{\"e\":["; +const char broadcastMsgGasFormat[] = "{\"n\":\"gasCount\",\"v\":%d},{\"n\":\"gasPulseRateMs\",\"v\":%d,\"u\":\"ms\"}"; +const char broadcastTemperatureFormat[] = "{\"n\":\"temp_%s\",\"v\":%0.1f,\"u\":\"degC\"}"; +const char broadcastVoltAlerterFormat[] = "{\"n\":\"pump_%d\",\"v\":%d}"; +const char broadcastMsgSuffix[] = "],\"bt\":%d}"; + +// Format message +const int broadcastMsgLen = sizeof(broadcastMsgPrefix) + + sizeof(broadcastMsgGasFormat) + + (sizeof(broadcastTemperatureFormat)*Thermometers::MAX_THERMOMETERS) + + (sizeof(broadcastVoltAlerterFormat)*NUM_VOLT_ALERTERS) + + sizeof(broadcastMsgSuffix) + + 60; +char broadcastMsgBuffer[broadcastMsgLen]; + // Utility function to log data void LogData(const char* format, ...) { @@ -71,31 +97,54 @@ // Get temperature values TemperatureValue tempValues[Thermometers::MAX_THERMOMETERS]; int numTempValues = thermometers.GetTemperatureValues(Thermometers::MAX_THERMOMETERS, tempValues, 100); - char tempStr[200]; for (int tempIdx = 0; tempIdx < numTempValues; tempIdx++) { printf("Temp: %.1f, Addr: %s, Time: %d\r\n", tempValues[tempIdx].tempInCentigrade, tempValues[tempIdx].address, tempValues[tempIdx].timeStamp); } - // Format message - char outBuf[200]; - sprintf(outBuf, "{\"e\":[{\"n\":\"gasCount\",\"v\":%d},{\"n\":\"gasPulseRateMs\",\"v\":%d,\"u\":\"ms\"}]}", - gasUseCounter.GetCount(), gasUseCounter.GetPulseRateMs()); - + // Data format of the message - senml - https://tools.ietf.org/html/draft-jennings-senml-08 + // { + // "e": [ + // {"n":"gasCount","v":%d}, + // {"n":"gasPulseRateMs","v":%d,"u":"ms"}, + // {"n":"temp_%s","v":%0.1f,"u":"degC"}, + // ... + // {"n":"pump_%d","v":%d}, + // ... + // ], + // "bt": %d + // } + + time_t timeNow = time(NULL); + strcpy(broadcastMsgBuffer, broadcastMsgPrefix); + sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastMsgGasFormat, gasUseCounter.GetCount(), gasUseCounter.GetPulseRateMs()); + strcpy(broadcastMsgBuffer+strlen(broadcastMsgBuffer), ","); + for (int tempIdx = 0; tempIdx < numTempValues; tempIdx++) + { + sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastTemperatureFormat, tempValues[tempIdx].address, tempValues[tempIdx].tempInCentigrade); + strcpy(broadcastMsgBuffer+strlen(broadcastMsgBuffer), ","); + } + sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastVoltAlerterFormat, 1, voltAlerter1.GetState()); + strcpy(broadcastMsgBuffer+strlen(broadcastMsgBuffer), ","); + sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastVoltAlerterFormat, 2, voltAlerter2.GetState()); + strcpy(broadcastMsgBuffer+strlen(broadcastMsgBuffer), ","); + sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastVoltAlerterFormat, 3, voltAlerter3.GetState()); + sprintf(broadcastMsgBuffer+strlen(broadcastMsgBuffer), broadcastMsgSuffix, timeNow); + // Send - int bytesToSend = strlen(outBuf); - int rslt = sendUDPSocket.sendTo(broadcastEndpoint, outBuf, bytesToSend); + int bytesToSend = strlen(broadcastMsgBuffer); + int rslt = sendUDPSocket.sendTo(broadcastEndpoint, broadcastMsgBuffer, bytesToSend); if (rslt == bytesToSend) { - pc.printf("Broadcast Sent ok %s\n", outBuf); + pc.printf("Broadcast (len %d) Sent ok %s\r\n", bytesToSend, broadcastMsgBuffer); } else if (rslt == -1) { - pc.printf("Broadcast Failed to send %s\n", outBuf); + pc.printf("Broadcast Failed to send %s\r\n", broadcastMsgBuffer); } else { - pc.printf("Broadcast Didn't send all of %s\n", outBuf); + pc.printf("Broadcast Didn't send all of %s\r\n", broadcastMsgBuffer); } // Log @@ -161,17 +210,21 @@ else { printf("Cannot set from NTP\r\n"); - } - // 1 hour - for (int i = 0; i < 60; i++) + } + + // Refresh time every K hours + for (int k = 0; k < NTP_REFRESH_INTERVAL_HOURS; k++) { - for (int j = 0; j < 60; j++) + // 1 hour + for (int i = 0; i < 60; i++) { - osDelay(1000); + for (int j = 0; j < 60; j++) + { + osDelay(1000); + } + pc.printf("%d mins to next NTP time refresh\r\n", (NTP_REFRESH_INTERVAL_HOURS-k-1)*60 + (59-i)); } - pc.printf("%d mins since NTP\r\n", i); } - break; } } @@ -180,6 +233,8 @@ pc.baud(115200); pc.printf("Gas Monitor V2 - Rob Dobson 2014\r\n"); + printf("Broadcast Msg Len %d\r\n", broadcastMsgLen); + // ticker.attach(&TickFunction,TICK_MS / 1000.0); // Initialise thermometers @@ -224,6 +279,12 @@ SendInfoBroadcast(); timeOfLastBroadcast = time(NULL); } + + // Service volt alerters + voltAlerter1.Service(); + voltAlerter2.Service(); + voltAlerter3.Service(); + led2 = voltAlerter1.GetState(); } }