mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 03:39:49 +03:00
Mercury electricity counter driver, refactoring
This commit is contained in:
@@ -38,3 +38,5 @@
|
||||
-DOTA_PORT=80
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
#-D MERCURY_ENABLE
|
||||
#-D IPMODBUS
|
||||
3
compiled/esp8266-wifi/upload.bat
Normal file
3
compiled/esp8266-wifi/upload.bat
Normal 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
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#define CST_UNKNOWN 0
|
||||
#define CST_INITIALIZED 1
|
||||
#define CST_FAILED 2
|
||||
#define CST_FAILED -1
|
||||
|
||||
class abstractCh {
|
||||
public:
|
||||
|
||||
@@ -71,16 +71,16 @@ case S_CMD:
|
||||
{
|
||||
cmd.setPercents(INIT_VOLUME);
|
||||
cmd.saveItem(item);
|
||||
item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
|
||||
item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
|
||||
};
|
||||
PixelCtrl(cmd,subItem, true);
|
||||
// item->SendStatus(SEND_COMMAND | SEND_PARAMETERS );
|
||||
// item->SendStatus(FLAG_COMMAND | FLAG_PARAMETERS );
|
||||
return 1;
|
||||
|
||||
case CMD_OFF:
|
||||
cmd.param.asInt32=0;
|
||||
PixelCtrl(cmd, subItem, true);
|
||||
// item->SendStatus(SEND_COMMAND);
|
||||
// item->SendStatus(FLAG_COMMAND);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
|
||||
@@ -1023,7 +1023,7 @@ void Input::onAnalogChanged(itemCmd newValue) {
|
||||
strncpy(addrstr,emit->valuestring,sizeof(addrstr));
|
||||
if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring);
|
||||
char strVal[16];
|
||||
newValue.toString(strVal,sizeof(strVal),SEND_PARAMETERS);
|
||||
newValue.toString(strVal,sizeof(strVal),FLAG_PARAMETERS);
|
||||
|
||||
if (mqttClient.connected() && !ethernetIdleCount)
|
||||
mqttClient.publish(addrstr, strVal, true);
|
||||
|
||||
@@ -53,6 +53,10 @@ e-mail anklimov@gmail.com
|
||||
#include "modules/out_relay.h"
|
||||
#include "modules/out_counter.h"
|
||||
|
||||
#ifdef MERCURY_ENABLE
|
||||
#include "modules/out_mercury.h"
|
||||
#endif
|
||||
|
||||
#ifdef ELEVATOR_ENABLE
|
||||
#include "modules/out_elevator.h"
|
||||
#endif
|
||||
@@ -218,6 +222,12 @@ void Item::Parse() {
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef MERCURY_ENABLE
|
||||
case CH_MERCURY:
|
||||
driver = new out_Mercury (this);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifndef COUNTER_DISABLE
|
||||
case CH_COUNTER:
|
||||
driver = new out_counter (this);
|
||||
@@ -238,8 +248,8 @@ if (driver)
|
||||
if (driver->Status()) driver->Stop();
|
||||
if (driver->Setup())
|
||||
{
|
||||
if (getCmd()) setFlag(SEND_COMMAND);
|
||||
if (itemVal) setFlag(SEND_PARAMETERS);
|
||||
if (getCmd()) setFlag(FLAG_COMMAND);
|
||||
if (itemVal) setFlag(FLAG_PARAMETERS);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -306,12 +316,12 @@ void Item::setCmd(uint8_t cmdValue) {
|
||||
if (itemCmd && (itemCmd->type == aJson_Int || itemCmd->type == aJson_NULL))
|
||||
{
|
||||
itemCmd->type = aJson_Int;
|
||||
itemCmd->valueint = cmdValue & CMD_MASK | itemCmd->valueint & FLAG_MASK; // Preserve special bits
|
||||
itemCmd->valueint = cmdValue & CMD_MASK | itemCmd->valueint & (FLAG_MASK); // Preserve special bits
|
||||
debugSerial<<F("SetCmd:")<<cmdValue<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
short Item::getFlag (short flag)
|
||||
uint32_t Item::getFlag (uint32_t flag)
|
||||
{
|
||||
aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD);
|
||||
if (itemCmd && (itemCmd->type == aJson_Int))
|
||||
@@ -321,7 +331,7 @@ short Item::getFlag (short flag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Item::setFlag (short flag)
|
||||
void Item::setFlag (uint32_t flag)
|
||||
{
|
||||
aJsonObject *itemCmd = aJson.getArrayItem(itemArr, I_CMD);
|
||||
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);
|
||||
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
|
||||
{
|
||||
if (!itemArg) return 0;//-1;
|
||||
@@ -820,8 +831,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
scale100=true; //openHab topic format
|
||||
chActive=(isActive()>0);
|
||||
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_ON);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 |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;}
|
||||
|
||||
// continue processing as 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))
|
||||
stored.scale100();
|
||||
cmd=stored;
|
||||
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
|
||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
||||
|
||||
break;
|
||||
case S_VAL:
|
||||
@@ -852,7 +863,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
{
|
||||
cmd=stored;
|
||||
cmd.setSuffix(S_SET);
|
||||
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
|
||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
||||
} else invalidArgument=true;
|
||||
break;
|
||||
|
||||
@@ -862,14 +873,14 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
{
|
||||
cmd=stored;
|
||||
cmd.setSuffix(S_SET);
|
||||
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
|
||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
||||
} else invalidArgument=true;
|
||||
break;
|
||||
case S_TEMP:
|
||||
stored.loadItemDef(this);
|
||||
stored.setColorTemp(cmd.getColorTemp());
|
||||
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.Cmd(CMD_ON);
|
||||
}
|
||||
status2Send |=SEND_COMMAND | SEND_IMMEDIATE;
|
||||
status2Send |=FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||
break;
|
||||
|
||||
|
||||
@@ -911,7 +922,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
//if (limit && suffixCode==S_NOTFOUND) limit = 100;
|
||||
if (cmd.incrementPercents(step,limit))
|
||||
{
|
||||
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
|
||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
||||
} else {cmd=fallbackCmd;invalidArgument=true;}
|
||||
}
|
||||
break;
|
||||
@@ -919,14 +930,14 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
case S_HUE:
|
||||
if (cmd.incrementH(step))
|
||||
{
|
||||
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
|
||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
||||
cmd.setSuffix(S_SET);
|
||||
} else {cmd=fallbackCmd;invalidArgument=true;}
|
||||
break;
|
||||
case S_SAT:
|
||||
if (cmd.incrementS(step))
|
||||
{
|
||||
status2Send |= SEND_PARAMETERS | SEND_DEFFERED;
|
||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
||||
cmd.setSuffix(S_SET);
|
||||
} else {cmd=fallbackCmd;invalidArgument=true;}
|
||||
} //switch suffix
|
||||
@@ -957,19 +968,19 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
debugSerial << F("Restored from:") << t << endl;
|
||||
cmd.loadItemDef(this);
|
||||
cmd.Cmd(CMD_ON); //turning on
|
||||
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||
break;
|
||||
default:
|
||||
return 3;
|
||||
}
|
||||
status2Send |= SEND_COMMAND;
|
||||
status2Send |= FLAG_COMMAND;
|
||||
break;
|
||||
case CMD_XOFF: // individual for group members
|
||||
switch (t = getCmd()) {
|
||||
case CMD_XON: //previous command was CMD_XON ?
|
||||
debugSerial << F("Turned off from:") << t << endl;
|
||||
cmd.Cmd(CMD_OFF); //turning Off
|
||||
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||
break;
|
||||
default:
|
||||
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.Cmd(CMD_ON);
|
||||
command2Set=CMD_XON;
|
||||
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -998,7 +1009,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
{
|
||||
cmd.Cmd(CMD_OFF);
|
||||
command2Set=CMD_HALT;
|
||||
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1008,9 +1019,9 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
break;
|
||||
}
|
||||
|
||||
status2Send |= SEND_IMMEDIATE;
|
||||
if (cmd.isChannelCommand()) status2Send |= SEND_COMMAND;
|
||||
if (cmd.isValue() || cmd.loadItem(this,SEND_PARAMETERS)) status2Send |= SEND_PARAMETERS; ;
|
||||
status2Send |= FLAG_SEND_IMMEDIATE;
|
||||
if (cmd.isChannelCommand()) status2Send |= FLAG_COMMAND;
|
||||
if (cmd.isValue() || cmd.loadItem(this,FLAG_PARAMETERS)) status2Send |= FLAG_PARAMETERS; ;
|
||||
} // end GROUP
|
||||
|
||||
else
|
||||
@@ -1053,12 +1064,12 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
toExecute=true;
|
||||
if (itemType == CH_THERMO) cmd.Cmd(CMD_AUTO); ////
|
||||
else cmd.Cmd(CMD_ON); //turning on
|
||||
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||
break;
|
||||
default:
|
||||
return 3;
|
||||
}
|
||||
status2Send |= SEND_COMMAND;
|
||||
status2Send |= FLAG_COMMAND;
|
||||
break;
|
||||
case CMD_XOFF: // individual for group members
|
||||
switch (t = getCmd()) {
|
||||
@@ -1066,7 +1077,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
debugSerial << F("Turned off from:") << t << endl;
|
||||
toExecute=true;
|
||||
cmd.Cmd(CMD_OFF); //turning Off
|
||||
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||
break;
|
||||
default:
|
||||
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.Cmd(CMD_ON);
|
||||
command2Set=CMD_XON;
|
||||
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||
toExecute=true;
|
||||
}
|
||||
else
|
||||
@@ -1094,7 +1105,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
{
|
||||
cmd.Cmd(CMD_OFF);
|
||||
command2Set=CMD_HALT;
|
||||
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||
toExecute=true;
|
||||
}
|
||||
else
|
||||
@@ -1112,7 +1123,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
}
|
||||
|
||||
if (getCmd() == CMD_HALT) return 3; //Halted, ignore OFF
|
||||
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||
toExecute=true;
|
||||
break;
|
||||
|
||||
@@ -1126,7 +1137,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
{
|
||||
debugSerial<<F("ON:Already Active\n");
|
||||
setCmd(CMD_ON);
|
||||
SendStatus(SEND_COMMAND | SEND_DEFFERED);
|
||||
SendStatus(FLAG_COMMAND | FLAG_SEND_DEFFERED);
|
||||
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
|
||||
status2Send |= SEND_COMMAND | SEND_PARAMETERS | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_COMMAND | FLAG_PARAMETERS | FLAG_SEND_IMMEDIATE;
|
||||
toExecute=true;
|
||||
break;
|
||||
case CMD_VOID:
|
||||
@@ -1153,8 +1164,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
||||
break;
|
||||
|
||||
default:
|
||||
if (cmd.isCommand()) status2Send |= SEND_COMMAND;
|
||||
if (cmd.isValue()) status2Send |= SEND_PARAMETERS;
|
||||
if (cmd.isCommand()) status2Send |= FLAG_COMMAND;
|
||||
if (cmd.isValue()) status2Send |= FLAG_PARAMETERS;
|
||||
toExecute=true;
|
||||
} //Switch commands
|
||||
} // NO GROUP
|
||||
@@ -1166,7 +1177,7 @@ if (status2Send) cmd.saveItem(this,status2Send);
|
||||
if (driver) //New style modular code
|
||||
{
|
||||
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
|
||||
}
|
||||
else
|
||||
@@ -1196,7 +1207,7 @@ switch (itemType) {
|
||||
else
|
||||
digitalWrite(iaddr, k = ((icmd == CMD_ON || icmd == CMD_AUTO) ? HIGH : LOW));
|
||||
debugSerial<<F("Pin:")<<iaddr<<F("=")<<k<<endl;
|
||||
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||
res=1;
|
||||
}
|
||||
}
|
||||
@@ -1220,12 +1231,12 @@ switch (itemType) {
|
||||
}
|
||||
break;
|
||||
case S_SET:
|
||||
status2Send |= SEND_PARAMETERS | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_IMMEDIATE;
|
||||
res=1;
|
||||
//st.saveItem(this);
|
||||
break;
|
||||
case S_CMD:
|
||||
status2Send |= SEND_COMMAND | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||
res=1;
|
||||
}
|
||||
break;
|
||||
@@ -1239,7 +1250,7 @@ switch (itemType) {
|
||||
if (!chActive && cmd.getCmd()== CMD_ON && (vol=cmd.getPercents())<MIN_VOLUME && vol>=0)
|
||||
{
|
||||
cmd.setPercents(INIT_VOLUME);
|
||||
status2Send |= SEND_PARAMETERS | SEND_IMMEDIATE;
|
||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_IMMEDIATE;
|
||||
};
|
||||
|
||||
res=modbusDimmerSet(cmd);
|
||||
@@ -1258,7 +1269,7 @@ switch (itemType) {
|
||||
} //else (nodriver)
|
||||
|
||||
//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);
|
||||
|
||||
debugSerial<<F("Ctrl Res:")<<res<<F(" time:")<<millis()-time<<endl;
|
||||
@@ -1362,13 +1373,13 @@ if (timestampObj)
|
||||
//if (!(remain % 1000))
|
||||
if (cause == POLLING_1S)
|
||||
{
|
||||
SendStatusImmediate(st,SEND_DELAYED);
|
||||
SendStatusImmediate(st,FLAG_SEND_DELAYED);
|
||||
debugSerial<< remain/1000 << F(" sec remaining") << endl;
|
||||
}
|
||||
|
||||
if (remain <0 && abs(remain)< 0xFFFFFFFFUL/2)
|
||||
{
|
||||
SendStatusImmediate(st,SEND_DELAYED);
|
||||
SendStatusImmediate(st,FLAG_SEND_DELAYED);
|
||||
Ctrl(itemCmd(ST_VOID,cmd));
|
||||
timestampObj->subtype=0;
|
||||
}
|
||||
@@ -1406,28 +1417,28 @@ switch (cause)
|
||||
}
|
||||
|
||||
void Item::sendDelayedStatus()
|
||||
{ long int flags = getFlag(SEND_COMMAND | SEND_PARAMETERS);
|
||||
{ long int flags = getFlag(FLAG_COMMAND | FLAG_PARAMETERS);
|
||||
|
||||
if (flags && lanStatus==OPERATION)
|
||||
{
|
||||
SendStatus(flags);//(SEND_COMMAND | SEND_PARAMETERS);
|
||||
clearFlag(SEND_COMMAND | SEND_PARAMETERS);
|
||||
SendStatus(flags);//(FLAG_COMMAND | FLAG_PARAMETERS);
|
||||
clearFlag(FLAG_COMMAND | FLAG_PARAMETERS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int Item::SendStatus(int sendFlags) {
|
||||
if (sendFlags & SEND_IMMEDIATE) sendFlags &= ~ (SEND_IMMEDIATE | SEND_DEFFERED);
|
||||
if ((sendFlags & SEND_DEFFERED) || freeRam()<150 || (!isNotRetainingStatus() )) {
|
||||
setFlag(sendFlags & (SEND_COMMAND | SEND_PARAMETERS));
|
||||
if (sendFlags & FLAG_SEND_IMMEDIATE) sendFlags &= ~ (FLAG_SEND_IMMEDIATE | FLAG_SEND_DEFFERED);
|
||||
if ((sendFlags & FLAG_SEND_DEFFERED) || freeRam()<150 || (!isNotRetainingStatus() )) {
|
||||
setFlag(sendFlags & (FLAG_COMMAND | FLAG_PARAMETERS));
|
||||
debugSerial<<F("Status deffered\n");
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
itemCmd st(ST_VOID,CMD_VOID);
|
||||
st.loadItem(this, SEND_COMMAND | SEND_PARAMETERS);
|
||||
sendFlags |= getFlag(SEND_COMMAND | SEND_PARAMETERS); //if some delayed status is pending
|
||||
st.loadItem(this, FLAG_COMMAND | FLAG_PARAMETERS);
|
||||
sendFlags |= getFlag(FLAG_COMMAND | FLAG_PARAMETERS); //if some delayed status is pending
|
||||
//debugSerial<<F("ssi:")<<sendFlags<<endl;
|
||||
return SendStatusImmediate(st,sendFlags);
|
||||
}
|
||||
@@ -1440,7 +1451,7 @@ int Item::SendStatus(int sendFlags) {
|
||||
char cmdstr[9] = "";
|
||||
//debugSerial<<"SSI "<<subItem<<endl;
|
||||
st.debugOut();
|
||||
if (sendFlags & SEND_COMMAND)
|
||||
if (sendFlags & FLAG_COMMAND)
|
||||
{
|
||||
// Preparing legacy Command payload //////////////
|
||||
switch (st.getCmd()) {
|
||||
@@ -1461,12 +1472,12 @@ int Item::SendStatus(int sendFlags) {
|
||||
break;
|
||||
case CMD_VOID:
|
||||
case CMD_RGB:
|
||||
sendFlags &= ~SEND_COMMAND; // Not send command for parametrized req
|
||||
sendFlags &= ~FLAG_COMMAND; // Not send command for parametrized req
|
||||
break;
|
||||
|
||||
default:
|
||||
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);
|
||||
|
||||
|
||||
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
|
||||
(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);
|
||||
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<valstr<<endl;
|
||||
}
|
||||
else if (sendFlags & SEND_COMMAND)
|
||||
else if (sendFlags & FLAG_COMMAND)
|
||||
{
|
||||
mqttClient.publish(addrstr, cmdstr, true);
|
||||
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/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);
|
||||
strncat(addrstr, itemArr->name, sizeof(addrstr)-1);
|
||||
@@ -1521,7 +1532,7 @@ int Item::SendStatus(int sendFlags) {
|
||||
|
||||
strncat(addrstr, "/", sizeof(addrstr)-1);
|
||||
|
||||
if (sendFlags & SEND_DELAYED)
|
||||
if (sendFlags & FLAG_SEND_DELAYED)
|
||||
strncat_P(addrstr, DEL_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:
|
||||
//valstr[0]='#';
|
||||
st.Cmd(CMD_RGB);
|
||||
st.toString(valstr, sizeof(valstr), SEND_PARAMETERS|SEND_COMMAND);
|
||||
st.toString(valstr, sizeof(valstr), FLAG_PARAMETERS|FLAG_COMMAND);
|
||||
break;
|
||||
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)
|
||||
{
|
||||
mqttClient.publish(addrstr, valstr,true);
|
||||
clearFlag(SEND_PARAMETERS);
|
||||
clearFlag(FLAG_PARAMETERS);
|
||||
}
|
||||
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:
|
||||
switch (st.getCmd()) {
|
||||
@@ -1598,7 +1609,7 @@ int Item::SendStatus(int sendFlags) {
|
||||
if (mqttClient.connected() && !ethernetIdleCount)
|
||||
{
|
||||
mqttClient.publish(addrstr, cmdstr,true);
|
||||
clearFlag(SEND_COMMAND);
|
||||
clearFlag(FLAG_COMMAND);
|
||||
}
|
||||
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) {
|
||||
debugSerial<<F("Modbus op failed:")<<_HEX(result)<<endl;
|
||||
setFlag(SEND_RETRY);
|
||||
setFlag(FLAG_SEND_RETRY);
|
||||
isPendedModbusWrites=true;
|
||||
}
|
||||
|
||||
@@ -1639,11 +1650,11 @@ void Item::mb_fail(int result) {
|
||||
int Item::checkModbusRetry() {
|
||||
int result = -1;
|
||||
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);
|
||||
val.loadItem(this, SEND_COMMAND | SEND_PARAMETERS);
|
||||
val.loadItem(this, FLAG_COMMAND | FLAG_PARAMETERS);
|
||||
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);
|
||||
#ifndef MODBUS_DISABLE
|
||||
else switch (itemType)
|
||||
@@ -1802,7 +1813,7 @@ int Item::VacomSetFan(itemCmd st) {
|
||||
if (modbusBusy) {
|
||||
// setCmd(cmd);
|
||||
// setVal(val);
|
||||
st.saveItem(this,SEND_PARAMETERS|SEND_COMMAND);
|
||||
st.saveItem(this,FLAG_PARAMETERS|FLAG_COMMAND);
|
||||
mb_fail();
|
||||
return 0;
|
||||
}
|
||||
@@ -1849,7 +1860,7 @@ int addr;
|
||||
if (modbusBusy) {
|
||||
//setCmd(cmd);
|
||||
//setVal(val);
|
||||
st.saveItem(this,SEND_COMMAND|SEND_PARAMETERS);
|
||||
st.saveItem(this,FLAG_COMMAND|FLAG_PARAMETERS);
|
||||
mb_fail();
|
||||
return 0;
|
||||
}
|
||||
@@ -2144,14 +2155,14 @@ int Item::checkModbusDimmer(int data) {
|
||||
if (d) { // Actually turned on
|
||||
if (cmd != CMD_XON && cmd != CMD_ON) setCmd(CMD_ON); //store command
|
||||
st.Percents255(d);
|
||||
st.saveItem(this,SEND_PARAMETERS);
|
||||
st.saveItem(this,FLAG_PARAMETERS);
|
||||
//setVal(d); //store value
|
||||
if (cmd == CMD_OFF || cmd == CMD_HALT) SendStatus(SEND_COMMAND); //update OH with ON if it was turned off before
|
||||
SendStatus(SEND_PARAMETERS); //update OH with value
|
||||
if (cmd == CMD_OFF || cmd == CMD_HALT) SendStatus(FLAG_COMMAND); //update OH with ON if it was turned off before
|
||||
SendStatus(FLAG_PARAMETERS); //update OH with value
|
||||
} else {
|
||||
if (cmd != CMD_HALT && cmd != CMD_OFF) {
|
||||
setCmd(CMD_OFF); // store command (not value)
|
||||
SendStatus(SEND_COMMAND);// update OH
|
||||
SendStatus(FLAG_COMMAND);// update OH
|
||||
}
|
||||
}
|
||||
} //if data changed
|
||||
|
||||
@@ -59,6 +59,7 @@ e-mail anklimov@gmail.com
|
||||
#define CH_ELEVATOR 19
|
||||
#define CH_COUNTER 20
|
||||
#define CH_HUMIDIFIER 21
|
||||
#define CH_MERCURY 22
|
||||
|
||||
//#define CHANNEL_TYPES 13
|
||||
|
||||
@@ -131,9 +132,9 @@ class Item
|
||||
chPersistent * getPersistent();
|
||||
chPersistent * setPersistent(chPersistent * par);
|
||||
void setCmd(uint8_t cmdValue);
|
||||
short getFlag (short flag=FLAG_MASK);
|
||||
void setFlag (short flag);
|
||||
void clearFlag (short flag);
|
||||
uint32_t getFlag (uint32_t flag=FLAG_MASK);
|
||||
void setFlag (uint32_t flag);
|
||||
void clearFlag (uint32_t flag);
|
||||
void setVal(long int par);
|
||||
void setFloatVal(float par);
|
||||
void setSubtype(uint8_t par);
|
||||
|
||||
@@ -1047,18 +1047,18 @@ bool itemCmd::loadItem(Item * item, uint16_t optionsFlag)
|
||||
if (item && item->isValid())
|
||||
{
|
||||
short subtype =item->getSubtype();
|
||||
if (optionsFlag & SEND_COMMAND) cmd.cmdCode = item->getCmd();
|
||||
if (optionsFlag & FLAG_COMMAND) cmd.cmdCode = item->getCmd();
|
||||
|
||||
if (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 :");
|
||||
//debugOut();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (optionsFlag & SEND_PARAMETERS)
|
||||
if (optionsFlag & FLAG_PARAMETERS)
|
||||
switch (item->itemVal->type)
|
||||
{
|
||||
case aJson_Int:
|
||||
@@ -1091,7 +1091,7 @@ bool itemCmd::loadItemDef(Item * item, uint16_t optionsFlag)
|
||||
setDefault();
|
||||
saveItem(item);
|
||||
debugOut();
|
||||
item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
|
||||
item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -1101,8 +1101,8 @@ bool itemCmd::saveItem(Item * item, uint16_t optionsFlag)
|
||||
{
|
||||
if (item && item->isValid())
|
||||
{
|
||||
if (optionsFlag & SEND_COMMAND) item->setCmd(cmd.cmdCode);
|
||||
if (optionsFlag & SEND_PARAMETERS)
|
||||
if (optionsFlag & FLAG_COMMAND) item->setCmd(cmd.cmdCode);
|
||||
if (optionsFlag & FLAG_PARAMETERS)
|
||||
switch (cmd.itemArgType)
|
||||
{
|
||||
case ST_FLOAT:
|
||||
@@ -1312,17 +1312,17 @@ char * itemCmd::toString(char * Buffer, int bufLen, int sendFlags, bool scale100
|
||||
if (!Buffer || !bufLen) return NULL;
|
||||
*Buffer=0;
|
||||
char * argPtr=Buffer;
|
||||
if (isCommand() && (sendFlags & SEND_COMMAND))
|
||||
if (isCommand() && (sendFlags & FLAG_COMMAND))
|
||||
{
|
||||
int len;
|
||||
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);
|
||||
argPtr+=len;
|
||||
bufLen-=len;
|
||||
bufLen--;
|
||||
}
|
||||
if (isValue() && (sendFlags & SEND_PARAMETERS))
|
||||
if (isValue() && (sendFlags & FLAG_PARAMETERS))
|
||||
{
|
||||
//strncat(Buffer, " ", bufLen);
|
||||
//bufLen--;
|
||||
|
||||
@@ -58,20 +58,27 @@ const cmdstr commands_P[] PROGMEM =
|
||||
#define CMD_HSV 0x18
|
||||
|
||||
#define CMD_MASK 0xff
|
||||
#define FLAG_MASK 0xff00
|
||||
#define FLAG_MASK 0xffff00
|
||||
//#define STATE_MASK 0xff0000
|
||||
|
||||
#define CMD_VOID 0
|
||||
#define CMD_UNKNOWN -1
|
||||
#define CMD_JSON -2
|
||||
|
||||
#define SEND_IMMEDIATE 0x1
|
||||
#define SEND_COMMAND 0x100
|
||||
#define SEND_PARAMETERS 0x200
|
||||
#define SEND_RETRY 0x400
|
||||
#define SEND_DEFFERED 0x800
|
||||
#define SEND_DELAYED 0x1000
|
||||
#define ACTION_NEEDED 0x2000
|
||||
#define ACTION_IN_PROCESS 0x4000
|
||||
//FLAGS
|
||||
#define FLAG_SEND_IMMEDIATE 0x1
|
||||
#define FLAG_COMMAND 0x100
|
||||
#define FLAG_PARAMETERS 0x200
|
||||
#define FLAG_SEND_RETRY 0x400
|
||||
#define FLAG_SEND_DEFFERED 0x800
|
||||
#define FLAG_SEND_DELAYED 0x1000
|
||||
#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);
|
||||
|
||||
bool loadItem(Item * item, uint16_t optionsFlag=SEND_PARAMETERS);
|
||||
bool loadItemDef(Item * item, uint16_t optionsFlag=SEND_PARAMETERS );
|
||||
bool saveItem(Item * item, uint16_t optionsFlag=SEND_PARAMETERS);
|
||||
bool loadItem(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS);
|
||||
bool loadItemDef(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS );
|
||||
bool saveItem(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS);
|
||||
|
||||
itemCmd Int(int32_t i);
|
||||
itemCmd Int(uint32_t i);
|
||||
@@ -209,7 +216,7 @@ public:
|
||||
uint8_t getCmd();
|
||||
uint8_t getArgType();
|
||||
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 isChannelCommand();
|
||||
|
||||
@@ -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;
|
||||
|
||||
itemCmd ic;
|
||||
ic.loadItem(&item,SEND_COMMAND|SEND_PARAMETERS);
|
||||
ic.loadItem(&item,FLAG_COMMAND|FLAG_PARAMETERS);
|
||||
char buf[32];
|
||||
response=ic.toString(buf, sizeof(buf));
|
||||
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);}
|
||||
|
||||
itemCmd ic;
|
||||
ic.loadItem(&item,SEND_COMMAND|SEND_PARAMETERS);
|
||||
ic.loadItem(&item,FLAG_COMMAND|FLAG_PARAMETERS);
|
||||
|
||||
char buf[32];
|
||||
response=ic.toString(buf, sizeof(buf));
|
||||
@@ -1392,8 +1392,8 @@ setupSyslog();
|
||||
switch (it.itemType) {
|
||||
case CH_THERMO:
|
||||
if (cmd<1) it.setCmd(CMD_OFF);
|
||||
it.setFlag(SEND_COMMAND);
|
||||
if (it.itemVal) it.setFlag(SEND_PARAMETERS);
|
||||
it.setFlag(FLAG_COMMAND);
|
||||
if (it.itemVal) it.setFlag(FLAG_PARAMETERS);
|
||||
pinMode(pin, OUTPUT);
|
||||
digitalWrite(pin, false); //Initially, all thermostates are LOW (OFF for electho heaters, open for water NO)
|
||||
debugSerial<<F("Thermo:")<<pin<<F("=LOW")<<F(";");
|
||||
|
||||
@@ -50,7 +50,7 @@ uint32_t timer = item->getExt();
|
||||
item->setExt(millisNZ());
|
||||
|
||||
itemCmd st;
|
||||
st.loadItem(item,SEND_PARAMETERS|SEND_COMMAND);
|
||||
st.loadItem(item,FLAG_PARAMETERS|FLAG_COMMAND);
|
||||
float val = st.getFloat();
|
||||
//short cmd = st.getCmd();
|
||||
debugSerial<<"CTR: tick val:"<<val<<endl;
|
||||
@@ -59,7 +59,7 @@ uint32_t timer = item->getExt();
|
||||
st.Float(val);
|
||||
st.saveItem(item);
|
||||
debugSerial<<"CTR: tick saved val:"<<val<<endl;
|
||||
item->SendStatus(SEND_PARAMETERS);
|
||||
item->SendStatus(FLAG_PARAMETERS);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
489
lighthub/modules/out_mercury.cpp
Normal file
489
lighthub/modules/out_mercury.cpp
Normal 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
|
||||
69
lighthub/modules/out_mercury.h
Normal file
69
lighthub/modules/out_mercury.h
Normal 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
|
||||
@@ -15,7 +15,7 @@ extern aJsonObject *modbusObj;
|
||||
extern ModbusMaster node;
|
||||
extern short modbusBusy;
|
||||
extern void modbusIdle(void) ;
|
||||
static uint32_t mbusSlenceTimer = 0;
|
||||
uint32_t mbusSlenceTimer = 0;
|
||||
|
||||
struct reg_t
|
||||
{
|
||||
@@ -97,6 +97,7 @@ serialParamType str2SerialParam(char * str)
|
||||
return static_cast<serialParamType> (SERIAL_8N1);
|
||||
}
|
||||
*/
|
||||
uint16_t swap (uint16_t x) {return ((x & 0xff) << 8) | ((x & 0xff00) >> 8);}
|
||||
|
||||
int str2regSize(char * str)
|
||||
{
|
||||
@@ -279,12 +280,12 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
||||
break;
|
||||
case PAR_I32:
|
||||
//isSigned=true;
|
||||
param = data | (node.getResponseBuffer(posInBuffer+1)<<16);
|
||||
param = swap(data ) | swap(node.getResponseBuffer(posInBuffer+1)<<16);
|
||||
mappedParam.Int((int32_t)param);
|
||||
break;
|
||||
|
||||
case PAR_U32:
|
||||
param = data | (node.getResponseBuffer(posInBuffer+1)<<16);
|
||||
param = swap(data )| swap (node.getResponseBuffer(posInBuffer+1)<<16 );
|
||||
mappedParam.Int((uint32_t)param);
|
||||
break;
|
||||
|
||||
@@ -345,10 +346,10 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
||||
switch (idObj->valueint)
|
||||
{
|
||||
case S_CMD:
|
||||
mappedParam.saveItem(item,SEND_COMMAND);
|
||||
mappedParam.saveItem(item,FLAG_COMMAND);
|
||||
break;
|
||||
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;
|
||||
case PAR_I32:
|
||||
case PAR_U32:
|
||||
res = node.writeSingleRegister(regObj->valueint,value & 0xFFFF);
|
||||
res += node.writeSingleRegister(regObj->valueint+1,value >> 16) ;
|
||||
res = node.writeSingleRegister(regObj->valueint,swap(value & 0xFFFF));
|
||||
res += node.writeSingleRegister(regObj->valueint+1,swap(value >> 16)) ;
|
||||
break;
|
||||
|
||||
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)))
|
||||
{
|
||||
|
||||
// Clean_up SEND_ERROR flag
|
||||
// Clean_up FLAG_SEND_ERROR flag
|
||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
{
|
||||
aJsonObject *execObj = itemParametersObj->child;
|
||||
|
||||
@@ -61,8 +61,8 @@ digitalWrite(pinDown,INACTIVE);
|
||||
|
||||
pinMode(pinFeedback, INPUT);
|
||||
item->setExt(0);
|
||||
item->clearFlag(ACTION_NEEDED);
|
||||
item->clearFlag(ACTION_IN_PROCESS);
|
||||
item->clearFlag(FLAG_ACTION_NEEDED);
|
||||
item->clearFlag(FLAG_ACTION_IN_PROCESS);
|
||||
driverStatus = CST_INITIALIZED;
|
||||
motorQuote = MOTOR_QUOTE;
|
||||
return 1;
|
||||
@@ -105,13 +105,13 @@ if (cause==POLLING_SLOW) return 0;
|
||||
int curPos = -1;
|
||||
int targetPos = -1;
|
||||
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)
|
||||
{
|
||||
item->setFlag(ACTION_IN_PROCESS);
|
||||
item->setFlag(FLAG_ACTION_IN_PROCESS);
|
||||
motorQuote--;
|
||||
}
|
||||
else return 0;
|
||||
@@ -245,8 +245,8 @@ else //Target zone
|
||||
digitalWrite(pinUp,INACTIVE);
|
||||
digitalWrite(pinDown,INACTIVE);
|
||||
item->setExt(0);
|
||||
item->clearFlag(ACTION_NEEDED);
|
||||
item->clearFlag(ACTION_IN_PROCESS);
|
||||
item->clearFlag(FLAG_ACTION_NEEDED);
|
||||
item->clearFlag(FLAG_ACTION_IN_PROCESS);
|
||||
motorQuote++;
|
||||
}
|
||||
|
||||
@@ -269,7 +269,7 @@ int suffixCode = cmd.getSuffix();
|
||||
//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
|
||||
|
||||
item->setFlag(ACTION_NEEDED);
|
||||
item->setFlag(FLAG_ACTION_NEEDED);
|
||||
|
||||
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_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
|
||||
}
|
||||
else item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
|
||||
else item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
|
||||
*/
|
||||
return 1;
|
||||
//break;
|
||||
@@ -307,7 +307,7 @@ case S_CMD:
|
||||
return 1;
|
||||
|
||||
case CMD_OFF:
|
||||
////item->SendStatus(SEND_COMMAND);
|
||||
////item->SendStatus(FLAG_COMMAND);
|
||||
if (item->getExt()) item->setExt(millisNZ()); //Extend motor time
|
||||
return 1;
|
||||
|
||||
|
||||
@@ -159,10 +159,10 @@ while (i)
|
||||
{
|
||||
setObj->valueint=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())
|
||||
@@ -175,7 +175,7 @@ while (i)
|
||||
debugSerial<<"Turning ON"<<endl;
|
||||
cmdObj->valueint = 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();
|
||||
@@ -186,20 +186,20 @@ while (i)
|
||||
{ debugSerial<<"Turning OFF"<<endl;
|
||||
cmdObj->valueint = 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;
|
||||
}
|
||||
|
||||
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())
|
||||
{
|
||||
setObj->valueint = cmd.getPercents255();
|
||||
//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);
|
||||
}
|
||||
|
||||
@@ -122,8 +122,8 @@ if (getConfig())
|
||||
{
|
||||
infoSerial<<F("PID config loaded ")<< item->itemArr->name<<endl;
|
||||
//item->On(); // Turn ON pid by default
|
||||
// if (item->getCmd()) item->setFlag(SEND_COMMAND);
|
||||
// if (item->itemVal) item->setFlag(SEND_PARAMETERS);
|
||||
// if (item->getCmd()) item->setFlag(FLAG_COMMAND);
|
||||
// if (item->itemVal) item->setFlag(FLAG_PARAMETERS);
|
||||
store->prevOut = -2.0;
|
||||
store->driverStatus = CST_INITIALIZED;
|
||||
return 1;
|
||||
@@ -321,7 +321,7 @@ if (itemCascadeObj) executeCommand(itemCascadeObj,-1,cmd);
|
||||
}
|
||||
|
||||
//cmd.saveItem(item);
|
||||
//item->SendStatus(SEND_PARAMETERS);
|
||||
//item->SendStatus(FLAG_PARAMETERS);
|
||||
return 1;
|
||||
//break;
|
||||
|
||||
@@ -348,14 +348,14 @@ case S_CMD:
|
||||
|
||||
case CMD_ENABLE:
|
||||
item->setCmd(CMD_ENABLE);
|
||||
item->SendStatus(SEND_COMMAND);
|
||||
item->SendStatus(FLAG_COMMAND);
|
||||
executeCommand(oCmd,-1,value);
|
||||
store->prevOut=-2.0;
|
||||
return 1;
|
||||
|
||||
case CMD_DISABLE:
|
||||
item->setCmd(CMD_DISABLE);
|
||||
item->SendStatus(SEND_COMMAND);
|
||||
item->SendStatus(FLAG_COMMAND);
|
||||
executeCommand(oCmd,-1,value);
|
||||
return 1;
|
||||
/*
|
||||
|
||||
@@ -41,8 +41,8 @@ debugSerial<<F("Relay-Out #")<<pin<<F(" init")<<endl;
|
||||
pinMode(pin, OUTPUT);
|
||||
digitalWrite(pin,INACTIVE);
|
||||
if (item) item->setExt(0);
|
||||
//if (item->getCmd()) item->setFlag(SEND_COMMAND);
|
||||
//if (item->itemVal) item->setFlag(SEND_PARAMETERS);
|
||||
//if (item->getCmd()) item->setFlag(FLAG_COMMAND);
|
||||
//if (item->itemVal) item->setFlag(FLAG_PARAMETERS);
|
||||
driverStatus = CST_INITIALIZED;
|
||||
if (item->isActive()>0) ///????
|
||||
{
|
||||
|
||||
@@ -209,9 +209,9 @@ case S_HSV:
|
||||
{
|
||||
if (chActive>0 && !st.getPercents()) item->setCmd(CMD_OFF);
|
||||
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;
|
||||
//break;
|
||||
@@ -234,7 +234,7 @@ case S_CMD:
|
||||
|
||||
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;
|
||||
}
|
||||
else
|
||||
@@ -245,7 +245,7 @@ case S_CMD:
|
||||
// Store
|
||||
//item->setVal(st.getInt());
|
||||
st.saveItem(item);
|
||||
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS );
|
||||
item->SendStatus(SEND_COMMAND | FLAG_PARAMETERS );
|
||||
}
|
||||
|
||||
PixelCtrl(st,from,to);
|
||||
|
||||
@@ -250,7 +250,7 @@ void parseBytes(const char *str, char separator, byte *bytes, int maxBytes, int
|
||||
|
||||
void printFloatValueToStr(char *valstr, float value) {
|
||||
#if defined(ESP8266) || defined(ARDUINO_ARCH_ESP32)
|
||||
sprintf(valstr, "%2.1f", value);
|
||||
sprintf(valstr, "%2.2f", value);
|
||||
#endif
|
||||
#if defined(__AVR__)
|
||||
sprintf(valstr, "%d", (int)value);
|
||||
@@ -261,7 +261,7 @@ void printFloatValueToStr(char *valstr, float value) {
|
||||
valstr[val_len+2]='\0';
|
||||
#endif
|
||||
#if defined(__SAM3X8E__)
|
||||
sprintf(valstr, "%2.1f",value);
|
||||
sprintf(valstr, "%2.2f",value);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -798,5 +798,6 @@ bool getPinVal(uint8_t pin)
|
||||
return (0!=(*portOutputRegister( digitalPinToPort(pin) ) & digitalPinToBitMask(pin)));
|
||||
}
|
||||
|
||||
|
||||
#pragma message(VAR_NAME_VALUE(debugSerial))
|
||||
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD))
|
||||
|
||||
@@ -76,3 +76,4 @@ unsigned long millisNZ(uint8_t shift=0);
|
||||
serialParamType str2SerialParam(char * str);
|
||||
String toString(const IPAddress& address);
|
||||
bool getPinVal(uint8_t pin);
|
||||
int str2regSize(char * str);
|
||||
|
||||
1
upload.bat
Normal file
1
upload.bat
Normal file
@@ -0,0 +1 @@
|
||||
arduinoOTA -address 192.168.11.120 -port 80 -username arduino -password password -b -upload /sketch -sketch $1 ;sleep 6
|
||||
Reference in New Issue
Block a user