-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[kermi] Initial contribution #15687
[kermi] Initial contribution #15687
Changes from 18 commits
f707659
e3e9416
8afc488
b5c56dc
5128c42
fbed6f2
b293457
05c0596
4e749ad
5ca5a2b
1d0f98b
02899a4
69db59c
731087b
ebf5838
e0ece61
9211798
15b651b
6ba94a9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
This content is produced and maintained by the openHAB project. | ||
|
||
* Project home: https://www.openhab.org | ||
|
||
== Declared Project Licenses | ||
|
||
This program and the accompanying materials are made available under the terms | ||
of the Eclipse Public License 2.0 which is available at | ||
https://www.eclipse.org/legal/epl-2.0/. | ||
|
||
== Source Code | ||
|
||
https://github.com/openhab/openhab-addons |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,78 @@ | ||||||
# Kermi Binding | ||||||
|
||||||
This binding connects to [Kermi x-center controller](https://www.kermi.com/en/de/indoor-climate/products/heat-pumps-and-storage/x-center-controller/ "x-center-controller") for heat pumps. | ||||||
|
||||||
# Kermi Binding | ||||||
|
||||||
Current support is developed and tested on | ||||||
|
||||||
* a franchised version of the Kermi heatpump, namely the [Heizbösch MOZART13AC-RW60](https://www.boesch.at/produkte/heizen/waermepumpe/luft/modulierende-luft-wasser-waermepumpe-mozart-aussenaufstellung~495589) heatpump manager version _1.6.0.118_ . | ||||||
|
||||||
No official documentation could be found or gathered. This plug-in is based | ||||||
on reverse engineering the protocol. | ||||||
|
||||||
## Supported Things | ||||||
|
||||||
The x-center consists of a heat-pump manager that provides the communication bridge. | ||||||
|
||||||
- `bridge`: The communication bridge, provided by the heat pump manager | ||||||
- `drinkingwater-heating`: The storage module responsible for heating the drinking water (Default bus address = 51) | ||||||
- `room-heating`: The storage module responsible for heating rooms (Default bus address = 50) | ||||||
- `heatpump-manager`: As thing | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 'As thing' is not very descriptive. |
||||||
- `heatpump`: The heatpump element itself (Default bus address = 40) | ||||||
|
||||||
## Discovery | ||||||
|
||||||
There is no obvious way to get a listing of all Datapoints for a given Device. Due to this, on first | ||||||
connection to a site, the API for the UI User Interface is used, to iterate over all menu entries to | ||||||
collect the datapoints - which may take a while. | ||||||
|
||||||
The gathered data is then stored in `OH_USERDATA/binding.kermi` and loaded on subsequent binding lifecycle | ||||||
changes. The cache data is bound to the device-uuid and its serial number. If these values change, | ||||||
the datapoints are automatically re-initialized. | ||||||
|
||||||
## Binding Configuration | ||||||
|
||||||
The following samples are provided, representing the current state of my usage. | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would suggest to create a table with config parameters and move the bridge declaration to examples. Just a mock asw suggestion:
|
||||||
``` | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
// kermi.things | ||||||
Bridge kermi:bridge:heatpumpbridge [hostname="xcenter-url",password="password",refreshInterval=60] { | ||||||
Thing drinkingwater-heating dwheating [ address=51 ] | ||||||
Thing room-heating rheating [ address=50 ] | ||||||
Thing heatpump heatpump [ address=40 ] | ||||||
} | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
``` | ||||||
|
||||||
The plugin is configured to collect all `WellKnownName` datapoints, so generally | ||||||
all of them should be supported. At the moment I only test the following items in read-only mode. | ||||||
|
||||||
``` | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
// kermi.items | ||||||
Number:Temperature Drinking_water_temperature {channel="kermi:drinkingwater-heating:heatpumpbridge:dwheating:BufferSystem_TweTemperatureActual"} | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
Number:Temperature Heating_current_temperature_buffer {channel="kermi:room-heating:heatpumpbridge:rheating:BufferSystem_HeatingTemperatureActual"} | ||||||
Number:Temperature Cooling_current_temperature_buffer {channel="kermi:room-heating:heatpumpbridge:rheating:BufferSystem_CoolingTemperatureActual"} | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
Number:Temperature Outside_temperature {channel="kermi:room-heating:heatpumpbridge:rheating:LuftTemperatur"} | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
Number:Power Current_Power_Inverter {channel="kermi:heatpump:heatpumpbridge:heatpump:Rubin_CurrentPowerInverter"} | ||||||
``` | ||||||
|
||||||
# Changelog | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changelog is not needed as git is used for release notes. |
||||||
|
||||||
20.10.23 | ||||||
* Support numeric values for datapointType = 0 | ||||||
* Support string values for datapointType = 3 | ||||||
* Support string values for datapointType = 4 | ||||||
|
||||||
# ToDo / Future Tasks | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please implement or create github issues for each todo item. |
||||||
|
||||||
* Change default query time, resemble webinterface behaviour (every 10 seconds to GetFavorites) | ||||||
* Support channels for bridge | ||||||
* Somehow add DatapointConfigId to channel, seems not supported | ||||||
* Collection of statistics providing virtual channels | ||||||
* 24/h power consumption (all, heating, drinking-water) | ||||||
* number of cycles (all, heating, drinking-water) | ||||||
* time between cycles |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
|
||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<parent> | ||
<groupId>org.openhab.addons.bundles</groupId> | ||
<artifactId>org.openhab.addons.reactor.bundles</artifactId> | ||
<version>4.1.0-SNAPSHOT</version> | ||
col-panic marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</parent> | ||
|
||
<artifactId>org.openhab.binding.kermi</artifactId> | ||
|
||
<name>openHAB Add-ons :: Bundles :: Kermi Binding</name> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.apache.commons</groupId> | ||
<artifactId>commons-collections4</artifactId> | ||
<version>4.1</version> | ||
<scope>compile</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<features name="org.openhab.binding.kermi-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0"> | ||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository> | ||
|
||
<feature name="openhab-binding-kermi" description="Kermi Binding" version="${project.version}"> | ||
<feature>openhab-runtime-base</feature> | ||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.kermi/${project.version}</bundle> | ||
</feature> | ||
</features> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
/** | ||
* Copyright (c) 2010-2023 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.kermi.internal; | ||
|
||
/** | ||
* @author Marco Descher - Initial contribution | ||
*/ | ||
public class KermiBaseDeviceConfiguration { | ||
public Integer address; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
/** | ||
* Copyright (c) 2010-2023 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.kermi.internal; | ||
|
||
import java.io.File; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.openhab.core.OpenHAB; | ||
import org.openhab.core.thing.ThingTypeUID; | ||
import org.openhab.core.thing.type.ChannelTypeUID; | ||
|
||
/** | ||
* The {@link KermiBindingConstants} class defines common constants, which are | ||
* used across the whole binding. | ||
* | ||
* @author Marco Descher - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public class KermiBindingConstants { | ||
|
||
private static final String BINDING_ID = "kermi"; | ||
|
||
// List of all Thing Type UIDs | ||
public static final ThingTypeUID THING_TYPE_BRIDGE = new ThingTypeUID(BINDING_ID, "bridge"); | ||
public static final ThingTypeUID THING_TYPE_DRINKINGWATER_HEATING = new ThingTypeUID(BINDING_ID, | ||
"drinkingwater-heating"); | ||
public static final ThingTypeUID THING_TYPE_ROOM_HEATING = new ThingTypeUID(BINDING_ID, "room-heating"); | ||
public static final ThingTypeUID THING_TYPE_HEATPUMP = new ThingTypeUID(BINDING_ID, "heatpump"); | ||
public static final ThingTypeUID THING_TYPE_HEATPUMP_MANAGER = new ThingTypeUID(BINDING_ID, "heatpump-manager"); | ||
|
||
public static final ChannelTypeUID CHANNEL_TYPE_TEMPERATURE = new ChannelTypeUID(BINDING_ID, "temperature"); | ||
public static final ChannelTypeUID CHANNEL_TYPE_POWER = new ChannelTypeUID(BINDING_ID, "power"); | ||
public static final ChannelTypeUID CHANNEL_TYPE_NUMBER = new ChannelTypeUID(BINDING_ID, "number"); | ||
public static final ChannelTypeUID CHANNEL_TYPE_ONOFF = new ChannelTypeUID(BINDING_ID, "onoff"); | ||
public static final ChannelTypeUID CHANNEL_TYPE_STRING = new ChannelTypeUID(BINDING_ID, "string"); | ||
|
||
// Device Constants | ||
public static final String DEVICE_ID_HEATPUMP_MANAGER = "00000000-0000-0000-0000-000000000000"; | ||
public static final int DEVICE_TYPE_HEATING_SYSTEM = 95; | ||
public static final int DEVICE_TYPE_HEATPUMP = 97; | ||
public static final int DEVICE_TYPE_HEATPUMP_MANAGER = 0; | ||
|
||
public static final String WELL_KNOWN_NAME_BS_TWE_TEMP_ACT = "BufferSystem_TweTemperatureActual"; | ||
public static final String WELL_KNOWN_NAME_FS_COOL_TEMP_ACT = "BufferSystem_CoolingTemperatureActual"; | ||
public static final String WELL_KNOWN_NAME_FS_HEAT_TEMP_ACT = "BufferSystem_HeatingTemperatureActual"; | ||
public static final String WELL_KNOWN_NAME_COMB_HEATPUMP_STATE = "Rubin_CombinedHeatpumpState"; | ||
public static final String WELL_KNOWN_NAME_COMB_HEATPUMP_CURR_COP = "Rubin_CurrentCOP"; | ||
public static final String WELL_KNOWN_NAME_CURR_OUT_CAP = "Rubin_CurrentOutputCapacity"; | ||
public static final String WELL_KNOWN_NAME_HEAT_AIR_TEMPERATURE = "LuftTemperatur"; | ||
|
||
// All Urls | ||
public static final String HPM_DEVICE_GETDEVICESBYFILTER_URL = "http://%IP%/api/Device/GetDevicesByFilter/00000000-0000-0000-0000-000000000000"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this limited to http on purpose? Would https also be possible? I guess some users have advanced reverse proxy's and so on? Same question applies to the port, is this 'fixed' on purpose? |
||
public static final String HPM_DEVICE_GETDEVICE_URL = "http://%IP%/api/Device/GetDevice/00000000-0000-0000-0000-000000000000"; | ||
public static final String HPM_DEVICE_GETALLDEVICES_URL = "http://%IP%/api/Device/GetAllDevices/00000000-0000-0000-0000-000000000000"; | ||
public static final String HPM_MENU_GETCHILDENTRIES_URL = "http://%IP%/api/Menu/GetChildEntries/00000000-0000-0000-0000-000000000000"; | ||
public static final String HPM_DATAPOINT_READVALUES_URL = "http://%IP%/api/Datapoint/ReadValues/00000000-0000-0000-0000-000000000000"; | ||
|
||
public static String parseUrl(String url, String ip) { | ||
return url.replace("%IP%", ip.trim()); | ||
} | ||
|
||
public static File getKermiUserDataFolder() { | ||
File kermiUserDataFolder = new File(OpenHAB.getUserDataFolder(), "binding.kermi"); | ||
kermiUserDataFolder.mkdir(); | ||
return kermiUserDataFolder; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/** | ||
* Copyright (c) 2010-2023 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.kermi.internal; | ||
|
||
/** | ||
* @author Marco Descher - Initial contribution | ||
*/ | ||
public class KermiBridgeConfiguration { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You might consider to make this non null by default |
||
public String hostname; | ||
public String password; | ||
public Integer refreshInterval; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* Copyright (c) 2010-2023 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.kermi.internal; | ||
|
||
import java.io.IOException; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.eclipse.jdt.annotation.Nullable; | ||
|
||
/** | ||
* Exception for unexpected response from or communication failure with the Kermi controller. | ||
* | ||
* @author Marco Descher - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public class KermiCommunicationException extends IOException { | ||
private static final long serialVersionUID = 619020705591964155L; | ||
|
||
public KermiCommunicationException(String message) { | ||
super(message); | ||
} | ||
|
||
public KermiCommunicationException(Throwable ex) { | ||
super(ex); | ||
} | ||
|
||
public KermiCommunicationException(String message, @Nullable Throwable cause) { | ||
super(message, cause); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/** | ||
* Copyright (c) 2010-2023 Contributors to the openHAB project | ||
* | ||
* See the NOTICE file(s) distributed with this work for additional | ||
* information. | ||
* | ||
* This program and the accompanying materials are made available under the | ||
* terms of the Eclipse Public License 2.0 which is available at | ||
* http://www.eclipse.org/legal/epl-2.0 | ||
* | ||
* SPDX-License-Identifier: EPL-2.0 | ||
*/ | ||
package org.openhab.binding.kermi.internal; | ||
|
||
import static org.openhab.binding.kermi.internal.KermiBindingConstants.*; | ||
|
||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.eclipse.jdt.annotation.Nullable; | ||
import org.openhab.binding.kermi.internal.api.KermiHttpUtil; | ||
import org.openhab.binding.kermi.internal.handler.KermiBaseThingHandler; | ||
import org.openhab.binding.kermi.internal.handler.KermiBridgeHandler; | ||
import org.openhab.binding.kermi.internal.model.KermiSiteInfo; | ||
import org.openhab.core.thing.Bridge; | ||
import org.openhab.core.thing.Thing; | ||
import org.openhab.core.thing.ThingTypeUID; | ||
import org.openhab.core.thing.binding.BaseThingHandlerFactory; | ||
import org.openhab.core.thing.binding.ThingHandler; | ||
import org.openhab.core.thing.binding.ThingHandlerFactory; | ||
import org.osgi.service.component.annotations.Component; | ||
|
||
/** | ||
* The {@link KermiThingHandlerFactory} is responsible for creating things and thing | ||
* handlers. | ||
* | ||
* @author Marco Descher - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
@Component(configurationPid = "binding.kermi", service = ThingHandlerFactory.class) | ||
public class KermiThingHandlerFactory extends BaseThingHandlerFactory { | ||
|
||
private KermiHttpUtil httpUtil; | ||
private KermiSiteInfo kermiSiteInfo; | ||
|
||
public KermiThingHandlerFactory() { | ||
httpUtil = new KermiHttpUtil(); | ||
kermiSiteInfo = new KermiSiteInfo(); | ||
} | ||
|
||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = new HashSet<ThingTypeUID>() { | ||
|
||
private static final long serialVersionUID = 1L; | ||
{ | ||
add(THING_TYPE_BRIDGE); | ||
add(THING_TYPE_HEATPUMP_MANAGER); | ||
add(THING_TYPE_HEATPUMP); | ||
add(THING_TYPE_DRINKINGWATER_HEATING); | ||
add(THING_TYPE_ROOM_HEATING); | ||
} | ||
}; | ||
|
||
@Override | ||
public boolean supportsThingType(ThingTypeUID thingTypeUID) { | ||
return SUPPORTED_THING_TYPES_UIDS.contains(thingTypeUID); | ||
} | ||
|
||
@Override | ||
protected @Nullable ThingHandler createHandler(Thing thing) { | ||
ThingTypeUID thingTypeUID = thing.getThingTypeUID(); | ||
|
||
if (thingTypeUID.equals(THING_TYPE_BRIDGE)) { | ||
return new KermiBridgeHandler((Bridge) thing, httpUtil, kermiSiteInfo); | ||
} else if (thingTypeUID.equals(THING_TYPE_HEATPUMP_MANAGER)) { | ||
return new KermiBaseThingHandler(thing, httpUtil, kermiSiteInfo); | ||
} else if (thingTypeUID.equals(THING_TYPE_DRINKINGWATER_HEATING)) { | ||
return new KermiBaseThingHandler(thing, httpUtil, kermiSiteInfo); | ||
} else if (thingTypeUID.equals(THING_TYPE_HEATPUMP)) { | ||
return new KermiBaseThingHandler(thing, httpUtil, kermiSiteInfo); | ||
} else if (thingTypeUID.equals(THING_TYPE_ROOM_HEATING)) { | ||
return new KermiBaseThingHandler(thing, httpUtil, kermiSiteInfo); | ||
} | ||
|
||
return null; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Every sentence has to be on its own line. Please adjust all in this file.