Skip to content
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

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f707659
wip
col-panic Sep 22, 2023
e3e9416
Merge branch 'main' of https://github.com/openhab/openhab-addons.git …
col-panic Sep 23, 2023
8afc488
Merge branch 'main' of https://github.com/openhab/openhab-addons.git …
col-panic Sep 25, 2023
b5c56dc
Merge branch 'main' of https://github.com/openhab/openhab-addons.git …
col-panic Sep 27, 2023
5128c42
Merge branch 'main' of https://github.com/openhab/openhab-addons.git …
col-panic Sep 29, 2023
fbed6f2
Merge branch 'main' of https://github.com/openhab/openhab-addons.git …
col-panic Oct 1, 2023
b293457
org.openhab.binding.kermi initial contribution
col-panic Oct 1, 2023
05c0596
Merge branch 'main' of https://github.com/openhab/openhab-addons.git …
col-panic Oct 1, 2023
4e749ad
Merge branch 'main' of https://github.com/openhab/openhab-addons.git …
col-panic Oct 11, 2023
5ca5a2b
15680 org.openhab.binding.kermi initial contribution
col-panic Sep 22, 2023
1d0f98b
15680 org.openhab.binding.kermi pom.xml, build fixes
col-panic Oct 2, 2023
02899a4
15680 org.openhab.binding.kermi pom.xml commons-collections4 dependency
col-panic Oct 2, 2023
69db59c
15680 org.openhab.binding.kermi minor fixes
col-panic Oct 2, 2023
731087b
Dynamically resolve all channels, multiple updates
col-panic Oct 13, 2023
ebf5838
correct kwh to watt conversion
col-panic Oct 15, 2023
e0ece61
support datapointType 0,3,4
col-panic Oct 20, 2023
9211798
satisfy checkstyle
col-panic Nov 11, 2023
15b651b
Fix value presentation for datapointType '0', refactor instanceof to J17
col-panic Nov 11, 2023
6ba94a9
Update bundles/org.openhab.binding.kermi/pom.xml
col-panic Dec 23, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,11 @@
<artifactId>org.openhab.binding.keba</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.kermi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.km200</artifactId>
Expand Down
13 changes: 13 additions & 0 deletions bundles/org.openhab.binding.kermi/NOTICE
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
78 changes: 78 additions & 0 deletions bundles/org.openhab.binding.kermi/README.md
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
Copy link
Contributor

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.

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
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor

Choose a reason for hiding this comment

The 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:

| Property        | Default | Required | Description      |
|-----------------|---------|:--------:|------------------|
| hostname        |         |   Yes    | Api user         |
| password        |         |   Yes    | Api password     |
| refreshInterval | 60      |   Yes    | Refresh interval |

```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
```
```java

// 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 ]
}

Copy link
Contributor

Choose a reason for hiding this comment

The 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.

```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
```
```java

// kermi.items
Number:Temperature Drinking_water_temperature {channel="kermi:drinkingwater-heating:heatpumpbridge:dwheating:BufferSystem_TweTemperatureActual"}

Copy link
Contributor

Choose a reason for hiding this comment

The 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"}

Copy link
Contributor

Choose a reason for hiding this comment

The 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"}

Copy link
Contributor

Choose a reason for hiding this comment

The 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
Copy link
Contributor

Choose a reason for hiding this comment

The 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
Copy link
Contributor

Choose a reason for hiding this comment

The 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
26 changes: 26 additions & 0 deletions bundles/org.openhab.binding.kermi/pom.xml
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.2.0-SNAPSHOT</version>
</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";
Copy link
Contributor

Choose a reason for hiding this comment

The 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 {
Copy link
Contributor

Choose a reason for hiding this comment

The 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;
}
}
Loading
Loading