mirror of
https://github.com/Laxilef/OTGateway.git
synced 2025-12-26 18:13:36 +05:00
Compare commits
9 Commits
1.5.2
...
fe93c00204
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe93c00204 | ||
|
|
05a2d080be | ||
|
|
664bd7938c | ||
|
|
a78f35328f | ||
|
|
eab47af0e1 | ||
|
|
c524abd959 | ||
|
|
666786fd65 | ||
|
|
8475833dce | ||
|
|
afe710abd3 |
@@ -210,6 +210,7 @@ build_flags =
|
|||||||
${esp32_defaults.build_flags}
|
${esp32_defaults.build_flags}
|
||||||
-D ARDUINO_USB_MODE=0
|
-D ARDUINO_USB_MODE=0
|
||||||
-D ARDUINO_USB_CDC_ON_BOOT=1
|
-D ARDUINO_USB_CDC_ON_BOOT=1
|
||||||
|
-D CONFIG_BT_NIMBLE_EXT_ADV=1
|
||||||
-D USE_BLE=1
|
-D USE_BLE=1
|
||||||
-D DEFAULT_OT_IN_GPIO=35
|
-D DEFAULT_OT_IN_GPIO=35
|
||||||
-D DEFAULT_OT_OUT_GPIO=36
|
-D DEFAULT_OT_OUT_GPIO=36
|
||||||
@@ -233,6 +234,7 @@ build_unflags =
|
|||||||
build_type = ${esp32_defaults.build_type}
|
build_type = ${esp32_defaults.build_type}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_defaults.build_flags}
|
${esp32_defaults.build_flags}
|
||||||
|
-D CONFIG_BT_NIMBLE_EXT_ADV=1
|
||||||
-D USE_BLE=1
|
-D USE_BLE=1
|
||||||
-D DEFAULT_OT_IN_GPIO=8
|
-D DEFAULT_OT_IN_GPIO=8
|
||||||
-D DEFAULT_OT_OUT_GPIO=10
|
-D DEFAULT_OT_OUT_GPIO=10
|
||||||
@@ -316,6 +318,7 @@ build_unflags =
|
|||||||
build_type = ${esp32_defaults.build_type}
|
build_type = ${esp32_defaults.build_type}
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32_defaults.build_flags}
|
${esp32_defaults.build_flags}
|
||||||
|
-D CONFIG_BT_NIMBLE_EXT_ADV=1
|
||||||
-D USE_BLE=1
|
-D USE_BLE=1
|
||||||
-D DEFAULT_OT_IN_GPIO=3
|
-D DEFAULT_OT_IN_GPIO=3
|
||||||
-D DEFAULT_OT_OUT_GPIO=1
|
-D DEFAULT_OT_OUT_GPIO=1
|
||||||
|
|||||||
@@ -1062,7 +1062,10 @@ protected:
|
|||||||
);
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log.swarningln(FPSTR(L_OT_HEATING), F("Failed set max heating temp"));
|
Log.swarningln(
|
||||||
|
FPSTR(L_OT_HEATING), F("Failed set max heating temp: %.2f (converted: %.2f)"),
|
||||||
|
vars.master.heating.setpointTemp, convertedTemp
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -196,6 +196,7 @@ protected:
|
|||||||
//if (vars.parameters.heatingEnabled) {
|
//if (vars.parameters.heatingEnabled) {
|
||||||
if (settings.heating.enabled && this->indoorSensorsConnected) {
|
if (settings.heating.enabled && this->indoorSensorsConnected) {
|
||||||
pidRegulator.Kp = settings.heating.turbo ? 0.0f : settings.pid.p_factor;
|
pidRegulator.Kp = settings.heating.turbo ? 0.0f : settings.pid.p_factor;
|
||||||
|
pidRegulator.Ki = settings.pid.i_factor;
|
||||||
pidRegulator.Kd = settings.pid.d_factor;
|
pidRegulator.Kd = settings.pid.d_factor;
|
||||||
|
|
||||||
pidRegulator.setLimits(settings.pid.minTemp, settings.pid.maxTemp);
|
pidRegulator.setLimits(settings.pid.minTemp, settings.pid.maxTemp);
|
||||||
@@ -203,12 +204,22 @@ protected:
|
|||||||
pidRegulator.input = vars.master.heating.indoorTemp;
|
pidRegulator.input = vars.master.heating.indoorTemp;
|
||||||
pidRegulator.setpoint = settings.heating.target;
|
pidRegulator.setpoint = settings.heating.target;
|
||||||
|
|
||||||
if (fabsf(pidRegulator.Ki - settings.pid.i_factor) >= 0.0001f) {
|
/*if (fabsf(pidRegulator.Ki - settings.pid.i_factor) >= 0.0001f) {
|
||||||
pidRegulator.Ki = settings.pid.i_factor;
|
pidRegulator.Ki = settings.pid.i_factor;
|
||||||
pidRegulator.integral = 0.0f;
|
pidRegulator.integral = 0.0f;
|
||||||
pidRegulator.getResultNow();
|
pidRegulator.getResultNow();
|
||||||
|
|
||||||
Log.sinfoln(FPSTR(L_REGULATOR_PID), F("Integral sum has been reset"));
|
Log.sinfoln(FPSTR(L_REGULATOR_PID), F("Integral sum has been reset"));
|
||||||
|
}*/
|
||||||
|
|
||||||
|
float error = pidRegulator.setpoint - pidRegulator.input;
|
||||||
|
bool hasDeadband = (error > -(settings.pid.deadband.thresholdHigh))
|
||||||
|
&& (error < settings.pid.deadband.thresholdLow);
|
||||||
|
|
||||||
|
if (hasDeadband) {
|
||||||
|
pidRegulator.Kp *= settings.pid.deadband.p_multiplier;
|
||||||
|
pidRegulator.Ki *= settings.pid.deadband.i_multiplier;
|
||||||
|
pidRegulator.Kd *= settings.pid.deadband.d_multiplier;
|
||||||
}
|
}
|
||||||
|
|
||||||
float pidResult = pidRegulator.getResultTimer();
|
float pidResult = pidRegulator.getResultTimer();
|
||||||
|
|||||||
@@ -445,6 +445,14 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
pClient = NimBLEDevice::createClient();
|
pClient = NimBLEDevice::createClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set initial connection parameters:
|
||||||
|
* These settings are safe for 3 clients to connect reliably, can go faster if you have less
|
||||||
|
* connections. Timeout should be a multiple of the interval, minimum is 100ms.
|
||||||
|
* Min interval: 12 * 1.25ms = 15, Max interval: 12 * 1.25ms = 15, 0 latency, 1000 * 10ms = 10000ms timeout
|
||||||
|
*/
|
||||||
|
pClient->setConnectionParams(12, 12, 0, 1000);
|
||||||
pClient->setConnectTimeout(5000);
|
pClient->setConnectTimeout(5000);
|
||||||
pClient->setSelfDelete(false, true);
|
pClient->setSelfDelete(false, true);
|
||||||
}
|
}
|
||||||
@@ -495,55 +503,59 @@ protected:
|
|||||||
NimBLEUUID charUuid((uint16_t) 0x2A6E);
|
NimBLEUUID charUuid((uint16_t) 0x2A6E);
|
||||||
pChar = pService->getCharacteristic(charUuid);
|
pChar = pService->getCharacteristic(charUuid);
|
||||||
|
|
||||||
if (pChar && pChar->canNotify()) {
|
if (pChar && (pChar->canNotify() || pChar->canIndicate())) {
|
||||||
Log.straceln(
|
Log.straceln(
|
||||||
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': found temp char (%s) in env service on device %s"),
|
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': found temp char (%s) in env service on device %s"),
|
||||||
sensorId, sSensor.name, charUuid.toString().c_str(), address.toString().c_str()
|
sensorId, sSensor.name, charUuid.toString().c_str(), address.toString().c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
tempNotifyCreated = pChar->subscribe(true, [sensorId](NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
|
pChar->unsubscribe();
|
||||||
if (pChar == nullptr) {
|
tempNotifyCreated = pChar->subscribe(
|
||||||
return;
|
pChar->canNotify(),
|
||||||
}
|
[sensorId](NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
|
||||||
|
if (pChar == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const NimBLERemoteService* pService = pChar->getRemoteService();
|
const NimBLERemoteService* pService = pChar->getRemoteService();
|
||||||
if (pService == nullptr) {
|
if (pService == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLEClient* pClient = pService->getClient();
|
NimBLEClient* pClient = pService->getClient();
|
||||||
if (pClient == nullptr) {
|
if (pClient == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& sSensor = Sensors::settings[sensorId];
|
auto& sSensor = Sensors::settings[sensorId];
|
||||||
|
|
||||||
if (length != 2) {
|
if (length != 2) {
|
||||||
Log.swarningln(
|
Log.swarningln(
|
||||||
|
FPSTR(L_SENSORS_BLE),
|
||||||
|
F("Sensor #%hhu '%s': invalid notification data at temp char (%s) on device %s"),
|
||||||
|
sensorId,
|
||||||
|
sSensor.name,
|
||||||
|
pChar->getUUID().toString().c_str(),
|
||||||
|
pClient->getPeerAddress().toString().c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rawTemp = (pChar->getValue<int16_t>() * 0.01f);
|
||||||
|
Log.straceln(
|
||||||
FPSTR(L_SENSORS_BLE),
|
FPSTR(L_SENSORS_BLE),
|
||||||
F("Sensor #%hhu '%s': invalid notification data at temp char (%s) on device %s"),
|
F("Sensor #%hhu '%s': received temp: %.2f"),
|
||||||
sensorId,
|
sensorId, sSensor.name, rawTemp
|
||||||
sSensor.name,
|
|
||||||
pChar->getUUID().toString().c_str(),
|
|
||||||
pClient->getPeerAddress().toString().c_str()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return;
|
// set temp
|
||||||
|
Sensors::setValueById(sensorId, rawTemp, Sensors::ValueType::TEMPERATURE, true, true);
|
||||||
|
|
||||||
|
// update rssi
|
||||||
|
Sensors::setValueById(sensorId, pClient->getRssi(), Sensors::ValueType::RSSI, false, false);
|
||||||
}
|
}
|
||||||
|
);
|
||||||
float rawTemp = (pChar->getValue<int16_t>() * 0.01f);
|
|
||||||
Log.straceln(
|
|
||||||
FPSTR(L_SENSORS_BLE),
|
|
||||||
F("Sensor #%hhu '%s': received temp: %.2f"),
|
|
||||||
sensorId, sSensor.name, rawTemp
|
|
||||||
);
|
|
||||||
|
|
||||||
// set temp
|
|
||||||
Sensors::setValueById(sensorId, rawTemp, Sensors::ValueType::TEMPERATURE, true, true);
|
|
||||||
|
|
||||||
// update rssi
|
|
||||||
Sensors::setValueById(sensorId, pClient->getRssi(), Sensors::ValueType::RSSI, false, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (tempNotifyCreated) {
|
if (tempNotifyCreated) {
|
||||||
Log.straceln(
|
Log.straceln(
|
||||||
@@ -568,55 +580,59 @@ protected:
|
|||||||
NimBLEUUID charUuid((uint16_t) 0x2A1F);
|
NimBLEUUID charUuid((uint16_t) 0x2A1F);
|
||||||
pChar = pService->getCharacteristic(charUuid);
|
pChar = pService->getCharacteristic(charUuid);
|
||||||
|
|
||||||
if (pChar && pChar->canNotify()) {
|
if (pChar && (pChar->canNotify() || pChar->canIndicate())) {
|
||||||
Log.straceln(
|
Log.straceln(
|
||||||
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': found temp char (%s) in env service on device %s"),
|
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': found temp char (%s) in env service on device %s"),
|
||||||
sensorId, sSensor.name, charUuid.toString().c_str(), address.toString().c_str()
|
sensorId, sSensor.name, charUuid.toString().c_str(), address.toString().c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
tempNotifyCreated = pChar->subscribe(true, [sensorId](NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
|
pChar->unsubscribe();
|
||||||
if (pChar == nullptr) {
|
tempNotifyCreated = pChar->subscribe(
|
||||||
return;
|
pChar->canNotify(),
|
||||||
}
|
[sensorId](NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
|
||||||
|
if (pChar == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const NimBLERemoteService* pService = pChar->getRemoteService();
|
const NimBLERemoteService* pService = pChar->getRemoteService();
|
||||||
if (pService == nullptr) {
|
if (pService == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLEClient* pClient = pService->getClient();
|
NimBLEClient* pClient = pService->getClient();
|
||||||
if (pClient == nullptr) {
|
if (pClient == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& sSensor = Sensors::settings[sensorId];
|
auto& sSensor = Sensors::settings[sensorId];
|
||||||
|
|
||||||
if (length != 2) {
|
if (length != 2) {
|
||||||
Log.swarningln(
|
Log.swarningln(
|
||||||
|
FPSTR(L_SENSORS_BLE),
|
||||||
|
F("Sensor #%hhu '%s': invalid notification data at temp char (%s) on device %s"),
|
||||||
|
sensorId,
|
||||||
|
sSensor.name,
|
||||||
|
pChar->getUUID().toString().c_str(),
|
||||||
|
pClient->getPeerAddress().toString().c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rawTemp = (pChar->getValue<int16_t>() * 0.1f);
|
||||||
|
Log.straceln(
|
||||||
FPSTR(L_SENSORS_BLE),
|
FPSTR(L_SENSORS_BLE),
|
||||||
F("Sensor #%hhu '%s': invalid notification data at temp char (%s) on device %s"),
|
F("Sensor #%hhu '%s': received temp: %.2f"),
|
||||||
sensorId,
|
sensorId, sSensor.name, rawTemp
|
||||||
sSensor.name,
|
|
||||||
pChar->getUUID().toString().c_str(),
|
|
||||||
pClient->getPeerAddress().toString().c_str()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return;
|
// set temp
|
||||||
|
Sensors::setValueById(sensorId, rawTemp, Sensors::ValueType::TEMPERATURE, true, true);
|
||||||
|
|
||||||
|
// update rssi
|
||||||
|
Sensors::setValueById(sensorId, pClient->getRssi(), Sensors::ValueType::RSSI, false, false);
|
||||||
}
|
}
|
||||||
|
);
|
||||||
float rawTemp = (pChar->getValue<int16_t>() * 0.1f);
|
|
||||||
Log.straceln(
|
|
||||||
FPSTR(L_SENSORS_BLE),
|
|
||||||
F("Sensor #%hhu '%s': received temp: %.2f"),
|
|
||||||
sensorId, sSensor.name, rawTemp
|
|
||||||
);
|
|
||||||
|
|
||||||
// set temp
|
|
||||||
Sensors::setValueById(sensorId, rawTemp, Sensors::ValueType::TEMPERATURE, true, true);
|
|
||||||
|
|
||||||
// update rssi
|
|
||||||
Sensors::setValueById(sensorId, pClient->getRssi(), Sensors::ValueType::RSSI, false, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (tempNotifyCreated) {
|
if (tempNotifyCreated) {
|
||||||
Log.straceln(
|
Log.straceln(
|
||||||
@@ -653,55 +669,59 @@ protected:
|
|||||||
NimBLEUUID charUuid((uint16_t) 0x2A6F);
|
NimBLEUUID charUuid((uint16_t) 0x2A6F);
|
||||||
pChar = pService->getCharacteristic(charUuid);
|
pChar = pService->getCharacteristic(charUuid);
|
||||||
|
|
||||||
if (pChar && pChar->canNotify()) {
|
if (pChar && (pChar->canNotify() || pChar->canIndicate())) {
|
||||||
Log.straceln(
|
Log.straceln(
|
||||||
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': found humidity char (%s) in env service on device %s"),
|
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': found humidity char (%s) in env service on device %s"),
|
||||||
sensorId, sSensor.name, charUuid.toString().c_str(), address.toString().c_str()
|
sensorId, sSensor.name, charUuid.toString().c_str(), address.toString().c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
humidityNotifyCreated = pChar->subscribe(true, [sensorId](NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
|
pChar->unsubscribe();
|
||||||
if (pChar == nullptr) {
|
humidityNotifyCreated = pChar->subscribe(
|
||||||
return;
|
pChar->canNotify(),
|
||||||
}
|
[sensorId](NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
|
||||||
|
if (pChar == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const NimBLERemoteService* pService = pChar->getRemoteService();
|
const NimBLERemoteService* pService = pChar->getRemoteService();
|
||||||
if (pService == nullptr) {
|
if (pService == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLEClient* pClient = pService->getClient();
|
NimBLEClient* pClient = pService->getClient();
|
||||||
if (pClient == nullptr) {
|
if (pClient == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& sSensor = Sensors::settings[sensorId];
|
auto& sSensor = Sensors::settings[sensorId];
|
||||||
|
|
||||||
if (length != 2) {
|
if (length != 2) {
|
||||||
Log.swarningln(
|
Log.swarningln(
|
||||||
|
FPSTR(L_SENSORS_BLE),
|
||||||
|
F("Sensor #%hhu '%s': invalid notification data at humidity char (%s) on device %s"),
|
||||||
|
sensorId,
|
||||||
|
sSensor.name,
|
||||||
|
pChar->getUUID().toString().c_str(),
|
||||||
|
pClient->getPeerAddress().toString().c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float rawHumidity = (pChar->getValue<uint16_t>() * 0.01f);
|
||||||
|
Log.straceln(
|
||||||
FPSTR(L_SENSORS_BLE),
|
FPSTR(L_SENSORS_BLE),
|
||||||
F("Sensor #%hhu '%s': invalid notification data at humidity char (%s) on device %s"),
|
F("Sensor #%hhu '%s': received humidity: %.2f"),
|
||||||
sensorId,
|
sensorId, sSensor.name, rawHumidity
|
||||||
sSensor.name,
|
|
||||||
pChar->getUUID().toString().c_str(),
|
|
||||||
pClient->getPeerAddress().toString().c_str()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return;
|
// set humidity
|
||||||
|
Sensors::setValueById(sensorId, rawHumidity, Sensors::ValueType::HUMIDITY, true, true);
|
||||||
|
|
||||||
|
// update rssi
|
||||||
|
Sensors::setValueById(sensorId, pClient->getRssi(), Sensors::ValueType::RSSI, false, false);
|
||||||
}
|
}
|
||||||
|
);
|
||||||
float rawHumidity = (pChar->getValue<uint16_t>() * 0.01f);
|
|
||||||
Log.straceln(
|
|
||||||
FPSTR(L_SENSORS_BLE),
|
|
||||||
F("Sensor #%hhu '%s': received humidity: %.2f"),
|
|
||||||
sensorId, sSensor.name, rawHumidity
|
|
||||||
);
|
|
||||||
|
|
||||||
// set humidity
|
|
||||||
Sensors::setValueById(sensorId, rawHumidity, Sensors::ValueType::HUMIDITY, true, true);
|
|
||||||
|
|
||||||
// update rssi
|
|
||||||
Sensors::setValueById(sensorId, pClient->getRssi(), Sensors::ValueType::RSSI, false, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (humidityNotifyCreated) {
|
if (humidityNotifyCreated) {
|
||||||
Log.straceln(
|
Log.straceln(
|
||||||
@@ -752,55 +772,59 @@ protected:
|
|||||||
NimBLEUUID charUuid((uint16_t) 0x2A19);
|
NimBLEUUID charUuid((uint16_t) 0x2A19);
|
||||||
pChar = pService->getCharacteristic(charUuid);
|
pChar = pService->getCharacteristic(charUuid);
|
||||||
|
|
||||||
if (pChar && pChar->canNotify()) {
|
if (pChar && (pChar->canNotify() || pChar->canIndicate())) {
|
||||||
Log.straceln(
|
Log.straceln(
|
||||||
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': found battery char (%s) in battery service on device %s"),
|
FPSTR(L_SENSORS_BLE), F("Sensor #%hhu '%s': found battery char (%s) in battery service on device %s"),
|
||||||
sensorId, sSensor.name, charUuid.toString().c_str(), address.toString().c_str()
|
sensorId, sSensor.name, charUuid.toString().c_str(), address.toString().c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
batteryNotifyCreated = pChar->subscribe(true, [sensorId](NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
|
pChar->unsubscribe();
|
||||||
if (pChar == nullptr) {
|
batteryNotifyCreated = pChar->subscribe(
|
||||||
return;
|
pChar->canNotify(),
|
||||||
}
|
[sensorId](NimBLERemoteCharacteristic* pChar, uint8_t* pData, size_t length, bool isNotify) {
|
||||||
|
if (pChar == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const NimBLERemoteService* pService = pChar->getRemoteService();
|
const NimBLERemoteService* pService = pChar->getRemoteService();
|
||||||
if (pService == nullptr) {
|
if (pService == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NimBLEClient* pClient = pService->getClient();
|
NimBLEClient* pClient = pService->getClient();
|
||||||
if (pClient == nullptr) {
|
if (pClient == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& sSensor = Sensors::settings[sensorId];
|
auto& sSensor = Sensors::settings[sensorId];
|
||||||
|
|
||||||
if (length != 1) {
|
if (length != 1) {
|
||||||
Log.swarningln(
|
Log.swarningln(
|
||||||
|
FPSTR(L_SENSORS_BLE),
|
||||||
|
F("Sensor #%hhu '%s': invalid notification data at battery char (%s) on device %s"),
|
||||||
|
sensorId,
|
||||||
|
sSensor.name,
|
||||||
|
pChar->getUUID().toString().c_str(),
|
||||||
|
pClient->getPeerAddress().toString().c_str()
|
||||||
|
);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto rawBattery = pChar->getValue<uint8_t>();
|
||||||
|
Log.straceln(
|
||||||
FPSTR(L_SENSORS_BLE),
|
FPSTR(L_SENSORS_BLE),
|
||||||
F("Sensor #%hhu '%s': invalid notification data at battery char (%s) on device %s"),
|
F("Sensor #%hhu '%s': received battery: %hhu"),
|
||||||
sensorId,
|
sensorId, sSensor.name, rawBattery
|
||||||
sSensor.name,
|
|
||||||
pChar->getUUID().toString().c_str(),
|
|
||||||
pClient->getPeerAddress().toString().c_str()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return;
|
// set battery
|
||||||
|
Sensors::setValueById(sensorId, rawBattery, Sensors::ValueType::BATTERY, true, true);
|
||||||
|
|
||||||
|
// update rssi
|
||||||
|
Sensors::setValueById(sensorId, pClient->getRssi(), Sensors::ValueType::RSSI, false, false);
|
||||||
}
|
}
|
||||||
|
);
|
||||||
auto rawBattery = pChar->getValue<uint8_t>();
|
|
||||||
Log.straceln(
|
|
||||||
FPSTR(L_SENSORS_BLE),
|
|
||||||
F("Sensor #%hhu '%s': received battery: %.2f"),
|
|
||||||
sensorId, sSensor.name, rawBattery
|
|
||||||
);
|
|
||||||
|
|
||||||
// set battery
|
|
||||||
Sensors::setValueById(sensorId, rawBattery, Sensors::ValueType::BATTERY, true, true);
|
|
||||||
|
|
||||||
// update rssi
|
|
||||||
Sensors::setValueById(sensorId, pClient->getRssi(), Sensors::ValueType::RSSI, false, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (batteryNotifyCreated) {
|
if (batteryNotifyCreated) {
|
||||||
Log.straceln(
|
Log.straceln(
|
||||||
|
|||||||
@@ -110,11 +110,20 @@ struct Settings {
|
|||||||
struct {
|
struct {
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
float p_factor = 2.0f;
|
float p_factor = 2.0f;
|
||||||
float i_factor = 0.0055f;
|
float i_factor = 0.002f;
|
||||||
float d_factor = 0.0f;
|
float d_factor = 0.0f;
|
||||||
unsigned short dt = 180;
|
unsigned short dt = 300;
|
||||||
short minTemp = 0;
|
short minTemp = 0;
|
||||||
short maxTemp = DEFAULT_HEATING_MAX_TEMP;
|
short maxTemp = DEFAULT_HEATING_MAX_TEMP;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool enabled = true;
|
||||||
|
float p_multiplier = 1.0f;
|
||||||
|
float i_multiplier = 0.05f;
|
||||||
|
float d_multiplier = 1.0f;
|
||||||
|
float thresholdHigh = 0.5f;
|
||||||
|
float thresholdLow = 1.0f;
|
||||||
|
} deadband;
|
||||||
} pid;
|
} pid;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ const char S_CRASH[] PROGMEM = "crash";
|
|||||||
const char S_CURRENT_TEMP[] PROGMEM = "currentTemp";
|
const char S_CURRENT_TEMP[] PROGMEM = "currentTemp";
|
||||||
const char S_DATA[] PROGMEM = "data";
|
const char S_DATA[] PROGMEM = "data";
|
||||||
const char S_DATE[] PROGMEM = "date";
|
const char S_DATE[] PROGMEM = "date";
|
||||||
|
const char S_DEADBAND[] PROGMEM = "deadband";
|
||||||
const char S_DHW[] PROGMEM = "dhw";
|
const char S_DHW[] PROGMEM = "dhw";
|
||||||
const char S_DHW_BLOCKING[] PROGMEM = "dhwBlocking";
|
const char S_DHW_BLOCKING[] PROGMEM = "dhwBlocking";
|
||||||
const char S_DHW_SUPPORT[] PROGMEM = "dhwSupport";
|
const char S_DHW_SUPPORT[] PROGMEM = "dhwSupport";
|
||||||
@@ -71,6 +72,7 @@ const char S_DIAG[] PROGMEM = "diag";
|
|||||||
const char S_DNS[] PROGMEM = "dns";
|
const char S_DNS[] PROGMEM = "dns";
|
||||||
const char S_DT[] PROGMEM = "dt";
|
const char S_DT[] PROGMEM = "dt";
|
||||||
const char S_D_FACTOR[] PROGMEM = "d_factor";
|
const char S_D_FACTOR[] PROGMEM = "d_factor";
|
||||||
|
const char S_D_MULTIPLIER[] PROGMEM = "d_multiplier";
|
||||||
const char S_EMERGENCY[] PROGMEM = "emergency";
|
const char S_EMERGENCY[] PROGMEM = "emergency";
|
||||||
const char S_ENABLED[] PROGMEM = "enabled";
|
const char S_ENABLED[] PROGMEM = "enabled";
|
||||||
const char S_ENV[] PROGMEM = "env";
|
const char S_ENV[] PROGMEM = "env";
|
||||||
@@ -108,6 +110,7 @@ const char S_INTERVAL[] PROGMEM = "interval";
|
|||||||
const char S_INVERT_STATE[] PROGMEM = "invertState";
|
const char S_INVERT_STATE[] PROGMEM = "invertState";
|
||||||
const char S_IP[] PROGMEM = "ip";
|
const char S_IP[] PROGMEM = "ip";
|
||||||
const char S_I_FACTOR[] PROGMEM = "i_factor";
|
const char S_I_FACTOR[] PROGMEM = "i_factor";
|
||||||
|
const char S_I_MULTIPLIER[] PROGMEM = "i_multiplier";
|
||||||
const char S_K_FACTOR[] PROGMEM = "k_factor";
|
const char S_K_FACTOR[] PROGMEM = "k_factor";
|
||||||
const char S_LOGIN[] PROGMEM = "login";
|
const char S_LOGIN[] PROGMEM = "login";
|
||||||
const char S_LOG_LEVEL[] PROGMEM = "logLevel";
|
const char S_LOG_LEVEL[] PROGMEM = "logLevel";
|
||||||
@@ -152,6 +155,7 @@ const char S_PREFIX[] PROGMEM = "prefix";
|
|||||||
const char S_PROTOCOL_VERSION[] PROGMEM = "protocolVersion";
|
const char S_PROTOCOL_VERSION[] PROGMEM = "protocolVersion";
|
||||||
const char S_PURPOSE[] PROGMEM = "purpose";
|
const char S_PURPOSE[] PROGMEM = "purpose";
|
||||||
const char S_P_FACTOR[] PROGMEM = "p_factor";
|
const char S_P_FACTOR[] PROGMEM = "p_factor";
|
||||||
|
const char S_P_MULTIPLIER[] PROGMEM = "p_multiplier";
|
||||||
const char S_REAL_SIZE[] PROGMEM = "realSize";
|
const char S_REAL_SIZE[] PROGMEM = "realSize";
|
||||||
const char S_REASON[] PROGMEM = "reason";
|
const char S_REASON[] PROGMEM = "reason";
|
||||||
const char S_RESET_DIAGNOSTIC[] PROGMEM = "resetDiagnostic";
|
const char S_RESET_DIAGNOSTIC[] PROGMEM = "resetDiagnostic";
|
||||||
@@ -183,6 +187,8 @@ const char S_TARGET[] PROGMEM = "target";
|
|||||||
const char S_TARGET_TEMP[] PROGMEM = "targetTemp";
|
const char S_TARGET_TEMP[] PROGMEM = "targetTemp";
|
||||||
const char S_TELNET[] PROGMEM = "telnet";
|
const char S_TELNET[] PROGMEM = "telnet";
|
||||||
const char S_TEMPERATURE[] PROGMEM = "temperature";
|
const char S_TEMPERATURE[] PROGMEM = "temperature";
|
||||||
|
const char S_THRESHOLD_HIGH[] PROGMEM = "thresholdHigh";
|
||||||
|
const char S_THRESHOLD_LOW[] PROGMEM = "thresholdLow";
|
||||||
const char S_THRESHOLD_TIME[] PROGMEM = "thresholdTime";
|
const char S_THRESHOLD_TIME[] PROGMEM = "thresholdTime";
|
||||||
const char S_TOTAL[] PROGMEM = "total";
|
const char S_TOTAL[] PROGMEM = "total";
|
||||||
const char S_TRESHOLD_TIME[] PROGMEM = "tresholdTime";
|
const char S_TRESHOLD_TIME[] PROGMEM = "tresholdTime";
|
||||||
|
|||||||
62
src/utils.h
62
src/utils.h
@@ -438,6 +438,14 @@ void settingsToJson(const Settings& src, JsonVariant dst, bool safe = false) {
|
|||||||
pid[FPSTR(S_MIN_TEMP)] = src.pid.minTemp;
|
pid[FPSTR(S_MIN_TEMP)] = src.pid.minTemp;
|
||||||
pid[FPSTR(S_MAX_TEMP)] = src.pid.maxTemp;
|
pid[FPSTR(S_MAX_TEMP)] = src.pid.maxTemp;
|
||||||
|
|
||||||
|
auto pidDeadband = pid[FPSTR(S_DEADBAND)].to<JsonObject>();
|
||||||
|
pidDeadband[FPSTR(S_ENABLED)] = src.pid.deadband.enabled;
|
||||||
|
pidDeadband[FPSTR(S_P_MULTIPLIER)] = src.pid.deadband.p_multiplier;
|
||||||
|
pidDeadband[FPSTR(S_I_MULTIPLIER)] = src.pid.deadband.i_multiplier;
|
||||||
|
pidDeadband[FPSTR(S_D_MULTIPLIER)] = src.pid.deadband.d_multiplier;
|
||||||
|
pidDeadband[FPSTR(S_THRESHOLD_HIGH)] = src.pid.deadband.thresholdHigh;
|
||||||
|
pidDeadband[FPSTR(S_THRESHOLD_LOW)] = src.pid.deadband.thresholdLow;
|
||||||
|
|
||||||
if (!safe) {
|
if (!safe) {
|
||||||
auto externalPump = dst[FPSTR(S_EXTERNAL_PUMP)].to<JsonObject>();
|
auto externalPump = dst[FPSTR(S_EXTERNAL_PUMP)].to<JsonObject>();
|
||||||
externalPump[FPSTR(S_USE)] = src.externalPump.use;
|
externalPump[FPSTR(S_USE)] = src.externalPump.use;
|
||||||
@@ -1075,6 +1083,60 @@ bool jsonToSettings(const JsonVariantConst src, Settings& dst, bool safe = false
|
|||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_ENABLED)].is<bool>()) {
|
||||||
|
bool value = src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_ENABLED)].as<bool>();
|
||||||
|
|
||||||
|
if (value != dst.pid.deadband.enabled) {
|
||||||
|
dst.pid.deadband.enabled = value;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_P_MULTIPLIER)].isNull()) {
|
||||||
|
float value = src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_P_MULTIPLIER)].as<float>();
|
||||||
|
|
||||||
|
if (value >= 0 && value <= 1 && fabsf(value - dst.pid.deadband.p_multiplier) > 0.0001f) {
|
||||||
|
dst.pid.deadband.p_multiplier = roundf(value, 3);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_I_MULTIPLIER)].isNull()) {
|
||||||
|
float value = src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_I_MULTIPLIER)].as<float>();
|
||||||
|
|
||||||
|
if (value >= 0 && value <= 1 && fabsf(value - dst.pid.deadband.i_multiplier) > 0.0001f) {
|
||||||
|
dst.pid.deadband.i_multiplier = roundf(value, 3);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_D_MULTIPLIER)].isNull()) {
|
||||||
|
float value = src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_D_MULTIPLIER)].as<float>();
|
||||||
|
|
||||||
|
if (value >= 0 && value <= 1 && fabsf(value - dst.pid.deadband.d_multiplier) > 0.0001f) {
|
||||||
|
dst.pid.deadband.d_multiplier = roundf(value, 3);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_THRESHOLD_HIGH)].isNull()) {
|
||||||
|
float value = src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_THRESHOLD_HIGH)].as<float>();
|
||||||
|
|
||||||
|
if (value >= 0.0f && value <= 5.0f && fabsf(value - dst.pid.deadband.thresholdHigh) > 0.0001f) {
|
||||||
|
dst.pid.deadband.thresholdHigh = roundf(value, 2);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_THRESHOLD_LOW)].isNull()) {
|
||||||
|
float value = src[FPSTR(S_PID)][FPSTR(S_DEADBAND)][FPSTR(S_THRESHOLD_LOW)].as<float>();
|
||||||
|
|
||||||
|
if (value >= 0.0f && value <= 5.0f && fabsf(value - dst.pid.deadband.thresholdLow) > 0.0001f) {
|
||||||
|
dst.pid.deadband.thresholdLow = roundf(value, 2);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// heating
|
// heating
|
||||||
if (src[FPSTR(S_HEATING)][FPSTR(S_ENABLED)].is<bool>()) {
|
if (src[FPSTR(S_HEATING)][FPSTR(S_ENABLED)].is<bool>()) {
|
||||||
|
|||||||
@@ -347,7 +347,19 @@
|
|||||||
"i": "I factor",
|
"i": "I factor",
|
||||||
"d": "D factor",
|
"d": "D factor",
|
||||||
"dt": "DT <small>in seconds</small>",
|
"dt": "DT <small>in seconds</small>",
|
||||||
"noteMinMaxTemp": "<b>Important:</b> When using «Equitherm» and «PID» at the same time, the min and max temperatures limit the influence on the «Equitherm» result temperature.<br />Thus, if the min temperature is set to -15 and the max temperature is set to 15, then the final heat carrier setpoint will be from <code>equitherm_result - 15</code> to <code>equitherm_result + 15</code>."
|
"limits": {
|
||||||
|
"title": "Limits",
|
||||||
|
"note": "<b>Important:</b> When using «Equitherm» and «PID» at the same time, the min and max temperatures limit the influence on the «Equitherm» result temperature.<br />Thus, if the min temperature is set to -15 and the max temperature is set to 15, then the final heat carrier setpoint will be from <code>equitherm_result - 15</code> to <code>equitherm_result + 15</code>."
|
||||||
|
},
|
||||||
|
"deadband": {
|
||||||
|
"title": "Deadband",
|
||||||
|
"note": "Deadband is a range around the target temperature where PID regulation becomes less active. Within this range, the algorithm can reduce intensity or pause adjustments to avoid overreacting to small fluctuations.<br /><br />For instance, with a target temperature of 22°, a lower threshold of 1.0, and an upper threshold of 0.5, the deadband operates between 21° and 22.5°. If the I coefficient is 0.0005 and the I multiplier is 0.05, then within the deadband, the I coefficient becomes: <code>0.0005 * 0.05 = 0.000025</code>",
|
||||||
|
"p_multiplier": "Multiplier for P factor",
|
||||||
|
"i_multiplier": "Multiplier for I factor",
|
||||||
|
"d_multiplier": "Multiplier for D factor",
|
||||||
|
"thresholdHigh": "Threshold high",
|
||||||
|
"thresholdLow": "Threshold low"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"ot": {
|
"ot": {
|
||||||
|
|||||||
@@ -347,7 +347,19 @@
|
|||||||
"i": "Fattore I",
|
"i": "Fattore I",
|
||||||
"d": "Fattore D",
|
"d": "Fattore D",
|
||||||
"dt": "DT <small>in secondi</small>",
|
"dt": "DT <small>in secondi</small>",
|
||||||
"noteMinMaxTemp": "<b>Importante:</b> Quando usi «Equitherm» e «PID» allo stesso tempo, i limiti della temperatura min e max influenzano il risultato della temperatura «Equitherm».<br />Thus, se la temperatura minima è impostata a -15 e la massima a 15, il riscaldamento finale sarà impostato fra <code>equitherm_result - 15</code> a <code>equitherm_result + 15</code>."
|
"limits": {
|
||||||
|
"title": "Limiti",
|
||||||
|
"note": "<b>Importante:</b> Quando usi «Equitherm» e «PID» allo stesso tempo, i limiti della temperatura min e max influenzano il risultato della temperatura «Equitherm».<br />Thus, se la temperatura minima è impostata a -15 e la massima a 15, il riscaldamento finale sarà impostato fra <code>equitherm_result - 15</code> a <code>equitherm_result + 15</code>."
|
||||||
|
},
|
||||||
|
"deadband": {
|
||||||
|
"title": "Zona morta (Deadband)",
|
||||||
|
"note": "La zona morta è un intervallo intorno alla temperatura target in cui la regolazione PID diventa meno attiva. In questo intervallo, l'algoritmo può ridurre l'intensità o interrompere gli aggiustamenti per evitare di reagire eccessivamente a piccole fluttuazioni.<br /><br />Ad esempio, con una temperatura target di 22°, una soglia inferiore di 1.0 e una soglia superiore di 0.5, la zona morta opera tra 21° e 22.5°. Se il coefficiente I è 0.0005 e il moltiplicatore I è 0.05, allora nella zona morta, il coefficiente I diventa: <code>0.0005 * 0.05 = 0.000025</code>",
|
||||||
|
"p_multiplier": "Moltiplicatore P",
|
||||||
|
"i_multiplier": "Moltiplicatore I",
|
||||||
|
"d_multiplier": "Moltiplicatore D",
|
||||||
|
"thresholdHigh": "Soglia superiore",
|
||||||
|
"thresholdLow": "Soglia inferiore"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"ot": {
|
"ot": {
|
||||||
|
|||||||
@@ -347,7 +347,19 @@
|
|||||||
"i": "Коэффициент I",
|
"i": "Коэффициент I",
|
||||||
"d": "Коэффициент D",
|
"d": "Коэффициент D",
|
||||||
"dt": "DT <small>(сек)</small>",
|
"dt": "DT <small>(сек)</small>",
|
||||||
"noteMinMaxTemp": "<b>Важно:</b> При использовании «ПЗА» и «ПИД» одновременно, мин. и макс. температура ограничивает влияние на расчётную температуру «ПЗА».<br />Таким образом, если мин. температура задана как -15, а макс. как 15, то конечная температура теплоносителя будет от <code>equitherm_result - 15</code> до <code>equitherm_result + 15</code>."
|
"limits": {
|
||||||
|
"title": "Лимиты",
|
||||||
|
"note": "<b>Важно:</b> При использовании «ПЗА» и «ПИД» одновременно, мин. и макс. температура ограничивает влияние на расчётную температуру «ПЗА».<br />Таким образом, если мин. температура задана как -15, а макс. как 15, то конечная температура теплоносителя будет от <code>equitherm_result - 15</code> до <code>equitherm_result + 15</code>."
|
||||||
|
},
|
||||||
|
"deadband": {
|
||||||
|
"title": "Зона нечувствительности (Deadband)",
|
||||||
|
"note": "Deadband - это зона нечувствительности вокруг целевой температуры, в которой PID-регулирование становится менее активным. В этом диапазоне алгоритм может снижать интенсивность или полностью прекращать корректировку температуры, чтобы избежать излишней чувствительности к небольшим колебаниям.<br /><br />Например, при целевой температуре 22°, нижнем пороге 1.0 и верхнем 0.5, deadband активен в диапазоне от 21° до 22.5°. Если коэфф. I=0.0005, а множитель I=0.05, то при включении зоны нечувствительности коэфф. I будет равен: <code>0.0005 * 0.05 = 0.000025</code>",
|
||||||
|
"p_multiplier": "Множитель для коэф. P",
|
||||||
|
"i_multiplier": "Множитель для коэф. I",
|
||||||
|
"d_multiplier": "Множитель для коэф. D",
|
||||||
|
"thresholdHigh": "Верхний порог",
|
||||||
|
"thresholdLow": "Нижний порог"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"ot": {
|
"ot": {
|
||||||
|
|||||||
@@ -259,7 +259,7 @@
|
|||||||
<b>Type:</b> <span class="sType"></span>
|
<b>Type:</b> <span class="sType"></span>
|
||||||
<b>AppVersion:</b> <span class="sAppVersion"></span>
|
<b>AppVersion:</b> <span class="sAppVersion"></span>
|
||||||
<b>OT version:</b> <span class="sProtocolVersion"></span>
|
<b>OT version:</b> <span class="sProtocolVersion"></span>
|
||||||
<b>Modulation limits:</b> <span class="sModMin"></span>...<span class="sModMax"></span> %
|
<b>Modulation limits:</b> <span class="sModMin"></span>...<span class="sAbsModMax"></span> %, curr. max: <span class="sModMax"></span> %
|
||||||
<b>Power limits:</b> <span class="sPowerMin"></span>...<span class="sPowerMax"></span> kW
|
<b>Power limits:</b> <span class="sPowerMin"></span>...<span class="sPowerMax"></span> kW
|
||||||
<b>Heating limits:</b> <span class="sHeatMinTemp"></span>...<span class="sHeatMaxTemp"></span> <span class="tempUnit"></span>
|
<b>Heating limits:</b> <span class="sHeatMinTemp"></span>...<span class="sHeatMaxTemp"></span> <span class="tempUnit"></span>
|
||||||
<b>DHW limits:</b> <span class="sDhwMinTemp"></span>...<span class="sDhwMaxTemp"></span> <span class="tempUnit"></span></pre>
|
<b>DHW limits:</b> <span class="sDhwMinTemp"></span>...<span class="sDhwMaxTemp"></span> <span class="tempUnit"></span></pre>
|
||||||
@@ -511,6 +511,7 @@
|
|||||||
setValue('.tempUnit', temperatureUnit(unitSystem));
|
setValue('.tempUnit', temperatureUnit(unitSystem));
|
||||||
setValue('.pressureUnit', pressureUnit(unitSystem));
|
setValue('.pressureUnit', pressureUnit(unitSystem));
|
||||||
setValue('.volumeUnit', volumeUnit(unitSystem));
|
setValue('.volumeUnit', volumeUnit(unitSystem));
|
||||||
|
setValue('.sAbsModMax', result.opentherm.maxModulation);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|||||||
@@ -211,7 +211,7 @@
|
|||||||
sensorNode.classList.remove("hidden");
|
sensorNode.classList.remove("hidden");
|
||||||
sensorNode.dataset.id = sensorId;
|
sensorNode.dataset.id = sensorId;
|
||||||
setValue(".id", sensorId, sensorNode);
|
setValue(".id", sensorId, sensorNode);
|
||||||
setValue(".pos", sensorId + 1, sensorNode);
|
setValue(".pos", parseInt(sensorId) + 1, sensorNode);
|
||||||
setValue(".name", result[sensorId], sensorNode);
|
setValue(".name", result[sensorId], sensorNode);
|
||||||
|
|
||||||
container.appendChild(sensorNode);
|
container.appendChild(sensorNode);
|
||||||
|
|||||||
@@ -313,19 +313,73 @@
|
|||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<div class="grid">
|
<details>
|
||||||
<label>
|
<summary><b data-i18n>settings.pid.limits.title</b></summary>
|
||||||
<span data-i18n>settings.temp.min</span>
|
|
||||||
<input type="number" inputmode="numeric" name="pid[minTemp]" min="0" max="0" step="1" required>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label>
|
<div>
|
||||||
<span data-i18n>settings.temp.max</span>
|
<div class="grid">
|
||||||
<input type="number" inputmode="numeric" name="pid[maxTemp]" min="0" max="0" step="1" required>
|
<label>
|
||||||
</label>
|
<span data-i18n>settings.temp.min</span>
|
||||||
</div>
|
<input type="number" inputmode="decimal" name="pid[minTemp]" min="0" max="0" step="1" required>
|
||||||
|
</label>
|
||||||
|
|
||||||
<small data-i18n>settings.pid.noteMinMaxTemp</small>
|
<label>
|
||||||
|
<span data-i18n>settings.temp.max</span>
|
||||||
|
<input type="number" inputmode="numeric" name="pid[maxTemp]" min="0" max="0" step="1" required>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<small data-i18n>settings.pid.limits.note</small>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b data-i18n>settings.pid.deadband.title</b></summary>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<fieldset>
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" name="pid[deadband][enabled]" value="true">
|
||||||
|
<span data-i18n>settings.enable</span>
|
||||||
|
</label>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<label>
|
||||||
|
<span data-i18n>settings.pid.deadband.p_multiplier</span>
|
||||||
|
<input type="number" inputmode="decimal" name="pid[deadband][p_multiplier]" min="0" max="5" step="0.001" required>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<span data-i18n>settings.pid.deadband.i_multiplier</span>
|
||||||
|
<input type="number" inputmode="decimal" name="pid[deadband][i_multiplier]" min="0" max="1" step="0.001" required>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<span data-i18n>settings.pid.deadband.d_multiplier</span>
|
||||||
|
<input type="number" inputmode="decimal" name="pid[deadband][d_multiplier]" min="0" max="1" step="0.001" required>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<label>
|
||||||
|
<span data-i18n>settings.pid.deadband.thresholdHigh</span>
|
||||||
|
<input type="number" inputmode="decimal" name="pid[deadband][thresholdHigh]" min="0" max="5" step="0.01" required>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<span data-i18n>settings.pid.deadband.thresholdLow</span>
|
||||||
|
<input type="number" inputmode="decimal" name="pid[deadband][thresholdLow]" min="0" max="5" step="0.01" required>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<small data-i18n>settings.pid.deadband.note</small>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
<button type="submit" data-i18n>button.save</button>
|
<button type="submit" data-i18n>button.save</button>
|
||||||
</form>
|
</form>
|
||||||
@@ -633,12 +687,12 @@
|
|||||||
<div class="grid">
|
<div class="grid">
|
||||||
<label>
|
<label>
|
||||||
<span data-i18n>settings.cascadeControl.output.gpio</span>
|
<span data-i18n>settings.cascadeControl.output.gpio</span>
|
||||||
<input type="number" outputmode="numeric" name="cascadeControl[output][gpio]" min="0" max="254" step="1">
|
<input type="number" inputmode="numeric" name="cascadeControl[output][gpio]" min="0" max="254" step="1">
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<span data-i18n>settings.cascadeControl.output.thresholdTime</span>
|
<span data-i18n>settings.cascadeControl.output.thresholdTime</span>
|
||||||
<input type="number" outputmode="numeric" name="cascadeControl[output][thresholdTime]" min="5" max="600" step="1" required>
|
<input type="number" inputmode="numeric" name="cascadeControl[output][thresholdTime]" min="5" max="600" step="1" required>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -823,6 +877,12 @@
|
|||||||
"min": (data.system.unitSystem == 0 ? 0 : 33),
|
"min": (data.system.unitSystem == 0 ? 0 : 33),
|
||||||
"max": (data.system.unitSystem == 0 ? 100 : 212)
|
"max": (data.system.unitSystem == 0 ? 100 : 212)
|
||||||
});
|
});
|
||||||
|
setCheckboxValue("[name='pid[deadband][enabled]']", data.pid.deadband.enabled);
|
||||||
|
setInputValue("[name='pid[deadband][p_multiplier]']", data.pid.deadband.p_multiplier);
|
||||||
|
setInputValue("[name='pid[deadband][i_multiplier]']", data.pid.deadband.i_multiplier);
|
||||||
|
setInputValue("[name='pid[deadband][d_multiplier]']", data.pid.deadband.d_multiplier);
|
||||||
|
setInputValue("[name='pid[deadband][thresholdHigh]']", data.pid.deadband.thresholdHigh);
|
||||||
|
setInputValue("[name='pid[deadband][thresholdLow]']", data.pid.deadband.thresholdLow);
|
||||||
setBusy('#pid-settings-busy', '#pid-settings', false);
|
setBusy('#pid-settings-busy', '#pid-settings', false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user