Mercury electricity counter driver, refactoring

This commit is contained in:
Климов Андрей Николаевич
2023-01-29 12:33:22 +03:00
parent b06dad9395
commit 86d0d784a0
22 changed files with 736 additions and 150 deletions

View File

@@ -38,3 +38,5 @@
-DOTA_PORT=80 -DOTA_PORT=80
-D CORS=\"*\" -D CORS=\"*\"
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\" -D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
#-D MERCURY_ENABLE
#-D IPMODBUS

View File

@@ -0,0 +1,3 @@
mode com3:1200,n,8,1
pause
..\tools\win\tool-bossac\bossac.exe -i --port=com3 -U false -e -w -v -b firmware.bin -R

View File

@@ -3,7 +3,7 @@
#define CST_UNKNOWN 0 #define CST_UNKNOWN 0
#define CST_INITIALIZED 1 #define CST_INITIALIZED 1
#define CST_FAILED 2 #define CST_FAILED -1
class abstractCh { class abstractCh {
public: public:

View File

@@ -71,16 +71,16 @@ case S_CMD:
{ {
cmd.setPercents(INIT_VOLUME); cmd.setPercents(INIT_VOLUME);
cmd.saveItem(item); cmd.saveItem(item);
item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED); item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
}; };
PixelCtrl(cmd,subItem, true); PixelCtrl(cmd,subItem, true);
// item->SendStatus(SEND_COMMAND | SEND_PARAMETERS ); // item->SendStatus(FLAG_COMMAND | FLAG_PARAMETERS );
return 1; return 1;
case CMD_OFF: case CMD_OFF:
cmd.param.asInt32=0; cmd.param.asInt32=0;
PixelCtrl(cmd, subItem, true); PixelCtrl(cmd, subItem, true);
// item->SendStatus(SEND_COMMAND); // item->SendStatus(FLAG_COMMAND);
return 1; return 1;
default: default:

View File

@@ -1023,7 +1023,7 @@ void Input::onAnalogChanged(itemCmd newValue) {
strncpy(addrstr,emit->valuestring,sizeof(addrstr)); strncpy(addrstr,emit->valuestring,sizeof(addrstr));
if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring); if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring);
char strVal[16]; char strVal[16];
newValue.toString(strVal,sizeof(strVal),SEND_PARAMETERS); newValue.toString(strVal,sizeof(strVal),FLAG_PARAMETERS);
if (mqttClient.connected() && !ethernetIdleCount) if (mqttClient.connected() && !ethernetIdleCount)
mqttClient.publish(addrstr, strVal, true); mqttClient.publish(addrstr, strVal, true);

View File

@@ -53,6 +53,10 @@ e-mail anklimov@gmail.com
#include "modules/out_relay.h" #include "modules/out_relay.h"
#include "modules/out_counter.h" #include "modules/out_counter.h"
#ifdef MERCURY_ENABLE
#include "modules/out_mercury.h"
#endif
#ifdef ELEVATOR_ENABLE #ifdef ELEVATOR_ENABLE
#include "modules/out_elevator.h" #include "modules/out_elevator.h"
#endif #endif
@@ -218,6 +222,12 @@ void Item::Parse() {
break; break;
#endif #endif
#ifdef MERCURY_ENABLE
case CH_MERCURY:
driver = new out_Mercury (this);
break;
#endif
#ifndef COUNTER_DISABLE #ifndef COUNTER_DISABLE
case CH_COUNTER: case CH_COUNTER:
driver = new out_counter (this); driver = new out_counter (this);
@@ -238,8 +248,8 @@ if (driver)
if (driver->Status()) driver->Stop(); if (driver->Status()) driver->Stop();
if (driver->Setup()) if (driver->Setup())
{ {
if (getCmd()) setFlag(SEND_COMMAND); if (getCmd()) setFlag(FLAG_COMMAND);
if (itemVal) setFlag(SEND_PARAMETERS); if (itemVal) setFlag(FLAG_PARAMETERS);
} }
return true; return true;
} }
@@ -306,12 +316,12 @@ void Item::setCmd(uint8_t cmdValue) {
if (itemCmd && (itemCmd->type == aJson_Int || itemCmd->type == aJson_NULL)) if (itemCmd && (itemCmd->type == aJson_Int || itemCmd->type == aJson_NULL))
{ {
itemCmd->type = aJson_Int; itemCmd->type = aJson_Int;
itemCmd->valueint = cmdValue & CMD_MASK | itemCmd->valueint & FLAG_MASK; // Preserve special bits itemCmd->valueint = cmdValue & CMD_MASK | itemCmd->valueint & (FLAG_MASK); // Preserve special bits
debugSerial<<F("SetCmd:")<<cmdValue<<endl; debugSerial<<F("SetCmd:")<<cmdValue<<endl;
} }
} }
short Item::getFlag (short flag) uint32_t Item::getFlag (uint32_t flag)
{ {
aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD); aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD);
if (itemCmd && (itemCmd->type == aJson_Int)) if (itemCmd && (itemCmd->type == aJson_Int))
@@ -321,7 +331,7 @@ short Item::getFlag (short flag)
return 0; return 0;
} }
void Item::setFlag (short flag) void Item::setFlag (uint32_t flag)
{ {
aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD); aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD);
if (itemCmd && (itemCmd->type == aJson_Int || itemCmd->type == aJson_NULL)) if (itemCmd && (itemCmd->type == aJson_Int || itemCmd->type == aJson_NULL))
@@ -333,7 +343,7 @@ void Item::setFlag (short flag)
} }
void Item::clearFlag (short flag) void Item::clearFlag (uint32_t flag)
{ {
aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD); aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD);
if (itemCmd && (itemCmd->type == aJson_Int || itemCmd->type == aJson_NULL)) if (itemCmd && (itemCmd->type == aJson_Int || itemCmd->type == aJson_NULL))
@@ -344,6 +354,7 @@ void Item::clearFlag (short flag)
} }
int Item::getArg(short n) //Return arg int or first array element if Arg is array int Item::getArg(short n) //Return arg int or first array element if Arg is array
{ {
if (!itemArg) return 0;//-1; if (!itemArg) return 0;//-1;
@@ -820,8 +831,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
scale100=true; //openHab topic format scale100=true; //openHab topic format
chActive=(isActive()>0); chActive=(isActive()>0);
debugSerial<<chActive<<" "<<cmd.getInt()<<endl; debugSerial<<chActive<<" "<<cmd.getInt()<<endl;
if (chActive>0 && !cmd.getInt()) {cmd.Cmd(CMD_OFF);status2Send |= SEND_COMMAND | SEND_IMMEDIATE;} if (chActive>0 && !cmd.getInt()) {cmd.Cmd(CMD_OFF);status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;}
if (chActive==0 && cmd.getInt()) {cmd.Cmd(CMD_ON);status2Send |= SEND_COMMAND | SEND_IMMEDIATE;} if (chActive==0 && cmd.getInt()) {cmd.Cmd(CMD_ON);status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;}
// continue processing as SET // continue processing as SET
case S_SET: case S_SET:
@@ -840,7 +851,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
if ((scale100 || SCALE_VOLUME_100) && (cmd.getArgType()==ST_HSV255 || cmd.getArgType()==ST_PERCENTS255 || cmd.getArgType()==ST_INT32 || cmd.getArgType()==ST_UINT32)) if ((scale100 || SCALE_VOLUME_100) && (cmd.getArgType()==ST_HSV255 || cmd.getArgType()==ST_PERCENTS255 || cmd.getArgType()==ST_INT32 || cmd.getArgType()==ST_UINT32))
stored.scale100(); stored.scale100();
cmd=stored; cmd=stored;
status2Send |= SEND_PARAMETERS | SEND_DEFFERED; status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
break; break;
case S_VAL: case S_VAL:
@@ -852,7 +863,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
{ {
cmd=stored; cmd=stored;
cmd.setSuffix(S_SET); cmd.setSuffix(S_SET);
status2Send |= SEND_PARAMETERS | SEND_DEFFERED; status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
} else invalidArgument=true; } else invalidArgument=true;
break; break;
@@ -862,14 +873,14 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
{ {
cmd=stored; cmd=stored;
cmd.setSuffix(S_SET); cmd.setSuffix(S_SET);
status2Send |= SEND_PARAMETERS | SEND_DEFFERED; status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
} else invalidArgument=true; } else invalidArgument=true;
break; break;
case S_TEMP: case S_TEMP:
stored.loadItemDef(this); stored.loadItemDef(this);
stored.setColorTemp(cmd.getColorTemp()); stored.setColorTemp(cmd.getColorTemp());
cmd=stored; cmd=stored;
status2Send |= SEND_PARAMETERS | SEND_DEFFERED; status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
} }
} }
@@ -884,7 +895,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
// cmd.loadItemDef(this); /// // cmd.loadItemDef(this); ///
cmd.Cmd(CMD_ON); cmd.Cmd(CMD_ON);
} }
status2Send |=SEND_COMMAND | SEND_IMMEDIATE; status2Send |=FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
break; break;
@@ -911,7 +922,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
//if (limit && suffixCode==S_NOTFOUND) limit = 100; //if (limit && suffixCode==S_NOTFOUND) limit = 100;
if (cmd.incrementPercents(step,limit)) if (cmd.incrementPercents(step,limit))
{ {
status2Send |= SEND_PARAMETERS | SEND_DEFFERED; status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
} else {cmd=fallbackCmd;invalidArgument=true;} } else {cmd=fallbackCmd;invalidArgument=true;}
} }
break; break;
@@ -919,14 +930,14 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
case S_HUE: case S_HUE:
if (cmd.incrementH(step)) if (cmd.incrementH(step))
{ {
status2Send |= SEND_PARAMETERS | SEND_DEFFERED; status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
cmd.setSuffix(S_SET); cmd.setSuffix(S_SET);
} else {cmd=fallbackCmd;invalidArgument=true;} } else {cmd=fallbackCmd;invalidArgument=true;}
break; break;
case S_SAT: case S_SAT:
if (cmd.incrementS(step)) if (cmd.incrementS(step))
{ {
status2Send |= SEND_PARAMETERS | SEND_DEFFERED; status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
cmd.setSuffix(S_SET); cmd.setSuffix(S_SET);
} else {cmd=fallbackCmd;invalidArgument=true;} } else {cmd=fallbackCmd;invalidArgument=true;}
} //switch suffix } //switch suffix
@@ -957,19 +968,19 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
debugSerial << F("Restored from:") << t << endl; debugSerial << F("Restored from:") << t << endl;
cmd.loadItemDef(this); cmd.loadItemDef(this);
cmd.Cmd(CMD_ON); //turning on cmd.Cmd(CMD_ON); //turning on
status2Send |= SEND_COMMAND | SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
break; break;
default: default:
return 3; return 3;
} }
status2Send |= SEND_COMMAND; status2Send |= FLAG_COMMAND;
break; break;
case CMD_XOFF: // individual for group members case CMD_XOFF: // individual for group members
switch (t = getCmd()) { switch (t = getCmd()) {
case CMD_XON: //previous command was CMD_XON ? case CMD_XON: //previous command was CMD_XON ?
debugSerial << F("Turned off from:") << t << endl; debugSerial << F("Turned off from:") << t << endl;
cmd.Cmd(CMD_OFF); //turning Off cmd.Cmd(CMD_OFF); //turning Off
status2Send |= SEND_COMMAND | SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
break; break;
default: default:
debugSerial << F("XOFF skipped. Prev cmd:") << t <<endl; debugSerial << F("XOFF skipped. Prev cmd:") << t <<endl;
@@ -984,7 +995,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
cmd.loadItemDef(this); cmd.loadItemDef(this);
cmd.Cmd(CMD_ON); cmd.Cmd(CMD_ON);
command2Set=CMD_XON; command2Set=CMD_XON;
status2Send |= SEND_COMMAND | SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
} }
else else
{ {
@@ -998,7 +1009,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
{ {
cmd.Cmd(CMD_OFF); cmd.Cmd(CMD_OFF);
command2Set=CMD_HALT; command2Set=CMD_HALT;
status2Send |= SEND_COMMAND | SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
} }
else else
{ {
@@ -1008,9 +1019,9 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
break; break;
} }
status2Send |= SEND_IMMEDIATE; status2Send |= FLAG_SEND_IMMEDIATE;
if (cmd.isChannelCommand()) status2Send |= SEND_COMMAND; if (cmd.isChannelCommand()) status2Send |= FLAG_COMMAND;
if (cmd.isValue() || cmd.loadItem(this,SEND_PARAMETERS)) status2Send |= SEND_PARAMETERS; ; if (cmd.isValue() || cmd.loadItem(this,FLAG_PARAMETERS)) status2Send |= FLAG_PARAMETERS; ;
} // end GROUP } // end GROUP
else else
@@ -1053,12 +1064,12 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
toExecute=true; toExecute=true;
if (itemType == CH_THERMO) cmd.Cmd(CMD_AUTO); //// if (itemType == CH_THERMO) cmd.Cmd(CMD_AUTO); ////
else cmd.Cmd(CMD_ON); //turning on else cmd.Cmd(CMD_ON); //turning on
status2Send |= SEND_COMMAND | SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
break; break;
default: default:
return 3; return 3;
} }
status2Send |= SEND_COMMAND; status2Send |= FLAG_COMMAND;
break; break;
case CMD_XOFF: // individual for group members case CMD_XOFF: // individual for group members
switch (t = getCmd()) { switch (t = getCmd()) {
@@ -1066,7 +1077,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
debugSerial << F("Turned off from:") << t << endl; debugSerial << F("Turned off from:") << t << endl;
toExecute=true; toExecute=true;
cmd.Cmd(CMD_OFF); //turning Off cmd.Cmd(CMD_OFF); //turning Off
status2Send |= SEND_COMMAND | SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
break; break;
default: default:
debugSerial << F("XOFF skipped. Prev cmd:") << t <<endl; debugSerial << F("XOFF skipped. Prev cmd:") << t <<endl;
@@ -1080,7 +1091,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
cmd.loadItemDef(this); cmd.loadItemDef(this);
cmd.Cmd(CMD_ON); cmd.Cmd(CMD_ON);
command2Set=CMD_XON; command2Set=CMD_XON;
status2Send |= SEND_COMMAND | SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
toExecute=true; toExecute=true;
} }
else else
@@ -1094,7 +1105,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
{ {
cmd.Cmd(CMD_OFF); cmd.Cmd(CMD_OFF);
command2Set=CMD_HALT; command2Set=CMD_HALT;
status2Send |= SEND_COMMAND | SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
toExecute=true; toExecute=true;
} }
else else
@@ -1112,7 +1123,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
} }
if (getCmd() == CMD_HALT) return 3; //Halted, ignore OFF if (getCmd() == CMD_HALT) return 3; //Halted, ignore OFF
status2Send |= SEND_COMMAND | SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
toExecute=true; toExecute=true;
break; break;
@@ -1126,7 +1137,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
{ {
debugSerial<<F("ON:Already Active\n"); debugSerial<<F("ON:Already Active\n");
setCmd(CMD_ON); setCmd(CMD_ON);
SendStatus(SEND_COMMAND | SEND_DEFFERED); SendStatus(FLAG_COMMAND | FLAG_SEND_DEFFERED);
return 3; return 3;
} }
@@ -1143,7 +1154,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
} }
if (!cmd.isValue()) cmd.loadItemDef(this); // if no_suffix - both, command ON and value provided if (!cmd.isValue()) cmd.loadItemDef(this); // if no_suffix - both, command ON and value provided
status2Send |= SEND_COMMAND | SEND_PARAMETERS | SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_PARAMETERS | FLAG_SEND_IMMEDIATE;
toExecute=true; toExecute=true;
break; break;
case CMD_VOID: case CMD_VOID:
@@ -1153,8 +1164,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
break; break;
default: default:
if (cmd.isCommand()) status2Send |= SEND_COMMAND; if (cmd.isCommand()) status2Send |= FLAG_COMMAND;
if (cmd.isValue()) status2Send |= SEND_PARAMETERS; if (cmd.isValue()) status2Send |= FLAG_PARAMETERS;
toExecute=true; toExecute=true;
} //Switch commands } //Switch commands
} // NO GROUP } // NO GROUP
@@ -1166,7 +1177,7 @@ if (status2Send) cmd.saveItem(this,status2Send);
if (driver) //New style modular code if (driver) //New style modular code
{ {
res = driver->Ctrl(cmd, subItem, toExecute); res = driver->Ctrl(cmd, subItem, toExecute);
if (driver->getChanType() == CH_THERMO) status2Send |= SEND_IMMEDIATE; if (driver->getChanType() == CH_THERMO) status2Send |= FLAG_SEND_IMMEDIATE;
//if (res==-1) status2Send=0; ///////not working //if (res==-1) status2Send=0; ///////not working
} }
else else
@@ -1196,7 +1207,7 @@ switch (itemType) {
else else
digitalWrite(iaddr, k = ((icmd == CMD_ON || icmd == CMD_AUTO) ? HIGH : LOW)); digitalWrite(iaddr, k = ((icmd == CMD_ON || icmd == CMD_AUTO) ? HIGH : LOW));
debugSerial<<F("Pin:")<<iaddr<<F("=")<<k<<endl; debugSerial<<F("Pin:")<<iaddr<<F("=")<<k<<endl;
status2Send |= SEND_COMMAND | SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
res=1; res=1;
} }
} }
@@ -1220,12 +1231,12 @@ switch (itemType) {
} }
break; break;
case S_SET: case S_SET:
status2Send |= SEND_PARAMETERS | SEND_IMMEDIATE; status2Send |= FLAG_PARAMETERS | FLAG_SEND_IMMEDIATE;
res=1; res=1;
//st.saveItem(this); //st.saveItem(this);
break; break;
case S_CMD: case S_CMD:
status2Send |= SEND_COMMAND | SEND_IMMEDIATE; status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
res=1; res=1;
} }
break; break;
@@ -1239,7 +1250,7 @@ switch (itemType) {
if (!chActive && cmd.getCmd()== CMD_ON && (vol=cmd.getPercents())<MIN_VOLUME && vol>=0) if (!chActive && cmd.getCmd()== CMD_ON && (vol=cmd.getPercents())<MIN_VOLUME && vol>=0)
{ {
cmd.setPercents(INIT_VOLUME); cmd.setPercents(INIT_VOLUME);
status2Send |= SEND_PARAMETERS | SEND_IMMEDIATE; status2Send |= FLAG_PARAMETERS | FLAG_SEND_IMMEDIATE;
}; };
res=modbusDimmerSet(cmd); res=modbusDimmerSet(cmd);
@@ -1258,7 +1269,7 @@ switch (itemType) {
} //else (nodriver) } //else (nodriver)
//update command for HALT & XON and send MQTT status //update command for HALT & XON and send MQTT status
if (command2Set) setCmd(command2Set | SEND_COMMAND); if (command2Set) setCmd(command2Set | FLAG_COMMAND);
if (operation) SendStatus(status2Send); if (operation) SendStatus(status2Send);
debugSerial<<F("Ctrl Res:")<<res<<F(" time:")<<millis()-time<<endl; debugSerial<<F("Ctrl Res:")<<res<<F(" time:")<<millis()-time<<endl;
@@ -1362,13 +1373,13 @@ if (timestampObj)
//if (!(remain % 1000)) //if (!(remain % 1000))
if (cause == POLLING_1S) if (cause == POLLING_1S)
{ {
SendStatusImmediate(st,SEND_DELAYED); SendStatusImmediate(st,FLAG_SEND_DELAYED);
debugSerial<< remain/1000 << F(" sec remaining") << endl; debugSerial<< remain/1000 << F(" sec remaining") << endl;
} }
if (remain <0 && abs(remain)< 0xFFFFFFFFUL/2) if (remain <0 && abs(remain)< 0xFFFFFFFFUL/2)
{ {
SendStatusImmediate(st,SEND_DELAYED); SendStatusImmediate(st,FLAG_SEND_DELAYED);
Ctrl(itemCmd(ST_VOID,cmd)); Ctrl(itemCmd(ST_VOID,cmd));
timestampObj->subtype=0; timestampObj->subtype=0;
} }
@@ -1406,28 +1417,28 @@ switch (cause)
} }
void Item::sendDelayedStatus() void Item::sendDelayedStatus()
{ long int flags = getFlag(SEND_COMMAND | SEND_PARAMETERS); { long int flags = getFlag(FLAG_COMMAND | FLAG_PARAMETERS);
if (flags && lanStatus==OPERATION) if (flags && lanStatus==OPERATION)
{ {
SendStatus(flags);//(SEND_COMMAND | SEND_PARAMETERS); SendStatus(flags);//(FLAG_COMMAND | FLAG_PARAMETERS);
clearFlag(SEND_COMMAND | SEND_PARAMETERS); clearFlag(FLAG_COMMAND | FLAG_PARAMETERS);
} }
} }
int Item::SendStatus(int sendFlags) { int Item::SendStatus(int sendFlags) {
if (sendFlags & SEND_IMMEDIATE) sendFlags &= ~ (SEND_IMMEDIATE | SEND_DEFFERED); if (sendFlags & FLAG_SEND_IMMEDIATE) sendFlags &= ~ (FLAG_SEND_IMMEDIATE | FLAG_SEND_DEFFERED);
if ((sendFlags & SEND_DEFFERED) || freeRam()<150 || (!isNotRetainingStatus() )) { if ((sendFlags & FLAG_SEND_DEFFERED) || freeRam()<150 || (!isNotRetainingStatus() )) {
setFlag(sendFlags & (SEND_COMMAND | SEND_PARAMETERS)); setFlag(sendFlags & (FLAG_COMMAND | FLAG_PARAMETERS));
debugSerial<<F("Status deffered\n"); debugSerial<<F("Status deffered\n");
return -1; return -1;
} }
else else
{ {
itemCmd st(ST_VOID,CMD_VOID); itemCmd st(ST_VOID,CMD_VOID);
st.loadItem(this, SEND_COMMAND | SEND_PARAMETERS); st.loadItem(this, FLAG_COMMAND | FLAG_PARAMETERS);
sendFlags |= getFlag(SEND_COMMAND | SEND_PARAMETERS); //if some delayed status is pending sendFlags |= getFlag(FLAG_COMMAND | FLAG_PARAMETERS); //if some delayed status is pending
//debugSerial<<F("ssi:")<<sendFlags<<endl; //debugSerial<<F("ssi:")<<sendFlags<<endl;
return SendStatusImmediate(st,sendFlags); return SendStatusImmediate(st,sendFlags);
} }
@@ -1440,7 +1451,7 @@ int Item::SendStatus(int sendFlags) {
char cmdstr[9] = ""; char cmdstr[9] = "";
//debugSerial<<"SSI "<<subItem<<endl; //debugSerial<<"SSI "<<subItem<<endl;
st.debugOut(); st.debugOut();
if (sendFlags & SEND_COMMAND) if (sendFlags & FLAG_COMMAND)
{ {
// Preparing legacy Command payload ////////////// // Preparing legacy Command payload //////////////
switch (st.getCmd()) { switch (st.getCmd()) {
@@ -1461,12 +1472,12 @@ int Item::SendStatus(int sendFlags) {
break; break;
case CMD_VOID: case CMD_VOID:
case CMD_RGB: case CMD_RGB:
sendFlags &= ~SEND_COMMAND; // Not send command for parametrized req sendFlags &= ~FLAG_COMMAND; // Not send command for parametrized req
break; break;
default: default:
debugSerial<<F("Unknown cmd \n"); debugSerial<<F("Unknown cmd \n");
sendFlags &= ~SEND_COMMAND; sendFlags &= ~FLAG_COMMAND;
} }
} }
@@ -1482,15 +1493,15 @@ int Item::SendStatus(int sendFlags) {
strncat(addrstr, itemArr->name, sizeof(addrstr)-1); strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
if (sendFlags & SEND_PARAMETERS && st.getCmd() != CMD_OFF && st.getCmd() != CMD_HALT && if (sendFlags & FLAG_PARAMETERS && st.getCmd() != CMD_OFF && st.getCmd() != CMD_HALT &&
// send only for OH bus supported types // send only for OH bus supported types
(st.getArgType() == ST_PERCENTS255 || st.getArgType() == ST_HSV255 || st.getArgType() == ST_FLOAT_CELSIUS)) (st.getArgType() == ST_PERCENTS255 || st.getArgType() == ST_HSV255 || st.getArgType() == ST_FLOAT_CELSIUS))
{ {
st.toString(valstr, sizeof(valstr), SEND_PARAMETERS,true); st.toString(valstr, sizeof(valstr), FLAG_PARAMETERS,true);
mqttClient.publish(addrstr, valstr, true); mqttClient.publish(addrstr, valstr, true);
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<valstr<<endl; debugSerial<<F("Pub: ")<<addrstr<<F("->")<<valstr<<endl;
} }
else if (sendFlags & SEND_COMMAND) else if (sendFlags & FLAG_COMMAND)
{ {
mqttClient.publish(addrstr, cmdstr, true); mqttClient.publish(addrstr, cmdstr, true);
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<cmdstr<<endl; debugSerial<<F("Pub: ")<<addrstr<<F("->")<<cmdstr<<endl;
@@ -1509,7 +1520,7 @@ int Item::SendStatus(int sendFlags) {
// myhome/s_out/item/cmd // myhome/s_out/item/cmd
// myhome/s_out/item/set // myhome/s_out/item/set
if ((st.isValue() && (sendFlags & SEND_PARAMETERS) || (sendFlags & SEND_DELAYED))) if ((st.isValue() && (sendFlags & FLAG_PARAMETERS) || (sendFlags & FLAG_SEND_DELAYED)))
{ {
setTopic(addrstr,sizeof(addrstr),T_OUT); setTopic(addrstr,sizeof(addrstr),T_OUT);
strncat(addrstr, itemArr->name, sizeof(addrstr)-1); strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
@@ -1521,7 +1532,7 @@ int Item::SendStatus(int sendFlags) {
strncat(addrstr, "/", sizeof(addrstr)-1); strncat(addrstr, "/", sizeof(addrstr)-1);
if (sendFlags & SEND_DELAYED) if (sendFlags & FLAG_SEND_DELAYED)
strncat_P(addrstr, DEL_P, sizeof(addrstr)-1); strncat_P(addrstr, DEL_P, sizeof(addrstr)-1);
else strncat_P(addrstr, SET_P, sizeof(addrstr)-1); else strncat_P(addrstr, SET_P, sizeof(addrstr)-1);
@@ -1531,10 +1542,10 @@ int Item::SendStatus(int sendFlags) {
case ST_RGBW: case ST_RGBW:
//valstr[0]='#'; //valstr[0]='#';
st.Cmd(CMD_RGB); st.Cmd(CMD_RGB);
st.toString(valstr, sizeof(valstr), SEND_PARAMETERS|SEND_COMMAND); st.toString(valstr, sizeof(valstr), FLAG_PARAMETERS|FLAG_COMMAND);
break; break;
default: default:
st.toString(valstr, sizeof(valstr), (sendFlags & SEND_DELAYED)?SEND_COMMAND|SEND_PARAMETERS:SEND_PARAMETERS,(SCALE_VOLUME_100)); st.toString(valstr, sizeof(valstr), (sendFlags & FLAG_SEND_DELAYED)?FLAG_COMMAND|FLAG_PARAMETERS:FLAG_PARAMETERS,(SCALE_VOLUME_100));
} }
@@ -1544,7 +1555,7 @@ int Item::SendStatus(int sendFlags) {
if (mqttClient.connected() && !ethernetIdleCount) if (mqttClient.connected() && !ethernetIdleCount)
{ {
mqttClient.publish(addrstr, valstr,true); mqttClient.publish(addrstr, valstr,true);
clearFlag(SEND_PARAMETERS); clearFlag(FLAG_PARAMETERS);
} }
else else
{ {
@@ -1554,7 +1565,7 @@ int Item::SendStatus(int sendFlags) {
} }
if (sendFlags & SEND_COMMAND) if (sendFlags & FLAG_COMMAND)
{ {
// Some additional preparing for extended set of commands: // Some additional preparing for extended set of commands:
switch (st.getCmd()) { switch (st.getCmd()) {
@@ -1598,7 +1609,7 @@ int Item::SendStatus(int sendFlags) {
if (mqttClient.connected() && !ethernetIdleCount) if (mqttClient.connected() && !ethernetIdleCount)
{ {
mqttClient.publish(addrstr, cmdstr,true); mqttClient.publish(addrstr, cmdstr,true);
clearFlag(SEND_COMMAND); clearFlag(FLAG_COMMAND);
} }
else else
{ {
@@ -1617,10 +1628,10 @@ return itemType;
} }
// Setup SEND_RETRY flag to repeat unsucsessfull modbus tranzaction after release line // Setup FLAG_SEND_RETRY flag to repeat unsucsessfull modbus tranzaction after release line
void Item::mb_fail(int result) { void Item::mb_fail(int result) {
debugSerial<<F("Modbus op failed:")<<_HEX(result)<<endl; debugSerial<<F("Modbus op failed:")<<_HEX(result)<<endl;
setFlag(SEND_RETRY); setFlag(FLAG_SEND_RETRY);
isPendedModbusWrites=true; isPendedModbusWrites=true;
} }
@@ -1639,11 +1650,11 @@ void Item::mb_fail(int result) {
int Item::checkModbusRetry() { int Item::checkModbusRetry() {
int result = -1; int result = -1;
if (modbusBusy) return M_BUSY; if (modbusBusy) return M_BUSY;
if (getFlag(SEND_RETRY)) { // if last sending attempt of command was failed if (getFlag(FLAG_SEND_RETRY)) { // if last sending attempt of command was failed
itemCmd val(ST_VOID,CMD_VOID); itemCmd val(ST_VOID,CMD_VOID);
val.loadItem(this, SEND_COMMAND | SEND_PARAMETERS); val.loadItem(this, FLAG_COMMAND | FLAG_PARAMETERS);
debugSerial<<F("Retrying modbus CMD\n"); debugSerial<<F("Retrying modbus CMD\n");
clearFlag(SEND_RETRY); // Clean retry flag clearFlag(FLAG_SEND_RETRY); // Clean retry flag
if (driver) result=driver->Ctrl(val); if (driver) result=driver->Ctrl(val);
#ifndef MODBUS_DISABLE #ifndef MODBUS_DISABLE
else switch (itemType) else switch (itemType)
@@ -1802,7 +1813,7 @@ int Item::VacomSetFan(itemCmd st) {
if (modbusBusy) { if (modbusBusy) {
// setCmd(cmd); // setCmd(cmd);
// setVal(val); // setVal(val);
st.saveItem(this,SEND_PARAMETERS|SEND_COMMAND); st.saveItem(this,FLAG_PARAMETERS|FLAG_COMMAND);
mb_fail(); mb_fail();
return 0; return 0;
} }
@@ -1849,7 +1860,7 @@ int addr;
if (modbusBusy) { if (modbusBusy) {
//setCmd(cmd); //setCmd(cmd);
//setVal(val); //setVal(val);
st.saveItem(this,SEND_COMMAND|SEND_PARAMETERS); st.saveItem(this,FLAG_COMMAND|FLAG_PARAMETERS);
mb_fail(); mb_fail();
return 0; return 0;
} }
@@ -2144,14 +2155,14 @@ int Item::checkModbusDimmer(int data) {
if (d) { // Actually turned on if (d) { // Actually turned on
if (cmd != CMD_XON && cmd != CMD_ON) setCmd(CMD_ON); //store command if (cmd != CMD_XON && cmd != CMD_ON) setCmd(CMD_ON); //store command
st.Percents255(d); st.Percents255(d);
st.saveItem(this,SEND_PARAMETERS); st.saveItem(this,FLAG_PARAMETERS);
//setVal(d); //store value //setVal(d); //store value
if (cmd == CMD_OFF || cmd == CMD_HALT) SendStatus(SEND_COMMAND); //update OH with ON if it was turned off before if (cmd == CMD_OFF || cmd == CMD_HALT) SendStatus(FLAG_COMMAND); //update OH with ON if it was turned off before
SendStatus(SEND_PARAMETERS); //update OH with value SendStatus(FLAG_PARAMETERS); //update OH with value
} else { } else {
if (cmd != CMD_HALT && cmd != CMD_OFF) { if (cmd != CMD_HALT && cmd != CMD_OFF) {
setCmd(CMD_OFF); // store command (not value) setCmd(CMD_OFF); // store command (not value)
SendStatus(SEND_COMMAND);// update OH SendStatus(FLAG_COMMAND);// update OH
} }
} }
} //if data changed } //if data changed

View File

@@ -59,6 +59,7 @@ e-mail anklimov@gmail.com
#define CH_ELEVATOR 19 #define CH_ELEVATOR 19
#define CH_COUNTER 20 #define CH_COUNTER 20
#define CH_HUMIDIFIER 21 #define CH_HUMIDIFIER 21
#define CH_MERCURY 22
//#define CHANNEL_TYPES 13 //#define CHANNEL_TYPES 13
@@ -131,9 +132,9 @@ class Item
chPersistent * getPersistent(); chPersistent * getPersistent();
chPersistent * setPersistent(chPersistent * par); chPersistent * setPersistent(chPersistent * par);
void setCmd(uint8_t cmdValue); void setCmd(uint8_t cmdValue);
short getFlag (short flag=FLAG_MASK); uint32_t getFlag (uint32_t flag=FLAG_MASK);
void setFlag (short flag); void setFlag (uint32_t flag);
void clearFlag (short flag); void clearFlag (uint32_t flag);
void setVal(long int par); void setVal(long int par);
void setFloatVal(float par); void setFloatVal(float par);
void setSubtype(uint8_t par); void setSubtype(uint8_t par);

View File

@@ -1047,18 +1047,18 @@ bool itemCmd::loadItem(Item * item, uint16_t optionsFlag)
if (item && item->isValid()) if (item && item->isValid())
{ {
short subtype =item->getSubtype(); short subtype =item->getSubtype();
if (optionsFlag & SEND_COMMAND) cmd.cmdCode = item->getCmd(); if (optionsFlag & FLAG_COMMAND) cmd.cmdCode = item->getCmd();
if (subtype) if (subtype)
{ {
cmd.itemArgType= subtype; cmd.itemArgType= subtype;
if (optionsFlag & SEND_PARAMETERS) param.asInt32 = item->itemVal->valueint; if (optionsFlag & FLAG_PARAMETERS) param.asInt32 = item->itemVal->valueint;
//debugSerial<<F("Loaded :"); //debugSerial<<F("Loaded :");
//debugOut(); //debugOut();
return true; return true;
} }
if (optionsFlag & SEND_PARAMETERS) if (optionsFlag & FLAG_PARAMETERS)
switch (item->itemVal->type) switch (item->itemVal->type)
{ {
case aJson_Int: case aJson_Int:
@@ -1091,7 +1091,7 @@ bool itemCmd::loadItemDef(Item * item, uint16_t optionsFlag)
setDefault(); setDefault();
saveItem(item); saveItem(item);
debugOut(); debugOut();
item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED); item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
return false; return false;
} }
return true; return true;
@@ -1101,8 +1101,8 @@ bool itemCmd::saveItem(Item * item, uint16_t optionsFlag)
{ {
if (item && item->isValid()) if (item && item->isValid())
{ {
if (optionsFlag & SEND_COMMAND) item->setCmd(cmd.cmdCode); if (optionsFlag & FLAG_COMMAND) item->setCmd(cmd.cmdCode);
if (optionsFlag & SEND_PARAMETERS) if (optionsFlag & FLAG_PARAMETERS)
switch (cmd.itemArgType) switch (cmd.itemArgType)
{ {
case ST_FLOAT: case ST_FLOAT:
@@ -1312,17 +1312,17 @@ char * itemCmd::toString(char * Buffer, int bufLen, int sendFlags, bool scale100
if (!Buffer || !bufLen) return NULL; if (!Buffer || !bufLen) return NULL;
*Buffer=0; *Buffer=0;
char * argPtr=Buffer; char * argPtr=Buffer;
if (isCommand() && (sendFlags & SEND_COMMAND)) if (isCommand() && (sendFlags & FLAG_COMMAND))
{ {
int len; int len;
strncpy_P(Buffer, commands_P[cmd.cmdCode], bufLen); strncpy_P(Buffer, commands_P[cmd.cmdCode], bufLen);
if (isValue() && (sendFlags & SEND_PARAMETERS)) strncat(Buffer, " ", bufLen); if (isValue() && (sendFlags & FLAG_PARAMETERS)) strncat(Buffer, " ", bufLen);
len=strlen(Buffer); len=strlen(Buffer);
argPtr+=len; argPtr+=len;
bufLen-=len; bufLen-=len;
bufLen--; bufLen--;
} }
if (isValue() && (sendFlags & SEND_PARAMETERS)) if (isValue() && (sendFlags & FLAG_PARAMETERS))
{ {
//strncat(Buffer, " ", bufLen); //strncat(Buffer, " ", bufLen);
//bufLen--; //bufLen--;

View File

@@ -58,20 +58,27 @@ const cmdstr commands_P[] PROGMEM =
#define CMD_HSV 0x18 #define CMD_HSV 0x18
#define CMD_MASK 0xff #define CMD_MASK 0xff
#define FLAG_MASK 0xff00 #define FLAG_MASK 0xffff00
//#define STATE_MASK 0xff0000
#define CMD_VOID 0 #define CMD_VOID 0
#define CMD_UNKNOWN -1 #define CMD_UNKNOWN -1
#define CMD_JSON -2 #define CMD_JSON -2
#define SEND_IMMEDIATE 0x1 //FLAGS
#define SEND_COMMAND 0x100 #define FLAG_SEND_IMMEDIATE 0x1
#define SEND_PARAMETERS 0x200 #define FLAG_COMMAND 0x100
#define SEND_RETRY 0x400 #define FLAG_PARAMETERS 0x200
#define SEND_DEFFERED 0x800 #define FLAG_SEND_RETRY 0x400
#define SEND_DELAYED 0x1000 #define FLAG_SEND_DEFFERED 0x800
#define ACTION_NEEDED 0x2000 #define FLAG_SEND_DELAYED 0x1000
#define ACTION_IN_PROCESS 0x4000 #define FLAG_ACTION_NEEDED 0x2000
#define FLAG_ACTION_IN_PROCESS 0x4000
#define FLAG_DISABLED 0x10000
#define FLAG_DISABLED_ALL 0x20000
#define FLAG_HALTED 0x40000
#define FLAG__XON 0x80000
@@ -161,9 +168,9 @@ public:
itemCmd assignFrom(itemCmd from, short chanType=-1); itemCmd assignFrom(itemCmd from, short chanType=-1);
bool loadItem(Item * item, uint16_t optionsFlag=SEND_PARAMETERS); bool loadItem(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS);
bool loadItemDef(Item * item, uint16_t optionsFlag=SEND_PARAMETERS ); bool loadItemDef(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS );
bool saveItem(Item * item, uint16_t optionsFlag=SEND_PARAMETERS); bool saveItem(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS);
itemCmd Int(int32_t i); itemCmd Int(int32_t i);
itemCmd Int(uint32_t i); itemCmd Int(uint32_t i);
@@ -209,7 +216,7 @@ public:
uint8_t getCmd(); uint8_t getCmd();
uint8_t getArgType(); uint8_t getArgType();
uint8_t getCmdParam(); uint8_t getCmdParam();
char * toString(char * Buffer, int bufLen, int sendFlags = SEND_COMMAND | SEND_PARAMETERS, bool scale100 = false); char * toString(char * Buffer, int bufLen, int sendFlags = FLAG_COMMAND | FLAG_PARAMETERS, bool scale100 = false);
bool isCommand(); bool isCommand();
bool isChannelCommand(); bool isChannelCommand();

View File

@@ -289,7 +289,7 @@ uint16_t httpHandler(Client& client, String request, uint8_t method, long conten
if (!item.isValid() || !item.Ctrl((char*) body.c_str())) return 400; if (!item.isValid() || !item.Ctrl((char*) body.c_str())) return 400;
itemCmd ic; itemCmd ic;
ic.loadItem(&item,SEND_COMMAND|SEND_PARAMETERS); ic.loadItem(&item,FLAG_COMMAND|FLAG_PARAMETERS);
char buf[32]; char buf[32];
response=ic.toString(buf, sizeof(buf)); response=ic.toString(buf, sizeof(buf));
return 200 | HTTP_TEXT_PLAIN; return 200 | HTTP_TEXT_PLAIN;
@@ -305,7 +305,7 @@ uint16_t httpHandler(Client& client, String request, uint8_t method, long conten
{if (item.isActive()) item.setCmd(CMD_ON); else item.setCmd(CMD_OFF);} {if (item.isActive()) item.setCmd(CMD_ON); else item.setCmd(CMD_OFF);}
itemCmd ic; itemCmd ic;
ic.loadItem(&item,SEND_COMMAND|SEND_PARAMETERS); ic.loadItem(&item,FLAG_COMMAND|FLAG_PARAMETERS);
char buf[32]; char buf[32];
response=ic.toString(buf, sizeof(buf)); response=ic.toString(buf, sizeof(buf));
@@ -1392,8 +1392,8 @@ setupSyslog();
switch (it.itemType) { switch (it.itemType) {
case CH_THERMO: case CH_THERMO:
if (cmd<1) it.setCmd(CMD_OFF); if (cmd<1) it.setCmd(CMD_OFF);
it.setFlag(SEND_COMMAND); it.setFlag(FLAG_COMMAND);
if (it.itemVal) it.setFlag(SEND_PARAMETERS); if (it.itemVal) it.setFlag(FLAG_PARAMETERS);
pinMode(pin, OUTPUT); pinMode(pin, OUTPUT);
digitalWrite(pin, false); //Initially, all thermostates are LOW (OFF for electho heaters, open for water NO) digitalWrite(pin, false); //Initially, all thermostates are LOW (OFF for electho heaters, open for water NO)
debugSerial<<F("Thermo:")<<pin<<F("=LOW")<<F(";"); debugSerial<<F("Thermo:")<<pin<<F("=LOW")<<F(";");

View File

@@ -50,7 +50,7 @@ uint32_t timer = item->getExt();
item->setExt(millisNZ()); item->setExt(millisNZ());
itemCmd st; itemCmd st;
st.loadItem(item,SEND_PARAMETERS|SEND_COMMAND); st.loadItem(item,FLAG_PARAMETERS|FLAG_COMMAND);
float val = st.getFloat(); float val = st.getFloat();
//short cmd = st.getCmd(); //short cmd = st.getCmd();
debugSerial<<"CTR: tick val:"<<val<<endl; debugSerial<<"CTR: tick val:"<<val<<endl;
@@ -59,7 +59,7 @@ uint32_t timer = item->getExt();
st.Float(val); st.Float(val);
st.saveItem(item); st.saveItem(item);
debugSerial<<"CTR: tick saved val:"<<val<<endl; debugSerial<<"CTR: tick saved val:"<<val<<endl;
item->SendStatus(SEND_PARAMETERS); item->SendStatus(FLAG_PARAMETERS);
} }
return 0; return 0;

View File

@@ -0,0 +1,489 @@
//Спецификация протокола тут
//https://ftp.owen.ru/CoDeSys3/04_Library/05_3.5.11.5/02_Libraries/02_vendor_protocols/merkuriy-sistema-komand-sogl-1-2021-02-02.pdf
// Использованы фрагменты кода отсюда: https://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/arduino-mega-merkurii-2032t-rs485
#ifdef MERCURY_ENABLE
#include "modules/out_mercury.h"
#include "Arduino.h"
#include "options.h"
#include "utils.h"
#include "Streaming.h"
#include "item.h"
#include <ModbusMaster.h>
#include "main.h"
#include <HardwareSerial.h>
extern aJsonObject *modbusObj;
extern ModbusMaster node;
extern short modbusBusy;
extern void modbusIdle(void) ;
extern uint32_t mbusSlenceTimer;
bool out_Mercury::getConfig()
{
if (!store || !item || !item->itemArg || (item->itemArg->type != aJson_Array) || aJson.getArraySize(item->itemArg)<6)
{
errorSerial<<F("Mercury: config failed:")<<(bool)store<<F(",")<<(bool)item<<F(",")<<(bool)item->itemArg<<F(",")<<(item->itemArg->type != aJson_Array)<<F(",")<< (aJson.getArraySize(item->itemArg)<6)<<endl;
return false;
}
aJsonObject * delayObj=aJson.getArrayItem(item->itemArg, 5);
if (delayObj) pollingInterval = delayObj->valueint;
else pollingInterval = 10000;
return true;
}
void out_Mercury::initLine(bool full)
{
int baud;
serialParamType serialParam;
aJsonObject * serialParamObj=aJson.getArrayItem(item->itemArg, 2);
if (serialParamObj && serialParamObj->type == aJson_String) serialParam = str2SerialParam(serialParamObj->valuestring);
else serialParam = SERIAL_8N1;
aJsonObject * baudObj=aJson.getArrayItem(item->itemArg, 1);
if (baudObj && baudObj->type == aJson_Int && baudObj->valueint) baud = baudObj->valueint;
else baud = 9600;
#if defined (__SAM3X8E__)
modbusSerial.begin(baud, static_cast <USARTClass::USARTModes> (serialParam));
#elif defined (ARDUINO_ARCH_ESP8266)
modbusSerial.begin(baud, static_cast <SerialConfig>(serialParam));
#elif defined (ESP32)
if (full) modbusSerial.begin(store->baud, (serialParam),MODBUS_UART_RX_PIN,MODBUS_UART_TX_PIN);
else modbusSerial.updateBaudRate (baud); //Some terrible error in ESP32 core with uart reinit
#else
modbusSerial.begin(baud, (serialParam));
#endif
//debugSerial<<F("Mercury: ")<< baud << F(" <")<< serialParam<< F("> addr:")<<item->getArg(0)<<endl;
node.begin(item->getArg(0), modbusSerial);
}
int out_Mercury::Setup()
{
abstractOut::Setup();
if (!store) store= (mercuryPersistent *)item->setPersistent(new mercuryPersistent);
if (!store)
{ errorSerial<<F("Mercury: Out of memory")<<endl;
return 0;}
store->timestamp=millisNZ();
if (getConfig())
{
infoSerial<<F("Mercury: config loaded ")<< item->itemArr->name<<endl;
store->driverStatus = CST_INITIALIZED;
store->lastSuccessTS = 0;
initLine(true);
return 1;
}
else
{ errorSerial<<F("Mercury: config error")<<endl;
store->driverStatus = CST_FAILED;
return 0;
}
}
int out_Mercury::Stop()
{
debugSerial.println("Mercury: De-Init");
disconnectMercury();
delete store;
item->setPersistent(NULL);
store = NULL;
return 1;
}
int out_Mercury::Status()
{
if (store)
return store->driverStatus;
return CST_UNKNOWN;
}
void out_Mercury::setStatus(short status)
{
if (store) store->driverStatus=status;
}
short out_Mercury::connectMercury()
{
if (!item || !item->itemArg || modbusBusy) return RET_INTERROR;
uint8_t buffer[10];
uint8_t ret;
modbusBusy=1;
initLine();
buffer[1]=1; //Login
aJsonObject * levelObj=aJson.getArrayItem(item->itemArg, 3);
if (levelObj && levelObj->type == aJson_Int) buffer[2] = levelObj->valueint;
else errorSerial<<F("Mercury: wrong accesslevel")<<endl;
aJsonObject * passObj=aJson.getArrayItem(item->itemArg, 4);
if (passObj && passObj->type == aJson_String && (strlen (passObj->valuestring) == 6)) memcpy((char*) buffer+3,passObj->valuestring,6);
else if (passObj && passObj->type == aJson_Array && (aJson.getArraySize (passObj) == 6))
{
//debugSerial<<F("Mercury: Pass :");
for(short i=0;i<6;i++)
{
aJsonObject * digitObj=aJson.getArrayItem(passObj,i);
if (digitObj && digitObj->type==aJson_Int)
{
buffer[3+i]=digitObj->valueint;
//debugSerial<< digitObj->valueint<< F(",");
}
}
debugSerial<<endl;
}
else errorSerial<<F("Mercury: passwort must be ether String[6] or Array[6]")<<endl;
debugSerial<<F("Mercury: Connect ")<< item->itemArr->name<<F(" level:")<< buffer[2] ;//<< F(" pass:")<< passObj->valuestring;
ret=node.ModbusRawTransaction(buffer,9,4);
modbusBusy=0;
if (!ret) ret = buffer[1];
debugSerial<<F(" res:")<< ret << endl;
mbusSlenceTimer = millisNZ();
return ret;
}
short out_Mercury::disconnectMercury()
{
if (!item || !item->itemArg || modbusBusy) return RET_INTERROR;
uint8_t buffer[4];
uint8_t ret;
modbusBusy=1;
initLine();
buffer[1]=2; //Close
ret=node.ModbusRawTransaction(buffer,2,4);
modbusBusy=0;
if (!ret) ret = buffer[1];
debugSerial<<F("Mercury: Disconnect ")<< item->itemArr->name<<F(" res:")<< ret << endl;
mbusSlenceTimer = millisNZ();
return ret;
}
///////////////////// команды//////////////////////////////////////////////////////
//byte testConnect[] = { 0x00, 0x00 }; //тест связи
//byte Sn[] = { 0x00, 0x08, 0x05 }; //запрос сетевого адреса
//byte Open[] = { 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; //открыть канал с паролеи
//byte Close[] = { 0x00, 0x02 }; // закрыть канал (а то ждать 4 минуты)
//byte activPower[] = { 0x00, 0x05, 0x00, 0x00 }; //суммарная энергия прямая + обратная + активная + реактивная
//byte ind[] = { 0x00, 0x03, 0x01, 0x01, 0x00, 0x01, 0x00, 0x1F, 0x00, 0x1F, 0x00 }; //маска индикации работает только для автоматического режима
//byte Angle[] = { 0x00, 0x08, 0x16, 0x51 }; // углы между фазами 1и2, 1и3, 2и3
////////////////////////подпрограмма чтения показаний счётчика////////////////////////////////////
#define M_BEGIN_YESTERDAY 0xD0 // показания на начало вчерашних суток
#define M_BEGIN_TODAY 0x21 // показания на начало сегодняшних суток
#define M_NOW 0x00 // показания на сейчас
//2.5.17 Запросы на чтение массивов регистров накопленной энергии
short out_Mercury::getCounters(byte when, String topic, int divisor)
{
if (!item || !item->itemArg || modbusBusy) return RET_INTERROR;
modbusBusy=1;
initLine();
uint8_t response[19]{}; //1+4+4+4+4+2
response[1]=0x05;
response[2]=when; // показания на начало вчерашних суток 0xD0
uint8_t ret=node.ModbusRawTransaction(response, 4 , sizeof(response));
if (!ret)
{
unsigned long r = 0;
r |= (unsigned long)response[2]<<24;
r |= (unsigned long)response[1]<<16;
r |= (unsigned long)response[4]<<8;
r |= (unsigned long)response[3];
publishTopic(item->itemArr->name, (float) r/1000,(topic+"/Active").c_str());
//Обратную (5-8) пропускаем
r = 0;
r |= (unsigned long)response[10]<<24;
r |= (unsigned long)response[9]<<16;
r |= (unsigned long)response[12]<<8;
r |= (unsigned long)response[11];
publishTopic(item->itemArr->name, (float) r/1000,(topic+"/Reactive").c_str());
//Обратную (13-16) пропускаем
};
debugSerial<<F("Mercury: getCounters ")<< item->itemArr->name << F(" res:")<< ret << endl;
modbusBusy=0;
mbusSlenceTimer = millisNZ();
return ret;
}
/////////////////////////углы, напряжения токи по фазам//////////////////////////////////////////////////
#define VOLTAGE 0x11 //0x11 напряжения пофазно, 100делитель
#define CURRENT 0x21 //0x21 токи пофазно
#define ANGLES 0x51 //0x51 углы между напряжениями фаз, 100делитель
#define M_COSF 0x31
#define M_ANGLE_DEF 0x30
#define M_PWR 0x00
short out_Mercury::getCurrentVal12(byte param, String topic, int divisor)
{
if (!item || !item->itemArg || modbusBusy) return RET_INTERROR;
modbusBusy=1;
initLine();
uint8_t response[12]{};
response[1]=0x08; //2.6 Запросы на чтение параметров
response[2]=0x16; //2.6.16 Чтение вспомогательных параметров: мгновенной активной,реактивной, полной мощности,
// фазных и линейных, напряжений,тока, коэффициента мощности,частоты, небаланса
// Ответ 12 (9) двоичных байт. Два старших разряда старшего байта указывают положение вектора полной мощности и
// должны маскироваться (см. п. 1.5)
response[3]=param;
uint8_t ret=node.ModbusRawTransaction(response, 4 , sizeof(response));
if (!ret)
{
long r = 0;
r |= (long)response[1]<<16;
r |= (long)response[3]<<8;
r |= (long)response[2];
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/A").c_str());
r = 0;
r |= (long)response[4]<<16;
r |= (long)response[6]<<8;
r |= (long)response[5];
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/B").c_str());
r=0;
r |= (long)response[7]<<16;
r |= (long)response[9]<<8;
r |= (long)response[8];
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/C").c_str());
}
debugSerial<<F("Mercury: getCurrentVal12 ")<< item->itemArr->name << F(" res:")<< ret << endl;
modbusBusy=0;
mbusSlenceTimer = millisNZ();
return ret;
}
//cosSN(); //0x31 углы между напряжениями фазы и током COSf
/////////////////////////COSf по фазам//////////////////////////////////////////////////
short out_Mercury::getCurrentVal15(byte param, String topic, int divisor)
{
if (!item || !item->itemArg || modbusBusy) return RET_INTERROR;
modbusBusy=1;
initLine();
uint8_t response[15]{};
response[1]=0x08;
response[2]=0x16;
response[3]=param;
uint8_t ret=node.ModbusRawTransaction(response, 4 , sizeof(response));
if (!ret)
{
long r = 0;
r |= (long)response[1]<<16;
r |= (long)response[3]<<8;
r |= (long)response[2];
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/sum").c_str());
r = 0;
r |= (long)response[4]<<16;
r |= (long)response[6]<<8;
r |= (long)response[5];
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/A").c_str());
r = 0;
r |= (long)response[7]<<16;
r |= (long)response[9]<<8;
r |= (long)response[8];
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/B").c_str());
r=0;
r |= (long)response[10]<<16;
r |= (long)response[12]<<8;
r |= (long)response[11];
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/C").c_str());
}
debugSerial<<F("Mercury: getCurrentVal15 ")<< item->itemArr->name << F(" res:")<< ret << endl;
modbusBusy=0;
mbusSlenceTimer = millisNZ();
return ret;
}
int out_Mercury::Poll(short cause)
{
//bool lineInitialized = false;
if (cause==POLLING_SLOW) return 0;
if (modbusBusy || ( mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),100))) return 0;
if (!getConfig()) return 0;
switch (Status())
{
case CST_INITIALIZED:
if (isTimeOver(store->timestamp,millis(),10000UL)) setStatus(M_CONNECTING);
break;
case M_CONNECTING:
switch (connectMercury())
{
case RET_SUCCESS: setStatus(M_CONNECTED);
store->lastSuccessTS=millisNZ();
break;
case RET_NOT_CONNECTED: setStatus(CST_FAILED);
break;
default:
setStatus(CST_INITIALIZED);
}
break;
case M_CONNECTED:
if (isTimeOver(store->lastSuccessTS,millis(),240000UL)) setStatus(CST_INITIALIZED);
if (isTimeOver(store->timestamp,millis(),pollingInterval)) setStatus(M_POLLING1);
break;
case M_POLLING1:
switch (getCurrentVal12(VOLTAGE,"/voltage",100))
{
case RET_SUCCESS: setStatus(M_POLLING2);
store->timestamp=millisNZ();
store->lastSuccessTS=millisNZ();
break;
case RET_NOT_CONNECTED: setStatus(M_CONNECTING);
break;
default:
setStatus(CST_INITIALIZED);
}
break;
case M_POLLING2:
switch (getCurrentVal12(CURRENT,"/current",1000))
{
case RET_SUCCESS: setStatus(M_POLLING3);
store->timestamp=millisNZ();
store->lastSuccessTS=millisNZ();
break;
case RET_NOT_CONNECTED: setStatus(M_CONNECTING);
break;
default:
setStatus(CST_INITIALIZED);
}
break;
case M_POLLING3:
switch (getCurrentVal12(ANGLES,"/angles",100))
{
case RET_SUCCESS: setStatus(M_POLLING4);
store->timestamp=millisNZ();
store->lastSuccessTS=millisNZ();
break;
case RET_NOT_CONNECTED: setStatus(M_CONNECTING);
break;
default:
setStatus(CST_INITIALIZED);
}
break;
case M_POLLING4:
switch (getCounters(M_NOW,"/counters",1000))
{
case RET_SUCCESS: setStatus(M_POLLING5);
store->timestamp=millisNZ();
store->lastSuccessTS=millisNZ();
break;
case RET_NOT_CONNECTED: setStatus(M_CONNECTING);
break;
default:
setStatus(CST_INITIALIZED);
}
break;
case M_POLLING5:
switch (getCurrentVal12(M_PWR+1,"/power",100))
{
case RET_SUCCESS: setStatus(M_POLLING6);
store->timestamp=millisNZ();
store->lastSuccessTS=millisNZ();
break;
case RET_NOT_CONNECTED: setStatus(M_CONNECTING);
break;
default:
setStatus(CST_INITIALIZED);
}
break;
case M_POLLING6:
switch (getCurrentVal12(M_COSF,"/cosf",1000))
{
case RET_SUCCESS: setStatus(M_CONNECTED);
store->timestamp=millisNZ();
store->lastSuccessTS=millisNZ();
break;
case RET_NOT_CONNECTED: setStatus(M_CONNECTING);
break;
default:
setStatus(CST_INITIALIZED);
}
break;
}
return pollingInterval;
};
int out_Mercury::getChanType()
{
return CH_MBUS;
}
//!Control unified item
int out_Mercury::Ctrl(itemCmd cmd, char* subItem, bool toExecute)
{
if (!store) return -1;
int suffixCode = cmd.getSuffix();
int res = -1;
return res;
}
#endif

View File

@@ -0,0 +1,69 @@
#pragma once
#include "options.h"
#ifdef MERCURY_ENABLE
#include <abstractout.h>
#include <item.h>
#include "itemCmd.h"
#include <utils.h>
#include <Arduino.h>
class mercuryPersistent : public chPersistent {
public:
int8_t driverStatus;
uint32_t timestamp;
uint32_t lastSuccessTS;
};
#define MB_NEED_SEND 8
#define MB_SEND_ERROR 4
#define MB_SEND_ATTEMPTS 3
#define M_CONNECTING 10
#define M_CONNECTED 11
#define M_POLLING1 12
#define M_POLLING2 13
#define M_POLLING3 14
#define M_POLLING4 15
#define M_POLLING5 16
#define M_POLLING6 17
#define M_POLLING7 18
#define M_POLLING8 19
#define RET_SUCCESS 0
#define RET_INVALID_PARAM 1
#define RET_INTERROR 2
#define RET_ACCESS_LEVEL 3
#define RET_RTC_ERR 4
#define RET_NOT_CONNECTED 3
class out_Mercury : public abstractOut {
public:
out_Mercury(Item * _item):abstractOut(_item){store = (mercuryPersistent *) item->getPersistent();};
int Setup() override;
int Poll(short cause) override;
int Stop() override;
int Status() override;
int getChanType() override;
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
int getDefaultStorageType(){return ST_INT32;};
protected:
mercuryPersistent * store;
uint16_t pollingInterval;
bool getConfig();
void initLine(bool full = false);
void setStatus(short);
short connectMercury();
short disconnectMercury();
short getCurrentVal12(byte param, String topic,int divisor=1);
short getCurrentVal15(byte param, String topic,int divisor=1);
short getCounters (byte when, String topic,int divisor=1);
};
#endif

View File

@@ -15,7 +15,7 @@ extern aJsonObject *modbusObj;
extern ModbusMaster node; extern ModbusMaster node;
extern short modbusBusy; extern short modbusBusy;
extern void modbusIdle(void) ; extern void modbusIdle(void) ;
static uint32_t mbusSlenceTimer = 0; uint32_t mbusSlenceTimer = 0;
struct reg_t struct reg_t
{ {
@@ -97,6 +97,7 @@ serialParamType str2SerialParam(char * str)
return static_cast<serialParamType> (SERIAL_8N1); return static_cast<serialParamType> (SERIAL_8N1);
} }
*/ */
uint16_t swap (uint16_t x) {return ((x & 0xff) << 8) | ((x & 0xff00) >> 8);}
int str2regSize(char * str) int str2regSize(char * str)
{ {
@@ -279,12 +280,12 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
break; break;
case PAR_I32: case PAR_I32:
//isSigned=true; //isSigned=true;
param = data | (node.getResponseBuffer(posInBuffer+1)<<16); param = swap(data ) | swap(node.getResponseBuffer(posInBuffer+1)<<16);
mappedParam.Int((int32_t)param); mappedParam.Int((int32_t)param);
break; break;
case PAR_U32: case PAR_U32:
param = data | (node.getResponseBuffer(posInBuffer+1)<<16); param = swap(data )| swap (node.getResponseBuffer(posInBuffer+1)<<16 );
mappedParam.Int((uint32_t)param); mappedParam.Int((uint32_t)param);
break; break;
@@ -345,10 +346,10 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
switch (idObj->valueint) switch (idObj->valueint)
{ {
case S_CMD: case S_CMD:
mappedParam.saveItem(item,SEND_COMMAND); mappedParam.saveItem(item,FLAG_COMMAND);
break; break;
case S_SET: case S_SET:
mappedParam.saveItem(item,SEND_PARAMETERS); mappedParam.saveItem(item,FLAG_PARAMETERS);
} }
@@ -494,8 +495,8 @@ int out_Modbus::sendModbus(char * paramName, int32_t value, uint8_t regType)
break; break;
case PAR_I32: case PAR_I32:
case PAR_U32: case PAR_U32:
res = node.writeSingleRegister(regObj->valueint,value & 0xFFFF); res = node.writeSingleRegister(regObj->valueint,swap(value & 0xFFFF));
res += node.writeSingleRegister(regObj->valueint+1,value >> 16) ; res += node.writeSingleRegister(regObj->valueint+1,swap(value >> 16)) ;
break; break;
case PAR_U8L: case PAR_U8L:
@@ -566,7 +567,7 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
if (isTimeOver(store->timestamp,millis(),store->pollingInterval) && ( !mbusSlenceTimer || isTimeOver(mbusSlenceTimer,millis(),100))) if (isTimeOver(store->timestamp,millis(),store->pollingInterval) && ( !mbusSlenceTimer || isTimeOver(mbusSlenceTimer,millis(),100)))
{ {
// Clean_up SEND_ERROR flag // Clean_up FLAG_SEND_ERROR flag
if (itemParametersObj && itemParametersObj->type ==aJson_Object) if (itemParametersObj && itemParametersObj->type ==aJson_Object)
{ {
aJsonObject *execObj = itemParametersObj->child; aJsonObject *execObj = itemParametersObj->child;

View File

@@ -61,8 +61,8 @@ digitalWrite(pinDown,INACTIVE);
pinMode(pinFeedback, INPUT); pinMode(pinFeedback, INPUT);
item->setExt(0); item->setExt(0);
item->clearFlag(ACTION_NEEDED); item->clearFlag(FLAG_ACTION_NEEDED);
item->clearFlag(ACTION_IN_PROCESS); item->clearFlag(FLAG_ACTION_IN_PROCESS);
driverStatus = CST_INITIALIZED; driverStatus = CST_INITIALIZED;
motorQuote = MOTOR_QUOTE; motorQuote = MOTOR_QUOTE;
return 1; return 1;
@@ -105,13 +105,13 @@ if (cause==POLLING_SLOW) return 0;
int curPos = -1; int curPos = -1;
int targetPos = -1; int targetPos = -1;
int dif; int dif;
if (!item->getFlag(ACTION_NEEDED)) return 0; if (!item->getFlag(FLAG_ACTION_NEEDED)) return 0;
if (!item->getFlag(ACTION_IN_PROCESS)) if (!item->getFlag(FLAG_ACTION_IN_PROCESS))
{ {
if (motorQuote) if (motorQuote)
{ {
item->setFlag(ACTION_IN_PROCESS); item->setFlag(FLAG_ACTION_IN_PROCESS);
motorQuote--; motorQuote--;
} }
else return 0; else return 0;
@@ -245,8 +245,8 @@ else //Target zone
digitalWrite(pinUp,INACTIVE); digitalWrite(pinUp,INACTIVE);
digitalWrite(pinDown,INACTIVE); digitalWrite(pinDown,INACTIVE);
item->setExt(0); item->setExt(0);
item->clearFlag(ACTION_NEEDED); item->clearFlag(FLAG_ACTION_NEEDED);
item->clearFlag(ACTION_IN_PROCESS); item->clearFlag(FLAG_ACTION_IN_PROCESS);
motorQuote++; motorQuote++;
} }
@@ -269,7 +269,7 @@ int suffixCode = cmd.getSuffix();
//itemCmd st(ST_PERCENTS,CMD_VOID); //itemCmd st(ST_PERCENTS,CMD_VOID);
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
item->setFlag(ACTION_NEEDED); item->setFlag(FLAG_ACTION_NEEDED);
switch(suffixCode) switch(suffixCode)
{ {
@@ -290,10 +290,10 @@ case S_SET:
{ {
if (chActive>0 && !st.getPercents()) item->setCmd(CMD_OFF); if (chActive>0 && !st.getPercents()) item->setCmd(CMD_OFF);
if (chActive==0 && st.getPercents()) item->setCmd(CMD_ON); if (chActive==0 && st.getPercents()) item->setCmd(CMD_ON);
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED); item->SendStatus(FLAG_COMMAND | FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
if (item->getExt()) item->setExt(millisNZ()); //Extend motor time if (item->getExt()) item->setExt(millisNZ()); //Extend motor time
} }
else item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED); else item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
*/ */
return 1; return 1;
//break; //break;
@@ -307,7 +307,7 @@ case S_CMD:
return 1; return 1;
case CMD_OFF: case CMD_OFF:
////item->SendStatus(SEND_COMMAND); ////item->SendStatus(FLAG_COMMAND);
if (item->getExt()) item->setExt(millisNZ()); //Extend motor time if (item->getExt()) item->setExt(millisNZ()); //Extend motor time
return 1; return 1;

View File

@@ -159,10 +159,10 @@ while (i)
{ {
setObj->valueint=30; setObj->valueint=30;
cmd.Percents255(30); cmd.Percents255(30);
//if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,SEND_PARAMETERS,i->name); //if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_PARAMETERS,i->name);
} }
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,SEND_COMMAND|SEND_PARAMETERS,i->name); if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_COMMAND|FLAG_PARAMETERS,i->name);
} }
else if (setObj && cmdObj && suffixCode == S_FAN && cmd.isValue()) else if (setObj && cmdObj && suffixCode == S_FAN && cmd.isValue())
@@ -175,7 +175,7 @@ while (i)
debugSerial<<"Turning ON"<<endl; debugSerial<<"Turning ON"<<endl;
cmdObj->valueint = CMD_ON; cmdObj->valueint = CMD_ON;
cmd.Cmd(CMD_ON); cmd.Cmd(CMD_ON);
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_ON),SEND_COMMAND,i->name); //if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_ON),FLAG_COMMAND,i->name);
} }
setObj->valueint = cmd.getInt(); setObj->valueint = cmd.getInt();
@@ -186,20 +186,20 @@ while (i)
{ debugSerial<<"Turning OFF"<<endl; { debugSerial<<"Turning OFF"<<endl;
cmdObj->valueint = CMD_OFF; cmdObj->valueint = CMD_OFF;
cmd.Cmd(CMD_OFF); cmd.Cmd(CMD_OFF);
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_OFF),SEND_COMMAND,i->name); //if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_OFF),FLAG_COMMAND,i->name);
} }
setObj->valueint = 0; setObj->valueint = 0;
} }
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,SEND_PARAMETERS|SEND_COMMAND,i->name); if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_PARAMETERS|FLAG_COMMAND,i->name);
} }
else if (setObj && cmd.isValue()) else if (setObj && cmd.isValue())
{ {
setObj->valueint = cmd.getPercents255(); setObj->valueint = cmd.getPercents255();
//publishTopic(i->name,setObj->valueint,"/set"); //publishTopic(i->name,setObj->valueint,"/set");
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,SEND_PARAMETERS,i->name); if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_PARAMETERS,i->name);
} }
if (cascadeObj) executeCommand(cascadeObj,-1,cmd); if (cascadeObj) executeCommand(cascadeObj,-1,cmd);
} }

View File

@@ -122,8 +122,8 @@ if (getConfig())
{ {
infoSerial<<F("PID config loaded ")<< item->itemArr->name<<endl; infoSerial<<F("PID config loaded ")<< item->itemArr->name<<endl;
//item->On(); // Turn ON pid by default //item->On(); // Turn ON pid by default
// if (item->getCmd()) item->setFlag(SEND_COMMAND); // if (item->getCmd()) item->setFlag(FLAG_COMMAND);
// if (item->itemVal) item->setFlag(SEND_PARAMETERS); // if (item->itemVal) item->setFlag(FLAG_PARAMETERS);
store->prevOut = -2.0; store->prevOut = -2.0;
store->driverStatus = CST_INITIALIZED; store->driverStatus = CST_INITIALIZED;
return 1; return 1;
@@ -321,7 +321,7 @@ if (itemCascadeObj) executeCommand(itemCascadeObj,-1,cmd);
} }
//cmd.saveItem(item); //cmd.saveItem(item);
//item->SendStatus(SEND_PARAMETERS); //item->SendStatus(FLAG_PARAMETERS);
return 1; return 1;
//break; //break;
@@ -348,14 +348,14 @@ case S_CMD:
case CMD_ENABLE: case CMD_ENABLE:
item->setCmd(CMD_ENABLE); item->setCmd(CMD_ENABLE);
item->SendStatus(SEND_COMMAND); item->SendStatus(FLAG_COMMAND);
executeCommand(oCmd,-1,value); executeCommand(oCmd,-1,value);
store->prevOut=-2.0; store->prevOut=-2.0;
return 1; return 1;
case CMD_DISABLE: case CMD_DISABLE:
item->setCmd(CMD_DISABLE); item->setCmd(CMD_DISABLE);
item->SendStatus(SEND_COMMAND); item->SendStatus(FLAG_COMMAND);
executeCommand(oCmd,-1,value); executeCommand(oCmd,-1,value);
return 1; return 1;
/* /*

View File

@@ -41,8 +41,8 @@ debugSerial<<F("Relay-Out #")<<pin<<F(" init")<<endl;
pinMode(pin, OUTPUT); pinMode(pin, OUTPUT);
digitalWrite(pin,INACTIVE); digitalWrite(pin,INACTIVE);
if (item) item->setExt(0); if (item) item->setExt(0);
//if (item->getCmd()) item->setFlag(SEND_COMMAND); //if (item->getCmd()) item->setFlag(FLAG_COMMAND);
//if (item->itemVal) item->setFlag(SEND_PARAMETERS); //if (item->itemVal) item->setFlag(FLAG_PARAMETERS);
driverStatus = CST_INITIALIZED; driverStatus = CST_INITIALIZED;
if (item->isActive()>0) ///???? if (item->isActive()>0) ///????
{ {

View File

@@ -209,9 +209,9 @@ case S_HSV:
{ {
if (chActive>0 && !st.getPercents()) item->setCmd(CMD_OFF); if (chActive>0 && !st.getPercents()) item->setCmd(CMD_OFF);
if (chActive==0 && st.getPercents()) item->setCmd(CMD_ON); if (chActive==0 && st.getPercents()) item->setCmd(CMD_ON);
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED); item->SendStatus(SEND_COMMAND | FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
} }
else item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED); else item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
} }
return 1; return 1;
//break; //break;
@@ -234,7 +234,7 @@ case S_CMD:
if (st.getInt() ) //Stored smthng if (st.getInt() ) //Stored smthng
{ {
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS); item->SendStatus(SEND_COMMAND | FLAG_PARAMETERS);
debugSerial<<F("Restored: ")<<st.param.h<<F(",")<<st.param.s<<F(",")<<st.param.v<<endl; debugSerial<<F("Restored: ")<<st.param.h<<F(",")<<st.param.s<<F(",")<<st.param.v<<endl;
} }
else else
@@ -245,7 +245,7 @@ case S_CMD:
// Store // Store
//item->setVal(st.getInt()); //item->setVal(st.getInt());
st.saveItem(item); st.saveItem(item);
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS ); item->SendStatus(SEND_COMMAND | FLAG_PARAMETERS );
} }
PixelCtrl(st,from,to); PixelCtrl(st,from,to);

View File

@@ -250,7 +250,7 @@ void parseBytes(const char *str, char separator, byte *bytes, int maxBytes, int
void printFloatValueToStr(char *valstr, float value) { void printFloatValueToStr(char *valstr, float value) {
#if defined(ESP8266) || defined(ARDUINO_ARCH_ESP32) #if defined(ESP8266) || defined(ARDUINO_ARCH_ESP32)
sprintf(valstr, "%2.1f", value); sprintf(valstr, "%2.2f", value);
#endif #endif
#if defined(__AVR__) #if defined(__AVR__)
sprintf(valstr, "%d", (int)value); sprintf(valstr, "%d", (int)value);
@@ -261,7 +261,7 @@ void printFloatValueToStr(char *valstr, float value) {
valstr[val_len+2]='\0'; valstr[val_len+2]='\0';
#endif #endif
#if defined(__SAM3X8E__) #if defined(__SAM3X8E__)
sprintf(valstr, "%2.1f",value); sprintf(valstr, "%2.2f",value);
#endif #endif
} }
@@ -798,5 +798,6 @@ bool getPinVal(uint8_t pin)
return (0!=(*portOutputRegister( digitalPinToPort(pin) ) & digitalPinToBitMask(pin))); return (0!=(*portOutputRegister( digitalPinToPort(pin) ) & digitalPinToBitMask(pin)));
} }
#pragma message(VAR_NAME_VALUE(debugSerial)) #pragma message(VAR_NAME_VALUE(debugSerial))
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD)) #pragma message(VAR_NAME_VALUE(SERIAL_BAUD))

View File

@@ -76,3 +76,4 @@ unsigned long millisNZ(uint8_t shift=0);
serialParamType str2SerialParam(char * str); serialParamType str2SerialParam(char * str);
String toString(const IPAddress& address); String toString(const IPAddress& address);
bool getPinVal(uint8_t pin); bool getPinVal(uint8_t pin);
int str2regSize(char * str);

1
upload.bat Normal file
View File

@@ -0,0 +1 @@
arduinoOTA -address 192.168.11.120 -port 80 -username arduino -password password -b -upload /sketch -sketch $1 ;sleep 6