[evcc] Fix bug #19206 where heating devices showing % instead of °C (#19211)

* Fix bug #19206 and add datapoints for currents for grid and chargers

Signed-off-by: Marcel Goerentz <57457529+marcelGoerentz@users.noreply.github.com>
This commit is contained in:
Marcel Goerentz
2025-08-21 15:36:51 +02:00
committed by GitHub
parent 1c5f750e97
commit f8fed2b938
7 changed files with 81 additions and 39 deletions
@@ -64,6 +64,7 @@ public class EvccBindingConstants {
public static final String JSON_MEMBER_PV = "pv";
public static final String JSON_MEMBER_STATISTICS = "statistics";
public static final String JSON_MEMBER_VEHICLES = "vehicles";
public static final String JSON_MEMBER_CHARGER_FEATURE_HEATING = "chargerFeatureHeating";
public static final String NUMBER_CURRENCY = CoreItemFactory.NUMBER + ":Currency";
public static final String NUMBER_DIMENSIONLESS = CoreItemFactory.NUMBER + ":Dimensionless";
@@ -56,7 +56,8 @@ public class LoadpointDiscoveryMapper implements EvccDiscoveryMapper {
properties.put(PROPERTY_INDEX, i);
properties.put(PROPERTY_TITLE, title);
if (lp.has(title) && lp.get("chargerFeatureHeating").getAsBoolean()) {
if (lp.has(JSON_MEMBER_CHARGER_FEATURE_HEATING)
&& lp.get(JSON_MEMBER_CHARGER_FEATURE_HEATING).getAsBoolean()) {
uid = new ThingUID(EvccBindingConstants.THING_TYPE_HEATING, bridgeHandler.getThing().getUID(),
Utils.sanitizeName(title));
properties.put(PROPERTY_TYPE, PROPERTY_TYPE_HEATING);
@@ -244,7 +244,8 @@ public abstract class EvccBaseThingHandler extends BaseThingHandler implements E
key += "Price";
}
}
return (props.get("type") + "-" + Utils.sanitizeChannelID(key));
String type = "heating".equals(props.get("type")) ? "loadpoint" : props.get("type");
return (type + "-" + Utils.sanitizeChannelID(key));
}
@Override
@@ -12,9 +12,15 @@
*/
package org.openhab.binding.evcc.internal.handler;
import static org.openhab.binding.evcc.internal.EvccBindingConstants.JSON_MEMBER_LOADPOINTS;
import java.util.Arrays;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.type.ChannelTypeRegistry;
import org.openhab.core.types.Command;
import com.google.gson.JsonObject;
@@ -26,6 +32,9 @@ import com.google.gson.JsonObject;
@NonNullByDefault
public class EvccHeatingHandler extends EvccLoadpointHandler {
private static final String[] TEMPERATURE_CHANNEL_IDS = { "loadpoint-effective-limit-temperature",
"loadpoint-limit-temperature", "loadpoint-vehicle-temperature" };
public EvccHeatingHandler(Thing thing, ChannelTypeRegistry channelTypeRegistry) {
super(thing, channelTypeRegistry);
}
@@ -35,8 +44,37 @@ public class EvccHeatingHandler extends EvccLoadpointHandler {
super.initialize();
}
@Override
public void handleCommand(ChannelUID channelUID, Command command) {
String id = channelUID.getId();
if (Arrays.asList(TEMPERATURE_CHANNEL_IDS).contains(id)) {
// Replace the generated key with the original one to get the correct
String thingKey = getThingKey(id.replace("Temperature", "Soc"));
channelUID = new ChannelUID(getThing().getUID(), thingKey);
}
super.handleCommand(channelUID, command);
}
@Override
public void updateFromEvccState(JsonObject state) {
updateJSON(state);
super.updateFromEvccState(state);
}
protected void updateJSON(JsonObject state) {
JsonObject heatingState = state.getAsJsonArray(JSON_MEMBER_LOADPOINTS).get(index).getAsJsonObject();
if (heatingState.has("vehicleLimitSoc")) {
heatingState.addProperty("vehicleLimitTemperature", heatingState.get("vehicleLimitSoc").getAsDouble());
heatingState.remove("vehicleLimitSoc");
}
if (heatingState.has("effectiveLimitSoc")) {
heatingState.add("effectiveLimitTemperature", heatingState.get("effectiveLimitSoc"));
heatingState.remove("effectiveLimitSoc");
}
if (heatingState.has("vehicleSoc")) {
heatingState.add("vehicleTemperature", heatingState.get("vehicleSoc"));
heatingState.remove("vehicleSoc");
}
state.getAsJsonArray(JSON_MEMBER_LOADPOINTS).set(index, heatingState); // Update the IDs in the original JSON
}
}
@@ -61,6 +61,10 @@ public class EvccLoadpointHandler extends EvccBaseThingHandler {
return;
}
if (this instanceof EvccHeatingHandler heating) {
heating.updateJSON(stateOpt.getAsJsonObject());
}
JsonObject state = stateOpt.getAsJsonArray(JSON_MEMBER_LOADPOINTS).get(index).getAsJsonObject();
modifyJSON(state);
@@ -107,7 +111,7 @@ public class EvccLoadpointHandler extends EvccBaseThingHandler {
super.updateFromEvccState(state);
}
public void modifyJSON(JsonObject state) {
private void modifyJSON(JsonObject state) {
// This is for backward compatibility with older evcc versions
if (state.has("chargeCurrent")) {
state.addProperty("offeredCurrent", state.get("chargeCurrent").getAsDouble());
@@ -12,5 +12,37 @@
<description>A heating loadpoint configured in your evcc instance</description>
<representation-property>index</representation-property>
</thing-type>
<!-- This thing is currently using the same channels as a loadpoint does -->
<channel-type id="loadpoint-effective-limit-temperature">
<item-type>Number:Temperature</item-type>
<label>Effective Charging Limit Temperature</label>
<description>Effective Temperature until which the heating device will be charged</description>
<category>Temperature</category>
<tags>
<tag>Setpoint</tag>
<tag>Temperature</tag>
</tags>
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="loadpoint-limit-temperature">
<item-type>Number:Temperature</item-type>
<label>Temperature Limit</label>
<description>Temperature to which the heating device is charged</description>
<category>Temperature</category>
<tags>
<tag>Setpoint</tag>
<tag>Temperature</tag>
</tags>
<state min="0" step="1" max="100" pattern="%.0f %unit%"/>
</channel-type>
<channel-type id="loadpoint-vehicle-temperature">
<item-type>Number:Temperature</item-type>
<label>Temperature</label>
<description>Current temperature of the heating device</description>
<category>Temperature</category>
<tags>
<tag>Measurement</tag>
<tag>Temperature</tag>
</tags>
<state pattern="%.0f %unit%" readOnly="true"/>
</channel-type>
</thing:thing-descriptions>
@@ -745,39 +745,4 @@
</options>
</state>
</channel-type>
<!-- Heating relevant channels -->
<channel-type id="loadpoint-effective-limit-temperature">
<item-type>Number:Temperature</item-type>
<label>Effective Charging Limit Temperature</label>
<description>Effective Temperature until which the heating device will be charged</description>
<category>Temperature</category>
<tags>
<tag>Setpoint</tag>
<tag>Temperature</tag>
</tags>
<state min="0" step="1" max="100" pattern="%.0f %unit%" readOnly="true"/>
</channel-type>
<channel-type id="loadpoint-limit-temperature">
<item-type>Number:Temperature</item-type>
<label>Temperature Limit</label>
<description>Temperature to which the heating device is charged</description>
<category>Temperature</category>
<tags>
<tag>Setpoint</tag>
<tag>Temperature</tag>
</tags>
<state min="0" step="1" max="100" pattern="%.0f %unit%"/>
</channel-type>
<channel-type id="loadpoint-vehicle-temperature">
<item-type>Number:Temperature</item-type>
<label>Temperature</label>
<description>Current temperature of the heating device</description>
<category>Temperature</category>
<tags>
<tag>Measurement</tag>
<tag>Temperature</tag>
</tags>
<state pattern="%.0f %unit%" readOnly="true"/>
</channel-type>
</thing:thing-descriptions>