generic output channel and first example on SPI LED

This commit is contained in:
2019-07-19 01:11:48 +03:00
parent 5c4b1512bb
commit a24e56e941
12 changed files with 179 additions and 51 deletions

View File

@@ -8,21 +8,21 @@
extern lan_status lanStatus; extern lan_status lanStatus;
extern PubSubClient mqttClient; extern PubSubClient mqttClient;
int abstractCh::publish(char* topic, long value, char* subtopic) int abstractCh::publishTopic(char* topic, long value, char* subtopic)
{ {
char valstr[16]; char valstr[16];
printUlongValueToStr(valstr, value); printUlongValueToStr(valstr, value);
return publish(topic, valstr,subtopic); return publishTopic(topic, valstr,subtopic);
}; };
int abstractCh::publish(char* topic, float value, char* subtopic) int abstractCh::publishTopic(char* topic, float value, char* subtopic)
{ {
char valstr[16]; char valstr[16];
printFloatValueToStr(value, valstr); printFloatValueToStr(value, valstr);
return publish(topic, valstr,subtopic); return publishTopic(topic, valstr,subtopic);
}; };
int abstractCh::publish(char* topic, char * value, char* subtopic) int abstractCh::publishTopic(char* topic, char * value, char* subtopic)
{ {
char addrstr[MQTT_TOPIC_LENGTH]; char addrstr[MQTT_TOPIC_LENGTH];

View File

@@ -4,13 +4,14 @@
class abstractCh { class abstractCh {
public: public:
abstractCh(){}; abstractCh(){};
// virtual int Setup(int addr) = 0; virtual ~abstractCh(){};
virtual int Poll() = 0; virtual int Poll() = 0;
virtual int Setup() =0;
virtual int Anounce () {};
protected: protected:
// Input * in; virtual int publishTopic(char* topic, long value, char* subtopic = NULL);
int publish(char* topic, long value, char* subtopic = NULL); virtual int publishTopic(char* topic, float value, char* subtopic = NULL );
int publish(char* topic, float value, char* subtopic = NULL ); virtual int publishTopic(char* topic, char * value, char* subtopic = NULL);
int publish(char* topic, char * value, char* subtopic = NULL);
//friend Input; //friend Input;
}; };

View File

@@ -1,5 +1,6 @@
#include "abstractin.h" #include "abstractin.h"
#include "abstractch.h"
#include <PubSubClient.h> #include <PubSubClient.h>
#include "utils.h" #include "utils.h"
#include <aJSON.h> #include <aJSON.h>
@@ -31,7 +32,7 @@ int abstractIn::publish(char * value, char* subtopic)
aJsonObject *emit = aJson.getObjectItem(in->inputObj, "emit"); aJsonObject *emit = aJson.getObjectItem(in->inputObj, "emit");
if (emit) if (emit)
{ {
return publish(emit->valuestring,value,subtopic); return publishTopic(emit->valuestring,value,subtopic);
} }
} }
return 0; return 0;

View File

@@ -6,8 +6,6 @@ class Input;
class abstractIn : public abstractCh{ class abstractIn : public abstractCh{
public: public:
abstractIn(Input * _in):abstractCh(){in=_in;}; abstractIn(Input * _in):abstractCh(){in=_in;};
virtual int Setup(int addr) = 0;
virtual int Poll() = 0;
protected: protected:
Input * in; Input * in;

View File

@@ -1,12 +1,12 @@
#pragma once #pragma once
#include "Arduino.h" #include "Arduino.h"
#include "abstractch.h"
class Item;
class abstractOut : public abstractCh{ class abstractOut : public abstractCh{
public: public:
abstractOut(Input * _in):abstractCh(){in=_in;}; abstractOut(Item * _item):abstractCh(){item=_item;};
virtual int Setup(int addr) = 0; virtual int Ctrl(short cmd, short n=0, int * Parameters=NULL, boolean send=true, int suffixCode=0, char* subItem=NULL) =0;
virtual int Poll() = 0;
protected: protected:
Item * item;
}; };

View File

@@ -118,12 +118,12 @@ if (!isValid() || (!root)) return;
if (inType == IN_CCS811) if (inType == IN_CCS811)
{ {
in_ccs811 ccs811(this); in_ccs811 ccs811(this);
ccs811.Setup(pin); ccs811.Setup();
} }
else if (inType == IN_HDC1080) else if (inType == IN_HDC1080)
{ {
in_hdc1080 hdc1080(this); in_hdc1080 hdc1080(this);
hdc1080.Setup(pin); hdc1080.Setup();
} }
// TODO rest types setup // TODO rest types setup
#endif #endif

View File

@@ -33,6 +33,8 @@ e-mail anklimov@gmail.com
#endif #endif
#include <PubSubClient.h> #include <PubSubClient.h>
#include "modules/out_spiled.h"
const char ON_P[] PROGMEM = "ON"; const char ON_P[] PROGMEM = "ON";
const char OFF_P[] PROGMEM = "OFF"; const char OFF_P[] PROGMEM = "OFF";
const char REST_P[] PROGMEM = "REST"; const char REST_P[] PROGMEM = "REST";
@@ -95,8 +97,8 @@ int txt2cmd(char *payload) {
int txt2subItem(char *payload) { int txt2subItem(char *payload) {
int cmd = -1; int cmd = S_NOTFOUND;
if (!payload || !strlen(payload)) return 0; if (!payload || !strlen(payload)) return S_NOTFOUND;
// Check for command // Check for command
if (strcmp_P(payload, SET_P) == 0) cmd = S_SET; if (strcmp_P(payload, SET_P) == 0) cmd = S_SET;
else if (strcmp_P(payload, TEMP_P) == 0) cmd = S_TEMP; else if (strcmp_P(payload, TEMP_P) == 0) cmd = S_TEMP;
@@ -115,6 +117,7 @@ const short defval[4] = {0, 0, 0, 0}; //Type,Arg,Val,Cmd
Item::Item(aJsonObject *obj)//Constructor Item::Item(aJsonObject *obj)//Constructor
{ {
itemArr = obj; itemArr = obj;
driver = NULL;
Parse(); Parse();
} }
@@ -127,18 +130,32 @@ void Item::Parse() {
itemType = aJson.getArrayItem(itemArr, I_TYPE)->valueint; itemType = aJson.getArrayItem(itemArr, I_TYPE)->valueint;
itemArg = aJson.getArrayItem(itemArr, I_ARG); itemArg = aJson.getArrayItem(itemArr, I_ARG);
itemVal = aJson.getArrayItem(itemArr, I_VAL); itemVal = aJson.getArrayItem(itemArr, I_VAL);
switch (itemType)
{
case CH_SPILED:
driver = new out_SPILed (this);
break;
}
// debugSerial << F(" Item:") << itemArr->name << F(" T:") << itemType << F(" =") << getArg() << endl; // debugSerial << F(" Item:") << itemArr->name << F(" T:") << itemType << F(" =") << getArg() << endl;
} }
} }
Item::~Item()
{
if (driver) delete driver;
}
Item::Item(char *name) //Constructor Item::Item(char *name) //Constructor
{ {
driver = NULL;
if (name && items) if (name && items)
itemArr = aJson.getObjectItem(items, name); itemArr = aJson.getObjectItem(items, name);
else itemArr = NULL; else itemArr = NULL;
Parse(); Parse();
} }
uint8_t Item::getCmd(bool ext) { uint8_t Item::getCmd(bool ext) {
aJsonObject *t = aJson.getArrayItem(itemArr, I_CMD); aJsonObject *t = aJson.getArrayItem(itemArr, I_CMD);
if (t) if (t)
@@ -240,34 +257,50 @@ boolean Item::getEnableCMD(int delta) {
#define MAXCTRLPAR 3 #define MAXCTRLPAR 3
// myhome/dev/item/subItem
int Item::Ctrl(char * payload, boolean send, char * subItem){ int Item::Ctrl(char * payload, boolean send, char * subItem){
if (!payload) return 0; if (!payload) return 0;
char* subsubItem = NULL; char* suffix = NULL;
int subItemN = 0; //int subItemN = 0;
int subsubItemN = 0; int suffixCode = 0;
bool isSet = false; bool isSet = false;
if (subItem && strlen(subItem)) if (subItem && strlen(subItem))
{ {
if (subsubItem = strchr(subItem, '/')) if (suffix = strrchr(subItem, '/')) //Trying to retrieving right part
{ {
*subsubItem = 0; *suffix= 0; //Truncate subItem string
subsubItem++; suffix++;
subsubItemN = txt2subItem(subsubItem); suffixCode = txt2subItem(suffix);
// myhome/dev/item/sub.....Item/suffix
} }
subItemN = txt2subItem(subItem); else
if (subItemN==S_SET || subsubItemN==S_SET) isSet = true;
} else isSet = true; /// To be removed - old compatmode
if (isSet)
{ {
suffix = subItem;
suffixCode = txt2subItem(suffix);
if (suffixCode)
subItem = NULL;
// myhome/dev/item/suffix
else //Invalid suffix - fallback to Subitem notation
suffix = NULL;
// myhome/dev/item/subItem
}
//if (suffixCode==S_SET) isSet = true;
} else suffixCode=S_SET; /// no subItem - To be removed - old compatmode
int cmd = txt2cmd(payload); int cmd = txt2cmd(payload);
debugSerial<<F("Txt2Cmd:")<<cmd<<endl; debugSerial<<F("Txt2Cmd:")<<cmd<<endl;
//if (isSet)
//{
switch (cmd) { switch (cmd) {
case CMD_NUM:
case CMD_HSV: case CMD_HSV:
suffixCode=S_HSV; //override code for known payload
case CMD_NUM:
{ {
short i = 0; short i = 0;
int Par[3]; int Par[3];
@@ -275,7 +308,7 @@ if (isSet)
while (payload && i < 3) while (payload && i < 3)
Par[i++] = getInt((char **) &payload); Par[i++] = getInt((char **) &payload);
return Ctrl(0, i, Par, send, subItemN); return Ctrl(0, i, Par, send, suffixCode, subItem);
} }
break; break;
@@ -285,6 +318,7 @@ if (isSet)
#if not defined(ARDUINO_ARCH_ESP32) and not defined(ESP8266) and not defined(ARDUINO_ARCH_STM32) and not defined(DMX_DISABLE) #if not defined(ARDUINO_ARCH_ESP32) and not defined(ESP8266) and not defined(ARDUINO_ARCH_STM32) and not defined(DMX_DISABLE)
case -3: //RGB color in #RRGGBB notation case -3: //RGB color in #RRGGBB notation
{ {
suffixCode=S_HSV; //override code for known payload
CRGB rgb; CRGB rgb;
if (sscanf((const char*)payload, "#%2X%2X%2X", &rgb.r, &rgb.g, &rgb.b) == 3) { if (sscanf((const char*)payload, "#%2X%2X%2X", &rgb.r, &rgb.g, &rgb.b) == 3) {
int Par[3]; int Par[3];
@@ -292,7 +326,7 @@ if (isSet)
Par[0] = map(hsv.h, 0, 255, 0, 365); Par[0] = map(hsv.h, 0, 255, 0, 365);
Par[1] = map(hsv.s, 0, 255, 0, 100); Par[1] = map(hsv.s, 0, 255, 0, 100);
Par[2] = map(hsv.v, 0, 255, 0, 100); Par[2] = map(hsv.v, 0, 255, 0, 100);
return Ctrl(0, 3, Par, send, subItemN); return Ctrl(0, 3, Par, send, suffixCode, subItem);
} }
break; break;
} }
@@ -301,21 +335,21 @@ if (isSet)
// if (item.getEnableCMD(500) || lanStatus == 4) // if (item.getEnableCMD(500) || lanStatus == 4)
return Ctrl(cmd, 0, NULL, return Ctrl(cmd, 0, NULL,
send, subItemN); //Accept ON command not earlier then 500 ms after set settings (Homekit hack) send, suffixCode, subItem); //Accept ON command not earlier then 500 ms after set settings (Homekit hack)
// else debugSerial<<F("on Skipped")); // else debugSerial<<F("on Skipped"));
break; break;
default: //some known command default: //some known command
return Ctrl(cmd, 0, NULL, send, subItemN); return Ctrl(cmd, 0, NULL, send, suffixCode, subItem);
} //ctrl } //ctrl
} //}
} }
int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int subItemN) { int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode, char *subItem) {
debugSerial<<F("RAM=")<<freeRam()<<F(" Item=")<<itemArr->name<<F(" Sub=")<<subItemN<<F(" Cmd=")<<cmd<<F(" Par= "); debugSerial<<F("RAM=")<<freeRam()<<F(" Item=")<<itemArr->name<<F(" Sub=")<<subItem<<F(" Suff=")<<suffixCode<<F(" Cmd=")<<cmd<<F(" Par= ");
if (!itemArr) return -1; if (!itemArr) return -1;
int Par[MAXCTRLPAR] = {0, 0, 0}; int Par[MAXCTRLPAR] = {0, 0, 0};
if (Parameters) if (Parameters)
@@ -324,6 +358,9 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int subItemN)
debugSerial<<F("<")<<Par[i]<<F("> "); debugSerial<<F("<")<<Par[i]<<F("> ");
} }
debugSerial<<endl; debugSerial<<endl;
if (driver) return driver->Ctrl(cmd, n, Parameters, send, suffixCode, subItem);
int iaddr = getArg(); int iaddr = getArg();
HSVstore st; HSVstore st;
switch (cmd) { switch (cmd) {
@@ -653,7 +690,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int subItemN)
while (i) { while (i) {
Item it(i->valuestring); Item it(i->valuestring);
// it.copyPar(itemVal); // it.copyPar(itemVal);
it.Ctrl(cmd, n, Par, send,subItemN); //// was true it.Ctrl(cmd, n, Par, send,suffixCode,subItem); //// was true
i = i->next; i = i->next;
} //while } //while
} //if } //if

View File

@@ -18,7 +18,9 @@ e-mail anklimov@gmail.com
*/ */
#include "options.h" #include "options.h"
#include "abstractout.h"
#define S_NOTFOUND 0
#define S_SET 1 #define S_SET 1
#define S_TEMP 2 #define S_TEMP 2
#define S_MODE 3 #define S_MODE 3
@@ -41,6 +43,7 @@ e-mail anklimov@gmail.com
#define CH_VCTEMP 8 //Vacom PID regulator #define CH_VCTEMP 8 //Vacom PID regulator
#define CH_VC 9 //Vacom modbus motor regulator #define CH_VC 9 //Vacom modbus motor regulator
#define CH_AC_HAIER 10 //AC Haier #define CH_AC_HAIER 10 //AC Haier
#define CH_SPILED 11
#define CH_WHITE 127// #define CH_WHITE 127//
#define CMD_NUM 0 #define CMD_NUM 0
@@ -118,12 +121,15 @@ class Item
public: public:
aJsonObject *itemArr, *itemArg,*itemVal; aJsonObject *itemArr, *itemArg,*itemVal;
uint8_t itemType; uint8_t itemType;
abstractOut * driver;
Item(char * name); Item(char * name);
Item(aJsonObject * obj); Item(aJsonObject * obj);
~Item();
boolean isValid (); boolean isValid ();
virtual int Ctrl(short cmd, short n=0, int * Parameters=NULL, boolean send=true, int subItem=0); virtual int Ctrl(short cmd, short n=0, int * Parameters=NULL, boolean send=true, int suffixCode=0, char* subItem=NULL);
virtual int Ctrl(char * payload, boolean send=true, char * subItem=NULL); virtual int Ctrl(char * payload, boolean send=true, char * subItem=NULL);
int getArg(short n=0); int getArg(short n=0);

View File

@@ -17,7 +17,7 @@ static bool HDC1080ready = false;
static bool CCS811ready = false; static bool CCS811ready = false;
int in_ccs811::Setup(int addr) int in_ccs811::Setup()
{ {
if (CCS811ready) {debugSerial<<F("ccs811 is already initialized")<<endl; return 0;} if (CCS811ready) {debugSerial<<F("ccs811 is already initialized")<<endl; return 0;}
@@ -52,7 +52,7 @@ delay(2000); */
return 1; return 1;
} }
int in_hdc1080::Setup(int addr) int in_hdc1080::Setup()
{ {
if (HDC1080ready) {debugSerial<<F("hdc1080 is already initialized")<<endl; return 0;} if (HDC1080ready) {debugSerial<<F("hdc1080 is already initialized")<<endl; return 0;}
Serial.println("HDC1080 Init "); Serial.println("HDC1080 Init ");

View File

@@ -40,7 +40,7 @@ public:
//CCS811 ccs811(CCS811_ADDR); //CCS811 ccs811(CCS811_ADDR);
//uint16_t ccs811Baseline; //uint16_t ccs811Baseline;
in_ccs811(Input * _in):abstractIn(_in){}; in_ccs811(Input * _in):abstractIn(_in){};
int Setup(int addr) override; int Setup() override;
int Poll() override; int Poll() override;
protected: protected:
@@ -52,7 +52,7 @@ class in_hdc1080 : public abstractIn {
public: public:
//ClosedCube_HDC1080 hdc1080; //ClosedCube_HDC1080 hdc1080;
in_hdc1080(Input * _in):abstractIn(_in){}; in_hdc1080(Input * _in):abstractIn(_in){};
int Setup(int addr) override; int Setup() override;
int Poll() override; int Poll() override;
protected: protected:

View File

@@ -0,0 +1,69 @@
#ifndef SPILED_DISABLE
#include "modules/out_spiled.h"
#include "Arduino.h"
#include "options.h"
#include "Streaming.h"
#include "FastLED.h"
#define NUM_LEDS 60
#define DATA_PIN 11
CRGB leds[NUM_LEDS];
int out_SPILed::Setup()
{
Serial.println("SPI-LED Init");
FastLED.addLeds<TM1809, DATA_PIN, BRG>(leds, NUM_LEDS);
return 1;
}
int out_SPILed::Poll()
{
FastLED.show();
return 1;
};
int out_SPILed::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixCode, char* subItem)
{
int from=0, to=NUM_LEDS-1;
if (subItem)
{ //Just single LED to control
from=atoi(subItem);
to=from;
}
for (n=from;n<=to;n++)
{
switch(cmd)
{
CMD_ON:
leds[n] = CRGB::White;
break;
CMD_OFF:
leds[n] = CRGB::Black;
break;
CMD_NUM:
switch (suffixCode)
{
S_POWER:
S_VOL:
//leds[n].setBrightness(Parameters[0]);
break;
S_SET:
S_HSV:
leds[n] = CHSV(Parameters[0],Parameters[1],Parameters[2]);
break;
S_RGB:
leds[n] = CRGB(Parameters[0],Parameters[1],Parameters[2]);
break;
}
}
}
FastLED.show();
return 1;
}
#endif

View File

@@ -0,0 +1,16 @@
#pragma once
#ifndef SPILED_DISABLE
#include <abstractout.h>
class out_SPILed : public abstractOut {
public:
out_SPILed(Item * _item):abstractOut(_item){};
int Setup() override;
int Poll() override;
virtual int Ctrl(short cmd, short n=0, int * Parameters=NULL, boolean send=true, int suffixCode=0, char* subItem=NULL) override;
protected:
};
#endif