Skip to content

Commit

Permalink
add support for Energy Management #10189
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Conte <andrea@conte.com>
Signed-off-by: Conte Andrea <andrea@conte.com>
  • Loading branch information
aconte80 committed Feb 17, 2021
1 parent 2bb6e38 commit 0a89dc5
Show file tree
Hide file tree
Showing 12 changed files with 229 additions and 9 deletions.
20 changes: 17 additions & 3 deletions bundles/org.openhab.binding.openwebnet/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -40,7 +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)

| Category | WHO | Thing Type IDs | Description | Status |
Expand Down Expand Up @@ -129,7 +131,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
Expand All @@ -154,6 +156,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" ]
}
```

Expand All @@ -176,6 +180,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:
Expand All @@ -198,6 +205,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"]
}
}
```

Expand All @@ -216,5 +229,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 modified bundles/org.openhab.binding.openwebnet/doc/F454_gateway.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion bundles/org.openhab.binding.openwebnet/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* 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
Expand All @@ -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");
Expand All @@ -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<>(
Expand All @@ -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";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
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;
Expand All @@ -60,6 +61,7 @@
* 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 {
Expand Down Expand Up @@ -286,7 +288,11 @@ private void discoverByActivation(BaseOpenMessage baseMsg) {
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();
Expand Down Expand Up @@ -386,7 +392,7 @@ public void onEventMessage(@Nullable OpenMessage msg) {

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);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**
* 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
public void initialize() {
logger.debug("initialize() thing={}", thing.getUID());
super.initialize();
}

@Override
public void dispose() {
logger.debug("dispose() thing={}", thing.getUID());
super.dispose();
}

@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.error("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) {
logger.debug("handleMessage({}) for thing: {}", msg, thing.getUID());
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(EnergyManagement msg) {
private void updateActivePower(BaseOpenMessage msg) {
logger.debug("updateActivePower() for thing: {}", thing.getUID());
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);
}
}
} // class
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
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;
Expand All @@ -34,6 +35,7 @@
* 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)
Expand All @@ -60,6 +62,9 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
} 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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
* bridge/gateway
*
* @author Massimo Valla - Initial contribution
* @author Andrea Conte - Energy management
*/
@NonNullByDefault
public class OpenWebNetDeviceDiscoveryService extends AbstractDiscoveryService
Expand Down Expand Up @@ -129,6 +130,14 @@ public void newDiscoveryResult(Where where, OpenDeviceType deviceType, @Nullable
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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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 Device Address (where)</label>
<description>Example: 5N with N=[1-255]</description>
</parameter>
</config-description>

</thing-type>
</thing:thing-descriptions>
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,12 @@
</tags>
</channel-type>

<!-- Energy channels -->
<channel-type id="power">
<item-type>Number</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>
Loading

0 comments on commit 0a89dc5

Please sign in to comment.