Refactoring #4 (untested)

This commit is contained in:
2020-11-17 20:13:06 +03:00
parent 963a934f51
commit 14ff55fd59
15 changed files with 311 additions and 211 deletions

View File

@@ -6,14 +6,23 @@
#include "item.h" #include "item.h"
#include "main.h" #include "main.h"
//colorChannel::colorChannel(Item * _item)
int out_dmx::Ctrl(itemCmd cmd, char* subItem)
short colorChannel::getChannelAddr(short n)
{
if (!n) return iaddr;
if (n+1>numArgs) return iaddr+n;
return item->getArg(n);
}
int colorChannel::Ctrl(itemCmd cmd, char* subItem)
{ {
int chActive = item->isActive(); int chActive = item->isActive();
bool toExecute = (chActive>0); // execute if channel is active now bool toExecute = (chActive>0); // execute if channel is active now
int suffixCode = cmd.getSuffix(); int suffixCode = cmd.getSuffix();
itemCmd st(ST_HSV); itemCmd st(ST_HSV,CMD_VOID);
if (!suffixCode) toExecute=true; //forced execute if no suffix if (!suffixCode) toExecute=true; //forced execute if no suffix
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command recognized , but w/o correct cmd suffix - threat it as command if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command recognized , but w/o correct cmd suffix - threat it as command
@@ -67,7 +76,7 @@ case S_CMD:
debugSerial<<st.param.aslong<<F(": No stored values - default\n"); debugSerial<<st.param.aslong<<F(": No stored values - default\n");
} }
st.saveItem(item, subItem, true); st.saveItem(item, true);
PixelCtrl(st); PixelCtrl(st);
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS ); item->SendStatus(SEND_COMMAND | SEND_PARAMETERS );
return 1; return 1;

View File

@@ -9,9 +9,15 @@
class colorChannel : public abstractOut { class colorChannel : public abstractOut {
public: public:
colorChannel(Item * _item):abstractOut(_item){}; colorChannel(Item * _item):abstractOut(_item) {
iaddr = item->getArg(); //Once retrieve and store base address
if (iaddr<0) iaddr=-iaddr;
numArgs = item->getArgCount(); // and how many addresses is configured
};
int Ctrl(itemCmd cmd, char* subItem=NULL) override; int Ctrl(itemCmd cmd, char* subItem=NULL) override;
virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true ) =0; virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true ) =0;
short getChannelAddr(short n =0);
protected: protected:
short iaddr;
short numArgs;
}; };

View File

@@ -23,6 +23,7 @@ e-mail anklimov@gmail.com
#include "utils.h" #include "utils.h"
#include <PubSubClient.h> #include <PubSubClient.h>
#include "main.h" #include "main.h"
#include "itemCmd.h""
#ifndef DHT_DISABLE #ifndef DHT_DISABLE
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
@@ -1012,11 +1013,11 @@ if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestri
Item it(item->valuestring); Item it(item->valuestring);
if (it.isValid()) { if (it.isValid()) {
if (newValue) { //send set command if (newValue) { //send set command
if (!scmd || scmd->type != aJson_String) it.Ctrl(CMD_ON, 0, NULL); if (!scmd || scmd->type != aJson_String) it.Ctrl(itemCmd(ST_VOID,CMD_ON));
else if (strlen(scmd->valuestring)) else if (strlen(scmd->valuestring))
it.Ctrl(scmd->valuestring); it.Ctrl(scmd->valuestring);
} else { //send reset command } else { //send reset command
if (!rcmd || rcmd->type != aJson_String) it.Ctrl(CMD_OFF, 0, NULL); if (!rcmd || rcmd->type != aJson_String) it.Ctrl(itemCmd(ST_VOID,CMD_OFF));
else if (strlen(rcmd->valuestring)) else if (strlen(rcmd->valuestring))
it.Ctrl(rcmd->valuestring); it.Ctrl(rcmd->valuestring);
} }
@@ -1049,10 +1050,11 @@ void Input::onAnalogChanged(float newValue) {
} }
if (item && item->type == aJson_String) { if (item && item->type == aJson_String) {
int intNewValue = round(newValue); //int intNewValue = round(newValue);
Item it(item->valuestring); Item it(item->valuestring);
if (it.isValid()) { if (it.isValid()) {
it.Ctrl(0, 1, &intNewValue, true); //it.Ctrl(0, 1, &intNewValue, true);
it.Ctrl(itemCmd(newValue));
} }
} }
} }

View File

@@ -25,6 +25,7 @@ e-mail anklimov@gmail.com
#include "textconst.h" #include "textconst.h"
#include "main.h" #include "main.h"
#include "bright.h" #include "bright.h"
#include "itemCmd.h"
#ifdef _dmxout #ifdef _dmxout
#include "dmx.h" #include "dmx.h"
@@ -134,7 +135,7 @@ void Item::Parse() {
case CH_RGB: case CH_RGB:
case CH_DIMMER: case CH_DIMMER:
driver = new out_dmx (this); driver = new out_dmx (this);
// debugSerial<<F("SPILED driver created")<<endl; // debugSerial<<F("DMX driver created")<<endl;
break; break;
#endif #endif
#ifndef SPILED_DISABLE #ifndef SPILED_DISABLE
@@ -289,6 +290,13 @@ int Item::getArg(short n) //Return arg int or first array element if Arg is arra
else return 0;//-2; else return 0;//-2;
} }
short Item::getArgCount()
{
if (!itemArg) return 0;
if (itemArg->type == aJson_Int) return 1;
if (itemArg->type == aJson_Array) return aJson.getArraySize(itemArg);
else return 0;
}
/* /*
int Item::getVal(short n) //Return Val from Value array int Item::getVal(short n) //Return Val from Value array
{ if (!itemVal) return -1; { if (!itemVal) return -1;
@@ -403,31 +411,6 @@ boolean Item::isValid() {
return (itemArr && (itemArr->type == aJson_Array)); return (itemArr && (itemArr->type == aJson_Array));
} }
/*
void Item::copyPar (aJsonObject *itemV)
{ int n=aJson.getArraySize(itemV);
//for (int i=aJson.getArraySize(itemVal);i<n;i++) aJson.addItemToArray(itemVal,aJson.createItem(int(0))); //Enlarge array of Values
for (int i=0;i<n;i++) setPar(i,aJson.getArrayItem(itemV,i)->valueint);
}
*/
#if defined(ARDUINO_ARCH_ESP32)
void analogWrite(int pin, int val)
{
//TBD
}
#endif
/*
boolean Item::getEnableCMD(int delta) {
return ((millis() - lastctrl > (unsigned long) delta));// || ((void *)itemArr != (void *) lastobj));
}
*/
// If retrieving subitem code ok - return it // If retrieving subitem code ok - return it
// parameter will point on the rest truncated part of subitem // parameter will point on the rest truncated part of subitem
// or pointer to NULL of whole string converted to subitem code // or pointer to NULL of whole string converted to subitem code
@@ -460,16 +443,16 @@ else
return suffixCode; return suffixCode;
} }
#define MAXCTRLPAR 3 //#define MAXCTRLPAR 3
// myhome/dev/item/subItem // myhome/dev/item/subItem
int Item::Ctrl(char * payload, char * subItem){ int Item::Ctrl(char * payload, char * subItem)
if (!payload) return 0; {
if (!payload) return 0;
itemCmd st(ST_VOID,CMD_VOID);
int suffixCode = 0; int suffixCode = 0;
//int setCommand = CMD_SET; //default SET behavior now - not turn on channels
int setCommand = 0;
if ((!subItem || !strlen(subItem)) && strlen(defaultSubItem)) if ((!subItem || !strlen(subItem)) && strlen(defaultSubItem))
subItem = defaultSubItem; /// possible problem here with truncated default subItem = defaultSubItem; /// possible problem here with truncated default
@@ -479,57 +462,66 @@ if (subItem && strlen(subItem))
if (!suffixCode && defaultSuffixCode) if (!suffixCode && defaultSuffixCode)
suffixCode = defaultSuffixCode; suffixCode = defaultSuffixCode;
st.setSuffix(suffixCode);
int i=0; int i=0;
while (payload[i]) {payload[i]=toupper(payload[i]);i++;}; while (payload[i]) {payload[i]=toupper(payload[i]);i++;};
int cmd = txt2cmd(payload); int cmd = txt2cmd(payload);
debugSerial<<F("Txt2Cmd:")<<cmd<<endl; debugSerial<<F("Txt2Cmd:")<<cmd<<endl;
st.Cmd(cmd);
//if (isSet)
//{
switch (cmd) { switch (cmd) {
case CMD_HSV: st.Cmd(0);
case CMD_UP: case CMD_UP:
case CMD_DN: case CMD_DN:
setCommand=cmd;
case CMD_HSV:
// suffixCode=S_HSV; //override code for known payload
case CMD_VOID: case CMD_VOID:
{ {
//Parsing integers from payload
short i = 0; short i = 0;
int Par[3]; int Par[3];
while (payload && i < 3) while (payload && i < 3)
Par[i++] = getInt((char **) &payload); Par[i++] = getInt((char **) &payload);
return Ctrl(setCommand, i, Par, suffixCode, subItem); switch (i) //Number of params
{
case 1: st.Percents(Par[0]);
break;
case 2: st.setH(Par[0]);
st.setS(Par[0]);
break;
case 3: st.HSV(Par[0],Par[1],Par[2]);
default:;
}
//return Ctrl(setCommand, i, Par, suffixCode, subItem);
return Ctrl(st,subItem);
} }
break; break;
case CMD_UNKNOWN: //Not known command case CMD_UNKNOWN: //Not known command
case CMD_JSON: //JSON input (not implemented yet case CMD_JSON: //JSON input (not implemented yet
break; break;
#if not defined(ARDUINO_ARCH_ESP32) and not defined(ESP8266) and not defined(ARDUINO_ARCH_STM32) and not defined(DMX_DISABLE)
#ifndef ADAFRUIT_LED
case CMD_RGB: //RGB color in #RRGGBB notation case CMD_RGB: //RGB color in #RRGGBB notation
{
suffixCode=S_HSV; //override code for known payload {
CRGB rgb; //Parsing integers from payload
if (sscanf((const char*)payload, "#%2X%2X%2X", &rgb.r, &rgb.g, &rgb.b) == 3) { short i = 0;
int Par[3]; int Par[4];
CHSV hsv = rgb2hsv_approximate(rgb); while (payload && i < 4)
Par[0] = map(hsv.h, 0, 255, 0, 365); Par[i++] = getInt((char **) &payload);
Par[1] = map(hsv.s, 0, 255, 0, 100);
Par[2] = map(hsv.v, 0, 255, 0, 100); switch (i) //Number of params
return Ctrl(setCommand, 3, Par, suffixCode, subItem); {
} case 3: st.RGB(Par[0],Par[1],Par[2]);
break; break;
case 4: st.RGBW(Par[0],Par[1],Par[2],Par[3]);
default:;
}
//return Ctrl(setCommand, i, Par, suffixCode, subItem);
return Ctrl(st,subItem);
} }
#endif
#endif
default: //some known command default: //some known command
return Ctrl(cmd, 0, NULL, suffixCode, subItem); return Ctrl(st, subItem);
} //ctrl } //ctrl
return 0; return 0;
@@ -583,7 +575,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem)
//int iaddr = getArg(); //int iaddr = getArg();
bool chActive =(isActive()>0); bool chActive =(isActive()>0);
itemCmd st; itemCmd st(ST_VOID,CMD_VOID);
st.loadItem(this); //Restore previous channel state to "st" st.loadItem(this); //Restore previous channel state to "st"
//threating Toggle, Restore, XOFF special conditional commands/ convert to ON, OFF //threating Toggle, Restore, XOFF special conditional commands/ convert to ON, OFF
@@ -724,7 +716,7 @@ if (driver) //New style modular code
} }
return res; return res;
} }
// Legacy monolite core code
//================== //==================
switch (itemType) { switch (itemType) {
case CH_GROUP://Group case CH_GROUP://Group
@@ -743,78 +735,57 @@ switch (itemType) {
configLocked--; configLocked--;
} //if } //if
} //case } //case
} //switch
//=========
/*
bool toExecute = (chActive>0);
if (cmd>0 && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it // rest of Legacy monolite core code (to be refactored )
case CH_RELAY:
{
short iaddr=getArg();
short icmd =cmd.getCmd();
if (iaddr)
{
int k;
short inverse = 0;
if (iaddr < 0) {
iaddr = -iaddr;
inverse = 1;
}
pinMode(iaddr, OUTPUT);
if (inverse)
digitalWrite(iaddr, k = ((icmd == CMD_ON || icmd == CMD_XON) ? LOW : HIGH));
else
digitalWrite(iaddr, k = ((icmd == CMD_ON || icmd == CMD_XON) ? HIGH : LOW));
debugSerial<<F("Pin:")<<iaddr<<F("=")<<k<<endl;
break;
}
}
case CH_THERMO:
///thermoSet(name,cmd,Par1); all activities done - update temp & cmd
break;
#ifndef MODBUS_DISABLE
switch(suffixCode) case CH_MODBUS:
{ modbusDimmerSet(cmd.getPercents());
case S_NOTFOUND: break;
// turn on and set case CH_VC:
toExecute = true; VacomSetFan(cmd.getPercents(), cmd.getCmd());
debugSerial<<F("Forced execution"); break;
case S_SET: case CH_VCTEMP: {
if (!Parameters || n==0) return 0; VacomSetHeat(cmd.getPercents(), cmd.getCmd());
item->setVal(st=Parameters[0]); //Store break;
if (!suffixCode)
{
if (chActive>0 && !st) item->setCmd(CMD_OFF);
if (chActive==0 && st) item->setCmd(CMD_ON);
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED);
if (item->getExt()) item->setExt(millis()+maxOnTime); //Extend motor time
}
else item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
return 1;
//break;
case S_CMD:
item->setCmd(cmd);
switch (cmd)
{
case CMD_ON:
//retrive stored values
st = item->getVal();
if (st && (st<MIN_VOLUME) ) st=INIT_VOLUME; // & send
item->setVal(st);
if (st) //Stored smthng
{
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS);
debugSerial<<F("Restored: ")<<st<<endl;
} }
else #endif
{ } //switch
debugSerial<<st<<F(": No stored values - default\n");
// Store
st=100;
item->setVal(st);
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS );
}
if (item->getExt()) item->setExt(millis()+maxOnTime); //Extend motor time
return 1;
case CMD_OFF:
item->SendStatus(SEND_COMMAND);
if (item->getExt()) item->setExt(millis()+maxOnTime); //Extend motor time
return 1;
} //switch cmd
break;
} //switch suffix
debugSerial<<F("Unknown cmd")<<endl;
return 0;
*/
} }
/* RIP
int Item::Ctrl(short cmd, short n, int *Parameters, int suffixCode, char *subItem) { int Item::Ctrl(short cmd, short n, int *Parameters, int suffixCode, char *subItem) {
bool send = isNotRetainingStatus() ; bool send = isNotRetainingStatus() ;
if ((!subItem || !strlen(subItem)) && strlen(defaultSubItem)) if ((!subItem || !strlen(subItem)) && strlen(defaultSubItem))
@@ -839,7 +810,7 @@ bool send = isNotRetainingStatus() ;
debugSerial<<F(")")<<endl; debugSerial<<F(")")<<endl;
//======================// //======================//
itemCmd _itemCmd; itemCmd _itemCmd(ST_VOID,CMD_VOID);
switch (n) { switch (n) {
case 0: case 0:
_itemCmd.Cmd(cmd); _itemCmd.Cmd(cmd);
@@ -884,28 +855,6 @@ bool send = isNotRetainingStatus() ;
itemArgStore st; itemArgStore st;
switch (cmd) { switch (cmd) {
int t; int t;
/*
case CMD_ON:
if (getChanType()==CH_RGBW && getCmd() == CMD_ON && send && (chActive>0)) {
debugSerial<<F("Force White\n");
st.aslong = getVal();
//itemType = CH_WHITE;
Par[0] = st.h;
Par[1] = 0; //Zero saturation
Par[2] = 100; //Full power
n=3;
cmd=CMD_NUM; */
// Store
/*
st.h = Par[0];
st.s = Par[1];
st.v = Par[2];
setVal(st.aslong);
setCmd(cmd);
//Send to OH
if (send) SendStatus(SEND_COMMAND | SEND_PARAMETERS ); */
// } // if forcewhite
// break;
case CMD_TOGGLE: case CMD_TOGGLE:
@@ -1091,11 +1040,11 @@ bool send = isNotRetainingStatus() ;
return -3; return -3;
} }
break; break;
/* ////
case CMD_SET: //case CMD_SET:
res = driver->Ctrl(cmd, n, Parameters, send, suffixCode, subItem); //res = driver->Ctrl(cmd, n, Parameters, send, suffixCode, subItem);
break; //break;
*/ //
default: default:
res = driver->Ctrl(_itemCmd, subItem); res = driver->Ctrl(_itemCmd, subItem);
if (cmd) setCmd(cmd); if (cmd) setCmd(cmd);
@@ -1500,7 +1449,7 @@ return 1;
} }
*/
@@ -1860,7 +1809,8 @@ int Item::checkFM() {
int val = 100; int val = 100;
Item item(airGateObj->valuestring); Item item(airGateObj->valuestring);
if (item.isValid()) if (item.isValid())
item.Ctrl(0, 1, &val); // item.Ctrl(0, 1, &val);
item.Ctrl(itemCmd(ST_PERCENTS,CMD_VOID).Percents(val));
} }
} }
} else } else
@@ -1871,7 +1821,7 @@ int Item::checkFM() {
result = node.readHoldingRegisters(2111 - 1, 1); result = node.readHoldingRegisters(2111 - 1, 1);
if (result == node.ku8MBSuccess) aJson.addNumberToObject(out, "flt", (int) node.getResponseBuffer(0)); if (result == node.ku8MBSuccess) aJson.addNumberToObject(out, "flt", (int) node.getResponseBuffer(0));
modbusBusy=0; modbusBusy=0;
if (isActive()>0) Ctrl(CMD_OFF); //Shut down /// if (isActive()>0) Off(); //Shut down ///
modbusBusy=1; modbusBusy=1;
} else aJson.addNumberToObject(out, "flt", 0); } else aJson.addNumberToObject(out, "flt", 0);
@@ -1900,7 +1850,7 @@ int Item::checkFM() {
if (ftemp > FM_OVERHEAT_CELSIUS && set) { if (ftemp > FM_OVERHEAT_CELSIUS && set) {
if (mqttClient.connected() && !ethernetIdleCount) if (mqttClient.connected() && !ethernetIdleCount)
mqttClient.publish("/alarm/ovrht", itemArr->name); mqttClient.publish("/alarm/ovrht", itemArr->name);
Ctrl(CMD_OFF); //Shut down Off(); //Shut down
} }
} else } else
debugSerial << F("Modbus polling error=") << _HEX(result); debugSerial << F("Modbus polling error=") << _HEX(result);

View File

@@ -102,11 +102,12 @@ class Item
boolean isValid (); boolean isValid ();
boolean Setup(); boolean Setup();
void Stop(); void Stop();
int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL); //int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL);
int Ctrl(itemCmd cmd, char* subItem=NULL); int Ctrl(itemCmd cmd, char* subItem=NULL);
int Ctrl(char * payload, char * subItem=NULL); int Ctrl(char * payload, char * subItem=NULL);
int getArg(short n=0); int getArg(short n=0);
short getArgCount();
//int getVal(short n); //From VAL array. Negative if no array //int getVal(short n); //From VAL array. Negative if no array
long int getVal(); //From int val OR array long int getVal(); //From int val OR array
uint8_t getSubtype(); uint8_t getSubtype();
@@ -125,9 +126,9 @@ class Item
int SendStatus(int sendFlags); int SendStatus(int sendFlags);
int isActive(); int isActive();
int getChanType(); int getChanType();
inline int On (){return Ctrl(CMD_ON);}; inline int On (){return Ctrl(itemCmd(ST_VOID,CMD_ON));};
inline int Off(){return Ctrl(CMD_OFF);}; inline int Off(){return Ctrl(itemCmd(ST_VOID,CMD_OFF));};
inline int Toggle(){return Ctrl(CMD_TOGGLE);}; inline int Toggle(){return Ctrl(itemCmd(ST_VOID,CMD_TOGGLE));};
protected: protected:
//short cmd2changeActivity(int lastActivity, short defaultCmd = CMD_SET); //short cmd2changeActivity(int lastActivity, short defaultCmd = CMD_SET);

View File

@@ -43,6 +43,13 @@ itemCmd::itemCmd(uint8_t _type, uint8_t _code)
cmd.cmdCode=_code; cmd.cmdCode=_code;
} }
itemCmd::itemCmd(float val)
{
cmd.cmdCode=0;
cmd.itemArgType=ST_FLOAT;
param.asfloat=val;
}
itemCmd itemCmd::setDefault() itemCmd itemCmd::setDefault()
{ {
switch (cmd.itemArgType){ switch (cmd.itemArgType){
@@ -333,34 +340,36 @@ long int itemCmd::getInt()
} }
short itemCmd::getPercents() short itemCmd::getPercents(bool inverse)
{ {
switch (cmd.itemArgType) { switch (cmd.itemArgType) {
case ST_PERCENTS: case ST_PERCENTS:
case ST_HSV: case ST_HSV:
return param.v; if (inverse) return 100-param.v; else return param.v;
case ST_PERCENTS255: case ST_PERCENTS255:
case ST_HSV255: case ST_HSV255:
return map(param.v,0,255,0,100); if (inverse) return map(param.v,0,255,100,0);
else return map(param.v,0,255,0,100);
default: default:
return 0; return 0;
} }
} }
short itemCmd::getPercents255() short itemCmd::getPercents255(bool inverse)
{ {
switch (cmd.itemArgType) { switch (cmd.itemArgType) {
case ST_PERCENTS: case ST_PERCENTS:
case ST_HSV: case ST_HSV:
return map(param.v,0,100,0,255); if (inverse) return map(param.v,0,100,255,0);
else return map(param.v,0,100,0,255);
case ST_PERCENTS255: case ST_PERCENTS255:
case ST_HSV255: case ST_HSV255:
return param.v; if (inverse) return 255-param.v; else return param.v;
default: default:
return 0; return 0;
@@ -454,6 +463,27 @@ itemCmd itemCmd::HSV(uint16_t h, uint8_t s, uint8_t v)
return *this; return *this;
} }
itemCmd itemCmd::RGB(uint8_t r, uint8_t g, uint8_t b)
{
cmd.itemArgType=ST_RGB;
param.r=r;
param.g=g;
param.b=b;
return *this;
}
itemCmd itemCmd::RGBW(uint8_t r, uint8_t g, uint8_t b, uint8_t w)
{
cmd.itemArgType=ST_RGBW;
param.r=r;
param.g=g;
param.b=b;
param.w=w;
return *this;
}
itemCmd itemCmd::Int(uint32_t i) itemCmd itemCmd::Int(uint32_t i)
{ {
cmd.itemArgType=ST_UINT32; cmd.itemArgType=ST_UINT32;

View File

@@ -169,6 +169,7 @@ public:
itemArgStore param; itemArgStore param;
itemCmd(uint8_t _type=ST_VOID, uint8_t _code=CMD_VOID); itemCmd(uint8_t _type=ST_VOID, uint8_t _code=CMD_VOID);
itemCmd(float val);
itemCmd assignFrom(itemCmd from); itemCmd assignFrom(itemCmd from);
bool loadItem(Item * item, bool includeCommand=false ); bool loadItem(Item * item, bool includeCommand=false );
@@ -178,6 +179,8 @@ public:
itemCmd Int(uint32_t i); itemCmd Int(uint32_t i);
itemCmd Cmd(uint8_t i); itemCmd Cmd(uint8_t i);
itemCmd HSV(uint16_t h, uint8_t s, uint8_t v); itemCmd HSV(uint16_t h, uint8_t s, uint8_t v);
itemCmd RGB(uint8_t r, uint8_t g, uint8_t b);
itemCmd RGBW(uint8_t r, uint8_t g, uint8_t b, uint8_t w);
itemCmd setH(uint16_t); itemCmd setH(uint16_t);
itemCmd setS(uint8_t); itemCmd setS(uint8_t);
itemCmd setArgType(uint8_t); itemCmd setArgType(uint8_t);
@@ -192,8 +195,8 @@ public:
itemCmd incrementS(int16_t); itemCmd incrementS(int16_t);
long int getInt(); long int getInt();
short getPercents(); short getPercents(bool inverse=false);
short getPercents255(); short getPercents255(bool inverse=false);
uint8_t getCmd(); uint8_t getCmd();
uint8_t getArgType(); uint8_t getArgType();
uint8_t getCmdParam(); uint8_t getCmdParam();

View File

@@ -45,27 +45,44 @@ return 0;
int out_dmx::getChanType() int out_dmx::getChanType()
{ {
if (item) return item->itemType; if (item)
{
switch (numArgs)
{
case 3:
return CH_RGB;
case 4:
return CH_RGBW;
default:
return item->itemType;
}
return 0; return 0;
}
} }
int out_dmx::PixelCtrl(itemCmd cmd) int out_dmx::PixelCtrl(itemCmd cmd, char* subItem, bool show)
//int out_dmx::PixelCtrl(itemCmd cmd)
{ {
if (!item) return 0; if (!item || !show) return 0;
int iaddr = item->getArg(0); short cType=getChanType();
itemCmd st(ST_RGB);
if (cType==CH_DIMMER) //Single channel
{
DmxWrite(iaddr, cmd.getPercents255());
return 1;
}
itemCmd st(ST_RGB,CMD_VOID);
st.assignFrom(cmd); st.assignFrom(cmd);
switch (getChanType()) switch (cType)
{ case CH_DIMMER: {
DmxWrite(iaddr + 3, cmd.getPercents255());
break;
case CH_RGBW: case CH_RGBW:
DmxWrite(iaddr + 3, st.param.w); DmxWrite(getChannelAddr(3), st.param.w);
case CH_RGB: case CH_RGB:
DmxWrite(iaddr, st.param.r); DmxWrite(iaddr, st.param.r);
DmxWrite(iaddr + 1, st.param.g); DmxWrite(getChannelAddr(1), st.param.g);
DmxWrite(iaddr + 2, st.param.b); DmxWrite(getChannelAddr(2), st.param.b);
break; break;
default: ; default: ;
} }

View File

@@ -5,19 +5,21 @@
#include <abstractout.h> #include <abstractout.h>
#include <item.h> #include <item.h>
#include "colorchannel.h"
class out_dmx : public abstractOut { class out_dmx : public colorChannel {
public: public:
out_dmx(Item * _item):abstractOut(_item){}; out_dmx(Item * _item):colorChannel(_item){};
int Setup() override; int Setup() override;
int Poll(short cause) override; int Poll(short cause) override;
int Stop() override; int Stop() override;
int Status() override; int Status() override;
int isActive() override; int isActive() override;
int getChanType() override; int getChanType() override;
int Ctrl(itemCmd cmd, char* subItem=NULL) override; // int Ctrl(itemCmd cmd, char* subItem=NULL) override;
int PixelCtrl(itemCmd cmd); // int PixelCtrl(itemCmd cmd) override;
virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true ) override;
protected: protected:
}; };

View File

@@ -342,7 +342,7 @@ int out_Modbus::Ctrl(itemCmd cmd, char* subItem)
{ {
int chActive = item->isActive(); int chActive = item->isActive();
bool toExecute = (chActive>0); bool toExecute = (chActive>0);
itemCmd st(ST_UINT32); itemCmd st(ST_UINT32,CMD_VOID);
int suffixCode = cmd.getSuffix(); int suffixCode = cmd.getSuffix();
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it

View File

@@ -216,7 +216,7 @@ int out_Motor::Ctrl(itemCmd cmd, char* subItem)
int chActive = item->isActive(); int chActive = item->isActive();
bool toExecute = (chActive>0); bool toExecute = (chActive>0);
int suffixCode = cmd.getSuffix(); int suffixCode = cmd.getSuffix();
itemCmd st(ST_PERCENTS); itemCmd st(ST_PERCENTS,CMD_VOID);
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
item->setFlag(ACTION_NEEDED); item->setFlag(ACTION_NEEDED);

View File

@@ -9,9 +9,50 @@
static int driverStatus = CST_UNKNOWN; static int driverStatus = CST_UNKNOWN;
#if defined(ARDUINO_ARCH_ESP32)
void analogWrite(int pin, int val)
{
//TBD
}
#endif
int out_pwm::Setup() int out_pwm::Setup()
{ {
debugSerial<<F("PWM-Out Init")<<endl; debugSerial<<F("PWM-Out Init")<<endl;
if (!item || iaddr) return 0;
switch (getChanType())
{
case CH_RGBW:
pinMode(getChannelAddr(3), OUTPUT);
case CH_RGB:
pinMode(getChannelAddr(0), OUTPUT);
pinMode(getChannelAddr(1), OUTPUT);
pinMode(getChannelAddr(2), OUTPUT);
break;
default:
pinMode(iaddr, OUTPUT);
}
//timer 0 for pin 13 and 4
//timer 1 for pin 12 and 11
//timer 2 for pin 10 and 9
//timer 3 for pin 5 and 3 and 2
//timer 4 for pin 8 and 7 and 6
//prescaler = 1 ---> PWM frequency is 31000 Hz
//prescaler = 2 ---> PWM frequency is 4000 Hz
//prescaler = 3 ---> PWM frequency is 490 Hz (default value)
//prescaler = 4 ---> PWM frequency is 120 Hz
//prescaler = 5 ---> PWM frequency is 30 Hz
//prescaler = 6 ---> PWM frequency is <20 Hz
#if defined(__AVR_ATmega2560__)
int tval = 7; // this is 111 in binary and is used as an eraser
TCCR4B &= ~tval; // this operation (AND plus NOT), set the three bits in TCCR2B to 0
TCCR3B &= ~tval;
tval = 2;
TCCR4B |= tval;
TCCR3B |= tval;
#endif
driverStatus = CST_INITIALIZED; driverStatus = CST_INITIALIZED;
return 1; return 1;
} }
@@ -19,6 +60,19 @@ return 1;
int out_pwm::Stop() int out_pwm::Stop()
{ {
debugSerial<<F("PWM-Out stop")<<endl; debugSerial<<F("PWM-Out stop")<<endl;
switch (getChanType())
{
case CH_RGBW:
pinMode(getChannelAddr(3), INPUT);
case CH_RGB:
pinMode(getChannelAddr(0), INPUT);
pinMode(getChannelAddr(1), INPUT);
pinMode(getChannelAddr(2), INPUT);
break;
default:
pinMode(iaddr, INPUT);
}
driverStatus = CST_UNKNOWN; driverStatus = CST_UNKNOWN;
return 1; return 1;
} }
@@ -43,23 +97,49 @@ return 0;
int out_pwm::getChanType() int out_pwm::getChanType()
{ {
if (item) return item->itemType; if (item)
{
switch (numArgs)
{
case 3:
return CH_RGB;
case 4:
return CH_RGBW;
default:
return item->itemType;
}
}
return 0; return 0;
} }
int out_pwm::PixelCtrl(itemCmd cmd) int out_pwm::PixelCtrl(itemCmd cmd, char* subItem, bool show)
{ {
if (!item) return 0; if (!item || !iaddr || !show) return 0;
int iaddr = item->getArg(0);
itemCmd st(ST_RGB); bool inverse = (item->getArg()<0);
short cType = getChanType();
if (cType=CH_PWM)
{ short k;
analogWrite(iaddr, k=cmd.getPercents255(inverse));
debugSerial<<F("Pin:")<<iaddr<<F("=")<<k<<endl;
return 1;
}
itemCmd st(ST_RGB,CMD_VOID);
st.assignFrom(cmd); st.assignFrom(cmd);
switch (getChanType()) switch (cType)
{ case CH_PWM: {
// DmxWrite(iaddr + 3, cmd.getPercents255()); case CH_RGBW:
break; analogWrite(getChannelAddr(3), st.param.w);
case CH_RGB:
analogWrite(iaddr, st.param.r);
analogWrite(getChannelAddr(1), st.param.g);
analogWrite(getChannelAddr(2), st.param.b);
break;
default: ;
}
default: ;
}
return 1; return 1;
} }

View File

@@ -7,7 +7,7 @@
#include <item.h> #include <item.h>
#include "colorchannel.h" #include "colorchannel.h"
class out_dmx : public colorChannel { class out_pwm : public colorChannel {
public: public:
out_pwm(Item * _item):colorChannel(_item){}; out_pwm(Item * _item):colorChannel(_item){};
@@ -18,9 +18,9 @@ public:
int isActive() override; int isActive() override;
int getChanType() override; int getChanType() override;
//int Ctrl(itemCmd cmd, char* subItem=NULL) override; //int Ctrl(itemCmd cmd, char* subItem=NULL) override;
//int PixelCtrl(itemCmd cmd) override;
int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true ) override; int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true ) override;
protected: protected:
short numChannels;
}; };
#endif #endif

View File

@@ -109,7 +109,7 @@ int out_SPILed::getChanType()
return CH_RGBW; return CH_RGBW;
} }
int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show ); int out_SPILed::PixelCtrl(itemCmd cmd, char* subItem, bool show )
//int out_SPILed::PixelCtrl(itemCmd cmd, int from, int to, bool show) //int out_SPILed::PixelCtrl(itemCmd cmd, int from, int to, bool show)
{ {
@@ -123,7 +123,7 @@ int from=0, to=numLeds-1; //All LEDs on the strip by default
debugSerial<<from<<F("-")<<to<<F(" cmd=")<<cmd.getCmd()<<endl; debugSerial<<from<<F("-")<<to<<F(" cmd=")<<cmd.getCmd()<<endl;
itemCmd st(ST_RGB); itemCmd st(ST_RGB,CMD_VOID);
#ifdef ADAFRUIT_LED #ifdef ADAFRUIT_LED
uint32_t pixel; uint32_t pixel;

View File

@@ -12,7 +12,7 @@
#include "FastLED.h" #include "FastLED.h"
#endif #endif
class out_SPILed : public abstractOut { class out_SPILed : public colorChannel {
public: public:
out_SPILed(Item * _item):colorChannel(_item){getConfig();}; out_SPILed(Item * _item):colorChannel(_item){getConfig();};