mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
Driver refactoring & core fixes
CAN fixes and extension stm32 timer
This commit is contained in:
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
-DENABLE_HWSERIAL1
|
-DENABLE_HWSERIAL1
|
||||||
-DdebugSerialPort=Serial1
|
-DdebugSerialPort=Serial1
|
||||||
|
-D TIMER_INT
|
||||||
|
|
||||||
|
|
||||||
#-DFLASH_BASE_ADDRESS
|
#-DFLASH_BASE_ADDRESS
|
||||||
#-DFLASH_DATA_SECTOR
|
#-DFLASH_DATA_SECTOR
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
-D THERMOSTAT_CHECK_PERIOD=5000
|
-D THERMOSTAT_CHECK_PERIOD=5000
|
||||||
-D ULTRASONIC
|
-D ULTRASONIC
|
||||||
|
|
||||||
|
-D TIMER_INT
|
||||||
-DENABLE_HWSERIAL1
|
-DENABLE_HWSERIAL1
|
||||||
-DdebugSerialPort=Serial1
|
-DdebugSerialPort=Serial1
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int publishTopic(const char* topic, long value, const char* subtopic = NULL);
|
int publishTopic(const char* topic, long value, const char* subtopic = NULL);
|
||||||
virtual int publishTopic(const char* topic, float value, const char* subtopic = NULL );
|
int publishTopic(const char* topic, float value, const char* subtopic = NULL );
|
||||||
virtual int publishTopic(const char* topic, const char * value, const char* subtopic = NULL);
|
int publishTopic(const char* topic, const char * value, const char* subtopic = NULL);
|
||||||
//friend Input;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "abstractout.h"
|
#include "abstractout.h"
|
||||||
#include "itemCmd.h"
|
#include "itemCmd.h"
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ class Item;
|
|||||||
class chPersistent {};
|
class chPersistent {};
|
||||||
class abstractOut : public abstractCh{
|
class abstractOut : public abstractCh{
|
||||||
public:
|
public:
|
||||||
abstractOut(Item * _item):abstractCh(){item=_item;};
|
//abstractOut(Item * _item):abstractCh(){item=_item;};
|
||||||
|
abstractOut():item(NULL){};
|
||||||
|
virtual void link(Item * _item){item=_item;};
|
||||||
virtual int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) =0;
|
virtual int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) =0;
|
||||||
virtual int isActive();
|
virtual int isActive();
|
||||||
virtual bool isAllowed(itemCmd cmd){return true;};
|
virtual bool isAllowed(itemCmd cmd){return true;};
|
||||||
@@ -17,8 +19,10 @@ public:
|
|||||||
virtual int Status() override;
|
virtual int Status() override;
|
||||||
virtual void setStatus(uint8_t status) override;
|
virtual void setStatus(uint8_t status) override;
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
|
Item * getItem() {return item;}
|
||||||
protected:
|
protected:
|
||||||
int pubAction(bool state);
|
int pubAction(bool state);
|
||||||
|
|
||||||
Item * item;
|
Item * item;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -522,8 +522,8 @@ else //Requests
|
|||||||
if ((id.payloadType == payloadType::itemCommand) && (len ==8))
|
if ((id.payloadType == payloadType::itemCommand) && (len ==8))
|
||||||
{
|
{
|
||||||
Item it(id.itemId,id.subItemId);
|
Item it(id.itemId,id.subItemId);
|
||||||
if (it.isValid())
|
if (!it.isValid()) return false;
|
||||||
{
|
|
||||||
itemCmd ic;
|
itemCmd ic;
|
||||||
ic.cmd = packet->cmd;
|
ic.cmd = packet->cmd;
|
||||||
ic.param = packet->param;
|
ic.param = packet->param;
|
||||||
@@ -531,8 +531,6 @@ else //Requests
|
|||||||
//ic.debugOut();
|
//ic.debugOut();
|
||||||
return it.Ctrl(ic,it.getSubItemStrById(id.subItemId));
|
return it.Ctrl(ic,it.getSubItemStrById(id.subItemId));
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if ((id.payloadType == payloadType::lookupMAC) && (len>=6))
|
else if ((id.payloadType == payloadType::lookupMAC) && (len>=6))
|
||||||
{
|
{
|
||||||
return sendRemoteID(packet->mac);
|
return sendRemoteID(packet->mac);
|
||||||
@@ -749,7 +747,17 @@ bool canDriver::sendCommand(aJsonObject * can, itemCmd cmd, bool status)
|
|||||||
int suffix=txt2subItem(sfx->valuestring);
|
int suffix=txt2subItem(sfx->valuestring);
|
||||||
if (suffix) cmd.setSuffix(suffix);
|
if (suffix) cmd.setSuffix(suffix);
|
||||||
}
|
}
|
||||||
if (subItemObj && subItemObj->type==aJson_Int && subItemObj->valueint>=0 && subItemObj->valueint<63) subItem=subItemObj->valueint;
|
|
||||||
|
if (subItemObj)
|
||||||
|
switch (subItemObj->type)
|
||||||
|
{
|
||||||
|
case aJson_Int:
|
||||||
|
if (subItemObj->valueint>=0 && subItemObj->valueint<SUBITEM_IS_COMMAND) subItem=subItemObj->valueint;
|
||||||
|
break;
|
||||||
|
case aJson_String:
|
||||||
|
int suffix=txt2cmd(subItemObj->valuestring);
|
||||||
|
if (suffix) subItem = suffix | SUBITEM_IS_COMMAND;
|
||||||
|
}
|
||||||
|
|
||||||
if (dev && it && dev->type == aJson_Int && it->type == aJson_Int)
|
if (dev && it && dev->type == aJson_Int && it->type == aJson_Int)
|
||||||
return sendCommand(dev->valueint, it->valueint, cmd, status,subItem);
|
return sendCommand(dev->valueint, it->valueint, cmd, status,subItem);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#define NO_SUBITEM 63
|
#define NO_SUBITEM 63
|
||||||
|
#define SUBITEM_IS_COMMAND 0x20
|
||||||
#ifdef CANDRV
|
#ifdef CANDRV
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_STM32)
|
#if defined(ARDUINO_ARCH_STM32)
|
||||||
|
|||||||
@@ -9,7 +9,9 @@
|
|||||||
class colorChannel : public abstractOut {
|
class colorChannel : public abstractOut {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
colorChannel(Item * _item):abstractOut(_item) {
|
colorChannel():iaddr(0),numArgs(0) {};
|
||||||
|
void link (Item * _item) {
|
||||||
|
abstractOut::link(_item);
|
||||||
iaddr = item->getArg(); //Once retrieve and store base address
|
iaddr = item->getArg(); //Once retrieve and store base address
|
||||||
if (iaddr<0) iaddr=-iaddr;
|
if (iaddr<0) iaddr=-iaddr;
|
||||||
numArgs = item->getArgCount(); // and how many addresses is configured
|
numArgs = item->getArgCount(); // and how many addresses is configured
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ extern PubSubClient mqttClient;
|
|||||||
extern int8_t ethernetIdleCount;
|
extern int8_t ethernetIdleCount;
|
||||||
extern int8_t configLocked;
|
extern int8_t configLocked;
|
||||||
extern lan_status lanStatus;
|
extern lan_status lanStatus;
|
||||||
|
driverFactory df;
|
||||||
|
|
||||||
int retrieveCode(char **psubItem);
|
int retrieveCode(char **psubItem);
|
||||||
|
|
||||||
@@ -172,7 +173,8 @@ void Item::Parse() {
|
|||||||
if (cmdObj) itemExt = cmdObj->next;
|
if (cmdObj) itemExt = cmdObj->next;
|
||||||
|
|
||||||
itemType = replaceTypeToInt (itemTypeObj);
|
itemType = replaceTypeToInt (itemTypeObj);
|
||||||
|
driver=df.getDriver(this);
|
||||||
|
/*
|
||||||
switch (itemType)
|
switch (itemType)
|
||||||
{
|
{
|
||||||
#ifndef PWM_DISABLE
|
#ifndef PWM_DISABLE
|
||||||
@@ -265,14 +267,13 @@ void Item::Parse() {
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
default: ;
|
default: ;
|
||||||
}
|
} */
|
||||||
// debugSerial << F(" Item:") << itemArr->name << F(" T:") << itemType << F(" =") << getArg() << endl;
|
// debugSerial << F(" Item:") << itemArr->name << F(" T:") << itemType << F(" =") << getArg() << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean Item::Setup()
|
boolean Item::Setup()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (driver)
|
if (driver)
|
||||||
{
|
{
|
||||||
if (driver->Status()) driver->Stop();
|
if (driver->Status()) driver->Stop();
|
||||||
@@ -299,7 +300,7 @@ Item::~Item()
|
|||||||
{
|
{
|
||||||
if (driver)
|
if (driver)
|
||||||
{
|
{
|
||||||
delete driver;
|
df.freeDriver (this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +357,7 @@ uint16_t getCanNum(aJsonObject* verb)
|
|||||||
|
|
||||||
char * Item::getSubItemStrById(uint8_t subItem)
|
char * Item::getSubItemStrById(uint8_t subItem)
|
||||||
{
|
{
|
||||||
if (subItem == NO_SUBITEM) return NULL;
|
if (subItem == NO_SUBITEM || (subItem | SUBITEM_IS_COMMAND)) return NULL;
|
||||||
if (!itemArg) return NULL;
|
if (!itemArg) return NULL;
|
||||||
aJsonObject * i = itemArg;
|
aJsonObject * i = itemArg;
|
||||||
if (i->type == aJson_Array) i=i->child;
|
if (i->type == aJson_Array) i=i->child;
|
||||||
@@ -421,8 +422,16 @@ return NO_SUBITEM;
|
|||||||
{
|
{
|
||||||
debugSerial<<"Find item: "<< itemArr->name << " addr:" << num << endl;
|
debugSerial<<"Find item: "<< itemArr->name << " addr:" << num << endl;
|
||||||
Parse();
|
Parse();
|
||||||
|
if (subItem | SUBITEM_IS_COMMAND)
|
||||||
|
{
|
||||||
|
subItem &=~ SUBITEM_IS_COMMAND;
|
||||||
|
if (subItem<commandsNum) strncpy_P(defaultSubItem, commands_P[subItem], sizeof(defaultSubItem));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
char * subItemStr = getSubItemStrById(subItem);
|
char * subItemStr = getSubItemStrById(subItem);
|
||||||
if (subItemStr) strncpy(defaultSubItem,subItemStr,sizeof(defaultSubItem));
|
if (subItemStr) strncpy(defaultSubItem,subItemStr,sizeof(defaultSubItem));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
itemArr = itemArr->next;
|
itemArr = itemArr->next;
|
||||||
@@ -1091,6 +1100,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
|
|||||||
long status2Send = 0;
|
long status2Send = 0;
|
||||||
uint8_t command2Set = 0;
|
uint8_t command2Set = 0;
|
||||||
itemCmd originalCmd = cmd;
|
itemCmd originalCmd = cmd;
|
||||||
|
int subitemCmd = subitem2cmd(subItem);
|
||||||
|
|
||||||
/// Common (GRP & NO GRP) commands
|
/// Common (GRP & NO GRP) commands
|
||||||
switch (cmd.getCmd())
|
switch (cmd.getCmd())
|
||||||
@@ -1228,6 +1238,13 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
|
|||||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
||||||
cmd.setSuffix(S_SET);
|
cmd.setSuffix(S_SET);
|
||||||
} else {cmd=fallbackCmd;invalidArgument=true; errorSerial << F("Invalid arg")<<endl;}
|
} else {cmd=fallbackCmd;invalidArgument=true; errorSerial << F("Invalid arg")<<endl;}
|
||||||
|
break;
|
||||||
|
case S_TEMP:
|
||||||
|
if (cmd.incrementTemp(step))
|
||||||
|
{
|
||||||
|
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
||||||
|
cmd.setSuffix(S_SET);
|
||||||
|
} else {cmd=fallbackCmd;invalidArgument=true; errorSerial << F("Invalid arg")<<endl;}
|
||||||
} //switch suffix
|
} //switch suffix
|
||||||
|
|
||||||
} //Case UP/DOWN
|
} //Case UP/DOWN
|
||||||
@@ -1273,18 +1290,19 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
|
|||||||
if ((suffixCode!=S_CMD) || (cmd.getCmd() != CMD_XON) || !getFlag(FLAG_DISABLED))
|
if ((suffixCode!=S_CMD) || (cmd.getCmd() != CMD_XON) || !getFlag(FLAG_DISABLED))
|
||||||
{
|
{
|
||||||
digGroup(itemArg,&cmd,subItem,authorized);
|
digGroup(itemArg,&cmd,subItem,authorized);
|
||||||
|
|
||||||
if ((suffixCode==S_CMD) && cmd.isValue())
|
if ((suffixCode==S_CMD) && cmd.isValue())
|
||||||
{
|
{
|
||||||
scheduleOppositeCommand(originalCmd,chActive,authorized);
|
scheduleOppositeCommand(originalCmd,chActive,authorized);
|
||||||
scheduledOppositeCommand = true;
|
scheduledOppositeCommand = true;
|
||||||
}
|
}
|
||||||
if (subItem) status2Send |= FLAG_SEND_IMMEDIATE;
|
if (subItem && !subitemCmd) status2Send |= FLAG_SEND_IMMEDIATE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res=1;
|
res=1;
|
||||||
|
if (subitemCmd) subItem = NULL;
|
||||||
|
|
||||||
// Post-processing of group command - converting HALT,REST,XON,XOFF to conventional ON/OFF for status
|
// Post-processing of group command - converting HALT,REST,XON,XOFF to conventional ON/OFF for status
|
||||||
switch (cmd.getCmd()) {
|
switch (cmd.getCmd()) {
|
||||||
@@ -1383,7 +1401,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized
|
|||||||
if (subItem)
|
if (subItem)
|
||||||
{
|
{
|
||||||
//Check if subitem is some sort of command
|
//Check if subitem is some sort of command
|
||||||
int subitemCmd = subitem2cmd(subItem);
|
|
||||||
short prevCmd = getCmd();
|
short prevCmd = getCmd();
|
||||||
if (!prevCmd && chActive) prevCmd=CMD_ON;
|
if (!prevCmd && chActive) prevCmd=CMD_ON;
|
||||||
|
|
||||||
@@ -1657,6 +1675,8 @@ if ((!driver || driver->isAllowed(cmd))
|
|||||||
case CMD_HALT:
|
case CMD_HALT:
|
||||||
case CMD_XOFF:
|
case CMD_XOFF:
|
||||||
digitalWrite(iaddr, k = (inverse) ? HIGH : LOW);
|
digitalWrite(iaddr, k = (inverse) ? HIGH : LOW);
|
||||||
|
default:
|
||||||
|
k = -1;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
if (inverse)
|
if (inverse)
|
||||||
@@ -1780,7 +1800,6 @@ int Item::isActive() {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int cmd = getCmd();
|
int cmd = getCmd();
|
||||||
|
|
||||||
if (driver) {
|
if (driver) {
|
||||||
short active = driver->isActive();
|
short active = driver->isActive();
|
||||||
if (active >= 0)
|
if (active >= 0)
|
||||||
@@ -1905,7 +1924,6 @@ switch (cause)
|
|||||||
sendDelayedStatus();
|
sendDelayedStatus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (driver && driver->Status())
|
if (driver && driver->Status())
|
||||||
{
|
{
|
||||||
return driver->Poll(cause);
|
return driver->Poll(cause);
|
||||||
@@ -2218,7 +2236,6 @@ int Item::checkRetry() {
|
|||||||
{ // if last sending attempt of command was failed
|
{ // if last sending attempt of command was failed
|
||||||
itemCmd val(ST_VOID,CMD_VOID);
|
itemCmd val(ST_VOID,CMD_VOID);
|
||||||
val.loadItem(this, FLAG_COMMAND | FLAG_PARAMETERS);
|
val.loadItem(this, FLAG_COMMAND | FLAG_PARAMETERS);
|
||||||
|
|
||||||
if (driver)
|
if (driver)
|
||||||
{
|
{
|
||||||
clearFlag(FLAG_SEND_RETRY); // Clean retry flag
|
clearFlag(FLAG_SEND_RETRY); // Clean retry flag
|
||||||
@@ -2721,5 +2738,158 @@ int Item::checkModbusDimmer(int data) {
|
|||||||
} //if data changed
|
} //if data changed
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Item * driverFactory::getItem(Item * item)
|
||||||
|
{
|
||||||
|
abstractOut * driver = findDriver(item);
|
||||||
|
if (driver) return driver->getItem();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstractOut * driverFactory::findDriver(Item * item)
|
||||||
|
{
|
||||||
|
if (!item || !item->isValid()) return NULL;
|
||||||
|
uint8_t itemType = item->itemType;
|
||||||
|
if (itemType>CH_MAX) return NULL;
|
||||||
|
|
||||||
|
switch (itemType)
|
||||||
|
{
|
||||||
|
case CH_RGBW:
|
||||||
|
case CH_RGB:
|
||||||
|
case CH_RGBWW:
|
||||||
|
itemType = CH_DIMMER;
|
||||||
|
}
|
||||||
|
return drivers[itemType];
|
||||||
|
}
|
||||||
|
|
||||||
|
void driverFactory::freeDriver(Item * item)
|
||||||
|
{
|
||||||
|
if (item && item->driver)
|
||||||
|
{
|
||||||
|
abstractOut * driver = findDriver(item);
|
||||||
|
if (driver)
|
||||||
|
{
|
||||||
|
if (driver->getItem() == item)
|
||||||
|
item->driver->link(NULL);
|
||||||
|
else delete item->driver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstractOut * driverFactory::getDriver(Item * item)
|
||||||
|
{
|
||||||
|
if (!item || !item->isValid()) return NULL;
|
||||||
|
abstractOut * driver = findDriver(item);
|
||||||
|
if (driver)
|
||||||
|
{
|
||||||
|
if (driver->getItem()) driver = newDriver(item->itemType);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
driver = newDriver(item->itemType);
|
||||||
|
if (driver) drivers[item->itemType]=driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (driver) driver->link(item);
|
||||||
|
return driver;
|
||||||
|
}
|
||||||
|
|
||||||
|
abstractOut * driverFactory::newDriver(uint8_t itemType)
|
||||||
|
{
|
||||||
|
abstractOut * driver = NULL;
|
||||||
|
switch (itemType)
|
||||||
|
{
|
||||||
|
#ifndef PWM_DISABLE
|
||||||
|
case CH_PWM:
|
||||||
|
driver = new out_pwm ;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DMX_DISABLE
|
||||||
|
case CH_DIMMER:
|
||||||
|
driver = new out_dmx ;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifndef SPILED_DISABLE
|
||||||
|
case CH_SPILED:
|
||||||
|
driver = new out_SPILed ;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef AC_DISABLE
|
||||||
|
case CH_AC:
|
||||||
|
driver = new out_AC ;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MOTOR_DISABLE
|
||||||
|
case CH_MOTOR:
|
||||||
|
driver = new out_Motor ;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MBUS_DISABLE
|
||||||
|
case CH_MBUS:
|
||||||
|
driver = new out_Modbus ;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PID_DISABLE
|
||||||
|
case CH_PID:
|
||||||
|
driver = new out_pid ;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef RELAY_DISABLE
|
||||||
|
case CH_RELAYX:
|
||||||
|
driver = new out_relay ;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MULTIVENT_DISABLE
|
||||||
|
case CH_MULTIVENT:
|
||||||
|
driver = new out_Multivent ;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef UARTBRIDGE_ENABLE
|
||||||
|
case CH_UARTBRIDGE:
|
||||||
|
driver = new out_UARTbridge ;
|
||||||
|
// debugSerial<<F("AC driver created")<<endl;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ELEVATOR_ENABLE
|
||||||
|
case CH_ELEVATOR:
|
||||||
|
driver = new out_elevator ;
|
||||||
|
// debugSerial<<F("AC driver created")<<endl;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HUMIDIFIER_ENABLE
|
||||||
|
case CH_HUMIDIFIER:
|
||||||
|
driver = new out_humidifier ;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MERCURY_ENABLE
|
||||||
|
case CH_MERCURY:
|
||||||
|
driver = new out_Mercury ;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef COUNTER_DISABLE
|
||||||
|
case CH_COUNTER:
|
||||||
|
driver = new out_counter ;
|
||||||
|
// debugSerial<<F("AC driver created")<<endl;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default: ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return driver;
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright © 2017-2020 Andrey Klimov. All rights reserved.
|
/* Copyright © 2017-2025 Andrey Klimov. All rights reserved.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -22,6 +22,7 @@ e-mail anklimov@gmail.com
|
|||||||
#include "abstractout.h"
|
#include "abstractout.h"
|
||||||
#include "itemCmd.h"
|
#include "itemCmd.h"
|
||||||
|
|
||||||
|
|
||||||
#define S_NOTFOUND 0
|
#define S_NOTFOUND 0
|
||||||
#define S_CMD 1
|
#define S_CMD 1
|
||||||
#define S_SET 2
|
#define S_SET 2
|
||||||
@@ -67,6 +68,7 @@ const suffixstr suffix_P[] PROGMEM =
|
|||||||
#define CH_COUNTER 20
|
#define CH_COUNTER 20
|
||||||
#define CH_HUMIDIFIER 21
|
#define CH_HUMIDIFIER 21
|
||||||
#define CH_MERCURY 22
|
#define CH_MERCURY 22
|
||||||
|
#define CH_MAX 22
|
||||||
|
|
||||||
#define POLLING_SLOW 1
|
#define POLLING_SLOW 1
|
||||||
#define POLLING_FAST 2
|
#define POLLING_FAST 2
|
||||||
@@ -169,6 +171,18 @@ class Item
|
|||||||
int defaultSuffixCode;
|
int defaultSuffixCode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class driverFactory {
|
||||||
|
public:
|
||||||
|
driverFactory(){memset(drivers,0,sizeof(drivers));};
|
||||||
|
Item * getItem(Item * item);
|
||||||
|
abstractOut * getDriver(Item * item);
|
||||||
|
abstractOut * findDriver(Item * item);
|
||||||
|
void freeDriver(Item * item);
|
||||||
|
abstractOut * newDriver(uint8_t itemType);
|
||||||
|
private:
|
||||||
|
abstractOut * drivers[CH_MAX+1];
|
||||||
|
};
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
|
|||||||
@@ -429,6 +429,23 @@ bool itemCmd::incrementS(long int dif)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool itemCmd::incrementTemp(long int dif)
|
||||||
|
{int par=param.colorTemp;
|
||||||
|
switch (cmd.itemArgType)
|
||||||
|
{
|
||||||
|
case ST_HSV255:
|
||||||
|
par+=dif/TENS_BASE;
|
||||||
|
if (par>100) par=100;
|
||||||
|
if (par<1) par=1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
|
param.colorTemp=par;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
itemCmd itemCmd::assignFrom(itemCmd from, short chanType)
|
itemCmd itemCmd::assignFrom(itemCmd from, short chanType)
|
||||||
{
|
{
|
||||||
@@ -1514,7 +1531,7 @@ char * itemCmd::toString(char * Buffer, int bufLen, int sendFlags, bool scale100
|
|||||||
if (!Buffer || !bufLen) return NULL;
|
if (!Buffer || !bufLen) return NULL;
|
||||||
*Buffer=0;
|
*Buffer=0;
|
||||||
char * argPtr=Buffer;
|
char * argPtr=Buffer;
|
||||||
if (isCommand() && (sendFlags & FLAG_COMMAND))
|
if (isCommand() && (sendFlags & FLAG_COMMAND) && cmd.cmdCode<commandsNum)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
strncpy_P(Buffer, commands_P[cmd.cmdCode], bufLen);
|
strncpy_P(Buffer, commands_P[cmd.cmdCode], bufLen);
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ public:
|
|||||||
bool incrementPercents(long int, long int limit);
|
bool incrementPercents(long int, long int limit);
|
||||||
bool incrementH(long int);
|
bool incrementH(long int);
|
||||||
bool incrementS(long int);
|
bool incrementS(long int);
|
||||||
|
bool incrementTemp(long int dif);
|
||||||
|
|
||||||
long int getInt();
|
long int getInt();
|
||||||
long int getTens();
|
long int getTens();
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ e-mail anklimov@gmail.com
|
|||||||
#include "flashstream.h"
|
#include "flashstream.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#if defined(__SAM3X8E__)
|
#if defined(TIMER_INT)
|
||||||
#include "TimerInterrupt_Generic.h"
|
#include "TimerInterrupt_Generic.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -2185,6 +2185,25 @@ int16_t attachTimer(double microseconds, timerCallback callback, const char* Tim
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_STM32) && defined (TIMER_INT)
|
||||||
|
STM32Timer ITimer0(TIM1);
|
||||||
|
|
||||||
|
int16_t attachTimer(double microseconds, timerCallback callback, const char* TimerName)
|
||||||
|
{
|
||||||
|
if (timerNumber!=-1) return timerNumber;
|
||||||
|
// Interval in microsecs
|
||||||
|
if (ITimer0.attachInterruptInterval(microseconds, callback))
|
||||||
|
{
|
||||||
|
debugSerial.print(F("Starting ITimer0 OK"));
|
||||||
|
timerNumber = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
debugSerial.println(F("Can't set ITimer0. Select another freq. or timer"));
|
||||||
|
return timerNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__SAM3X8E__) && defined (PULSEPIN12)
|
#if defined(__SAM3X8E__) && defined (PULSEPIN12)
|
||||||
#define MATURA_PULSE 100
|
#define MATURA_PULSE 100
|
||||||
#define MATURA_PERIOD 2500
|
#define MATURA_PERIOD 2500
|
||||||
@@ -3117,7 +3136,11 @@ configLocked++;
|
|||||||
// Interval in microsecs
|
// Interval in microsecs
|
||||||
attachTimer(TIMER_CHECK_INPUT * 1000, TimerHandler, "ITimer");
|
attachTimer(TIMER_CHECK_INPUT * 1000, TimerHandler, "ITimer");
|
||||||
attachMaturaTimer();
|
attachMaturaTimer();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ARDUINO_ARCH_STM32) && defined (TIMER_INT)
|
||||||
|
// Interval in microsecs
|
||||||
|
attachTimer(TIMER_CHECK_INPUT * 1000, TimerHandler, "ITimer");
|
||||||
#endif
|
#endif
|
||||||
configLocked--;
|
configLocked--;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ public:
|
|||||||
class out_AC : public abstractOut {
|
class out_AC : public abstractOut {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
out_AC(Item * _item):abstractOut(_item){store = (acPersistent *) item->getPersistent(); getConfig();};
|
out_AC():store(NULL){};
|
||||||
|
void link(Item * _item){abstractOut::link(_item); if (_item) {store = (acPersistent *) item->getPersistent(); getConfig();} else store = NULL;};
|
||||||
void getConfig();
|
void getConfig();
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
|
|||||||
@@ -8,8 +8,6 @@
|
|||||||
|
|
||||||
class out_counter : public abstractOut {
|
class out_counter : public abstractOut {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
out_counter(Item * _item):abstractOut(_item){};
|
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
|
|||||||
@@ -9,14 +9,10 @@
|
|||||||
|
|
||||||
class out_dmx : public colorChannel {
|
class out_dmx : public colorChannel {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
out_dmx(Item * _item):colorChannel(_item){};
|
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
|
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
// int Ctrl(itemCmd cmd, char* subItem=NULL) override;
|
|
||||||
// int PixelCtrl(itemCmd cmd) override;
|
|
||||||
virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false) override;
|
virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -42,13 +42,15 @@ public:
|
|||||||
class out_Mercury : public abstractOut {
|
class out_Mercury : public abstractOut {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
out_Mercury(Item * _item):abstractOut(_item){store = (mercuryPersistent *) item->getPersistent();};
|
//out_Mercury(Item * _item):abstractOut(_item){store = (mercuryPersistent *) item->getPersistent();};
|
||||||
|
out_Mercury():store(NULL){};
|
||||||
|
void link(Item * _item){abstractOut::link(_item); if (_item) {store = (mercuryPersistent *) item->getPersistent();} else store = NULL;};
|
||||||
|
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||||
//int getDefaultStorageType(){return ST_INT32;};
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -451,7 +451,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
|||||||
{
|
{
|
||||||
mappedParam = findRegister(defMappingObj->valueint,defMappingObj->valueint-registerFrom,regType,registerFrom,registerTo,false,&submitRecurrentOut);
|
mappedParam = findRegister(defMappingObj->valueint,defMappingObj->valueint-registerFrom,regType,registerFrom,registerTo,false,&submitRecurrentOut);
|
||||||
executeWithoutCheck=true;
|
executeWithoutCheck=true;
|
||||||
debugSerial<<"MBUSD: recurrent check res: "<<"SRO:"<<submitRecurrentOut<<endl;
|
traceSerial<<"MBUSD: recurrent check res: "<<"SRO:"<<submitRecurrentOut<<endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,8 +31,10 @@ public:
|
|||||||
|
|
||||||
class out_Modbus : public abstractOut {
|
class out_Modbus : public abstractOut {
|
||||||
public:
|
public:
|
||||||
|
//out_Modbus(Item * _item):abstractOut(_item){store = (mbPersistent *) item->getPersistent();};
|
||||||
|
out_Modbus():store(NULL){};
|
||||||
|
void link(Item * _item){abstractOut::link(_item); if (_item) {store = (mbPersistent *) item->getPersistent(); } else store = NULL;};
|
||||||
|
|
||||||
out_Modbus(Item * _item):abstractOut(_item){store = (mbPersistent *) item->getPersistent();};
|
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ static int8_t motorQuote = MOTOR_QUOTE;
|
|||||||
class out_Motor : public abstractOut {
|
class out_Motor : public abstractOut {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
out_Motor(Item * _item):abstractOut(_item){getConfig();};
|
//out_Motor(Item * _item):abstractOut(_item){getConfig();};
|
||||||
|
//out_Motor(){};
|
||||||
|
void link(Item * _item){abstractOut::link(_item); if (_item) getConfig();};
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
|
|||||||
@@ -12,7 +12,9 @@
|
|||||||
class out_Multivent : public abstractOut {
|
class out_Multivent : public abstractOut {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
out_Multivent(Item * _item):abstractOut(_item){getConfig();};
|
//out_Multivent(Item * _item):abstractOut(_item){getConfig();};
|
||||||
|
//out_Multivent(){};
|
||||||
|
void link(Item * _item){abstractOut::link(_item); if (_item) getConfig();};
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ public:
|
|||||||
class out_pid : public abstractOut {
|
class out_pid : public abstractOut {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
out_pid(Item * _item):abstractOut(_item){store = (pidPersistent *) item->getPersistent();};
|
//out_pid(Item * _item):abstractOut(_item){store = (pidPersistent *) item->getPersistent();};
|
||||||
|
out_pid():store(NULL){};
|
||||||
|
void link(Item * _item){abstractOut::link(_item); if (_item) {store = (pidPersistent *) item->getPersistent();} else store = NULL;};
|
||||||
|
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
class out_pwm : public colorChannel {
|
class out_pwm : public colorChannel {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
out_pwm(Item * _item):colorChannel(_item){numChannels=0;};
|
// out_pwm():numChannels(0){};
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ public:
|
|||||||
//int Ctrl(itemCmd cmd, char* subItem=NULL) override;
|
//int Ctrl(itemCmd cmd, char* subItem=NULL) override;
|
||||||
int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false ) override;
|
int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false ) override;
|
||||||
|
|
||||||
protected:
|
//protected:
|
||||||
short numChannels;
|
// short numChannels;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
class out_relay : public abstractOut {
|
class out_relay : public abstractOut {
|
||||||
public:
|
public:
|
||||||
|
void link(Item * _item){abstractOut::link(_item); if (_item) getConfig();};
|
||||||
out_relay(Item * _item):abstractOut(_item){ getConfig();};
|
|
||||||
void getConfig();
|
void getConfig();
|
||||||
void relay(bool state);
|
void relay(bool state);
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
|
|||||||
@@ -15,7 +15,9 @@
|
|||||||
class out_SPILed : public colorChannel {
|
class out_SPILed : public colorChannel {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
out_SPILed(Item * _item):colorChannel(_item){getConfig();};
|
//out_SPILed(Item * _item):colorChannel(_item){getConfig();};
|
||||||
|
//out_SPILed(){};
|
||||||
|
void link(Item * _item){colorChannel::link(_item);if (_item) getConfig();};
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
|
|||||||
@@ -58,7 +58,12 @@ public:
|
|||||||
class out_UARTbridge : public abstractOut {
|
class out_UARTbridge : public abstractOut {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
out_UARTbridge(Item * _item):abstractOut(_item){store = (ubPersistent *) item->getPersistent();};
|
// out_UARTbridge(Item * _item):abstractOut(_item){store = (ubPersistent *) item->getPersistent();};
|
||||||
|
|
||||||
|
out_UARTbridge():store(NULL){};
|
||||||
|
void link(Item * _item){abstractOut::link(_item); if (_item) {store = (ubPersistent *) item->getPersistent();} else store = NULL;};
|
||||||
|
|
||||||
|
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ long getIntFromStr(char **chan) {
|
|||||||
// chan is pointer to pointer to string
|
// chan is pointer to pointer to string
|
||||||
// Function return first retrived number and move pointer to position next after ','
|
// Function return first retrived number and move pointer to position next after ','
|
||||||
itemCmd getNumber(char **chan) {
|
itemCmd getNumber(char **chan) {
|
||||||
itemCmd val(ST_TENS,CMD_VOID);
|
itemCmd val(ST_VOID,CMD_VOID); //WAS ST_TENS ?
|
||||||
if (chan && *chan && **chan)
|
if (chan && *chan && **chan)
|
||||||
{
|
{
|
||||||
//Skip non-numeric values
|
//Skip non-numeric values
|
||||||
@@ -161,7 +161,7 @@ itemCmd getNumber(char **chan) {
|
|||||||
if (isDigit(*(fractptr+i))) fractnumbers += constrain(*(fractptr+i)-'0',0,9);
|
if (isDigit(*(fractptr+i))) fractnumbers += constrain(*(fractptr+i)-'0',0,9);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!fractlen && !intlen) return val; //VOID
|
||||||
if (!fractlen) val.Int(atol(*chan));
|
if (!fractlen) val.Int(atol(*chan));
|
||||||
else if (fractlen<=TENS_FRACT_LEN && intlen+TENS_FRACT_LEN<=9)
|
else if (fractlen<=TENS_FRACT_LEN && intlen+TENS_FRACT_LEN<=9)
|
||||||
{
|
{
|
||||||
@@ -670,11 +670,15 @@ aJsonObject *can = NULL;
|
|||||||
aJsonObject *icmd = NULL;
|
aJsonObject *icmd = NULL;
|
||||||
aJsonObject *ecmd = NULL;
|
aJsonObject *ecmd = NULL;
|
||||||
char cmdType = 0;
|
char cmdType = 0;
|
||||||
|
if (serialDebugLevel>=LOG_TRACE || udpDebugLevel>=LOG_TRACE)
|
||||||
//char * out = aJson.print(cmd);
|
{
|
||||||
//debugSerial<<"Exec:"<<out<<endl;
|
char* out = aJson.print(cmd);
|
||||||
//free (out);
|
if (out)
|
||||||
|
{
|
||||||
|
debugSerial<<"Exec:"<<out<<endl;
|
||||||
|
free (out);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (cmd) cmdType = cmd->type;
|
if (cmd) cmdType = cmd->type;
|
||||||
|
|
||||||
switch (cmdType)
|
switch (cmdType)
|
||||||
|
|||||||
@@ -1010,7 +1010,8 @@ lib_deps =
|
|||||||
https://github.com/anklimov/ModbusMaster
|
https://github.com/anklimov/ModbusMaster
|
||||||
pazi88/STM32_CAN
|
pazi88/STM32_CAN
|
||||||
ericksimoes/Ultrasonic
|
ericksimoes/Ultrasonic
|
||||||
https://github.com/mathertel/RotaryEncoderv
|
https://github.com/mathertel/RotaryEncoder
|
||||||
|
;TimerInterrupt_Generic
|
||||||
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user