mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c70a4eaac9 | |||
| a956b6f8e2 | |||
| 07688f53ae | |||
| 6d28cb9f34 | |||
| d7e93177d6 | |||
| c23543b213 | |||
| b94ab723ee |
@@ -17,7 +17,7 @@
|
||||
-DMOTOR_DISABLE
|
||||
#-DWiz5100
|
||||
-DARDUINO_OTA_MDNS_DISABLE
|
||||
#-DMDNS_ENABLE
|
||||
-DMDNS_ENABLE
|
||||
|
||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||
-D CORS=\"http://lazyhome.ru\"
|
||||
|
||||
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.
Binary file not shown.
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.
@@ -19,7 +19,7 @@ int abstractCh::publishTopic(const char* topic, long value, const char* subtopic
|
||||
int abstractCh::publishTopic(const char* topic, float value, const char* subtopic)
|
||||
{
|
||||
char valstr[16];
|
||||
printFloatValueToStr(value, valstr);
|
||||
printFloatValueToStr(valstr, value);
|
||||
return publishTopic(topic, valstr,subtopic);
|
||||
};
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ int abstractIn::publish(long value, const char* subtopic)
|
||||
int abstractIn::publish(float value, const char* subtopic)
|
||||
{
|
||||
char valstr[16];
|
||||
printFloatValueToStr(value, valstr);
|
||||
printFloatValueToStr(valstr, value);
|
||||
return publish(valstr,subtopic);
|
||||
};
|
||||
|
||||
|
||||
@@ -39,6 +39,8 @@ extern NRFFlashStorage EEPROM;
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
DueFlashStorage EEPROM;
|
||||
static char samBuffer[64];
|
||||
short samBufferPos = 0;
|
||||
#endif
|
||||
|
||||
#ifdef NRF5
|
||||
@@ -129,6 +131,11 @@ NRFFlashStorage EEPROM;
|
||||
int flashStream::open(short fileNum, char mode)
|
||||
{
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
if (samBufferPos) flush();
|
||||
samBufferPos = 0;
|
||||
#endif
|
||||
|
||||
switch (fileNum) {
|
||||
case FN_CONFIG_JSON:
|
||||
pos = 0;
|
||||
@@ -138,6 +145,7 @@ NRFFlashStorage EEPROM;
|
||||
#ifdef OTA
|
||||
contentType = HTTP_TEXT_JSON;
|
||||
#endif
|
||||
openmode = mode;
|
||||
return 1;
|
||||
|
||||
case FN_CONFIG_BIN:
|
||||
@@ -148,6 +156,7 @@ NRFFlashStorage EEPROM;
|
||||
#ifdef OTA
|
||||
contentType = HTTP_OCTET_STREAM;
|
||||
#endif
|
||||
openmode = mode;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
@@ -171,7 +180,13 @@ NRFFlashStorage EEPROM;
|
||||
};
|
||||
|
||||
unsigned int flashStream::seek(unsigned int _pos)
|
||||
{ pos=min(_pos, streamSize);
|
||||
{
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
if (samBufferPos) flush();
|
||||
#endif
|
||||
|
||||
pos=min(_pos, streamSize);
|
||||
//debugSerial<<F("Seek:")<<pos<<endl;
|
||||
return pos;
|
||||
};
|
||||
@@ -196,21 +211,38 @@ NRFFlashStorage EEPROM;
|
||||
else return -1;
|
||||
};
|
||||
|
||||
|
||||
void flashStream::flush() {
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
if (EEPROM.commitReset())
|
||||
infoSerial<<"Commited to FLASH"<<endl;
|
||||
else errorSerial<<"Commit error. len:"<<EEPROM.length()<<endl;
|
||||
#elif defined(__SAM3X8E__)
|
||||
if (samBufferPos)
|
||||
EEPROM.write(startPos+pos-samBufferPos,(byte*)samBuffer,samBufferPos);
|
||||
samBufferPos=0;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
size_t flashStream::write(uint8_t ch)
|
||||
{
|
||||
#if defined(__AVR__)
|
||||
EEPROM.update(startPos+pos++,(char)ch);
|
||||
return 1;
|
||||
#elif defined(__SAM3X8E__)
|
||||
return EEPROM.write(startPos+pos++,(char)ch);
|
||||
|
||||
if (samBufferPos==sizeof(samBuffer))
|
||||
{
|
||||
samBufferPos = 0;
|
||||
EEPROM.write(startPos+pos-sizeof(samBuffer),(byte*)samBuffer,sizeof(samBuffer));
|
||||
}
|
||||
|
||||
samBuffer[samBufferPos++]=ch;
|
||||
pos++;
|
||||
return 1;
|
||||
// return EEPROM.write(startPos+pos++,(char)ch);
|
||||
|
||||
#else
|
||||
EEPROM.write(startPos+pos++,(char)ch);
|
||||
return 1;
|
||||
@@ -237,7 +269,10 @@ NRFFlashStorage EEPROM;
|
||||
|
||||
void flashStream::close()
|
||||
{
|
||||
putEOF();
|
||||
if (openmode == 'w') putEOF();
|
||||
#if defined(__SAM3X8E__)
|
||||
if (samBufferPos) flush();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -53,9 +53,10 @@ class flashStream : public seekableStream
|
||||
protected:
|
||||
unsigned int pos;
|
||||
unsigned int startPos;
|
||||
char openmode ;
|
||||
|
||||
public:
|
||||
flashStream():seekableStream(MAX_STREAM_SIZE){};
|
||||
flashStream():seekableStream(MAX_STREAM_SIZE){openmode = '\0';};
|
||||
void setSize(unsigned int _size);
|
||||
int open(short fileNum, char mode='\0') ;
|
||||
virtual int open(String _filename, char mode='\0') override;
|
||||
|
||||
@@ -503,11 +503,11 @@ debugSerial << F("IN:") << pin << F(" DHT22 type. T=") << temp << F("°C H=") <<
|
||||
strncpy(addrstr, emit->valuestring, sizeof(addrstr));
|
||||
if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring);
|
||||
strcat(addrstr, "T");
|
||||
printFloatValueToStr(temp, valstr);
|
||||
printFloatValueToStr(valstr, temp);
|
||||
if (mqttClient.connected() && !ethernetIdleCount)
|
||||
mqttClient.publish(addrstr, valstr);
|
||||
addrstr[strlen(addrstr) - 1] = 'H';
|
||||
printFloatValueToStr(humidity, valstr);
|
||||
printFloatValueToStr(valstr, humidity);
|
||||
if (mqttClient.connected() && !ethernetIdleCount)
|
||||
mqttClient.publish(addrstr, valstr);
|
||||
|
||||
|
||||
@@ -1181,6 +1181,7 @@ return false;
|
||||
i=i->next;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case aJson_String:
|
||||
if (strcmp(cmdMapping->valuestring,"fan")==0)
|
||||
switch (getCmd())
|
||||
@@ -1209,7 +1210,10 @@ return false;
|
||||
|
||||
} //switch
|
||||
|
||||
if (matchedCmd) return itemCmd().Int((uint32_t)matchedCmd->valueint);
|
||||
if (matchedCmd && matchedCmd->type != aJson_NULL)
|
||||
{
|
||||
return itemCmd().Int((uint32_t)matchedCmd->valueint);
|
||||
}
|
||||
|
||||
aJsonObject *valMapping = aJson.getObjectItem(mappingData, "val");
|
||||
if (isValue() && valMapping && valMapping->type == aJson_Array && aJson.getArraySize(valMapping) == 4)
|
||||
@@ -1220,6 +1224,7 @@ if (isValue() && valMapping && valMapping->type == aJson_Array && aJson.getArray
|
||||
aJson.getArrayItem(valMapping,0)->valueint,aJson.getArrayItem(valMapping,1)->valueint,
|
||||
aJson.getArrayItem(valMapping,2)->valueint,aJson.getArrayItem(valMapping,3)->valueint));
|
||||
}
|
||||
else if (valMapping && valMapping->type == aJson_NULL) return itemCmd(ST_VOID,CMD_VOID);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1335,6 +1340,9 @@ char * itemCmd::toString(char * Buffer, int bufLen, int sendFlags, bool scale100
|
||||
snprintf(argPtr, bufLen, "%ld", param.asInt32);
|
||||
break;
|
||||
case ST_TENS:
|
||||
if (param.asInt32<0)
|
||||
snprintf(argPtr, bufLen, "-%ld.%0"QUOTE(TENS_FRACT_LEN)"d", abs(param.asInt32)/TENS_BASE, abs(param.asInt32 % TENS_BASE));
|
||||
else
|
||||
snprintf(argPtr, bufLen, "%ld.%0"QUOTE(TENS_FRACT_LEN)"d", param.asInt32/TENS_BASE, abs(param.asInt32 % TENS_BASE));
|
||||
break;
|
||||
case ST_HSV255:
|
||||
|
||||
@@ -665,6 +665,8 @@ lan_status lanLoop() {
|
||||
strncat(buf, "+/+/#", sizeof(buf)); // Subscribing only on separated command/parameters topics
|
||||
mqttClient.unsubscribe(buf);
|
||||
|
||||
onMQTTConnect();
|
||||
|
||||
lanStatus = OPERATION;//3;
|
||||
infoSerial<<F("Accepting commands...\n");
|
||||
}
|
||||
@@ -1002,7 +1004,7 @@ void ip_ready_config_loaded_connecting_to_broker() {
|
||||
debugSerialPort.println(buf);
|
||||
mqttClient.subscribe(buf);
|
||||
|
||||
onMQTTConnect();
|
||||
//onMQTTConnect();
|
||||
// if (_once) {DMXput(); _once=0;}
|
||||
lanStatus = RETAINING_COLLECTING;//4;
|
||||
timerLanCheckTime = millis();// + 5000;
|
||||
@@ -1497,11 +1499,11 @@ if (arg_cnt>1)
|
||||
#else
|
||||
sysConfStream.open(FN_CONFIG_JSON,'w');
|
||||
#endif
|
||||
|
||||
/*
|
||||
#if defined(__SAM3X8E__)
|
||||
long configBufSize = min(MAX_JSON_CONF_SIZE,freeRam()-1024);
|
||||
debugSerial<<"Allocate "<<configBufSize<<" bytes for buffer"<<endl;
|
||||
char* outBuf = (char*) malloc(configBufSize); /* XXX: Dynamic size. */
|
||||
char* outBuf = (char*) malloc(configBufSize);
|
||||
if (!outBuf)
|
||||
{
|
||||
sysConfStream.close();
|
||||
@@ -1509,23 +1511,22 @@ if (arg_cnt>1)
|
||||
return 500;
|
||||
}
|
||||
infoSerial<<F("Saving config to EEPROM..")<<endl;
|
||||
aJsonStringStream stringStream(NULL, outBuf, configBufSize);
|
||||
aJsonStringStream stringStream(NULL, outBuf, configBufSize-2);
|
||||
aJson.print(root, &stringStream);
|
||||
int len = strlen(outBuf);
|
||||
outBuf[len++]= EOFchar;
|
||||
|
||||
infoSerial<<len<< F(" bytes collected")<<endl;
|
||||
size_t res = sysConfStream.write((byte*) outBuf,len);
|
||||
free (outBuf);
|
||||
infoSerial<<res<< F(" bytes from ")<<len<<F(" are saved to EEPROM")<<endl;
|
||||
#else
|
||||
infoSerial<<res<< F(" bytes are saved to EEPROM")<<endl;
|
||||
#else */
|
||||
|
||||
aJsonStream jsonEEPROMStream = aJsonStream(&sysConfStream);
|
||||
infoSerial<<F("Saving config to EEPROM..");
|
||||
aJson.print(root, &jsonEEPROMStream);
|
||||
//sysConfStream.putEOF();
|
||||
//sysConfStream.flush();
|
||||
sysConfStream.close();
|
||||
infoSerial<<F("Saved to EEPROM")<<endl;
|
||||
#endif
|
||||
//#endif
|
||||
sysConf.saveETAG();
|
||||
return 200;
|
||||
}
|
||||
@@ -2285,6 +2286,10 @@ infoSerial<<F("\n(+)HUMIDIFIER");
|
||||
#ifdef ELEVATOR_ENABLE
|
||||
infoSerial<<F("\n(+)ELEVATOR");
|
||||
#endif
|
||||
|
||||
#ifdef IPMODBUS
|
||||
infoSerial<<F("\n(+)IPMODBUS");
|
||||
#endif
|
||||
infoSerial<<endl;
|
||||
|
||||
// WDT_Disable( WDT ) ;
|
||||
|
||||
@@ -317,4 +317,6 @@ void ip_ready_config_loaded_connecting_to_broker();
|
||||
|
||||
void printCurentLanConfig();
|
||||
|
||||
void onMQTTConnect();
|
||||
|
||||
//void printFreeRam();
|
||||
|
||||
@@ -15,6 +15,7 @@ void out_counter::getConfig()
|
||||
if (!item) return;
|
||||
impulse = item->getFloatArg(0);
|
||||
period = item->getFloatArg(1)*1000.0;
|
||||
//debugSerial<<"CTR: imp:"<<impulse<<" period:"<<period<<endl;
|
||||
}
|
||||
|
||||
int out_counter::Setup()
|
||||
@@ -38,7 +39,7 @@ return driverStatus;
|
||||
|
||||
int out_counter::Poll(short cause)
|
||||
{
|
||||
if (cause==POLLING_SLOW) return 0;
|
||||
if (cause==POLLING_SLOW || cause==POLLING_INT) return 0;
|
||||
if (!item) return 0;
|
||||
|
||||
|
||||
@@ -47,13 +48,18 @@ uint32_t timer = item->getExt();
|
||||
if (timer && period && isTimeOver(timer,millis(),period))
|
||||
{
|
||||
item->setExt(millisNZ());
|
||||
|
||||
itemCmd st;
|
||||
st.loadItem(item,SEND_PARAMETERS|SEND_COMMAND);
|
||||
float val = st.getFloat();
|
||||
//short cmd = st.getCmd();
|
||||
debugSerial<<"CTR: tick val:"<<val<<endl;
|
||||
|
||||
val+=impulse;
|
||||
st.Float(val);
|
||||
st.saveItem(item);
|
||||
debugSerial<<"CTR: tick saved val:"<<val<<endl;
|
||||
item->SendStatus(SEND_PARAMETERS);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -82,13 +88,11 @@ case S_SET:
|
||||
if (!item->getExt())
|
||||
{
|
||||
item->setExt(millisNZ());
|
||||
//relay(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
item->setExt(0);
|
||||
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@@ -105,13 +109,11 @@ case S_CMD:
|
||||
if (!item->getExt())
|
||||
{
|
||||
item->setExt(millisNZ());
|
||||
//relay(true);
|
||||
}
|
||||
return 1;
|
||||
|
||||
case CMD_OFF:
|
||||
item->setExt(0);
|
||||
|
||||
return 1;
|
||||
|
||||
default:
|
||||
|
||||
@@ -15,6 +15,7 @@ extern aJsonObject *modbusObj;
|
||||
extern ModbusMaster node;
|
||||
extern short modbusBusy;
|
||||
extern void modbusIdle(void) ;
|
||||
static uint32_t mbusSlenceTimer = 0;
|
||||
|
||||
struct reg_t
|
||||
{
|
||||
@@ -116,13 +117,13 @@ bool out_Modbus::getConfig()
|
||||
aJsonObject * templateIdObj = aJson.getArrayItem(item->itemArg, 1);
|
||||
if (templateIdObj->type != aJson_String || !templateIdObj->valuestring)
|
||||
{
|
||||
errorSerial<<F("Invalid template.")<<endl;
|
||||
errorSerial<<F("MBUS: Invalid template.")<<endl;
|
||||
return false;
|
||||
}
|
||||
aJsonObject * templateObj = aJson.getObjectItem(modbusObj, templateIdObj->valuestring);
|
||||
if (! templateObj)
|
||||
{
|
||||
errorSerial<<F("Modbus template not found: ")<<templateIdObj->valuestring<<endl;
|
||||
errorSerial<<F("MBUS: Modbus template not found: ")<<templateIdObj->valuestring<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -173,12 +174,12 @@ if (!store)
|
||||
store->timestamp=millisNZ();
|
||||
if (getConfig())
|
||||
{
|
||||
infoSerial<<F("Modbus config loaded ")<< item->itemArr->name<<endl;
|
||||
infoSerial<<F("MBUS: config loaded ")<< item->itemArr->name<<endl;
|
||||
store->driverStatus = CST_INITIALIZED;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{ errorSerial<<F("Modbus config error")<<endl;
|
||||
{ errorSerial<<F("MBUS: config error")<<endl;
|
||||
store->driverStatus = CST_FAILED;
|
||||
return 0;
|
||||
}
|
||||
@@ -187,7 +188,7 @@ else
|
||||
|
||||
int out_Modbus::Stop()
|
||||
{
|
||||
debugSerial.println("Modbus De-Init");
|
||||
debugSerial.println("MBUS: De-Init");
|
||||
|
||||
delete store;
|
||||
item->setPersistent(NULL);
|
||||
@@ -221,8 +222,9 @@ switch (regType) {
|
||||
result = node.readInputRegisters(reg, count);
|
||||
break;
|
||||
default:
|
||||
debugSerial<<F("Not supported reg type\n");
|
||||
debugSerial<<F("MBUS: Not supported reg type\n");
|
||||
}
|
||||
mbusSlenceTimer = millisNZ();
|
||||
if (result != node.ku8MBSuccess) errorSerial<<F("MBUS: Polling error ")<<_HEX(result)<<endl;
|
||||
return (result == node.ku8MBSuccess);
|
||||
}
|
||||
@@ -260,7 +262,7 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
case PAR_I16:
|
||||
//isSigned=true;
|
||||
param=data;
|
||||
mappedParam.Int((int32_t)data);
|
||||
mappedParam.Int((int32_t)(int16_t)data);
|
||||
break;
|
||||
|
||||
case PAR_U16:
|
||||
@@ -292,21 +294,21 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
|
||||
case PAR_TENS:
|
||||
param=data;
|
||||
mappedParam.Tens((int32_t) data);
|
||||
mappedParam.Tens((int16_t) data);
|
||||
break;
|
||||
|
||||
case PAR_100:
|
||||
param=data;
|
||||
mappedParam.Tens_raw(data * (TENS_BASE/100));
|
||||
mappedParam.Float((int32_t) data/100.);
|
||||
mappedParam.Tens_raw((int16_t) data * (TENS_BASE/100));
|
||||
mappedParam.Float((int32_t) (int16_t) data/100.);
|
||||
}
|
||||
|
||||
debugSerial << F("MB got ")<<mappedParam.toString(buf,sizeof(buf))<< F(" from ")<<regType<<F(":")<<paramObj->name<<endl;
|
||||
debugSerial << F("MBUSD: got ")<<mappedParam.toString(buf,sizeof(buf))<< F(" from ")<<regType<<F(":")<<paramObj->name<<endl;
|
||||
|
||||
if (mapObj && (mapObj->type==aJson_Array || mapObj->type==aJson_Object))
|
||||
{
|
||||
mappedParam=mappedParam.doReverseMapping(mapObj);
|
||||
debugSerial << F("Mapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
||||
debugSerial << F("MBUSD: Mapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
||||
}
|
||||
|
||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
@@ -328,7 +330,7 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
}
|
||||
else //No container to store value yet
|
||||
{
|
||||
debugSerial<<F("Add @S: ")<<paramObj->name<<endl;
|
||||
debugSerial<<F("MBUS: Add @S: ")<<paramObj->name<<endl;
|
||||
aJson.addNumberToObject(execObj, "@S", (long) param);
|
||||
}
|
||||
if (submitParam)
|
||||
@@ -338,9 +340,15 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
aJsonObject *settedValue = aJson.getObjectItem(execObj,"@V");
|
||||
if (settedValue && settedValue->type==aJson_Int && (settedValue->valueint == param))
|
||||
{
|
||||
debugSerial<<F("Ignored - equal with setted val")<<endl;
|
||||
debugSerial<<F("MBUSD: Ignored - equal with setted val")<<endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
executeCommand(execObj, -1, mappedParam);
|
||||
// if param updated by device and no new value queued to send - update @V to avoid "Ignored - equal with setted val"
|
||||
if (settedValue && !(execObj->subtype & MB_NEED_SEND))
|
||||
settedValue->valueint=param;
|
||||
}
|
||||
else executeCommand(execObj, -1, mappedParam);
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
@@ -410,7 +418,7 @@ void out_Modbus::initLine()
|
||||
#else
|
||||
modbusSerial.begin(store->baud, (store->serialParam));
|
||||
#endif
|
||||
debugSerial<< store->baud << F("---")<< store->serialParam<<endl;
|
||||
//debugSerial<< store->baud << F("---")<< store->serialParam<<endl;
|
||||
node.begin(item->getArg(0), modbusSerial);
|
||||
}
|
||||
|
||||
@@ -452,7 +460,8 @@ int out_Modbus::sendModbus(char * paramName, int32_t value, uint8_t regType)
|
||||
res = node.writeSingleRegister(regObj->valueint,(value & 0xFFFF)>> 8);
|
||||
break;
|
||||
}
|
||||
debugSerial<<F("MB_SEND Res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<value<<F(" ival:")<<(int32_t) value<<endl;
|
||||
mbusSlenceTimer = millisNZ();
|
||||
debugSerial<<F("Res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<value<<endl;
|
||||
return ( res == 0);
|
||||
}
|
||||
|
||||
@@ -461,7 +470,7 @@ int out_Modbus::Poll(short cause)
|
||||
if (cause==POLLING_SLOW) return 0;
|
||||
bool lineInitialized = false;
|
||||
|
||||
if (modbusBusy || (Status() != CST_INITIALIZED)) return 0;
|
||||
if (modbusBusy || (Status() != CST_INITIALIZED) || ( mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),100))) return 0;
|
||||
|
||||
aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
@@ -480,18 +489,22 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
lineInitialized=true;
|
||||
initLine();
|
||||
}
|
||||
debugSerial<<"MBUS: SEND "<<item->itemArr->name<<" ";
|
||||
switch (sendModbus(execObj->name,outValue->valueint,outValue->subtype))
|
||||
{
|
||||
case 1: //success
|
||||
execObj->subtype&=~ MB_NEED_SEND;
|
||||
///return 1; //relax
|
||||
|
||||
break;
|
||||
case 0: //fault
|
||||
execObj->subtype |= MB_SEND_ERROR;
|
||||
errorSerial<<F("MBus ")<<execObj->name<<F(" send error")<<endl;
|
||||
errorSerial<<F("MBUS: ")<<execObj->name<<F(" send error. ");
|
||||
if ((execObj->subtype & 3) != MB_SEND_ATTEMPTS) execObj->subtype++;
|
||||
errorSerial<<"Attempt: "<< (execObj->subtype & 3) <<endl;
|
||||
break;
|
||||
default: //param not found
|
||||
errorSerial<<F("MBus param ")<<execObj->name<<F(" not found")<<endl;
|
||||
errorSerial<<F("MBUS: param ")<<execObj->name<<F(" not found")<<endl;
|
||||
execObj->subtype&=~ MB_NEED_SEND;
|
||||
}
|
||||
}
|
||||
@@ -502,7 +515,7 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
}
|
||||
|
||||
|
||||
if (isTimeOver(store->timestamp,millis(),store->pollingInterval))
|
||||
if (isTimeOver(store->timestamp,millis(),store->pollingInterval) && ( !mbusSlenceTimer || isTimeOver(mbusSlenceTimer,millis(),100)))
|
||||
{
|
||||
|
||||
// Clean_up SEND_ERROR flag
|
||||
@@ -512,7 +525,14 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
while (execObj && execObj->type == aJson_Object)
|
||||
{
|
||||
if (execObj->subtype & MB_SEND_ERROR) execObj->subtype&=~ MB_SEND_ERROR;
|
||||
if ((execObj->subtype & 0x3) >= MB_SEND_ATTEMPTS) execObj->subtype&=~ MB_NEED_SEND;
|
||||
if ((execObj->subtype & 0x3) >= MB_SEND_ATTEMPTS)
|
||||
{
|
||||
//execObj->subtype&=~ MB_NEED_SEND;
|
||||
//Clean ERROR, NEED, Attempts
|
||||
errorSerial<<"MBUS: send failed "<<item->itemArr->name<<endl;
|
||||
execObj->subtype = 0;
|
||||
}
|
||||
|
||||
execObj=execObj->next;
|
||||
}
|
||||
}
|
||||
@@ -520,7 +540,7 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
// if some polling configured
|
||||
if (store->pollingRegisters || store->pollingIrs)
|
||||
{
|
||||
debugSerial<<F("Poll ")<< item->itemArr->name << endl;
|
||||
debugSerial<<F("MBUSD: Poll ")<< item->itemArr->name << endl;
|
||||
modbusBusy=1;
|
||||
|
||||
if (!lineInitialized)
|
||||
@@ -531,7 +551,7 @@ if (store->pollingRegisters || store->pollingIrs)
|
||||
|
||||
pollModbus(store->pollingRegisters,MODBUS_HOLDING_REG_TYPE);
|
||||
pollModbus(store->pollingIrs,MODBUS_INPUT_REG_TYPE);
|
||||
debugSerial<<F("endPoll ")<< item->itemArr->name << endl;
|
||||
debugSerial<<F("MBUSD: endPoll ")<< item->itemArr->name << endl;
|
||||
|
||||
//Non blocking waiting to release line
|
||||
uint32_t time = millis();
|
||||
@@ -561,6 +581,7 @@ if (!suffixCode) return 0;
|
||||
|
||||
char *suffixStr =templateParamObj->name;
|
||||
// We have find template for suffix or suffixCode
|
||||
itemCmd cmdValue = itemCmd(ST_VOID,CMD_VOID);
|
||||
long Value = 0;
|
||||
int8_t regType = PAR_I16;
|
||||
aJsonObject * typeObj = aJson.getObjectItem(templateParamObj, "type");
|
||||
@@ -577,29 +598,36 @@ aJsonObject * mapObj = aJson.getObjectItem(templateParamObj, "map");
|
||||
case PAR_I8H:
|
||||
case PAR_I8L:
|
||||
|
||||
Value=cmd.doMapping(mapObj).getInt();
|
||||
cmdValue=cmd.doMapping(mapObj);
|
||||
if (!cmdValue.isValue())return 0;
|
||||
Value=cmdValue.getInt();
|
||||
break;
|
||||
case PAR_TENS:
|
||||
Value=cmd.doMapping(mapObj).getTens();
|
||||
cmdValue=cmd.doMapping(mapObj);
|
||||
if (!cmdValue.isValue())return 0;
|
||||
Value=cmdValue.getTens();
|
||||
break;
|
||||
case PAR_100:
|
||||
Value=cmd.doMapping(mapObj).getTens_raw()*(100/TENS_BASE);
|
||||
cmdValue=cmd.doMapping(mapObj);
|
||||
if (!cmdValue.isValue())return 0;
|
||||
Value=cmdValue.getTens_raw()*(100/TENS_BASE);
|
||||
}
|
||||
|
||||
debugSerial<<F("MB suffix:")<<suffixStr<< F(" Val: ")<<Value<<endl;
|
||||
debugSerial<<F("MBUSD: suffix:")<<suffixStr<< F(" Val: ")<<Value<<endl;
|
||||
aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
{
|
||||
aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,suffixStr);
|
||||
if (execObj && execObj->type == aJson_Object)
|
||||
{
|
||||
/*
|
||||
aJsonObject *polledValue = aJson.getObjectItem(execObj,"@S");
|
||||
if (polledValue && polledValue->type == aJson_Int && (polledValue->valueint == Value))
|
||||
{
|
||||
debugSerial<<F("Ignored - not changed")<<endl;
|
||||
}
|
||||
|
||||
else
|
||||
else */
|
||||
{ //Schedule update
|
||||
execObj->subtype |= MB_NEED_SEND;
|
||||
|
||||
@@ -608,7 +636,6 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
{
|
||||
outValue->valueint=Value;
|
||||
outValue->subtype =regType & 0xF;
|
||||
if (outValue->type == aJson_Int) polledValue->valueint=Value; //to pevent suppressing to change back to previously polled value if this occurs before next polling
|
||||
}
|
||||
else //No container to store value yet
|
||||
// If no @V in config - creating with INT type - normal behavior - no supress in-to-out
|
||||
@@ -618,6 +645,10 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
outValue = aJson.getObjectItem(execObj,"@V");
|
||||
if (outValue) outValue->subtype =regType & 0xF;
|
||||
}
|
||||
|
||||
aJsonObject *polledValue = aJson.getObjectItem(execObj,"@S");
|
||||
if (polledValue && outValue->type == aJson_Int) polledValue->valueint=Value; //to pevent suppressing to change back to previously polled value if this occurs before next polling
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -663,7 +694,7 @@ else
|
||||
}
|
||||
templateParamObj=templateParamObj->next;
|
||||
}
|
||||
if (!suffixFinded) errorSerial<<F("No template for ")<<subItem<<F(" or suffix ")<<suffixCode<<endl;
|
||||
if (!suffixFinded) errorSerial<<F("MBUS: No template for ")<<subItem<<F(" or suffix ")<<suffixCode<<endl;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ bool out_pid::getConfig()
|
||||
double kI=0.0;
|
||||
double kD=0.0;
|
||||
int direction = DIRECT;
|
||||
bool limits = false;
|
||||
|
||||
// Retrieve and store
|
||||
if (!store || !item || !item->itemArg || (item->itemArg->type != aJson_Array) || aJson.getArraySize(item->itemArg)<1)
|
||||
@@ -28,8 +29,8 @@ bool out_pid::getConfig()
|
||||
errorSerial<<F("Invalid PID param array.")<<endl;
|
||||
return false;
|
||||
}
|
||||
double outMin=0.; //UNUSED
|
||||
double outMax=255.;//UNUSED
|
||||
double outMin=0.;
|
||||
double outMax=255.;
|
||||
float dT=5.;
|
||||
uint32_t alarmTO=PERIOD_THERMOSTAT_FAILED;
|
||||
|
||||
@@ -37,13 +38,13 @@ bool out_pid::getConfig()
|
||||
switch (aJson.getArraySize(kPIDObj))
|
||||
{ case 8: //kP,kI,kD,dT, alarmTO, alarmVal, outMin, outMax
|
||||
param = aJson.getArrayItem(kPIDObj, 7);
|
||||
if (param->type == aJson_Float) outMax=param->valuefloat;
|
||||
else if (param->type == aJson_Int) outMax=param->valueint;
|
||||
if (param->type == aJson_Float) {outMax=param->valuefloat;limits=true;}
|
||||
else if (param->type == aJson_Int) {outMax=param->valueint;limits=true;}
|
||||
|
||||
case 7: //kP,kI,kD,dT alarmTO, alarmVal, outMin
|
||||
param = aJson.getArrayItem(kPIDObj, 6);
|
||||
if (param->type == aJson_Float) outMin=param->valuefloat;
|
||||
else if (param->type == aJson_Int) outMin=param->valueint;
|
||||
if (param->type == aJson_Float) {outMin=param->valuefloat;limits=true;}
|
||||
else if (param->type == aJson_Int) {outMin=param->valueint;limits=true;}
|
||||
|
||||
case 6: //kP,kI,kD,dT, alarmTO, alarmVal
|
||||
case 5: //kP,kI,kD,dT, alarmTO
|
||||
@@ -99,7 +100,7 @@ bool out_pid::getConfig()
|
||||
{store->pid= new PID (&store->input, &store->output, &store->setpoint, kP, kI, kD, direction);
|
||||
if (!store->pid) return false;
|
||||
store->pid->SetMode(AUTOMATIC);
|
||||
//store->pid->SetOutputLimits(outMin,outMax);
|
||||
if (limits) store->pid->SetOutputLimits(outMin,outMax);
|
||||
store->pid->SetSampleTime(dT*1000.0);
|
||||
return true;}
|
||||
else errorSerial<<F("PID already initialized")<<endl;
|
||||
@@ -213,16 +214,17 @@ int out_pid::getAlarmVal()
|
||||
aJsonObject * param;
|
||||
switch (aJson.getArraySize(kPIDObj))
|
||||
{
|
||||
case 7: //kP,kI,kD, alarmTO, alarmVal, outMin, outMax
|
||||
case 6: //kP,kI,kD, alarmTO, alarmVal, outMin
|
||||
case 5: //kP,kI,kD, alarmTO, alarmVal
|
||||
param = aJson.getArrayItem(kPIDObj, 4);
|
||||
case 8: //kP,kI,kD,dT, alarmTO, alarmVal, outMin, outMax
|
||||
case 7: //kP,kI,kD,dT, alarmTO, alarmVal, outMin
|
||||
case 6: //kP,kI,kD,dT,alarmTO, alarmVal
|
||||
param = aJson.getArrayItem(kPIDObj, 5);
|
||||
alarmValDefined=true;
|
||||
if (param->type == aJson_Float) outAlarm=param->valuefloat;
|
||||
else if (param->type == aJson_Int) outAlarm=param->valueint;
|
||||
else alarmValDefined=false;
|
||||
|
||||
case 4: //kP,kI,kD, alarmTO
|
||||
case 5: //kP,kI,kD,dT, alarmTO
|
||||
case 4: //kP,kI,kD,dT
|
||||
case 3: //kP,kI,kD
|
||||
case 2: //kP,kI
|
||||
case 1: //kP
|
||||
@@ -234,7 +236,7 @@ int out_pid::getAlarmVal()
|
||||
{
|
||||
if (!alarmValDefined) outAlarm = 0.;
|
||||
}
|
||||
else if (!alarmValDefined) outAlarm = .255;
|
||||
else if (!alarmValDefined) outAlarm = 255.;
|
||||
}
|
||||
}
|
||||
return outAlarm;
|
||||
@@ -340,11 +342,13 @@ case S_CMD:
|
||||
case CMD_ENABLE:
|
||||
item->setCmd(CMD_ENABLE);
|
||||
item->SendStatus(SEND_COMMAND);
|
||||
//executeCommand(oCmd,-1,value);
|
||||
return 1;
|
||||
|
||||
case CMD_DISABLE:
|
||||
item->setCmd(CMD_DISABLE);
|
||||
item->SendStatus(SEND_COMMAND);
|
||||
//executeCommand(oCmd,-1,value);
|
||||
return 1;
|
||||
/*
|
||||
case CMD_OFF:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#ifndef MAX_JSON_CONF_SIZE
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
#define MAX_JSON_CONF_SIZE 24000
|
||||
#define MAX_JSON_CONF_SIZE 65535
|
||||
#elif defined(ARDUINO_ARCH_AVR)
|
||||
#define MAX_JSON_CONF_SIZE 4096
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
|
||||
@@ -124,9 +124,14 @@ itemCmd getNumber(char **chan) {
|
||||
long fractnumbers = 0;
|
||||
short fractlen = 0;
|
||||
short intlen = 0;
|
||||
bool negative = false;
|
||||
|
||||
char * intptr = * chan;
|
||||
if (*intptr == '-') intptr ++;
|
||||
if (*intptr == '-')
|
||||
{
|
||||
negative=true;
|
||||
intptr ++;
|
||||
}
|
||||
while (isDigit(*(intptr+intlen))) intlen++;
|
||||
|
||||
char * fractptr = strchr(*chan,'.');
|
||||
@@ -146,7 +151,7 @@ itemCmd getNumber(char **chan) {
|
||||
else if (fractlen<=TENS_FRACT_LEN && intlen+TENS_FRACT_LEN<=9)
|
||||
{
|
||||
long intpart = atol(*chan);
|
||||
val.Tens_raw(intpart*TENS_BASE+((intpart>=0)?fractnumbers:-fractnumbers));
|
||||
val.Tens_raw(intpart*TENS_BASE+((negative)?-fractnumbers:fractnumbers));
|
||||
}
|
||||
else
|
||||
val.Float(atof(*chan));
|
||||
@@ -243,7 +248,7 @@ void parseBytes(const char *str, char separator, byte *bytes, int maxBytes, int
|
||||
}
|
||||
|
||||
|
||||
void printFloatValueToStr(float value, char *valstr) {
|
||||
void printFloatValueToStr(char *valstr, float value) {
|
||||
#if defined(ESP8266) || defined(ARDUINO_ARCH_ESP32)
|
||||
sprintf(valstr, "%2.1f", value);
|
||||
#endif
|
||||
@@ -499,6 +504,8 @@ return buf;
|
||||
|
||||
|
||||
void printUlongValueToStr(char *valstr, unsigned long value) {
|
||||
ultoa(value,valstr,10);
|
||||
/*
|
||||
char buf[11];
|
||||
int i=0;
|
||||
for(;value>0;i++){
|
||||
@@ -510,7 +517,7 @@ void printUlongValueToStr(char *valstr, unsigned long value) {
|
||||
for(int n=0;n<=i;n++){
|
||||
valstr[n]=buf[i-n-1];
|
||||
}
|
||||
valstr[i]='\0';
|
||||
valstr[i]='\0';*/
|
||||
}
|
||||
|
||||
|
||||
@@ -771,7 +778,7 @@ const serial_st serialModes_P[] PROGMEM =
|
||||
#define serialModesNum sizeof(serialModes_P)/sizeof(serial_st)
|
||||
|
||||
serialParamType str2SerialParam(char * str)
|
||||
{ debugSerial<<str<<F(" =>");
|
||||
{ //debugSerial<<str<<F(" =>");
|
||||
for(uint8_t i=0; i<serialModesNum && str;i++)
|
||||
if (strcmp_P(str, serialModes_P[i].verb) == 0)
|
||||
{
|
||||
@@ -782,7 +789,7 @@ serialParamType str2SerialParam(char * str)
|
||||
else
|
||||
return pgm_read_word_near(&serialModes_P[i].mode);
|
||||
}
|
||||
debugSerial<< F("Default serial mode N81 used");
|
||||
debugSerial<< F("Default serial mode N81 used")<<endl;
|
||||
return static_cast<serialParamType> (SERIAL_8N1);
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ itemCmd getNumber(char ** chan);
|
||||
unsigned long freeRam ();
|
||||
void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base);
|
||||
int log(const char *str, ...);
|
||||
void printFloatValueToStr(float value, char *valstr);
|
||||
void printFloatValueToStr(char *valstr, float value);
|
||||
void ReadUniqueID( uint32_t * pdwUniqueID );
|
||||
int _inet_aton(const char* aIPAddrString, IPAddress& aResult);
|
||||
char *_inet_ntoa_r(IPAddress addr, char *buf, int buflen);
|
||||
|
||||
Reference in New Issue
Block a user