mirror of
https://github.com/rvdbreemen/OTGW-firmware
synced 2024-09-26 16:19:56 +02:00
Implement s0 counter and enhance onewire logic. Improve MQTT HA Autodiscover for temp sensor and s0 counter
This commit is contained in:
parent
836ef33811
commit
9199e43b8b
@ -528,6 +528,18 @@ void doAutoConfigure(bool bForcaAll = false){
|
||||
}
|
||||
//===========================================================================================
|
||||
bool doAutoConfigureMsgid(byte OTid)
|
||||
{
|
||||
String cfgSensorId = "" ;
|
||||
// check if foney dataid is called to do autoconfigure for temp sensors, call configsensors instead
|
||||
if (OTid == OTGWdallasdataid) {
|
||||
MQTTDebugTf(PSTR("Sending auto configuration for temp sensors %d\r\n"), OTid);
|
||||
configSensors() ;
|
||||
return true;
|
||||
}
|
||||
else return doAutoConfigureMsgid(OTid, cfgSensorId);
|
||||
}
|
||||
|
||||
bool doAutoConfigureMsgid(byte OTid, String cfgSensorId )
|
||||
{
|
||||
bool _result = false;
|
||||
|
||||
@ -590,6 +602,9 @@ bool doAutoConfigureMsgid(byte OTid)
|
||||
|
||||
/// node
|
||||
sTopic.replace("%node_id%", CSTR(NodeId));
|
||||
|
||||
/// SensorId
|
||||
sTopic.replace("%sensor_id%", CSTR(cfgSensorId));
|
||||
MQTTDebugf("[%s]\r\n", CSTR(sTopic));
|
||||
/// ----------------------
|
||||
|
||||
@ -598,6 +613,9 @@ bool doAutoConfigureMsgid(byte OTid)
|
||||
/// node
|
||||
sMsg.replace("%node_id%", CSTR(NodeId));
|
||||
|
||||
/// SensorId
|
||||
sTopic.replace("%sensor_id%", CSTR(cfgSensorId));
|
||||
|
||||
/// hostname
|
||||
sMsg.replace("%hostname%", CSTR(settingHostname));
|
||||
|
||||
@ -632,6 +650,27 @@ bool doAutoConfigureMsgid(byte OTid)
|
||||
return _result;
|
||||
}
|
||||
|
||||
void sensorAutoConfigure(byte dataid, bool finishflag , String cfgSensorId = "") {
|
||||
// Special version of Autoconfigure for sensors
|
||||
// dataid is a foney id, not used by OT
|
||||
// check wheter MQTT topic needs to be configured
|
||||
// cfgNodeId can be set to alternate NodeId to allow for multiple temperature sensors, should normally be NodeId
|
||||
// When finishflag is true, check on dataid is already done and complete the config. On false do the config and leave completion to caller
|
||||
if(getMQTTConfigDone(dataid)==false or !finishflag) {
|
||||
MQTTDebugTf(PSTR("Need to set MQTT config for sensor id(%d)\r\n"),dataid);
|
||||
bool success = doAutoConfigureMsgid(dataid,cfgSensorId);
|
||||
if(success) {
|
||||
MQTTDebugTf(PSTR("Successfully sent MQTT config for sensor id(%d)\r\n"),dataid);
|
||||
if (finishflag) setMQTTConfigDone(dataid);
|
||||
} else {
|
||||
MQTTDebugTf(PSTR("Not able to complete MQTT configuration for sensor id(%d)\r\n"),dataid);
|
||||
}
|
||||
} else {
|
||||
// MQTTDebugTf("No need to set MQTT config for sensor id(%d)\r\n",dataid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
@ -447,6 +447,9 @@ enum OpenThermMessageID {
|
||||
{ 132, OT_READ , ot_u8u8, "RemehaServicemessage", "Remeha Servicemessage", "" },
|
||||
{ 133, OT_READ , ot_u8u8, "RemehaDetectionConnectedSCU", "Remeha detection connected SCU’s", "" },
|
||||
// all data ids are not defined above are resevered for future use
|
||||
// A foney id is used for sensors on GPIO ports,
|
||||
// 245 for counter and
|
||||
// 246 for Dallas temperature sensors
|
||||
};
|
||||
|
||||
#define OT_MSGID_MAX 133
|
||||
|
@ -1487,7 +1487,7 @@ void processOT(const char *buf, int len){
|
||||
if (is_value_valid(OTdata, OTlookupitem) && settingMQTTenable ) {
|
||||
if(getMQTTConfigDone(OTdata.id)==false) {
|
||||
MQTTDebugTf(PSTR("Need to set MQTT config for message %s (%d)\r\n"), OTlookupitem.label, OTdata.id);
|
||||
bool success = doAutoConfigureMsgid(OTdata.id);
|
||||
bool success = doAutoConfigureMsgid(OTdata.id, NodeId);
|
||||
if(success) {
|
||||
MQTTDebugTf(PSTR("Successfully sent MQTT config for message %s (%d)\r\n"), OTlookupitem.label, OTdata.id);
|
||||
setMQTTConfigDone(OTdata.id);
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "safeTimers.h"
|
||||
#include "src/libraries/OTGWSerial/OTGWSerial.h" // Bron Schelte's Serial class - it upgrades and more
|
||||
#include "OTGW-Core.h" // Core code for this firmware
|
||||
#include <OneWire.h> // required for Dallas sensor library
|
||||
#include <DallasTemperature.h> // Miles Burton's - Arduino Dallas library
|
||||
|
||||
//OTGW Nodoshop hardware definitions
|
||||
#define I2CSCL D1
|
||||
@ -124,8 +126,36 @@ bool settingLEDblink = true;
|
||||
|
||||
// GPIO Sensor Settings
|
||||
bool settingGPIOSENSORSenabled = false;
|
||||
int8_t settingGPIOSENSORSpin = 10;
|
||||
int16_t settingGPIOSENSORSinterval = 5;
|
||||
int8_t settingGPIOSENSORSpin = 13; // GPIO 13 = D7, GPIO 10 = SDIO 3
|
||||
int16_t settingGPIOSENSORSinterval = 20; // Interval time to read out temp and send to MQ
|
||||
byte OTGWdallasdataid = 246; // foney dataid to be used to do autoconfigure for temp sensors
|
||||
int DallasrealDeviceCount = 0; // Total temperature devices found on the bus
|
||||
#define MAXDALLASDEVICES 16 // maximum number of devices on the bus
|
||||
|
||||
// Define structure to store temperature device addresses found on bus with their latest tempC value
|
||||
struct
|
||||
{
|
||||
int id;
|
||||
DeviceAddress addr;
|
||||
float tempC;
|
||||
time_t lasttime;
|
||||
} DallasrealDevice[MAXDALLASDEVICES];
|
||||
// prototype to allow use in restAPI.ino
|
||||
char* getDallasAddress(DeviceAddress deviceAddress);
|
||||
|
||||
|
||||
// S0 Counter Settings and variables with global scope
|
||||
bool settingS0COUNTERenabled = false;
|
||||
uint8_t settingS0COUNTERpin = 12; // GPIO 12 = D6, preferred, can be any pin with Interupt support
|
||||
uint16_t settingS0COUNTERdebouncetime = 80; // Depending on S0 switch a debouncetime should be tailored
|
||||
uint16_t settingS0COUNTERpulsekw = 1000; // Most S0 counters have 1000 pulses per kW, but this can be different
|
||||
uint16_t settingS0COUNTERinterval = 60; // Sugggested measurement reporting interval
|
||||
uint16_t OTGWs0pulseCount; // Number of S0 pulses in measurement interval
|
||||
uint32_t OTGWs0pulseCountTot = 0; // Number of S0 pulses since start of measurement
|
||||
float OTGWs0powerkw = 0 ; // Calculated kW actual consumption based on time between last pulses and settings
|
||||
time_t OTGWs0lasttime = 0; // Last time S0 counters have been read
|
||||
byte OTGWs0dataid = 245; // foney dataid to be used to do autoconfigure for counter
|
||||
|
||||
|
||||
//boot commands
|
||||
bool settingOTGWcommandenable = false;
|
||||
@ -135,6 +165,7 @@ String settingOTGWcommands = "";
|
||||
bool bDebugOTmsg = true;
|
||||
bool bDebugRestAPI = false;
|
||||
bool bDebugMQTT = false;
|
||||
bool bDebugSensors = false;
|
||||
|
||||
//GPIO Output Settings
|
||||
bool settingMyDEBUG = false;
|
||||
|
@ -41,6 +41,7 @@
|
||||
#define OFF HIGH
|
||||
|
||||
DECLARE_TIMER_SEC(timerpollsensor, settingGPIOSENSORSinterval, CATCH_UP_MISSED_TICKS);
|
||||
DECLARE_TIMER_SEC(timers0counter, settingS0COUNTERinterval, CATCH_UP_MISSED_TICKS);
|
||||
|
||||
//=====================================================================
|
||||
void setup() {
|
||||
@ -100,7 +101,7 @@ void setup() {
|
||||
// Setup the OTGW PIC
|
||||
resetOTGW(); // reset the OTGW pic
|
||||
startOTGWstream(); // start port 25238
|
||||
initSensors(); // init DS18B20
|
||||
// initSensors(); // init DS18B20 (after MQ is up! )
|
||||
initOutputs();
|
||||
|
||||
WatchDogEnabled(1); // turn on watchdog
|
||||
@ -111,6 +112,8 @@ void setup() {
|
||||
setLed(LED2, OFF);
|
||||
sendMQTTuptime();
|
||||
sendMQTTversioninfo();
|
||||
initS0Count(); // init S0 counter
|
||||
initSensors(); // init DS18B20 (after MQ is up!)
|
||||
}
|
||||
//=====================================================================
|
||||
|
||||
@ -317,6 +320,7 @@ void loop()
|
||||
DECLARE_TIMER_MIN(timer24h, 1440, CATCH_UP_MISSED_TICKS);
|
||||
|
||||
if (DUE(timerpollsensor)) pollSensors(); // poll the temperature sensors connected to 2wire gpio pin
|
||||
if (DUE(timers0counter)) sendS0Counters(); // poll the s0 counter connected to gpio pin when due
|
||||
if (DUE(timer5min)) do5minevent();
|
||||
if (DUE(timer60s)) doTaskEvery60s();
|
||||
if (DUE(timer30s)) doTaskEvery30s();
|
||||
|
@ -45,7 +45,9 @@ The features of this Nodosop OpenTherm Gateware ESP8266 based firmware are:
|
||||
- integration with any MQTT based Home Automation solution, like Domoticz (plugin available) & OpenHAB
|
||||
- reliable OTGW PIC upgrades (v0.6.0+), to the latest firmware available at http://otgw.tclcode.com/download.html
|
||||
- cleaner RestAPI's for Telegraf OTmonitor integration
|
||||
- readout Dallas-type temperture sensors (eg. DS18B20) connected to GPIO
|
||||
- readout Dallas-type temperture sensors (eg. DS18B20) connected to GPIO, added automatic Home Assistant Discovery
|
||||
- readout S0 output counter and timing from kWh meter connected to configurable GPIO
|
||||
- Enhance Home Assistant discovery for Dallas sensors and S0 output counter
|
||||
|
||||
**Warning: Never flash your OTGW PIC firmware through wifi using OTmonitor application, you can brick your OTGW PIC. Instead use the buildin PIC firmware upgrade feature (based on code by Schelte Bron)**
|
||||
|
||||
@ -58,6 +60,7 @@ Looking for the documentation, go here (work in progress): <br> https://github.
|
||||
|
||||
| Version | Release notes |
|
||||
|-|-|
|
||||
| 0.10.0 | Readout S0 output from configurable GPIO, interupt rtn added for this, enhanced Dallas-type sensor logic (autoconfigure, code cleanup)|
|
||||
| 0.9.6 | Bugfix: bitwise not bytewise AND operation for ASF flags OEM codes |
|
||||
| 0.9.5 | Improved: WebUI improved by community<br>Bugfix: Device Online status indicator for Home Assistant<br>Improved: Update of 5.x series (pic16f88) firmwares, preparing for 6.x (pic16f1847) updates.<br>Bugfix: Prevent spamming OTGW firmware website in case of rebootloop<br>Added: Unique useragent|
|
||||
| 0.9.4 | Update: New firmware included gateway version 5.3 for PIC P16F88.<br>Update: Preventing >5.x PIC firmwares to be detected, incompatible (for now)|
|
||||
|
BIN
data/.DS_Store
vendored
Normal file
BIN
data/.DS_Store
vendored
Normal file
Binary file not shown.
@ -778,6 +778,15 @@
|
||||
,[ "gpiosensorsenabled", "GPIO Sensors Enabled"]
|
||||
,[ "gpiosensorsinterval", "GPIO Publish Interval (sec)"]
|
||||
,[ "gpiosensorspin", "GPIO pin # (SD3 = GPIO10 => 10)"]
|
||||
,[ "numberofsensors", "Number of temperature sensors"]
|
||||
,[ "s0counterenabled", "S0 Counter Enabled"]
|
||||
,[ "s0counterinterval", "S0 Counter Interval (sec)"]
|
||||
,[ "s0counterpin", "S0 Counter pin # (D6 = GPIO12 => 12)"]
|
||||
,[ "s0counterdebouncetime", "S0 Counter debouncetime (mS)"]
|
||||
,[ "s0counterpulsekw", "S0 pulses per kW"]
|
||||
,[ "s0powerkw", "S0 actual power (kW)"]
|
||||
,[ "s0intervalcount", "S0 interval pulses"]
|
||||
,[ "s0totalcount", "S0 total pulses"]
|
||||
,[ "mqttotmessage", "MQTT OT msg Enable"]
|
||||
,[ "otgwcommandenable", "OTGW Boot Command Enabled"]
|
||||
,[ "otgwcommands", "OTGW Boot Command"]
|
||||
|
@ -152,3 +152,10 @@
|
||||
36 ; %homeassistant%/sensor/%node_id%/ElectricalCurrentBurnerFlame/config ; {"avty_t": "%mqtt_pub_topic%", "dev": {"identifiers": "%node_id%", "manufacturer": "Schelte Bron", "model": "otgw-nodo", "name": "OpenTherm Gateway (%hostname%)", "sw_version": "%version%"}, "uniq_id": "%node_id%-ElectricalCurrentBurnerFlame", "name": "%hostname%_ElectricalCurrentBurnerFlame", "stat_t": "%mqtt_pub_topic%/ElectricalCurrentBurnerFlame", "unit_of_measurement": "uA", "value_template": "{{ value }}" }
|
||||
// split
|
||||
115 ; %homeassistant%/sensor/%node_id%/OEMDiagnosticCode/config ; {"avty_t": "%mqtt_pub_topic%", "dev": {"identifiers": "%node_id%", "manufacturer": "Schelte Bron", "model": "otgw-nodo", "name": "OpenTherm Gateway (%hostname%)", "sw_version": "%version%"}, "uniq_id": "%node_id%-OEMDiagnosticCode", "name": "%hostname%_OEMDiagnosticCode", "stat_t": "%mqtt_pub_topic%/OEMDiagnosticCode", "unit_of_measurement": "", "value_template": "{{ value }}" }
|
||||
// S0 counter special purpose foney dataid
|
||||
245 ; %homeassistant%/sensor/%node_id%/s0pulsecount/config ; {"avty_t": "%mqtt_pub_topic%", "dev": {"identifiers": "%node_id%", "manufacturer": "Schelte Bron", "model": "otgw-nodo", "name": "OpenTherm Gateway (%hostname%)", "sw_version": "%version%"}, "uniq_id": "%node_id%-s0pulsecount", "name": "%hostname%_S0_Pulse_Count", "stat_t": "%mqtt_pub_topic%/s0pulsecount", "unit_of_measurement": "", "value_template": "{{ value }}" }
|
||||
245 ; %homeassistant%/sensor/%node_id%/s0pulsecounttot/config ; {"avty_t": "%mqtt_pub_topic%", "dev": {"identifiers": "%node_id%", "manufacturer": "Schelte Bron", "model": "otgw-nodo", "name": "OpenTherm Gateway (%hostname%)", "sw_version": "%version%"}, "uniq_id": "%node_id%-s0pulsecounttot", "name": "%hostname%_S0_Pulse_Count_Total", "stat_t": "%mqtt_pub_topic%/s0pulsecounttot", "unit_of_measurement": "", "value_template": "{{ value }}" }
|
||||
245 ; %homeassistant%/sensor/%node_id%/s0pulsetime/config ; {"avty_t": "%mqtt_pub_topic%", "dev": {"identifiers": "%node_id%", "manufacturer": "Schelte Bron", "model": "otgw-nodo", "name": "OpenTherm Gateway (%hostname%)", "sw_version": "%version%"}, "uniq_id": "%node_id%-s0pulsetime", "name": "%hostname%_S0_Pulse_Time", "stat_t": "%mqtt_pub_topic%/s0pulsetime", "unit_of_measurement": "mS", "value_template": "{{ value }}" }
|
||||
245 ; %homeassistant%/sensor/%node_id%/s0powerkw/config ; {"avty_t": "%mqtt_pub_topic%", "dev": {"identifiers": "%node_id%", "manufacturer": "Schelte Bron", "model": "otgw-nodo", "name": "OpenTherm Gateway (%hostname%)", "sw_version": "%version%"}, "uniq_id": "%node_id%-s0powerkw", "name": "%hostname%_S0_Power_kw", "stat_t": "%mqtt_pub_topic%/s0powerkw", "device_class": "power","state_class": "measurement","unit_of_measurement": "kW", "value_template": "{{ value }}" }
|
||||
// Dallas temperature sensor special purpose foney dataid
|
||||
246 ; %homeassistant%/sensor/%node_id%/%sensor_id%/config ; {"avty_t": "%mqtt_pub_topic%", "dev": {"identifiers": "%node_id%", "manufacturer": "Schelte Bron", "model": "otgw-nodo", "name": "OpenTherm Gateway (%hostname%)", "sw_version": "%version%"}, "uniq_id": "%node_id%-%sensor_id%", "name": "%hostname%_%sensor_id%", "stat_t": "%mqtt_pub_topic%/%sensor_id%", "state_class" : "measurement", "unit_of_measurement": "°C", "value_template": "{{ value }}" }
|
||||
|
@ -7,9 +7,10 @@ void handleDebug(){
|
||||
case 'h':
|
||||
Debugln();
|
||||
Debugln(F("---===[ Debug Help Menu ]===---"));
|
||||
Debugln(F("1) Toggle verbose debug logging - OT message parsing"));
|
||||
Debugln(F("2) Toggle verbose debug logging - API handeling"));
|
||||
Debugln(F("3) Toggle verbose debug logging - MQTT module"));
|
||||
Debugf(PSTR("1) Toggle debuglog - OT message parsing: %s\r\n"), CBOOLEAN(bDebugOTmsg));
|
||||
Debugf(PSTR("2) Toggle debuglog - API handeling: %s\r\n"), CBOOLEAN(bDebugRestAPI));
|
||||
Debugf(PSTR("3) Toggle debuglog - MQTT module: %s\r\n"), CBOOLEAN(bDebugMQTT));
|
||||
Debugf(PSTR("4) Toggle debuglog - Sensor modules: %s\r\n"), CBOOLEAN(bDebugSensors));
|
||||
Debugln(F("q) Force read settings"));
|
||||
Debugln(F("m) Force MQTT discovery"));
|
||||
Debugln(F("r) Reconnect wifi, telnet, otgwstream and mqtt"));
|
||||
@ -68,6 +69,10 @@ void handleDebug(){
|
||||
bDebugMQTT = !bDebugMQTT;
|
||||
DebugTf(PSTR("\r\nDebug MQTT: %s\r\n"), CBOOLEAN(bDebugMQTT));
|
||||
break;
|
||||
case '4':
|
||||
bDebugSensors = !bDebugSensors;
|
||||
DebugTf(PSTR("\r\nDebug Sensors: %s\r\n"), CBOOLEAN(bDebugSensors));
|
||||
break;
|
||||
case 'b':
|
||||
DebugTln(F("Blink led 1"));
|
||||
blinkLED(LED1, 5, 500);
|
||||
|
@ -200,6 +200,7 @@ bool updateRebootLog(String text)
|
||||
uint32_t errorCode = -1;
|
||||
|
||||
//waitforNTPsync();
|
||||
loopNTP(); // make sure time is up to date (improved error logging)
|
||||
|
||||
struct rst_info *rtc_info = system_get_rst_info();
|
||||
|
||||
|
23
restAPI.ino
23
restAPI.ino
@ -255,6 +255,7 @@ void sendTelegraf()
|
||||
|
||||
void sendOTmonitor()
|
||||
{
|
||||
time_t now = time(nullptr); // needed for Dallas sensor display
|
||||
RESTDebugTln(F("sending OT monitor values ...\r"));
|
||||
|
||||
sendStartJsonObj("otmonitor");
|
||||
@ -300,7 +301,22 @@ void sendOTmonitor()
|
||||
sendJsonOTmonObj("chwaterpressure", OTcurrentSystemState.CHPressure, "bar", msglastupdated[OT_CHPressure]);
|
||||
sendJsonOTmonObj("oemdiagnosticcode", OTcurrentSystemState.OEMDiagnosticCode, "", msglastupdated[OT_OEMDiagnosticCode]);
|
||||
sendJsonOTmonObj("oemfaultcode", OTcurrentSystemState.ASFflags & 0xFF, "", msglastupdated[OT_ASFflags]);
|
||||
|
||||
|
||||
if (settingS0COUNTERenabled)
|
||||
{
|
||||
sendJsonOTmonObj("s0powerkw", formatFloat(OTGWs0powerkw,3) , "kW", OTGWs0lasttime);
|
||||
sendJsonOTmonObj("s0intervalcount", OTGWs0pulseCount , "", OTGWs0lasttime);
|
||||
sendJsonOTmonObj("s0totalcount", OTGWs0pulseCountTot , "", OTGWs0lasttime);
|
||||
}
|
||||
if (settingGPIOSENSORSenabled)
|
||||
{
|
||||
sendJsonOTmonObj("numberofsensors", DallasrealDeviceCount , "", int(now));
|
||||
for (int i = 0; i < DallasrealDeviceCount; i++) {
|
||||
const char * strDeviceAddress = getDallasAddress(DallasrealDevice[i].addr);
|
||||
sendJsonOTmonObj(strDeviceAddress, formatFloat(DallasrealDevice[i].tempC,1) , "°C", DallasrealDevice[i].lasttime);
|
||||
}
|
||||
}
|
||||
|
||||
sendEndJsonObj("otmonitor");
|
||||
|
||||
} // sendOTmonitor()
|
||||
@ -424,6 +440,11 @@ void sendDeviceSettings()
|
||||
sendJsonSettingObj("gpiosensorsenabled", settingGPIOSENSORSenabled, "b");
|
||||
sendJsonSettingObj("gpiosensorspin", settingGPIOSENSORSpin, "i", 0, 16);
|
||||
sendJsonSettingObj("gpiosensorsinterval", settingGPIOSENSORSinterval, "i", 5, 65535);
|
||||
sendJsonSettingObj("s0counterenabled", settingS0COUNTERenabled, "b");
|
||||
sendJsonSettingObj("s0counterpin", settingS0COUNTERpin, "i", 1, 16);
|
||||
sendJsonSettingObj("s0counterdebouncetime", settingS0COUNTERdebouncetime, "i", 0, 1000);
|
||||
sendJsonSettingObj("s0counterpulsekw", settingS0COUNTERpulsekw, "i", 1, 5000);
|
||||
sendJsonSettingObj("s0counterinterval", settingS0COUNTERinterval, "i", 5, 65535);
|
||||
sendJsonSettingObj("gpiooutputsenabled", settingGPIOOUTPUTSenabled, "b");
|
||||
sendJsonSettingObj("gpiooutputspin", settingGPIOOUTPUTSpin, "i", 0, 16);
|
||||
sendJsonSettingObj("gpiooutputstriggerbit", settingGPIOOUTPUTStriggerBit, "i", 0,16);
|
||||
|
127
s0PulseCount.ino
Normal file
127
s0PulseCount.ino
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
***************************************************************************
|
||||
** Program : s0PulseCount
|
||||
** Version : v0.10.0
|
||||
**
|
||||
** Copyright (c) 2021-2023 Rob Roos / Robert van Breemen
|
||||
** based on Framework ESP8266 from Willem Aandewiel
|
||||
**
|
||||
** TERMS OF USE: MIT License. See bottom of file.
|
||||
***************************************************************************
|
||||
Functionality to measure number of pulses from a S0 output, eg from an energy consumption meter.
|
||||
The S0 port is to be connected in a NO mode, with pulse closing contact pulling a configurable pin to Low.
|
||||
MQ interface is enabled with Home Assistant AutoConfigure, for this the OTGW function is reused by using a foney dataid (245)
|
||||
// S0 Counter Settings and variables with global scope, to be defined in xx.h
|
||||
bool settingS0COUNTERenabled = false;
|
||||
uint8_t settingS0COUNTERpin = 12; // GPIO 12 = D6, preferred, can be any pin with Interupt support
|
||||
uint16_t settingS0COUNTERdebouncetime = 80; // Depending on S0 switch a debouncetime should be tailored
|
||||
uint16_t settingS0COUNTERpulsekw = 1000; // Most S0 counters have 1000 pulses per kW, but this can be different
|
||||
uint16_t settingS0COUNTERinterval = 60; // Sugggested measurement reporting interval
|
||||
uint16_t OTGWs0pulseCount; // Number of S0 pulses in measurement interval
|
||||
uint32_t OTGWs0pulseCountTot = 0; // Number of S0 pulses since start of measurement
|
||||
float OTGWs0powerkw = 0 ; // Calculated kW actual consumption based on time between last pulses and settings
|
||||
time_t OTGWs0lasttime = 0; // Last time S0 counters have been read
|
||||
byte OTGWs0dataid = 245; // Foney dataid to be used to do autoconfigure, align value with mqttha.cfg contents
|
||||
*/
|
||||
#include <Arduino.h>
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
volatile uint8_t pulseCount = 0; // Number of pulses, used to measure energy.
|
||||
volatile uint32_t last_pulse_duration = 0; // Duration of the time between last pulses
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
void IRAM_ATTR IRQcounter() {
|
||||
static uint32_t last_interrupt_time = 0;
|
||||
volatile uint32_t interrupt_time;
|
||||
|
||||
interrupt_time = millis() ;
|
||||
// If interrupts come faster than debouncetime, assume it's a bounce and ignore
|
||||
if (interrupt_time - last_interrupt_time > settingS0COUNTERdebouncetime)
|
||||
{
|
||||
pulseCount++;
|
||||
last_pulse_duration = interrupt_time - last_interrupt_time ;
|
||||
}
|
||||
last_interrupt_time = interrupt_time;
|
||||
}
|
||||
|
||||
|
||||
void initS0Count()
|
||||
{
|
||||
if (!settingS0COUNTERenabled) return;
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
pinMode(settingS0COUNTERpin, INPUT_PULLUP); // Set interrupt pulse counting pin as input (Dig 3 / INT1)
|
||||
OTGWs0pulseCount=0; // Make sure pulse count starts at zero
|
||||
attachInterrupt(digitalPinToInterrupt(settingS0COUNTERpin), IRQcounter, FALLING) ;
|
||||
if (bDebugSensors) DebugTf(PSTR("*** S0PulseCounter initialized on GPIO[%d] )\r\n"), settingS0COUNTERpin) ;
|
||||
} //end SETUP
|
||||
|
||||
void sendS0Counters()
|
||||
{
|
||||
time_t now = time(nullptr);
|
||||
if (!settingS0COUNTERenabled) return;
|
||||
|
||||
if (pulseCount != 0 ) {
|
||||
noInterrupts();
|
||||
OTGWs0pulseCount = pulseCount;
|
||||
OTGWs0pulseCountTot = OTGWs0pulseCountTot + pulseCount;
|
||||
pulseCount=0;
|
||||
interrupts();
|
||||
|
||||
OTGWs0powerkw = (float) 3600000 / (float)settingS0COUNTERpulsekw / (float)last_pulse_duration ;
|
||||
if (bDebugSensors) DebugTf(PSTR("*** S0PulseCount(%d) S0PulseCountTot(%d)\r\n"), OTGWs0pulseCount, OTGWs0pulseCountTot) ;
|
||||
if (bDebugSensors) DebugTf(PSTR("*** S0LastPulsetime(%d) S0Pulsekw:(%4.3f) \r\n"), last_pulse_duration, OTGWs0powerkw) ;
|
||||
OTGWs0lasttime = int(now) ;
|
||||
if (settingMQTTenable ) {
|
||||
sensorAutoConfigure(OTGWs0dataid, true , "" ) ; // Configure S0 sensor with the
|
||||
s0sendMQ() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void s0sendMQ()
|
||||
{
|
||||
//Build string for MQTT
|
||||
char _msg[15]{0};
|
||||
char _topic[50]{0};
|
||||
snprintf(_topic, sizeof _topic, "s0pulsecount");
|
||||
snprintf(_msg, sizeof _msg, "%d", OTGWs0pulseCount);
|
||||
sendMQTTData(_topic, _msg);
|
||||
|
||||
snprintf(_topic, sizeof _topic, "s0pulsecounttot");
|
||||
snprintf(_msg, sizeof _msg, "%d", OTGWs0pulseCountTot);
|
||||
sendMQTTData(_topic, _msg);
|
||||
|
||||
snprintf(_topic, sizeof _topic, "s0pulsetime");
|
||||
snprintf(_msg, sizeof _msg, "%d", last_pulse_duration);
|
||||
sendMQTTData(_topic, _msg);
|
||||
|
||||
snprintf(_topic, sizeof _topic, "s0powerkw");
|
||||
snprintf(_msg, sizeof _msg, "%4.3f", OTGWs0powerkw);
|
||||
sendMQTTData(_topic, _msg);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
* persons to whom the Software is furnished to do so, subject to the
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
|
||||
* OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
|
||||
* THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
****************************************************************************
|
||||
*/
|
139
sensors_ext.ino
139
sensors_ext.ino
@ -1,32 +1,42 @@
|
||||
/*
|
||||
** Program : output_ext.ino
|
||||
** Version : v0.9.5
|
||||
** Version : v0.10.0
|
||||
**
|
||||
** Copyright (c) 2021-2023 Robert van den Breemen
|
||||
** Contributed by Sjorsjuhmaniac
|
||||
** Modified by Rob Roos to enable MQ autoconfigure and cleanup
|
||||
**
|
||||
** TERMS OF USE: MIT License. See bottom of file.
|
||||
**
|
||||
** most code shamelessly copied from Miles Burton's - Arduino Dallas library
|
||||
** example 'Multiple'
|
||||
*/
|
||||
|
||||
#include <OneWire.h>
|
||||
#include <DallasTemperature.h>
|
||||
|
||||
//prototype
|
||||
char* getDallasAddress(DeviceAddress deviceAddress);
|
||||
|
||||
// GPIO where the DS18B20 is connected to
|
||||
// Data wire is plugged TO GPIO 10
|
||||
// #define ONE_WIRE_BUS 10
|
||||
// To be included in OTGW-firmware.h
|
||||
// #include <OneWire.h>
|
||||
// #include <DallasTemperature.h>
|
||||
// GPIO Sensor Settings
|
||||
// bool settingGPIOSENSORSenabled = false;
|
||||
// int8_t settingGPIOSENSORSpin = 10;
|
||||
// int16_t settingGPIOSENSORSinterval = 20; // Interval time to read out temp and send to MQ
|
||||
// byte OTGWdallasdataid = 246; // foney dataid to be used to do autoconfigure for temp sensors
|
||||
// int DallasrealDeviceCount = 0; // Total temperature devices found on the bus
|
||||
// #define MAXDALLASDEVICES 16 // maximum number of devices on the bus
|
||||
//
|
||||
// // Define structure to store temperature device addresses found on bus with their latest tempC value
|
||||
// struct
|
||||
// {
|
||||
// int id;
|
||||
// DeviceAddress addr;
|
||||
// float tempC;
|
||||
// time_t lasttime;
|
||||
// } DallasrealDevice[MAXDALLASDEVICES];
|
||||
//
|
||||
// prototype to allow use in restAPI.ino
|
||||
// char* getDallasAddress(DeviceAddress deviceAddress);
|
||||
|
||||
// Number of temperature devices found
|
||||
int numberOfDevices;
|
||||
|
||||
// We'll use this variable to store a found device address
|
||||
DeviceAddress tempDeviceAddress;
|
||||
|
||||
// Setup a oneWire instance to communicate with any OneWire devices
|
||||
// needs a PIN to init correctly, pin is changed when we initSensors()
|
||||
// this still may cause problems though because we this configures the pin already
|
||||
@ -38,11 +48,11 @@ OneWire oneWire(settingGPIOSENSORSpin);
|
||||
// Pass our oneWire reference to Dallas Temperature sensor
|
||||
DallasTemperature sensors(&oneWire);
|
||||
|
||||
|
||||
// Initialise the oneWire bus on the GPIO pin
|
||||
void initSensors() {
|
||||
if (!settingGPIOSENSORSenabled) return;
|
||||
|
||||
DebugTf(PSTR("init GPIO Sensors on GPIO%d...\r\n"), settingGPIOSENSORSpin);
|
||||
if (bDebugSensors)DebugTf(PSTR("init GPIO Temperature sensors on GPIO%d...\r\n"), settingGPIOSENSORSpin);
|
||||
|
||||
oneWire.begin(settingGPIOSENSORSpin);
|
||||
|
||||
@ -52,81 +62,92 @@ void initSensors() {
|
||||
// Grab a count of devices on the wire
|
||||
numberOfDevices = sensors.getDeviceCount();
|
||||
|
||||
DebugTf(PSTR("Found %d device(s)\r\n"), numberOfDevices);
|
||||
int realDeviceCount = 0;
|
||||
// Loop through each device, print out address
|
||||
DallasrealDeviceCount = 0; // To determine the total found real temp sensors
|
||||
|
||||
if (numberOfDevices > MAXDALLASDEVICES)
|
||||
{
|
||||
DebugTf(PSTR("***ERR More (%d) sensor devices found than allowed(%d) on the bus\r\n"), numberOfDevices, MAXDALLASDEVICES);
|
||||
numberOfDevices = MAXDALLASDEVICES ; // limit to max number of devices
|
||||
}
|
||||
if (bDebugSensors) DebugTf(PSTR("Sensors: Found %d device(s)\r\n"), numberOfDevices);
|
||||
// Loop through each device, check if it is real temp sensor
|
||||
|
||||
for (int i = 0; i < numberOfDevices; i++)
|
||||
{
|
||||
// Search the wire for address
|
||||
if (sensors.getAddress(tempDeviceAddress, i))
|
||||
if (sensors.getAddress(DallasrealDevice[i].addr, i))
|
||||
{
|
||||
//TODO: get real device address, push data to mqtt topic.
|
||||
DebugTf(PSTR("Device address %u device(s)\r\n"), (unsigned int) tempDeviceAddress);
|
||||
DebugFlush();
|
||||
realDeviceCount++;
|
||||
if (bDebugSensors) DebugTf(PSTR("Device address %u device(s)\r\n"), (unsigned int) DallasrealDevice[i].addr);
|
||||
DallasrealDevice[i].id = DallasrealDeviceCount ;
|
||||
DallasrealDevice[i].tempC = 0 ;
|
||||
DallasrealDevice[i].lasttime = 0 ;
|
||||
DallasrealDeviceCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugTf(PSTR("Found ghost device %d but could not detect address. Check power and cabling\r\n"), i);
|
||||
DebugTf(PSTR("***ERR Found ghost device %d but could not detect address. Check power and cabling\r\n"), i);
|
||||
}
|
||||
}
|
||||
|
||||
if (numberOfDevices < 1 or realDeviceCount < 1)
|
||||
if (numberOfDevices < 1 or DallasrealDeviceCount < 1)
|
||||
{
|
||||
DebugTln("No Sensors Found, disabled GPIO Sensors! Reboot node to search again.");
|
||||
DebugTln(PSTR("***ERR No Sensors Found, disabled GPIO Sensors! Reboot node to search again."));
|
||||
settingGPIOSENSORSenabled = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int pollSensors()
|
||||
// Send the sensor device address to MQ for Autoconfigure
|
||||
void configSensors()
|
||||
{
|
||||
if (!settingGPIOSENSORSenabled) return 1;
|
||||
// Setup a oneWire instance to communicate with any OneWire devices
|
||||
// oneWire.begin(settingGPIOSENSORSpin);
|
||||
if (settingMQTTenable) {
|
||||
if (bDebugSensors) DebugTf(PSTR("Sensor Device MQ configuration started \r\n"));
|
||||
|
||||
// Pass our oneWire reference to Dallas Temperature sensor
|
||||
DallasTemperature sensors(&oneWire);
|
||||
|
||||
if (numberOfDevices < 1)
|
||||
{
|
||||
DebugTln("No Sensors Found, please reboot the node to search for sensors");
|
||||
return 1;
|
||||
for (int i = 0; i < DallasrealDeviceCount ; i++)
|
||||
{
|
||||
// Now configure the MQ interface, it will return immediatly when already configured
|
||||
const char * strDeviceAddress = getDallasAddress(DallasrealDevice[i].addr);
|
||||
if (bDebugSensors) DebugTf(PSTR("Sensor Device MQ configuration for device no[%d] addr[%s] \r\n"), i, strDeviceAddress);
|
||||
sensorAutoConfigure(OTGWdallasdataid, false, strDeviceAddress) ; // Configure sensor with the Dallas Deviceaddress
|
||||
}
|
||||
// after last sensor set the ConfigDone flag
|
||||
setMQTTConfigDone(OTGWdallasdataid);
|
||||
}
|
||||
// DebugTln("start polling sensors");
|
||||
} // configSensors()
|
||||
|
||||
void pollSensors()
|
||||
{
|
||||
time_t now = time(nullptr);
|
||||
if (!settingGPIOSENSORSenabled) return;
|
||||
sensors.requestTemperatures(); // Send the command to get temperatures
|
||||
|
||||
// Loop through each device, print out temperature data
|
||||
for (int i = 0; i < numberOfDevices; i++)
|
||||
// check if HA Autoconfigure must be performed (initial or as repeat for HA reboot)
|
||||
if (settingMQTTenable && getMQTTConfigDone(OTGWdallasdataid)==false) configSensors() ;
|
||||
// Loop through each real device, store temperature data and send to MQ
|
||||
for (int i = 0; i < DallasrealDeviceCount; i++)
|
||||
{
|
||||
// Search the wire for address
|
||||
if (sensors.getAddress(tempDeviceAddress, i))
|
||||
{
|
||||
// Output the device ID
|
||||
// Print the data
|
||||
|
||||
const char * strDeviceAddress = getDallasAddress(tempDeviceAddress);
|
||||
|
||||
float tempC = sensors.getTempC(tempDeviceAddress);
|
||||
DebugTf(PSTR("Device: %s, TempC: %f\r\n"), strDeviceAddress, tempC);
|
||||
|
||||
//Build string for MQTT
|
||||
// Convert device address to string
|
||||
const char * strDeviceAddress = getDallasAddress(DallasrealDevice[i].addr);
|
||||
// Store the C temp in struc to allow it to be shown on Homepage through restAPI.ino
|
||||
DallasrealDevice[i].tempC = sensors.getTempC(DallasrealDevice[i].addr);
|
||||
DallasrealDevice[i].lasttime = int(now) ;
|
||||
if (settingMQTTenable ) {
|
||||
//Build string for MQTT, rse sendMQTTData for this
|
||||
// ref MQTTPubNamespace = settingMQTTtopTopic + "/value/" + strDeviceAddress ;
|
||||
char _msg[15]{0};
|
||||
char _topic[50]{0};
|
||||
snprintf(_topic, sizeof _topic, "otgw-firmware/sensors/%s", strDeviceAddress);
|
||||
snprintf(_msg, sizeof _msg, "%f", tempC);
|
||||
snprintf(_topic, sizeof _topic, "%s", strDeviceAddress);
|
||||
snprintf(_msg, sizeof _msg, "%4.1f", DallasrealDevice[i].tempC);
|
||||
|
||||
// DebugTf(PSTR("Topic: %s -- Payload: %s\r\n"), _topic, _msg);
|
||||
DebugFlush();
|
||||
|
||||
if (bDebugSensors) DebugFlush();
|
||||
// sendMQTTData(_topic, _msg);
|
||||
sendMQTTData(_topic, _msg);
|
||||
// Serial.println(DallasTemperature::toFahrenheit(tempC)); // Converts tempC to Fahrenheit
|
||||
}
|
||||
}
|
||||
delay(100);
|
||||
// DebugTln("end polling sensors");
|
||||
DebugFlush();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// function to print a device address
|
||||
|
@ -47,6 +47,11 @@ void writeSettings(bool show)
|
||||
root["GPIOSENSORSenabled"] = settingGPIOSENSORSenabled;
|
||||
root["GPIOSENSORSpin"] = settingGPIOSENSORSpin;
|
||||
root["GPIOSENSORSinterval"] = settingGPIOSENSORSinterval;
|
||||
root["S0COUNTERenabled"] = settingS0COUNTERenabled;
|
||||
root["S0COUNTERpin"] = settingS0COUNTERpin;
|
||||
root["S0COUNTERdebouncetime"] = settingS0COUNTERdebouncetime;
|
||||
root["S0COUNTERpulsekw"] = settingS0COUNTERpulsekw;
|
||||
root["S0COUNTERinterval"] = settingS0COUNTERinterval;
|
||||
root["OTGWcommandenable"] = settingOTGWcommandenable;
|
||||
root["OTGWcommands"] = settingOTGWcommands;
|
||||
root["GPIOOUTPUTSenabled"] = settingGPIOOUTPUTSenabled;
|
||||
@ -117,6 +122,12 @@ void readSettings(bool show)
|
||||
settingGPIOSENSORSpin = doc["GPIOSENSORSpin"] | settingGPIOSENSORSpin;
|
||||
settingGPIOSENSORSinterval = doc["GPIOSENSORSinterval"] | settingGPIOSENSORSinterval;
|
||||
CHANGE_INTERVAL_SEC(timerpollsensor, settingGPIOSENSORSinterval, CATCH_UP_MISSED_TICKS);
|
||||
settingS0COUNTERenabled = doc["S0COUNTERenabled"] | settingS0COUNTERenabled;
|
||||
settingS0COUNTERpin = doc["S0COUNTERpin"] | settingS0COUNTERpin;
|
||||
settingS0COUNTERdebouncetime = doc["S0COUNTERdebouncetime"] | settingS0COUNTERdebouncetime;
|
||||
settingS0COUNTERpulsekw = doc["S0COUNTERpulsekw"] | settingS0COUNTERpulsekw;
|
||||
settingS0COUNTERinterval = doc["S0COUNTERinterval"] | settingS0COUNTERinterval;
|
||||
CHANGE_INTERVAL_SEC(timers0counter, settingS0COUNTERinterval, CATCH_UP_MISSED_TICKS);
|
||||
settingOTGWcommandenable = doc["OTGWcommandenable"] | settingOTGWcommandenable;
|
||||
settingOTGWcommands = doc["OTGWcommands"].as<String>();
|
||||
if (settingOTGWcommands=="null") settingOTGWcommands = "";
|
||||
@ -148,6 +159,11 @@ void readSettings(bool show)
|
||||
Debugf("GPIO Sensors : %s\r\n", CBOOLEAN(settingGPIOSENSORSenabled));
|
||||
Debugf("GPIO Sen. Pin : %d\r\n", settingGPIOSENSORSpin);
|
||||
Debugf("GPIO Interval : %d\r\n", settingGPIOSENSORSinterval);
|
||||
Debugf("S0 Counter : %s\r\n", CBOOLEAN(settingS0COUNTERenabled));
|
||||
Debugf("S0 Counter Pin : %d\r\n", settingS0COUNTERpin);
|
||||
Debugf("S0 Counter Debouncetime:%d\r\n", settingS0COUNTERdebouncetime);
|
||||
Debugf("S0 Counter Pulses/kw : %d\r\n", settingS0COUNTERpulsekw);
|
||||
Debugf("S0 Counter Interval : %d\r\n", settingS0COUNTERinterval);
|
||||
Debugf("OTGW boot cmd enabled : %s\r\n", CBOOLEAN(settingOTGWcommandenable));
|
||||
Debugf("OTGW boot cmd : %s\r\n", CSTR(settingOTGWcommands));
|
||||
Debugf("GPIO Outputs : %s\r\n", CBOOLEAN(settingGPIOOUTPUTSenabled));
|
||||
@ -234,6 +250,25 @@ void updateSetting(const char *field, const char *newValue)
|
||||
settingGPIOSENSORSinterval = atoi(newValue);
|
||||
CHANGE_INTERVAL_SEC(timerpollsensor, settingGPIOSENSORSinterval, CATCH_UP_MISSED_TICKS);
|
||||
}
|
||||
if (strcasecmp(field, "S0COUNTERenabled") == 0)
|
||||
{
|
||||
settingS0COUNTERenabled = EVALBOOLEAN(newValue);
|
||||
Debugln();
|
||||
DebugTf(PSTR("Need reboot before S0 Counter starts counting on pin GPIO%d!\r\n\n"), settingS0COUNTERpin);
|
||||
}
|
||||
if (strcasecmp(field, "S0COUNTERpin") == 0)
|
||||
{
|
||||
settingS0COUNTERpin = atoi(newValue);
|
||||
Debugln();
|
||||
DebugTf(PSTR("Need reboot before S0 Counter will use new pin GPIO%d!\r\n\n"), settingS0COUNTERpin);
|
||||
}
|
||||
if (strcasecmp(field, "S0COUNTERdebouncetime") == 0) settingS0COUNTERdebouncetime = atoi(newValue);
|
||||
if (strcasecmp(field, "S0COUNTERpulsekw") == 0) settingS0COUNTERpulsekw = atoi(newValue);
|
||||
|
||||
if (strcasecmp(field, "S0COUNTERinterval") == 0) {
|
||||
settingS0COUNTERinterval = atoi(newValue);
|
||||
CHANGE_INTERVAL_SEC(timers0counter, settingS0COUNTERinterval, CATCH_UP_MISSED_TICKS);
|
||||
}
|
||||
if (strcasecmp(field, "OTGWcommandenable")==0) settingOTGWcommandenable = EVALBOOLEAN(newValue);
|
||||
if (strcasecmp(field, "OTGWcommands")==0) settingOTGWcommands = String(newValue);
|
||||
if (strcasecmp(field, "GPIOOUTPUTSenabled") == 0)
|
||||
|
24
version.h
24
version.h
@ -1,16 +1,16 @@
|
||||
//The version number conforms to semver.org format
|
||||
#define _VERSION_MAJOR 0
|
||||
#define _VERSION_MINOR 9
|
||||
#define _VERSION_PATCH 6
|
||||
#define _VERSION_BUILD 1952
|
||||
#define _VERSION_GITHASH "e218a09"
|
||||
#define _VERSION_MINOR 10
|
||||
#define _VERSION_PATCH 0
|
||||
#define _VERSION_BUILD 1953
|
||||
#define _VERSION_GITHASH "0000000"
|
||||
#define _VERSION_PRERELEASE beta
|
||||
#define _VERSION_DATE "22-01-2023"
|
||||
#define _VERSION_TIME "23:11:17"
|
||||
#define _SEMVER_CORE "0.9.6"
|
||||
#define _SEMVER_BUILD "0.9.6+1952"
|
||||
#define _SEMVER_GITHASH "0.9.6+e218a09"
|
||||
#define _SEMVER_FULL "0.9.6-beta+e218a09"
|
||||
#define _SEMVER_NOBUILD "0.9.6-beta (22-01-2023)"
|
||||
#define _VERSION "0.9.6-beta+e218a09 (22-01-2023)"
|
||||
#define _VERSION_DATE "23/01/2023"
|
||||
#define _VERSION_TIME "19:52:17"
|
||||
#define _SEMVER_CORE "0.10.0"
|
||||
#define _SEMVER_BUILD "0.10.0+1953"
|
||||
#define _SEMVER_GITHASH "0.10.0+0000000"
|
||||
#define _SEMVER_FULL "0.10.0 beta (23/01/2023)"
|
||||
#define _SEMVER_NOBUILD "0.10.0 (23/01/2023)"
|
||||
#define _VERSION "0.10.0+1953 (23/01/2023)"
|
||||
//The version information is created automatically, more information here: https://github.com/rvdbreemen/autoinc-semver
|
||||
|
Loading…
Reference in New Issue
Block a user