Skip to content

Commit

Permalink
[openwebnet] initial support for general/area light events
Browse files Browse the repository at this point in the history
Signed-off-by: Massimo Valla <[email protected]>
  • Loading branch information
mvalla committed Oct 14, 2023
1 parent 2d92fda commit 23263a3
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 12 deletions.
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>io.github.openwebnet4j</groupId>
<artifactId>openwebnet4j</artifactId>
<version>0.10.1</version>
<version>0.11.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants;
import org.openhab.binding.openwebnet.internal.discovery.OpenWebNetDeviceDiscoveryService;
import org.openhab.binding.openwebnet.internal.handler.OpenWebNetLightingHandler.LightAutomHandlersMap;
import org.openhab.binding.openwebnet.internal.handler.config.OpenWebNetBusBridgeConfig;
import org.openhab.binding.openwebnet.internal.handler.config.OpenWebNetZigBeeBridgeConfig;
import org.openhab.core.config.core.status.ConfigStatusMessage;
Expand Down Expand Up @@ -64,6 +65,7 @@
import org.openwebnet4j.message.Thermoregulation;
import org.openwebnet4j.message.What;
import org.openwebnet4j.message.Where;
import org.openwebnet4j.message.WhereLightAutom;
import org.openwebnet4j.message.WhereZigBee;
import org.openwebnet4j.message.Who;
import org.slf4j.Logger;
Expand Down Expand Up @@ -106,6 +108,9 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
private Map<String, @Nullable OpenWebNetThingHandler> registeredDevices = new ConcurrentHashMap<>();
private Map<String, Long> discoveringDevices = new ConcurrentHashMap<>();

protected @Nullable LightAutomHandlersMap lightsMap; // a static map of lights handlers organised by AREA they
// belong to

protected @Nullable OpenGateway gateway;
private boolean isBusGateway = false;

Expand Down Expand Up @@ -386,7 +391,7 @@ private void discoverByActivation(BaseOpenMessage baseMsg) {
/**
* Register a device ThingHandler to this BridgHandler
*
* @param ownId the device OpenWebNet id
* @param ownId the device OpenWebNet id
* @param thingHandler the thing handler to be registered
*/
protected void registerDevice(String ownId, OpenWebNetThingHandler thingHandler) {
Expand Down Expand Up @@ -510,7 +515,20 @@ public void onEventMessage(@Nullable OpenMessage msg) {
return;
}

// LIGHTING multiple messages
if (msg instanceof Lighting lmsg) {
WhereLightAutom w = (WhereLightAutom) lmsg.getWhere();
LightAutomHandlersMap lm = lightsMap;
if (w.isMultiple() && lm != null && !lm.isEmpty()) {
OpenWebNetLightingHandler lh = (OpenWebNetLightingHandler) lm.getOne();
if (lh != null) {
lh.handleMultipleMessage(lmsg);
}
}
}

BaseOpenMessage baseMsg = (BaseOpenMessage) msg;

// let's try to get the Thing associated with this message...
if (baseMsg instanceof Lighting || baseMsg instanceof Automation || baseMsg instanceof EnergyManagement
|| baseMsg instanceof Thermoregulation || baseMsg instanceof CEN || baseMsg instanceof Auxiliary
Expand Down Expand Up @@ -677,7 +695,7 @@ public void onReconnected() {
/**
* Return a ownId string (=WHO.WHERE) from the device Where address and handler
*
* @param where the Where address (to be normalized)
* @param where the Where address (to be normalized)
* @param handler the device handler
* @return the ownId String
*/
Expand All @@ -688,7 +706,7 @@ protected String ownIdFromDeviceWhere(Where where, OpenWebNetThingHandler handle
/**
* Returns a ownId string (=WHO.WHERE) from a Who and Where address
*
* @param who the Who
* @param who the Who
* @param where the Where address (to be normalized)
* @return the ownId String
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@

import static org.openhab.binding.openwebnet.internal.OpenWebNetBindingConstants.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import org.eclipse.jdt.annotation.NonNullByDefault;
Expand Down Expand Up @@ -46,13 +50,123 @@
* commands/messages for a Lighting OpenWebNet device.
* It extends the abstract {@link OpenWebNetThingHandler}.
*
* @author Massimo Valla - Initial contribution
* @author Massimo Valla - Initial contribution. Added LightAutomHandlersMap.
*/
@NonNullByDefault
public class OpenWebNetLightingHandler extends OpenWebNetThingHandler {

private final Logger logger = LoggerFactory.getLogger(OpenWebNetLightingHandler.class);

protected class LightAutomHandlersMap {

private Map<Integer, Map<String, OpenWebNetThingHandler>> hndlrsMap;
private @Nullable OpenWebNetThingHandler oneHandler = null;

protected LightAutomHandlersMap() {
hndlrsMap = new ConcurrentHashMap<>();
}

protected void add(int area, OpenWebNetThingHandler h) {
if (!hndlrsMap.containsKey(area)) {
hndlrsMap.put(area, new ConcurrentHashMap<>());
}
Map<String, OpenWebNetThingHandler> areaHndlrs = hndlrsMap.get(Integer.valueOf(area));
final String oId = h.ownId;
if (oId != null) {
areaHndlrs.put(oId, h);
if (oneHandler == null) {
oneHandler = h;
}
logger.warn("/////////////////////// Added handler {} to Area {}", oId, area);
logger.warn(this.toString());
}

}

protected void remove(int area, OpenWebNetThingHandler h) {
if (hndlrsMap.containsKey(area)) {
Map<String, OpenWebNetThingHandler> areaHndlrs = hndlrsMap.get(Integer.valueOf(area));
if (areaHndlrs != null) {
boolean removed = areaHndlrs.remove(h.ownId, h);
if (removed && oneHandler == h) {
oneHandler = getFirst();
}
logger.warn("/////////////////////// ^^^^^^^^^^^^ Removed handler {} from Area {}", h.ownId, area);
logger.warn(this.toString());
}
}
}

protected @Nullable List<OpenWebNetThingHandler> getAreaHandlers(int area) {
Map<String, OpenWebNetThingHandler> areaHndlrs = hndlrsMap.get(area);
if (areaHndlrs != null) {
List<OpenWebNetThingHandler> list = new ArrayList<OpenWebNetThingHandler>(areaHndlrs.values());
return list;
} else {
return null;
}
}

protected @Nullable List<OpenWebNetThingHandler> getAllHandlers() {
List<OpenWebNetThingHandler> list = new ArrayList<OpenWebNetThingHandler>();
for (Map.Entry<Integer, Map<String, OpenWebNetThingHandler>> entry : hndlrsMap.entrySet()) {
Map<String, OpenWebNetThingHandler> innerMap = entry.getValue();
for (Map.Entry<String, OpenWebNetThingHandler> innerEntry : innerMap.entrySet()) {
OpenWebNetThingHandler hndlr = innerEntry.getValue();
if (hndlr != null) {
list.add(hndlr);
}
}
}
return list;
}

protected boolean isEmpty() {
return oneHandler == null;
}

protected @Nullable OpenWebNetThingHandler getOne() {
if (oneHandler == null) {
oneHandler = getFirst();
}
return oneHandler;
}

private @Nullable OpenWebNetThingHandler getFirst() {
for (Map.Entry<Integer, Map<String, OpenWebNetThingHandler>> entry : hndlrsMap.entrySet()) {
Map<String, OpenWebNetThingHandler> innerMap = entry.getValue();
for (Map.Entry<String, OpenWebNetThingHandler> innerEntry : innerMap.entrySet()) {
OpenWebNetThingHandler hndlr = innerEntry.getValue();
if (hndlr != null) {
return hndlr;
}
}
}
return null;
}

@Override
public String toString() {
String log = "\n---- LightAutomHandlersMap ----";
for (Map.Entry<Integer, Map<String, OpenWebNetThingHandler>> entry : hndlrsMap.entrySet()) {
log += "\n- Area: " + entry.getKey() + "\n -";
Map<String, OpenWebNetThingHandler> innerMap = entry.getValue();
for (Map.Entry<String, OpenWebNetThingHandler> innerEntry : innerMap.entrySet()) {
OpenWebNetThingHandler hndlr = innerEntry.getValue();
if (hndlr != null) {
log += " " + hndlr.ownId;
}
}
}
log += "\n# getAllHandlers: ";
for (OpenWebNetThingHandler e : getAllHandlers()) {
log += " " + e.ownId;
}
log += "\n# oneH = " + (oneHandler == null ? "null" : oneHandler.ownId);
return log;
}
}

public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = OpenWebNetBindingConstants.LIGHTING_SUPPORTED_THING_TYPES;

// interval to interpret ON as response to requestStatus
Expand All @@ -65,17 +179,35 @@ public class OpenWebNetLightingHandler extends OpenWebNetThingHandler {
private static final int UNKNOWN_STATE = 1000;

private long lastBrightnessChangeSentTS = 0; // timestamp when last brightness change was sent to the device

private long lastStatusRequestSentTS = 0; // timestamp when last status request was sent to the device

private static long lastAllDevicesRefreshTS = 0; // ts when last all device refresh was sent for this handler

private int brightness = UNKNOWN_STATE; // current brightness percent value for this device

private int brightnessBeforeOff = UNKNOWN_STATE; // latest brightness before device was set to off

/**
* Reference to {@link OpenWebNetBridgeHandler#lightsMap}
*/
private @Nullable LightAutomHandlersMap lightsMap;

public OpenWebNetLightingHandler(Thing thing) {
super(thing);

}

@Override
public void initialize() {
super.initialize();
Where w = deviceWhere;
OpenWebNetBridgeHandler bridge = bridgeHandler;
if (w != null && bridge != null) {
if (bridge.lightsMap == null) {
bridge.lightsMap = new LightAutomHandlersMap();
}
lightsMap = bridge.lightsMap;

int area = ((WhereLightAutom) w).getArea();
lightsMap.add(area, this);
}
}

@Override
Expand Down Expand Up @@ -223,7 +355,8 @@ private void dimLightTo(int percent, Command command) {
lastBrightnessChangeSentTS = System.currentTimeMillis();
send(Lighting.requestDimTo(w.value(), newBrightnessWhat));
} catch (OWNException e) {
logger.warn("Exception while sending dimTo request for command {}: {}", command, e.getMessage());
logger.warn("Exception while sending dimTo request for command {}: {}", command,
e.getMessage());
}
}
} else {
Expand All @@ -240,6 +373,24 @@ protected String ownIdPrefix() {
return Who.LIGHTING.value().toString();
}

protected void handleMultipleMessage(Lighting msg) {
WhereLightAutom w = (WhereLightAutom) msg.getWhere();
LightAutomHandlersMap map = lightsMap;
if (map != null) {
List<OpenWebNetThingHandler> l = null;
if (w.isGeneral()) {
l = map.getAllHandlers();
} else if (w.getArea() > 0) {
l = map.getAreaHandlers(w.getArea());
}
if (l != null) {
for (OpenWebNetThingHandler hndlr : l) {
hndlr.handleMessage(msg);
}
}
}
}

@Override
protected void handleMessage(BaseOpenMessage msg) {
logger.debug("handleMessage({}) for thing: {}", msg, thing.getUID());
Expand Down Expand Up @@ -306,7 +457,8 @@ private synchronized void updateBrightness(Lighting msg) {
}
brightness = newBrightness;
} else {
logger.warn("updateBrightness() Cannot handle message {} for thing {}", msg, getThing().getUID());
logger.warn("updateBrightness() Cannot handle message {} for thing {}", msg,
getThing().getUID());
return;
}
}
Expand Down Expand Up @@ -368,7 +520,8 @@ private void updateOnOffState(Lighting msg) {
}
updateState(channelId, OnOffType.from(msg.isOn()));
} else {
logger.debug("updateOnOffState() Ignoring unsupported WHAT for thing {}. Frame={}", getThing().getUID(),
logger.debug("updateOnOffState() Ignoring unsupported WHAT for thing {}. Frame={}",
getThing().getUID(),
msg.getFrameValue());
return;
}
Expand Down Expand Up @@ -402,4 +555,16 @@ private String toWhere(String channelId) {
}
return null;
}

@Override
public void dispose() {
Where w = deviceWhere;
if (w != null) {
int area = ((WhereLightAutom) w).getArea();
lightsMap.remove(area, this);
logger.debug("Light.dispose() - removed APL {}", w);
}
super.dispose();
}

}

0 comments on commit 23263a3

Please sign in to comment.