mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 09831781aa | |||
| 340d54be09 | |||
| bcae3c9d50 | |||
| 1654f05bbe | |||
| 99466f6e9f | |||
| 05ea031977 | |||
| 5ec57f0414 | |||
| 7ab78ab2ae | |||
| 4d909dd449 | |||
|
|
b3db766b1a | ||
| 080cdd4e22 | |||
| 91d5acf619 | |||
| 454b88fbbf | |||
| 6e283e32db | |||
| 18fbc783b5 | |||
|
|
5235bb67c1 | ||
| 9683e51c18 | |||
| fd65c1a3a1 |
@@ -43,4 +43,7 @@
|
||||
-UMCP23017
|
||||
-D BEARSSL_SSL_BASIC
|
||||
-D SPILED_DISABLE
|
||||
-D PWM_DISABLE
|
||||
-D PWM_DISABLE
|
||||
|
||||
# WAK for HDC1080 (pin D3 on wemos is IO0)
|
||||
-D WAK_PIN=D3
|
||||
@@ -39,4 +39,5 @@
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
-D MERCURY_ENABLE
|
||||
#-D IPMODBUS
|
||||
#-D IPMODBUS
|
||||
-D CONFIG_CLEAN_PIN=2
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,3 +1,3 @@
|
||||
export PORT=cu.usbmodem14101
|
||||
export PORT=cu.usbmodem142101
|
||||
echo . | stty -f /dev/$PORT speed 1200
|
||||
../tools/mac/tool-bossac/bossac -U false -p $PORT -i -e -w -v -b firmware.bin -R
|
||||
../tools/mac/tool-bossac/bossac -U false -p $PORT -i -w -v -b firmware.bin -R
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@
|
||||
#define CST_UNKNOWN 0
|
||||
#define CST_FAILED 1
|
||||
#define CST_INITIALIZED 2
|
||||
#define CST_USER 3
|
||||
|
||||
class abstractCh {
|
||||
public:
|
||||
@@ -11,7 +12,7 @@ public:
|
||||
virtual ~abstractCh(){};
|
||||
virtual int Poll(short cause) {return 0;}
|
||||
virtual int Setup() =0; //Should initialize hardware and reserve resources
|
||||
virtual int Anounce () {return 0;};
|
||||
// virtual int Anounce () {return 0;};
|
||||
virtual int Stop() {return 0;}; //Should free resources
|
||||
virtual int Status() {return CST_UNKNOWN;}
|
||||
virtual void setStatus(uint8_t status) {}
|
||||
|
||||
@@ -13,7 +13,7 @@ public:
|
||||
virtual bool isAllowed(itemCmd cmd){return true;};
|
||||
virtual itemCmd getDefaultOnVal(){return itemCmd().Percents255(255);};
|
||||
virtual int getChanType(){return 0;}
|
||||
virtual int getDefaultStorageType(){return 0;} /// Remove?? Now getChanType used instead
|
||||
// virtual int getDefaultStorageType(){return 0;} /// Remove?? Now getChanType used instead
|
||||
virtual int Status() override;
|
||||
virtual void setStatus(uint8_t status) override;
|
||||
int Setup() override;
|
||||
|
||||
@@ -16,7 +16,7 @@ short colorChannel::getChannelAddr(short n)
|
||||
return item->getArg(n);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int colorChannel::getDefaultStorageType()
|
||||
{
|
||||
|
||||
@@ -33,7 +33,7 @@ int colorChannel::getDefaultStorageType()
|
||||
return ST_VOID;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
int colorChannel::isActive()
|
||||
{
|
||||
itemCmd st;
|
||||
@@ -58,7 +58,6 @@ case S_NOTFOUND:
|
||||
// turn on and set
|
||||
toExecute = true;
|
||||
case S_SET:
|
||||
//case S_ESET:
|
||||
case S_HSV:
|
||||
PixelCtrl(cmd, subItem, toExecute, authorized);
|
||||
return 1;
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
numArgs = item->getArgCount(); // and how many addresses is configured
|
||||
};
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized=false) override;
|
||||
int getDefaultStorageType()override;
|
||||
//int getDefaultStorageType()override;
|
||||
virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false ) =0;
|
||||
short getChannelAddr(short n =0);
|
||||
// int isActive() override;
|
||||
|
||||
171
lighthub/dmx.cpp
171
lighthub/dmx.cpp
@@ -47,6 +47,7 @@ volatile uint32_t checkTimestamp=0L;
|
||||
#if defined(_dmxin)
|
||||
volatile uint32_t D_State=0;
|
||||
volatile unsigned long D_checkT=0;
|
||||
uint8_t DMXINChannels=0;
|
||||
#endif
|
||||
|
||||
#ifdef _artnet
|
||||
@@ -61,6 +62,61 @@ extern aJsonObject *items;
|
||||
extern aJsonObject *dmxArr;
|
||||
|
||||
|
||||
|
||||
itemCmd rgb2hsv(itemCmd in)
|
||||
{
|
||||
itemCmd out;
|
||||
out.setArgType(ST_HSV255);
|
||||
|
||||
double min, max, delta;
|
||||
|
||||
double inr=in.param.r/255;
|
||||
double ing=in.param.g/255;
|
||||
double inb=in.param.b/255;
|
||||
double inw=in.param.w/255;
|
||||
|
||||
min = inr < ing ? inr : ing;
|
||||
min = min < inb ? min : inb;
|
||||
|
||||
max = inr > ing ? inr : ing;
|
||||
max = max > inb ? max : inb;
|
||||
max = max > inw ? max : inw;
|
||||
|
||||
out.param.v = max*255; // v
|
||||
delta = max - min;
|
||||
if (delta < 0.00001)
|
||||
{
|
||||
out.param.s = 0;
|
||||
out.param.h = 0; // undefined, maybe nan?
|
||||
return out;
|
||||
}
|
||||
if( max > 0.0 ) { // NOTE: if Max is == 0, this divide would cause a crash
|
||||
out.param.s = (delta / max)*100; // s
|
||||
} else {
|
||||
// if max is 0, then r = g = b = 0
|
||||
// s = 0, h is undefined
|
||||
out.param.s = 0;
|
||||
out.param.h = 0; // its now undefined
|
||||
return out;
|
||||
}
|
||||
double outh;
|
||||
if( inr >= max ) // > is bogus, just keeps compilor happy
|
||||
outh = ( ing - inb ) / delta; // between yellow & magenta
|
||||
else
|
||||
if( ing >= max )
|
||||
outh = 2.0 + ( inb - inr ) / delta; // between cyan & yellow
|
||||
else
|
||||
outh = 4.0 + ( inr - ing ) / delta; // between magenta & cyan
|
||||
|
||||
outh *= 60.0; // degrees
|
||||
|
||||
if( outh < 0.0 )
|
||||
outh += 360.0;
|
||||
out.param.h=outh;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
int itemCtrl2(char* name,int r,int g, int b, int w)
|
||||
{
|
||||
if (!items) return 0;
|
||||
@@ -68,7 +124,6 @@ int itemCtrl2(char* name,int r,int g, int b, int w)
|
||||
|
||||
if (itemArr && (itemArr->type==aJson_Array))
|
||||
{
|
||||
|
||||
short itemtype = aJson.getArrayItem(itemArr,0)->valueint;
|
||||
short itemaddr = aJson.getArrayItem(itemArr,1)->valueint;
|
||||
switch (itemtype){
|
||||
@@ -84,7 +139,6 @@ int itemCtrl2(char* name,int r,int g, int b, int w)
|
||||
|
||||
case CH_RGB: // RGB
|
||||
{
|
||||
|
||||
DmxWrite(itemaddr, r);
|
||||
DmxWrite(itemaddr+1, g);
|
||||
DmxWrite(itemaddr+2, b);
|
||||
@@ -96,7 +150,7 @@ int itemCtrl2(char* name,int r,int g, int b, int w)
|
||||
if (groupArr && (groupArr->type==aJson_Array))
|
||||
{ aJsonObject *i =groupArr->child;
|
||||
while (i)
|
||||
{ //Serial.println(i->valuestring);
|
||||
{
|
||||
if (i->type == aJson_String) itemCtrl2(i->valuestring,r,g,b,w);
|
||||
i=i->next;}
|
||||
}
|
||||
@@ -119,9 +173,34 @@ void DMXImmediateUpdate(short tch,short r, short g, short b, short w) {
|
||||
}
|
||||
}
|
||||
|
||||
void DMXSemiImmediateUpdate(short tch,short trh, int val)
|
||||
void DMXSemiImmediateUpdate(short tch,short r, short g, short b, short w)
|
||||
{
|
||||
//Here any code for passthrow between DMX IN and DMX OUT in idle state
|
||||
if (dmxArr && (dmxArr->type==aJson_Array))
|
||||
|
||||
{
|
||||
aJsonObject *DMXch = aJson.getArrayItem(dmxArr,tch);
|
||||
char* itemname = NULL;
|
||||
if (DMXch->type == aJson_String) itemname=DMXch->valuestring;
|
||||
if (itemname)
|
||||
{
|
||||
Item it(itemname);
|
||||
if (!r && !g && !b && !w) it.Ctrl(itemCmd().Cmd(CMD_OFF).setSuffix(S_CMD));
|
||||
else
|
||||
{
|
||||
/*
|
||||
CRGB rgb;
|
||||
rgb.r = r;
|
||||
rgb.g = g;
|
||||
rgb.b = b;
|
||||
CHSV hsv = rgb2hsv_approximate(rgb);
|
||||
it.Ctrl(itemCmd().HSV255(hsv.h,hsv.s,hsv.v).setSuffix(S_SET)); */
|
||||
it.Ctrl(itemCmd().RGBW(r,g,b,w).setSuffix(S_SET));
|
||||
//it.Ctrl(rgb2hsv(itemCmd().RGBW(r,g,b,w)).setSuffix(S_SET));
|
||||
it.Ctrl(itemCmd().Cmd(CMD_ON).setSuffix(S_CMD));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DMXput(void)
|
||||
@@ -132,6 +211,7 @@ for (short tch=0; tch<=3 ; tch++)
|
||||
short base = tch*4;
|
||||
DMXImmediateUpdate(tch,DMXin[base],DMXin[base+1],DMXin[base+2],DMXin[base+3]);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern volatile uint8_t timerHandlerBusy;
|
||||
@@ -140,81 +220,62 @@ extern volatile uint8_t timerHandlerBusy;
|
||||
volatile int DMXinDoublecheck=0;
|
||||
#endif
|
||||
|
||||
// INVOKED BY INTERRUPTS - MUST BE SAFE CODE
|
||||
void DMXUpdate(void)
|
||||
{
|
||||
#if defined(_dmxin)
|
||||
int t;
|
||||
if(!DMXin) return;
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
if (dmxin.getRxLength()<16) return;
|
||||
if (dmxin.getRxLength()<DMXINChannels) return;
|
||||
#endif
|
||||
for (short tch=0; tch<=3 ; tch++)
|
||||
|
||||
uint8_t RGBWChannels=DMXINChannels >> 2;
|
||||
for (short tch=0; tch<RGBWChannels ; tch++)
|
||||
{
|
||||
short base = tch*4;
|
||||
bool updated = 0;
|
||||
bool confirmed = 0;
|
||||
bool updated = false;
|
||||
int t;
|
||||
|
||||
for (short trh=0; trh<4 ; trh++)
|
||||
if (((t=dmxin.read(base+trh+1)) != DMXin[base+trh]))
|
||||
if ((t=dmxin.read(base+trh+1)) != DMXin[base+trh])
|
||||
{
|
||||
D_State |= (1<<tch);
|
||||
updated=1;
|
||||
if (DMXinDoublecheck>2)
|
||||
{
|
||||
D_State |= (1<<tch);
|
||||
DMXin[base+trh]=t;
|
||||
confirmed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (updated) DMXinDoublecheck++; else DMXinDoublecheck=0;
|
||||
|
||||
|
||||
if (confirmed)
|
||||
DMXin[base+trh]=t;
|
||||
}
|
||||
if (updated)
|
||||
{
|
||||
|
||||
DMXImmediateUpdate(tch,DMXin[base],DMXin[base+1],DMXin[base+2],DMXin[base+3]);
|
||||
//for (int i=1; i<17; i++) {debugSerial.print(dmxin.read(i));debugSerial.print("-");};debugSerial.print("|");
|
||||
D_checkT=millisNZ();
|
||||
}
|
||||
}
|
||||
//Serial.print(D_State,BIN);Serial.println();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void DMXCheck(void)
|
||||
// INVOKED in safe loop
|
||||
void DMXCheck(void)
|
||||
{
|
||||
// CHSV hsv;
|
||||
// CRGB rgb;
|
||||
DMXOUT_propagate();
|
||||
#if defined(_dmxin)
|
||||
|
||||
short t,tch;
|
||||
//Here code for semi-immediate update
|
||||
for (t=1,tch=0; t<=8 ; t<<=1,tch++)
|
||||
if (D_State & t)
|
||||
{
|
||||
// Serial.print(D_State,BIN);Serial.print(":");
|
||||
D_State &= ~t;
|
||||
for (short trh=0; trh<4 ; trh++)
|
||||
DMXSemiImmediateUpdate(tch,trh,DMXin[tch*4+trh]);
|
||||
|
||||
}
|
||||
|
||||
//if ((millis()<D_checkT) || (D_checkT==0)) return;
|
||||
if ( (!D_checkT) || (!isTimeOver(D_checkT,millis(),D_CHECKT))) return;
|
||||
if ( (!D_checkT) || (!isTimeOver(D_checkT,millis(),D_CHECKT))) return;
|
||||
D_checkT=0;
|
||||
uint8_t RGBWChannels=DMXINChannels >> 2;
|
||||
for (short rgbwChan=0; rgbwChan < RGBWChannels; rgbwChan++)
|
||||
{
|
||||
short base = rgbwChan*4;
|
||||
short bitMask = 1 << rgbwChan;
|
||||
if (D_State & bitMask)
|
||||
{
|
||||
D_State &= ~bitMask;
|
||||
DMXSemiImmediateUpdate(rgbwChan,DMXin[base],DMXin[base+1],DMXin[base+2],DMXin[base+3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Here code for network update
|
||||
//int ch = 0;
|
||||
|
||||
DMXput();
|
||||
|
||||
#ifdef _dmxout
|
||||
for (int i=1; i<17; i++) {debugSerial.print(dmxin.read(i));debugSerial.print(";");}
|
||||
debugSerial.println();
|
||||
#endif
|
||||
//#ifdef _dmxout
|
||||
//for (int i=1; i<17; i++) {debugSerial.print(dmxin.read(i));debugSerial.print(";");}
|
||||
//debugSerial.println();
|
||||
//#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -238,7 +299,9 @@ void DMXinSetup(int channels)
|
||||
//DmxSimple.maxChannel(channels);
|
||||
|
||||
#if defined(_dmxin)
|
||||
if (channels>(32*4)) channels = 32*4;
|
||||
DMXin = new uint8_t [channels];
|
||||
DMXINChannels=channels;
|
||||
#if defined(ARDUINO_ARCH_AVR)
|
||||
DMXSerial.init(DMXReceiver,0,channels);
|
||||
if (DMXSerial.getBuffer()) {debugSerial.print(F("Init in ch:"));debugSerial.println(channels);} else debugSerial.println(F("DMXin Buffer alloc err"));
|
||||
|
||||
@@ -146,7 +146,8 @@ if (input->type == aJson_Object) {
|
||||
else
|
||||
{
|
||||
Input in(input);
|
||||
in.Poll(CHECK_INPUT);
|
||||
in.store->aslong = 0;
|
||||
//in.Poll(CHECK_INPUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -524,7 +525,7 @@ bool Input::changeState(uint8_t newState, short cause)
|
||||
if (!inputObj || !store) return false;
|
||||
|
||||
if (newState == IS_REQSTATE)
|
||||
if (store->delayedState && cause != CHECK_INTERRUPT)
|
||||
if (store->delayedState && (cause != CHECK_INTERRUPT))
|
||||
{
|
||||
// Requested delayed change State and safe moment
|
||||
newState=store->reqState; //Retrieve requested state
|
||||
|
||||
@@ -105,7 +105,7 @@ extern aJsonObject *inputs;
|
||||
|
||||
|
||||
typedef union {
|
||||
long int aslong;
|
||||
uint32_t aslong;
|
||||
uint32_t timestamp;
|
||||
// Analog input structure
|
||||
struct {
|
||||
|
||||
@@ -104,8 +104,15 @@ int subitem2cmd(char *payload) {
|
||||
}
|
||||
|
||||
int txt2subItem(char *payload) {
|
||||
int cmd = S_NOTFOUND;
|
||||
if (!payload || !strlen(payload)) return S_NOTFOUND;
|
||||
for(uint8_t i=1; i<suffixNum ;i++)
|
||||
if (strcmp_P(payload, suffix_P[i]) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
return S_NOTFOUND;
|
||||
/*
|
||||
int cmd = S_NOTFOUND;
|
||||
// Check for command
|
||||
if (strcmp_P(payload, SET_P) == 0) cmd = S_SET;
|
||||
else if (strcmp_P(payload, CTRL_P) == 0) cmd = S_CTRL;
|
||||
@@ -120,7 +127,8 @@ int txt2subItem(char *payload) {
|
||||
else if (strcmp_P(payload, VAL_P) == 0) cmd = S_VAL;
|
||||
else if (strcmp_P(payload, DEL_P) == 0) cmd = S_DELAYED;
|
||||
else if (strcmp_P(payload, _RAW_P) == 0) cmd = S_RAW;
|
||||
return cmd;
|
||||
return cmd; */
|
||||
|
||||
}
|
||||
|
||||
//const short defval[4] = {0, 0, 0, 0}; //Type,Arg,Val,Cmd
|
||||
@@ -319,7 +327,7 @@ void Item::setCmd(uint8_t cmdValue) {
|
||||
{
|
||||
itemCmd->type = aJson_Int;
|
||||
itemCmd->valueint = cmdValue & CMD_MASK | itemCmd->valueint & (FLAG_MASK); // Preserve special bits
|
||||
debugSerial<<F("SetCmd:")<<cmdValue<<endl;
|
||||
//debugSerial<<F("SetCmd:")<<cmdValue<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -487,7 +495,7 @@ void Item::setExt(long int par) // Only store if VAL is int (autogenerated or c
|
||||
if(itemExt->type == aJson_NULL) itemExt->type=aJson_Int;
|
||||
else if(itemExt->type != aJson_Int ) return;
|
||||
itemExt->valueint = par;
|
||||
debugSerial<<F("Stored EXT:")<<par<<endl;
|
||||
//debugSerial<<F("Stored EXT:")<<par<<endl;
|
||||
}
|
||||
|
||||
|
||||
@@ -908,6 +916,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
|
||||
int res = -1;
|
||||
uint16_t status2Send = 0;
|
||||
uint8_t command2Set = 0;
|
||||
itemCmd originalCmd = cmd;
|
||||
|
||||
/// Common (GRP & NO GRP) commands
|
||||
switch (cmd.getCmd())
|
||||
@@ -1063,7 +1072,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
|
||||
|
||||
if ((suffixCode==S_CMD) && cmd.isValue())
|
||||
{
|
||||
scheduleOppositeCommand(cmd,chActive,authorized);
|
||||
scheduleOppositeCommand(originalCmd,chActive,authorized);
|
||||
scheduledOppositeCommand = true;
|
||||
}
|
||||
}
|
||||
@@ -1372,7 +1381,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
|
||||
|
||||
if (oppositeCommandToBeSchedulled) //invoked not as group part, delayed
|
||||
{
|
||||
scheduleOppositeCommand(cmd,chActive,authorized);
|
||||
scheduleOppositeCommand(originalCmd,chActive,authorized);
|
||||
status2Send &=~FLAG_PARAMETERS;
|
||||
}
|
||||
} // NO GROUP
|
||||
@@ -1464,7 +1473,7 @@ if ((!driver || driver->isAllowed(cmd)) && (!getFlag(FLAG_FREEZED)))
|
||||
if (!tStore.timestamp16) mqttClient.publish("/alarmoff/snsr", itemArr->name);
|
||||
tStore.tempX100=cmd.getFloat()*100.; //Save measurement
|
||||
tStore.timestamp16=millisNZ(8) & 0xFFFF; //And timestamp
|
||||
debugSerial<<F(" T:")<<tStore.tempX100<<F(" TS:")<<tStore.timestamp16<<endl;
|
||||
//debugSerial<<F(" T:")<<tStore.tempX100<<F(" TS:")<<tStore.timestamp16<<endl;
|
||||
setExt(tStore.asint);
|
||||
res=1;
|
||||
}
|
||||
@@ -1801,9 +1810,14 @@ int Item::SendStatus(int sendFlags) {
|
||||
|
||||
strncat(addrstr, "/", sizeof(addrstr)-1);
|
||||
|
||||
// if (sendFlags & FLAG_SEND_DELAYED)
|
||||
// strncat_P(addrstr, DEL_P, sizeof(addrstr)-1);
|
||||
// else strncat_P(addrstr, SET_P, sizeof(addrstr)-1);
|
||||
|
||||
if (sendFlags & FLAG_SEND_DELAYED)
|
||||
strncat_P(addrstr, DEL_P, sizeof(addrstr)-1);
|
||||
else strncat_P(addrstr, SET_P, sizeof(addrstr)-1);
|
||||
strncat_P(addrstr, suffix_P[S_DELAYED], sizeof(addrstr)-1);
|
||||
else strncat_P(addrstr, suffix_P[S_SET], sizeof(addrstr)-1);
|
||||
|
||||
|
||||
// Preparing parameters payload //////////
|
||||
switch (st.getArgType()) {
|
||||
@@ -1872,7 +1886,8 @@ int Item::SendStatus(int sendFlags) {
|
||||
strncat(addrstr, subItem, sizeof(addrstr)-1);
|
||||
}
|
||||
strncat(addrstr, "/", sizeof(addrstr)-1);
|
||||
strncat_P(addrstr, CMD_P, sizeof(addrstr)-1);
|
||||
// strncat_P(addrstr, CMD_P, sizeof(addrstr)-1);
|
||||
strncat_P(addrstr, suffix_P[S_CMD], sizeof(addrstr)-1);
|
||||
|
||||
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<cmdstr<<endl;
|
||||
if (mqttClient.connected() && !ethernetIdleCount)
|
||||
@@ -1909,7 +1924,8 @@ int Item::SendStatus(int sendFlags) {
|
||||
strncat(addrstr, subItem, sizeof(addrstr)-1);
|
||||
}
|
||||
strncat(addrstr, "/", sizeof(addrstr)-1);
|
||||
strncat_P(addrstr, CTRL_P, sizeof(addrstr)-1);
|
||||
//strncat_P(addrstr, CTRL_P, sizeof(addrstr)-1);
|
||||
strncat_P(addrstr, suffix_P[S_CTRL], sizeof(addrstr)-1);
|
||||
|
||||
debugSerial<<F("Pub: ")<<addrstr<<F("->")<<cmdstr<<endl;
|
||||
if (mqttClient.connected() && !ethernetIdleCount)
|
||||
@@ -2006,38 +2022,6 @@ int Item::checkRetry() {
|
||||
return M_CLEAN;
|
||||
}
|
||||
|
||||
/*
|
||||
bool Item::resumeModbus()
|
||||
{
|
||||
|
||||
if (modbusBusy) return false;
|
||||
bool success = true;
|
||||
|
||||
//debugSerial<<F("Pushing MB: ");
|
||||
configLocked++;
|
||||
if (items) {
|
||||
aJsonObject * item = items->child;
|
||||
while (items && item)
|
||||
if (item->type == aJson_Array && aJson.getArraySize(item)>1) {
|
||||
Item it(item);
|
||||
if (it.isValid()) {
|
||||
|
||||
short res = it.checkModbusRetry();
|
||||
if (res<=0) success = false;
|
||||
|
||||
} //isValid
|
||||
yield();
|
||||
item = item->next;
|
||||
} //if
|
||||
debugSerial<<endl;
|
||||
}
|
||||
configLocked--;
|
||||
if (success) isPendedModbusWrites=false;
|
||||
return true;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
//////////////////// Begin of legacy MODBUS code - to be moved in separate module /////////////////////
|
||||
|
||||
|
||||
@@ -2409,14 +2393,6 @@ int Item::checkModbusDimmer() {
|
||||
uint16_t reg = getArg(MODBUS_CMD_ARG_REG);
|
||||
int _regType = MODBUS_HOLDING_REG_TYPE;
|
||||
if (numpar >= (MODBUS_CMD_ARG_REG_TYPE+1)) _regType = aJson.getArrayItem(itemArg, MODBUS_CMD_ARG_REG_TYPE)->valueint;
|
||||
// short mask = getArg(2);
|
||||
// debugSerial<<F("Modbus polling "));
|
||||
// debugSerial<<addr);
|
||||
// debugSerial<<F("=>"));
|
||||
// debugSerial<<reg, HEX);
|
||||
// debugSerial<<F("(T:"));
|
||||
// debugSerial<<_regType);
|
||||
// debugSerial<<F(")"));
|
||||
|
||||
int data;
|
||||
|
||||
|
||||
@@ -37,6 +37,11 @@ e-mail anklimov@gmail.com
|
||||
#define S_TEMP 12
|
||||
#define S_RAW 13
|
||||
|
||||
typedef char suffixstr[5];
|
||||
const suffixstr suffix_P[] PROGMEM =
|
||||
{"","cmd","set","val","del","HSV","RGB","fan","mode","ctrl","hue","sat","temp","raw"};
|
||||
#define suffixNum sizeof(suffix_P)/sizeof(suffixstr)
|
||||
|
||||
#define S_ADDITIONAL 13
|
||||
|
||||
#define CH_DIMMER 0 //DMX 1-4 ch
|
||||
@@ -63,16 +68,6 @@ e-mail anklimov@gmail.com
|
||||
#define CH_HUMIDIFIER 21
|
||||
#define CH_MERCURY 22
|
||||
|
||||
//#define CHANNEL_TYPES 13
|
||||
|
||||
//static uint32_t pollInterval[CHANNEL_TYPES] = {0,0,0,0,MODB};
|
||||
//static uint32_t nextPollTime[CHANNEL_TYPES] = {0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
|
||||
#define CH_WHITE 127//
|
||||
|
||||
|
||||
|
||||
|
||||
#define POLLING_SLOW 1
|
||||
#define POLLING_FAST 2
|
||||
#define POLLING_INT 3
|
||||
@@ -157,24 +152,16 @@ class Item
|
||||
int VacomSetFan (itemCmd st);
|
||||
int VacomSetHeat(itemCmd st);
|
||||
int modbusDimmerSet(itemCmd st);
|
||||
|
||||
int modbusDimmerSet(int addr, uint16_t _reg, int _regType, int _mask, uint16_t value);
|
||||
void mb_fail(int result=0);
|
||||
void Parse();
|
||||
int checkModbusDimmer();
|
||||
int checkModbusDimmer(int data);
|
||||
|
||||
int checkRetry();
|
||||
//boolean checkVCRetry();
|
||||
//boolean checkHeatRetry();
|
||||
void sendDelayedStatus();
|
||||
//bool resumeModbus();
|
||||
|
||||
|
||||
int checkFM();
|
||||
char defaultSubItem[16];
|
||||
int defaultSuffixCode;
|
||||
|
||||
};
|
||||
|
||||
typedef union
|
||||
|
||||
@@ -1171,8 +1171,8 @@ bool itemCmd::saveItem(Item * item, uint16_t optionsFlag)
|
||||
item->setVal(param.asInt32);
|
||||
item->setSubtype(cmd.itemArgType);
|
||||
}
|
||||
debugSerial<<F("Saved:");
|
||||
debugOut();
|
||||
//debugSerial<<F("Saved:");
|
||||
//debugOut();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -170,6 +170,13 @@ bool cleanConf(bool wait)
|
||||
{
|
||||
if (!root) return true;
|
||||
bool clean = true;
|
||||
if (configLocked)
|
||||
{
|
||||
errorSerial<<F("Can not clean - locked")<<endl;
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
No more unsafe operations
|
||||
if (wait)
|
||||
{
|
||||
debugSerial<<F("Unlocking config ...")<<endl;
|
||||
@@ -196,6 +203,7 @@ if (configLocked)
|
||||
clean = false;
|
||||
}
|
||||
} //wait
|
||||
*/
|
||||
|
||||
debugSerial<<F("Stopping channels ...")<<endl;
|
||||
timerHandlerBusy++;
|
||||
@@ -230,7 +238,7 @@ debugSerial<<F("Deleting conf. RAM was:")<<freeRam();
|
||||
topics = NULL;
|
||||
mqttArr = NULL;
|
||||
deviceName = NULL;
|
||||
topics = NULL;
|
||||
|
||||
#ifdef _dmxout
|
||||
dmxArr = NULL;
|
||||
#endif
|
||||
@@ -400,7 +408,7 @@ void mqttCallback(char *topic, byte *payload, unsigned int length)
|
||||
|
||||
int fr = freeRam();
|
||||
|
||||
debugSerial<<F("\n")<<fr<<F(":[")<<topic<<F("] ");
|
||||
debugSerial<<fr<<F(":[")<<topic<<F("] ");
|
||||
|
||||
if (fr < 250+MQTT_TOPIC_LENGTH) {
|
||||
errorSerial<<F("OutOfMemory!")<<endl;
|
||||
@@ -619,12 +627,14 @@ lan_status lanLoop() {
|
||||
if (!initializedListeners)
|
||||
{
|
||||
setupSyslog();
|
||||
debugSerial<<F("Setup OTA")<<endl;
|
||||
setupOTA();
|
||||
#ifdef _artnet
|
||||
if (artnet) artnet->begin();
|
||||
#endif
|
||||
|
||||
#ifdef IPMODBUS
|
||||
debugSerial<<F("Setup IPModbus")<<endl;
|
||||
setupIpmodbus();
|
||||
#endif
|
||||
initializedListeners = true;
|
||||
@@ -753,7 +763,7 @@ lan_status lanLoop() {
|
||||
lanStatus=READ_RE_CONFIG;
|
||||
break;
|
||||
|
||||
case READ_RE_CONFIG: // Restore config from FLASH, re-init LAN
|
||||
case READ_RE_CONFIG: // Restore config from FLASH, re-init LAN
|
||||
if (loadConfigFromEEPROM()) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
|
||||
else
|
||||
if (isTimeOver(timerLanCheckTime,millis(),TIMEOUT_RELOAD))
|
||||
@@ -763,8 +773,32 @@ lan_status lanLoop() {
|
||||
}
|
||||
break;
|
||||
|
||||
case DO_GET:
|
||||
if (mqttClient.connected()) mqttClient.disconnect();
|
||||
timerLanCheckTime = millis();// + 5000;
|
||||
lanStatus = GET;
|
||||
break;
|
||||
|
||||
case GET:
|
||||
statusLED.set(ledRED|ledGREEN|((configLoaded)?ledBLINK:0));
|
||||
if (configLocked) return GET;
|
||||
lanStatus = GET_IN_PROGRESS;
|
||||
if (loadConfigFromHttp()==200) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
|
||||
else if (configLoaded) {
|
||||
infoSerial<<F("Continue with previously loaded config")<<endl;
|
||||
lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
|
||||
}
|
||||
|
||||
else if (Ethernet.localIP()) lanStatus = DO_READ_RE_CONFIG;
|
||||
|
||||
else lanStatus = DO_REINIT; //Load from NVRAM
|
||||
|
||||
break;
|
||||
|
||||
|
||||
case DO_NOTHING:
|
||||
case OPERATION_NO_MQTT:
|
||||
case GET_IN_PROGRESS:
|
||||
;
|
||||
}
|
||||
|
||||
@@ -1680,7 +1714,10 @@ if (arg_cnt>1)
|
||||
if (lanStatus>=HAVE_IP_ADDRESS)
|
||||
{
|
||||
|
||||
|
||||
lanStatus = DO_GET;
|
||||
return 200;
|
||||
/*
|
||||
let Re-Get will be only in safe time
|
||||
int retCode=loadConfigFromHttp();
|
||||
if (retCode==200)
|
||||
{
|
||||
@@ -1699,6 +1736,7 @@ int retCode=loadConfigFromHttp();
|
||||
if (configLoaded) lanStatus =IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
|
||||
else lanStatus = DO_READ_RE_CONFIG;
|
||||
return retCode;
|
||||
*/
|
||||
}
|
||||
errorSerial<<F("No IP adress")<<endl;
|
||||
return 500;
|
||||
@@ -1772,7 +1810,12 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
||||
infoSerial<<F("got Config\n"); delay(500);
|
||||
aJsonFileStream as = aJsonFileStream(configStream);
|
||||
noInterrupts();
|
||||
cleanConf(true);
|
||||
if (!cleanConf(true))
|
||||
{
|
||||
errorSerial<<F("Get aborted")<<endl;
|
||||
hclient.closeStream(configStream);
|
||||
return 500;
|
||||
}
|
||||
root = aJson.parse(&as);
|
||||
interrupts();
|
||||
hclient.closeStream(configStream); // this is very important -- be sure to close the STREAM
|
||||
@@ -1844,7 +1887,13 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
||||
if (responseStatusCode == 200) {
|
||||
aJsonStream socketStream = aJsonStream(&htclient);
|
||||
debugSerial<<F("Free:")<<freeRam()<<endl;
|
||||
cleanConf(true);
|
||||
if (!cleanConf(true))
|
||||
{
|
||||
errorSerial<<F("Get aborted")<<endl;
|
||||
htclient.stop();
|
||||
return 500;
|
||||
}
|
||||
|
||||
debugSerial<<F("Configuration cleaned")<<endl;
|
||||
debugSerial<<F("Free:")<<freeRam()<<endl;
|
||||
//root = aJson.parse((char *) response.c_str());
|
||||
@@ -1917,7 +1966,12 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
||||
sysConf.setETAG(httpClient.header("ETag"));
|
||||
//String response = httpClient.getString();
|
||||
//debugSerial<<response;
|
||||
cleanConf(true);
|
||||
if (!cleanConf(true))
|
||||
{
|
||||
errorSerial<<F("Get aborted")<<endl;
|
||||
httpClient.end();
|
||||
return 500;
|
||||
}
|
||||
//root = aJson.parse((char *) response.c_str());
|
||||
root = aJson.parse(&socketStream);
|
||||
|
||||
@@ -2003,6 +2057,10 @@ int16_t attachTimer(double microseconds, timerCallback callback, const char* Tim
|
||||
dueTimerInterrupt.attachInterruptInterval(microseconds, callback);
|
||||
timerNumber = dueTimerInterrupt.getTimerNumber();
|
||||
debugSerial<<TimerName<<F(" attached to Timer(")<<timerNumber<<F(")")<<endl;
|
||||
//DueTimer.Timers[timerNumber].irq
|
||||
NVIC_SetPriority(TC0_IRQn,2);
|
||||
debugSerial << "USART0 prio:" << NVIC_GetPriority (USART0_IRQn)<< " TC0 prio:" << NVIC_GetPriority (TC0_IRQn)<<endl;
|
||||
|
||||
return timerNumber;
|
||||
}
|
||||
#endif
|
||||
@@ -2493,6 +2551,11 @@ infoSerial<<F("\nNOSERIAL");
|
||||
infoSerial<<F("\n(+)ELEVATOR");
|
||||
#endif
|
||||
|
||||
#ifdef MERCURY_ENABLE
|
||||
infoSerial<<F("\n(+)MERCURY");
|
||||
#else
|
||||
infoSerial<<F("\n(-)MERCURY");
|
||||
#endif
|
||||
//#ifdef IPMODBUS
|
||||
//infoSerial<<F("\n(+)IPMODBUS");
|
||||
//#endif
|
||||
@@ -2625,12 +2688,12 @@ void loop_main() {
|
||||
|
||||
#if defined(OTA)
|
||||
yield();
|
||||
ArduinoOTA.poll();
|
||||
if (initializedListeners) ArduinoOTA.poll();
|
||||
#endif
|
||||
|
||||
#ifdef _artnet
|
||||
yield();
|
||||
if (artnet) artnet->read(); ///hung if network not initialized
|
||||
if (artnet && initializedListeners) artnet->read(); ///hung if network not initialized
|
||||
#endif
|
||||
#ifdef MDNS_ENABLE
|
||||
#ifndef WIFI_ENABLE
|
||||
@@ -2679,7 +2742,7 @@ if (initializedListeners) ipmodbusLoop();
|
||||
void owIdle(void) {
|
||||
// timerCtr++;
|
||||
#ifdef _artnet
|
||||
if (artnet && (lanStatus>=HAVE_IP_ADDRESS)) artnet->read();
|
||||
if (artnet && initializedListeners && (lanStatus>=HAVE_IP_ADDRESS)) artnet->read();
|
||||
#endif
|
||||
|
||||
wdt_res();
|
||||
@@ -2738,7 +2801,7 @@ void modbusIdle(void) {
|
||||
yield();
|
||||
mqttClient.loop();
|
||||
#ifdef _artnet
|
||||
if (artnet) artnet->read();
|
||||
if (artnet && initializedListeners) artnet->read();
|
||||
#endif
|
||||
#if defined(OTA)
|
||||
yield();
|
||||
@@ -2810,9 +2873,10 @@ inputLoopBusy--;
|
||||
void inputSensorsLoop() {
|
||||
if (!inputs || inputLoopBusy) return;
|
||||
//inputLoopBusy++;
|
||||
configLocked++;
|
||||
//configLocked++;
|
||||
if (isTimeOver(timerSensorCheck,millis(),INTERVAL_CHECK_SENSOR))
|
||||
{
|
||||
configLocked++;
|
||||
aJsonObject *input = inputs->child;
|
||||
while (input) {
|
||||
if ((input->type == aJson_Object)) {
|
||||
@@ -2824,14 +2888,16 @@ configLocked++;
|
||||
input = input->next;
|
||||
}
|
||||
timerSensorCheck = millis();
|
||||
configLocked--;
|
||||
}
|
||||
configLocked--;
|
||||
//configLocked--;
|
||||
//inputLoopBusy--;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void inputSetup(void) {
|
||||
infoSerial<<F("Initializing Inputs")<<endl;
|
||||
if (!inputs) return;
|
||||
configLocked++;
|
||||
aJsonObject *input = inputs->child;
|
||||
|
||||
@@ -218,7 +218,10 @@ enum lan_status {
|
||||
RECONNECT = 13,
|
||||
READ_RE_CONFIG = 14,
|
||||
DO_READ_RE_CONFIG = 15,
|
||||
DO_NOTHING = -15
|
||||
DO_NOTHING = -15,
|
||||
DO_GET = -16,
|
||||
GET = -17,
|
||||
GET_IN_PROGRESS = 18
|
||||
};
|
||||
|
||||
extern lan_status lanStatus;
|
||||
|
||||
@@ -22,14 +22,14 @@ static bool CCS811ready = false;
|
||||
|
||||
int in_ccs811::Setup()
|
||||
{
|
||||
if (CCS811ready) {errorSerial<<F("ccs811 is already initialized")<<endl; return 0;}
|
||||
if (CCS811ready) {errorSerial<<F("CCS811: Already initialized")<<endl; return 0;}
|
||||
|
||||
#ifdef WAK_PIN
|
||||
pinMode(WAK_PIN,OUTPUT);
|
||||
digitalWrite(WAK_PIN,LOW);
|
||||
#endif
|
||||
|
||||
infoSerial.println("CCS811 Init");
|
||||
infoSerial.println(F("CCS811: Init"));
|
||||
|
||||
#if defined (TWI_SCL) && defined (TWI_SDA)
|
||||
Wire.begin(TWI_SDA,TWI_SCL); //Inialize I2C Harware
|
||||
@@ -37,7 +37,9 @@ Wire.begin(TWI_SDA,TWI_SCL); //Inialize I2C Harware
|
||||
Wire.begin(); //Inialize I2C Harware
|
||||
#endif
|
||||
|
||||
Wire.setClock(4000);
|
||||
#ifdef I2C_CLOCK
|
||||
Wire.setClock(I2C_CLOCK);
|
||||
#endif
|
||||
|
||||
//It is recommended to check return status on .begin(), but it is not
|
||||
//required.
|
||||
@@ -46,8 +48,7 @@ Wire.setClock(4000);
|
||||
if (returnCode != CCS811Core::SENSOR_SUCCESS)
|
||||
//if (returnCode != CCS811Core::CCS811_Stat_SUCCESS)
|
||||
{
|
||||
errorSerial.print("CCS811 Init error ");
|
||||
//debugSerial.println(ccs811.statusString(returnCode));
|
||||
errorSerial.print(F("CCS811: Init error "));
|
||||
printDriverError(returnCode);
|
||||
return 0;
|
||||
}
|
||||
@@ -68,16 +69,16 @@ return 1;
|
||||
int in_hdc1080::Setup()
|
||||
{
|
||||
//i2cReset();
|
||||
if (HDC1080ready) {debugSerial<<F("hdc1080 is already initialized")<<endl; return 0;}
|
||||
debugSerial.println("HDC1080 Init ");
|
||||
if (HDC1080ready) {debugSerial<<F("HDC1080: Already initialized")<<endl; return 0;}
|
||||
debugSerial.print(F("HDC1080: Init. "));
|
||||
Wire.begin(); //Inialize I2C Harware
|
||||
// Default settings:
|
||||
// - Heater off
|
||||
// - 14 bit Temperature and Humidity Measurement Resolutions
|
||||
hdc1080.begin(0x40);
|
||||
debugSerial.print("Manufacturer ID=0x");
|
||||
debugSerial.println(hdc1080.readManufacturerId(), HEX); // 0x5449 ID of Texas Instruments
|
||||
debugSerial.print("Device ID=0x");
|
||||
debugSerial.print(F("Manufacturer ID=0x"));
|
||||
debugSerial.print(hdc1080.readManufacturerId(), HEX); // 0x5449 ID of Texas Instruments
|
||||
debugSerial.print(F(" Device ID=0x"));
|
||||
debugSerial.println(hdc1080.readDeviceId(), HEX); // 0x1050 ID of the device
|
||||
printSerialNumber();
|
||||
HDC1080ready = true;
|
||||
@@ -91,14 +92,14 @@ int in_hdc1080::Poll(short cause)
|
||||
float h,t;
|
||||
int reg;
|
||||
if (cause!=POLLING_SLOW) return 0;
|
||||
if (!HDC1080ready) {debugSerial<<F("HDC1080 not initialized")<<endl; return 0;}
|
||||
debugSerial.print("HDC Status=");
|
||||
debugSerial.println(reg=hdc1080.readRegister().rawData,HEX);
|
||||
if (!HDC1080ready) {errorSerial<<F("HDC1080: Not initialized")<<endl; return 0;}
|
||||
debugSerial.print(F("HDC1080: Status="));
|
||||
debugSerial.print(reg=hdc1080.readRegister().rawData,HEX);
|
||||
if (reg!=0xff)
|
||||
{
|
||||
debugSerial.print(" T=");
|
||||
debugSerial.print(t=hdc1080.readTemperature());
|
||||
debugSerial.print("C, RH=");
|
||||
debugSerial.print(F("C, RH="));
|
||||
debugSerial.print(h=hdc1080.readHumidity());
|
||||
debugSerial.println("%");
|
||||
|
||||
@@ -126,6 +127,7 @@ if (reg!=0xff)
|
||||
}
|
||||
else //ESP I2C glitch
|
||||
{
|
||||
debugSerial.println();
|
||||
i2cReset();
|
||||
}
|
||||
return INTERVAL_SLOW_POLLING;
|
||||
@@ -147,14 +149,14 @@ int in_ccs811::Poll(short cause)
|
||||
CCS811Core::status returnCode = ccs811.readAlgorithmResults();
|
||||
printDriverError(returnCode);
|
||||
float co2,tvoc;
|
||||
debugSerial.print(" CO2[");
|
||||
debugSerial.print(F(" CO2["));
|
||||
//Returns calculated CO2 reading
|
||||
debugSerial.print(co2 = ccs811.getCO2());
|
||||
debugSerial.print("] tVOC[");
|
||||
debugSerial.print(F("] tVOC["));
|
||||
//Returns calculated TVOC reading
|
||||
|
||||
debugSerial.print(tvoc = ccs811.getTVOC());
|
||||
debugSerial.print("] baseline[");
|
||||
debugSerial.print(F("] baseline["));
|
||||
debugSerial.print(ccs811Baseline = ccs811.getBaseline());
|
||||
|
||||
#ifdef M5STACK
|
||||
@@ -192,11 +194,11 @@ int in_ccs811::Poll(short cause)
|
||||
}
|
||||
|
||||
void in_hdc1080::printSerialNumber() {
|
||||
debugSerial.print("Device Serial Number=");
|
||||
infoSerial.print(F("Device Serial Number="));
|
||||
HDC1080_SerialNumber sernum = hdc1080.readSerialNumber();
|
||||
char format[16];
|
||||
sprintf(format, "%02X-%04X-%04X", sernum.serialFirst, sernum.serialMid, sernum.serialLast);
|
||||
debugSerial.println(format);
|
||||
infoSerial.println(format);
|
||||
}
|
||||
|
||||
//printDriverError decodes the CCS811Core::status type and prints the
|
||||
@@ -206,25 +208,26 @@ debugSerial.println(format);
|
||||
//to this function to see what the output was.
|
||||
void in_ccs811::printDriverError( CCS811Core::status errorCode )
|
||||
{
|
||||
debugSerial.print(F("CCS811: "));
|
||||
switch ( errorCode )
|
||||
{
|
||||
case CCS811Core::SENSOR_SUCCESS:
|
||||
debugSerial.print("SUCCESS");
|
||||
debugSerial.print(F("SUCCESS"));
|
||||
break;
|
||||
case CCS811Core::SENSOR_ID_ERROR:
|
||||
debugSerial.print("ID_ERROR");
|
||||
debugSerial.print(F("ID_ERROR"));
|
||||
break;
|
||||
case CCS811Core::SENSOR_I2C_ERROR:
|
||||
debugSerial.print("I2C_ERROR");
|
||||
debugSerial.print(F("I2C_ERROR"));
|
||||
break;
|
||||
case CCS811Core::SENSOR_INTERNAL_ERROR:
|
||||
debugSerial.print("INTERNAL_ERROR");
|
||||
debugSerial.print(F("INTERNAL_ERROR"));
|
||||
break;
|
||||
case CCS811Core::SENSOR_GENERIC_ERROR:
|
||||
debugSerial.print("GENERIC_ERROR");
|
||||
debugSerial.print(F("GENERIC_ERROR"));
|
||||
break;
|
||||
default:
|
||||
debugSerial.print("Unspecified error.");
|
||||
debugSerial.print(F("Unspecified error."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,18 +239,18 @@ void in_ccs811::printSensorError()
|
||||
|
||||
if ( error == 0xFF ) //comm error
|
||||
{
|
||||
debugSerial.println("Failed to get ERROR_ID register.");
|
||||
errorSerial.println(F("CCS811: Failed to get ERROR_ID register."));
|
||||
}
|
||||
else
|
||||
{
|
||||
//debugSerial.print("");
|
||||
if (error & 1 << 5) debugSerial.print("Error: HeaterSupply");
|
||||
if (error & 1 << 4) debugSerial.print("Error: HeaterFault");
|
||||
if (error & 1 << 3) debugSerial.print("Error: MaxResistance");
|
||||
if (error & 1 << 2) debugSerial.print("Error: MeasModeInvalid");
|
||||
if (error & 1 << 1) debugSerial.print("Error: ReadRegInvalid");
|
||||
if (error & 1 << 0) debugSerial.print("Error: MsgInvalid");
|
||||
debugSerial.println();
|
||||
if (error) errorSerial.print(F("CCS811: Error "));
|
||||
if (error & 1 << 5) errorSerial.print(F("HeaterSupply"));
|
||||
if (error & 1 << 4) errorSerial.print(F("HeaterFault"));
|
||||
if (error & 1 << 3) errorSerial.print(F("MaxResistance"));
|
||||
if (error & 1 << 2) errorSerial.print(F("MeasModeInvalid"));
|
||||
if (error & 1 << 1) errorSerial.print(F("ReadRegInvalid"));
|
||||
if (error & 1 << 0) errorSerial.print(F("MsgInvalid"));
|
||||
if (error) errorSerial.println();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7,18 +7,22 @@
|
||||
#include "ClosedCube_HDC1080.h"
|
||||
#include "SparkFunCCS811.h" //Click here to get the library: http://librarymanager/All#SparkFun_CCS811
|
||||
|
||||
//#ifndef I2C_CLOCK
|
||||
//#define I2C_CLOCK 4000
|
||||
//#endif
|
||||
|
||||
//#define CCS811_ADDR 0x5B //Default I2C Address
|
||||
#define CCS811_ADDR 0x5A //Alternate I2C Address
|
||||
|
||||
#if defined (ARDUINO_ARCH_ESP8266)
|
||||
|
||||
#if not defined (TWI_SCL) && defined (D1)
|
||||
#define TWI_SCL D1
|
||||
#endif
|
||||
// #if not defined (TWI_SCL) && defined (D1)
|
||||
// #define TWI_SCL D1
|
||||
// #endif
|
||||
|
||||
#if not defined (WAK_PIN) && defined (D3)
|
||||
#define WAK_PIN D3
|
||||
#endif
|
||||
// #if not defined (WAK_PIN) && defined (D3)
|
||||
// #define WAK_PIN D3
|
||||
// #endif
|
||||
|
||||
#if defined (TWI_SCL)
|
||||
#define SCL_LOW() (GPES = (1 << TWI_SCL))
|
||||
@@ -28,16 +32,10 @@
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
#if defined (__SAM3X8E__)
|
||||
#define SCL_LOW() digitalWrite(21,LOW)
|
||||
#define SCL_HIGH() digitalWrite(21,HIGH)
|
||||
#define SCL_RESET
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
||||
#if defined (ARDUINO_ARCH_ESP32)
|
||||
#undef WAK_PIN
|
||||
//#undef WAK_PIN
|
||||
#undef SCL_RESET
|
||||
//#ifndef WAK_PIN
|
||||
//#define WAK_PIN 17
|
||||
@@ -45,9 +43,9 @@
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_AVR)
|
||||
#ifndef WAK_PIN
|
||||
#define WAK_PIN 3 // for LightHub UEXT SCS Pin
|
||||
#endif
|
||||
//#ifndef WAK_PIN
|
||||
//#define WAK_PIN 3 // for LightHub UEXT SCS Pin
|
||||
//#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,7 +42,7 @@ public:
|
||||
int Stop() override;
|
||||
int isActive() override;
|
||||
int getChanType() override;
|
||||
int getDefaultStorageType(){return ST_FLOAT_CELSIUS;};
|
||||
// int getDefaultStorageType(){return ST_FLOAT_CELSIUS;};
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||
void SubmitParameters(const char * name, itemCmd value);
|
||||
|
||||
|
||||
@@ -97,6 +97,7 @@ debugSerial.println("Mercury: De-Init");
|
||||
disconnectMercury();
|
||||
delete store;
|
||||
item->setPersistent(NULL);
|
||||
setStatus(CST_UNKNOWN);
|
||||
store = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -20,16 +20,16 @@ public:
|
||||
#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 M_CONNECTING CST_USER+0
|
||||
#define M_CONNECTED CST_USER+1
|
||||
#define M_POLLING1 CST_USER+2
|
||||
#define M_POLLING2 CST_USER+3
|
||||
#define M_POLLING3 CST_USER+4
|
||||
#define M_POLLING4 CST_USER+5
|
||||
#define M_POLLING5 CST_USER+6
|
||||
#define M_POLLING6 CST_USER+7
|
||||
#define M_POLLING7 CST_USER+8
|
||||
#define M_POLLING8 CST_USER+9
|
||||
|
||||
#define RET_SUCCESS 0
|
||||
#define RET_INVALID_PARAM 1
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
int Stop() override;
|
||||
int getChanType() override;
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||
int getDefaultStorageType(){return ST_INT32;};
|
||||
//int getDefaultStorageType(){return ST_INT32;};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@@ -327,7 +327,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
||||
mappedParam.Int((uint32_t)param);
|
||||
}
|
||||
|
||||
debugSerial << F("MBUSD: got ")<<mappedParam.toString(buf,sizeof(buf))<< F(" from type ")<<parType<<F(":")<<paramObj->name<<endl;
|
||||
traceSerial << F("MBUSD: got ")<<mappedParam.toString(buf,sizeof(buf))<< F(" from type ")<<parType<<F(":")<<paramObj->name<<endl;
|
||||
|
||||
if (mapObj && (mapObj->type==aJson_Array || mapObj->type==aJson_Object))
|
||||
{
|
||||
@@ -341,7 +341,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
||||
switch (defMappingObj->type)
|
||||
{
|
||||
case aJson_Int: //register/coil/.. number
|
||||
debugSerial<<F("Searching reg#")<<defMappingObj->valueint<<endl;
|
||||
traceSerial<<F("Searching reg#")<<defMappingObj->valueint<<endl;
|
||||
if ((defMappingObj->valueint>= registerFrom) && (defMappingObj->valueint<=registerTo))
|
||||
{
|
||||
mappedParam = findRegister(defMappingObj->valueint,defMappingObj->valueint-registerFrom,regType,registerFrom,registerTo,false,&submitRecurrentOut);
|
||||
@@ -351,7 +351,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
||||
|
||||
break;
|
||||
case aJson_String: // parameter name
|
||||
debugSerial<<F("Searching reg: ")<<defMappingObj->valuestring<<endl;
|
||||
traceSerial<<F("Searching reg: ")<<defMappingObj->valuestring<<endl;
|
||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
{
|
||||
//Searching item param for nested mapping
|
||||
@@ -364,7 +364,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
||||
aJsonObject *lastMeasured = aJson.getObjectItem(itemParObj,"@S");
|
||||
if (lastMeasured && lastMeasured->type ==aJson_Int)
|
||||
{
|
||||
debugSerial<<F("LastKnown value: ")<<lastMeasured->valueint<<endl;
|
||||
traceSerial<<F("LastKnown value: ")<<lastMeasured->valueint<<endl;
|
||||
//Searching template param for nested mapping
|
||||
aJsonObject * templateParObj = aJson.getObjectItem(store->parameters,defMappingObj->valuestring);
|
||||
if (templateParObj)
|
||||
@@ -401,7 +401,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
||||
|
||||
aJsonObject * nestedMapObj = aJson.getObjectItem(templateParObj, "map");
|
||||
if (nestedMapObj && (nestedMapObj->type==aJson_Array || nestedMapObj->type==aJson_Object)) mappedParam=mappedParam.doReverseMapping(nestedMapObj);
|
||||
debugSerial << F("MBUSD: NestedMapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
||||
traceSerial << F("MBUSD: NestedMapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
||||
|
||||
if (!(lastMeasured->subtype & MB_VALUE_OUTDATED))
|
||||
{
|
||||
@@ -449,7 +449,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
||||
*/
|
||||
}
|
||||
else
|
||||
debugSerial << F("MBUSD: Mapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
||||
traceSerial << F("MBUSD: Mapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
||||
} //mapping
|
||||
|
||||
if (doExecution && idObj && idObj->type==aJson_Int)
|
||||
@@ -505,7 +505,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
||||
aJsonObject *settedValue = aJson.getObjectItem(markObj,"@V");
|
||||
if (settedValue && settedValue->type==aJson_Int && (settedValue->valueint == param))
|
||||
{
|
||||
debugSerial<<F("MBUSD: Ignored - equal with setted val")<<endl;
|
||||
traceSerial<<F("MBUSD: Ignored - equal with setted val")<<endl;
|
||||
*submitParam=false;
|
||||
}
|
||||
else
|
||||
@@ -550,7 +550,7 @@ return itemCmd();
|
||||
int registerTo=aJson.getArrayItem(reg, 1)->valueint;
|
||||
|
||||
if (readModbus(registerFrom,regType,registerTo-registerFrom+1))
|
||||
{ debugSerial<<endl;
|
||||
{ traceSerial<<endl;
|
||||
for(int i=registerFrom;i<=registerTo;i++)
|
||||
{
|
||||
findRegister(i,i-registerFrom,regType,registerFrom,registerTo);
|
||||
@@ -633,7 +633,7 @@ int out_Modbus::sendModbus(char * paramName, int32_t value, uint8_t regType)
|
||||
break;
|
||||
}
|
||||
mbusSlenceTimer = millisNZ();
|
||||
debugSerial<<F("Res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<value<<endl;
|
||||
debugSerial<<F("MBUS res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<value<<endl;
|
||||
return ( res == 0);
|
||||
}
|
||||
|
||||
@@ -667,8 +667,18 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
lineInitialized=true;
|
||||
initLine();
|
||||
}
|
||||
debugSerial<<"MBUS: SEND "<<item->itemArr->name<<" ";
|
||||
switch (sendModbus(execObj->name,outValue->valueint,outValue->subtype))
|
||||
|
||||
int sendRes;
|
||||
int savedValue;
|
||||
do
|
||||
{
|
||||
savedValue = outValue->valueint;
|
||||
debugSerial<<"MBUS: SEND "<<item->itemArr->name<<" ";
|
||||
sendRes = sendModbus(execObj->name,outValue->valueint,outValue->subtype);
|
||||
}
|
||||
while (savedValue != outValue->valueint); //repeat sending if target value changed while we're waited for mbus responce
|
||||
|
||||
switch (sendRes)
|
||||
{
|
||||
case 1: //success
|
||||
execObj->subtype&=~ MB_NEED_SEND;
|
||||
@@ -719,7 +729,7 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
// if some polling configured
|
||||
if (store->pollingRegisters || store->pollingIrs || store->pollingCoils || store->poolingDiscreteIns)
|
||||
{
|
||||
debugSerial<<F("MBUSD: Poll ")<< item->itemArr->name << endl;
|
||||
traceSerial<<F("MBUSD: Poll ")<< item->itemArr->name << endl;
|
||||
modbusBusy=1;
|
||||
|
||||
if (!lineInitialized)
|
||||
@@ -732,7 +742,7 @@ if (store->pollingRegisters || store->pollingIrs || store->pollingCoils || store
|
||||
pollModbus(store->pollingIrs,MODBUS_INPUT_REG_TYPE);
|
||||
pollModbus(store->pollingCoils,MODBUS_COIL_REG_TYPE);
|
||||
pollModbus(store->poolingDiscreteIns ,MODBUS_DISCRETE_REG_TYPE);
|
||||
debugSerial<<F("MBUSD: endPoll ")<< item->itemArr->name << endl;
|
||||
traceSerial<<F("MBUSD: endPoll ")<< item->itemArr->name << endl;
|
||||
|
||||
//Non blocking waiting to release line
|
||||
uint32_t time = millis();
|
||||
@@ -794,7 +804,7 @@ aJsonObject * mapObj = aJson.getObjectItem(templateParamObj, "map");
|
||||
Value=cmdValue.getTens_raw()*(100/TENS_BASE);
|
||||
}
|
||||
|
||||
debugSerial<<F("MBUSD: suffix:")<<suffixStr<< F(" Val: ")<<Value<<endl;
|
||||
traceSerial<<F("MBUSD: suffix:")<<suffixStr<< F(" Val: ")<<Value<<endl;
|
||||
aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
int Stop() override;
|
||||
int getChanType() override;
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||
int getDefaultStorageType(){return ST_INT32;};
|
||||
//int getDefaultStorageType(){return ST_INT32;};
|
||||
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL) override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
int Stop() override;
|
||||
//int isActive() override;
|
||||
int getChanType() override;
|
||||
int getDefaultStorageType(){return ST_PERCENTS255;};
|
||||
//int getDefaultStorageType(){return ST_PERCENTS255;};
|
||||
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL) override;
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||
|
||||
|
||||
@@ -1,249 +1,252 @@
|
||||
#ifndef MULTIVENT_DISABLE
|
||||
|
||||
#include "modules/out_multivent.h"
|
||||
#include "Arduino.h"
|
||||
#include "options.h"
|
||||
#include "Streaming.h"
|
||||
|
||||
#include "item.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
void out_Multivent::getConfig()
|
||||
{
|
||||
gatesObj = NULL;
|
||||
if (!item || !item->itemArg || item->itemArg->type != aJson_Object) return;
|
||||
gatesObj = item->itemArg;
|
||||
}
|
||||
|
||||
int out_Multivent::Setup()
|
||||
{
|
||||
abstractOut::Setup();
|
||||
//getConfig();
|
||||
|
||||
//Expand Argument storage to 2
|
||||
//for (int i = aJson.getArraySize(item->itemArg); i < 2; i++)
|
||||
// aJson.addItemToArray(item->itemArg, aJson.createItem( (long int) 0));
|
||||
|
||||
//Allocate objects to store persistent data in config tree
|
||||
if (gatesObj /*&& aJson.getArraySize(item->itemArg)>=2*/)
|
||||
{
|
||||
aJsonObject * i = gatesObj->child;
|
||||
while (i)
|
||||
{
|
||||
if (i->name && *i->name)
|
||||
{
|
||||
aJsonObject * setObj = aJson.getObjectItem(i, "set");
|
||||
if (!setObj) aJson.addNumberToObject(i, "set", (long int) -1);
|
||||
|
||||
aJsonObject * cmdObj = aJson.getObjectItem(i, "cmd");
|
||||
if (!cmdObj) aJson.addNumberToObject(i, "cmd", (long int) -1);
|
||||
|
||||
aJsonObject * outObj = aJson.getObjectItem(i, "out");
|
||||
if (!outObj) aJson.addNumberToObject(i, "out", (long int) -1);
|
||||
}
|
||||
i=i->next;
|
||||
}
|
||||
debugSerial << F ("MultiVent init")<< endl;
|
||||
setStatus(CST_INITIALIZED);
|
||||
return 1;
|
||||
}
|
||||
|
||||
debugSerial << F ("MultiVent config failed")<< endl;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int out_Multivent::Stop()
|
||||
{
|
||||
debugSerial << F ("Multivent De-Init") << endl;
|
||||
setStatus(CST_UNKNOWN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int out_Multivent::Poll(short cause)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
int out_Multivent::getChanType()
|
||||
{
|
||||
return CH_PWM;
|
||||
}
|
||||
|
||||
|
||||
int out_Multivent::Ctrl(itemCmd cmd, char* subItem , bool toExecute, bool authorized)
|
||||
{
|
||||
|
||||
if (cmd.getCmd()==CMD_DISABLE || cmd.getCmd()==CMD_ENABLE) return 0;
|
||||
int suffixCode = cmd.getSuffix();
|
||||
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
||||
|
||||
aJsonObject * i = NULL;
|
||||
|
||||
if (cmd.isCommand() && cmd.getSuffix()==S_FAN)
|
||||
switch (cmd.getCmd())
|
||||
{
|
||||
case CMD_HIGH:
|
||||
cmd.Percents255(255);
|
||||
break;
|
||||
|
||||
case CMD_MED:
|
||||
cmd.Percents255(128);
|
||||
break;
|
||||
|
||||
case CMD_LOW:
|
||||
cmd.setPercents(10);
|
||||
break;
|
||||
|
||||
} //switch cmd
|
||||
|
||||
|
||||
if (gatesObj) i = gatesObj->child; // Pass 1 - calculate summ air value, max value etc
|
||||
|
||||
int activeV = 0;
|
||||
int totalV = 0;
|
||||
int maxV=0;
|
||||
int maxRequestedV=0;
|
||||
int maxPercent=0;
|
||||
|
||||
|
||||
while (i)
|
||||
{
|
||||
|
||||
aJsonObject * setObj=aJson.getObjectItem(i, "set");
|
||||
aJsonObject * cmdObj=aJson.getObjectItem(i, "cmd");
|
||||
aJsonObject * cascadeObj=aJson.getObjectItem(i, "cas");
|
||||
if (setObj && cmdObj && setObj->type==aJson_Int && cmdObj->type==aJson_Int)
|
||||
{
|
||||
|
||||
int V =aJson.getObjectItem(i,"V")->valueint;
|
||||
int requestedV=0;
|
||||
|
||||
if (subItem && !strcmp (i->name,subItem))
|
||||
{
|
||||
if (cmdObj && cmd.isCommand())
|
||||
{
|
||||
cmdObj->valueint = cmd.getCmd();
|
||||
//publishTopic(i->name,cmdObj->valueint,"/set");
|
||||
switch (cmd.getCmd())
|
||||
{
|
||||
case CMD_ON:
|
||||
cmd.Percents255(setObj->valueint);
|
||||
break;
|
||||
case CMD_OFF:
|
||||
cmd.Percents255(0);
|
||||
}
|
||||
if (isNotRetainingStatus() && (cmdObj->valueint == CMD_ON) && (setObj->valueint<20))
|
||||
{
|
||||
setObj->valueint=30;
|
||||
cmd.Percents255(30);
|
||||
//if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_PARAMETERS,i->name);
|
||||
}
|
||||
|
||||
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_COMMAND|FLAG_PARAMETERS,i->name);
|
||||
}
|
||||
|
||||
else if (setObj && cmdObj && suffixCode == S_FAN && cmd.isValue())
|
||||
{
|
||||
if (cmd.getInt())
|
||||
{
|
||||
|
||||
if (cmdObj->valueint == CMD_OFF || cmdObj->valueint == -1)
|
||||
{
|
||||
debugSerial<<"Turning ON"<<endl;
|
||||
cmdObj->valueint = CMD_ON;
|
||||
cmd.Cmd(CMD_ON);
|
||||
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_ON),FLAG_COMMAND,i->name);
|
||||
}
|
||||
|
||||
setObj->valueint = cmd.getInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cmdObj->valueint != CMD_OFF && cmdObj->valueint != -1)
|
||||
{ debugSerial<<"Turning OFF"<<endl;
|
||||
cmdObj->valueint = CMD_OFF;
|
||||
cmd.Cmd(CMD_OFF);
|
||||
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_OFF),FLAG_COMMAND,i->name);
|
||||
}
|
||||
|
||||
setObj->valueint = 0;
|
||||
}
|
||||
|
||||
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,FLAG_PARAMETERS,i->name);
|
||||
}
|
||||
if (cascadeObj) executeCommand(cascadeObj,-1,cmd);
|
||||
}
|
||||
|
||||
if (cmdObj->valueint != CMD_OFF && cmdObj->valueint != -1)
|
||||
{
|
||||
requestedV=V*setObj->valueint;
|
||||
activeV+=requestedV;
|
||||
|
||||
if (setObj->valueint>maxPercent )
|
||||
{
|
||||
maxRequestedV=requestedV;
|
||||
maxV=V;
|
||||
maxPercent=setObj->valueint;
|
||||
}
|
||||
}
|
||||
totalV+=V;
|
||||
|
||||
}
|
||||
i=i->next;
|
||||
}
|
||||
|
||||
if (!totalV) return 0;
|
||||
|
||||
int fanV=activeV/totalV;
|
||||
debugSerial << F("Total V:")<<totalV<<F(" active V:")<<activeV/255<< F(" fan%:")<<fanV<< F(" Max request:")<<maxRequestedV/255 <<F(" from ")<<maxV<<F(" m3")<< endl;
|
||||
|
||||
executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV).Cmd((fanV)?CMD_ON:CMD_OFF));
|
||||
|
||||
//Move gates only if fan is actually on
|
||||
if (!fanV) return 1;
|
||||
|
||||
i=NULL;
|
||||
if (gatesObj) i = gatesObj->child; //Pass 2: re-distribute airflow
|
||||
|
||||
while (i)
|
||||
{
|
||||
int V =aJson.getObjectItem(i,"V")->valueint;
|
||||
|
||||
aJsonObject * outObj=aJson.getObjectItem(i, "out");
|
||||
aJsonObject * setObj=aJson.getObjectItem(i, "set");
|
||||
aJsonObject * cmdObj=aJson.getObjectItem(i, "cmd");
|
||||
|
||||
if (outObj && setObj && cmdObj && outObj->type==aJson_Int && setObj->type==aJson_Int && cmdObj->type==aJson_Int && V)
|
||||
{
|
||||
long int out = 0;
|
||||
if (cmdObj->valueint != CMD_OFF && cmdObj->valueint != -1 && maxRequestedV)
|
||||
{
|
||||
int requestedV=V*setObj->valueint;
|
||||
out = (( long)requestedV*255L)/(( long)V)*( long)maxV/( long)maxRequestedV;
|
||||
debugSerial<<i->name<<(" Req:")<<requestedV/255<<F(" Out:")<<out<<endl;
|
||||
}
|
||||
|
||||
|
||||
if ((out != outObj->valueint))
|
||||
{
|
||||
//report out
|
||||
executeCommand(i,-1,itemCmd().Percents255(out));
|
||||
outObj->valueint=out;
|
||||
}
|
||||
}
|
||||
i=i->next;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifndef MULTIVENT_DISABLE
|
||||
|
||||
#include "modules/out_multivent.h"
|
||||
#include "Arduino.h"
|
||||
#include "options.h"
|
||||
#include "Streaming.h"
|
||||
|
||||
#include "item.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
void out_Multivent::getConfig()
|
||||
{
|
||||
gatesObj = NULL;
|
||||
if (!item || !item->itemArg || item->itemArg->type != aJson_Object) return;
|
||||
gatesObj = item->itemArg;
|
||||
}
|
||||
|
||||
int out_Multivent::Setup()
|
||||
{
|
||||
abstractOut::Setup();
|
||||
//getConfig();
|
||||
|
||||
//Expand Argument storage to 2
|
||||
//for (int i = aJson.getArraySize(item->itemArg); i < 2; i++)
|
||||
// aJson.addItemToArray(item->itemArg, aJson.createItem( (long int) 0));
|
||||
|
||||
//Allocate objects to store persistent data in config tree
|
||||
if (gatesObj /*&& aJson.getArraySize(item->itemArg)>=2*/)
|
||||
{
|
||||
aJsonObject * i = gatesObj->child;
|
||||
while (i)
|
||||
{
|
||||
if (i->name && *i->name)
|
||||
{
|
||||
aJsonObject * setObj = aJson.getObjectItem(i, "set");
|
||||
if (!setObj) aJson.addNumberToObject(i, "set", (long int) -1);
|
||||
|
||||
aJsonObject * cmdObj = aJson.getObjectItem(i, "cmd");
|
||||
if (!cmdObj) aJson.addNumberToObject(i, "cmd", (long int) -1);
|
||||
|
||||
aJsonObject * outObj = aJson.getObjectItem(i, "out");
|
||||
if (!outObj) aJson.addNumberToObject(i, "out", (long int) -1);
|
||||
}
|
||||
i=i->next;
|
||||
}
|
||||
debugSerial << F ("VENT: init")<< endl;
|
||||
setStatus(CST_INITIALIZED);
|
||||
return 1;
|
||||
}
|
||||
|
||||
debugSerial << F ("VENT: config failed")<< endl;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int out_Multivent::Stop()
|
||||
{
|
||||
debugSerial << F ("VENT: De-Init") << endl;
|
||||
setStatus(CST_UNKNOWN);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int out_Multivent::Poll(short cause)
|
||||
{
|
||||
return 0;
|
||||
};
|
||||
|
||||
int out_Multivent::getChanType()
|
||||
{
|
||||
return CH_PWM;
|
||||
}
|
||||
|
||||
|
||||
int out_Multivent::Ctrl(itemCmd cmd, char* subItem , bool toExecute, bool authorized)
|
||||
{
|
||||
|
||||
if (cmd.getCmd()==CMD_DISABLE || cmd.getCmd()==CMD_ENABLE) return 0;
|
||||
int suffixCode = cmd.getSuffix();
|
||||
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
||||
|
||||
aJsonObject * i = NULL;
|
||||
|
||||
if (cmd.isCommand() && cmd.getSuffix()==S_FAN)
|
||||
switch (cmd.getCmd())
|
||||
{
|
||||
case CMD_HIGH:
|
||||
cmd.Percents255(255);
|
||||
break;
|
||||
|
||||
case CMD_MED:
|
||||
cmd.Percents255(128);
|
||||
break;
|
||||
|
||||
case CMD_LOW:
|
||||
cmd.setPercents(10);
|
||||
break;
|
||||
|
||||
} //switch cmd
|
||||
|
||||
|
||||
if (gatesObj) i = gatesObj->child; // Pass 1 - calculate summ air value, max value etc
|
||||
|
||||
int activeV = 0;
|
||||
int totalV = 0;
|
||||
int maxV=0;
|
||||
int maxRequestedV=0;
|
||||
int maxPercent=0;
|
||||
|
||||
|
||||
while (i)
|
||||
{
|
||||
|
||||
aJsonObject * setObj=aJson.getObjectItem(i, "set");
|
||||
aJsonObject * cmdObj=aJson.getObjectItem(i, "cmd");
|
||||
aJsonObject * cascadeObj=aJson.getObjectItem(i, "cas");
|
||||
if (setObj && cmdObj && setObj->type==aJson_Int && cmdObj->type==aJson_Int)
|
||||
{
|
||||
|
||||
int V =aJson.getObjectItem(i,"V")->valueint;
|
||||
int requestedV=0;
|
||||
|
||||
if (subItem && !strcmp (i->name,subItem))
|
||||
{
|
||||
if (cmdObj && cmd.isCommand())
|
||||
{
|
||||
cmdObj->valueint = cmd.getCmd();
|
||||
//publishTopic(i->name,cmdObj->valueint,"/set");
|
||||
switch (cmd.getCmd())
|
||||
{
|
||||
case CMD_ON:
|
||||
cmd.Percents255(setObj->valueint);
|
||||
break;
|
||||
case CMD_OFF:
|
||||
cmd.Percents255(0);
|
||||
}
|
||||
if (isNotRetainingStatus() && (cmdObj->valueint == CMD_ON) && (setObj->valueint<20))
|
||||
{
|
||||
setObj->valueint=30;
|
||||
cmd.Percents255(30);
|
||||
//if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_PARAMETERS,i->name);
|
||||
}
|
||||
|
||||
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_COMMAND|FLAG_PARAMETERS,i->name);
|
||||
}
|
||||
|
||||
else if (setObj && cmdObj && suffixCode == S_FAN && cmd.isValue())
|
||||
{
|
||||
if (cmd.getInt())
|
||||
{
|
||||
|
||||
if (cmdObj->valueint == CMD_OFF || cmdObj->valueint == -1)
|
||||
{
|
||||
debugSerial<<"VENT: Turning ON"<<endl;
|
||||
cmdObj->valueint = CMD_ON;
|
||||
cmd.Cmd(CMD_ON);
|
||||
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_ON),FLAG_COMMAND,i->name);
|
||||
}
|
||||
|
||||
setObj->valueint = cmd.getInt();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cmdObj->valueint != CMD_OFF && cmdObj->valueint != -1)
|
||||
{ debugSerial<<"VENT: Turning OFF"<<endl;
|
||||
cmdObj->valueint = CMD_OFF;
|
||||
cmd.Cmd(CMD_OFF);
|
||||
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_OFF),FLAG_COMMAND,i->name);
|
||||
}
|
||||
|
||||
setObj->valueint = 0;
|
||||
}
|
||||
|
||||
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,FLAG_PARAMETERS,i->name);
|
||||
}
|
||||
if (cascadeObj) executeCommand(cascadeObj,-1,cmd);
|
||||
}
|
||||
|
||||
if (cmdObj->valueint != CMD_OFF && cmdObj->valueint != -1)
|
||||
{
|
||||
requestedV=V*setObj->valueint;
|
||||
activeV+=requestedV;
|
||||
|
||||
if (setObj->valueint>maxPercent )
|
||||
{
|
||||
maxRequestedV=requestedV;
|
||||
maxV=V;
|
||||
maxPercent=setObj->valueint;
|
||||
}
|
||||
}
|
||||
totalV+=V;
|
||||
|
||||
}
|
||||
i=i->next;
|
||||
}
|
||||
|
||||
if (!totalV) return 0;
|
||||
|
||||
int fanV=activeV/totalV;
|
||||
debugSerial << F("VENT: Total V:")<<totalV<<F(" active V:")<<activeV/255<< F(" fan%:")<<fanV<< F(" Max req:")<<maxRequestedV/255 <<F(" from ")<<maxV<<F(" m3")<< endl;
|
||||
|
||||
//executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV).Cmd((fanV)?CMD_ON:CMD_OFF));
|
||||
if (fanV)
|
||||
executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV).Cmd(CMD_ON));
|
||||
else
|
||||
executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV));
|
||||
//Move gates only if fan is actually on
|
||||
if (!fanV) return 1;
|
||||
|
||||
i=NULL;
|
||||
if (gatesObj) i = gatesObj->child; //Pass 2: re-distribute airflow
|
||||
|
||||
while (i)
|
||||
{
|
||||
int V =aJson.getObjectItem(i,"V")->valueint;
|
||||
|
||||
aJsonObject * outObj=aJson.getObjectItem(i, "out");
|
||||
aJsonObject * setObj=aJson.getObjectItem(i, "set");
|
||||
aJsonObject * cmdObj=aJson.getObjectItem(i, "cmd");
|
||||
|
||||
if (outObj && setObj && cmdObj && outObj->type==aJson_Int && setObj->type==aJson_Int && cmdObj->type==aJson_Int && V)
|
||||
{
|
||||
long int out = 0;
|
||||
if (cmdObj->valueint != CMD_OFF && cmdObj->valueint != -1 && maxRequestedV)
|
||||
{
|
||||
int requestedV=V*setObj->valueint;
|
||||
out = (( long)requestedV*255L)/(( long)V)*( long)maxV/( long)maxRequestedV;
|
||||
debugSerial<<F("VENT: ")<<i->name<<F(" Req:")<<requestedV/255<<F(" Out:")<<out<<endl;
|
||||
}
|
||||
|
||||
|
||||
if ((out != outObj->valueint))
|
||||
{
|
||||
//report out
|
||||
executeCommand(i,-1,itemCmd().Percents255(out));
|
||||
outObj->valueint=out;
|
||||
}
|
||||
}
|
||||
i=i->next;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
int Stop() override;
|
||||
//int isActive() override;
|
||||
int getChanType() override;
|
||||
int getDefaultStorageType(){return ST_PERCENTS255;};
|
||||
//int getDefaultStorageType(){return ST_PERCENTS255;};
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||
protected:
|
||||
void getConfig();
|
||||
|
||||
@@ -334,32 +334,38 @@ case S_CTRL:
|
||||
switch (command)
|
||||
{
|
||||
case CMD_OFF:
|
||||
//value.Percents255(0);
|
||||
|
||||
if (isNotRetainingStatus()) executeCommand(oCmd,-1,itemCmd().Cmd(CMD_DISABLE)); // Not actually disable, just inform depended systems, that no autoreg now (for pannels indication)
|
||||
executeCommand(oCmd,-1,value);
|
||||
item->SendStatus(FLAG_FLAGS);
|
||||
return 1;
|
||||
case CMD_ON:
|
||||
case CMD_HEAT:
|
||||
case CMD_COOL:
|
||||
case CMD_AUTO:
|
||||
case CMD_FAN:
|
||||
case CMD_DRY:
|
||||
|
||||
executeCommand(oCmd,-1,value);
|
||||
executeCommand(oCmd,-1,itemCmd().Cmd((item->getFlag(FLAG_DISABLED))?CMD_DISABLE:CMD_ENABLE));
|
||||
executeCommand(oCmd,-1,value);
|
||||
item->SendStatus(FLAG_FLAGS);
|
||||
return 1;
|
||||
|
||||
case CMD_ENABLE:
|
||||
//item->setCmd(CMD_ENABLE);
|
||||
//item->SendStatus(FLAG_COMMAND);
|
||||
if (isNotRetainingStatus())
|
||||
{
|
||||
item->setCmd(CMD_ON);
|
||||
item->SendStatus(FLAG_COMMAND);
|
||||
}
|
||||
item->setFlag(FLAG_ACTION_NEEDED);
|
||||
executeCommand(oCmd,-1,value);
|
||||
executeCommand(oCmd,-1,value);
|
||||
if (isActive()) executeCommand(oCmd,-1,itemCmd().Cmd((CMD_ON)));
|
||||
|
||||
|
||||
store->prevOut=-2.0;
|
||||
return 1;
|
||||
|
||||
case CMD_DISABLE:
|
||||
//item->setCmd(CMD_DISABLE);
|
||||
//item->SendStatus(FLAG_COMMAND);
|
||||
executeCommand(oCmd,-1,value);
|
||||
if (!isActive()) executeCommand(oCmd,-1,itemCmd().Cmd((CMD_OFF)));
|
||||
return 1;
|
||||
/*
|
||||
case CMD_OFF:
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
int Stop() override;
|
||||
int isActive() override;
|
||||
int getChanType() override;
|
||||
int getDefaultStorageType(){return ST_FLOAT;};
|
||||
//int getDefaultStorageType(){return ST_FLOAT;};
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||
void alarm(bool);
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
int Stop() override;
|
||||
int getChanType() override;
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||
int getDefaultStorageType(){return ST_INT32;};
|
||||
//int getDefaultStorageType(){return ST_INT32;};
|
||||
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL) override;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -26,10 +26,9 @@ e-mail anklimov@gmail.com
|
||||
#include "options.h"
|
||||
#include "main.h"
|
||||
#include "aJSON.h"
|
||||
//#include "twi.h"
|
||||
|
||||
extern aJsonObject *owArr;
|
||||
extern uint32_t timerCtr;
|
||||
//extern uint32_t timerCtr;
|
||||
aJsonObject *dev2Check = NULL;
|
||||
|
||||
OneWire *oneWire = NULL;
|
||||
@@ -62,7 +61,7 @@ char * getReadableNote(aJsonObject * owObj)
|
||||
void processTemp(aJsonObject * owObj, float currentTemp) {
|
||||
if (!owObj || !owArr) return;
|
||||
char* note = getReadableNote(owObj);
|
||||
debugSerial<<endl<<F("1WT:")<<currentTemp<<F(" <")<<owObj->name<<F("> ");
|
||||
debugSerial <<F("1WT:")<<currentTemp<<F(" <")<<owObj->name<<F("> ");
|
||||
if ((currentTemp != -127.0) && (currentTemp != 85.0) && (currentTemp != 0.0))
|
||||
{
|
||||
if (note) debugSerial<<note;
|
||||
@@ -127,8 +126,8 @@ int owSetup() {
|
||||
if (oneWire) return true; // Already initialized
|
||||
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
|
||||
|
||||
debugSerial<<F("DS2482_100_I2C_TO_1W_BRIDGE init")<<endl;
|
||||
debugSerial<<F("Free:")<<freeRam()<<endl;
|
||||
debugSerial<<F("1WT: DS2482_100_I2C_TO_1W_BRIDGE init")<<endl;
|
||||
//debugSerial<<F("Free:")<<freeRam()<<endl;
|
||||
oneWire = new OneWire;
|
||||
#else
|
||||
debugSerial.print(F("One wire setup on PIN:"));
|
||||
@@ -146,7 +145,7 @@ if (!oneWire)
|
||||
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
|
||||
Wire.begin();
|
||||
if (oneWire->checkPresence()) {
|
||||
infoSerial.println(F("1WT: DS2482-100 present"));
|
||||
infoSerial.println(F("1WT: DS2482-100 present, reset"));
|
||||
oneWire->deviceReset();
|
||||
#ifdef APU_OFF
|
||||
debugSerial.println(F("APU off"));
|
||||
@@ -154,11 +153,11 @@ if (!oneWire)
|
||||
oneWire->setActivePullup();
|
||||
#endif
|
||||
|
||||
debugSerial.println(F("\tChecking for 1-Wire devices..."));
|
||||
// debugSerial.println(F("\tChecking for 1-Wire devices..."));
|
||||
if (oneWire->wireReset())
|
||||
debugSerial.println(F("\tReset done"));
|
||||
debugSerial.println(F("1WT: Bus Reset done"));
|
||||
else
|
||||
debugSerial.println(F("\tDS2482 reset error"));
|
||||
debugSerial.println(F("1WT: Bus reset error"));
|
||||
//return true;
|
||||
}
|
||||
else
|
||||
@@ -226,25 +225,25 @@ int sensors_loop(void) {
|
||||
|
||||
case DS2482_ERROR_CONFIG:
|
||||
errorSerial<<F("1WT: DS2482_ERROR_CONFIG")<<endl;
|
||||
oneWire->wireReset();
|
||||
return INTERVAL_1W;
|
||||
i2cReset();
|
||||
break;
|
||||
|
||||
case DS2482_ERROR_TIMEOUT:
|
||||
errorSerial<<F("1WT: 1-wire shorted")<<endl;
|
||||
oneWire->wireReset();
|
||||
return INTERVAL_1W;
|
||||
case DS2482_ERROR_TIMEOUT: //Busy over time
|
||||
errorSerial<<F("1WT: BUSY timeout")<<endl;
|
||||
i2cReset();
|
||||
break;
|
||||
|
||||
default:
|
||||
errorSerial<<F("1WT: error")<<endl;
|
||||
oneWire->wireReset();
|
||||
return INTERVAL_1W;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
if (!oneWire->checkPresence())
|
||||
{
|
||||
infoSerial.println(F("1WT: lost DS2482-100"));
|
||||
i2cReset();
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -24,10 +24,12 @@ extern uint8_t udpDebugLevel;
|
||||
#define SerialPortType HardwareSerial
|
||||
#endif
|
||||
|
||||
#define LOG_TRACE 9
|
||||
#define LOG_DEBUG 7
|
||||
#define LOG_INFO 6
|
||||
#define LOG_ERROR 3
|
||||
|
||||
#define traceSerial if (serialDebugLevel>=LOG_TRACE || udpDebugLevel>=LOG_TRACE) debugSerial
|
||||
class Streamlog : public Print
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#define MAXFLASHSTR 32
|
||||
#define PWDFLASHSTR 16
|
||||
#define EEPROM_SIGNATURE "LHC1"
|
||||
#define EEPROM_SIGNATURE "LHC2"
|
||||
#define EEPROM_SIGNATURE_LENGTH 4
|
||||
|
||||
//#define EEPROM_offsetJSON IFLASH_PAGE_SIZE
|
||||
@@ -23,12 +23,12 @@ const char EEPROM_signature[] = EEPROM_SIGNATURE;
|
||||
uint32_t configFlags32bit;
|
||||
struct
|
||||
{
|
||||
uint8_t serialDebugLevel:3;
|
||||
uint8_t serialDebugLevel:4;
|
||||
uint8_t notGetConfigFromHTTP:1;
|
||||
uint8_t udpDebugLevel:3;
|
||||
uint8_t notSaveSuccedConfig:1;
|
||||
uint8_t dhcpFallback:1;
|
||||
uint8_t spare2:7;
|
||||
uint8_t spare2:6;
|
||||
uint16_t sysConfigHash;
|
||||
};
|
||||
} systemConfigFlags;
|
||||
|
||||
0
lighthub/templateStr.cpp
Normal file
0
lighthub/templateStr.cpp
Normal file
110
lighthub/templateStr.h
Normal file
110
lighthub/templateStr.h
Normal file
@@ -0,0 +1,110 @@
|
||||
#ifndef _TEMPLATE_STREAM_H_
|
||||
#define _TEMPLATE_STREAM_H_
|
||||
|
||||
#include <Stream.h>
|
||||
#include <aJSON.h>
|
||||
#include <streamlog.h>
|
||||
//#define KEYLEN 8
|
||||
extern aJsonObject * topics;
|
||||
|
||||
class templateStream : public Stream
|
||||
{
|
||||
public:
|
||||
templateStream(char *s, short sfx=0) : str(s), pos(0), val(NULL), valpos(0), bucket(0),suffix(sfx) { }
|
||||
|
||||
// Stream methods
|
||||
virtual int available() { return str[pos]; }
|
||||
virtual int read() {
|
||||
if (bucket)
|
||||
|
||||
{ int ch = bucket;
|
||||
bucket=0;
|
||||
return ch;
|
||||
};
|
||||
|
||||
if (str[pos]=='$')
|
||||
{
|
||||
if (str[pos+1]=='{')
|
||||
{
|
||||
unsigned int i = 0;
|
||||
while (str[pos+2+i] && str[pos+2+i]!='}') i++;
|
||||
if (i && (str[pos+2+i]=='}'))
|
||||
{
|
||||
str[pos+2+i]='\0';
|
||||
val=resolveKey(str+pos+2);
|
||||
valpos=0;
|
||||
str[pos+2+i]='}';
|
||||
pos+=3+i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (val)
|
||||
{
|
||||
char ch = val[valpos];
|
||||
if (ch)
|
||||
{
|
||||
valpos++;
|
||||
return ch;
|
||||
}
|
||||
else val = NULL;
|
||||
|
||||
}
|
||||
|
||||
if (str)
|
||||
{
|
||||
char ch = str[pos];
|
||||
if (ch)
|
||||
{
|
||||
pos++;
|
||||
return ch;
|
||||
}
|
||||
else
|
||||
{
|
||||
str=NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
else return -1;
|
||||
|
||||
}
|
||||
virtual int peek()
|
||||
{
|
||||
int bucket = read();
|
||||
return bucket;
|
||||
}
|
||||
|
||||
virtual void flush() { };
|
||||
// Print methods
|
||||
virtual size_t write(uint8_t c) { return 0; };
|
||||
virtual char * resolveKey(char *key)
|
||||
{
|
||||
if (topics && topics->type == aJson_Object)
|
||||
{
|
||||
aJsonObject *valObj = aJson.getObjectItem(topics, key);
|
||||
if (valObj->type == aJson_String) return valObj->valuestring;
|
||||
|
||||
}
|
||||
if (suffix && (suffix<suffixNum) && !strcmp(key,"sfx"))
|
||||
{
|
||||
//debugSerial<<F("Template: Suffix=")<<suffix<<endl;
|
||||
buffer[0]='/';
|
||||
strncpy_P(buffer+1,suffix_P[suffix],sizeof(buffer)-2);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
char *str;
|
||||
unsigned int pos;
|
||||
char *val;
|
||||
unsigned int valpos;
|
||||
int bucket;
|
||||
short suffix;
|
||||
char buffer[8];
|
||||
};
|
||||
|
||||
#endif // _TEMPLATE_STREAM_H_
|
||||
@@ -82,17 +82,29 @@ const char on_P[] PROGMEM = "on";
|
||||
|
||||
*/
|
||||
|
||||
#define ON_P commands_P[CMD_ON]
|
||||
#define OFF_P commands_P[CMD_OFF]
|
||||
#define REST_P commands_P[CMD_RESTORE]
|
||||
#define TOGGLE_P commands_P[CMD_TOGGLE]
|
||||
#define HALT_P commands_P[CMD_HALT]
|
||||
#define XON_P commands_P[CMD_XON]
|
||||
#define XOFF_P commands_P[CMD_XOFF]
|
||||
#define HEAT_P commands_P[CMD_HEAT]
|
||||
#define COOL_P commands_P[CMD_COOL]
|
||||
#define AUTO_P commands_P[CMD_AUTO]
|
||||
#define FAN_ONLY_P commands_P[CMD_FAN]
|
||||
#define DRY_P commands_P[CMD_DRY]
|
||||
#define HIGH_P commands_P[CMD_HIGH]
|
||||
#define MED_P commands_P[CMD_MED]
|
||||
#define LOW_P commands_P[CMD_LOW]
|
||||
#define ENABLE_P commands_P[CMD_ENABLE]
|
||||
#define DISABLE_P commands_P[CMD_DISABLE]
|
||||
#define FREEZE_P commands_P[CMD_FREEZE]
|
||||
#define UNFREEZE_P commands_P[CMD_UNFREEZE]
|
||||
|
||||
const char ERROR_P[] PROGMEM = "ERR";
|
||||
|
||||
//Commands
|
||||
|
||||
const char ON_P[] PROGMEM = "ON";
|
||||
const char OFF_P[] PROGMEM = "OFF";
|
||||
const char REST_P[] PROGMEM = "REST";
|
||||
const char TOGGLE_P[] PROGMEM = "TOGGLE";
|
||||
const char HALT_P[] PROGMEM = "HALT";
|
||||
const char XON_P[] PROGMEM = "XON";
|
||||
const char XOFF_P[] PROGMEM = "XOFF";
|
||||
/*
|
||||
const char INCREASE_P[] PROGMEM = "INCREASE";
|
||||
const char DECREASE_P[] PROGMEM = "DECREASE";
|
||||
@@ -102,6 +114,15 @@ const char FALSE_P[] PROGMEM = "FALSE";
|
||||
const char ENABLED_P[] PROGMEM = "ENABLED";
|
||||
const char DISABLED_P[] PROGMEM = "DISABLED";
|
||||
*/
|
||||
|
||||
/*
|
||||
const char ON_P[] PROGMEM = "ON";
|
||||
const char OFF_P[] PROGMEM = "OFF";
|
||||
const char REST_P[] PROGMEM = "REST";
|
||||
const char TOGGLE_P[] PROGMEM = "TOGGLE";
|
||||
const char HALT_P[] PROGMEM = "HALT";
|
||||
const char XON_P[] PROGMEM = "XON";
|
||||
const char XOFF_P[] PROGMEM = "XOFF";
|
||||
const char HEAT_P[] PROGMEM = "HEAT";
|
||||
const char COOL_P[] PROGMEM = "COOL";
|
||||
const static char AUTO_P[] PROGMEM = "AUTO";
|
||||
@@ -112,13 +133,15 @@ const char DRY_P[] PROGMEM = "DRY";
|
||||
const char HIGH_P[] PROGMEM = "HIGH";
|
||||
const char MED_P[] PROGMEM = "MEDIUM";
|
||||
const char LOW_P[] PROGMEM = "LOW";
|
||||
const char ERROR_P[] PROGMEM = "ERR";
|
||||
|
||||
const char ENABLE_P[] PROGMEM = "ENABLE";
|
||||
const char DISABLE_P[] PROGMEM = "DISABLE";
|
||||
const char FREEZE_P[] PROGMEM = "FREEZE";
|
||||
const char UNFREEZE_P[] PROGMEM = "UNFREEZE";
|
||||
*/
|
||||
|
||||
// SubTopics
|
||||
/*
|
||||
const char SET_P[] PROGMEM = "set";
|
||||
const char CMD_P[] PROGMEM = "cmd";
|
||||
const char MODE_P[] PROGMEM = "mode";
|
||||
@@ -132,7 +155,7 @@ const char VAL_P[] PROGMEM = "val";
|
||||
const char DEL_P[] PROGMEM = "del";
|
||||
const char _RAW_P[] PROGMEM = "raw";
|
||||
const char CTRL_P[] PROGMEM = "ctrl";
|
||||
|
||||
*/
|
||||
/*
|
||||
const char RPM_P[] PROGMEM = "rpm";
|
||||
const char STATE_P[] PROGMEM = "state";
|
||||
|
||||
@@ -27,6 +27,7 @@ e-mail anklimov@gmail.com
|
||||
#include "item.h"
|
||||
#include <PubSubClient.h>
|
||||
#include <HardwareSerial.h>
|
||||
#include "templateStr.h"
|
||||
|
||||
#ifdef CRYPT
|
||||
#include "SHA256.h"
|
||||
@@ -690,8 +691,22 @@ switch (cmdType)
|
||||
//else itemCommand = _itemCmd.toString(Buffer,sizeof(Buffer));
|
||||
|
||||
char * emitCommand;
|
||||
short suffix=0;
|
||||
// aJsonObject * dict=NULL;
|
||||
|
||||
if(ecmd && ecmd->type == aJson_String) emitCommand = ecmd->valuestring;
|
||||
else emitCommand = _itemCmd.toString(Buffer,sizeof(Buffer));
|
||||
else
|
||||
{
|
||||
emitCommand = _itemCmd.toString(Buffer,sizeof(Buffer));
|
||||
// dict = aJson.createObject();
|
||||
// aJson.addStringToObject(dict, "sfx", )
|
||||
suffix=_itemCmd.getSuffix();
|
||||
if (!suffix)
|
||||
{
|
||||
if (_itemCmd.isCommand()) suffix=S_CMD;
|
||||
else if (_itemCmd.isValue()) suffix = S_SET;
|
||||
}
|
||||
}
|
||||
|
||||
//debugSerial << F("IN:") << (pin) << F(" : ") <<endl;
|
||||
if (item) {
|
||||
@@ -705,7 +720,12 @@ switch (cmdType)
|
||||
|
||||
|
||||
if (emit && emitCommand && emit->type == aJson_String) {
|
||||
debugSerial << F("Emit: ")<<emit->valuestring<< F(" -> ")<<emitCommand<<endl;
|
||||
|
||||
templateStream ts(emit->valuestring,suffix);
|
||||
char addrstr[MQTT_TOPIC_LENGTH];
|
||||
//ts.setTimeout(0);
|
||||
addrstr[ts.readBytesUntil('\0',addrstr,sizeof(addrstr))]='\0';
|
||||
debugSerial << F("Emit: <")<<emit->valuestring<<"> "<<addrstr<< F(" -> ")<<emitCommand<<endl;
|
||||
/*
|
||||
TODO implement
|
||||
#ifdef WITH_DOMOTICZ
|
||||
@@ -720,8 +740,8 @@ switch (cmdType)
|
||||
*/
|
||||
|
||||
|
||||
char addrstr[MQTT_TOPIC_LENGTH];
|
||||
strncpy(addrstr,emit->valuestring,sizeof(addrstr));
|
||||
|
||||
//strncpy(addrstr,emit->valuestring,sizeof(addrstr));
|
||||
if (mqttClient.connected() && !ethernetIdleCount)
|
||||
{
|
||||
if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring);
|
||||
@@ -880,7 +900,7 @@ bool checkToken(char * token, char * data)
|
||||
|
||||
|
||||
bool i2cReset(){
|
||||
debugSerial.println("I2C Reset");
|
||||
debugSerial.println(F("I2C Reset"));
|
||||
|
||||
Wire.endTransmission(true);
|
||||
#if !defined(ARDUINO_ARCH_ESP8266)
|
||||
@@ -896,19 +916,22 @@ pinMode(SDA,INPUT);
|
||||
pulse=!pulse;
|
||||
delay(10);//10us мкс
|
||||
}
|
||||
|
||||
delay(20);
|
||||
Wire.begin();
|
||||
|
||||
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
|
||||
if (oneWire && oneWire->checkPresence())
|
||||
{
|
||||
oneWire->deviceReset();
|
||||
debugSerial.println(F("1WT: DS2482 present, reset"));
|
||||
#ifndef APU_OFF
|
||||
oneWire->setActivePullup();
|
||||
#endif
|
||||
if (oneWire->wireReset())
|
||||
debugSerial.println(F("\tReset done"));
|
||||
debugSerial.println(F("1WT: Bus Reset done"));
|
||||
else
|
||||
debugSerial.println(F("\tDS2482 reset error"));
|
||||
debugSerial.println(F("1WT: Bus reset error"));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -916,5 +939,8 @@ if (oneWire && oneWire->checkPresence())
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#pragma message(VAR_NAME_VALUE(debugSerial))
|
||||
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD))
|
||||
|
||||
@@ -193,7 +193,7 @@ monitor_speed = 115200
|
||||
platform = espressif32
|
||||
framework = arduino
|
||||
monitor_filters = esp32_exception_decoder
|
||||
build_type = debug
|
||||
;build_type = debug
|
||||
board = esp32-evb
|
||||
extra_scripts = extra_script.py
|
||||
monitor_speed = 115200
|
||||
@@ -521,10 +521,24 @@ lib_deps =
|
||||
platform = espressif8266
|
||||
framework = arduino
|
||||
;board = nodemcuv2
|
||||
board = esp01_1m
|
||||
;esp12e ESP8266 80MHz 4MB 80KB Espressif ESP8266 ESP-12E
|
||||
;esp01_1m ESP8266 80MHz 1MB 80KB Espressif Generic ESP8266 ESP-01 1M
|
||||
extra_scripts = extra_script.py
|
||||
board_build.ldscript = eagle.flash.1m64.ld
|
||||
;upload_protocol = esptool
|
||||
|
||||
;;;; 1M plug ;;;
|
||||
;board = esp01_1m
|
||||
;board_build.ldscript = eagle.flash.1m64.ld
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;;; WEMOS D1 ;;;;;
|
||||
board = d1_mini
|
||||
; change microcontroller
|
||||
board_build.mcu = esp8266
|
||||
; change MCU frequency
|
||||
board_build.f_cpu = 80000000L
|
||||
upload_protocol = esptool
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;build_type = debug
|
||||
;monitor_filters = esp8266_exception_decoder
|
||||
|
||||
|
||||
Reference in New Issue
Block a user