mirror of
https://github.com/openhab/openhab-addons.git
synced 2025-01-10 15:11:59 +01:00
[grundfosalpha] Initial contribution (#15907)
* [Bluez] Disable automatic filtering of duplicate data * Added Grundfos Alpha binding Signed-off-by: Markus Heberling <markus@heberling.net>
This commit is contained in:
parent
c22de9bcd3
commit
f5065ad6e4
@ -46,6 +46,7 @@
|
|||||||
/bundles/org.openhab.binding.bluetooth.enoceanble/ @pfink
|
/bundles/org.openhab.binding.bluetooth.enoceanble/ @pfink
|
||||||
/bundles/org.openhab.binding.bluetooth.generic/ @cpmeister
|
/bundles/org.openhab.binding.bluetooth.generic/ @cpmeister
|
||||||
/bundles/org.openhab.binding.bluetooth.govee/ @cpmeister
|
/bundles/org.openhab.binding.bluetooth.govee/ @cpmeister
|
||||||
|
/bundles/org.openhab.binding.bluetooth.grundfosalpha/ @tisoft
|
||||||
/bundles/org.openhab.binding.bluetooth.radoneye/ @petero-dk
|
/bundles/org.openhab.binding.bluetooth.radoneye/ @petero-dk
|
||||||
/bundles/org.openhab.binding.bluetooth.roaming/ @cpmeister
|
/bundles/org.openhab.binding.bluetooth.roaming/ @cpmeister
|
||||||
/bundles/org.openhab.binding.bluetooth.ruuvitag/ @ssalonen
|
/bundles/org.openhab.binding.bluetooth.ruuvitag/ @ssalonen
|
||||||
|
@ -221,6 +221,11 @@
|
|||||||
<artifactId>org.openhab.binding.bluetooth.govee</artifactId>
|
<artifactId>org.openhab.binding.bluetooth.govee</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
|
<artifactId>org.openhab.binding.bluetooth.grundfosalpha</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openhab.addons.bundles</groupId>
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
<artifactId>org.openhab.binding.bluetooth.radoneye</artifactId>
|
<artifactId>org.openhab.binding.bluetooth.radoneye</artifactId>
|
||||||
|
@ -12,13 +12,20 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.binding.bluetooth.bluez.internal;
|
package org.openhab.binding.bluetooth.bluez.internal;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.bluez.exceptions.BluezFailedException;
|
||||||
|
import org.bluez.exceptions.BluezInvalidArgumentsException;
|
||||||
|
import org.bluez.exceptions.BluezNotReadyException;
|
||||||
|
import org.bluez.exceptions.BluezNotSupportedException;
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.freedesktop.dbus.types.Variant;
|
||||||
import org.openhab.binding.bluetooth.AbstractBluetoothBridgeHandler;
|
import org.openhab.binding.bluetooth.AbstractBluetoothBridgeHandler;
|
||||||
import org.openhab.binding.bluetooth.BluetoothAddress;
|
import org.openhab.binding.bluetooth.BluetoothAddress;
|
||||||
import org.openhab.binding.bluetooth.bluez.internal.events.AdapterDiscoveringChangedEvent;
|
import org.openhab.binding.bluetooth.bluez.internal.events.AdapterDiscoveringChangedEvent;
|
||||||
@ -139,6 +146,15 @@ public class BlueZBridgeHandler extends AbstractBluetoothBridgeHandler<BlueZBlue
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, Variant<?>> filter = new HashMap<>();
|
||||||
|
filter.put("DuplicateData", new Variant<>(true));
|
||||||
|
try {
|
||||||
|
adapter.setDiscoveryFilter(filter);
|
||||||
|
} catch (BluezInvalidArgumentsException | BluezFailedException | BluezNotSupportedException
|
||||||
|
| BluezNotReadyException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
// now lets make sure that discovery is turned on
|
// now lets make sure that discovery is turned on
|
||||||
if (!localAdapter.startDiscovery()) {
|
if (!localAdapter.startDiscovery()) {
|
||||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, "Trying to start discovery");
|
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.NONE, "Trying to start discovery");
|
||||||
|
13
bundles/org.openhab.binding.bluetooth.grundfosalpha/NOTICE
Normal file
13
bundles/org.openhab.binding.bluetooth.grundfosalpha/NOTICE
Normal file
@ -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
|
@ -0,0 +1,49 @@
|
|||||||
|
# GrundfosAlpha Binding
|
||||||
|
|
||||||
|
This adds support for reading out the data of Grundfos Alpha Pumps with a [Grundfos Alpha Reader](https://product-selection.grundfos.com/products/alpha-reader)
|
||||||
|
|
||||||
|
The reverse engineering of the protocol was taken from [https://github.com/JsBergbau/AlphaDecoder](https://github.com/JsBergbau/AlphaDecoder).
|
||||||
|
|
||||||
|
## Supported Things
|
||||||
|
|
||||||
|
- `mi401`: The Grundfos MI401 ALPHA Reader
|
||||||
|
|
||||||
|
## Discovery
|
||||||
|
|
||||||
|
All readers are auto-detected as soon as Bluetooth is configured in openHAB and the MI401 device is powered on.
|
||||||
|
|
||||||
|
## Thing Configuration
|
||||||
|
|
||||||
|
### `mi401` Thing Configuration
|
||||||
|
|
||||||
|
| Name | Type | Description | Default | Required | Advanced |
|
||||||
|
|---------|------|-----------------------------------------------|---------|----------|----------|
|
||||||
|
| address | text | Bluetooth address in XX:XX:XX:XX:XX:XX format | N/A | yes | no |
|
||||||
|
|
||||||
|
## Channels
|
||||||
|
|
||||||
|
| Channel | Type | Read/Write | Description |
|
||||||
|
|------------------|---------------------------|------------|------------------------------------|
|
||||||
|
| rssi | Number | R | Received Signal Strength Indicator |
|
||||||
|
| flow-rate | Number:VolumetricFlowRate | R | The flow rate of the pump |
|
||||||
|
| pump-head | Number:Length | R | The water head above the pump |
|
||||||
|
| pump-temperature | Number:Temperature | R | The temperature of the pump |
|
||||||
|
| battery-level | Number:Dimensionless | R | The battery level of the reader |
|
||||||
|
|
||||||
|
## Full Example
|
||||||
|
|
||||||
|
grundfos_alpha.things (assuming you have a Bluetooth bridge with the ID `bluetooth:bluegiga:adapter1`:
|
||||||
|
|
||||||
|
```java
|
||||||
|
bluetooth:mi401:hci0:sensor1 "Grundfos Alpha Reader 1" (bluetooth:bluegiga:adapter1) [ address="12:34:56:78:9A:BC" ]
|
||||||
|
```
|
||||||
|
|
||||||
|
grundfos_alpha.items:
|
||||||
|
|
||||||
|
```java
|
||||||
|
Number RSSI "RSSI [%.1f dBm]" <QualityOfService> { channel="bluetooth:mi401:hci0:sensor1:rssi" }
|
||||||
|
Number:VolumetricFlowRate Flow_rate "Flowrate [%.1f %unit%]" <flow> { channel="bluetooth:mi401:hci0:sensor1:flow-rate" }
|
||||||
|
Number:Length Pump_Head "Pump head [%.1f %unit%]" <water> { channel="bluetooth:mi401:hci0:sensor1:pump-head" }
|
||||||
|
Number:Temperature Pump_Temperature "Temperature [%.1f %unit%]" <temperature> { channel="bluetooth:mi401:hci0:sensor1:pump-temperature" }
|
||||||
|
Number:Dimensionless Battery_Level "Battery Level [%d %%]" <battery> { channel="bluetooth:mi401:hci0:sensor1:battery-level" }
|
||||||
|
```
|
25
bundles/org.openhab.binding.bluetooth.grundfosalpha/pom.xml
Normal file
25
bundles/org.openhab.binding.bluetooth.grundfosalpha/pom.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?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>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>org.openhab.binding.bluetooth.grundfosalpha</artifactId>
|
||||||
|
|
||||||
|
<name>openHAB Add-ons :: Bundles :: GrundfosAlpha Binding</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openhab.addons.bundles</groupId>
|
||||||
|
<artifactId>org.openhab.binding.bluetooth</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<features name="org.openhab.binding.bluetooth.grundfosalpha-${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-bluetooth-grundfosalpha" description="GrundfosAlpha Binding" version="${project.version}">
|
||||||
|
<feature>openhab-runtime-base</feature>
|
||||||
|
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.bluetooth/${project.version}</bundle>
|
||||||
|
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.binding.bluetooth.grundfosalpha/${project.version}</bundle>
|
||||||
|
</feature>
|
||||||
|
</features>
|
@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* 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.bluetooth.grundfosalpha.internal;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.bluetooth.BluetoothBindingConstants;
|
||||||
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link GrundfosAlphaBindingConstants} class defines common constants, which are
|
||||||
|
* used across the whole binding.
|
||||||
|
*
|
||||||
|
* @author Markus Heberling - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class GrundfosAlphaBindingConstants {
|
||||||
|
|
||||||
|
// List of all Thing Type UIDs
|
||||||
|
public static final ThingTypeUID THING_TYPE_MI401 = new ThingTypeUID(BluetoothBindingConstants.BINDING_ID, "mi401");
|
||||||
|
|
||||||
|
// List of all Channel ids
|
||||||
|
public static final String CHANNEL_TYPE_FLOW_RATE = "flow-rate";
|
||||||
|
public static final String CHANNEL_TYPE_PUMP_HEAD = "pump-head";
|
||||||
|
public static final String CHANNEL_TYPE_BATTERY_LEVEL = "battery-level";
|
||||||
|
public static final String CHANNEL_TYPE_PUMP_TEMPERATUR = "pump-temperature";
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
/**
|
||||||
|
* 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.bluetooth.grundfosalpha.internal;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.binding.bluetooth.BluetoothBindingConstants;
|
||||||
|
import org.openhab.binding.bluetooth.discovery.BluetoothDiscoveryDevice;
|
||||||
|
import org.openhab.binding.bluetooth.discovery.BluetoothDiscoveryParticipant;
|
||||||
|
import org.openhab.core.config.discovery.DiscoveryResult;
|
||||||
|
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
|
||||||
|
import org.openhab.core.thing.Thing;
|
||||||
|
import org.openhab.core.thing.ThingTypeUID;
|
||||||
|
import org.openhab.core.thing.ThingUID;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This discovery participant is able to recognize Grundfos Alpha devices and create discovery results for them.
|
||||||
|
*
|
||||||
|
* @author Markus Heberling - Initial contribution
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
@Component
|
||||||
|
public class GrundfosAlphaDiscoveryParticipant implements BluetoothDiscoveryParticipant {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(GrundfosAlphaDiscoveryParticipant.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<ThingTypeUID> getSupportedThingTypeUIDs() {
|
||||||
|
return Set.of(GrundfosAlphaBindingConstants.THING_TYPE_MI401);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresConnection(BluetoothDiscoveryDevice device) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable ThingUID getThingUID(BluetoothDiscoveryDevice device) {
|
||||||
|
Integer manufacturerId = device.getManufacturerId();
|
||||||
|
@Nullable
|
||||||
|
String name = device.getName();
|
||||||
|
logger.debug("Discovered device {} with manufacturerId {} and name {}", device.getAddress(), manufacturerId,
|
||||||
|
name);
|
||||||
|
if ("MI401".equals(name)) {
|
||||||
|
return new ThingUID(GrundfosAlphaBindingConstants.THING_TYPE_MI401, device.getAdapter().getUID(),
|
||||||
|
device.getAddress().toString().toLowerCase().replace(":", ""));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable DiscoveryResult createResult(BluetoothDiscoveryDevice device) {
|
||||||
|
ThingUID thingUID = getThingUID(device);
|
||||||
|
if (thingUID == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String label = "Grundfos Alpha Reader MI401";
|
||||||
|
Map<String, Object> properties = new HashMap<>();
|
||||||
|
properties.put(BluetoothBindingConstants.CONFIGURATION_ADDRESS, device.getAddress().toString());
|
||||||
|
properties.put(Thing.PROPERTY_VENDOR, "Grundfos");
|
||||||
|
Integer txPower = device.getTxPower();
|
||||||
|
if (txPower != null) {
|
||||||
|
properties.put(BluetoothBindingConstants.PROPERTY_TXPOWER, Integer.toString(txPower));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the discovery result and add to the inbox
|
||||||
|
return DiscoveryResultBuilder.create(thingUID).withProperties(properties)
|
||||||
|
.withRepresentationProperty(BluetoothBindingConstants.CONFIGURATION_ADDRESS)
|
||||||
|
.withBridge(device.getAdapter().getUID()).withLabel(label).build();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* 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.bluetooth.grundfosalpha.internal;
|
||||||
|
|
||||||
|
import static org.openhab.binding.bluetooth.grundfosalpha.internal.GrundfosAlphaBindingConstants.*;
|
||||||
|
|
||||||
|
import javax.measure.quantity.Dimensionless;
|
||||||
|
import javax.measure.quantity.Length;
|
||||||
|
import javax.measure.quantity.Temperature;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.openhab.binding.bluetooth.BeaconBluetoothHandler;
|
||||||
|
import org.openhab.binding.bluetooth.BluetoothDeviceListener;
|
||||||
|
import org.openhab.binding.bluetooth.notification.BluetoothScanNotification;
|
||||||
|
import org.openhab.core.library.dimension.VolumetricFlowRate;
|
||||||
|
import org.openhab.core.library.types.QuantityType;
|
||||||
|
import org.openhab.core.library.unit.SIUnits;
|
||||||
|
import org.openhab.core.library.unit.Units;
|
||||||
|
import org.openhab.core.thing.Thing;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link GrundfosAlphaHandler} is responsible for handling commands, which are
|
||||||
|
* sent to one of the channels.
|
||||||
|
*
|
||||||
|
* @author Markus Heberling - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class GrundfosAlphaHandler extends BeaconBluetoothHandler implements BluetoothDeviceListener {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(GrundfosAlphaHandler.class);
|
||||||
|
|
||||||
|
public GrundfosAlphaHandler(Thing thing) {
|
||||||
|
super(thing);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onScanRecordReceived(BluetoothScanNotification scanNotification) {
|
||||||
|
super.onScanRecordReceived(scanNotification);
|
||||||
|
byte[] data = scanNotification.getManufacturerData();
|
||||||
|
if (data != null && data.length == 21) {
|
||||||
|
int batteryLevel = (data[5] & 0xFF) * 25;
|
||||||
|
QuantityType<Dimensionless> quantity = new QuantityType<>(batteryLevel, Units.PERCENT);
|
||||||
|
updateState(CHANNEL_TYPE_BATTERY_LEVEL, quantity);
|
||||||
|
|
||||||
|
float flowRate = ((data[9] & 0xFF) << 8 | (data[8] & 0xFF)) / 6553.5f;
|
||||||
|
QuantityType<VolumetricFlowRate> quantity2 = new QuantityType<>(flowRate, Units.CUBICMETRE_PER_HOUR);
|
||||||
|
updateState(CHANNEL_TYPE_FLOW_RATE, quantity2);
|
||||||
|
|
||||||
|
float pumpHead = ((data[11] & 0xFF) << 8 | (data[10] & 0xFF)) / 3276.7f;
|
||||||
|
QuantityType<Length> quantity3 = new QuantityType<>(pumpHead, SIUnits.METRE);
|
||||||
|
updateState(CHANNEL_TYPE_PUMP_HEAD, quantity3);
|
||||||
|
|
||||||
|
float pumpTemperature = data[14] & 0xFF;
|
||||||
|
QuantityType<Temperature> quantity4 = new QuantityType<>(pumpTemperature, SIUnits.CELSIUS);
|
||||||
|
updateState(CHANNEL_TYPE_PUMP_TEMPERATUR, quantity4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
/**
|
||||||
|
* 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.bluetooth.grundfosalpha.internal;
|
||||||
|
|
||||||
|
import static org.openhab.binding.bluetooth.grundfosalpha.internal.GrundfosAlphaBindingConstants.*;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
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 GrundfosAlphaHandlerFactory} is responsible for creating things and thing
|
||||||
|
* handlers.
|
||||||
|
*
|
||||||
|
* @author Markus Heberling - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
@Component(configurationPid = "binding.bluetooth.grundfosalpha", service = ThingHandlerFactory.class)
|
||||||
|
public class GrundfosAlphaHandlerFactory extends BaseThingHandlerFactory {
|
||||||
|
|
||||||
|
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_MI401);
|
||||||
|
|
||||||
|
@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 (THING_TYPE_MI401.equals(thingTypeUID)) {
|
||||||
|
return new GrundfosAlphaHandler(thing);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
# thing types
|
||||||
|
|
||||||
|
thing-type.bluetooth.mi401.label = Grundfos Alpha Reader MI401
|
||||||
|
thing-type.bluetooth.mi401.description = A Grundfos Alpha Reader MI401
|
||||||
|
|
||||||
|
# thing types config
|
||||||
|
|
||||||
|
thing-type.config.bluetooth.mi401.address.label = Address
|
||||||
|
thing-type.config.bluetooth.mi401.address.description = Bluetooth address in XX:XX:XX:XX:XX:XX format
|
||||||
|
|
||||||
|
# channel types
|
||||||
|
|
||||||
|
channel-type.bluetooth.grundfos-flow.label = Current Flow
|
||||||
|
channel-type.bluetooth.grundfos-flow.description = Current flow
|
||||||
|
channel-type.bluetooth.grundfos-head.label = Current Head
|
||||||
|
channel-type.bluetooth.grundfos-head.description = Current head
|
||||||
|
channel-type.bluetooth.grundfos-temperature.label = Current Pump Temperature
|
||||||
|
channel-type.bluetooth.grundfos-temperature.description = Current pump temperature
|
@ -0,0 +1,62 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<thing:thing-descriptions bindingId="bluetooth"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:thing="https://openhab.org/schemas/thing-description/v1.0.0"
|
||||||
|
xsi:schemaLocation="https://openhab.org/schemas/thing-description/v1.0.0 https://openhab.org/schemas/thing-description-1.0.0.xsd">
|
||||||
|
|
||||||
|
<channel-type id="grundfos-flow">
|
||||||
|
<item-type>Number:VolumetricFlowRate</item-type>
|
||||||
|
<label>Current Flow</label>
|
||||||
|
<description>Current flow</description>
|
||||||
|
<category>Flow</category>
|
||||||
|
<state readOnly="true" pattern="%.2f %unit%"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="grundfos-head">
|
||||||
|
<item-type>Number:Length</item-type>
|
||||||
|
<label>Current Head</label>
|
||||||
|
<description>Current head</description>
|
||||||
|
<category>Water</category>
|
||||||
|
<state readOnly="true" pattern="%.2f %unit%"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<channel-type id="grundfos-temperature">
|
||||||
|
<item-type>Number:Temperature</item-type>
|
||||||
|
<label>Current Pump Temperature</label>
|
||||||
|
<description>Current pump temperature</description>
|
||||||
|
<category>Temperature</category>
|
||||||
|
<tags>
|
||||||
|
<tag>Measurement</tag>
|
||||||
|
<tag>Temperature</tag>
|
||||||
|
</tags>
|
||||||
|
<state readOnly="true" pattern="%.2f %unit%"/>
|
||||||
|
</channel-type>
|
||||||
|
|
||||||
|
<thing-type id="mi401">
|
||||||
|
<supported-bridge-type-refs>
|
||||||
|
<bridge-type-ref id="roaming"/>
|
||||||
|
<bridge-type-ref id="bluegiga"/>
|
||||||
|
<bridge-type-ref id="bluez"/>
|
||||||
|
</supported-bridge-type-refs>
|
||||||
|
|
||||||
|
<label>Grundfos Alpha Reader MI401</label>
|
||||||
|
<description>A Grundfos Alpha Reader MI401</description>
|
||||||
|
<category>Pump</category>
|
||||||
|
|
||||||
|
<channels>
|
||||||
|
<channel id="rssi" typeId="rssi"/>
|
||||||
|
<channel id="flow-rate" typeId="grundfos-flow"/>
|
||||||
|
<channel id="pump-head" typeId="grundfos-head"/>
|
||||||
|
<channel id="pump-temperature" typeId="grundfos-temperature"/>
|
||||||
|
<channel id="battery-level" typeId="system.battery-level"/>
|
||||||
|
</channels>
|
||||||
|
|
||||||
|
<config-description>
|
||||||
|
<parameter name="address" type="text">
|
||||||
|
<label>Address</label>
|
||||||
|
<description>Bluetooth address in XX:XX:XX:XX:XX:XX format</description>
|
||||||
|
</parameter>
|
||||||
|
</config-description>
|
||||||
|
|
||||||
|
</thing-type>
|
||||||
|
</thing:thing-descriptions>
|
@ -0,0 +1,91 @@
|
|||||||
|
/**
|
||||||
|
* 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.bluetooth.grundfosalpha.internal;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
import org.openhab.binding.bluetooth.notification.BluetoothScanNotification;
|
||||||
|
import org.openhab.core.library.types.QuantityType;
|
||||||
|
import org.openhab.core.library.unit.SIUnits;
|
||||||
|
import org.openhab.core.library.unit.Units;
|
||||||
|
import org.openhab.core.thing.ChannelUID;
|
||||||
|
import org.openhab.core.thing.Thing;
|
||||||
|
import org.openhab.core.thing.ThingStatus;
|
||||||
|
import org.openhab.core.thing.ThingStatusDetail;
|
||||||
|
import org.openhab.core.thing.ThingStatusInfo;
|
||||||
|
import org.openhab.core.thing.ThingUID;
|
||||||
|
import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||||
|
import org.openhab.core.util.HexUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test the {@link GrundfosAlphaHandler}.
|
||||||
|
*
|
||||||
|
* @author Markus Heberling - Initial contribution
|
||||||
|
*/
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class GrundfosAlphaHandlerTest {
|
||||||
|
|
||||||
|
private @Mock Thing thingMock;
|
||||||
|
|
||||||
|
private @Mock ThingHandlerCallback callback;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMessageType0xf1() {
|
||||||
|
byte[] data = HexUtils.hexToBytes("15f130017a5113030300994109589916613003004005");
|
||||||
|
final BluetoothScanNotification scanNotification = new BluetoothScanNotification();
|
||||||
|
scanNotification.setManufacturerData(data);
|
||||||
|
final GrundfosAlphaHandler handler = new GrundfosAlphaHandler(thingMock);
|
||||||
|
handler.setCallback(callback);
|
||||||
|
handler.onScanRecordReceived(scanNotification);
|
||||||
|
|
||||||
|
verify(callback).statusUpdated(thingMock,
|
||||||
|
new ThingStatusInfo(ThingStatus.ONLINE, ThingStatusDetail.NONE, null));
|
||||||
|
|
||||||
|
verifyNoMoreInteractions(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMessageType0xf2() {
|
||||||
|
when(thingMock.getUID()).thenReturn(new ThingUID(GrundfosAlphaBindingConstants.THING_TYPE_MI401, "dummy"));
|
||||||
|
|
||||||
|
byte[] data = HexUtils.hexToBytes("14f23001650305065419b9180f011f007c1878170d");
|
||||||
|
final BluetoothScanNotification scanNotification = new BluetoothScanNotification();
|
||||||
|
scanNotification.setManufacturerData(data);
|
||||||
|
final GrundfosAlphaHandler handler = new GrundfosAlphaHandler(thingMock);
|
||||||
|
handler.setCallback(callback);
|
||||||
|
handler.onScanRecordReceived(scanNotification);
|
||||||
|
|
||||||
|
verify(callback).statusUpdated(thingMock,
|
||||||
|
new ThingStatusInfo(ThingStatus.ONLINE, ThingStatusDetail.NONE, null));
|
||||||
|
verify(callback).stateUpdated(
|
||||||
|
new ChannelUID(thingMock.getUID(), GrundfosAlphaBindingConstants.CHANNEL_TYPE_BATTERY_LEVEL),
|
||||||
|
new QuantityType<>(75, Units.PERCENT));
|
||||||
|
verify(callback).stateUpdated(
|
||||||
|
new ChannelUID(thingMock.getUID(), GrundfosAlphaBindingConstants.CHANNEL_TYPE_FLOW_RATE),
|
||||||
|
new QuantityType<>(0.98939496, Units.CUBICMETRE_PER_HOUR));
|
||||||
|
verify(callback).stateUpdated(
|
||||||
|
new ChannelUID(thingMock.getUID(), GrundfosAlphaBindingConstants.CHANNEL_TYPE_PUMP_HEAD),
|
||||||
|
new QuantityType<>(1.9315165, SIUnits.METRE));
|
||||||
|
verify(callback).stateUpdated(
|
||||||
|
new ChannelUID(thingMock.getUID(), GrundfosAlphaBindingConstants.CHANNEL_TYPE_PUMP_TEMPERATUR),
|
||||||
|
new QuantityType<>(31, SIUnits.CELSIUS));
|
||||||
|
|
||||||
|
verifyNoMoreInteractions(callback);
|
||||||
|
}
|
||||||
|
}
|
@ -78,6 +78,7 @@
|
|||||||
<module>org.openhab.binding.bluetooth.enoceanble</module>
|
<module>org.openhab.binding.bluetooth.enoceanble</module>
|
||||||
<module>org.openhab.binding.bluetooth.generic</module>
|
<module>org.openhab.binding.bluetooth.generic</module>
|
||||||
<module>org.openhab.binding.bluetooth.govee</module>
|
<module>org.openhab.binding.bluetooth.govee</module>
|
||||||
|
<module>org.openhab.binding.bluetooth.grundfosalpha</module>
|
||||||
<module>org.openhab.binding.bluetooth.radoneye</module>
|
<module>org.openhab.binding.bluetooth.radoneye</module>
|
||||||
<module>org.openhab.binding.bluetooth.roaming</module>
|
<module>org.openhab.binding.bluetooth.roaming</module>
|
||||||
<module>org.openhab.binding.bluetooth.ruuvitag</module>
|
<module>org.openhab.binding.bluetooth.ruuvitag</module>
|
||||||
|
Loading…
Reference in New Issue
Block a user