EctoControl Opentherm

This commit is contained in:
Mit4el
2024-09-20 13:13:42 +03:00
parent 596eb9cad4
commit a1ab70fc07
9 changed files with 1030 additions and 0 deletions

View File

@@ -9,6 +9,11 @@ lib_deps_external =
[env]
extra_scripts = pre:tools/prebuildscript.py
build_flags =
; библиотека OpenTherm EctoControl Adapter
-I./src/modules/exec/EctoControlAdapter/lib
-L./src/modules/exec/EctoControlAdapter/lib
-lEctoControlAdapterLib
[env:esp8266_1mb_ota]
lib_deps =

View File

@@ -0,0 +1,273 @@
#include "Global.h"
#include "classes/IoTItem.h"
#include <map>
#include <HardwareSerial.h>
#include "rsEctoControl.h"
// class ModbusUart;
Stream *_mbUART = nullptr;
#define UART_LINE 2
// Modbus stuff
// Данные Modbus по умолчанию
#define MODBUS_RX_PIN 18 // Rx pin
#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);
// }
// ModbusMaster node;
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; // Дебаг
//uint8_t _dir_pin;
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);
if (_prot == "SERIAL_8N1")
{
protocol = SERIAL_8N1;
}
else if (_prot == "SERIAL_8N2")
{
protocol = SERIAL_8N2;
}
// Serial2.begin(baud-rate, protocol, RX pin, TX pin);
_mbUART = 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);
}
void doByInterval()
{
if (rsEC)
rsEC->doByInterval();
}
void loop()
{
if (rsEC)
rsEC->loop(isNetworkActive(), mqttIsConnect());
// для новых версий IoTManager
IoTItem::loop();
}
IoTValue execute(String command, std::vector<IoTValue> &param)
{
if (rsEC)
rsEC->execute(command, param);
else
return {};
if (command == "getModelVersion")
{
rsEC->getModelVersion();
}
if (command == "getModelVersion")
{
rsEC->getModelVersion();
}
if (command == "getBoilerInfo")
{
rsEC->getBoilerInfo();
}
if (command == "getBoilerStatus")
{
rsEC->getBoilerStatus();
}
if (command == "getCodeError")
{
rsEC->getCodeError();
}
if (command == "getCodeErrorExt")
{
rsEC->getCodeErrorExt();
}
if (command == "getFlagErrorOT")
{
rsEC->getFlagErrorOT();
}
if (command == "getFlowRate")
{
rsEC->getFlowRate();
}
if (command == "getMaxSetCH")
{
rsEC->getMaxSetCH();
}
if (command == "getMaxSetDHW")
{
rsEC->getMaxSetDHW();
}
if (command == "getMinSetCH")
{
rsEC->getMinSetCH();
}
if (command == "getMinSetDHW")
{
rsEC->getMinSetDHW();
}
if (command == "getModLevel")
{
rsEC->getModLevel();
}
if (command == "getPressure")
{
rsEC->getPressure();
}
if (command == "getTempCH")
{
rsEC->getTempCH();
}
if (command == "getTempDHW")
{
rsEC->getTempDHW();
}
if (command == "getTempOutside")
{
rsEC->getTempOutside();
}
if (command == "setTypeConnect")
{
rsEC->setTypeConnect(param[0].valD);
}
if (command == "setTCH")
{
rsEC->setTCH(param[0].valD);
}
if (command == "setTCHFaultConn")
{
rsEC->setTCHFaultConn(param[0].valD);
}
if (command == "setMinCH")
{
rsEC->setMinCH(param[0].valD);
}
if (command == "setMaxCH")
{
rsEC->setMaxCH(param[0].valD);
}
if (command == "setMinDHW")
{
rsEC->setMinDHW(param[0].valD);
}
if (command == "setMaxDHW")
{
rsEC->setMaxDHW(param[0].valD);
}
if (command == "setTDHW")
{
rsEC->setTDHW(param[0].valD);
}
if (command == "setMaxModLevel")
{
rsEC->setMaxModLevel(param[0].valD);
}
if (command == "setStatusCH")
{
rsEC->setStatusCH((bool)param[0].valD);
}
if (command == "setStatusDHW")
{
rsEC->setStatusDHW((bool)param[0].valD);
}
if (command == "setStatusCH2")
{
rsEC->setStatusCH2((bool)param[0].valD);
}
if (command == "lockOutReset")
{
rsEC->lockOutReset();
}
if (command == "rebootAdapter")
{
rsEC->rebootAdapter();
}
return {};
}
void publishData(String widget, String status)
{
IoTItem *tmp = findIoTItem(widget);
if (tmp)
tmp->setValue(status, true);
else
{
if (_debugLevel > 0)
SerialPrint("i", "NEW", widget + " = " + status);
}
}
static void sendTelegramm(String msg)
{
if (tlgrmItem)
tlgrmItem->sendTelegramMsg(false, msg);
}
~EctoControlAdapter()
{
delete rsEC;
rsEC = nullptr;
};
};
void *getAPI_EctoControlAdapter(String subtype, String param)
{
if (subtype == F("ecAdapter"))
{
return new EctoControlAdapter(param);
}
{
return nullptr;
}
}

View File

@@ -0,0 +1,182 @@
#pragma once
#include <Arduino.h>
#define comm_RebootAdapter 2u
#define comm_LockOutReset 3u
struct BoilerInfo
{
uint8_t adapterType; // тип адаптера. 000 - Opentherm 001 - eBus 010 - Navien
uint8_t boilerStatus; // состояние связи с котлом 0 - нет ответа от котла на последнюю команду 1 - есть ответ от котла на последнюю команду
uint8_t rebootStatus; // Код последней перезагрузки адаптера. 0...255 - код
uint8_t adapterHardVer; // Аппаратная версия адаптера. 0...255 - номер версии
uint8_t adapterSoftVer; // u8 Программная версия адаптера. 0...255 - номер версии
uint16_t boilerMemberCode; // 0x0021 R u16 Код производителя котла. Зависит от марки и модели котла. 0...65535 - код производителя
uint16_t boilerModelCode; // 0x0022 R u16 Код модели котла. Зависит от марки и модели котла. 0...65535 - код модели
};
struct BoilerStatus
{
uint8_t burnStatus; // бит 0 - текущее состояние горелки 0 - отключена 1 - включена
uint8_t CHStatus; // бит 1 - текущее состояние отопления 0 - отключено 1 - включено
uint8_t DHWStatus; // бит 2 - текущее состояние ГВС 0 - отключено 1 - включено
};
// Флаги ошибок (только для котлов с интерфейсом OpenTherm)
enum FlagErrorOT //: uitn8_t
{
er_SecviceReq, // 0: Необходимо обслуживание
er_LockOut, // 1: Котел заблокирован
er_LowWater, // 2: Низкое давление в отопительном контуре
er_FlameFault, // 3: Ошибка розжига
er_AirPresFault, // 4: Низкое давление воздуха
er_OverTem // 5: Перегрев теплоносителя в контуре
};
////////////////// Данные регистров второй версии адаптера котла
//////////////////// Регистры для чтения
enum ReadDataEctoControl //: uitn16_t
{
ecR_AdapterInfo = 0x0010, // 0x0010 R bitfields бит 2...0 - тип адаптера. 000 - Opentherm 001 - eBus 010 - Navien
// бит 3 - состояние связи с котлом 0 - нет ответа от котла на последнюю команду 1 - есть ответ от котла на последнюю команду
// u8 Код последней перезагрузки адаптера. 0...255 - код
ecR_AdaperVersion = 0x0011, // 0x0011 R u8 Аппаратная версия адаптера. 0...255 - номер версии
// u8 Программная версия адаптера. 0...255 - номер версии
ecR_Time = 0x0012, // 0x0012 - 0x0013 R u32 Время работы адаптера после перезагрузки 0...4294967295 - время в секундах
ecR_MinSetCH = 0x0014, // 0x0014 R u8 Нижний предел уставки теплоносителя. 0...100 - температура уставки в град. С
ecR_MaxSetCH = 0x0015, // 0x0015 R u8 Верхний предел уставки теплоносителя 0...100 - температура уставки в град. С
ecR_MinSetDHW = 0x0016, // 0x0016 R u8 Нижний предел уставки ГВС 0...100 - температура уставки в град. С
ecR_MaxSetDHW = 0x0017, // 0x0017 R u8 Верхний предел уставки ГВС 0...100 - температура уставки в град. С
ecR_TempCH = 0x0018, // 0x0018 R i16 Текущая температура теплоносителя -100...100 - температура в 0.1 гр. С
ecR_TempDHW = 0x0019, // 0x0019 R u16 Текущая температура ГВС 0...100 - температура в 0.1 гр. С
ecR_Pressure = 0x001A, // 0x001A R u8 Текущее Давление в контуре 0...50 - давление в (0,1бар)
ecR_FlowRate = 0x001B, // 0x001B R u8? Текущий расход ГВС 1...255 - расход в (0,1 л/мин)
ecR_ModLevel = 0x001C, // 0x001C R u8? Текущая модуляция горелки 0xFF - не определено 0...100 - модуляция в (%)
ecR_BoilerStatus = 0x001D, // 0x001D R bitfields бит 0 - текущее состояние горелки 0 - отключена 1 - включена
// бит 1 - текущее состояние отопления 0 - отключено 1 - включено
// бит 2 - текущее состояние ГВС 0 - отключено 1 - включено
ecR_CodeError = 0x001E, // 0x001E R u16 Код ошибки котла (основной). Зависит от марки и модели котла. 0...65535 - код ошибки
ecR_CodeErrorExt = 0x001F, // 0x001F R u16 Код ошибки котла (дополнительный). Зависит от марки и модели котла. 0...65535 - код ошибки
ecR_TempOutside = 0x0020, // 0x0020 R s8 Температура уличного датчика котла (при егоналичии). -65…+100 температура в градусах С
ecR_MemberCode = 0x0021, // 0x0021 R u16 Код производителя котла. Зависит от марки и модели котла. 0...65535 - код производителя
ecR_ModelCode = 0x0022, // 0x0022 R u16 Код модели котла. Зависит от марки и модели котла. 0...65535 - код модели
ecR_FlagErrorOT = 0x0023 // 0x0023 R s8 Флаги ошибок (только для котлов с интерфейсом OpenTherm)
// 0: Необходимо обслуживание
// 1: Котел заблокирован
// 2: Низкое давление в отопительном контуре
// 3: Ошибка розжига
// 4: Низкое давление воздуха
// 5: Перегрев теплоносителя в контуре
};
////////////////////////////// WRITE /////////////
enum WriteDataEctoControl //: uitn16_t
{
ecW_SetTypeConnect = 0x0030, // 0x0030 W u8 Тип внешних подключений (будет сохранено в постоянной памяти адаптера)
// 0 - адаптер подключен к котлу
// 1 - котел подключен к внешнему устройству (панель или перемычка)
ecW_TSetCH = 0x0031, // 0x0031 W int16 Уставка теплоносителя (будет сохранено в постоянной памяти адаптера).
// Будет передана котлу при старте адаптера, пока главным устройством не
// были записаны регистры уставки температуры.
// 0...1000 - температура уставки в десятых долях градуса С (например, для
// установки 45С нужно записать число 450). Во многих котлах необходимо до
// подключения адаптера необходимо поднять температуру теплоносителя
// отопления (нажимая “+” на панели котла) для согласования диапазона
// температуры теплоносителя, в противном случае температура теплоносителя
// может не достигнуть требуемого значения.
ecW_TSetCHFaultConn = 0x0032, // 0x0032 W int16 Уставка теплоносителя в аварийном режиме(будет сохранено в постоянной памяти адаптера).
// Будет передана котлу в случае
// отсутствия связи с главным управляющим устройством.
// 0...1000 - температура уставки в десятых долях град. С (например,
// для установки 45С нужно записать число 450)
ecW_TSetMinCH = 0x0033, // 0x0033 W u8 Нижний предел уставки теплоносителя 0...100 - температура уставки в град. С
// Не все котлы поддерживают этот параметр. Как правило, этот
// предел не должен быть ниже аналогичного предела,
// установленного в настройках котла.
ecW_TSetMaxCH = 0x0034, // 0x0034 W u8 Верхний предел уставки теплоносителя 0...100 - температура уставки в град. С
// Не все котлы поддерживают этот параметр. Как правило, этот
// предел не должен быть выше аналогичного предела,
// установленного в настройках котла.
ecW_TSetMinDHW = 0x0035, // 0x0035 W u8 Нижний предел уставки ГВС 0...100 - температура уставки в град. С
// Не все котлы поддерживают этот параметр. Как правило, этот
// предел не должен быть ниже аналогичного предела,
// установленного в настройках котла.
ecW_TSetMaxDHW = 0x0036, // 0x0036 W u8 Верхний предел уставки ГВС 0...100 - температура уставки в град. С
// Не все котлы поддерживают этот параметр. Как правило, этот
// предел не должен быть выше аналогичного предела,
// установленного в настройках котла.
ecW_TSetDHW = 0x0037, // 0x0037 W u8 Уставка ГВС (EPROM) 0...100 - температура уставки в град. С
// Для большинства котлов эта уставка должна находиться ниже
// предела, установленного в меню самого котла, иначе она может быть
// проигнорирована котлом. Для некоторых котлов стоит устанавливать
// этот параметр равным верхнему пределу уставки ГВС.
ecW_SetMaxModLevel = 0x0038, // 0x0038 W u8 Уставка максимальной модуляции горелки (будет сохранено в постоянной памяти адаптера) 0...100 - уровень модуляции в процентах.
// Данный параметр поддерживается не всеми котлами. Для
// электрических трехфазных котлов возможно задать только 3
// уровня модуляции (в диапазоне 0…100%).
ecW_SetStatusBoiler = 0x0039, // 0x0039 W bitfields бит 0 - режим контура отопления (будет сохранено в постоянной памяти адаптера) 0 - отключен 1 - включен
// бит 1 - режим контура ГВС 0 - отключен 1 - включен
// бит 2 - “второй контур”, используется только некоторыми котлами с
// интерфейсом OpenTherm и может отвечать за активацию бойлера
// косвенного нагрева или встроенной функции ГВС. 0 - отключен 1 - включен
ecW_Command = 0x0080 // 0x0080 W uint16 команда
// 0 - нет команды
// 1 - CH water filling (зарезервировано)
// 2 - перезагрузка адаптера
// 3 - сброс ошибок котла
// 4..65525 - зарезервировано
// При записи любой команды, кроме «нет команды», сразу же меняется
// состояние регистра «Ответ на команду» - становится 2 идет
// обработка команжы
};
///////////////////////////////////////// Регистры состояния:
/*
0x0040…0x006F R i16 состояние данных в регистре ($addr - 0x30)
-2 - ошибка чтения/записи в котел
-1 - регистр не поддерживается
0- для регистра на чтение означает, что данные из котла прочитаны и
валидны. Для регистра на запись означает, что данные успешно приняты
котлом.
1- не инициализирован.
если регистр R: чтение соответствующих данные из котла не
приводилось,
если регистр W: адаптеру не было задано значение для записи
соответствующего значения в котле
*/
/*
0x0081 R int16 Ответ на команду
-32768..-6 - зарезервировано
-5 ошибка выполнения команды
-4 неподдерживаемая котлом команда
-3 не поддерживаемый котлом идентификатор устройства
-2 не поддерживается данный адаптером
-1 не получен ответ за отведенное врекмя
0 команда выполнена успешно
1 не было команды (значение по умолчанию)
2 идет обработка команды (обмен данными)
3..32767 - зарезервировано
Если команда после перезагрузки адаптера не давалась, регистр
читается как 1 - не было команды.
*/

View File

@@ -0,0 +1,97 @@
#ifndef ModbusEC_h
#define ModbusEC_h
#define __MODBUSMASTER_DEBUG__ (0)
#define __MODBUSMASTER_DEBUG_PIN_A__ 4
#define __MODBUSMASTER_DEBUG_PIN_B__ 5
#include "Arduino.h"
#include "util/crc16.h"
#include "util/word.h"
/* _____CLASS DEFINITIONS____________________________________________________ */
/**
Arduino class library for communicating with Modbus slaves over
RS232/485 (via RTU protocol).
*/
class ModbusMaster
{
public:
ModbusMaster();
void begin(uint8_t, Stream &serial);
void idle(void (*)());
void preTransmission(void (*)());
void postTransmission(void (*)());
static const uint8_t ku8MBIllegalFunction = 0x01;
static const uint8_t ku8MBIllegalDataAddress = 0x02;
static const uint8_t ku8MBIllegalDataValue = 0x03;
static const uint8_t ku8MBSlaveDeviceFailure = 0x04;
static const uint8_t ku8MBSuccess = 0x00;
static const uint8_t ku8MBInvalidSlaveID = 0xE0;
static const uint8_t ku8MBInvalidFunction = 0xE1;
static const uint8_t ku8MBResponseTimedOut = 0xE2;
static const uint8_t ku8MBInvalidCRC = 0xE3;
uint16_t getResponseBuffer(uint8_t);
void clearResponseBuffer();
uint8_t setTransmitBuffer(uint8_t, uint16_t);
void clearTransmitBuffer();
void beginTransmission(uint16_t);
uint8_t requestFrom(uint16_t, uint16_t);
void sendBit(bool);
void send(uint8_t);
void send(uint16_t);
void send(uint32_t);
uint8_t available(void);
uint16_t receive(void);
uint8_t readHoldingRegisters(uint16_t, uint16_t);
uint8_t writeMultipleRegisters(uint16_t, uint16_t);
uint8_t writeMultipleRegisters();
uint8_t readAddresEctoControl();
uint8_t writeAddresEctoControl(uint8_t);
private:
Stream *_serial; ///< reference to serial port object
uint8_t _u8MBSlave; ///< Modbus slave (1..255) initialized in begin()
static const uint8_t ku8MaxBufferSize = 20; ///< size of response/transmit buffers
uint16_t _u16ReadAddress; ///< slave register from which to read
uint16_t _u16ReadQty; ///< quantity of words to read
uint16_t _u16ResponseBuffer[ku8MaxBufferSize]; ///< buffer to store Modbus slave response; read via GetResponseBuffer()
uint16_t _u16WriteAddress; ///< slave register to which to write
uint16_t _u16WriteQty; ///< quantity of words to write
uint16_t _u16TransmitBuffer[ku8MaxBufferSize]; ///< buffer containing data to transmit to Modbus slave; set via SetTransmitBuffer()
uint16_t *txBuffer; // from Wire.h -- need to clean this up Rx
uint8_t _u8TransmitBufferIndex;
uint16_t u16TransmitBufferLength;
uint16_t *rxBuffer; // from Wire.h -- need to clean this up Rx
uint8_t _u8ResponseBufferIndex;
uint8_t _u8ResponseBufferLength;
// Modbus function codes for 16 bit access
static const uint8_t ku8MBReadHoldingRegisters = 0x03; ///< Modbus function 0x03 Read Holding Registers
static const uint8_t ku8MBWriteMultipleRegisters = 0x10; ///< Modbus function 0x10 Write Multiple Registers
static const uint8_t ku8MBProgRead46 = 0x46; ///< EctoControl function 0x46 Устройство возвращает в ответе свой текущий адрес ADDR
static const uint8_t ku8MBProgWrite47 = 0x47; ///< EctoControl function 0x47 высылается ведущим устройством ведомому с указанием сменить свой имеющийся адрес на заданный
// высылается ведущим устройством единственному устройству на шине с неизвестным адресом
// Modbus timeout [milliseconds]
static const uint16_t ku16MBResponseTimeout = 2000; ///< Modbus timeout [milliseconds]
// master function that conducts Modbus transactions
uint8_t ModbusMasterTransaction(uint8_t u8MBFunction);
// idle callback function; gets called during idle time between TX and RX
void (*_idle)();
// preTransmission callback function; gets called before writing a Modbus message
void (*_preTransmission)();
// postTransmission callback function; gets called after a Modbus message has been sent
void (*_postTransmission)();
};
#endif

View File

@@ -0,0 +1,113 @@
#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;
String _license;
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;
int md = 0;
int md2 = 0;
uint32_t getFlashChipIdNew();
uint32_t ESP_getChipId(void);
const String getChipId();
bool readFunctionModBus(const uint16_t &reg, uint16_t &reading);
bool writeFunctionModBus(const uint16_t &reg, 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> &param);
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();
};

View File

@@ -0,0 +1,88 @@
/**
@file
CRC Computations
@defgroup util_crc16 "util/crc16.h": CRC Computations
@code#include "util/crc16.h"@endcode
This header file provides functions for calculating
cyclic redundancy checks (CRC) using common polynomials.
Modified by Doc Walker to be processor-independent (removed inline
assembler to allow it to compile on SAM3X8E processors).
@par References:
Jack Crenshaw's "Implementing CRCs" article in the January 1992 issue of @e
Embedded @e Systems @e Programming. This may be difficult to find, but it
explains CRC's in very clear and concise terms. Well worth the effort to
obtain a copy.
*/
/* Copyright (c) 2002, 2003, 2004 Marek Michalkiewicz
Copyright (c) 2005, 2007 Joerg Wunsch
Copyright (c) 2013 Dave Hylands
Copyright (c) 2013 Frederic Nadeau
Copyright (c) 2015 Doc Walker
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. */
#ifndef _UTIL_CRC16_H_
#define _UTIL_CRC16_H_
/** @ingroup util_crc16
Processor-independent CRC-16 calculation.
Polynomial: x^16 + x^15 + x^2 + 1 (0xA001)<br>
Initial value: 0xFFFF
This CRC is normally used in disk-drive controllers.
@param uint16_t crc (0x0000..0xFFFF)
@param uint8_t a (0x00..0xFF)
@return calculated CRC (0x0000..0xFFFF)
*/
static uint16_t crc16_update(uint16_t crc, uint8_t a)
{
int i;
crc ^= a;
for (i = 0; i < 8; ++i)
{
if (crc & 1)
crc = (crc >> 1) ^ 0xA001;
else
crc = (crc >> 1);
}
return crc;
}
#endif /* _UTIL_CRC16_H_ */

View File

@@ -0,0 +1,64 @@
/**
@file
Utility Functions for Manipulating Words
@defgroup util_word "util/word.h": Utility Functions for Manipulating Words
@code#include "util/word.h"@endcode
This header file provides utility functions for manipulating words.
*/
/*
word.h - Utility Functions for Manipulating Words
This file is part of ModbusMaster.
ModbusMaster is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ModbusMaster is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ModbusMaster. If not, see <http://www.gnu.org/licenses/>.
Written by Doc Walker (Rx)
Copyright © 2009-2015 Doc Walker <4-20ma at wvfans dot net>
*/
#ifndef _UTIL_WORD_H_
#define _UTIL_WORD_H_
/** @ingroup util_word
Return low word of a 32-bit integer.
@param uint32_t ww (0x00000000..0xFFFFFFFF)
@return low word of input (0x0000..0xFFFF)
*/
static inline uint16_t lowWord(uint32_t ww)
{
return (uint16_t) ((ww) & 0xFFFF);
}
/** @ingroup util_word
Return high word of a 32-bit integer.
@param uint32_t ww (0x00000000..0xFFFFFFFF)
@return high word of input (0x0000..0xFFFF)
*/
static inline uint16_t highWord(uint32_t ww)
{
return (uint16_t) ((ww) >> 16);
}
#endif /* _UTIL_WORD_H_ */

View File

@@ -0,0 +1,208 @@
{
"menuSection": "sensors",
"configItem": [
{
"global": 0,
"name": "ectoCtrlAdapter",
"type": "Reading",
"subtype": "ecAdapter",
"id": "ecto",
"widget": "anydataTmp",
"page": "Котёл",
"descr": "Адаптер",
"int": 60,
"addr": "0xF0",
"RX": 18,
"TX": 19,
"DIR_PIN": 4,
"baud": 9600,
"protocol": "SERIAL_8N2",
"debug": 1
}
],
"about": {
"authorName": "Mikhail Bubnov",
"authorContact": "https://t.me/Mit4bmw",
"authorGit": "https://github.com/Mit4el",
"specialThanks": "",
"moduleName": "EctoControlAdapter",
"moduleVersion": "1.0",
"usedRam": {
"esp32_4mb": 15,
"esp8266_4mb": 15
},
"subTypes": [
"ecAdapter"
],
"title": "EctoControlAdapter",
"moduleDesc": "Управление отопительным котлом через адаптер EctoControl по протоколам OpenTherm, eBUS, Navien. Посредством Modbus RTU. Разъем 4P4C: 1-Желтый(красный)+12V; 2-Белый-GND; 3-Зелёный-A; 4-Коричневый(Синий)-B",
"propInfo": {
"addr": "Адрес slav",
"int": "Количество секунд между опросами датчика.",
"RX": "Пин RX",
"TX": "Пин TX",
"DIR_PIN": "connect DR, RE pin of MAX485 to gpio, указать 0 если не нужен",
"baud": "скорость Uart",
"protocol": "Протокол Uart: SERIAL_8N1 или SERIAL_8N2",
"debug": "0 - отключить дебаг, 1 - включить вывод дебага, 2 - лог комманд, 3 - вывод modbus"
},
"funcInfo": [
{
"name": "getModelVersion",
"descr": "Запрос модели и версии адаптера и бойлера",
"params": []
},
{
"name": "getBoilerInfo",
"descr": "Запрос состояния связи с котлом, типа адаптера и код перезагрузки адаптера",
"params": []
},
{
"name": "getBoilerStatus",
"descr": "Запрос состояния контуров котла и горелки",
"params": []
},
{
"name": "getCodeError",
"descr": "Код ошибки котла (основной). Зависит от марки и модели котла.",
"params": []
},
{
"name": "getCodeErrorExt",
"descr": "Код ошибки котла (дополнительный). Зависит от марки и модели котла.",
"params": []
},
{
"name": "getFlagErrorOT",
"descr": "Стандартные флаги ошибок котла (только для котлов с интерфейсом OpenTherm)",
"params": []
},
{
"name": "getFlowRate",
"descr": "Текущий расхода ГВС",
"params": []
},
{
"name": "getMaxSetCH",
"descr": "Верхний предел уставки теплоносителя",
"params": []
},
{
"name": "getMaxSetDHW",
"descr": "Верхний предел уставки ГВС",
"params": []
},
{
"name": "getMinSetCH",
"descr": "Нижний предел уставки теплоносителя",
"params": []
},
{
"name": "getMinSetDHW",
"descr": "Нижний предел уставки ГВС",
"params": []
},
{
"name": "getModLevel",
"descr": "Текущая модуляция горелки",
"params": []
},
{
"name": "getPressure",
"descr": "Текущее Давление в контуре",
"params": []
},
{
"name": "getTempCH",
"descr": "Текущая температура теплоносителя",
"params": []
},
{
"name": "getTempDHW",
"descr": "Текущая температура ГВС",
"params": []
},
{
"name": "getTempOutside",
"descr": "Температура уличного датчика котла",
"params": []
},
{
"name": "setTypeConnect",
"descr": "Установить тип внешних подключений (сохраняется в EPROM Адаптера): 0 - адаптер подключен к котлу, 1 - котел подключен к внешнему устройству (панель или перемычка)",
"params": ["Тип подключения"]
},
{
"name": "setTCH",
"descr": "Уставка температуры теплоносителя (сохраняется в EPROM Адаптера)",
"params": ["температура передаётся до десятых градуса"]
},
{
"name": "setTDHW",
"descr": "Уставка температуры ГВС (сохраняется в EPROM Адаптера)",
"params": ["температура передаётся до десятых градуса"]
},
{
"name": "setTCHFaultConn",
"descr": "Уставка теплоносителя в аварийном режиме (сохраняется в EPROM Адаптера). Будет передана котлу в случае отсутствия связи адаптера с управляющим устройством",
"params": ["температура передаётся до десятых градуса"]
},
{
"name": "setMinCH",
"descr": "Задать нижний предел уставки теплоносителя",
"params": ["температура от 0 до 100"]
},
{
"name": "setMaxCH",
"descr": "Задать верхний предел уставки теплоносителя",
"params": ["температура от 0 до 100"]
},
{
"name": "setMinDHW",
"descr": "Задать нижний предел уставки ГВС",
"params": ["температура от 0 до 100"]
},
{
"name": "setMaxDHW",
"descr": "Задать верхний предел уставки ГВС",
"params": ["температура от 0 до 100"]
},
{
"name": "setMaxModLevel",
"descr": "Уставка максимальной модуляции горелки (сохраняется в EPROM Адаптера)",
"params": ["уровень модуляции 0-100%"]
},
{
"name": "setStatusCH",
"descr": "Установить режим (Включить) контура отопления; 0 - отключен, 1 - включен",
"params": ["вкл/откл отопления"]
},
{
"name": "setStatusDHW",
"descr": "Установить режим (Включить) ГВС; 0 - отключен, 1 - включен",
"params": ["вкл/откл ГВС"]
},
{
"name": "setStatusCH2",
"descr": "Установить режим (Включить) второго контура отопления; 0 - отключен, 1 - включен. используется только некоторыми котлами с интерфейсом OpenTherm и может отвечать за активацию бойлера косвенного нагрева или встроенной функции ГВС",
"params": ["вкл/откл второго контура отопления"]
},
{
"name": "lockOutReset",
"descr": "Сброс ошибок котла",
"params": []
},
{
"name": "rebootAdapter",
"descr": "Перезагрузка адаптера",
"params": []
}
]
},
"defActive": false,
"usedLibs": {
"esp32*": [],
"esp82*": []
}
}