refactor: dynamic sensors

This commit is contained in:
Yurii
2024-11-09 17:10:26 +03:00
parent c3d0d94806
commit e71f3868fd
27 changed files with 4666 additions and 3388 deletions

View File

@@ -42,31 +42,31 @@
<div class="thermostat" id="thermostat-heating">
<div class="thermostat-header" data-i18n>dashboard.thermostat.heating</div>
<div class="thermostat-temp">
<div class="thermostat-temp-target"><span id="thermostat-heating-target"></span> <span class="temp-unit"></span></div>
<div class="thermostat-temp-current"><span data-i18n>dashboard.thermostat.temp.current</span>: <span id="thermostat-heating-current"></span> <span class="temp-unit"></span></div>
<div class="thermostat-temp-target"><span id="tHeatTargetTemp"></span> <span class="tempUnit"></span></div>
<div class="thermostat-temp-current"><span data-i18n>dashboard.thermostat.temp.current</span>: <span id="tHeatCurrentTemp"></span> <span class="tempUnit"></span></div>
</div>
<div class="thermostat-minus"><button id="thermostat-heating-minus" class="outline"><i class="icons-down"></i></button></div>
<div class="thermostat-plus"><button id="thermostat-heating-plus" class="outline"><i class="icons-up"></i></button></div>
<div class="thermostat-minus"><button id="tHeatActionMinus" class="outline"><i class="icons-down"></i></button></div>
<div class="thermostat-plus"><button id="tHeatActionPlus" class="outline"><i class="icons-up"></i></button></div>
<div class="thermostat-control">
<input type="checkbox" role="switch" id="thermostat-heating-enabled" value="true">
<label htmlFor="thermostat-heating-enabled" data-i18n>dashboard.thermostat.enable</label>
<input type="checkbox" role="switch" id="tHeatEnabled" value="true">
<label htmlFor="tHeatEnabled" data-i18n>dashboard.thermostat.enable</label>
<input type="checkbox" role="switch" id="thermostat-heating-turbo" value="true">
<label htmlFor="thermostat-heating-turbo" data-i18n>dashboard.thermostat.turbo</label>
<input type="checkbox" role="switch" id="tHeatTurbo" value="true">
<label htmlFor="tHeatTurbo" data-i18n>dashboard.thermostat.turbo</label>
</div>
</div>
<div class="thermostat" id="thermostat-dhw">
<div class="thermostat-header" data-i18n>dashboard.thermostat.dhw</div>
<div class="thermostat-temp">
<div class="thermostat-temp-target"><span id="thermostat-dhw-target"></span> <span class="temp-unit"></span></div>
<div class="thermostat-temp-current"><span data-i18n>dashboard.thermostat.temp.current</span>: <span id="thermostat-dhw-current"></span> <span class="temp-unit"></span></div>
<div class="thermostat-temp-target"><span id="tDhwTargetTemp"></span> <span class="tempUnit"></span></div>
<div class="thermostat-temp-current"><span data-i18n>dashboard.thermostat.temp.current</span>: <span id="tDhwCurrentTemp"></span> <span class="tempUnit"></span></div>
</div>
<div class="thermostat-minus"><button class="outline" id="thermostat-dhw-minus"><i class="icons-down"></i></button></div>
<div class="thermostat-plus"><button class="outline" id="thermostat-dhw-plus"><i class="icons-up"></i></button></div>
<div class="thermostat-minus"><button class="outline" id="tDhwActionMinus"><i class="icons-down"></i></button></div>
<div class="thermostat-plus"><button class="outline" id="tDhwActionPlus"><i class="icons-up"></i></button></div>
<div class="thermostat-control">
<input type="checkbox" role="switch" id="thermostat-dhw-enabled" value="true">
<label htmlFor="thermostat-dhw-enabled" data-i18n>dashboard.thermostat.enable</label>
<input type="checkbox" role="switch" id="tDhwEnabled" value="true">
<label htmlFor="tDhwEnabled" data-i18n>dashboard.thermostat.enable</label>
</div>
</div>
</div>
@@ -79,132 +79,112 @@
<table>
<tbody>
<tr>
<th scope="row" data-i18n>dashboard.state.ot</th>
<td><input type="radio" id="ot-connected" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.mNetworkConnected</th>
<td><input type="radio" class="mNetworkConnected" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.mqtt</th>
<td><input type="radio" id="mqtt-connected" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.mMqttConnected</th>
<td><input type="radio" class="mMqttConnected" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.emergency</th>
<td><input type="radio" id="ot-emergency" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.mEmergencyState</th>
<td><input type="radio" class="mEmergencyState" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.heating</th>
<td><input type="radio" id="ot-heating" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.mExtPumpState</th>
<td><input type="radio" class="mExtPumpState" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.dhw</th>
<td><input type="radio" id="ot-dhw" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.mCascadeControlInput</th>
<td><input type="radio" id="mCascadeControlInput" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.flame</th>
<td><input type="radio" id="ot-flame" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.mCascadeControlOutput</th>
<td><input type="radio" id="mCascadeControlOutput" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.states.sConnected</th>
<td><input type="radio" class="sConnected" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.fault</th>
<td><input type="radio" id="ot-fault" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.sFlame</th>
<td><input type="radio" class="sFlame" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.states.sFaultActive</th>
<td><input type="radio" class="sFaultActive" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.diag</th>
<td><input type="radio" id="ot-diagnostic" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.sFaultCode</th>
<td><b class="sFaultCode"></b></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.extpump</th>
<td><input type="radio" id="ot-external-pump" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.sDiagActive</th>
<td><input type="radio" class="sDiagActive" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.outdoorSensorConnected</th>
<td><input type="radio" id="outdoor-sensor-connected" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.sDiagCode</th>
<td><b class="sDiagCode"></b></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.states.mHeatEnabled</th>
<td><input type="radio" class="mHeatEnabled" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.outdoorSensorRssi</th>
<td><b id="outdoor-sensor-rssi"></b> <span data-i18n>dbm</span></td>
<th scope="row" data-i18n>dashboard.states.mHeatBlocking</th>
<td><input type="radio" class="mHeatBlocking" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.outdoorSensorHumidity</th>
<td><b id="outdoor-sensor-humidity"></b> %</td>
<th scope="row" data-i18n>dashboard.states.sHeatActive</th>
<td><input type="radio" class="sHeatActive" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.outdoorSensorBattery</th>
<td><b id="outdoor-sensor-battery"></b> %</td>
<th scope="row" data-i18n>dashboard.states.mHeatTargetTemp</th>
<td><b class="mHeatTargetTemp"></b> <span class="tempUnit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.indoorSensorConnected</th>
<td><input type="radio" id="indoor-sensor-connected" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.mHeatCurrTemp</th>
<td><b class="mHeatCurrTemp"></b> <span class="tempUnit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.cascadeControlInput</th>
<td><input type="radio" id="cc-input" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.mHeatRetTemp</th>
<td><b class="mHeatRetTemp"></b> <span class="tempUnit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.cascadeControlOutput</th>
<td><input type="radio" id="cc-output" aria-invalid="false" checked disabled /></td>
<th scope="row" data-i18n>dashboard.states.mHeatIndoorTemp</th>
<td><b class="mHeatIndoorTemp"></b> <span class="tempUnit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.indoorSensorRssi</th>
<td><b id="indoor-sensor-rssi"></b> <span data-i18n>dbm</span></td>
<th scope="row" data-i18n>dashboard.states.mHeatOutdoorTemp</th>
<td><b class="mHeatOutdoorTemp"></b> <span class="tempUnit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.states.mDhwEnabled</th>
<td><input type="radio" class="mDhwEnabled" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.indoorSensorHumidity</th>
<td><b id="indoor-sensor-humidity"></b> %</td>
<th scope="row" data-i18n>dashboard.states.sDhwActive</th>
<td><input type="radio" class="sDhwActive" aria-invalid="false" checked disabled /></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.indoorSensorBattery</th>
<td><b id="indoor-sensor-battery"></b> %</td>
<th scope="row" data-i18n>dashboard.states.mDhwTargetTemp</th>
<td><b class="mDhwTargetTemp"></b> <span class="tempUnit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.modulation</th>
<td><b id="ot-modulation"></b> %</td>
<th scope="row" data-i18n>dashboard.states.mDhwCurrTemp</th>
<td><b class="mDhwCurrTemp"></b> <span class="tempUnit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.pressure</th>
<td><b id="ot-pressure"></b> <span class="pressure-unit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.dhwFlowRate</th>
<td><b id="ot-dhw-flow-rate"></b> <span class="volume-unit"></span>/min</td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.power</th>
<td><b id="ot-power"></b> <span data-i18n>kw</span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.faultCode</th>
<td><b id="ot-fault-code"></b></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.diagCode</th>
<td><b id="ot-diag-code"></b></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.indoorTemp</th>
<td><b id="indoor-temp"></b> <span class="temp-unit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.outdoorTemp</th>
<td><b id="outdoor-temp"></b> <span class="temp-unit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.heatingTemp</th>
<td><b id="heating-temp"></b> <span class="temp-unit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.heatingSetpointTemp</th>
<td><b id="heating-setpoint-temp"></b> <span class="temp-unit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.heatingReturnTemp</th>
<td><b id="heating-return-temp"></b> <span class="temp-unit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.dhwTemp</th>
<td><b id="dhw-temp"></b> <span class="temp-unit"></span></td>
</tr>
<tr>
<th scope="row" data-i18n>dashboard.state.exhaustTemp</th>
<td><b id="exhaust-temp"></b> <span class="temp-unit"></span></td>
<th scope="row" data-i18n>dashboard.states.mDhwRetTemp</th>
<td><b class="mDhwRetTemp"></b> <span class="tempUnit"></span></td>
</tr>
</tbody>
</table>
@@ -213,15 +193,17 @@
<hr />
<details>
<summary><b data-i18n>dashboard.section.otDiag</b></summary>
<pre><b>Vendor:</b> <span id="slave-vendor"></span>
<b>Member ID:</b> <span id="slave-member-id"></span>
<b>Flags:</b> <span id="slave-flags"></span>
<b>Type:</b> <span id="slave-type"></span>
<b>Version:</b> <span id="slave-version"></span>
<b>OT version:</b> <span id="slave-ot-version"></span>
<b>Heating limits:</b> <span id="heating-min-temp"></span>...<span id="heating-max-temp"></span> <span class="temp-unit"></span>
<b>DHW limits:</b> <span id="dhw-min-temp"></span>...<span id="dhw-max-temp"></span> <span class="temp-unit"></span></pre>
<summary><b data-i18n>dashboard.section.diag</b></summary>
<pre><b>Vendor:</b> <span class="sVendor"></span>
<b>Member ID:</b> <span class="sMemberId"></span>
<b>Flags:</b> <span class="sFlags"></span>
<b>Type:</b> <span class="sType"></span>
<b>AppVersion:</b> <span class="sAppVersion"></span>
<b>OT version:</b> <span class="sProtocolVersion"></span>
<b>Modulation limits:</b> <span class="sModMin"></span>...<span class="sModMax"></span> %
<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>DHW limits:</b> <span class="sDhwMinTemp"></span>...<span class="sDhwMaxTemp"></span> <span class="tempUnit"></span></pre>
</details>
</div>
</article>
@@ -259,7 +241,7 @@
const lang = new Lang(document.getElementById('lang'));
lang.build();
document.querySelector('#thermostat-heating-minus').addEventListener('click', (event) => {
document.querySelector('#tHeatActionMinus').addEventListener('click', (event) => {
if (!prevSettings) {
return;
}
@@ -278,10 +260,10 @@
newSettings.heating.target = minTemp;
}
setValue('#thermostat-heating-target', newSettings.heating.target);
setValue('#tHeatTargetTemp', newSettings.heating.target);
});
document.querySelector('#thermostat-heating-plus').addEventListener('click', (event) => {
document.querySelector('#tHeatActionPlus').addEventListener('click', (event) => {
if (!prevSettings) {
return;
}
@@ -300,10 +282,10 @@
newSettings.heating.target = maxTemp;
}
setValue('#thermostat-heating-target', newSettings.heating.target);
setValue('#tHeatTargetTemp', newSettings.heating.target);
});
document.querySelector('#thermostat-dhw-minus').addEventListener('click', (event) => {
document.querySelector('#tDhwActionMinus').addEventListener('click', (event) => {
if (!prevSettings) {
return;
}
@@ -315,10 +297,10 @@
newSettings.dhw.target = prevSettings.dhw.minTemp;
}
setValue('#thermostat-dhw-target', newSettings.dhw.target);
setValue('#tDhwTargetTemp', newSettings.dhw.target);
});
document.querySelector('#thermostat-dhw-plus').addEventListener('click', (event) => {
document.querySelector('#tDhwActionPlus').addEventListener('click', (event) => {
if (!prevSettings) {
return;
}
@@ -330,22 +312,22 @@
newSettings.dhw.target = prevSettings.dhw.maxTemp;
}
setValue('#thermostat-dhw-target', newSettings.dhw.target);
setValue('#tDhwTargetTemp', newSettings.dhw.target);
});
document.querySelector('#thermostat-heating-enabled').addEventListener('change', (event) => {
document.querySelector('#tHeatEnabled').addEventListener('change', (event) => {
modifiedTime = Date.now();
newSettings.heating.enable = event.currentTarget.checked;
newSettings.heating.enabled = event.currentTarget.checked;
});
document.querySelector('#thermostat-heating-turbo').addEventListener('change', (event) => {
document.querySelector('#tHeatTurbo').addEventListener('change', (event) => {
modifiedTime = Date.now();
newSettings.heating.turbo = event.currentTarget.checked;
});
document.querySelector('#thermostat-dhw-enabled').addEventListener('change', (event) => {
document.querySelector('#tDhwEnabled').addEventListener('change', (event) => {
modifiedTime = Date.now();
newSettings.dhw.enable = event.currentTarget.checked;
newSettings.dhw.enabled = event.currentTarget.checked;
});
setTimeout(async function onLoadPage() {
@@ -361,10 +343,10 @@
// settings
try {
let modified = prevSettings && (
(prevSettings.heating.enable != newSettings.heating.enable)
(prevSettings.heating.enabled != newSettings.heating.enabled)
|| (prevSettings.heating.turbo != newSettings.heating.turbo)
|| (prevSettings.heating.target != newSettings.heating.target)
|| (prevSettings.opentherm.dhwPresent && prevSettings.dhw.enable != newSettings.dhw.enable)
|| (prevSettings.opentherm.dhwPresent && prevSettings.dhw.enabled != newSettings.dhw.enabled)
|| (prevSettings.opentherm.dhwPresent && prevSettings.dhw.target != newSettings.dhw.target)
);
@@ -384,12 +366,12 @@
}
const result = await response.json();
noRegulators = !result.opentherm.nativeHeatingControl && !result.equitherm.enable && !result.pid.enable;
noRegulators = !result.opentherm.nativeHeatingControl && !result.equitherm.enabled && !result.pid.enabled;
prevSettings = result;
newSettings.heating.enable = result.heating.enable;
newSettings.heating.enabled = result.heating.enabled;
newSettings.heating.turbo = result.heating.turbo;
newSettings.heating.target = result.heating.target;
newSettings.dhw.enable = result.dhw.enable;
newSettings.dhw.enabled = result.dhw.enabled;
newSettings.dhw.target = result.dhw.target;
if (result.opentherm.dhwPresent) {
@@ -398,16 +380,16 @@
hide('#thermostat-dhw');
}
setCheckboxValue('#thermostat-heating-enabled', result.heating.enable);
setCheckboxValue('#thermostat-heating-turbo', result.heating.turbo);
setValue('#thermostat-heating-target', result.heating.target);
setCheckboxValue('#tHeatEnabled', result.heating.enabled);
setCheckboxValue('#tHeatTurbo', result.heating.turbo);
setValue('#tHeatTargetTemp', result.heating.target);
setCheckboxValue('#thermostat-dhw-enabled', result.dhw.enable);
setValue('#thermostat-dhw-target', result.dhw.target);
setCheckboxValue('#tDhwEnabled', result.dhw.enabled);
setValue('#tDhwTargetTemp', result.dhw.target);
setValue('.temp-unit', temperatureUnit(result.system.unitSystem));
setValue('.pressure-unit', pressureUnit(result.system.unitSystem));
setValue('.volume-unit', volumeUnit(result.system.unitSystem));
setValue('.tempUnit', temperatureUnit(result.system.unitSystem));
setValue('.pressureUnit', pressureUnit(result.system.unitSystem));
setValue('.volumeUnit', volumeUnit(result.system.unitSystem));
} catch (error) {
console.log(error);
@@ -421,67 +403,83 @@
}
const result = await response.json();
setValue('#thermostat-heating-current', noRegulators ? result.temperatures.heating : result.temperatures.indoor);
setValue('#thermostat-dhw-current', result.temperatures.dhw);
setState('#ot-connected', result.states.otStatus);
setState('#mqtt-connected', result.states.mqtt);
setState('#ot-emergency', result.states.emergency);
setState('#ot-heating', result.states.heating);
setState('#ot-dhw', result.states.dhw);
setState('#ot-flame', result.states.flame);
setState('#ot-fault', result.states.fault);
setState('#ot-diagnostic', result.states.diagnostic);
setState('#ot-external-pump', result.states.externalPump);
setState('#outdoor-sensor-connected', result.sensors.outdoor.connected);
setState('#indoor-sensor-connected', result.sensors.indoor.connected);
setState('#cc-input', result.cascadeControl.input);
setState('#cc-output', result.cascadeControl.output);
setValue('#outdoor-sensor-rssi', result.sensors.outdoor.rssi);
setValue('#outdoor-sensor-humidity', result.sensors.outdoor.humidity);
setValue('#outdoor-sensor-battery', result.sensors.outdoor.battery);
setValue('#indoor-sensor-rssi', result.sensors.indoor.rssi);
setValue('#indoor-sensor-humidity', result.sensors.indoor.humidity);
setValue('#indoor-sensor-battery', result.sensors.indoor.battery);
setValue('#ot-modulation', result.sensors.modulation);
setValue('#ot-pressure', result.sensors.pressure);
setValue('#ot-dhw-flow-rate', result.sensors.dhwFlowRate);
setValue('#ot-power', result.sensors.power);
setValue(
'#ot-fault-code',
result.sensors.faultCode
? (result.sensors.faultCode + " (0x" + dec2hex(result.sensors.faultCode) + ")")
: "-"
// Graph
setValue('#tHeatCurrentTemp', result.master.indoorTempControl
? result.master.heating.indoorTemp
: result.master.heating.currentTemp
);
setValue('#tDhwCurrentTemp', result.master.dhw.currentTemp);
// SLAVE
setValue('.sMemberId', result.slave.memberId);
setValue('.sVendor', memberIdToVendor(result.slave.memberId));
setValue('.sFlags', result.slave.flags);
setValue('.sType', result.slave.type);
setValue('.sAppVersion', result.slave.appVersion);
setValue('.sProtocolVersion', result.slave.protocolVersion);
setState('.sConnected', result.slave.connected);
setState('.sFlame', result.slave.flame);
setValue('.sModMin', result.slave.modulation.min);
setValue('.sModMax', result.slave.modulation.max);
setValue('.sPowerMin', result.slave.power.min);
setValue('.sPowerMax', result.slave.power.max);
setState('.sHeatActive', result.slave.heating.active);
setValue('.sHeatMinTemp', result.slave.heating.minTemp);
setValue('.sHeatMaxTemp', result.slave.heating.maxTemp);
setState('.sDhwActive', result.slave.dhw.active);
setValue('.sDhwMinTemp', result.slave.dhw.minTemp);
setValue('.sDhwMaxTemp', result.slave.dhw.maxTemp);
setState('.sFaultActive', result.slave.fault.active);
setValue(
'#ot-diag-code',
result.sensors.diagnosticCode
? (result.sensors.diagnosticCode + " (0x" + dec2hex(result.sensors.diagnosticCode) + ")")
'.sFaultCode',
result.slave.fault.active
? (result.slave.fault.code + " (0x" + dec2hex(result.slave.fault.code) + ")")
: "-"
);
setValue('#indoor-temp', result.temperatures.indoor);
setValue('#outdoor-temp', result.temperatures.outdoor);
setValue('#heating-temp', result.temperatures.heating);
setValue('#heating-return-temp', result.temperatures.heatingReturn);
setValue('#dhw-temp', result.temperatures.dhw);
setValue('#exhaust-temp', result.temperatures.exhaust);
setState('.sDiagActive', result.slave.diag.active);
setValue(
'.sDiagCode',
result.slave.diag.active
? (result.slave.diag.code + " (0x" + dec2hex(result.slave.diag.code) + ")")
: "-"
);
setValue('#heating-min-temp', result.parameters.heatingMinTemp);
setValue('#heating-max-temp', result.parameters.heatingMaxTemp);
setValue('#heating-setpoint-temp', result.parameters.heatingSetpoint);
setValue('#dhw-min-temp', result.parameters.dhwMinTemp);
setValue('#dhw-max-temp', result.parameters.dhwMaxTemp);
setValue('#slave-member-id', result.parameters.slaveMemberId);
setValue('#slave-vendor', memberIdToVendor(result.parameters.slaveMemberId));
// MASTER
setState('.mHeatEnabled', result.master.heating.enabled);
setState('.mHeatBlocking', result.master.heating.blocking);
setState('.mHeatIndoorTempControl', result.master.heating.indoorTempControl);
setValue('.mHeatTargetTemp', result.master.heating.targetTemp);
setValue('.mHeatCurrTemp', result.master.heating.currentTemp);
setValue('.mHeatRetTemp', result.master.heating.returnTemp);
setValue('.mHeatIndoorTemp', result.master.heating.indoorTemp);
setValue('.mHeatOutdoorTemp', result.master.heating.outdoorTemp);
setValue('.mHeatMinTemp', result.master.heating.minTemp);
setValue('.mHeatMaxTemp', result.master.heating.maxTemp);
setState('.mDhwEnabled', result.master.dhw.enabled);
setValue('.mDhwTargetTemp', result.master.dhw.targetTemp);
setValue('.mDhwCurrTemp', result.master.dhw.currentTemp);
setValue('.mDhwRetTemp', result.master.dhw.returnTemp);
setValue('.mDhwMinTemp', result.master.dhw.minTemp);
setValue('.mDhwMaxTemp', result.master.dhw.maxTemp);
setState('.mNetworkConnected', result.master.network.connected);
setState('.mMqttConnected', result.master.mqtt.connected);
setState('.mEmergencyState', result.master.emergency.state);
setState('.mExtPumpState', result.master.externalPump.state);
setState('.mCascadeControlInput', result.master.cascadeControl.input);
setState('.mCascadeControlOutput', result.master.cascadeControl.output);
setValue('#slave-flags', result.parameters.slaveFlags);
setValue('#slave-type', result.parameters.slaveType);
setValue('#slave-version', result.parameters.slaveVersion);
setValue('#slave-ot-version', result.parameters.slaveOtVersion);
setBusy('#dashboard-busy', '#dashboard-container', false);
} catch (error) {