From 36ea71c2706d12fcdb8685abf2ac6afc404f112c Mon Sep 17 00:00:00 2001 From: Mit4el Date: Sat, 22 Feb 2025 18:32:41 +0300 Subject: [PATCH] fix ecto modbus --- .../EctoControlAdapter/EctoControlAdapter.cpp | 1445 ++++++++--------- .../exec/EctoControlAdapter/ModbusEC.cpp | 6 +- .../exec/EctoControlAdapter/modinfo.json | 8 +- 3 files changed, 730 insertions(+), 729 deletions(-) diff --git a/src/modules/exec/EctoControlAdapter/EctoControlAdapter.cpp b/src/modules/exec/EctoControlAdapter/EctoControlAdapter.cpp index c721fa1f..c8c7e1f2 100644 --- a/src/modules/exec/EctoControlAdapter/EctoControlAdapter.cpp +++ b/src/modules/exec/EctoControlAdapter/EctoControlAdapter.cpp @@ -40,771 +40,768 @@ void modbusPostTransmission() // ModbusMaster node; -//RsEctoControl *rsEC; +// RsEctoControl *rsEC; class EctoControlAdapter : public IoTItem { private: - int _rx = MODBUS_RX_PIN; // адреса прочитаем с веба - int _tx = MODBUS_TX_PIN; - int _baud = MODBUS_SERIAL_BAUD; - String _prot = "SERIAL_8N1"; - int protocol = SERIAL_8N1; - uint8_t _addr = 0xF0; // Адрес слейва от 1 до 247 - uint8_t _type = 0x14; // Тип устройства: 0x14 – адаптер OpenTherm (вторая версия); 0x11 – адаптер OpenTherm (первая версия, снята с производства) - bool _debugLevel; // Дебаг + int _rx = MODBUS_RX_PIN; // адреса прочитаем с веба + int _tx = MODBUS_TX_PIN; + int _baud = MODBUS_SERIAL_BAUD; + String _prot = "SERIAL_8N1"; + int protocol = SERIAL_8N1; + uint8_t _addr = 0xF0; // Адрес слейва от 1 до 247 + uint8_t _type = 0x14; // Тип устройства: 0x14 – адаптер OpenTherm (вторая версия); 0x11 – адаптер OpenTherm (первая версия, снята с производства) + bool _debugLevel; // Дебаг - 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; + 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; - _addr = jsonReadInt(parameters, "addr"); // адреса slave прочитаем с веба - _rx = jsonReadInt(parameters, "RX"); // прочитаем с веба - _tx = jsonReadInt(parameters, "TX"); - _DIR_PIN = jsonReadInt(parameters, "DIR_PIN"); - _baud = jsonReadInt(parameters, "baud"); - _prot = jsonReadStr(parameters, "protocol"); - jsonRead(parameters, "debug", _debugLevel); + EctoControlAdapter(String parameters) : IoTItem(parameters) + { + _DIR_PIN = 0; + _addr = jsonReadInt(parameters, "addr"); // адреса slave прочитаем с веба + _rx = jsonReadInt(parameters, "RX"); // прочитаем с веба + _tx = jsonReadInt(parameters, "TX"); + _DIR_PIN = jsonReadInt(parameters, "DIR_PIN"); + _baud = jsonReadInt(parameters, "baud"); + _prot = jsonReadStr(parameters, "protocol"); + jsonRead(parameters, "debug", _debugLevel); - if (_prot == "SERIAL_8N1") - { - protocol = SERIAL_8N1; - } - else if (_prot == "SERIAL_8N2") - { - protocol = SERIAL_8N2; + if (_prot == "SERIAL_8N1") + { + protocol = SERIAL_8N1; + } + else if (_prot == "SERIAL_8N2") + { + protocol = SERIAL_8N2; + } + + // Serial2.begin(baud-rate, protocol, RX pin, TX pin); + + _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 *)_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 + if (_addr > 0) + { + 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)); + } + } + else if (_addr == 0) + { // если адреса нет, то шлем широковещательный запрос адреса + uint8_t addr = node.readAddresEctoControl(); + SerialPrint("I", "EctoControlAdapter", "readAddresEctoControl, addr: " + String(addr, HEX) + " - Enter to configuration"); + } + getModelVersion(); + getBoilerInfo(); + getBoilerStatus(); } - // Serial2.begin(baud-rate, protocol, RX pin, TX pin); - - _modbusUART = new HardwareSerial(UART_LINE); - - if (_debugLevel > 2) + void doByInterval() { - SerialPrint("I", "EctoControlAdapter", "baud: " + String(_baud) + ", protocol: " + String(protocol, HEX) + ", RX: " + String(_rx) + ", TX: " + String(_tx)); - } - ((HardwareSerial *)_modbusUART)->begin(_baud, protocol, _rx, _tx); // выбираем тип протокола, скорость и все пины с веба - ((HardwareSerial *)_modbusUART)->setTimeout(200); - //_modbusUART = &serial; - node.begin(_addr, _modbusUART); + // readBoilerInfo(); + getBoilerStatus(); - node.preTransmission(modbusPreTransmission); - node.postTransmission(modbusPostTransmission); - - - if (_DIR_PIN) - { - _DIR_PIN = _DIR_PIN; - pinMode(_DIR_PIN, OUTPUT); - digitalWrite(_DIR_PIN, LOW); + getCodeError(); + getCodeErrorExt(); + if (info.adapterType == 0) + getFlagErrorOT(); + // getFlowRate(); + // getMaxSetCH(); + // getMaxSetDHW(); + // getMinSetCH(); + // getMinSetDHW(); + getModLevel(); + getPressure(); + getTempCH(); + getTempDHW(); + getTempOutside(); } - // 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) + void loop() { - SerialPrint("E", "EctoControlAdapter", "Не подходящее устройство, type: " + String(type, HEX)); + // для новых версий IoTManager + IoTItem::loop(); } - uint8_t addr = node.readAddresEctoControl(); - SerialPrint("I", "EctoControlAdapter", "readAddresEctoControl, addr: " + String(addr, HEX) + " - Enter to configuration"); + IoTValue execute(String command, std::vector ¶m) + { + if (command == "getModelVersion") + { + getModelVersion(); + } + if (command == "getModelVersion") + { + getModelVersion(); + } + if (command == "getBoilerInfo") + { + getBoilerInfo(); + } + if (command == "getBoilerStatus") + { + getBoilerStatus(); + } + if (command == "getCodeError") + { + getCodeError(); + } + if (command == "getCodeErrorExt") + { + getCodeErrorExt(); + } + if (command == "getFlagErrorOT") + { + getFlagErrorOT(); + } + if (command == "getFlowRate") + { + getFlowRate(); + } + if (command == "getMaxSetCH") + { + getMaxSetCH(); + } + if (command == "getMaxSetDHW") + { + getMaxSetDHW(); + } + if (command == "getMinSetCH") + { + getMinSetCH(); + } + if (command == "getMinSetDHW") + { + getMinSetDHW(); + } + if (command == "getModLevel") + { + getModLevel(); + } + if (command == "getPressure") + { + getPressure(); + } + if (command == "getTempCH") + { + getTempCH(); + } + if (command == "getTempDHW") + { + getTempDHW(); + } + if (command == "getTempOutside") + { + getTempOutside(); + } - getModelVersion(); - getBoilerInfo(); - getBoilerStatus(); - } + if (command == "setTypeConnect") + { + setTypeConnect(param[0].valD); + } + if (command == "setTCH") + { + setTCH(param[0].valD); + } + if (command == "setTCHFaultConn") + { + setTCHFaultConn(param[0].valD); + } + if (command == "setMinCH") + { + setMinCH(param[0].valD); + } + if (command == "setMaxCH") + { + setMaxCH(param[0].valD); + } + if (command == "setMinDHW") + { + setMinDHW(param[0].valD); + } + if (command == "setMaxDHW") + { + setMaxDHW(param[0].valD); + } + if (command == "setTDHW") + { + setTDHW(param[0].valD); + } + if (command == "setMaxModLevel") + { + setMaxModLevel(param[0].valD); + } + if (command == "setStatusCH") + { + setStatusCH((bool)param[0].valD); + } + if (command == "setStatusDHW") + { + setStatusDHW((bool)param[0].valD); + } + if (command == "setStatusCH2") + { + setStatusCH2((bool)param[0].valD); + } - void doByInterval() - { - // readBoilerInfo(); - getBoilerStatus(); - - getCodeError(); - getCodeErrorExt(); - if (info.adapterType == 0) - getFlagErrorOT(); - // getFlowRate(); - // getMaxSetCH(); - // getMaxSetDHW(); - // getMinSetCH(); - // getMinSetDHW(); - getModLevel(); - getPressure(); - getTempCH(); - getTempDHW(); - getTempOutside(); - } - - void loop() - { - // для новых версий IoTManager - IoTItem::loop(); - } - - IoTValue execute(String command, std::vector ¶m) - { - if (command == "getModelVersion") - { - getModelVersion(); - } - if (command == "getModelVersion") - { - getModelVersion(); - } - if (command == "getBoilerInfo") - { - getBoilerInfo(); - } - if (command == "getBoilerStatus") - { - getBoilerStatus(); - } - if (command == "getCodeError") - { - getCodeError(); - } - if (command == "getCodeErrorExt") - { - getCodeErrorExt(); - } - if (command == "getFlagErrorOT") - { - getFlagErrorOT(); - } - if (command == "getFlowRate") - { - getFlowRate(); - } - if (command == "getMaxSetCH") - { - getMaxSetCH(); - } - if (command == "getMaxSetDHW") - { - getMaxSetDHW(); - } - if (command == "getMinSetCH") - { - getMinSetCH(); - } - if (command == "getMinSetDHW") - { - getMinSetDHW(); - } - if (command == "getModLevel") - { - getModLevel(); - } - if (command == "getPressure") - { - getPressure(); - } - if (command == "getTempCH") - { - getTempCH(); - } - if (command == "getTempDHW") - { - getTempDHW(); - } - if (command == "getTempOutside") - { - getTempOutside(); + if (command == "lockOutReset") + { + lockOutReset(); + } + if (command == "rebootAdapter") + { + rebootAdapter(); + } + return {}; } - if (command == "setTypeConnect") + void publishData(String widget, String status) { - setTypeConnect(param[0].valD); - } - if (command == "setTCH") - { - setTCH(param[0].valD); - } - if (command == "setTCHFaultConn") - { - setTCHFaultConn(param[0].valD); - } - if (command == "setMinCH") - { - setMinCH(param[0].valD); - } - if (command == "setMaxCH") - { - setMaxCH(param[0].valD); - } - if (command == "setMinDHW") - { - setMinDHW(param[0].valD); - } - if (command == "setMaxDHW") - { - setMaxDHW(param[0].valD); - } - if (command == "setTDHW") - { - setTDHW(param[0].valD); - } - if (command == "setMaxModLevel") - { - setMaxModLevel(param[0].valD); - } - if (command == "setStatusCH") - { - setStatusCH((bool)param[0].valD); - } - if (command == "setStatusDHW") - { - setStatusDHW((bool)param[0].valD); - } - if (command == "setStatusCH2") - { - setStatusCH2((bool)param[0].valD); + + IoTItem *tmp = findIoTItem(widget); + if (tmp) + tmp->setValue(status, true); + else + { + if (_debugLevel > 0) + SerialPrint("i", "NEW", widget + " = " + status); + } } - if (command == "lockOutReset") + static void sendTelegramm(String msg) { - lockOutReset(); + if (tlgrmItem) + tlgrmItem->sendTelegramMsg(false, msg); } - if (command == "rebootAdapter") + + ~EctoControlAdapter() { + }; + + bool writeFunctionModBus(const uint16_t ®, uint16_t &data) { - rebootAdapter(); + // 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; } - return {}; - } - void publishData(String widget, String status) - { - - IoTItem *tmp = findIoTItem(widget); - if (tmp) - tmp->setValue(status, true); - else + bool readFunctionModBus(const uint16_t ®, uint16_t &reading) { - if (_debugLevel > 0) - SerialPrint("i", "NEW", widget + " = " + status); + // 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; } - } - static void sendTelegramm(String msg) - { - if (tlgrmItem) - tlgrmItem->sendTelegramMsg(false, msg); - } + 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; + } - ~EctoControlAdapter() - { - }; + 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 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; - } - + 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) { - if (subtype == F("ecAdapter")) - { - return new EctoControlAdapter(param); - } - { - return nullptr; - } + if (subtype == F("ecAdapter")) + { + return new EctoControlAdapter(param); + } + { + return nullptr; + } } diff --git a/src/modules/exec/EctoControlAdapter/ModbusEC.cpp b/src/modules/exec/EctoControlAdapter/ModbusEC.cpp index 1b74d552..dd88f86c 100644 --- a/src/modules/exec/EctoControlAdapter/ModbusEC.cpp +++ b/src/modules/exec/EctoControlAdapter/ModbusEC.cpp @@ -429,8 +429,12 @@ uint8_t ModbusMaster::ModbusMasterTransaction(uint8_t u8MBFunction) if (u8ModbusADUSize == 5) { // verify response is for correct Modbus slave - if (u8ModbusADU[0] != _u8MBSlave || u8ModbusADU[0] != 0x00) + if (u8ModbusADU[0] != _u8MBSlave) { + // Serial.print(u8ModbusADU[0], HEX); + // Serial.print(" != "); + // Serial.println(_u8MBSlave, HEX); + u8MBStatus = ku8MBInvalidSlaveID; break; } diff --git a/src/modules/exec/EctoControlAdapter/modinfo.json b/src/modules/exec/EctoControlAdapter/modinfo.json index 01c3c690..459168cd 100644 --- a/src/modules/exec/EctoControlAdapter/modinfo.json +++ b/src/modules/exec/EctoControlAdapter/modinfo.json @@ -11,12 +11,12 @@ "page": "Котёл", "descr": "Адаптер", "int": 60, - "addr": "0xF0", + "addr": 240, "RX": 18, "TX": 19, "DIR_PIN": 4, - "baud": 9600, - "protocol": "SERIAL_8N2", + "baud": 19200, + "protocol": "SERIAL_8N1", "debug": 1 } ], @@ -37,7 +37,7 @@ "title": "EctoControlAdapter", "moduleDesc": "Управление отопительным котлом через адаптер EctoControl по протоколам OpenTherm, eBUS, Navien. Посредством Modbus RTU. Разъем 4P4C: 1-Желтый(красный)+12V; 2-Белый-GND; 3-Зелёный-A; 4-Коричневый(Синий)-B", "propInfo": { - "addr": "Адрес slave", + "addr": "Адрес slave, что бы узнать адрес - в конфиге адрес 0 и смотреть лог (требуется проверка)", "int": "Количество секунд между опросами датчика.", "RX": "Пин RX", "TX": "Пин TX",