mirror of
https://github.com/anklimov/lighthub
synced 2025-12-07 04:09:49 +03:00
generic output channel and first example on SPI LED
This commit is contained in:
@@ -8,21 +8,21 @@
|
||||
extern lan_status lanStatus;
|
||||
extern PubSubClient mqttClient;
|
||||
|
||||
int abstractCh::publish(char* topic, long value, char* subtopic)
|
||||
int abstractCh::publishTopic(char* topic, long value, char* subtopic)
|
||||
{
|
||||
char valstr[16];
|
||||
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];
|
||||
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];
|
||||
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
class abstractCh {
|
||||
public:
|
||||
abstractCh(){};
|
||||
// virtual int Setup(int addr) = 0;
|
||||
virtual ~abstractCh(){};
|
||||
virtual int Poll() = 0;
|
||||
virtual int Setup() =0;
|
||||
virtual int Anounce () {};
|
||||
|
||||
protected:
|
||||
// Input * in;
|
||||
int publish(char* topic, long value, char* subtopic = NULL);
|
||||
int publish(char* topic, float value, char* subtopic = NULL );
|
||||
int publish(char* topic, char * value, char* subtopic = NULL);
|
||||
virtual int publishTopic(char* topic, long value, char* subtopic = NULL);
|
||||
virtual int publishTopic(char* topic, float value, char* subtopic = NULL );
|
||||
virtual int publishTopic(char* topic, char * value, char* subtopic = NULL);
|
||||
//friend Input;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
#include "abstractin.h"
|
||||
#include "abstractch.h"
|
||||
#include <PubSubClient.h>
|
||||
#include "utils.h"
|
||||
#include <aJSON.h>
|
||||
@@ -31,7 +32,7 @@ int abstractIn::publish(char * value, char* subtopic)
|
||||
aJsonObject *emit = aJson.getObjectItem(in->inputObj, "emit");
|
||||
if (emit)
|
||||
{
|
||||
return publish(emit->valuestring,value,subtopic);
|
||||
return publishTopic(emit->valuestring,value,subtopic);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -6,8 +6,6 @@ class Input;
|
||||
class abstractIn : public abstractCh{
|
||||
public:
|
||||
abstractIn(Input * _in):abstractCh(){in=_in;};
|
||||
virtual int Setup(int addr) = 0;
|
||||
virtual int Poll() = 0;
|
||||
|
||||
protected:
|
||||
Input * in;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
#include "Arduino.h"
|
||||
#include "abstractch.h"
|
||||
|
||||
|
||||
class Item;
|
||||
class abstractOut : public abstractCh{
|
||||
public:
|
||||
abstractOut(Input * _in):abstractCh(){in=_in;};
|
||||
virtual int Setup(int addr) = 0;
|
||||
virtual int Poll() = 0;
|
||||
abstractOut(Item * _item):abstractCh(){item=_item;};
|
||||
virtual int Ctrl(short cmd, short n=0, int * Parameters=NULL, boolean send=true, int suffixCode=0, char* subItem=NULL) =0;
|
||||
protected:
|
||||
|
||||
Item * item;
|
||||
};
|
||||
|
||||
@@ -118,12 +118,12 @@ if (!isValid() || (!root)) return;
|
||||
if (inType == IN_CCS811)
|
||||
{
|
||||
in_ccs811 ccs811(this);
|
||||
ccs811.Setup(pin);
|
||||
ccs811.Setup();
|
||||
}
|
||||
else if (inType == IN_HDC1080)
|
||||
{
|
||||
in_hdc1080 hdc1080(this);
|
||||
hdc1080.Setup(pin);
|
||||
hdc1080.Setup();
|
||||
}
|
||||
// TODO rest types setup
|
||||
#endif
|
||||
|
||||
@@ -33,6 +33,8 @@ e-mail anklimov@gmail.com
|
||||
#endif
|
||||
#include <PubSubClient.h>
|
||||
|
||||
#include "modules/out_spiled.h"
|
||||
|
||||
const char ON_P[] PROGMEM = "ON";
|
||||
const char OFF_P[] PROGMEM = "OFF";
|
||||
const char REST_P[] PROGMEM = "REST";
|
||||
@@ -95,8 +97,8 @@ int txt2cmd(char *payload) {
|
||||
|
||||
|
||||
int txt2subItem(char *payload) {
|
||||
int cmd = -1;
|
||||
if (!payload || !strlen(payload)) return 0;
|
||||
int cmd = S_NOTFOUND;
|
||||
if (!payload || !strlen(payload)) return S_NOTFOUND;
|
||||
// Check for command
|
||||
if (strcmp_P(payload, SET_P) == 0) cmd = S_SET;
|
||||
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
|
||||
{
|
||||
itemArr = obj;
|
||||
driver = NULL;
|
||||
Parse();
|
||||
}
|
||||
|
||||
@@ -127,18 +130,32 @@ void Item::Parse() {
|
||||
itemType = aJson.getArrayItem(itemArr, I_TYPE)->valueint;
|
||||
itemArg = aJson.getArrayItem(itemArr, I_ARG);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
Item::~Item()
|
||||
{
|
||||
if (driver) delete driver;
|
||||
}
|
||||
|
||||
Item::Item(char *name) //Constructor
|
||||
{
|
||||
driver = NULL;
|
||||
if (name && items)
|
||||
itemArr = aJson.getObjectItem(items, name);
|
||||
else itemArr = NULL;
|
||||
Parse();
|
||||
}
|
||||
|
||||
|
||||
uint8_t Item::getCmd(bool ext) {
|
||||
aJsonObject *t = aJson.getArrayItem(itemArr, I_CMD);
|
||||
if (t)
|
||||
@@ -240,34 +257,50 @@ boolean Item::getEnableCMD(int delta) {
|
||||
|
||||
#define MAXCTRLPAR 3
|
||||
|
||||
|
||||
// myhome/dev/item/subItem
|
||||
int Item::Ctrl(char * payload, boolean send, char * subItem){
|
||||
if (!payload) return 0;
|
||||
|
||||
char* subsubItem = NULL;
|
||||
int subItemN = 0;
|
||||
int subsubItemN = 0;
|
||||
char* suffix = NULL;
|
||||
//int subItemN = 0;
|
||||
int suffixCode = 0;
|
||||
bool isSet = false;
|
||||
|
||||
if (subItem && strlen(subItem))
|
||||
{
|
||||
if (subsubItem = strchr(subItem, '/'))
|
||||
if (suffix = strrchr(subItem, '/')) //Trying to retrieving right part
|
||||
{
|
||||
*subsubItem = 0;
|
||||
subsubItem++;
|
||||
subsubItemN = txt2subItem(subsubItem);
|
||||
*suffix= 0; //Truncate subItem string
|
||||
suffix++;
|
||||
suffixCode = txt2subItem(suffix);
|
||||
// myhome/dev/item/sub.....Item/suffix
|
||||
}
|
||||
subItemN = txt2subItem(subItem);
|
||||
if (subItemN==S_SET || subsubItemN==S_SET) isSet = true;
|
||||
} else isSet = true; /// To be removed - old compatmode
|
||||
else
|
||||
{
|
||||
suffix = subItem;
|
||||
suffixCode = txt2subItem(suffix);
|
||||
if (suffixCode)
|
||||
subItem = NULL;
|
||||
// myhome/dev/item/suffix
|
||||
|
||||
if (isSet)
|
||||
{
|
||||
int cmd = txt2cmd(payload);
|
||||
debugSerial<<F("Txt2Cmd:")<<cmd<<endl;
|
||||
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);
|
||||
debugSerial<<F("Txt2Cmd:")<<cmd<<endl;
|
||||
|
||||
//if (isSet)
|
||||
//{
|
||||
switch (cmd) {
|
||||
case CMD_NUM:
|
||||
case CMD_HSV:
|
||||
suffixCode=S_HSV; //override code for known payload
|
||||
case CMD_NUM:
|
||||
{
|
||||
short i = 0;
|
||||
int Par[3];
|
||||
@@ -275,7 +308,7 @@ if (isSet)
|
||||
while (payload && i < 3)
|
||||
Par[i++] = getInt((char **) &payload);
|
||||
|
||||
return Ctrl(0, i, Par, send, subItemN);
|
||||
return Ctrl(0, i, Par, send, suffixCode, subItem);
|
||||
}
|
||||
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)
|
||||
case -3: //RGB color in #RRGGBB notation
|
||||
{
|
||||
suffixCode=S_HSV; //override code for known payload
|
||||
CRGB rgb;
|
||||
if (sscanf((const char*)payload, "#%2X%2X%2X", &rgb.r, &rgb.g, &rgb.b) == 3) {
|
||||
int Par[3];
|
||||
@@ -292,7 +326,7 @@ if (isSet)
|
||||
Par[0] = map(hsv.h, 0, 255, 0, 365);
|
||||
Par[1] = map(hsv.s, 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;
|
||||
}
|
||||
@@ -301,21 +335,21 @@ if (isSet)
|
||||
|
||||
// if (item.getEnableCMD(500) || lanStatus == 4)
|
||||
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"));
|
||||
|
||||
break;
|
||||
default: //some known command
|
||||
return Ctrl(cmd, 0, NULL, send, subItemN);
|
||||
return Ctrl(cmd, 0, NULL, send, suffixCode, subItem);
|
||||
|
||||
} //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;
|
||||
int Par[MAXCTRLPAR] = {0, 0, 0};
|
||||
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<<endl;
|
||||
|
||||
if (driver) return driver->Ctrl(cmd, n, Parameters, send, suffixCode, subItem);
|
||||
|
||||
int iaddr = getArg();
|
||||
HSVstore st;
|
||||
switch (cmd) {
|
||||
@@ -653,7 +690,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int subItemN)
|
||||
while (i) {
|
||||
Item it(i->valuestring);
|
||||
// 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;
|
||||
} //while
|
||||
} //if
|
||||
|
||||
@@ -18,7 +18,9 @@ e-mail anklimov@gmail.com
|
||||
|
||||
*/
|
||||
#include "options.h"
|
||||
#include "abstractout.h"
|
||||
|
||||
#define S_NOTFOUND 0
|
||||
#define S_SET 1
|
||||
#define S_TEMP 2
|
||||
#define S_MODE 3
|
||||
@@ -41,6 +43,7 @@ e-mail anklimov@gmail.com
|
||||
#define CH_VCTEMP 8 //Vacom PID regulator
|
||||
#define CH_VC 9 //Vacom modbus motor regulator
|
||||
#define CH_AC_HAIER 10 //AC Haier
|
||||
#define CH_SPILED 11
|
||||
#define CH_WHITE 127//
|
||||
|
||||
#define CMD_NUM 0
|
||||
@@ -118,12 +121,15 @@ class Item
|
||||
public:
|
||||
aJsonObject *itemArr, *itemArg,*itemVal;
|
||||
uint8_t itemType;
|
||||
abstractOut * driver;
|
||||
|
||||
|
||||
Item(char * name);
|
||||
Item(aJsonObject * obj);
|
||||
~Item();
|
||||
|
||||
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);
|
||||
|
||||
int getArg(short n=0);
|
||||
|
||||
@@ -17,7 +17,7 @@ static bool HDC1080ready = 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;}
|
||||
|
||||
@@ -52,7 +52,7 @@ delay(2000); */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int in_hdc1080::Setup(int addr)
|
||||
int in_hdc1080::Setup()
|
||||
{
|
||||
if (HDC1080ready) {debugSerial<<F("hdc1080 is already initialized")<<endl; return 0;}
|
||||
Serial.println("HDC1080 Init ");
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
//CCS811 ccs811(CCS811_ADDR);
|
||||
//uint16_t ccs811Baseline;
|
||||
in_ccs811(Input * _in):abstractIn(_in){};
|
||||
int Setup(int addr) override;
|
||||
int Setup() override;
|
||||
int Poll() override;
|
||||
|
||||
protected:
|
||||
@@ -52,7 +52,7 @@ class in_hdc1080 : public abstractIn {
|
||||
public:
|
||||
//ClosedCube_HDC1080 hdc1080;
|
||||
in_hdc1080(Input * _in):abstractIn(_in){};
|
||||
int Setup(int addr) override;
|
||||
int Setup() override;
|
||||
int Poll() override;
|
||||
|
||||
protected:
|
||||
|
||||
69
lighthub/modules/out_spiled.cpp
Normal file
69
lighthub/modules/out_spiled.cpp
Normal 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
|
||||
16
lighthub/modules/out_spiled.h
Normal file
16
lighthub/modules/out_spiled.h
Normal 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
|
||||
Reference in New Issue
Block a user