Skip to content

Commit

Permalink
[kermi] Initial contribution (openhab#16329)
Browse files Browse the repository at this point in the history
* [kermi] Initial working state

Signed-off-by: Kai Neuhaus <[email protected]>
  • Loading branch information
KaaNee authored Nov 23, 2024
1 parent a9a02af commit 37c6d6b
Show file tree
Hide file tree
Showing 36 changed files with 2,157 additions and 0 deletions.
5 changes: 5 additions & 0 deletions bom/openhab-addons/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1151,6 +1151,11 @@
<artifactId>org.openhab.binding.modbus.helioseasycontrols</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.modbus.kermi</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.modbus.sbc</artifactId>
Expand Down
235 changes: 235 additions & 0 deletions bundles/org.openhab.binding.modbus.kermi/README.md

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions bundles/org.openhab.binding.modbus.kermi/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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.3.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.binding.modbus.kermi</artifactId>

<name>openHAB Add-ons :: Bundles :: Kermi Modbus Binding</name>

<dependencies>
<dependency>
<groupId>org.openhab.addons.bundles</groupId>
<artifactId>org.openhab.binding.modbus</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* Copyright (c) 2010-2024 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.modbus.kermi.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.modbus.ModbusBindingConstants;
import org.openhab.core.thing.ThingTypeUID;

/**
* The {@link KermiBindingConstants} class defines common constants, which are
* used across the whole binding.
*
* @author Kai Neuhaus - Initial contribution
*/
@NonNullByDefault
public class KermiBindingConstants {

public static final String STATE_AND_ALARM_READ_ERRORS = "Status And Alarm Modbus Read Errors";
public static final String STATE_READ_ERROR = "Information Modbus Read Error";
public static final String DATA_READ_ERROR = "Data Modbus Read Error";
static final String PV_READ_ERROR = "PV Modbus Read Error";
public static final String ALARM_GROUP = "xcenter-alarm";
public static final String STATE_GROUP = "xcenter-state";
public static final String ENERGY_SOURCE_GROUP = "xcenter-energy-source";
public static final String CHARGING_CIRCUIT_GROUP = "xcenter-charging-circuit";
public static final String POWER_GROUP = "xcenter-power";
public static final String WORKHOURS_GROUP = "xcenter-workhours";
public static final String PV_GROUP = "xcenter-pv-modulation";
private static final String BINDING_ID = ModbusBindingConstants.BINDING_ID;

// Supported Thing Types
public static final ThingTypeUID THING_TYPE_KERMI_XCENTER = new ThingTypeUID(BINDING_ID, "kermi-xcenter");

// Channels for State
public static final String GLOBAL_STATE_ID_CHANNEL = "global-state-id";

// Alarm State
public static final String ALARM_STATE_CHANNEL = "alarm-state";

// Energy Source
public static final String FLOW_TEMPERATURE_CHANNEL = "flow-temperature";
public static final String RETURN_TEMPERATURE_CHANNEL = "return-temperature";
public static final String FLOW_SPEED_CHANNEL = "flow-speed";

// Charging Circuit
public static final String EXIT_TEMPERATURE_CHANNEL = "exit-temperature";
public static final String INCOMING_TEMPERATURE_CHANNEL = "incoming-temperature";
public static final String TEMPERATURE_SENSOR_OUTSIDE_CHANNEL = "temperature-sensor-outside";

// Power
public static final String COP_CHANNEL = "cop";
public static final String COP_HEATING_CHANNEL = "cop-heating";
public static final String COP_DRINKINGWATER_CHANNEL = "cop-drinkingwater";
public static final String COP_COOLING_CHANNEL = "cop-cooling";

public static final String POWER_CHANNEL = "power";
public static final String POWER_HEATING_CHANNEL = "power-heating";
public static final String POWER_DRINKINGWATER_CHANNEL = "power-drinkingwater";
public static final String POWER_COOLING_CHANNEL = "power-cooling";

public static final String ELECTRIC_POWER_CHANNEL = "electric-power";
public static final String ELECTRIC_POWER_HEATING_CHANNEL = "electric-power-heating";
public static final String ELECTRIC_POWER_DRINKINGWATER_CHANNEL = "electric-power-drinkingwater";
public static final String ELECTRIC_POWER_COOLING_CHANNEL = "electric-power-cooling";

// Work hours
public static final String WORKHOURS_FAN_CHANNEL = "workhours-fan";
public static final String WORKHOURS_STORAGE_LOADING_PUMP_CHANNEL = "workhours-storage-loading-pump";
public static final String WORKHOURS_COMPRESSOR_CHANNEL = "workhours-compressor";

// PV
public static final String PV_STATE_CHANNEL = "pv-state";
public static final String PV_POWER_CHANNEL = "pv-power";
public static final String PV_TARGET_TEMPERATURE_HEATING_CHANNEL = "pv-target-temperature-heating";
public static final String PV_TARGET_TEMPERATURE_DRINKINGWATER_CHANNEL = "pv-target-temperature-drinkingwater";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* Copyright (c) 2010-2024 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.modbus.kermi.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* The {@link KermiConfiguration} class contains fields mapping thing configuration parameters.
*
* @author Kai Neuhaus - Initial contribution
*/
@NonNullByDefault
public class KermiConfiguration {

public int refresh = 5000;
public boolean pvEnabled = false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright (c) 2010-2024 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.modbus.kermi.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.modbus.kermi.internal.handler.KermiXcenterThingHandler;
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 KermiHandlerFactory} is responsible for creating things and thing handlers.
*
* @author Kai Neuhaus - Initial contribution
*/
@NonNullByDefault
@Component(configurationPid = "binding.kermi", service = ThingHandlerFactory.class)
public class KermiHandlerFactory extends BaseThingHandlerFactory {
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return thingTypeUID.equals(KermiBindingConstants.THING_TYPE_KERMI_XCENTER);
}

@Override
protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
if (KermiBindingConstants.THING_TYPE_KERMI_XCENTER.equals(thingTypeUID)) {
return new KermiXcenterThingHandler((Bridge) thing);
} // else here
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright (c) 2010-2024 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.modbus.kermi.internal.dto;

import static org.openhab.binding.modbus.kermi.internal.modbus.KermiModbusConstans.ALARM_REG_SIZE;

import org.openhab.binding.modbus.kermi.internal.modbus.Data;
import org.openhab.core.io.transport.modbus.ModbusBitUtilities;
import org.openhab.core.library.types.OnOffType;

/**
* The {@link AlarmDTO} Data object for Kermi Xcenter
*
* @author Kai Neuhaus - Initial contribution
*/
public class AlarmDTO implements Data {

public OnOffType alarmIsActive;

public AlarmDTO(byte[] bArray) {
int status = ModbusBitUtilities.extractBit(bArray, ALARM_REG_SIZE);
alarmIsActive = OnOffType.from(status != 0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* Copyright (c) 2010-2024 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.modbus.kermi.internal.dto;

import static org.openhab.core.library.unit.Units.LITRE_PER_MINUTE;

import javax.measure.quantity.Temperature;

import org.openhab.binding.modbus.kermi.internal.modbus.Data;
import org.openhab.core.io.transport.modbus.ValueBuffer;
import org.openhab.core.library.dimension.VolumetricFlowRate;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.SIUnits;

/**
* The {@link ChargingCircuitDTO} Data object for Kermi Xcenter
*
* @author Kai Neuhaus - Initial contribution
*/
public class ChargingCircuitDTO implements Data {

public QuantityType<Temperature> flowTemperature;
public QuantityType<Temperature> returnFlowTemperature;
public QuantityType<VolumetricFlowRate> flowSpeed;

public ChargingCircuitDTO(byte[] bArray) {
ValueBuffer wrap = ValueBuffer.wrap(bArray);
flowTemperature = QuantityType.valueOf(DataConverter.getSDoubleValue(wrap, 0.1), SIUnits.CELSIUS);
returnFlowTemperature = QuantityType.valueOf(DataConverter.getSDoubleValue(wrap, 0.1), SIUnits.CELSIUS);
flowSpeed = QuantityType.valueOf(DataConverter.getSDoubleValue(wrap, 0.1), LITRE_PER_MINUTE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* Copyright (c) 2010-2024 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.modbus.kermi.internal.dto;

import java.nio.charset.StandardCharsets;
import java.util.BitSet;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.io.transport.modbus.ModbusBitUtilities;
import org.openhab.core.io.transport.modbus.ValueBuffer;

/**
* The {@link DataConverter} Helper class to convert bytes from modbus into desired data format
*
* @author Bernd Weymann - Initial contribution
* @author Kai Neuhaus - used for Modbus.Kermi Binding
*/
@NonNullByDefault
public class DataConverter {

/**
* Retrieves a double value from the first two bytes of the provided {@link ValueBuffer} using the given correction
* factor.
*
* @param wrap The {@link ValueBuffer} from which to extract the bytes.
* @param factor The correction factor to apply to the extracted value.
* @return The calculated double value.
*/
public static double getUDoubleValue(ValueBuffer wrap, double factor) {
return round(wrap.getUInt16() * factor, 2);
}

/**
* Retrieves a signed double value from the first two bytes of the provided {@link ValueBuffer} using the given
* correction factor.
*
* @param wrap The {@link ValueBuffer} from which to extract the bytes. This {@link ValueBuffer} should contain at
* least two bytes.
* @param factor The correction factor to apply to the extracted value. This factor is used to adjust the calculated
* value.
* @return The calculated signed double value. The value is obtained by extracting the first two bytes from the
* {@link ValueBuffer},
* converting them to a signed 16-bit integer, multiplying it by the correction factor, and rounding the
* result to two decimal places.
*/
public static double getSDoubleValue(ValueBuffer wrap, double factor) {
return round(wrap.getSInt16() * factor, 2);
}

public static String getString(byte[] bArray) {
return ModbusBitUtilities.extractStringFromBytes(bArray, 0, bArray.length, StandardCharsets.US_ASCII).trim();
}

public static int toInt(BitSet bitSet) {
int intValue = 0;
for (int bit = 0; bit < bitSet.length(); bit++) {
if (bitSet.get(bit)) {
intValue |= (1 << bit);
}
}
return intValue;
}

public static double round(double value, int places) {
if (places < 0) {
throw new IllegalArgumentException();
}

long factor = (long) Math.pow(10, places);
long tmp = Math.round(value * factor);
return (double) tmp / factor;
}
}
Loading

0 comments on commit 37c6d6b

Please sign in to comment.