mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 03:39:49 +03:00
STABILITY when re-load, Artnet, RGBWW, ETAG, Logs
This commit is contained in:
@@ -244,6 +244,7 @@ bool systemConfig::isValidSysConf()
|
||||
for (unsigned int i=0;i<sizeof(systemConfigData::signature);i++)
|
||||
if (stream->write(EEPROM_signature[i]));
|
||||
stream->close();
|
||||
setETAG("");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ volatile unsigned long D_checkT=0;
|
||||
#ifdef _artnet
|
||||
#include <Artnet.h>
|
||||
Artnet *artnet = NULL;
|
||||
uint8_t artnetMinCh=1;
|
||||
uint8_t artnetMaxCh=512;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -216,8 +218,8 @@ debugSerial.println();
|
||||
|
||||
void onDmxFrame(uint16_t universe, uint16_t length, uint8_t sequence, uint8_t* data, IPAddress remoteIP)
|
||||
{
|
||||
#ifdef _dmxout
|
||||
for (unsigned int i = 0 ; i < length && i<MAX_CHANNELS ; i++)
|
||||
#if defined (_dmxout) && defined (_artnet)
|
||||
for (unsigned int i = artnetMinCh-1 ; i < length && i<artnetMaxCh ; i++)
|
||||
{
|
||||
DmxWrite(i+1,data[i]);
|
||||
}
|
||||
@@ -256,6 +258,11 @@ dmxin.begin();
|
||||
void DMXoutSetup(int channels)
|
||||
{
|
||||
#ifdef _dmxout
|
||||
|
||||
//#ifdef _artnet
|
||||
//if (channels<artnetMaxCh) artnetMaxCh=channels;
|
||||
//#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_AVR)
|
||||
DmxSimple.usePin(AVR_DMXOUT_PIN);
|
||||
DmxSimple.maxChannel(channels);
|
||||
@@ -323,7 +330,7 @@ void DMXOUT_propagate()
|
||||
#endif
|
||||
}
|
||||
|
||||
void ArtnetSetup()
|
||||
void artnetSetup()
|
||||
{
|
||||
#ifdef _artnet
|
||||
if (!artnet) artnet = new Artnet;
|
||||
@@ -332,6 +339,13 @@ void ArtnetSetup()
|
||||
#endif
|
||||
}
|
||||
|
||||
void artnetSetChans(uint8_t minCh, uint8_t maxCh)
|
||||
{
|
||||
#ifdef _artnet
|
||||
artnetMinCh=minCh;
|
||||
artnetMaxCh=maxCh;
|
||||
#endif
|
||||
}
|
||||
|
||||
void DmxWriteBuf(uint16_t chan,uint8_t val)
|
||||
{
|
||||
|
||||
@@ -105,9 +105,9 @@ extern aJsonObject *dmxArr;
|
||||
void DMXput(void);
|
||||
void DMXinSetup(int channels);
|
||||
void DMXoutSetup(int channels);
|
||||
void ArtnetSetup();
|
||||
void artnetSetup();
|
||||
void artnetSetChans(uint8_t minCh, uint8_t maxCh);
|
||||
void DMXCheck(void);
|
||||
int itemCtrl2(char* name,int r,int g, int b, int w);
|
||||
void ArtnetSetup();
|
||||
void DmxWriteBuf(uint16_t chan,uint8_t val);
|
||||
void DMXOUT_propagate();
|
||||
|
||||
@@ -279,7 +279,7 @@ uint8_t Item::getCmd() {
|
||||
|
||||
void Item::setCmd(uint8_t cmdValue) {
|
||||
aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD);
|
||||
if (itemCmd)
|
||||
if (itemCmd && (itemCmd->type == aJson_Int || itemCmd->type == aJson_NULL))
|
||||
{
|
||||
itemCmd->type = aJson_Int;
|
||||
itemCmd->valueint = cmdValue & CMD_MASK | itemCmd->valueint & FLAG_MASK; // Preserve special bits
|
||||
@@ -290,7 +290,7 @@ void Item::setCmd(uint8_t cmdValue) {
|
||||
short Item::getFlag (short flag)
|
||||
{
|
||||
aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD);
|
||||
if (itemCmd)
|
||||
if (itemCmd && (itemCmd->type == aJson_Int))
|
||||
{
|
||||
return itemCmd->valueint & flag & FLAG_MASK;
|
||||
}
|
||||
@@ -300,7 +300,7 @@ return 0;
|
||||
void Item::setFlag (short flag)
|
||||
{
|
||||
aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD);
|
||||
if (itemCmd)
|
||||
if (itemCmd && (itemCmd->type == aJson_Int || itemCmd->type == aJson_NULL))
|
||||
{
|
||||
itemCmd->type = aJson_Int;
|
||||
itemCmd->valueint |= flag & FLAG_MASK; // Preserve CMD bits
|
||||
@@ -312,7 +312,7 @@ void Item::setFlag (short flag)
|
||||
void Item::clearFlag (short flag)
|
||||
{
|
||||
aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD);
|
||||
if (itemCmd)
|
||||
if (itemCmd && (itemCmd->type == aJson_Int || itemCmd->type == aJson_NULL))
|
||||
{
|
||||
itemCmd->valueint &= CMD_MASK | ~(flag & FLAG_MASK); // Preserve CMD bits
|
||||
// debugSerial<<F("ClrFlag:")<<flag<<endl;
|
||||
@@ -705,7 +705,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
aJsonObject *timestampObj = aJson.getArrayItem(itemArr, I_TIMESTAMP);
|
||||
if (timestampObj && cmd.getCmd()<=0xf)
|
||||
{
|
||||
if (cmd.getInt()>0)
|
||||
if ((cmd.getInt()>0) && (timestampObj->type == aJson_Int || timestampObj->type == aJson_NULL))
|
||||
{
|
||||
timestampObj->valueint = millis()+cmd.getInt();
|
||||
timestampObj->type = aJson_Int;
|
||||
|
||||
@@ -92,6 +92,7 @@ uint8_t itemCmd::getStoragetypeByChanType(short chanType)
|
||||
{
|
||||
case CH_RGB:
|
||||
case CH_RGBW:
|
||||
case CH_RGBWW:
|
||||
case CH_SPILED:
|
||||
return ST_HSV255;
|
||||
break;
|
||||
|
||||
@@ -189,7 +189,7 @@ aJsonObject * item = items->child;
|
||||
}
|
||||
pollingItem = NULL;
|
||||
debugSerial<<F("Stopped")<<endl;
|
||||
|
||||
delay(100);
|
||||
#ifdef SYSLOG_ENABLE
|
||||
syslogInitialized=false; //Garbage in memory
|
||||
#endif
|
||||
@@ -201,6 +201,8 @@ debugSerial<<F("Deleting conf. RAM was:")<<freeRam();
|
||||
items = NULL;
|
||||
topics = NULL;
|
||||
mqttArr = NULL;
|
||||
deviceName = NULL;
|
||||
topics = NULL;
|
||||
#ifdef _dmxout
|
||||
dmxArr = NULL;
|
||||
#endif
|
||||
@@ -647,6 +649,7 @@ lan_status lanLoop() {
|
||||
break;
|
||||
|
||||
case READ_RE_CONFIG: // Restore config from FLASH, re-init LAN
|
||||
debugSerial<<F("Restoring config from EEPROM")<<endl;
|
||||
if (loadConfigFromEEPROM()) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;//2;
|
||||
else {
|
||||
//timerLanCheckTime = millis();// + 5000;
|
||||
@@ -833,6 +836,7 @@ void ip_ready_config_loaded_connecting_to_broker() {
|
||||
|
||||
if (!mqttArr || ((n = aJson.getArraySize(mqttArr)) < 2)) //At least device name and broker IP must be configured
|
||||
{
|
||||
errorSerial<<F("At least device name and broker IP must be configured")<<endl;
|
||||
lanStatus = READ_RE_CONFIG;
|
||||
return;
|
||||
}
|
||||
@@ -1158,9 +1162,9 @@ return 500;
|
||||
}
|
||||
|
||||
void applyConfig() {
|
||||
if (!root) return;
|
||||
if (!root || configLocked) return;
|
||||
configLocked++;
|
||||
|
||||
infoSerial<<F("Applying config")<<endl;
|
||||
items = aJson.getObjectItem(root, "items");
|
||||
topics = aJson.getObjectItem(root, "topics");
|
||||
inputs = aJson.getObjectItem(root, "in");
|
||||
@@ -1183,9 +1187,33 @@ setupSyslog();
|
||||
short numParams;
|
||||
aJsonObject *dmxoutArr = aJson.getObjectItem(root, "dmx");
|
||||
if (dmxoutArr && (numParams=aJson.getArraySize(dmxoutArr)) >=1 ) {
|
||||
DMXoutSetup(maxChannels = aJson.getArrayItem(dmxoutArr, numParams-1)->valueint);
|
||||
maxChannels = aJson.getArrayItem(dmxoutArr, numParams-1)->valueint;
|
||||
|
||||
#ifdef _artnet
|
||||
aJsonObject *artnetArr = aJson.getObjectItem(root, "artnet");
|
||||
if (artnetArr)
|
||||
{
|
||||
uint8_t artnetMinCh = 1;
|
||||
uint8_t artnetMaxCh = maxChannels;
|
||||
short artnetNumParams;
|
||||
|
||||
if (artnetNumParams=aJson.getArraySize(artnetArr)>=2)
|
||||
{
|
||||
artnetMinCh = aJson.getArrayItem(artnetArr, 0)->valueint;
|
||||
if (artnetMinCh<1) artnetMinCh = 1;
|
||||
artnetMaxCh = aJson.getArrayItem(artnetArr, 1)->valueint;
|
||||
if (artnetMaxCh>maxChannels) artnetMaxCh=maxChannels;
|
||||
}
|
||||
infoSerial<<F("Artnet start. Channels:")<<artnetMinCh<<F("-")<<artnetMaxCh<<endl;
|
||||
artnetSetChans(artnetMinCh,artnetMaxCh);
|
||||
//artnetInitialized=true;
|
||||
}
|
||||
#endif
|
||||
DMXoutSetup(maxChannels);
|
||||
infoSerial<<F("DMX out started. Channels: ")<<maxChannels<<endl;
|
||||
debugSerial<<F("Free:")<<freeRam()<<endl;
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
#ifdef _modbus
|
||||
@@ -1259,8 +1287,8 @@ setupSyslog();
|
||||
printConfigSummary();
|
||||
configLoaded=true;
|
||||
if (sysConf.getSaveSuccedConfig()) cmdFunctionSave(0,NULL);
|
||||
configLocked--;
|
||||
ethClient.stop(); //Refresh MQTT connection
|
||||
configLocked--;
|
||||
}
|
||||
|
||||
void printConfigSummary() {
|
||||
@@ -1300,7 +1328,7 @@ int cmdFunctionLoad(int arg_cnt, char **args) {
|
||||
|
||||
int loadConfigFromEEPROM()
|
||||
{
|
||||
char ch;
|
||||
if (configLocked) return 0;
|
||||
infoSerial<<F("Loading Config from EEPROM")<<endl;
|
||||
#if defined(FS_STORAGE)
|
||||
sysConfStream.open("/config.json",'r');
|
||||
@@ -1319,7 +1347,7 @@ int loadConfigFromEEPROM()
|
||||
// sysConfStream.close();
|
||||
return 0;
|
||||
}
|
||||
infoSerial<<F("Loaded")<<endl;
|
||||
infoSerial<<F("Loaded from EEPROM")<<endl;
|
||||
applyConfig();
|
||||
sysConf.loadETAG();
|
||||
//ethClient.stop(); //Refresh MQTT connect to get retained info
|
||||
@@ -1365,7 +1393,7 @@ if (arg_cnt>1)
|
||||
|
||||
size_t res = sysConfStream.write((byte*) outBuf,len);
|
||||
free (outBuf);
|
||||
infoSerial<<res<< F("bytes from ")<<len<<F(" are saved to EEPROM")<<endl;
|
||||
infoSerial<<res<< F(" bytes from ")<<len<<F(" are saved to EEPROM")<<endl;
|
||||
#else
|
||||
aJsonStream jsonEEPROMStream = aJsonStream(&sysConfStream);
|
||||
infoSerial<<F("Saving config to EEPROM..");
|
||||
@@ -1571,9 +1599,18 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
||||
//if (freeRam()<512) cleanConf();
|
||||
|
||||
HTTPClient hclient(configServer, 80);
|
||||
|
||||
String ETAG = sysConf.getETAG();
|
||||
|
||||
http_client_parameter get_header[] = {
|
||||
{"If-None-Match",NULL},{NULL,NULL}
|
||||
};
|
||||
get_header[0].value = ETAG.c_str();
|
||||
|
||||
|
||||
debugSerial<<F("free ")<<freeRam()<<endl;delay(100);
|
||||
// FILE is the return STREAM type of the HTTPClient
|
||||
configStream = hclient.getURI(URI);
|
||||
configStream = hclient.getURI(URI,get_header);
|
||||
debugSerial<<F("hclient")<<endl;delay(100);
|
||||
responseStatusCode = hclient.getLastReturnCode();
|
||||
debugSerial<<F("retcode ")<<responseStatusCode<<endl;delay(100);
|
||||
@@ -1598,7 +1635,6 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
infoSerial<<F("Applying.\n");
|
||||
applyConfig();
|
||||
infoSerial<<F("Done.\n");
|
||||
return true;
|
||||
@@ -1622,7 +1658,7 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
#if defined(__SAM3X8E__) || defined(ARDUINO_ARCH_STM32) || defined (NRF5) //|| defined(ARDUINO_ARCH_ESP32) //|| defined(ARDUINO_ARCH_ESP8266)
|
||||
#if defined(__SAM3X8E__) || defined(ARDUINO_ARCH_STM32) || defined (NRF5) //|| defined(ARDUINO_ARCH_AVR)//|| defined(ARDUINO_ARCH_ESP32) //|| defined(ARDUINO_ARCH_ESP8266)
|
||||
#if defined(WIFI_ENABLE)
|
||||
WiFiClient configEthClient;
|
||||
#else
|
||||
@@ -1656,8 +1692,6 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
||||
if (responseStatusCode == 200) {
|
||||
aJsonStream socketStream = aJsonStream(&htclient);
|
||||
debugSerial<<F("Free:")<<freeRam()<<endl;
|
||||
//debugSerial<<F("Response Len:")<<response.length()<<endl;
|
||||
//debugSerial<<F("GET Response: ")<<response<<endl;
|
||||
cleanConf();
|
||||
debugSerial<<F("Configuration cleaned")<<endl;
|
||||
debugSerial<<F("Free:")<<freeRam()<<endl;
|
||||
@@ -1745,7 +1779,6 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
||||
errorSerial<<F("Config parsing failed\n");
|
||||
return false;
|
||||
} else {
|
||||
infoSerial<<F("Config OK, Applying\n");
|
||||
applyConfig();
|
||||
|
||||
infoSerial<<F("Done.\n");
|
||||
@@ -1915,7 +1948,7 @@ void setup_main() {
|
||||
mqttClient.setCallback(mqttCallback);
|
||||
|
||||
#ifdef _artnet
|
||||
ArtnetSetup();
|
||||
artnetSetup();
|
||||
#endif
|
||||
|
||||
#if defined(WIFI_ENABLE) and not defined(WIFI_MANAGER_DISABLE)
|
||||
@@ -2425,21 +2458,30 @@ configLocked--;
|
||||
}
|
||||
|
||||
////// Legacy Thermostat code below - to be moved in module /////
|
||||
void thermoRelay(int pin, bool on)
|
||||
|
||||
enum heaterMode {HEAT,OFF,ERROR};
|
||||
|
||||
void thermoRelay(int pin, heaterMode on)
|
||||
{
|
||||
int thermoPin = abs(pin);
|
||||
pinMode(thermoPin, OUTPUT);
|
||||
|
||||
if (on)
|
||||
if (on == ERROR)
|
||||
{
|
||||
digitalWrite(thermoPin, LOW);
|
||||
debugSerial<<F(" BYPASS")<<endl;
|
||||
}
|
||||
|
||||
else if (on == HEAT)
|
||||
{
|
||||
digitalWrite(thermoPin, (pin<0)?LOW:HIGH);
|
||||
debugSerial<<F(" ON")<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
digitalWrite(thermoPin, (pin<0)?HIGH:LOW);
|
||||
debugSerial<<F(" OFF")<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2477,15 +2519,15 @@ void thermoLoop(void) {
|
||||
mqttClient.publish("/alarm/snsr", thermoItem->name);
|
||||
tStore.timestamp16=0; //Stop termostat
|
||||
thermostat.setExt(tStore.asint);
|
||||
thermoRelay(thermoPin,false);
|
||||
thermoRelay(thermoPin,ERROR);
|
||||
}
|
||||
else
|
||||
{ // Not expired yet
|
||||
if (curTemp > THERMO_OVERHEAT_CELSIUS) mqttClient.publish("/alarm/ovrht", thermoItem->name);
|
||||
|
||||
if (!active) thermoRelay(thermoPin,false);//OFF
|
||||
else if (curTemp < thermoSetting - THERMO_GIST_CELSIUS) thermoRelay(thermoPin,true);//ON
|
||||
else if (curTemp >= thermoSetting) thermoRelay(thermoPin,false);//OFF
|
||||
if (!active) thermoRelay(thermoPin,OFF);//OFF
|
||||
else if (curTemp < thermoSetting - THERMO_GIST_CELSIUS) thermoRelay(thermoPin,HEAT);//ON
|
||||
else if (curTemp >= thermoSetting) thermoRelay(thermoPin,OFF);//OFF
|
||||
else debugSerial<<F(" -target zone-")<<endl; // Nothing to do
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#if defined(ARDUINO_ARCH_AVR)
|
||||
#include "HTTPClientAVR.h"
|
||||
#include <ArduinoHttpClient.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/wdt.h>
|
||||
//#include <EEPROM.h>
|
||||
|
||||
@@ -188,7 +188,7 @@ byte getCRC(byte req[], size_t size){
|
||||
void SendData(byte req[], size_t size){
|
||||
AC_Serial.write(req, size - 1);
|
||||
AC_Serial.write(getCRC(req, size-1));
|
||||
AC_Serial.flush();
|
||||
//AC_Serial.flush();
|
||||
/*
|
||||
Serial.print("<<");
|
||||
for (int i=0; i < size-1; i++)
|
||||
|
||||
@@ -14,14 +14,14 @@ static int driverStatus = CST_UNKNOWN;
|
||||
int out_dmx::Setup()
|
||||
{
|
||||
abstractOut::Setup();
|
||||
debugSerial<<F("DMX-Out Init")<<endl;
|
||||
debugSerial<<F("DMX-Out Init: ")<< item->itemArr->name <<endl;
|
||||
driverStatus = CST_INITIALIZED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int out_dmx::Stop()
|
||||
{
|
||||
debugSerial<<F("DMX-Out stop")<<endl;
|
||||
debugSerial<<F("DMX-Out stop: ")<< item->itemArr->name << endl;
|
||||
driverStatus = CST_UNKNOWN;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ void analogWrite(int pin, int val)
|
||||
int out_pwm::Setup()
|
||||
{
|
||||
abstractOut::Setup();
|
||||
debugSerial<<F("PWM-Out Init")<<endl;
|
||||
debugSerial<<F("PWM-Out #")<<iaddr<<F(" init")<<endl;
|
||||
if (!item || iaddr) return 0;
|
||||
|
||||
switch (getChanType())
|
||||
@@ -61,7 +61,7 @@ return 1;
|
||||
|
||||
int out_pwm::Stop()
|
||||
{
|
||||
debugSerial<<F("PWM-Out stop")<<endl;
|
||||
debugSerial<<F("PWM-Out #")<<iaddr<<F(" stop")<<endl;
|
||||
|
||||
switch (getChanType())
|
||||
{
|
||||
@@ -95,17 +95,23 @@ int out_pwm::getChanType()
|
||||
{
|
||||
if (item)
|
||||
{
|
||||
debugSerial<<F("PWM Chan type ");
|
||||
switch (numArgs)
|
||||
{
|
||||
case 3:
|
||||
debugSerial<<F("RGB PWM")<<endl;
|
||||
debugSerial<<F("RGB")<<endl;
|
||||
return CH_RGB;
|
||||
|
||||
case 4:
|
||||
debugSerial<<F("RGBW PWM")<<endl;
|
||||
debugSerial<<F("RGBW")<<endl;
|
||||
return CH_RGBW;
|
||||
|
||||
case 5:
|
||||
debugSerial<<F("RGBWW")<<endl;
|
||||
return CH_RGBWW;
|
||||
|
||||
default:
|
||||
debugSerial<<item->itemType<<F(" PWM")<<endl;
|
||||
debugSerial<<F("#")<<item->itemType<<endl;
|
||||
return item->itemType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,8 +49,8 @@ class Streamlog : public Print
|
||||
private:
|
||||
uint8_t severity;
|
||||
SerialPortType *serialPort;
|
||||
uint8_t ledPattern;
|
||||
#ifdef SYSLOG_ENABLE
|
||||
Syslog * syslog;
|
||||
uint8_t ledPattern;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -402,6 +402,7 @@ lib_deps =
|
||||
https://github.com/anklimov/DS2482_OneWire
|
||||
https://github.com/anklimov/DmxSimple
|
||||
https://github.com/anklimov/httpClient
|
||||
;ArduinoHttpClient
|
||||
https://github.com/anklimov/aJson
|
||||
https://github.com/anklimov/CmdArduino
|
||||
https://github.com/anklimov/ModbusMaster
|
||||
@@ -609,7 +610,7 @@ framework = arduino
|
||||
board = due
|
||||
monitor_baud = 115200
|
||||
build_flags = !python get_build_flags.py lighthub21
|
||||
upload_command = arduinoOTA -address 192.168.11.172 -port 65280 -username arduino -password password -b -upload /sketch -sketch $SOURCE ;sleep 6
|
||||
upload_command = /opt/local/sbin/arduinoOTA -address 192.168.11.172 -port 65280 -username arduino -password password -b -upload /sketch -sketch $SOURCE ;sleep 6
|
||||
;upload_command = arduinoOTA -address 192.168.88.45 -port 65280 -username arduino -password password -b -upload /sketch -sketch $SOURCE;sleep 6
|
||||
upload_protocol = custom
|
||||
lib_ignore =
|
||||
|
||||
Reference in New Issue
Block a user