mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 22:22:16 +03:00
not lib ecto
This commit is contained in:
@@ -3,13 +3,17 @@
|
||||
#include <map>
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
#include "lib/rsEctoControl.h"
|
||||
#include "ModbusEC.h"
|
||||
#include "AdapterCommon.h"
|
||||
// #include "Stream.h"
|
||||
#include <vector>
|
||||
|
||||
|
||||
// class ModbusUart;
|
||||
Stream *_mbUART = nullptr;
|
||||
Stream *_modbusUART = nullptr;
|
||||
|
||||
#define UART_LINE 2
|
||||
|
||||
uint8_t _DIR_PIN = 0;
|
||||
// Modbus stuff
|
||||
// Данные Modbus по умолчанию
|
||||
|
||||
@@ -17,25 +21,26 @@ Stream *_mbUART = nullptr;
|
||||
#define MODBUS_TX_PIN 19 // Tx pin
|
||||
#define MODBUS_SERIAL_BAUD 9600 // Baud rate for esp32 and max485 communication
|
||||
|
||||
// void modbusPreTransmission()
|
||||
// {
|
||||
// // delay(500);
|
||||
// if (_DIR_PIN)
|
||||
// digitalWrite(_DIR_PIN, HIGH);
|
||||
// }
|
||||
|
||||
// // Pin 4 made low for Modbus receive mode
|
||||
// // Контакт 4 установлен на низком уровне для режима приема Modbus
|
||||
// void modbusPostTransmission()
|
||||
// {
|
||||
// if (_DIR_PIN)
|
||||
// digitalWrite(_DIR_PIN, LOW);
|
||||
// // delay(500);
|
||||
// }
|
||||
void modbusPreTransmission()
|
||||
{
|
||||
// delay(500);
|
||||
if (_DIR_PIN)
|
||||
digitalWrite(_DIR_PIN, HIGH);
|
||||
}
|
||||
|
||||
// Pin 4 made low for Modbus receive mode
|
||||
// Контакт 4 установлен на низком уровне для режима приема Modbus
|
||||
void modbusPostTransmission()
|
||||
{
|
||||
if (_DIR_PIN)
|
||||
digitalWrite(_DIR_PIN, LOW);
|
||||
// delay(500);
|
||||
}
|
||||
|
||||
// ModbusMaster node;
|
||||
|
||||
RsEctoControl *rsEC;
|
||||
//RsEctoControl *rsEC;
|
||||
|
||||
class EctoControlAdapter : public IoTItem
|
||||
{
|
||||
@@ -48,16 +53,43 @@ private:
|
||||
uint8_t _addr = 0xF0; // Адрес слейва от 1 до 247
|
||||
uint8_t _type = 0x14; // Тип устройства: 0x14 – адаптер OpenTherm (вторая версия); 0x11 – адаптер OpenTherm (первая версия, снята с производства)
|
||||
bool _debugLevel; // Дебаг
|
||||
//uint8_t _dir_pin;
|
||||
|
||||
ModbusMaster node;
|
||||
uint8_t _debug;
|
||||
//Stream *_modbusUART;
|
||||
|
||||
BoilerInfo info;
|
||||
BoilerStatus status;
|
||||
|
||||
uint16_t code;
|
||||
uint16_t codeExt;
|
||||
uint8_t flagErr;
|
||||
float flow;
|
||||
float maxSetCH;
|
||||
float maxSetDHW;
|
||||
float minSetCH;
|
||||
float minSetDHW;
|
||||
float modLevel;
|
||||
float press;
|
||||
float tCH;
|
||||
float tDHW;
|
||||
float tOut;
|
||||
bool enableCH;
|
||||
bool enableDHW;
|
||||
bool enableCH2;
|
||||
bool _isNetworkActive;
|
||||
bool _mqttIsConnect;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
EctoControlAdapter(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
//_dir_pin = 0;
|
||||
_DIR_PIN = 0;
|
||||
_addr = jsonReadInt(parameters, "addr"); // адреса slave прочитаем с веба
|
||||
_rx = jsonReadInt(parameters, "RX"); // прочитаем с веба
|
||||
_tx = jsonReadInt(parameters, "TX");
|
||||
//_dir_pin = jsonReadInt(parameters, "DIR_PIN");
|
||||
_DIR_PIN = jsonReadInt(parameters, "DIR_PIN");
|
||||
_baud = jsonReadInt(parameters, "baud");
|
||||
_prot = jsonReadStr(parameters, "protocol");
|
||||
jsonRead(parameters, "debug", _debugLevel);
|
||||
@@ -73,163 +105,200 @@ public:
|
||||
|
||||
// Serial2.begin(baud-rate, protocol, RX pin, TX pin);
|
||||
|
||||
_mbUART = new HardwareSerial(UART_LINE);
|
||||
_modbusUART = new HardwareSerial(UART_LINE);
|
||||
|
||||
if (_debugLevel > 2)
|
||||
{
|
||||
SerialPrint("I", "EctoControlAdapter", "baud: " + String(_baud) + ", protocol: " + String(protocol, HEX) + ", RX: " + String(_rx) + ", TX: " + String(_tx));
|
||||
}
|
||||
((HardwareSerial *)_mbUART)->begin(_baud, protocol, _rx, _tx); // выбираем тип протокола, скорость и все пины с веба
|
||||
((HardwareSerial *)_mbUART)->setTimeout(200);
|
||||
rsEC = new RsEctoControl(parameters);
|
||||
rsEC->begin(_addr, (Stream &)*_mbUART);
|
||||
((HardwareSerial *)_modbusUART)->begin(_baud, protocol, _rx, _tx); // выбираем тип протокола, скорость и все пины с веба
|
||||
((HardwareSerial *)_modbusUART)->setTimeout(200);
|
||||
//_modbusUART = &serial;
|
||||
node.begin(_addr, _modbusUART);
|
||||
|
||||
node.preTransmission(modbusPreTransmission);
|
||||
node.postTransmission(modbusPostTransmission);
|
||||
|
||||
|
||||
if (_DIR_PIN)
|
||||
{
|
||||
_DIR_PIN = _DIR_PIN;
|
||||
pinMode(_DIR_PIN, OUTPUT);
|
||||
digitalWrite(_DIR_PIN, LOW);
|
||||
}
|
||||
|
||||
// 0x14 – адаптер OpenTherm (вторая версия)
|
||||
// 0x15 – адаптер eBus
|
||||
// 0x16 – адаптер Navien
|
||||
uint16_t type;
|
||||
readFunctionModBus(0x0000, type);
|
||||
if (0x14 != (uint8_t)type || 0x15 != (uint8_t)type || 0x16 != (uint8_t)type)
|
||||
{
|
||||
SerialPrint("E", "EctoControlAdapter", "Не подходящее устройство, type: " + String(type, HEX));
|
||||
}
|
||||
|
||||
uint8_t addr = node.readAddresEctoControl();
|
||||
SerialPrint("I", "EctoControlAdapter", "readAddresEctoControl, addr: " + String(addr, HEX) + " - Enter to configuration");
|
||||
|
||||
getModelVersion();
|
||||
getBoilerInfo();
|
||||
getBoilerStatus();
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
if (rsEC)
|
||||
rsEC->doByInterval();
|
||||
// readBoilerInfo();
|
||||
getBoilerStatus();
|
||||
|
||||
getCodeError();
|
||||
getCodeErrorExt();
|
||||
if (info.adapterType == 0)
|
||||
getFlagErrorOT();
|
||||
// getFlowRate();
|
||||
// getMaxSetCH();
|
||||
// getMaxSetDHW();
|
||||
// getMinSetCH();
|
||||
// getMinSetDHW();
|
||||
getModLevel();
|
||||
getPressure();
|
||||
getTempCH();
|
||||
getTempDHW();
|
||||
getTempOutside();
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (rsEC)
|
||||
rsEC->loop(isNetworkActive(), mqttIsConnect());
|
||||
// для новых версий IoTManager
|
||||
IoTItem::loop();
|
||||
}
|
||||
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m)
|
||||
{
|
||||
if (rsEC)
|
||||
rsEC->execute(command, param);
|
||||
else
|
||||
return {};
|
||||
if (command == "getModelVersion")
|
||||
{
|
||||
rsEC->getModelVersion();
|
||||
getModelVersion();
|
||||
}
|
||||
if (command == "getModelVersion")
|
||||
{
|
||||
rsEC->getModelVersion();
|
||||
getModelVersion();
|
||||
}
|
||||
if (command == "getBoilerInfo")
|
||||
{
|
||||
rsEC->getBoilerInfo();
|
||||
getBoilerInfo();
|
||||
}
|
||||
if (command == "getBoilerStatus")
|
||||
{
|
||||
rsEC->getBoilerStatus();
|
||||
getBoilerStatus();
|
||||
}
|
||||
if (command == "getCodeError")
|
||||
{
|
||||
rsEC->getCodeError();
|
||||
getCodeError();
|
||||
}
|
||||
if (command == "getCodeErrorExt")
|
||||
{
|
||||
rsEC->getCodeErrorExt();
|
||||
getCodeErrorExt();
|
||||
}
|
||||
if (command == "getFlagErrorOT")
|
||||
{
|
||||
rsEC->getFlagErrorOT();
|
||||
getFlagErrorOT();
|
||||
}
|
||||
if (command == "getFlowRate")
|
||||
{
|
||||
rsEC->getFlowRate();
|
||||
getFlowRate();
|
||||
}
|
||||
if (command == "getMaxSetCH")
|
||||
{
|
||||
rsEC->getMaxSetCH();
|
||||
getMaxSetCH();
|
||||
}
|
||||
if (command == "getMaxSetDHW")
|
||||
{
|
||||
rsEC->getMaxSetDHW();
|
||||
getMaxSetDHW();
|
||||
}
|
||||
if (command == "getMinSetCH")
|
||||
{
|
||||
rsEC->getMinSetCH();
|
||||
getMinSetCH();
|
||||
}
|
||||
if (command == "getMinSetDHW")
|
||||
{
|
||||
rsEC->getMinSetDHW();
|
||||
getMinSetDHW();
|
||||
}
|
||||
if (command == "getModLevel")
|
||||
{
|
||||
rsEC->getModLevel();
|
||||
getModLevel();
|
||||
}
|
||||
if (command == "getPressure")
|
||||
{
|
||||
rsEC->getPressure();
|
||||
getPressure();
|
||||
}
|
||||
if (command == "getTempCH")
|
||||
{
|
||||
rsEC->getTempCH();
|
||||
getTempCH();
|
||||
}
|
||||
if (command == "getTempDHW")
|
||||
{
|
||||
rsEC->getTempDHW();
|
||||
getTempDHW();
|
||||
}
|
||||
if (command == "getTempOutside")
|
||||
{
|
||||
rsEC->getTempOutside();
|
||||
getTempOutside();
|
||||
}
|
||||
|
||||
if (command == "setTypeConnect")
|
||||
{
|
||||
rsEC->setTypeConnect(param[0].valD);
|
||||
setTypeConnect(param[0].valD);
|
||||
}
|
||||
if (command == "setTCH")
|
||||
{
|
||||
rsEC->setTCH(param[0].valD);
|
||||
setTCH(param[0].valD);
|
||||
}
|
||||
if (command == "setTCHFaultConn")
|
||||
{
|
||||
rsEC->setTCHFaultConn(param[0].valD);
|
||||
setTCHFaultConn(param[0].valD);
|
||||
}
|
||||
if (command == "setMinCH")
|
||||
{
|
||||
rsEC->setMinCH(param[0].valD);
|
||||
setMinCH(param[0].valD);
|
||||
}
|
||||
if (command == "setMaxCH")
|
||||
{
|
||||
rsEC->setMaxCH(param[0].valD);
|
||||
setMaxCH(param[0].valD);
|
||||
}
|
||||
if (command == "setMinDHW")
|
||||
{
|
||||
rsEC->setMinDHW(param[0].valD);
|
||||
setMinDHW(param[0].valD);
|
||||
}
|
||||
if (command == "setMaxDHW")
|
||||
{
|
||||
rsEC->setMaxDHW(param[0].valD);
|
||||
setMaxDHW(param[0].valD);
|
||||
}
|
||||
if (command == "setTDHW")
|
||||
{
|
||||
rsEC->setTDHW(param[0].valD);
|
||||
setTDHW(param[0].valD);
|
||||
}
|
||||
if (command == "setMaxModLevel")
|
||||
{
|
||||
rsEC->setMaxModLevel(param[0].valD);
|
||||
setMaxModLevel(param[0].valD);
|
||||
}
|
||||
if (command == "setStatusCH")
|
||||
{
|
||||
rsEC->setStatusCH((bool)param[0].valD);
|
||||
setStatusCH((bool)param[0].valD);
|
||||
}
|
||||
if (command == "setStatusDHW")
|
||||
{
|
||||
rsEC->setStatusDHW((bool)param[0].valD);
|
||||
setStatusDHW((bool)param[0].valD);
|
||||
}
|
||||
if (command == "setStatusCH2")
|
||||
{
|
||||
rsEC->setStatusCH2((bool)param[0].valD);
|
||||
setStatusCH2((bool)param[0].valD);
|
||||
}
|
||||
|
||||
if (command == "lockOutReset")
|
||||
{
|
||||
rsEC->lockOutReset();
|
||||
lockOutReset();
|
||||
}
|
||||
if (command == "rebootAdapter")
|
||||
{
|
||||
rsEC->rebootAdapter();
|
||||
rebootAdapter();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@@ -255,9 +324,477 @@ public:
|
||||
|
||||
~EctoControlAdapter()
|
||||
{
|
||||
delete rsEC;
|
||||
rsEC = nullptr;
|
||||
};
|
||||
|
||||
bool writeFunctionModBus(const uint16_t ®, uint16_t &data)
|
||||
{
|
||||
// set word 0 of TX buffer to least-significant word of counter (bits 15..0)
|
||||
node.setTransmitBuffer(1, lowWord(data));
|
||||
// set word 1 of TX buffer to most-significant word of counter (bits 31..16)
|
||||
node.setTransmitBuffer(0, highWord(data));
|
||||
// slave: write TX buffer to (2) 16-bit registers starting at register 0
|
||||
uint8_t result = node.writeMultipleRegisters(0, 2);
|
||||
if (_debug > 2)
|
||||
{
|
||||
SerialPrint("I", "EctoControlAdapter", "writeSingleRegister, addr: " + String((uint8_t)_addr, HEX) + ", reg: " + String(reg, HEX) + ", state: " + String(data) + " = result: " + String(result, HEX));
|
||||
}
|
||||
if (result == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool readFunctionModBus(const uint16_t ®, uint16_t &reading)
|
||||
{
|
||||
// float retValue = 0;
|
||||
if (_modbusUART)
|
||||
{
|
||||
// if (!addr)
|
||||
// addr = _addr;
|
||||
node.begin(_addr, _modbusUART);
|
||||
uint8_t result;
|
||||
// uint32_t reading;
|
||||
|
||||
if (reg == 0x0000)
|
||||
result = node.readHoldingRegisters(reg, 4);
|
||||
else
|
||||
result = node.readHoldingRegisters(reg, 1);
|
||||
if (_debug > 2)
|
||||
SerialPrint("I", "EctoControlAdapter", "readHoldingRegisters, addr: " + String(_addr, HEX) + ", reg: " + String(reg, HEX) + " = result: " + String(result, HEX));
|
||||
// break;
|
||||
if (result == node.ku8MBSuccess)
|
||||
{
|
||||
if (reg == 0x0000)
|
||||
{
|
||||
reading = node.getResponseBuffer(0x03);
|
||||
reading = (uint16_t)((uint8_t)(reading) >> 8);
|
||||
SerialPrint("I", "EctoControlAdapter", "read info, addr: " + String(_addr, HEX) + ", type: " + String(reading, HEX));
|
||||
}
|
||||
else
|
||||
{
|
||||
reading = node.getResponseBuffer(0x00);
|
||||
if (_debug > 2)
|
||||
SerialPrint("I", "EctoControlAdapter", "Success, Received data, register: " + String(reg) + " = " + String(reading, HEX));
|
||||
}
|
||||
node.clearResponseBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 2)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, Response Code: " + String(result, HEX));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reading != 0x7FFF)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool getModelVersion()
|
||||
{
|
||||
uint16_t reqData;
|
||||
info.boilerMemberCode = readFunctionModBus(ReadDataEctoControl::ecR_MemberCode, info.boilerMemberCode);
|
||||
info.boilerModelCode = readFunctionModBus(ReadDataEctoControl::ecR_ModelCode, info.boilerModelCode);
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_AdaperVersion, reqData);
|
||||
info.adapterHardVer = highByte(reqData);
|
||||
info.adapterSoftVer = lowByte(reqData);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool getBoilerInfo()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_AdapterInfo, reqData);
|
||||
info.adapterType = highByte(reqData) & 0xF8;
|
||||
info.boilerStatus = (highByte(reqData) >> 3) & 1u;
|
||||
info.rebootStatus = lowByte(reqData);
|
||||
if (ret)
|
||||
{
|
||||
publishData("adapterType", String(info.adapterType));
|
||||
publishData("boilerStatus", String(info.boilerStatus));
|
||||
publishData("rebootStatus", String(info.rebootStatus));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool getBoilerStatus()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_BoilerStatus, reqData);
|
||||
status.burnStatus = (lowByte(reqData) >> 0) & 1u;
|
||||
status.CHStatus = (lowByte(reqData) >> 1) & 1u;
|
||||
status.DHWStatus = (lowByte(reqData) >> 2) & 1u;
|
||||
if (ret)
|
||||
{
|
||||
publishData("burnStatus", String(status.burnStatus));
|
||||
publishData("CHStatus", String(status.CHStatus));
|
||||
publishData("DHWStatus", String(status.DHWStatus));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool getCodeError()
|
||||
{
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_CodeError, code);
|
||||
if (ret)
|
||||
{
|
||||
publishData("codeError", String(code));
|
||||
if (codeExt)
|
||||
sendTelegramm("EctoControlAdapter: код ошибки: " + String((int)codeExt));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool getCodeErrorExt()
|
||||
{
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_CodeErrorExt, codeExt);
|
||||
if (ret)
|
||||
{
|
||||
publishData("codeErrorExt", String(codeExt));
|
||||
if (codeExt)
|
||||
sendTelegramm("EctoControlAdapter: код ошибки: " + String((int)codeExt));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool getFlagErrorOT()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_FlagErrorOT, reqData);
|
||||
flagErr = lowByte(reqData);
|
||||
if (ret)
|
||||
{
|
||||
publishData("flagErr", String(flagErr));
|
||||
switch (flagErr)
|
||||
{
|
||||
case 0:
|
||||
sendTelegramm("EctoControlAdapter: Необходимо обслуживание!");
|
||||
break;
|
||||
case 1:
|
||||
sendTelegramm("EctoControlAdapter: Котёл заблокирован!");
|
||||
break;
|
||||
case 2:
|
||||
sendTelegramm("EctoControlAdapter: Низкое давление в отопительном контуре!");
|
||||
break;
|
||||
case 3:
|
||||
sendTelegramm("EctoControlAdapter: Ошибка розжига!");
|
||||
break;
|
||||
case 4:
|
||||
sendTelegramm("EctoControlAdapter: Низкое давления воздуха!");
|
||||
break;
|
||||
case 5:
|
||||
sendTelegramm("EctoControlAdapter: Перегрев теплоносителя в контуре!");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool getFlowRate()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_FlowRate, reqData);
|
||||
flow = lowByte(reqData) / 10.f;
|
||||
if (ret)
|
||||
publishData("flowRate", String(flow));
|
||||
return ret;
|
||||
}
|
||||
bool getMaxSetCH()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_MaxSetCH, reqData);
|
||||
maxSetCH = (float)lowByte(reqData);
|
||||
if (ret)
|
||||
publishData("maxSetCH", String(maxSetCH));
|
||||
return ret;
|
||||
}
|
||||
bool getMaxSetDHW()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_MaxSetDHW, reqData);
|
||||
maxSetDHW = (float)lowByte(reqData);
|
||||
if (ret)
|
||||
publishData("maxSetDHW", String(maxSetDHW));
|
||||
return ret;
|
||||
}
|
||||
bool getMinSetCH()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_MinSetCH, reqData);
|
||||
minSetCH = (float)lowByte(reqData);
|
||||
if (ret)
|
||||
publishData("minSetCH", String(minSetCH));
|
||||
return ret;
|
||||
}
|
||||
bool getMinSetDHW()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_MinSetDHW, reqData);
|
||||
minSetDHW = (float)lowByte(reqData);
|
||||
if (ret)
|
||||
publishData("minSetDHW", String(minSetDHW));
|
||||
return ret;
|
||||
}
|
||||
bool getModLevel()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_ModLevel, reqData);
|
||||
modLevel = (float)lowByte(reqData);
|
||||
if (ret)
|
||||
publishData("modLevel", String(modLevel));
|
||||
return ret;
|
||||
}
|
||||
bool getPressure()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_Pressure, reqData);
|
||||
press = lowByte(reqData) / 10.f;
|
||||
if (ret)
|
||||
publishData("press", String(press));
|
||||
return ret;
|
||||
}
|
||||
bool getTempCH()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_TempCH, reqData);
|
||||
tCH = reqData / 10.f;
|
||||
if (ret)
|
||||
publishData("tCH", String(tCH));
|
||||
return ret;
|
||||
}
|
||||
bool getTempDHW()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_TempDHW, reqData);
|
||||
tDHW = reqData / 10.f;
|
||||
if (ret)
|
||||
publishData("tDHW", String(tDHW));
|
||||
return ret;
|
||||
}
|
||||
bool getTempOutside()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_TempOutside, reqData);
|
||||
tOut = (float)lowByte(reqData);
|
||||
if (ret)
|
||||
publishData("tOut", String(tOut));
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool setTypeConnect(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_SetTypeConnect, (uint16_t &)data))
|
||||
{
|
||||
// TODO запросить результат записи у адаптера
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, setTypeConnect");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool setTCH(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
uint16_t d16 = data * 10;
|
||||
if (writeFunctionModBus(ecW_TSetCH, d16))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, setTCH");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
bool setTCHFaultConn(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
uint16_t d16 = data * 10;
|
||||
if (writeFunctionModBus(ecW_TSetCHFaultConn, d16))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, setTCHFaultConn");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool setMinCH(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_TSetMinCH, (uint16_t &)data))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, setMinCH");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool setMaxCH(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_TSetMaxCH, (uint16_t &)data))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, setMaxCH");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool setMinDHW(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_TSetMinDHW, (uint16_t &)data))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, setMinDHW");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool setMaxDHW(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_TSetMaxDHW, (uint16_t &)data))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, setMaxDHW");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool setTDHW(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_TSetDHW, (uint16_t &)data))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, setTDHW");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool setMaxModLevel(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_SetMaxModLevel, (uint16_t &)data))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, setMaxModLevel");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool setStatusCH(bool data)
|
||||
{
|
||||
bool ret = false;
|
||||
enableCH = data;
|
||||
uint16_t stat = enableCH | (enableDHW << 1) | (enableCH2 << 2);
|
||||
if (writeFunctionModBus(ecW_SetStatusBoiler, stat))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, setStatusCH");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool setStatusDHW(bool data)
|
||||
{
|
||||
bool ret = false;
|
||||
enableDHW = data;
|
||||
uint16_t stat = enableCH | (enableDHW << 1) | (enableCH2 << 2);
|
||||
if (writeFunctionModBus(ecW_SetStatusBoiler, stat))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, setStatusDHW");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool setStatusCH2(bool data)
|
||||
{
|
||||
bool ret = false;
|
||||
enableCH2 = data;
|
||||
uint16_t stat = enableCH | (enableDHW << 1) | (enableCH2 << 2);
|
||||
if (writeFunctionModBus(ecW_SetStatusBoiler, stat))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, setStatusCH2");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool lockOutReset()
|
||||
{
|
||||
bool ret = false;
|
||||
uint16_t d16 = comm_LockOutReset;
|
||||
if (writeFunctionModBus(ecW_Command, d16))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, lockOutReset");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool rebootAdapter()
|
||||
{
|
||||
bool ret = false;
|
||||
uint16_t d16 = comm_RebootAdapter;
|
||||
if (writeFunctionModBus(ecW_Command, d16))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
SerialPrint("E", "EctoControlAdapter", "Failed, rebootAdapter");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
void *getAPI_EctoControlAdapter(String subtype, String param)
|
||||
|
||||
@@ -18,11 +18,11 @@ Call once class has been instantiated, typically within setup().
|
||||
@param &serial reference to serial port object (Serial, Serial1, ... Serial3)
|
||||
@ingroup setup
|
||||
*/
|
||||
void ModbusMaster::begin(uint8_t slave, Stream &serial)
|
||||
void ModbusMaster::begin(uint8_t slave, Stream *serial)
|
||||
{
|
||||
// txBuffer = (uint16_t*) calloc(ku8MaxBufferSize, sizeof(uint16_t));
|
||||
_u8MBSlave = slave;
|
||||
_serial = &serial;
|
||||
_serial = serial;
|
||||
_u8TransmitBufferIndex = 0;
|
||||
u16TransmitBufferLength = 0;
|
||||
|
||||
@@ -20,7 +20,7 @@ class ModbusMaster
|
||||
public:
|
||||
ModbusMaster();
|
||||
|
||||
void begin(uint8_t, Stream &serial);
|
||||
void begin(uint8_t, Stream *serial);
|
||||
void idle(void (*)());
|
||||
void preTransmission(void (*)());
|
||||
void postTransmission(void (*)());
|
||||
Binary file not shown.
@@ -1,633 +0,0 @@
|
||||
#include <Arduino.h>
|
||||
#include <ArduinoJson.h>
|
||||
#ifdef ESP32
|
||||
#include <rom/spi_flash.h>
|
||||
#endif
|
||||
#include "rsEctoControl.h"
|
||||
|
||||
struct IoTValue
|
||||
{
|
||||
float valD = 0;
|
||||
String valS = "";
|
||||
|
||||
bool isDecimal = true;
|
||||
};
|
||||
uint8_t _DIR_PIN_ = 0;
|
||||
|
||||
void modbusPreTransmission()
|
||||
{
|
||||
// delay(500);
|
||||
if (_DIR_PIN_)
|
||||
digitalWrite(_DIR_PIN_, HIGH);
|
||||
}
|
||||
|
||||
// Pin 4 made low for Modbus receive mode
|
||||
// Контакт 4 установлен на низком уровне для режима приема Modbus
|
||||
void modbusPostTransmission()
|
||||
{
|
||||
if (_DIR_PIN_)
|
||||
digitalWrite(_DIR_PIN_, LOW);
|
||||
// delay(500);
|
||||
}
|
||||
|
||||
//=======================================================================================================
|
||||
// setup()
|
||||
RsEctoControl::RsEctoControl(String parameters)
|
||||
{
|
||||
node.preTransmission(modbusPreTransmission);
|
||||
node.postTransmission(modbusPostTransmission);
|
||||
|
||||
if (parameters != "")
|
||||
{
|
||||
DynamicJsonDocument doc(4096);
|
||||
DeserializationError error = deserializeJson(doc, parameters);
|
||||
if (!error)
|
||||
{
|
||||
if (doc.containsKey("DIR_PIN"))
|
||||
_DIR_PIN = doc["DIR_PIN"].as<int>();
|
||||
if (doc.containsKey("addr"))
|
||||
_addr = doc["addr"].as<int>();
|
||||
if (doc.containsKey("debug"))
|
||||
_debug = doc["debug"].as<int>();
|
||||
}
|
||||
}
|
||||
if (_DIR_PIN)
|
||||
{
|
||||
_DIR_PIN_ = _DIR_PIN;
|
||||
pinMode(_DIR_PIN, OUTPUT);
|
||||
digitalWrite(_DIR_PIN, LOW);
|
||||
}
|
||||
|
||||
// 0x14 – адаптер OpenTherm (вторая версия)
|
||||
// 0x15 – адаптер eBus
|
||||
// 0x16 – адаптер Navien
|
||||
uint16_t type;
|
||||
readFunctionModBus(0x0000, type);
|
||||
if (0x14 != (uint8_t)type || 0x15 != (uint8_t)type || 0x16 != (uint8_t)type)
|
||||
{
|
||||
_SerialPrint("E", "EctoControlAdapter", "Не подходящее устройство, type: " + String(type, HEX));
|
||||
}
|
||||
|
||||
uint8_t addr = node.readAddresEctoControl();
|
||||
_SerialPrint("I", "EctoControlAdapter", "readAddresEctoControl, addr: " + String(addr, HEX) + " - Enter to configuration");
|
||||
|
||||
getModelVersion();
|
||||
getBoilerInfo();
|
||||
getBoilerStatus();
|
||||
}
|
||||
|
||||
void RsEctoControl::begin(uint8_t slave, Stream &serial)
|
||||
{
|
||||
_modbusUART = &serial;
|
||||
node.begin(slave, serial);
|
||||
}
|
||||
|
||||
void RsEctoControl::initFunction(void (*publishData)(String, String), void (*sendTelegramm)(String), void (*SerialPrint)(const String &, const String &, const String &))
|
||||
{ //, const String &
|
||||
_publishData = publishData;
|
||||
_sendTelegramm = sendTelegramm;
|
||||
_SerialPrint = SerialPrint;
|
||||
};
|
||||
|
||||
void RsEctoControl::doByInterval()
|
||||
{
|
||||
// readBoilerInfo();
|
||||
getBoilerStatus();
|
||||
|
||||
getCodeError();
|
||||
getCodeErrorExt();
|
||||
if (info.adapterType == 0)
|
||||
getFlagErrorOT();
|
||||
// getFlowRate();
|
||||
// getMaxSetCH();
|
||||
// getMaxSetDHW();
|
||||
// getMinSetCH();
|
||||
// getMinSetDHW();
|
||||
getModLevel();
|
||||
getPressure();
|
||||
getTempCH();
|
||||
getTempDHW();
|
||||
getTempOutside();
|
||||
}
|
||||
|
||||
// Основной цикл программы
|
||||
void RsEctoControl::loop(bool isNetworkActive, bool mqttIsConnect)
|
||||
{
|
||||
_isNetworkActive = isNetworkActive;
|
||||
_mqttIsConnect = mqttIsConnect;
|
||||
}
|
||||
|
||||
// Исполнительные комманды
|
||||
void RsEctoControl::execute(String command, std::vector<IoTValue> ¶m)
|
||||
{
|
||||
}
|
||||
|
||||
bool RsEctoControl::writeFunctionModBus(const uint16_t ®, uint16_t &data)
|
||||
{
|
||||
// set word 0 of TX buffer to least-significant word of counter (bits 15..0)
|
||||
node.setTransmitBuffer(1, lowWord(data));
|
||||
// set word 1 of TX buffer to most-significant word of counter (bits 31..16)
|
||||
node.setTransmitBuffer(0, highWord(data));
|
||||
// slave: write TX buffer to (2) 16-bit registers starting at register 0
|
||||
uint8_t result = node.writeMultipleRegisters(0, 2);
|
||||
if (_debug > 2)
|
||||
{
|
||||
_SerialPrint("I", "EctoControlAdapter", "writeSingleRegister, addr: " + String((uint8_t)_addr, HEX) + ", reg: " + String(reg, HEX) + ", state: " + String(data) + " = result: " + String(result, HEX));
|
||||
}
|
||||
}
|
||||
|
||||
bool RsEctoControl::readFunctionModBus(const uint16_t ®, uint16_t &reading)
|
||||
{
|
||||
// float retValue = 0;
|
||||
if (_modbusUART)
|
||||
{
|
||||
// if (!addr)
|
||||
// addr = _addr;
|
||||
node.begin(_addr, (Stream &)*_modbusUART);
|
||||
uint8_t result;
|
||||
// uint32_t reading;
|
||||
|
||||
if (reg == 0x0000)
|
||||
result = node.readHoldingRegisters(reg, 4);
|
||||
else
|
||||
result = node.readHoldingRegisters(reg, 1);
|
||||
if (_debug > 2)
|
||||
_SerialPrint("I", "EctoControlAdapter", "readHoldingRegisters, addr: " + String(_addr, HEX) + ", reg: " + String(reg, HEX) + " = result: " + String(result, HEX));
|
||||
// break;
|
||||
if (result == node.ku8MBSuccess)
|
||||
{
|
||||
if (reg == 0x0000)
|
||||
{
|
||||
reading = node.getResponseBuffer(0x03);
|
||||
reading = (uint16_t)((uint8_t)(reading) >> 8);
|
||||
_SerialPrint("I", "EctoControlAdapter", "read info, addr: " + String(_addr, HEX) + ", type: " + String(reading, HEX));
|
||||
}
|
||||
else
|
||||
{
|
||||
reading = node.getResponseBuffer(0x00);
|
||||
if (_debug > 2)
|
||||
_SerialPrint("I", "EctoControlAdapter", "Success, Received data, register: " + String(reg) + " = " + String(reading, HEX));
|
||||
}
|
||||
node.clearResponseBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 2)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, Response Code: " + String(result, HEX));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reading != 0x7FFF)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RsEctoControl::getModelVersion()
|
||||
{
|
||||
uint16_t reqData;
|
||||
info.boilerMemberCode = readFunctionModBus(ReadDataEctoControl::ecR_MemberCode, info.boilerMemberCode);
|
||||
info.boilerModelCode = readFunctionModBus(ReadDataEctoControl::ecR_ModelCode, info.boilerModelCode);
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_AdaperVersion, reqData);
|
||||
info.adapterHardVer = highByte(reqData);
|
||||
info.adapterSoftVer = lowByte(reqData);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RsEctoControl::getBoilerInfo()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_AdapterInfo, reqData);
|
||||
info.adapterType = highByte(reqData) & 0xF8;
|
||||
info.boilerStatus = (highByte(reqData) >> 3) & 1u;
|
||||
info.rebootStatus = lowByte(reqData);
|
||||
if (ret)
|
||||
{
|
||||
_publishData("adapterType", String(info.adapterType));
|
||||
_publishData("boilerStatus", String(info.boilerStatus));
|
||||
_publishData("rebootStatus", String(info.rebootStatus));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getBoilerStatus()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_BoilerStatus, reqData);
|
||||
status.burnStatus = (lowByte(reqData) >> 0) & 1u;
|
||||
status.CHStatus = (lowByte(reqData) >> 1) & 1u;
|
||||
status.DHWStatus = (lowByte(reqData) >> 2) & 1u;
|
||||
if (ret)
|
||||
{
|
||||
_publishData("burnStatus", String(status.burnStatus));
|
||||
_publishData("CHStatus", String(status.CHStatus));
|
||||
_publishData("DHWStatus", String(status.DHWStatus));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getCodeError()
|
||||
{
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_CodeError, code);
|
||||
if (ret)
|
||||
{
|
||||
_publishData("codeError", String(code));
|
||||
if (codeExt)
|
||||
_sendTelegramm("EctoControlAdapter: код ошибки: " + String((int)codeExt));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getCodeErrorExt()
|
||||
{
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_CodeErrorExt, codeExt);
|
||||
if (ret)
|
||||
{
|
||||
_publishData("codeErrorExt", String(codeExt));
|
||||
if (codeExt)
|
||||
_sendTelegramm("EctoControlAdapter: код ошибки: " + String((int)codeExt));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getFlagErrorOT()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_FlagErrorOT, reqData);
|
||||
flagErr = lowByte(reqData);
|
||||
if (ret)
|
||||
{
|
||||
_publishData("flagErr", String(flagErr));
|
||||
switch (flagErr)
|
||||
{
|
||||
case 0:
|
||||
_sendTelegramm("EctoControlAdapter: Необходимо обслуживание!");
|
||||
break;
|
||||
case 1:
|
||||
_sendTelegramm("EctoControlAdapter: Котёл заблокирован!");
|
||||
break;
|
||||
case 2:
|
||||
_sendTelegramm("EctoControlAdapter: Низкое давление в отопительном контуре!");
|
||||
break;
|
||||
case 3:
|
||||
_sendTelegramm("EctoControlAdapter: Ошибка розжига!");
|
||||
break;
|
||||
case 4:
|
||||
_sendTelegramm("EctoControlAdapter: Низкое давления воздуха!");
|
||||
break;
|
||||
case 5:
|
||||
_sendTelegramm("EctoControlAdapter: Перегрев теплоносителя в контуре!");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RsEctoControl::getFlowRate()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_FlowRate, reqData);
|
||||
flow = lowByte(reqData) / 10.f;
|
||||
if (ret)
|
||||
_publishData("flowRate", String(flow));
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getMaxSetCH()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_MaxSetCH, reqData);
|
||||
maxSetCH = (float)lowByte(reqData);
|
||||
if (ret)
|
||||
_publishData("maxSetCH", String(maxSetCH));
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getMaxSetDHW()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_MaxSetDHW, reqData);
|
||||
maxSetDHW = (float)lowByte(reqData);
|
||||
if (ret)
|
||||
_publishData("maxSetDHW", String(maxSetDHW));
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getMinSetCH()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_MinSetCH, reqData);
|
||||
minSetCH = (float)lowByte(reqData);
|
||||
if (ret)
|
||||
_publishData("minSetCH", String(minSetCH));
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getMinSetDHW()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_MinSetDHW, reqData);
|
||||
minSetDHW = (float)lowByte(reqData);
|
||||
if (ret)
|
||||
_publishData("minSetDHW", String(minSetDHW));
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getModLevel()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_ModLevel, reqData);
|
||||
modLevel = (float)lowByte(reqData);
|
||||
if (ret)
|
||||
_publishData("modLevel", String(modLevel));
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getPressure()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_Pressure, reqData);
|
||||
press = lowByte(reqData) / 10.f;
|
||||
if (ret)
|
||||
_publishData("press", String(press));
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getTempCH()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_TempCH, reqData);
|
||||
tCH = reqData / 10.f;
|
||||
if (ret)
|
||||
_publishData("tCH", String(tCH));
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getTempDHW()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_TempDHW, reqData);
|
||||
tDHW = reqData / 10.f;
|
||||
if (ret)
|
||||
_publishData("tDHW", String(tDHW));
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::getTempOutside()
|
||||
{
|
||||
uint16_t reqData;
|
||||
bool ret = readFunctionModBus(ReadDataEctoControl::ecR_TempOutside, reqData);
|
||||
tOut = (float)lowByte(reqData);
|
||||
if (ret)
|
||||
_publishData("tOut", String(tOut));
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RsEctoControl::setTypeConnect(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_SetTypeConnect, (uint16_t &)data))
|
||||
{
|
||||
// TODO запросить результат записи у адаптера
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, setTypeConnect");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::setTCH(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
uint16_t d16 = data * 10;
|
||||
if (writeFunctionModBus(ecW_TSetCH, d16))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, setTCH");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::setTCHFaultConn(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
uint16_t d16 = data * 10;
|
||||
if (writeFunctionModBus(ecW_TSetCHFaultConn, d16))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, setTCHFaultConn");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::setMinCH(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_TSetMinCH, (uint16_t &)data))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, setMinCH");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::setMaxCH(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_TSetMaxCH, (uint16_t &)data))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, setMaxCH");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::setMinDHW(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_TSetMinDHW, (uint16_t &)data))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, setMinDHW");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::setMaxDHW(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_TSetMaxDHW, (uint16_t &)data))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, setMaxDHW");
|
||||
}
|
||||
}
|
||||
bool RsEctoControl::setTDHW(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_TSetDHW, (uint16_t &)data))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, setTDHW");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::setMaxModLevel(float &data)
|
||||
{
|
||||
bool ret = false;
|
||||
if (writeFunctionModBus(ecW_SetMaxModLevel, (uint16_t &)data))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, setMaxModLevel");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RsEctoControl::setStatusCH(bool data)
|
||||
{
|
||||
bool ret = false;
|
||||
enableCH = data;
|
||||
uint16_t stat = enableCH | (enableDHW << 1) | (enableCH2 << 2);
|
||||
if (writeFunctionModBus(ecW_SetStatusBoiler, stat))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, setStatusCH");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::setStatusDHW(bool data)
|
||||
{
|
||||
bool ret = false;
|
||||
enableDHW = data;
|
||||
uint16_t stat = enableCH | (enableDHW << 1) | (enableCH2 << 2);
|
||||
if (writeFunctionModBus(ecW_SetStatusBoiler, stat))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, setStatusDHW");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::setStatusCH2(bool data)
|
||||
{
|
||||
bool ret = false;
|
||||
enableCH2 = data;
|
||||
uint16_t stat = enableCH | (enableDHW << 1) | (enableCH2 << 2);
|
||||
if (writeFunctionModBus(ecW_SetStatusBoiler, stat))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, setStatusCH2");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool RsEctoControl::lockOutReset()
|
||||
{
|
||||
bool ret = false;
|
||||
uint16_t d16 = comm_LockOutReset;
|
||||
if (writeFunctionModBus(ecW_Command, d16))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, lockOutReset");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool RsEctoControl::rebootAdapter()
|
||||
{
|
||||
bool ret = false;
|
||||
uint16_t d16 = comm_RebootAdapter;
|
||||
if (writeFunctionModBus(ecW_Command, d16))
|
||||
{
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_debug > 1)
|
||||
_SerialPrint("E", "EctoControlAdapter", "Failed, rebootAdapter");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const String RsEctoControl::getChipId()
|
||||
{
|
||||
return String(ESP_getChipId()) + "-" + String(getFlashChipIdNew()); // + "v" + String(FIRMWARE_VERSION);
|
||||
}
|
||||
|
||||
uint32_t RsEctoControl::getFlashChipIdNew()
|
||||
{
|
||||
// Cache since size does not change
|
||||
static uint32_t flashChipId = 0;
|
||||
|
||||
if (flashChipId == 0)
|
||||
{
|
||||
#ifdef ESP32
|
||||
uint32_t tmp = g_rom_flashchip.device_id;
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
flashChipId = flashChipId << 8;
|
||||
flashChipId |= (tmp & 0xFF);
|
||||
tmp = tmp >> 8;
|
||||
}
|
||||
|
||||
// esp_flash_read_id(nullptr, &flashChipId);
|
||||
#elif defined(ESP8266)
|
||||
flashChipId = ESP.getFlashChipId();
|
||||
#endif // ifdef ESP32
|
||||
}
|
||||
return flashChipId;
|
||||
}
|
||||
|
||||
uint32_t RsEctoControl::ESP_getChipId(void)
|
||||
{
|
||||
#ifdef ESP32
|
||||
uint32_t id = 0;
|
||||
for (uint32_t i = 0; i < 17; i = i + 8)
|
||||
{
|
||||
id |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
|
||||
}
|
||||
return id;
|
||||
#else
|
||||
return ESP.getChipId();
|
||||
#endif
|
||||
}
|
||||
|
||||
RsEctoControl::~RsEctoControl()
|
||||
{
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "ModbusEC.h"
|
||||
#include "AdapterCommon.h"
|
||||
// #include "Stream.h"
|
||||
#include <vector>
|
||||
|
||||
struct IoTValue;
|
||||
|
||||
// static void publishData(String widget, String status);
|
||||
static void (*_publishData)(String, String);
|
||||
|
||||
// static void sendTelegramm(String msg);
|
||||
static void (*_sendTelegramm)(String);
|
||||
|
||||
static void (*_SerialPrint)(const String &, const String &, const String &); //, const String& itemId = ""
|
||||
|
||||
class RsEctoControl //: public ModbusMaster
|
||||
{
|
||||
private:
|
||||
ModbusMaster node;
|
||||
uint8_t _addr;
|
||||
uint8_t _debug;
|
||||
Stream *_modbusUART;
|
||||
|
||||
BoilerInfo info;
|
||||
BoilerStatus status;
|
||||
|
||||
uint16_t code;
|
||||
uint16_t codeExt;
|
||||
uint8_t flagErr;
|
||||
float flow;
|
||||
float maxSetCH;
|
||||
float maxSetDHW;
|
||||
float minSetCH;
|
||||
float minSetDHW;
|
||||
float modLevel;
|
||||
float press;
|
||||
float tCH;
|
||||
float tDHW;
|
||||
float tOut;
|
||||
bool enableCH;
|
||||
bool enableDHW;
|
||||
bool enableCH2;
|
||||
bool _isNetworkActive;
|
||||
bool _mqttIsConnect;
|
||||
|
||||
uint32_t getFlashChipIdNew();
|
||||
|
||||
uint32_t ESP_getChipId(void);
|
||||
|
||||
const String getChipId();
|
||||
|
||||
bool readFunctionModBus(const uint16_t ®, uint16_t &reading);
|
||||
|
||||
bool writeFunctionModBus(const uint16_t ®, uint16_t &data);
|
||||
|
||||
public:
|
||||
uint8_t _DIR_PIN;
|
||||
//=======================================================================================================
|
||||
// setup()
|
||||
RsEctoControl(String parameters); //: ModbusMaster();
|
||||
|
||||
~RsEctoControl();
|
||||
|
||||
void begin(uint8_t slave, Stream &serial);
|
||||
|
||||
static void initFunction(void (*_publishData_)(String, String), void (*_sendTelegramm_)(String), void (*_SerialPrint_)(const String &, const String &, const String &)); //, const String&
|
||||
|
||||
void doByInterval();
|
||||
|
||||
// Основной цикл программы
|
||||
void loop(bool isNetworkActive, bool mqttIsConnect);
|
||||
|
||||
// Исполнительные комманды
|
||||
void execute(String command, std::vector<IoTValue> ¶m);
|
||||
|
||||
bool getModelVersion();
|
||||
bool getBoilerInfo();
|
||||
bool getBoilerStatus();
|
||||
bool getCodeError();
|
||||
bool getCodeErrorExt();
|
||||
bool getFlagErrorOT();
|
||||
bool getFlowRate();
|
||||
bool getMaxSetCH();
|
||||
bool getMaxSetDHW();
|
||||
bool getMinSetCH();
|
||||
bool getMinSetDHW();
|
||||
bool getModLevel();
|
||||
bool getPressure();
|
||||
bool getTempCH();
|
||||
bool getTempDHW();
|
||||
bool getTempOutside();
|
||||
|
||||
bool setTypeConnect(float &data);
|
||||
bool setTCH(float &data);
|
||||
bool setTCHFaultConn(float &data);
|
||||
bool setMinCH(float &data);
|
||||
bool setMaxCH(float &data);
|
||||
bool setMinDHW(float &data);
|
||||
bool setMaxDHW(float &data);
|
||||
bool setTDHW(float &data);
|
||||
bool setMaxModLevel(float &data);
|
||||
bool setStatusCH(bool data);
|
||||
bool setStatusDHW(bool data);
|
||||
bool setStatusCH2(bool data);
|
||||
|
||||
bool lockOutReset();
|
||||
bool rebootAdapter();
|
||||
};
|
||||
Reference in New Issue
Block a user