[HOW TO] Advanced Virtual Device for ESPAltherma

const b_ip = ‘192.168.2.61’;
const b_baseurl = ‘http://’+ b_ip + ‘/getData’;

function toFixed(num) {
return Math.trunc((num * 100) / 100);
}

data = {};

try {
const res = await fetch(b_baseurl);
if (res.ok) data = await res.json();
} catch (err) {
log(err);
}

let ops = ;

altherma = {};
switch(data[‘Operation Mode’]) {
case ‘Fan Only’:
altherma[‘mode’] = ‘Fan Only’;
break;
case ‘Heating’:
altherma[‘mode’] = ‘Heating’;
break;
case ‘Cooling’:
altherma[‘mode’] = ‘Cooling’;
break;
default:
altherma[‘mode’] = data[‘Operation Mode’];
}

switch(data[‘I/U operation mode’]) {
case ‘DHW’:
altherma[‘status’] = ‘On’;
altherma[‘mode’] = ‘DHW’;
break;
case ‘Stop’:
altherma[‘status’] = ‘-’;
break;
default:
altherma[‘status’] = ‘On’;
}
//if (altherma[‘status’] == ‘Stop’) altherma[‘status’] = ‘Off’;

let voltage = Math.min(230, data[‘Voltage (N-phase) (V)’]);

altherma[‘heat_pump_power’] = (data[‘INV primary current (A)’] * voltage);
altherma[‘heat_pump_power_2’] = (data[‘INV secondary current (A)’] * voltage);
altherma[‘valve_2way’] = (data[‘2way valve(On:Heat_Off:Cool)’] == ‘ON’ ? ‘Heat’ : ‘Cool’) + ’ (‘+ data[‘2way valve(On:Heat_Off:Cool)’] +’)‘;
altherma[‘valve_3way’] = (data[‘3way valve(On:DHW_Off:Space)’] == ‘OFF’ ? ‘Ambient’ : ‘DHW’) + ’ (’+ data[‘3way valve(On:DHW_Off:Space)’] +‘)’;
altherma[‘thermostat’] = data[‘Thermostat ON/OFF’];
if (data[‘Defrost Operation’] == ‘ON’) ops.push(‘defrost’);
if (data[‘Oil Return Operation’] == ‘ON’) ops.push(‘oil_return’);
if (data[‘Brine Flow Switch’] == ‘ON’) ops.push(‘brine’);
if (ops.length > 0) altherma[‘operations’] = ops.join(‘, ‘);
altherma[‘t_outdoor’] = data[‘R1T-Outdoor air temp.’];
altherma[‘t_acs’] = data[‘2nd Domestic hot water temperature’];
altherma[‘t_aanvoer’] = data[’[HPSU] Tv inflow Temp (R1T)’];
altherma[‘t_aanvoerBuh’] = data[‘[HPSU] Tvbh inflow Temp after Buffer/BUH (R2T)’];
altherma[‘t_retour’] = data[‘[HPSU] Tr return Temp (R4T)’];
altherma[‘t_tanktemp_dhw’] = data[‘DHW tank temp. (R5T)’];
altherma[‘t_setpoint’] = data[‘LW setpoint (main)’];
altherma[‘dhw_setpoint’] = data[‘DHW setpoint’];
altherma[‘t_heatingTarget’] = data[‘Boiler Heating Target Temp.’];
altherma[‘flowSensor’] = (data[‘Flow sensor (l/min)’] > 0 ? (data[‘Flow sensor (l/min)’] * 60).toFixed(0) : 0);
altherma[‘waterPump’] = data[‘Water pump operation’];
altherma[‘heat_delivered’] = (data[‘Flow sensor (l/min)’] * 0.06 * 1.16 * (altherma[‘t_aanvoerBuh’] - altherma[‘t_retour’]));
altherma[‘heat_delivered_alt’] = (data[‘Flow sensor (l/min)’] * 0.06 * 1.16 * (altherma[‘t_aanvoer’] - altherma[‘t_retour’]));

altherma[‘backupHeater’] = ‘OFF’;
if (data[‘BUH Step1’] == ‘ON’ || data[‘BUH Step2’] == ‘ON’) altherma[‘backupHeater’] = ‘ON’;
altherma[‘dt_h’] = data[‘Target delta T heating’];
altherma[‘dt_c’] = data[‘Target delta T cooling’];
altherma[‘cop’] = 0;
altherma[‘cop_alt’] = 0;
if (data[‘Operation Mode’] == ‘Heating’ && data[‘Freeze Protection’] == ‘OFF’) {
let c = (altherma[‘heat_delivered’] / (altherma[‘heat_pump_power’] / 1000));
if (c > 0) altherma[‘cop’] = parseFloat(c.toFixed(1));
let c_alt = (altherma[‘heat_delivered_alt’] / (altherma[‘heat_pump_power’] / 1000));
if (c_alt > 0) altherma[‘cop_alt’] = parseFloat(c_alt.toFixed(1));
}
altherma[‘heat_pump_power’] = parseFloat(altherma[‘heat_pump_power’].toFixed(1));
altherma[‘heat_pump_power_2’] = parseFloat(altherma[‘heat_pump_power_2’].toFixed(1));
if (altherma[‘mode’] == ‘Cooling’) {
altherma[‘heat_delivered’] = 0;
altherma[‘heat_delivered_alt’] = 0;
}
altherma[‘heat_delivered’] = parseFloat(altherma[‘heat_delivered’].toFixed(1));
altherma[‘heat_delivered_alt’] = parseFloat(altherma[‘heat_delivered_alt’].toFixed(1));
let operation = ‘-’;
if (altherma[‘defrost’] == ‘ON’) operation = ‘defrost’;
if (altherma[‘oil_return’] == ‘ON’) operation = ‘oil_return’;
if (altherma[‘brine’] == ‘ON’) operation = ‘brine’;

//await tag(‘esp_altherma_operation’, operation);
await tag(‘esp_altherma_mode’, altherma[‘mode’]);
await tag(‘esp_altherma_status’, altherma[‘status’]);
await tag(‘esp_altherma_cop’, altherma[‘cop’]);
await tag(‘esp_altherma_acs’, altherma[‘t_acs’]);
await tag(‘esp_altherma_heat_pump_power’, altherma[‘heat_pump_power’]);
await tag(‘esp_altherma_heat_pump_power_2’, altherma[‘heat_pump_power_2’]);
await tag(‘esp_altherma_aanvoer’, altherma[‘t_aanvoer’]);
await tag(‘esp_altherma_aanvoerBuh’, altherma[‘t_aanvoerBuh’]);
await tag(‘esp_altherma_retour’, altherma[‘t_retour’]);
await tag(‘esp_altherma_t_tanktemp_dhw’, altherma[‘t_tanktemp_dhw’]);
await tag(‘esp_altherma_dhw_setpoint’, altherma[‘dhw_setpoint’]);
await tag(‘esp_altherma_Target_delta_t_heating’, altherma[‘dt_h’]);
await tag(‘esp_altherma_2wegklep’, altherma[‘valve_2way’]);
await tag(‘esp_altherma_3wegklep’, altherma[‘valve_3way’]);
await tag(‘esp_altherma_thermostaat’, altherma[‘thermostat’]);
await tag(‘esp_altherma_buitentemp’, altherma[‘t_outdoor’]);
await tag(‘esp_altherma_LW_setpoint_main’, altherma[‘t_setpoint’]);
await tag(‘esp_altherma_Boiler_heating_target_temp’, altherma[‘t_heatingTarget’]);
await tag(‘esp_altherma_Flow_sensor_lmin’, altherma[‘flowSensor’]);
await tag(‘esp_altherma_Water_pump_operation’, altherma[‘waterPump’]);
await tag(‘esp_altherma_Heat_delivered’, altherma[‘heat_delivered’]);
await tag(‘esp_altherma_Heat_delivered_alt’, altherma[‘heat_delivered_alt’]);

altherma[‘heat_pump_power’] += ’ Wh’;
altherma[‘heat_pump_power_2’] += ’ Wh’;
altherma[‘heat_delivered’] += ’ Wh’;
altherma[‘heat_delivered_alt’] += ’ Wh’;
altherma[‘t_outdoor’] += ‘°’;
altherma[‘t_acs’] += ‘°’;
altherma[‘t_aanvoer’] += ‘°’;
altherma[‘t_aanvoerBuh’] += ‘°’;
altherma[‘t_retour’] += ‘°’;
altherma[‘t_tanktemp_dhw’] += ‘°’;
altherma[‘t_setpoint’] += ‘°’;
altherma[‘dhw_setpoint’] += ‘°’;
altherma[‘t_heatingTarget’] += ‘°’;
altherma[‘flowSensor’] += ’ l/h’;

await tag(‘esp_altherma’, JSON.stringify(altherma));

log(data);
log(altherma);

return true;

i think you have created a numeric tag and you try to set it with a string value. Add parseFloat() on tag with error…
If you don’t know which one it is, deactivate them all and activate them one at a time