mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 22:22:16 +03:00
Merge pull request #258 from avaksru/ver4stable
Добавлены модули Термостат и NextionUpload
This commit is contained in:
@@ -225,6 +225,10 @@
|
||||
{
|
||||
"path": "src/modules/exec/TelegramLT",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/exec/Thermostat",
|
||||
"active": false
|
||||
}
|
||||
],
|
||||
"Экраны": [
|
||||
@@ -232,6 +236,10 @@
|
||||
"path": "src/modules/display/Lcd2004",
|
||||
"active": true
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/NextionUpload",
|
||||
"active": false
|
||||
},
|
||||
{
|
||||
"path": "src/modules/display/Ws2812b",
|
||||
"active": false
|
||||
|
||||
117
src/modules/display/NextionUpload/NextionUpload.cpp
Normal file
117
src/modules/display/NextionUpload/NextionUpload.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
|
||||
#define DEBUG_SERIAL_ENABLE
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
#include "ESPNexUpload.h"
|
||||
bool updated = false;
|
||||
// const char *host = "live-control.com";
|
||||
// const char *url = "/iotm/Live-Control.tft";
|
||||
extern IoTGpio IoTgpio;
|
||||
|
||||
class NextionUpload : public IoTItem
|
||||
{
|
||||
private:
|
||||
String _url;
|
||||
String _host;
|
||||
int _NEXT_RX;
|
||||
int _NEXT_TX;
|
||||
|
||||
public:
|
||||
NextionUpload(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
_url = jsonReadStr(parameters, "url");
|
||||
_host = jsonReadStr(parameters, "host");
|
||||
|
||||
_NEXT_RX = jsonReadInt(parameters, "NEXT_RX");
|
||||
_NEXT_TX = jsonReadInt(parameters, "NEXT_TX");
|
||||
#define NEXT_RX _NEXT_RX // Nextion RX pin | Default 16
|
||||
#define NEXT_TX _NEXT_TX // Nextion TX pin | Default 17
|
||||
}
|
||||
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m)
|
||||
{
|
||||
|
||||
if (command == "Update")
|
||||
{
|
||||
SerialPrint("I", F("NextionUpdate"), "Update .... ");
|
||||
|
||||
if (!updated)
|
||||
{
|
||||
SerialPrint("I", F("NextionUpdate"), "connecting to " + (String)_host);
|
||||
HTTPClient http;
|
||||
|
||||
#if defined ESP8266
|
||||
if (!http.begin(_host, 80, _url))
|
||||
{
|
||||
#elif defined ESP32
|
||||
if (!http.begin(String("http://") + _host + _url))
|
||||
{
|
||||
#endif
|
||||
// Serial.println("connection failed");
|
||||
SerialPrint("I", F("NextionUpdate"), "connection failed ");
|
||||
}
|
||||
|
||||
SerialPrint("I", F("NextionUpdate"), "Requesting file: " + (String)_url);
|
||||
int code = http.GET();
|
||||
int contentLength = http.getSize();
|
||||
|
||||
// Update the nextion display
|
||||
if (code == 200)
|
||||
{
|
||||
SerialPrint("I", F("NextionUpdate"), "File received. Update Nextion... ");
|
||||
bool result;
|
||||
ESPNexUpload nextion(115200);
|
||||
nextion.setUpdateProgressCallback([]()
|
||||
{ SerialPrint("I", F("NextionUpdate"), "... "); });
|
||||
|
||||
result = nextion.prepareUpload(contentLength);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
SerialPrint("I", F("NextionUpdate"), "Error: " + (String)nextion.statusMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
SerialPrint("I", F("NextionUpdate"), "Start upload. File size is: " + (String)contentLength);
|
||||
result = nextion.upload(*http.getStreamPtr());
|
||||
|
||||
if (result)
|
||||
{
|
||||
updated = true;
|
||||
SerialPrint("I", F("NextionUpdate"), "Succesfully updated Nextion! ");
|
||||
}
|
||||
else
|
||||
{
|
||||
SerialPrint("I", F("NextionUpdate"), "Error updating Nextion: " + (String)nextion.statusMessage);
|
||||
}
|
||||
|
||||
nextion.end();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SerialPrint("I", F("NextionUpdate"), "HTTP error: " + (String)http.errorToString(code).c_str());
|
||||
}
|
||||
|
||||
http.end();
|
||||
SerialPrint("I", F("NextionUpdate"), "Closing connection ");
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
~NextionUpload(){};
|
||||
};
|
||||
|
||||
void *getAPI_NextionUpload(String subtype, String param)
|
||||
{
|
||||
if (subtype == F("NextionUpload"))
|
||||
{
|
||||
return new NextionUpload(param);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
50
src/modules/display/NextionUpload/modinfo.json
Normal file
50
src/modules/display/NextionUpload/modinfo.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"menuSection": "Экраны",
|
||||
|
||||
"configItem": [
|
||||
{
|
||||
"global": 0,
|
||||
"name": "Nextion Uploud",
|
||||
"type": "Reading",
|
||||
"subtype": "NextionUpload",
|
||||
"id": "Nextion",
|
||||
"widget": "",
|
||||
"page": "",
|
||||
"descr": "",
|
||||
"host": "192.168.1.10",
|
||||
"url": "castom_nextion.tif",
|
||||
"NEXT_TX": 16,
|
||||
"NEXT_RX": 17
|
||||
}
|
||||
],
|
||||
|
||||
"about": {
|
||||
"authorName": "AVAKS",
|
||||
"authorContact": "https://t.me/@avaks_dev",
|
||||
"authorGit": "https://github.com/avaksru",
|
||||
"specialThanks": "",
|
||||
"moduleName": "NextionUpload",
|
||||
"moduleVersion": "1.0",
|
||||
"usedRam": {
|
||||
"esp32_4mb": 15,
|
||||
"esp8266_4mb": 15
|
||||
},
|
||||
"title": "Nextion Upload",
|
||||
"moduleDesc": "загрузка прошивки в дисплей Nextion. Команда для запуска обновления дисплея: Nextion.Update(); ",
|
||||
"propInfo": {
|
||||
"host": "Сервер обновления",
|
||||
"url": "файл прошивки"
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": false,
|
||||
|
||||
"usedLibs": {
|
||||
"esp32_4mb": ["https://github.com/avaksru/ESPNexUpload.git"],
|
||||
"esp8266_4mb": ["https://github.com/avaksru/ESPNexUpload.git"],
|
||||
"esp8266_1mb": ["https://github.com/avaksru/ESPNexUpload.git"],
|
||||
"esp8266_1mb_ota": ["https://github.com/avaksru/ESPNexUpload.git"],
|
||||
"esp8285_1mb": ["https://github.com/avaksru/ESPNexUpload.git"],
|
||||
"esp8285_1mb_ota": ["https://github.com/avaksru/ESPNexUpload.git"]
|
||||
}
|
||||
}
|
||||
471
src/modules/exec/Thermostat/Thermostat.cpp
Normal file
471
src/modules/exec/Thermostat/Thermostat.cpp
Normal file
@@ -0,0 +1,471 @@
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
extern IoTGpio IoTgpio;
|
||||
|
||||
class ThermostatGIST : public IoTItem
|
||||
{
|
||||
private:
|
||||
String _set_id; // заданная температура
|
||||
String _term_id; // термометр
|
||||
String _term_rezerv_id; // резервный термометр
|
||||
String _rele; // реле
|
||||
float pv_last = 0; // предыдущая температура
|
||||
float _gist = 1; // гистерис
|
||||
float sp, pv, pv2;
|
||||
String interim;
|
||||
int enable = 1;
|
||||
|
||||
public:
|
||||
ThermostatGIST(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
jsonRead(parameters, "set_id", _set_id);
|
||||
jsonRead(parameters, "term_id", _term_id);
|
||||
jsonRead(parameters, "term_rezerv_id", _term_rezerv_id);
|
||||
jsonRead(parameters, "gist", _gist);
|
||||
jsonRead(parameters, "rele", _rele);
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
// заданная температура
|
||||
IoTItem *tmp = findIoTItem(_set_id);
|
||||
if (tmp)
|
||||
{
|
||||
interim = tmp->getValue();
|
||||
sp = ::atof(interim.c_str());
|
||||
}
|
||||
// термометр
|
||||
tmp = findIoTItem(_term_id);
|
||||
if (tmp)
|
||||
{
|
||||
interim = tmp->getValue();
|
||||
pv = ::atof(interim.c_str());
|
||||
}
|
||||
if (sp && _rele != "")
|
||||
{
|
||||
if (pv > -40 && pv < 120 && pv)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
setValue("штатный режим");
|
||||
}
|
||||
// работаем по основному датчику
|
||||
if (pv >= sp + _gist && enable)
|
||||
{
|
||||
tmp = findIoTItem(_rele);
|
||||
if (tmp)
|
||||
tmp->setValue("0", true);
|
||||
}
|
||||
if (pv <= sp - _gist && enable)
|
||||
{
|
||||
tmp = findIoTItem(_rele);
|
||||
if (tmp)
|
||||
tmp->setValue("1", true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// резервный термометр
|
||||
if (_term_rezerv_id != "")
|
||||
{
|
||||
tmp = findIoTItem(_term_rezerv_id);
|
||||
if (tmp)
|
||||
{
|
||||
interim = tmp->getValue();
|
||||
pv2 = ::atof(interim.c_str());
|
||||
}
|
||||
// работаем по резервному датчику
|
||||
if (pv2 > -40 && pv2 < 120 && pv2)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
setValue("резервный датчик");
|
||||
}
|
||||
if (pv2 >= sp + _gist && enable)
|
||||
{
|
||||
tmp = findIoTItem(_rele);
|
||||
if (tmp)
|
||||
tmp->setValue("0", true);
|
||||
}
|
||||
if (pv2 <= sp - _gist && enable)
|
||||
{
|
||||
tmp = findIoTItem(_rele);
|
||||
if (tmp)
|
||||
tmp->setValue("1", true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
setValue("ошибка резервного датчика");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
setValue("ошибка датчика температуры");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// если не заполнены настройки термостата
|
||||
setValue("ошибка настройки термостата");
|
||||
}
|
||||
|
||||
pv_last = pv;
|
||||
}
|
||||
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m)
|
||||
{
|
||||
if (param.size() == 1)
|
||||
{
|
||||
if (command == "enable")
|
||||
{
|
||||
if (param.size())
|
||||
{
|
||||
enable = param[0].valD;
|
||||
if (enable)
|
||||
{
|
||||
setValue("включен");
|
||||
}
|
||||
else
|
||||
{
|
||||
setValue("выключен");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
~ThermostatGIST(){};
|
||||
};
|
||||
|
||||
class ThermostatPID : public IoTItem
|
||||
{
|
||||
private:
|
||||
String _set_id; // заданная температура
|
||||
String _term_id; // термометр
|
||||
float _int, _KP, _KI, _KD, sp, pv,
|
||||
pv_last = 0, // предыдущая температура
|
||||
ierr = 0, // интегральная погрешность
|
||||
dt = 0; // время между измерениями
|
||||
String _rele; // реле
|
||||
String interim;
|
||||
int enable = 1;
|
||||
long interval;
|
||||
IoTItem *tmp;
|
||||
int releState = 0;
|
||||
|
||||
public:
|
||||
ThermostatPID(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
jsonRead(parameters, "set_id", _set_id);
|
||||
jsonRead(parameters, "term_id", _term_id);
|
||||
jsonRead(parameters, "int", _int);
|
||||
jsonRead(parameters, "KP", _KP);
|
||||
jsonRead(parameters, "KI", _KI);
|
||||
jsonRead(parameters, "KD", _KD);
|
||||
jsonRead(parameters, F("int"), interval);
|
||||
interval = interval * 1000; // интервал проверки в сек
|
||||
jsonRead(parameters, "rele", _rele);
|
||||
}
|
||||
|
||||
protected:
|
||||
//===============================================================
|
||||
// Вычисляем температуру контура отпления, коэффициенты ПИД регулятора
|
||||
//===============================================================
|
||||
float pid(float sp, float pv, float pv_last, float &ierr, float dt)
|
||||
{
|
||||
float Kc = _KP; // K / %Heater 5
|
||||
float tauI = _KI; // sec 50
|
||||
float tauD = _KD; // sec 1
|
||||
// ПИД коэффициенты
|
||||
float KP = Kc; // 5
|
||||
if (tauI == 0)
|
||||
{
|
||||
tauI = 50;
|
||||
}
|
||||
float KI = Kc / tauI; // 0.1
|
||||
float KD = Kc * tauD; // 5
|
||||
// верхняя и нижняя границы уровня нагрева
|
||||
float ophi = 100;
|
||||
float oplo = 0;
|
||||
// вычислить ошибку
|
||||
float error = sp - pv; // 0
|
||||
// calculate the integral error
|
||||
ierr = ierr + KI * error * dt; // 0
|
||||
// вычислить производную измерения
|
||||
float dpv = (pv - pv_last) / dt; // 0
|
||||
// рассчитать выход ПИД регулятора
|
||||
float P = KP * error; // пропорциональная составляющая
|
||||
float I = ierr; // интегральная составляющая
|
||||
float D = -KD * dpv; // дифференциальная составляющая
|
||||
float op = P + I + D;
|
||||
// защита от сброса
|
||||
if ((op < oplo) || (op > ophi))
|
||||
{
|
||||
I = I - KI * error * dt;
|
||||
// выход регулятора, он же уставка для ID-1 (температура теплоносителя контура СО котла)
|
||||
op = constrain(op, oplo, ophi);
|
||||
}
|
||||
|
||||
ierr = I;
|
||||
return op;
|
||||
}
|
||||
|
||||
void
|
||||
doByInterval()
|
||||
{
|
||||
// заданная температура
|
||||
IoTItem *tmp = findIoTItem(_set_id);
|
||||
if (tmp)
|
||||
{
|
||||
interim = tmp->getValue();
|
||||
sp = ::atof(interim.c_str());
|
||||
}
|
||||
// термометр
|
||||
tmp = findIoTItem(_term_id);
|
||||
if (tmp)
|
||||
{
|
||||
interim = tmp->getValue();
|
||||
pv = ::atof(interim.c_str());
|
||||
}
|
||||
if (sp && pv)
|
||||
{
|
||||
value.valD = pid(sp, pv, pv_last, ierr, _int);
|
||||
value.valS = (String)(int)pid(sp, pv, pv_last, ierr, _int);
|
||||
regEvent(value.valS, "ThermostatPID", false, true);
|
||||
}
|
||||
pv_last = pv;
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (enableDoByInt)
|
||||
{
|
||||
currentMillis = millis();
|
||||
difference = currentMillis - prevMillis;
|
||||
|
||||
if (_rele != "" && enable && value.valD * interval / 100000 > difference / 1000 && releState == 0)
|
||||
{
|
||||
releState = 1;
|
||||
tmp = findIoTItem(_rele);
|
||||
if (tmp)
|
||||
tmp->setValue("1", true);
|
||||
}
|
||||
if (_rele != "" && enable && value.valD * interval / 100000 < difference / 1000 && releState == 1)
|
||||
{
|
||||
releState = 0;
|
||||
tmp = findIoTItem(_rele);
|
||||
if (tmp)
|
||||
tmp->setValue("0", true);
|
||||
}
|
||||
|
||||
if (difference >= interval)
|
||||
{
|
||||
prevMillis = millis();
|
||||
this->doByInterval();
|
||||
}
|
||||
}
|
||||
}
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m)
|
||||
{
|
||||
if (param.size() == 1)
|
||||
{
|
||||
if (command == "enable")
|
||||
{
|
||||
if (param.size())
|
||||
{
|
||||
enable = param[0].valD;
|
||||
}
|
||||
}
|
||||
if (command == "KP")
|
||||
{
|
||||
if (param.size())
|
||||
{
|
||||
_KP = param[0].valD;
|
||||
}
|
||||
}
|
||||
if (command == "KI")
|
||||
{
|
||||
if (param.size())
|
||||
{
|
||||
_KI = param[0].valD;
|
||||
}
|
||||
}
|
||||
if (command == "KD")
|
||||
{
|
||||
if (param.size())
|
||||
{
|
||||
_KD = param[0].valD;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
~ThermostatPID(){};
|
||||
};
|
||||
|
||||
class ThermostatETK : public IoTItem
|
||||
{
|
||||
private:
|
||||
float pv, sp, outside_temp;
|
||||
float _iv_k; // эквитермические кривые
|
||||
String _set_id; // заданная температура
|
||||
String _term_id; // термометр
|
||||
String _outside_id; // уличный термометр
|
||||
String interim;
|
||||
int enable = 1;
|
||||
|
||||
public:
|
||||
ThermostatETK(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
jsonRead(parameters, "set_id", _set_id);
|
||||
jsonRead(parameters, "term_id", _term_id);
|
||||
jsonRead(parameters, "iv_k", _iv_k);
|
||||
jsonRead(parameters, "outside_id", _outside_id);
|
||||
}
|
||||
|
||||
protected:
|
||||
//===================================================================================================================
|
||||
// Вычисляем температуру контура отпления, эквитермические кривые
|
||||
//===================================================================================================================
|
||||
float curve(float iv_k, float outside_temp)
|
||||
{
|
||||
float a = (-0.21 * iv_k) - 0.06; // a = -0,21k — 0,06
|
||||
float b = (6.04 * iv_k) + 1.98; // b = 6,04k + 1,98
|
||||
float c = (-5.06 * iv_k) + 18.06; // с = -5,06k + 18,06
|
||||
float x = (-0.2 * outside_temp) + 5; // x = -0.2*t1 + 5
|
||||
float temp_n = (a * x * x) + (b * x) + c; // Tn = ax2 + bx + c
|
||||
// Расчетная температура конура отопления
|
||||
float op = temp_n; // T = Tn
|
||||
// Ограничиваем температуру для ID-1
|
||||
op = constrain(op, 0, 100);
|
||||
return op;
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
// уличный термометр
|
||||
IoTItem *tmp = findIoTItem(_outside_id);
|
||||
if (tmp)
|
||||
{
|
||||
interim = tmp->getValue();
|
||||
outside_temp = ::atof(interim.c_str());
|
||||
}
|
||||
if (_iv_k && outside_temp)
|
||||
{
|
||||
|
||||
value.valD = curve(_iv_k, outside_temp);
|
||||
regEvent(value.valD, "ThermostatETK");
|
||||
}
|
||||
}
|
||||
|
||||
~ThermostatETK(){};
|
||||
};
|
||||
|
||||
class ThermostatETK2 : public IoTItem
|
||||
{
|
||||
private:
|
||||
float pv, sp, outside_temp;
|
||||
float _iv_k; // эквитермические кривые
|
||||
String _set_id; // заданная температура
|
||||
String _term_id; // термометр
|
||||
String _outside_id; // уличный термометр
|
||||
String interim;
|
||||
int enable = 1;
|
||||
|
||||
public:
|
||||
ThermostatETK2(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
jsonRead(parameters, "set_id", _set_id);
|
||||
jsonRead(parameters, "term_id", _term_id);
|
||||
jsonRead(parameters, "iv_k", _iv_k);
|
||||
jsonRead(parameters, "outside_id", _outside_id);
|
||||
}
|
||||
|
||||
protected:
|
||||
//===================================================================================================================
|
||||
// Вычисляем температуру контура отпления, эквитермические кривые с учётом влияния температуры в помещении
|
||||
//===================================================================================================================
|
||||
float curve2(float sp, float pv, float iv_k, float outside_temp)
|
||||
{
|
||||
// Расчет поправки (ошибки) термостата
|
||||
float error = sp - pv; // Tt = (Tu — T2) × 5
|
||||
float temp_t = error * 3.0;
|
||||
// Поправка на желаемую комнатную температуру
|
||||
// Температура контура отопления в зависимости от наружной температуры
|
||||
float a = (-0.21 * iv_k) - 0.06; // a = -0,21k — 0,06
|
||||
float b = (6.04 * iv_k) + 1.98; // b = 6,04k + 1,98
|
||||
float c = (-5.06 * iv_k) + 18.06; // с = -5,06k + 18,06
|
||||
float x = (-0.2 * outside_temp) + 5; // x = -0.2*t1 + 5
|
||||
float temp_n = (a * x * x) + (b * x) + c; // Tn = ax2 + bx + c
|
||||
// Расчетная температура конура отопления
|
||||
float op = temp_n + temp_t; // T = Tn + Tk + Tt
|
||||
// Ограничиваем температуру для ID-1
|
||||
op = constrain(op, 0, 100);
|
||||
return op;
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
// заданная температура
|
||||
IoTItem *tmp = findIoTItem(_set_id);
|
||||
if (tmp)
|
||||
{
|
||||
interim = tmp->getValue();
|
||||
sp = ::atof(interim.c_str());
|
||||
}
|
||||
// термометр
|
||||
tmp = findIoTItem(_term_id);
|
||||
if (tmp)
|
||||
{
|
||||
interim = tmp->getValue();
|
||||
pv = ::atof(interim.c_str());
|
||||
}
|
||||
// уличный термометр
|
||||
tmp = findIoTItem(_outside_id);
|
||||
if (tmp)
|
||||
{
|
||||
interim = tmp->getValue();
|
||||
outside_temp = ::atof(interim.c_str());
|
||||
}
|
||||
if (sp && pv && _iv_k && outside_temp)
|
||||
{
|
||||
value.valD = curve2(sp, pv, _iv_k, outside_temp);
|
||||
regEvent(value.valD, "ThermostatETK2");
|
||||
}
|
||||
}
|
||||
|
||||
~ThermostatETK2(){};
|
||||
};
|
||||
|
||||
void *getAPI_Thermostat(String subtype, String param)
|
||||
{
|
||||
if (subtype == F("ThermostatGIST"))
|
||||
{
|
||||
return new ThermostatGIST(param);
|
||||
}
|
||||
else if (subtype == F("ThermostatPID"))
|
||||
{
|
||||
return new ThermostatPID(param);
|
||||
}
|
||||
else if (subtype == F("ThermostatETK"))
|
||||
{
|
||||
return new ThermostatETK(param);
|
||||
}
|
||||
else if (subtype == F("ThermostatETK2"))
|
||||
{
|
||||
return new ThermostatETK2(param);
|
||||
}
|
||||
//}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
139
src/modules/exec/Thermostat/modinfo.json
Normal file
139
src/modules/exec/Thermostat/modinfo.json
Normal file
@@ -0,0 +1,139 @@
|
||||
{
|
||||
"menuSection": "Исполнительные устройства",
|
||||
|
||||
"configItem": [
|
||||
{
|
||||
"global": 0,
|
||||
"needSave": 0,
|
||||
"name": "Термостат Гистере́зис ",
|
||||
"type": "Writing",
|
||||
"subtype": "ThermostatGIST",
|
||||
"id": "Thermo",
|
||||
"widget": "anydataDef",
|
||||
"page": "Климат",
|
||||
"descr": "термостат",
|
||||
"int": 60,
|
||||
"round": 1,
|
||||
"set_id": "",
|
||||
"term_id": "",
|
||||
"term_rezerv_id": "",
|
||||
"gist": 0.3,
|
||||
"rele": ""
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"needSave": 0,
|
||||
"name": "Термостат PID",
|
||||
"type": "Writing",
|
||||
"subtype": "ThermostatPID",
|
||||
"id": "Thermo",
|
||||
"widget": "anydataHum",
|
||||
"page": "Климат",
|
||||
"descr": "термостат",
|
||||
"int": 60,
|
||||
"round": 1,
|
||||
"map": "1,100,1,100",
|
||||
"set_id": "",
|
||||
"term_id": "",
|
||||
"rele": "",
|
||||
"KP": 5.0,
|
||||
"KI": 50,
|
||||
"KD": 1.0
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"needSave": 0,
|
||||
"name": "Термостат ЭТК",
|
||||
"type": "Writing",
|
||||
"subtype": "ThermostatETK",
|
||||
"id": "Thermo",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Климат",
|
||||
"descr": "термостат",
|
||||
"int": 60,
|
||||
"round": 1,
|
||||
"iv_k": 1,
|
||||
"outside_id": ""
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"needSave": 0,
|
||||
"name": "Термостат ЭТК2 ",
|
||||
"type": "Writing",
|
||||
"subtype": "ThermostatETK2",
|
||||
"id": "Thermo",
|
||||
"widget": "anydataTmp",
|
||||
"page": "Климат",
|
||||
"descr": "термостат",
|
||||
"int": 60,
|
||||
"round": 1,
|
||||
"set_id": "",
|
||||
"term_id": "",
|
||||
"iv_k": 1,
|
||||
"outside_id": ""
|
||||
}
|
||||
],
|
||||
|
||||
"about": {
|
||||
"authorName": "AVAKS",
|
||||
"authorContact": "https://t.me/@avaks_dev",
|
||||
"authorGit": "https://github.com/avaksru",
|
||||
"specialThanks": "@Serghei63 за работу PID с обычным реле, Serg помощь в тестировании и устранении ошибок",
|
||||
"moduleName": "Thermostat",
|
||||
"moduleVersion": "1",
|
||||
"usedRam": {
|
||||
"esp32_4mb": 15,
|
||||
"esp8266_4mb": 15
|
||||
},
|
||||
"title": "Термостат",
|
||||
"moduleDesc": "Реализованы четыре варианта термостатирования: PID , Гистере́зис , эквитермические кривые, эквитермические кривые с учётом температуры в помещении",
|
||||
"propInfo": {
|
||||
"set_id": "Заданная температура в помещении",
|
||||
"gist": "Гистере́зис - отклонение от заданной температуры при котором будет срабатывать термостат",
|
||||
"term_id": "ID виджета термометра в помещении",
|
||||
"term_rezerv_id": "ID резервного термометра в помещении",
|
||||
"rele": "ID реле термостата",
|
||||
"int": "интервал дискретизации термостата",
|
||||
"outside_id": "ID уличного термометра",
|
||||
"iv_k": "Эквитермическая кривая",
|
||||
"KP": "Пропорциональный коэффициент PID ",
|
||||
"KI": "Интегральный коэффициент PID ",
|
||||
"KD": "Дифференциальный коэффициент PID ",
|
||||
"round": "округление",
|
||||
"map": "преобразование интервала значений"
|
||||
},
|
||||
"funcInfo": [
|
||||
{
|
||||
"name": "enable",
|
||||
"descr": "включить / выключить термостатирование (режим AUTO) применим к PID и Гистере́зис ",
|
||||
"params": ["thermostat.enable(1) - вкл, thermostat.enable(0) - выкл, "]
|
||||
},
|
||||
{
|
||||
"name": "KP",
|
||||
"descr": "Пропорциональный коэффициент PID .",
|
||||
"params": ["thermostat.KP(1) - задает значение коэффициента"]
|
||||
},
|
||||
{
|
||||
"name": "KI",
|
||||
"descr": "Интегральный коэффициент PID .",
|
||||
"params": ["thermostat.KI(1) - задает значение коэффициента"]
|
||||
},
|
||||
{
|
||||
"name": "KD",
|
||||
"descr": "Дифференциальный коэффициент PID .",
|
||||
"params": ["thermostat.KD(1) - задает значение коэффициента"]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
"defActive": false,
|
||||
|
||||
"usedLibs": {
|
||||
"esp32_4mb": [],
|
||||
"esp8266_4mb": [],
|
||||
"esp8266_1mb": [],
|
||||
"esp8266_1mb_ota": [],
|
||||
"esp8285_1mb": [],
|
||||
"esp8285_1mb_ota": []
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user