7 Commits

Author SHA1 Message Date
09831781aa bins 2024-01-28 16:27:01 +03:00
340d54be09 sync 2024-01-28 16:20:45 +03:00
bcae3c9d50 artnet hung, sensors loop, inputs, multivent 2024-01-28 16:19:45 +03:00
1654f05bbe lh21 bins 2024-01-28 15:12:35 +03:00
99466f6e9f bins & cross-compilation 2024-01-28 15:10:56 +03:00
05ea031977 PID out, less logs, GET cfg fix, mbus concurr wrte 2024-01-28 12:05:10 +03:00
5ec57f0414 GET cmd refactored to operate in safe time 2024-01-27 15:03:11 +03:00
32 changed files with 54961 additions and 54498 deletions

View File

@@ -44,3 +44,6 @@
-D BEARSSL_SSL_BASIC
-D SPILED_DISABLE
-D PWM_DISABLE
# WAK for HDC1080 (pin D3 on wemos is IO0)
-D WAK_PIN=D3

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,3 +1,3 @@
export PORT=cu.usbmodem141101
export PORT=cu.usbmodem142101
echo . | stty -f /dev/$PORT speed 1200
../tools/mac/tool-bossac/bossac -U false -p $PORT -i -w -v -b firmware.bin -R

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -146,7 +146,8 @@ if (input->type == aJson_Object) {
else
{
Input in(input);
in.Poll(CHECK_INPUT);
in.store->aslong = 0;
//in.Poll(CHECK_INPUT);
}
}
}
@@ -524,7 +525,7 @@ bool Input::changeState(uint8_t newState, short cause)
if (!inputObj || !store) return false;
if (newState == IS_REQSTATE)
if (store->delayedState && cause != CHECK_INTERRUPT)
if (store->delayedState && (cause != CHECK_INTERRUPT))
{
// Requested delayed change State and safe moment
newState=store->reqState; //Retrieve requested state

View File

@@ -105,7 +105,7 @@ extern aJsonObject *inputs;
typedef union {
long int aslong;
uint32_t aslong;
uint32_t timestamp;
// Analog input structure
struct {

View File

@@ -327,7 +327,7 @@ void Item::setCmd(uint8_t cmdValue) {
{
itemCmd->type = aJson_Int;
itemCmd->valueint = cmdValue & CMD_MASK | itemCmd->valueint & (FLAG_MASK); // Preserve special bits
debugSerial<<F("SetCmd:")<<cmdValue<<endl;
//debugSerial<<F("SetCmd:")<<cmdValue<<endl;
}
}

View File

@@ -1171,8 +1171,8 @@ bool itemCmd::saveItem(Item * item, uint16_t optionsFlag)
item->setVal(param.asInt32);
item->setSubtype(cmd.itemArgType);
}
debugSerial<<F("Saved:");
debugOut();
//debugSerial<<F("Saved:");
//debugOut();
return true;
}
return false;

View File

@@ -170,6 +170,13 @@ bool cleanConf(bool wait)
{
if (!root) return true;
bool clean = true;
if (configLocked)
{
errorSerial<<F("Can not clean - locked")<<endl;
return false;
}
/*
No more unsafe operations
if (wait)
{
debugSerial<<F("Unlocking config ...")<<endl;
@@ -196,6 +203,7 @@ if (configLocked)
clean = false;
}
} //wait
*/
debugSerial<<F("Stopping channels ...")<<endl;
timerHandlerBusy++;
@@ -400,7 +408,7 @@ void mqttCallback(char *topic, byte *payload, unsigned int length)
int fr = freeRam();
debugSerial<<F("\n")<<fr<<F(":[")<<topic<<F("] ");
debugSerial<<fr<<F(":[")<<topic<<F("] ");
if (fr < 250+MQTT_TOPIC_LENGTH) {
errorSerial<<F("OutOfMemory!")<<endl;
@@ -619,12 +627,14 @@ lan_status lanLoop() {
if (!initializedListeners)
{
setupSyslog();
debugSerial<<F("Setup OTA")<<endl;
setupOTA();
#ifdef _artnet
if (artnet) artnet->begin();
#endif
#ifdef IPMODBUS
debugSerial<<F("Setup IPModbus")<<endl;
setupIpmodbus();
#endif
initializedListeners = true;
@@ -763,8 +773,32 @@ lan_status lanLoop() {
}
break;
case DO_GET:
if (mqttClient.connected()) mqttClient.disconnect();
timerLanCheckTime = millis();// + 5000;
lanStatus = GET;
break;
case GET:
statusLED.set(ledRED|ledGREEN|((configLoaded)?ledBLINK:0));
if (configLocked) return GET;
lanStatus = GET_IN_PROGRESS;
if (loadConfigFromHttp()==200) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
else if (configLoaded) {
infoSerial<<F("Continue with previously loaded config")<<endl;
lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
}
else if (Ethernet.localIP()) lanStatus = DO_READ_RE_CONFIG;
else lanStatus = DO_REINIT; //Load from NVRAM
break;
case DO_NOTHING:
case OPERATION_NO_MQTT:
case GET_IN_PROGRESS:
;
}
@@ -1680,7 +1714,10 @@ if (arg_cnt>1)
if (lanStatus>=HAVE_IP_ADDRESS)
{
lanStatus = DO_GET;
return 200;
/*
let Re-Get will be only in safe time
int retCode=loadConfigFromHttp();
if (retCode==200)
{
@@ -1699,6 +1736,7 @@ int retCode=loadConfigFromHttp();
if (configLoaded) lanStatus =IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
else lanStatus = DO_READ_RE_CONFIG;
return retCode;
*/
}
errorSerial<<F("No IP adress")<<endl;
return 500;
@@ -1772,7 +1810,12 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
infoSerial<<F("got Config\n"); delay(500);
aJsonFileStream as = aJsonFileStream(configStream);
noInterrupts();
cleanConf(true);
if (!cleanConf(true))
{
errorSerial<<F("Get aborted")<<endl;
hclient.closeStream(configStream);
return 500;
}
root = aJson.parse(&as);
interrupts();
hclient.closeStream(configStream); // this is very important -- be sure to close the STREAM
@@ -1844,7 +1887,13 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
if (responseStatusCode == 200) {
aJsonStream socketStream = aJsonStream(&htclient);
debugSerial<<F("Free:")<<freeRam()<<endl;
cleanConf(true);
if (!cleanConf(true))
{
errorSerial<<F("Get aborted")<<endl;
htclient.stop();
return 500;
}
debugSerial<<F("Configuration cleaned")<<endl;
debugSerial<<F("Free:")<<freeRam()<<endl;
//root = aJson.parse((char *) response.c_str());
@@ -1917,7 +1966,12 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
sysConf.setETAG(httpClient.header("ETag"));
//String response = httpClient.getString();
//debugSerial<<response;
cleanConf(true);
if (!cleanConf(true))
{
errorSerial<<F("Get aborted")<<endl;
httpClient.end();
return 500;
}
//root = aJson.parse((char *) response.c_str());
root = aJson.parse(&socketStream);
@@ -2634,12 +2688,12 @@ void loop_main() {
#if defined(OTA)
yield();
ArduinoOTA.poll();
if (initializedListeners) ArduinoOTA.poll();
#endif
#ifdef _artnet
yield();
if (artnet) artnet->read(); ///hung if network not initialized
if (artnet && initializedListeners) artnet->read(); ///hung if network not initialized
#endif
#ifdef MDNS_ENABLE
#ifndef WIFI_ENABLE
@@ -2688,7 +2742,7 @@ if (initializedListeners) ipmodbusLoop();
void owIdle(void) {
// timerCtr++;
#ifdef _artnet
if (artnet && (lanStatus>=HAVE_IP_ADDRESS)) artnet->read();
if (artnet && initializedListeners && (lanStatus>=HAVE_IP_ADDRESS)) artnet->read();
#endif
wdt_res();
@@ -2747,7 +2801,7 @@ void modbusIdle(void) {
yield();
mqttClient.loop();
#ifdef _artnet
if (artnet) artnet->read();
if (artnet && initializedListeners) artnet->read();
#endif
#if defined(OTA)
yield();
@@ -2819,9 +2873,10 @@ inputLoopBusy--;
void inputSensorsLoop() {
if (!inputs || inputLoopBusy) return;
//inputLoopBusy++;
configLocked++;
//configLocked++;
if (isTimeOver(timerSensorCheck,millis(),INTERVAL_CHECK_SENSOR))
{
configLocked++;
aJsonObject *input = inputs->child;
while (input) {
if ((input->type == aJson_Object)) {
@@ -2833,8 +2888,9 @@ configLocked++;
input = input->next;
}
timerSensorCheck = millis();
}
configLocked--;
}
//configLocked--;
//inputLoopBusy--;
}

View File

@@ -218,7 +218,10 @@ enum lan_status {
RECONNECT = 13,
READ_RE_CONFIG = 14,
DO_READ_RE_CONFIG = 15,
DO_NOTHING = -15
DO_NOTHING = -15,
DO_GET = -16,
GET = -17,
GET_IN_PROGRESS = 18
};
extern lan_status lanStatus;

View File

@@ -16,13 +16,13 @@
#if defined (ARDUINO_ARCH_ESP8266)
#if not defined (TWI_SCL) && defined (D1)
#define TWI_SCL D1
#endif
// #if not defined (TWI_SCL) && defined (D1)
// #define TWI_SCL D1
// #endif
#if not defined (WAK_PIN) && defined (D3)
#define WAK_PIN D3
#endif
// #if not defined (WAK_PIN) && defined (D3)
// #define WAK_PIN D3
// #endif
#if defined (TWI_SCL)
#define SCL_LOW() (GPES = (1 << TWI_SCL))
@@ -35,7 +35,7 @@
#if defined (ARDUINO_ARCH_ESP32)
#undef WAK_PIN
//#undef WAK_PIN
#undef SCL_RESET
//#ifndef WAK_PIN
//#define WAK_PIN 17
@@ -43,9 +43,9 @@
#endif
#if defined(ARDUINO_ARCH_AVR)
#ifndef WAK_PIN
#define WAK_PIN 3 // for LightHub UEXT SCS Pin
#endif
//#ifndef WAK_PIN
//#define WAK_PIN 3 // for LightHub UEXT SCS Pin
//#endif
#endif

View File

@@ -468,6 +468,7 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute, bool authorized)
case S_CMD:
// s_mode[0]='\0';
store->inCheck=0;
switch (cmd.getCmd())
{
case CMD_ON:
@@ -549,9 +550,42 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute, bool authorized)
store->data[B_FAN_SPD] = 2;
strcpy_P(s_speed,LOW_P);
break;
case CMD_OFF:
store->inCheck=0;
store->data[B_POWER] = store->power;
store->data[B_POWER] &= ~1;
SendData(off, sizeof(off)/sizeof(byte));
return 1;
default:
//if (n) data[B_FAN_SPD] = Parameters[0];
store->data[B_FAN_SPD] = cmd.getInt();
{
uint8_t speed = 0;
if (cmd.getInt()) speed = map(cmd.getInt(),1,255,1,3);
store->inCheck=0;
switch (speed) {
case 0:
store->data[B_POWER] = store->power;
store->data[B_POWER] &= ~1;
SendData(off, sizeof(off)/sizeof(byte));
return 1;
case 1:
store->data[B_FAN_SPD] = 2;
strcpy_P(s_speed,LOW_P);
store->data[B_POWER] = store->power;
store->data[B_POWER] |= 1;
break;
case 2:
store->data[B_FAN_SPD] = 1;
strcpy_P(s_speed,MED_P);
store->data[B_POWER] = store->power;
store->data[B_POWER] |= 1;
break;
case 3:
store->data[B_FAN_SPD] = 0;
strcpy_P(s_speed,HIGH_P);
store->data[B_POWER] = store->power;
store->data[B_POWER] |= 1;
}
}
//TODO - mapping digits to speed
}
publishTopic(item->itemArr->name,s_speed,"/fan");

View File

@@ -341,7 +341,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
switch (defMappingObj->type)
{
case aJson_Int: //register/coil/.. number
debugSerial<<F("Searching reg#")<<defMappingObj->valueint<<endl;
traceSerial<<F("Searching reg#")<<defMappingObj->valueint<<endl;
if ((defMappingObj->valueint>= registerFrom) && (defMappingObj->valueint<=registerTo))
{
mappedParam = findRegister(defMappingObj->valueint,defMappingObj->valueint-registerFrom,regType,registerFrom,registerTo,false,&submitRecurrentOut);
@@ -351,7 +351,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
break;
case aJson_String: // parameter name
debugSerial<<F("Searching reg: ")<<defMappingObj->valuestring<<endl;
traceSerial<<F("Searching reg: ")<<defMappingObj->valuestring<<endl;
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
{
//Searching item param for nested mapping
@@ -364,7 +364,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
aJsonObject *lastMeasured = aJson.getObjectItem(itemParObj,"@S");
if (lastMeasured && lastMeasured->type ==aJson_Int)
{
debugSerial<<F("LastKnown value: ")<<lastMeasured->valueint<<endl;
traceSerial<<F("LastKnown value: ")<<lastMeasured->valueint<<endl;
//Searching template param for nested mapping
aJsonObject * templateParObj = aJson.getObjectItem(store->parameters,defMappingObj->valuestring);
if (templateParObj)
@@ -550,7 +550,7 @@ return itemCmd();
int registerTo=aJson.getArrayItem(reg, 1)->valueint;
if (readModbus(registerFrom,regType,registerTo-registerFrom+1))
{ debugSerial<<endl;
{ traceSerial<<endl;
for(int i=registerFrom;i<=registerTo;i++)
{
findRegister(i,i-registerFrom,regType,registerFrom,registerTo);
@@ -633,7 +633,7 @@ int out_Modbus::sendModbus(char * paramName, int32_t value, uint8_t regType)
break;
}
mbusSlenceTimer = millisNZ();
debugSerial<<F("Res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<value<<endl;
debugSerial<<F("MBUS res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<value<<endl;
return ( res == 0);
}
@@ -667,8 +667,18 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
lineInitialized=true;
initLine();
}
int sendRes;
int savedValue;
do
{
savedValue = outValue->valueint;
debugSerial<<"MBUS: SEND "<<item->itemArr->name<<" ";
switch (sendModbus(execObj->name,outValue->valueint,outValue->subtype))
sendRes = sendModbus(execObj->name,outValue->valueint,outValue->subtype);
}
while (savedValue != outValue->valueint); //repeat sending if target value changed while we're waited for mbus responce
switch (sendRes)
{
case 1: //success
execObj->subtype&=~ MB_NEED_SEND;

View File

@@ -44,19 +44,19 @@ if (gatesObj /*&& aJson.getArraySize(item->itemArg)>=2*/)
}
i=i->next;
}
debugSerial << F ("MultiVent init")<< endl;
debugSerial << F ("VENT: init")<< endl;
setStatus(CST_INITIALIZED);
return 1;
}
debugSerial << F ("MultiVent config failed")<< endl;
debugSerial << F ("VENT: config failed")<< endl;
return 0;
}
int out_Multivent::Stop()
{
debugSerial << F ("Multivent De-Init") << endl;
debugSerial << F ("VENT: De-Init") << endl;
setStatus(CST_UNKNOWN);
return 1;
}
@@ -151,7 +151,7 @@ while (i)
if (cmdObj->valueint == CMD_OFF || cmdObj->valueint == -1)
{
debugSerial<<"Turning ON"<<endl;
debugSerial<<"VENT: Turning ON"<<endl;
cmdObj->valueint = CMD_ON;
cmd.Cmd(CMD_ON);
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_ON),FLAG_COMMAND,i->name);
@@ -162,7 +162,7 @@ while (i)
else
{
if (cmdObj->valueint != CMD_OFF && cmdObj->valueint != -1)
{ debugSerial<<"Turning OFF"<<endl;
{ debugSerial<<"VENT: Turning OFF"<<endl;
cmdObj->valueint = CMD_OFF;
cmd.Cmd(CMD_OFF);
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_OFF),FLAG_COMMAND,i->name);
@@ -204,10 +204,13 @@ while (i)
if (!totalV) return 0;
int fanV=activeV/totalV;
debugSerial << F("Total V:")<<totalV<<F(" active V:")<<activeV/255<< F(" fan%:")<<fanV<< F(" Max request:")<<maxRequestedV/255 <<F(" from ")<<maxV<<F(" m3")<< endl;
executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV).Cmd((fanV)?CMD_ON:CMD_OFF));
debugSerial << F("VENT: Total V:")<<totalV<<F(" active V:")<<activeV/255<< F(" fan%:")<<fanV<< F(" Max req:")<<maxRequestedV/255 <<F(" from ")<<maxV<<F(" m3")<< endl;
//executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV).Cmd((fanV)?CMD_ON:CMD_OFF));
if (fanV)
executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV).Cmd(CMD_ON));
else
executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV));
//Move gates only if fan is actually on
if (!fanV) return 1;
@@ -229,7 +232,7 @@ while (i)
{
int requestedV=V*setObj->valueint;
out = (( long)requestedV*255L)/(( long)V)*( long)maxV/( long)maxRequestedV;
debugSerial<<i->name<<(" Req:")<<requestedV/255<<F(" Out:")<<out<<endl;
debugSerial<<F("VENT: ")<<i->name<<F(" Req:")<<requestedV/255<<F(" Out:")<<out<<endl;
}

View File

@@ -334,32 +334,38 @@ case S_CTRL:
switch (command)
{
case CMD_OFF:
//value.Percents255(0);
if (isNotRetainingStatus()) executeCommand(oCmd,-1,itemCmd().Cmd(CMD_DISABLE)); // Not actually disable, just inform depended systems, that no autoreg now (for pannels indication)
executeCommand(oCmd,-1,value);
item->SendStatus(FLAG_FLAGS);
return 1;
case CMD_ON:
case CMD_HEAT:
case CMD_COOL:
case CMD_AUTO:
case CMD_FAN:
case CMD_DRY:
executeCommand(oCmd,-1,value);
executeCommand(oCmd,-1,itemCmd().Cmd((item->getFlag(FLAG_DISABLED))?CMD_DISABLE:CMD_ENABLE));
executeCommand(oCmd,-1,value);
item->SendStatus(FLAG_FLAGS);
return 1;
case CMD_ENABLE:
//item->setCmd(CMD_ENABLE);
//item->SendStatus(FLAG_COMMAND);
if (isNotRetainingStatus())
{
item->setCmd(CMD_ON);
item->SendStatus(FLAG_COMMAND);
}
item->setFlag(FLAG_ACTION_NEEDED);
executeCommand(oCmd,-1,value);
if (isActive()) executeCommand(oCmd,-1,itemCmd().Cmd((CMD_ON)));
store->prevOut=-2.0;
return 1;
case CMD_DISABLE:
//item->setCmd(CMD_DISABLE);
//item->SendStatus(FLAG_COMMAND);
executeCommand(oCmd,-1,value);
if (!isActive()) executeCommand(oCmd,-1,itemCmd().Cmd((CMD_OFF)));
return 1;
/*
case CMD_OFF:

View File

@@ -5,7 +5,7 @@
#define MAXFLASHSTR 32
#define PWDFLASHSTR 16
#define EEPROM_SIGNATURE "LHC1"
#define EEPROM_SIGNATURE "LHC2"
#define EEPROM_SIGNATURE_LENGTH 4
//#define EEPROM_offsetJSON IFLASH_PAGE_SIZE
@@ -23,12 +23,12 @@ const char EEPROM_signature[] = EEPROM_SIGNATURE;
uint32_t configFlags32bit;
struct
{
uint8_t serialDebugLevel:3;
uint8_t serialDebugLevel:4;
uint8_t notGetConfigFromHTTP:1;
uint8_t udpDebugLevel:3;
uint8_t notSaveSuccedConfig:1;
uint8_t dhcpFallback:1;
uint8_t spare2:7;
uint8_t spare2:6;
uint16_t sysConfigHash;
};
} systemConfigFlags;

View File

@@ -193,7 +193,7 @@ monitor_speed = 115200
platform = espressif32
framework = arduino
monitor_filters = esp32_exception_decoder
build_type = debug
;build_type = debug
board = esp32-evb
extra_scripts = extra_script.py
monitor_speed = 115200
@@ -521,10 +521,24 @@ lib_deps =
platform = espressif8266
framework = arduino
;board = nodemcuv2
board = esp01_1m
;esp12e ESP8266 80MHz 4MB 80KB Espressif ESP8266 ESP-12E
;esp01_1m ESP8266 80MHz 1MB 80KB Espressif Generic ESP8266 ESP-01 1M
extra_scripts = extra_script.py
board_build.ldscript = eagle.flash.1m64.ld
;upload_protocol = esptool
;;;; 1M plug ;;;
;board = esp01_1m
;board_build.ldscript = eagle.flash.1m64.ld
;;;;;;;;;;;;;;;;;;;
;;;; WEMOS D1 ;;;;;
board = d1_mini
; change microcontroller
board_build.mcu = esp8266
; change MCU frequency
board_build.f_cpu = 80000000L
upload_protocol = esptool
;;;;;;;;;;;;;;;;;;;
;build_type = debug
;monitor_filters = esp8266_exception_decoder