[openwebnet] add support for Energy Meter (#10191)

Signed-off-by: Andrea Conte <andrea@conte.com>
This commit is contained in:
Conte Andrea 2021-03-21 20:26:21 +01:00 committed by GitHub
parent 65b7467e56
commit 2e770a375e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 217 additions and 9 deletions

View File

@ -8,6 +8,8 @@ The binding supports:
- auto discovery of BUS/SCS IP and ZigBee USB gateways; auto discovery of devices
- commands from openHAB and feedback (events) from BUS/SCS and wireless network
![MyHOMEServer1 Gateway](doc/MyHOMEServer1_gateway.jpg)
![F454 Gateway](doc/F454_gateway.png)
![ZigBee USB Gateway](doc/USB_gateway.jpg)
@ -40,6 +42,7 @@ The following Things and OpenWebNet `WHOs` are supported:
| Gateway Management | `13` | `bus_gateway` | Any IP gateway supporting OpenWebNet protocol should work (e.g. F454 / MyHOMEServer1 / MH202 / F455 / MH200N, ...) | Successfully tested: F454, MyHOMEServer1, MyHOME_Screen10, F455, F452, F453AV, MH201, MH202, MH200N. Some connection stability issues/gateway resets reported with MH202 |
| Lighting | `1` | `bus_on_off_switch`, `bus_dimmer` | BUS switches and dimmers | Successfully tested: F411/2, F411/4, F411U2, F422, F429. Some discovery issues reported with F429 (DALI Dimmers) |
| Automation | `2` | `bus_automation` | BUS roller shutters, with position feedback and auto-calibration | Successfully tested: LN4672M2 |
| Energy Management | `18` | `bus_energy_meter` | Energy Management | Successfully tested: F520, F521 |
### For ZigBee (Radio)
@ -129,7 +132,7 @@ Devices support some of the following channels:
| `switch` or `switch_01`/`02` for ZigBee | Switch | To switch the device `ON` and `OFF` | R/W |
| `brightness` | Dimmer | To adjust the brightness value (Percent, `ON`, `OFF`) | R/W |
| `shutter` | Rollershutter | To activate roller shutters (`UP`, `DOWN`, `STOP`, Percent - [see Shutter position](#shutter-position)) | R/W |
| `power` | Number:Power | The current active power usage from Energy Meter | R |
### Notes on channels
#### `shutter` position
@ -154,6 +157,8 @@ Bridge openwebnet:bus_gateway:mybridge "MyHOMEServer1" [ host="192.168.1.35", pa
bus_on_off_switch LR_switch "Living Room Light" [ where="51" ]
bus_dimmer LR_dimmer "Living Room Dimmer" [ where="0311#4#01" ]
bus_automation LR_shutter "Living Room Shutter" [ where="93", shutterRun="10050"]
bus_energy_meter CENTRAL_Ta "Energy Meter Ta" [ where="51" ]
bus_energy_meter CENTRAL_Tb "Energy Meter Tb" [ where="52" ]
}
```
@ -176,6 +181,9 @@ Example items linked to BUS devices:
Switch iLR_switch "Light" <light> (gLivingRoom) [ "Lighting" ] { channel="openwebnet:bus_on_off_switch:mybridge:LR_switch:switch" }
Dimmer iLR_dimmer "Dimmer [%.0f %%]" <DimmableLight> (gLivingRoom) [ "Lighting" ] { channel="openwebnet:bus_dimmer:mybridge:LR_dimmer:brightness" }
Rollershutter iLR_shutter "Shutter [%.0f %%]" <rollershutter> (gShutters, gLivingRoom) [ "Blinds" ] { channel="openwebnet:bus_automation:mybridge:LR_shutter:shutter" }
Number:Power iCENTRAL_Ta "Power [%.0f %unit%]" <energy> { channel="openwebnet:bus_energy_meter:mybridge:CENTRAL_Ta:power" }
Number:Power iCENTRAL_Tb "Power [%.0f %unit%]" <energy> { channel="openwebnet:bus_energy_meter:mybridge:CENTRAL_Tb:power" }
```
Example items linked to OpenWebNet ZigBee devices:
@ -198,6 +206,12 @@ sitemap openwebnet label="OpenWebNet Binding Example Sitemap"
Default item=iLR_dimmer icon="light"
Default item=iLR_shutter
}
Frame label="Energy Meters" icon="energy"
{
Default item=iCENTRAL_Ta label="General" icon="energy" valuecolor=[>3000="red"]
Default item=iCENTRAL_Tb label="Ground Floor" icon="energy" valuecolor=[>3000="red"]
}
}
```
@ -216,5 +230,6 @@ Special thanks for helping on testing this binding go to:
[@gilberto.cocchi](https://community.openhab.org/u/gilberto.cocchi/),
[@llegovich](https://community.openhab.org/u/llegovich),
[@gabriele.daltoe](https://community.openhab.org/u/gabriele.daltoe),
[@feodor](https://community.openhab.org/u/feodor)
[@feodor](https://community.openhab.org/u/feodor),
[@aconte80](https://community.openhab.org/u/aconte80)
and many others at the fantastic openHAB community!

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -23,7 +23,7 @@
<dependency>
<groupId>com.github.openwebnet4j</groupId>
<artifactId>openwebnet4j</artifactId>
<version>0.3.4</version>
<version>0.4.0</version>
<scope>compile</scope>
</dependency>

View File

@ -26,6 +26,7 @@ import org.openhab.core.thing.ThingTypeUID;
* The {@link OpenWebNetBindingConstants} class defines common constants, which are used across the whole binding.
*
* @author Massimo Valla - Initial contribution
* @author Andrea Conte - Energy management
*/
@NonNullByDefault
@ -52,6 +53,8 @@ public class OpenWebNetBindingConstants {
public static final String THING_LABEL_BUS_DIMMER = "Dimmer";
public static final ThingTypeUID THING_TYPE_BUS_AUTOMATION = new ThingTypeUID(BINDING_ID, "bus_automation");
public static final String THING_LABEL_BUS_AUTOMATION = "Automation";
public static final ThingTypeUID THING_TYPE_BUS_ENERGY_METER = new ThingTypeUID(BINDING_ID, "bus_energy_meter");
public static final String THING_LABEL_BUS_ENERGY_METER = "Energy Meter";
// ZIGBEE
public static final ThingTypeUID THING_TYPE_ZB_ON_OFF_SWITCH = new ThingTypeUID(BINDING_ID, "zb_on_off_switch");
@ -76,9 +79,14 @@ public class OpenWebNetBindingConstants {
public static final Set<ThingTypeUID> AUTOMATION_SUPPORTED_THING_TYPES = new HashSet<>(
Arrays.asList(THING_TYPE_ZB_AUTOMATION, THING_TYPE_BUS_AUTOMATION));
// ## Energy Management
public static final Set<ThingTypeUID> ENERGY_MANAGEMENT_SUPPORTED_THING_TYPES = new HashSet<>(
Arrays.asList(THING_TYPE_BUS_ENERGY_METER));
// ## Groups
public static final Set<ThingTypeUID> DEVICE_SUPPORTED_THING_TYPES = Stream
.of(LIGHTING_SUPPORTED_THING_TYPES, AUTOMATION_SUPPORTED_THING_TYPES, GENERIC_SUPPORTED_THING_TYPES)
.of(LIGHTING_SUPPORTED_THING_TYPES, AUTOMATION_SUPPORTED_THING_TYPES,
ENERGY_MANAGEMENT_SUPPORTED_THING_TYPES, GENERIC_SUPPORTED_THING_TYPES)
.flatMap(Collection::stream).collect(Collectors.toCollection(HashSet::new));
public static final Set<ThingTypeUID> BRIDGE_SUPPORTED_THING_TYPES = new HashSet<>(
@ -94,9 +102,13 @@ public class OpenWebNetBindingConstants {
public static final String CHANNEL_SWITCH_01 = "switch_01";
public static final String CHANNEL_SWITCH_02 = "switch_02";
public static final String CHANNEL_BRIGHTNESS = "brightness";
// automation
public static final String CHANNEL_SHUTTER = "shutter";
// energy management
public static final String CHANNEL_POWER = "power";
// devices config properties
public static final String CONFIG_PROPERTY_WHERE = "where";
public static final String CONFIG_PROPERTY_SHUTTER_RUN = "shutterRun";

View File

@ -12,7 +12,9 @@
*/
package org.openhab.binding.openwebnet.handler;
import static org.openhab.binding.openwebnet.OpenWebNetBindingConstants.*;
import static org.openhab.binding.openwebnet.OpenWebNetBindingConstants.PROPERTY_FIRMWARE_VERSION;
import static org.openhab.binding.openwebnet.OpenWebNetBindingConstants.PROPERTY_SERIAL_NO;
import static org.openhab.binding.openwebnet.OpenWebNetBindingConstants.THING_TYPE_ZB_GATEWAY;
import java.util.Collection;
import java.util.Collections;
@ -45,6 +47,7 @@ import org.openwebnet4j.communication.OWNAuthException;
import org.openwebnet4j.communication.OWNException;
import org.openwebnet4j.message.Automation;
import org.openwebnet4j.message.BaseOpenMessage;
import org.openwebnet4j.message.EnergyManagement;
import org.openwebnet4j.message.FrameException;
import org.openwebnet4j.message.GatewayMgmt;
import org.openwebnet4j.message.Lighting;
@ -60,6 +63,7 @@ import org.slf4j.LoggerFactory;
* The {@link OpenWebNetBridgeHandler} is responsible for handling communication with gateways and handling events.
*
* @author Massimo Valla - Initial contribution
* @author Andrea Conte - Energy management
*/
@NonNullByDefault
public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implements GatewayListener {
@ -286,7 +290,11 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
logger.warn("discoverByActivation: null OpenWebNetDeviceDiscoveryService, ignoring msg={}", baseMsg);
return;
}
if (baseMsg instanceof Lighting || baseMsg instanceof Automation) { // we support these types only
if (baseMsg instanceof Lighting || baseMsg instanceof Automation || baseMsg instanceof EnergyManagement) { // we
// support
// these
// types
// only
BaseOpenMessage bmsg = baseMsg;
if (baseMsg instanceof Lighting) {
What what = baseMsg.getWhat();
@ -386,7 +394,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
BaseOpenMessage baseMsg = (BaseOpenMessage) msg;
// let's try to get the Thing associated with this message...
if (baseMsg instanceof Lighting || baseMsg instanceof Automation) {
if (baseMsg instanceof Lighting || baseMsg instanceof Automation || baseMsg instanceof EnergyManagement) {
String ownId = ownIdFromMessage(baseMsg);
logger.debug("ownIdFromMessage({}) --> {}", baseMsg, ownId);
OpenWebNetThingHandler deviceHandler = registeredDevices.get(ownId);

View File

@ -0,0 +1,113 @@
/**
* Copyright (c) 2010-2021 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.openwebnet.handler;
import static org.openhab.binding.openwebnet.OpenWebNetBindingConstants.CHANNEL_POWER;
import java.util.Set;
import javax.measure.quantity.Power;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.openwebnet.OpenWebNetBindingConstants;
import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.Units;
import org.openhab.core.thing.ChannelUID;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.types.Command;
import org.openhab.core.types.UnDefType;
import org.openwebnet4j.communication.OWNException;
import org.openwebnet4j.message.BaseOpenMessage;
import org.openwebnet4j.message.EnergyManagement;
import org.openwebnet4j.message.FrameException;
import org.openwebnet4j.message.Where;
import org.openwebnet4j.message.WhereEnergyManagement;
import org.openwebnet4j.message.Who;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link OpenWebNetEnergyHandler} is responsible for handling commands/messages for a Energy Management OpenWebNet
* device. It extends the abstract {@link OpenWebNetThingHandler}.
*
* @author Massimo Valla - Initial contribution
* @author Andrea Conte - Energy management
*/
@NonNullByDefault
public class OpenWebNetEnergyHandler extends OpenWebNetThingHandler {
private final Logger logger = LoggerFactory.getLogger(OpenWebNetEnergyHandler.class);
public final static Set<ThingTypeUID> SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.ENERGY_MANAGEMENT_SUPPORTED_THING_TYPES;
public OpenWebNetEnergyHandler(Thing thing) {
super(thing);
}
@Override
protected Where buildBusWhere(String wStr) throws IllegalArgumentException {
return new WhereEnergyManagement(wStr);
}
@Override
protected void requestChannelState(ChannelUID channel) {
logger.debug("requestChannelState() thingUID={} channel={}", thing.getUID(), channel.getId());
try {
bridgeHandler.gateway.send(EnergyManagement.requestActivePower(deviceWhere.value()));
} catch (OWNException e) {
logger.warn("requestChannelState() OWNException thingUID={} channel={}: {}", thing.getUID(),
channel.getId(), e.getMessage());
}
}
@Override
protected void handleChannelCommand(ChannelUID channel, Command command) {
logger.warn("handleChannelCommand() Read only channel, unsupported command {}", command);
}
@Override
protected String ownIdPrefix() {
return Who.ENERGY_MANAGEMENT.value().toString();
}
@Override
protected void handleMessage(BaseOpenMessage msg) {
super.handleMessage(msg);
if (msg.isCommand()) {
logger.warn("handleMessage() Ignoring unsupported command for thing {}. Frame={}", getThing().getUID(),
msg);
return;
} else {
updateActivePower(msg);
}
}
/**
* Updates energy power state based on a EnergyManagement message received from the OWN network
*
* @param msg the EnergyManagement message received
* @throws FrameException
*/
private void updateActivePower(BaseOpenMessage msg) {
Integer activePower;
try {
activePower = Integer.parseInt(msg.getDimValues()[0]);
updateState(CHANNEL_POWER, new QuantityType<Power>(activePower, Units.WATT));
} catch (FrameException e) {
logger.warn("FrameException on frame {}: {}", msg, e.getMessage());
updateState(CHANNEL_POWER, UnDefType.UNDEF);
}
}
}

View File

@ -18,6 +18,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.openwebnet.handler.OpenWebNetAutomationHandler;
import org.openhab.binding.openwebnet.handler.OpenWebNetBridgeHandler;
import org.openhab.binding.openwebnet.handler.OpenWebNetEnergyHandler;
import org.openhab.binding.openwebnet.handler.OpenWebNetGenericHandler;
import org.openhab.binding.openwebnet.handler.OpenWebNetLightingHandler;
import org.openhab.core.thing.Bridge;
@ -34,6 +35,7 @@ import org.slf4j.LoggerFactory;
* The {@link OpenWebNetHandlerFactory} is responsible for creating thing handlers.
*
* @author Massimo Valla - Initial contribution
* @author Andrea Conte - Energy management
*/
@NonNullByDefault
@Component(configurationPid = "binding.openwebnet", service = ThingHandlerFactory.class)
@ -60,6 +62,9 @@ public class OpenWebNetHandlerFactory extends BaseThingHandlerFactory {
} else if (OpenWebNetAutomationHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("creating NEW AUTOMATION Handler");
return new OpenWebNetAutomationHandler(thing);
} else if (OpenWebNetEnergyHandler.SUPPORTED_THING_TYPES.contains(thing.getThingTypeUID())) {
logger.debug("creating NEW ENERGY Handler");
return new OpenWebNetEnergyHandler(thing);
}
logger.warn("ThingType {} is not supported by this binding", thing.getThingTypeUID());
return null;

View File

@ -41,6 +41,7 @@ import org.slf4j.LoggerFactory;
* bridge/gateway
*
* @author Massimo Valla - Initial contribution
* @author Andrea Conte - Energy management
*/
@NonNullByDefault
public class OpenWebNetDeviceDiscoveryService extends AbstractDiscoveryService
@ -129,6 +130,14 @@ public class OpenWebNetDeviceDiscoveryService extends AbstractDiscoveryService
deviceWho = Who.AUTOMATION;
break;
}
case SCS_ENERGY_METER: {
thingTypeUID = OpenWebNetBindingConstants.THING_TYPE_BUS_ENERGY_METER;
thingLabel = OpenWebNetBindingConstants.THING_LABEL_BUS_ENERGY_METER;
deviceWho = Who.ENERGY_MANAGEMENT;
break;
}
default:
logger.warn("Device type {} is not supported, default to GENERIC device (WHERE={})", deviceType, where);
if (where instanceof WhereZigBee) {

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<thing:thing-descriptions bindingId="openwebnet"
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">
<!-- Thing for BUS Energy Management Central Unit (BTicino F52x) -->
<thing-type id="bus_energy_meter">
<supported-bridge-type-refs>
<bridge-type-ref id="bus_gateway"/>
</supported-bridge-type-refs>
<label>Energy Meter</label>
<description>A OpenWebNet BUS/SCS Energy Meter. BTicino models: F52x</description>
<channels>
<channel id="power" typeId="power"/>
</channels>
<properties>
<property name="vendor">BTicino/Legrand</property>
<property name="model">BTI-F52x</property>
<property name="ownDeviceType">1830</property>
</properties>
<representation-property>ownId</representation-property>
<config-description>
<parameter name="where" type="text" required="true">
<label>OpenWebNet Address</label>
<description>Example: 5N with N=[1-255]</description>
</parameter>
</config-description>
</thing-type>
</thing:thing-descriptions>

View File

@ -37,4 +37,12 @@
</tags>
</channel-type>
<!-- Energy channels -->
<channel-type id="power">
<item-type>Number:Power</item-type>
<label>Power</label>
<description>Current active power</description>
<category>Energy</category>
<state readOnly="true" pattern="%.0f %unit%"></state>
</channel-type>
</thing:thing-descriptions>

View File

@ -22,6 +22,7 @@ import org.openhab.core.thing.Bridge;
import org.openwebnet4j.message.BaseOpenMessage;
import org.openwebnet4j.message.FrameException;
import org.openwebnet4j.message.Where;
import org.openwebnet4j.message.WhereEnergyManagement;
import org.openwebnet4j.message.WhereLightAutom;
import org.openwebnet4j.message.WhereZigBee;
import org.openwebnet4j.message.Who;
@ -33,6 +34,7 @@ import org.slf4j.LoggerFactory;
* methods: normalizeWhere(), ownIdFromWhoWhere(), ownIdFromMessage(), thingIdFromWhere()
*
* @author Massimo Valla - Initial contribution
* @author Andrea Conte - Energy management
*/
@NonNullByDefault
public class OwnIdTest {
@ -68,12 +70,12 @@ public class OwnIdTest {
zb_switch_2u_1(new WhereZigBee("789301201#9"), Who.fromValue(1), "*1*1*789301201#9##", "789301200h9", "1.789301200h9", "789301200h9"),
zb_switch_2u_2(new WhereZigBee("789301202#9"), Who.fromValue(1), "*1*1*789301202#9##", "789301200h9", "1.789301200h9", "789301200h9"),
bus_switch(new WhereLightAutom("51"), Who.fromValue(1), "*1*1*51##", "51", "1.51", "51"),
bus_localbus(new WhereLightAutom("25#4#01"), Who.fromValue(1), "*1*1*25#4#01##", "25h4h01", "1.25h4h01", "25h4h01");
bus_localbus(new WhereLightAutom("25#4#01"), Who.fromValue(1), "*1*1*25#4#01##", "25h4h01", "1.25h4h01", "25h4h01"),
//bus_thermo_zone(new WhereThermo("1"), Who.fromValue(4),"*#4*1*0*0020##" , "1", "4.1", "1"),
//bus_thermo_zone_act(new WhereThermo("2#1"), Who.fromValue(4),"*#4*2#1*20*0##" ,"2", "4.2", "2"),
//bus_thermo_via_cu(new WhereThermo("#1"), Who.fromValue(4),"*#4*#1*0*0020##" ,"1", "4.1", "1"),
// bus_tempSensor("500", "4", "500", "4.500", "500"),
// bus_energy("51", "18", "51", "18.51", "51");
bus_energy(new WhereEnergyManagement("51"), Who.fromValue(18), "*#18*51*113##", "51", "18.51", "51");
// @formatter:on