diff --git a/ESH-INF/thing/thing-types.xml b/ESH-INF/thing/thing-types.xml
index 915c4d14f..5f17634b2 100644
--- a/ESH-INF/thing/thing-types.xml
+++ b/ESH-INF/thing/thing-types.xml
@@ -85,7 +85,7 @@
true
30
-
+
Websocket client's maximum binary message size in kB
true
diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF
index bba9c2726..e2c7c1a2a 100644
--- a/META-INF/MANIFEST.MF
+++ b/META-INF/MANIFEST.MF
@@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2
Bundle-Name: Loxone Binding
Bundle-SymbolicName: org.openhab.binding.loxone;singleton:=true
Bundle-Vendor: openHAB
-Bundle-Version: 2.1.0.12
+Bundle-Version: 2.1.0.13
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ClassPath: .
Import-Package:
diff --git a/pom.xml b/pom.xml
index 7645f5264..82c8f5b05 100644
--- a/pom.xml
+++ b/pom.xml
@@ -11,7 +11,7 @@
org.openhab.binding
org.openhab.binding.loxone
- 2.1.0-12
+ 2.1.0-13
Loxone Binding
eclipse-plugin
diff --git a/src/main/java/org/openhab/binding/loxone/core/LxControl.java b/src/main/java/org/openhab/binding/loxone/core/LxControl.java
index b2247b3c7..8cd15abf2 100644
--- a/src/main/java/org/openhab/binding/loxone/core/LxControl.java
+++ b/src/main/java/org/openhab/binding/loxone/core/LxControl.java
@@ -35,10 +35,10 @@ public abstract class LxControl {
private LxContainer room;
private LxCategory category;
private Map states = new HashMap();
- Logger logger = LoggerFactory.getLogger(LxControl.class);
LxUuid uuid;
LxWsClient socketClient;
+ Logger logger = LoggerFactory.getLogger(LxControl.class);
Map subControls = new HashMap();
/**
@@ -56,6 +56,7 @@ public abstract class LxControl {
* Category that this control belongs to
*/
LxControl(LxWsClient client, LxUuid uuid, LxJsonControl json, LxContainer room, LxCategory category) {
+ logger.trace("Creating new LxControl: {}", json.type);
socketClient = client;
this.uuid = uuid;
if (json.type != null) {
@@ -186,6 +187,9 @@ public boolean equals(Object object) {
* New category that this control belongs to
*/
void update(LxJsonControl json, LxContainer room, LxCategory category) {
+
+ logger.trace("Updating LxControl: {}", json.type);
+
this.name = json.name;
this.room = room;
this.category = category;
@@ -199,6 +203,9 @@ void update(LxJsonControl json, LxContainer room, LxCategory category) {
// retrieve all states from the configuration
if (json.states != null) {
+
+ logger.trace("Reading states for LxControl: {}", json.type);
+
for (Map.Entry jsonState : json.states.entrySet()) {
JsonElement element = jsonState.getValue();
if (element instanceof JsonArray) {
@@ -213,8 +220,10 @@ void update(LxJsonControl json, LxContainer room, LxCategory category) {
String name = jsonState.getKey().toLowerCase();
LxControlState state = states.get(name);
if (state == null) {
+ logger.trace("New state for LxControl {}: {}", json.type, name);
state = new LxControlState(id, name, this);
} else {
+ logger.trace("Existing state for LxControl{} : {}", json.type, name);
state.getUuid().setUpdate(true);
state.setName(name);
}
@@ -224,39 +233,55 @@ void update(LxJsonControl json, LxContainer room, LxCategory category) {
}
}
- static LxControl createControl(LxWsClient client, LxUuid id, LxJsonControl json, LxContainer room,
+ /**
+ *
+ * @param client
+ * websocket client to facilitate communication with Miniserver
+ * @param uuid
+ * UUID of the control to be created
+ * @param json
+ * JSON describing the control as received from the Miniserver
+ * @param room
+ * Room that this control belongs to
+ * @param category
+ * Category that this control belongs to
+ * @return
+ * created control object or null if error
+ */
+ static LxControl createControl(LxWsClient client, LxUuid uuid, LxJsonControl json, LxContainer room,
LxCategory category) {
+
if (json == null || json.type == null || json.name == null) {
return null;
}
-
LxControl ctrl = null;
String type = json.type.toLowerCase();
if (LxControlSwitch.accepts(type)) {
- ctrl = new LxControlSwitch(client, id, json, room, category);
+ ctrl = new LxControlSwitch(client, uuid, json, room, category);
} else if (LxControlPushbutton.accepts(type)) {
- ctrl = new LxControlPushbutton(client, id, json, room, category);
+ ctrl = new LxControlPushbutton(client, uuid, json, room, category);
} else if (LxControlJalousie.accepts(type)) {
- ctrl = new LxControlJalousie(client, id, json, room, category);
+ ctrl = new LxControlJalousie(client, uuid, json, room, category);
+
} else if (LxControlTextState.accepts(type)) {
- ctrl = new LxControlTextState(client, id, json, room, category);
+ ctrl = new LxControlTextState(client, uuid, json, room, category);
} else if (json.details != null) {
if (LxControlInfoOnlyDigital.accepts(type) && json.details.text != null) {
- ctrl = new LxControlInfoOnlyDigital(client, id, json, room, category);
+ ctrl = new LxControlInfoOnlyDigital(client, uuid, json, room, category);
} else if (LxControlInfoOnlyAnalog.accepts(type)) {
- ctrl = new LxControlInfoOnlyAnalog(client, id, json, room, category);
+ ctrl = new LxControlInfoOnlyAnalog(client, uuid, json, room, category);
} else if (LxControlLightController.accepts(type)) {
- ctrl = new LxControlLightController(client, id, json, room, category);
+ ctrl = new LxControlLightController(client, uuid, json, room, category);
} else if (LxControlRadio.accepts(type)) {
- ctrl = new LxControlRadio(client, id, json, room, category);
+ ctrl = new LxControlRadio(client, uuid, json, room, category);
}
}
return ctrl;
diff --git a/src/main/java/org/openhab/binding/loxone/core/LxControlLightController.java b/src/main/java/org/openhab/binding/loxone/core/LxControlLightController.java
index 050148d71..cf1213dc8 100644
--- a/src/main/java/org/openhab/binding/loxone/core/LxControlLightController.java
+++ b/src/main/java/org/openhab/binding/loxone/core/LxControlLightController.java
@@ -9,6 +9,8 @@
package org.openhab.binding.loxone.core;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@@ -27,6 +29,10 @@
*
*/
public class LxControlLightController extends LxControl implements LxControlStateListener {
+ /**
+ * Number of scenes supported by the Miniserver. Indexing starts with 0 to NUM_OF_SCENES-1.
+ */
+ public static final int NUM_OF_SCENES = 10;
/**
* A name by which Miniserver refers to light controller controls
@@ -59,7 +65,6 @@ public class LxControlLightController extends LxControl implements LxControlStat
private static final String CMD_PREVIOUS_SCENE = "minus";
private static final int SCENE_ALL_ON = 9;
- public static final int NUM_OF_SCENES = 10;
private Map sceneNames = new TreeMap();
private boolean newSceneNames = false;
private int movementScene = -1;
@@ -80,23 +85,13 @@ public class LxControlLightController extends LxControl implements LxControlStat
*/
LxControlLightController(LxWsClient client, LxUuid uuid, LxJsonControl json, LxContainer room,
LxCategory category) {
+
super(client, uuid, json, room, category);
if (json.details != null) {
this.movementScene = json.details.movementScene;
}
-
- if (json.subControls != null) {
- for (LxJsonControl subControl : json.subControls.values()) {
- // recursively create a subcontrol as a new control
- subControl.room = json.room;
- subControl.cat = json.cat;
- LxUuid subId = new LxUuid(subControl.uuidAction);
- LxControl control = LxControl.createControl(client, subId, subControl, room, category);
- subControls.put(control.uuid, control);
- }
- }
-
+ // sub-controls of this control have been created when update() method was called by super class constructor
LxControlState sceneListState = getState(STATE_SCENE_LIST);
if (sceneListState != null) {
sceneListState.addListener(this);
@@ -115,6 +110,7 @@ public class LxControlLightController extends LxControl implements LxControlStat
*/
@Override
void update(LxJsonControl json, LxContainer room, LxCategory category) {
+
super.update(json, room, category);
if (json.subControls != null) {
@@ -127,15 +123,21 @@ void update(LxJsonControl json, LxContainer room, LxCategory category) {
subControls.get(uuid).update(json, room, category);
} else {
LxControl control = LxControl.createControl(socketClient, uuid, subControl, room, category);
- subControls.put(control.uuid, control);
+ if (control != null) {
+ subControls.put(control.uuid, control);
+ }
}
}
}
+ List toRemove = new ArrayList(subControls.size());
for (LxControl control : subControls.values()) {
if (!control.uuid.getUpdate()) {
- subControls.remove(control.uuid);
+ toRemove.add(control.uuid);
}
}
+ for (LxUuid id : toRemove) {
+ subControls.remove(id);
+ }
}
/**
diff --git a/src/main/java/org/openhab/binding/loxone/core/LxServer.java b/src/main/java/org/openhab/binding/loxone/core/LxServer.java
index d3d174900..f8f6d57b3 100644
--- a/src/main/java/org/openhab/binding/loxone/core/LxServer.java
+++ b/src/main/java/org/openhab/binding/loxone/core/LxServer.java
@@ -18,6 +18,7 @@
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
import org.openhab.binding.loxone.core.LxServerEvent.EventType;
import org.slf4j.Logger;
@@ -55,7 +56,7 @@ public class LxServer {
private final InetAddress host;
private final int port;
private final String user, password;
- private String miniserverName, projectName, location, serial, cloudAddress;
+ private String miniserverName = "", projectName = "", location = "", serial = "", cloudAddress = "";
@SuppressWarnings("unused")
private String roomTitle, categoryTitle;
private int firstConDelay = 1, connectErrDelay = 10, userErrorDelay = 60, comErrorDelay = 30;
@@ -75,7 +76,9 @@ public class LxServer {
private BlockingQueue queue = new LinkedBlockingQueue();
private Logger logger = LoggerFactory.getLogger(LxServer.class);
- private static int debugId = 1;
+
+ private int debugId;
+ private static AtomicInteger staticDebugId = new AtomicInteger(1);
/**
* Reasons why Miniserver may be not reachable
@@ -135,7 +138,9 @@ public LxServer(InetAddress host, int port, String user, String password) {
this.port = port;
this.user = user;
this.password = password;
- socketClient = new LxWsClient(++debugId, queue, host, port, user, password);
+
+ debugId = staticDebugId.getAndIncrement();
+ socketClient = new LxWsClient(debugId, queue, host, port, user, password);
}
/**
@@ -200,7 +205,9 @@ public void stop() {
*/
public void update(int firstConDelay, int keepAlivePeriod, int connectErrDelay, int userErrorDelay,
int comErrorDelay, int maxBinMsgSize, int maxTextMsgSize) {
+
logger.debug("[{}] Server update configuration", debugId);
+
if (firstConDelay >= 0) {
this.firstConDelay = firstConDelay;
}
@@ -397,6 +404,7 @@ public void run() {
LxServerEvent wsMsg = queue.take();
EventType event = wsMsg.getEvent();
logger.trace("[{}] Server received event: {}", debugId, event.toString());
+
switch (event) {
case RECEIVED_CONFIG:
LxJsonApp3 config = (LxJsonApp3) wsMsg.getObject();
@@ -489,6 +497,7 @@ public void run() {
* parsed JSON LoxApp3.json file
*/
private void updateConfig(LxJsonApp3 config) {
+ logger.trace("[{}] Updating configuration from Miniserver", debugId);
for (LxUuid id : uuids) {
id.setUpdate(false);
@@ -497,26 +506,45 @@ private void updateConfig(LxJsonApp3 config) {
id.setUpdate(false);
}
- miniserverName = buildName(config.msInfo.msName);
- projectName = buildName(config.msInfo.projectName);
- location = buildName(config.msInfo.location);
- serial = buildName(config.msInfo.serialNr);
- roomTitle = buildName(config.msInfo.roomTitle);
- categoryTitle = buildName(config.msInfo.catTitle);
- cloudAddress = buildName(config.msInfo.remoteUrl);
+ if (config.msInfo != null) {
+ logger.trace("[{}] updating global config", debugId);
+ miniserverName = buildName(config.msInfo.msName);
+ projectName = buildName(config.msInfo.projectName);
+ location = buildName(config.msInfo.location);
+ serial = buildName(config.msInfo.serialNr);
+ roomTitle = buildName(config.msInfo.roomTitle);
+ categoryTitle = buildName(config.msInfo.catTitle);
+ cloudAddress = buildName(config.msInfo.remoteUrl);
+ } else {
+ logger.warn("[{}] missing global configuration msInfo on Loxone", debugId);
+ }
// create internal structures based on configuration file
- for (LxJsonApp3.LxJsonRoom room : config.rooms.values()) {
- addOrUpdateRoom(new LxUuid(room.uuid), room.name);
+ if (config.rooms != null) {
+ logger.trace("[{}] creating rooms", debugId);
+ for (LxJsonApp3.LxJsonRoom room : config.rooms.values()) {
+ addOrUpdateRoom(new LxUuid(room.uuid), room.name);
+ }
}
- for (LxJsonApp3.LxJsonCat cat : config.cats.values()) {
- addOrUpdateCategory(new LxUuid(cat.uuid), cat.name, cat.type);
+ if (config.cats != null) {
+ logger.trace("[{}] creating categories", debugId);
+ for (LxJsonApp3.LxJsonCat cat : config.cats.values()) {
+ addOrUpdateCategory(new LxUuid(cat.uuid), cat.name, cat.type);
+ }
}
- for (LxJsonApp3.LxJsonControl ctrl : config.controls.values()) {
- // create a new control or update existing one
- addOrUpdateControl(ctrl);
+ if (config.controls != null) {
+ logger.trace("[{}] creating controls", debugId);
+ for (LxJsonApp3.LxJsonControl ctrl : config.controls.values()) {
+ // create a new control or update existing one
+ try {
+ addOrUpdateControl(ctrl);
+ } catch (Exception e) {
+ logger.error("[{}] exception creating control {}: {}", debugId, ctrl.name, e.toString());
+ }
+ }
}
// remove items that do not exist anymore in Miniserver
+ logger.trace("[{}] removing unused objects", debugId);
removeUnusedFromMap(rooms);
removeUnusedFromMap(categories);
removeUnusedFromMap(controls);
@@ -697,7 +725,6 @@ private LxCategory addOrUpdateCategory(LxUuid id, String name, String type) {
* JSON original object of this control to get extra parameters
*/
private void addOrUpdateControl(LxJsonApp3.LxJsonControl json) {
-
if (json == null || json.uuidAction == null || json.name == null || json.type == null) {
return;
}
@@ -739,12 +766,12 @@ private void updateControls(LxControl control) {
}
/**
- * Check and converts null string to empty string.
+ * Check and convert null string to empty string.
*
* @param name
* string to check
* @return
- * string guaranteed to not be null
+ * string guaranteed to be not null
*/
private String buildName(String name) {
if (name == null) {
diff --git a/src/main/java/org/openhab/binding/loxone/core/LxWsClient.java b/src/main/java/org/openhab/binding/loxone/core/LxWsClient.java
index 9593ce297..9b3a40f10 100644
--- a/src/main/java/org/openhab/binding/loxone/core/LxWsClient.java
+++ b/src/main/java/org/openhab/binding/loxone/core/LxWsClient.java
@@ -247,7 +247,7 @@ private class LxWsBinaryHeader {
* true if connection request initiated correctly, false if not
*/
boolean connect() {
-
+ logger.trace("[{}] connect() websocket", debugId);
if (state != ClientState.IDLE) {
close("Attempt to connect a websocket in non-idle state: " + state.toString());
return false;
@@ -281,6 +281,7 @@ boolean connect() {
* After calling this method, client is ready to perform a new connection request with {@link #connect()}.
*/
void disconnect() {
+ logger.trace("[{}] disconnect() websocket", debugId);
if (wsClient != null) {
try {
close("Disconnecting websocket client");
@@ -290,7 +291,7 @@ void disconnect() {
logger.debug("[{}] Failed to stop websocket client, message = {}", debugId, e.getMessage());
}
} else {
- logger.debug("[{}] Attempt to disconnect websocket client, but wsClient = null", debugId);
+ logger.debug("[{}] Attempt to disconnect websocket client, but wsClient == null", debugId);
}
}
@@ -302,6 +303,7 @@ void disconnect() {
* reason for closing the websocket
*/
private void close(String reason) {
+ logger.trace("[{}] close() websocket", debugId);
if (socket != null) {
synchronized (socket) {
if (socket.session != null) {
@@ -379,35 +381,8 @@ public class LxWebSocket {
private ScheduledFuture> keepAlive = null;
private LxWsBinaryHeader header = null;
- @OnWebSocketClose
- public void onClose(int statusCode, String reason) {
- logger.debug("[{}] Websocket connection in state {} closed with code {} reason : {}", debugId,
- state.toString(), statusCode, reason);
- if (keepAlive != null) {
- keepAlive.cancel(true);
- keepAlive = null;
- }
- if (state == ClientState.CLOSING) {
- synchronized (this) {
- session = null;
- }
- } else if (state != ClientState.IDLE) {
- LxServer.OfflineReason reasonCode;
- if (statusCode == 1001) {
- reasonCode = LxServer.OfflineReason.IDLE_TIMEOUT;
- } else if (statusCode == 4003) {
- reasonCode = LxServer.OfflineReason.TOO_MANY_FAILED_LOGIN_ATTEMPTS;
- } else {
- reasonCode = LxServer.OfflineReason.COMMUNICATION_ERROR;
- }
- notifyMaster(EventType.SERVER_OFFLINE, reasonCode, reason);
- }
- setClientState(ClientState.IDLE);
- }
-
@OnWebSocketConnect
public void onConnect(Session session) {
-
if (state != ClientState.CONNECTING) {
logger.debug("[{}] Unexpected connect received on websocket in state {}", debugId, state.toString());
return;
@@ -431,16 +406,43 @@ public void onConnect(Session session) {
keepAlive = SCHEDULER.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
- try {
- logger.debug("[{}] sending keepalive message", debugId);
- sendString(CMD_KEEPALIVE);
- } catch (IOException e) {
- logger.debug("[{}] error sending keepalive message", debugId);
+ if (state == ClientState.CLOSING || state == ClientState.IDLE || state == ClientState.CONNECTING) {
+ stopKeepAlive();
+ } else {
+ try {
+ logger.debug("[{}] sending keepalive message", debugId);
+ sendString(CMD_KEEPALIVE);
+ } catch (IOException e) {
+ logger.debug("[{}] error sending keepalive message", debugId);
+ }
}
}
}, keepAlivePeriod, keepAlivePeriod, TimeUnit.SECONDS);
}
+ @OnWebSocketClose
+ public void onClose(int statusCode, String reason) {
+ logger.debug("[{}] Websocket connection in state {} closed with code {} reason : {}", debugId,
+ state.toString(), statusCode, reason);
+ stopKeepAlive();
+ if (state == ClientState.CLOSING) {
+ synchronized (this) {
+ session = null;
+ }
+ } else if (state != ClientState.IDLE) {
+ LxServer.OfflineReason reasonCode;
+ if (statusCode == 1001) {
+ reasonCode = LxServer.OfflineReason.IDLE_TIMEOUT;
+ } else if (statusCode == 4003) {
+ reasonCode = LxServer.OfflineReason.TOO_MANY_FAILED_LOGIN_ATTEMPTS;
+ } else {
+ reasonCode = LxServer.OfflineReason.COMMUNICATION_ERROR;
+ }
+ notifyMaster(EventType.SERVER_OFFLINE, reasonCode, reason);
+ }
+ setClientState(ClientState.IDLE);
+ }
+
@OnWebSocketError
public void onError(Throwable error) {
logger.debug("[{}] Websocket error : {}", debugId, error.getMessage());
@@ -581,6 +583,14 @@ public void onMessage(String msg) {
}
}
+ private void stopKeepAlive() {
+ logger.trace("[{}] stopping keepalives in state {}", debugId, state.toString());
+ if (keepAlive != null) {
+ keepAlive.cancel(true);
+ keepAlive = null;
+ }
+ }
+
private void notifyMaster(EventType event, LxServer.OfflineReason reason, Object object) {
if (reason == null) {
reason = LxServer.OfflineReason.NONE;
diff --git a/src/main/java/org/openhab/binding/loxone/handler/LoxoneMiniserverHandler.java b/src/main/java/org/openhab/binding/loxone/handler/LoxoneMiniserverHandler.java
index 4df91c868..7dcf353bd 100644
--- a/src/main/java/org/openhab/binding/loxone/handler/LoxoneMiniserverHandler.java
+++ b/src/main/java/org/openhab/binding/loxone/handler/LoxoneMiniserverHandler.java
@@ -108,7 +108,6 @@ public void handleCommand(ChannelUID channelUID, Command command) {
logger.debug("Control '{}' received command: {}", control.getName(), command.toString());
- // do not check for compatibility between command and control type here, each control has to do it itself
try {
if (command instanceof RefreshType) {
updateChannelState(channelUID, control);
@@ -131,7 +130,6 @@ public void handleCommand(ChannelUID channelUID, Command command) {
}
if (control instanceof LxControlJalousie) {
-
LxControlJalousie jalousie = (LxControlJalousie) control;
if (command instanceof PercentType) {
jalousie.moveToPosition(((PercentType) command).doubleValue() / 100);
@@ -201,7 +199,7 @@ public void channelLinked(ChannelUID channelUID) {
@Override
public void initialize() {
-
+ logger.trace("Initializing thing");
switchTypeId = addNewChannelType("switch", "Switch", "Switch", "Loxone Switch");
rollerTypeId = addNewChannelType("rollershutter", "Rollershutter", "Rollershutter", "Loxone Jalousie");
infoTypeId = addNewChannelType("infoonly", "String", "Information", "Loxone read-only information");
@@ -231,6 +229,7 @@ public void initialize() {
@Override
public void onNewConfig(LxServer server) {
+ logger.trace("Processing new configuration");
Thing thing = getThing();
thing.setProperty(MINISERVER_PROPERTY_MINISERVER_NAME, server.getMiniserverName());
thing.setProperty(MINISERVER_PROPERTY_SERIAL, server.getSerial());
@@ -241,6 +240,7 @@ public void onNewConfig(LxServer server) {
thing.setLocation(server.getLocation());
}
+ logger.trace("Removing old channels");
ArrayList channels = new ArrayList();
ThingBuilder builder = editThing();
@@ -250,6 +250,7 @@ public void onNewConfig(LxServer server) {
}
}
+ logger.trace("Building new channels ({} controls)", server.getControls().size());
for (LxControl control : server.getControls().values()) {
Channel channel = createChannelForControl(control);
if (channel != null) {
@@ -258,6 +259,7 @@ public void onNewConfig(LxServer server) {
}
}
+ logger.trace("Sorting channels");
channels.sort(new Comparator() {
@Override
public int compare(Channel c1, Channel c2) {
@@ -265,6 +267,7 @@ public int compare(Channel c1, Channel c2) {
}
});
+ logger.trace("Updating thing");
builder.withChannels(channels);
updateThing(builder.build());
}
@@ -277,11 +280,14 @@ public void onControlStateUpdate(LxControl control) {
@Override
public void onServerGoesOnline() {
+ logger.debug("Server goes online.");
updateStatus(ThingStatus.ONLINE);
}
@Override
public void onServerGoesOffline(LxServer.OfflineReason reason, String details) {
+ logger.debug("Server goes offline: {}, {}", reason.toString(), details);
+
switch (reason) {
case AUTHENTICATION_TIMEOUT:
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, "User authentication timeout");
@@ -317,6 +323,7 @@ public void onServerGoesOffline(LxServer.OfflineReason reason, String details) {
@Override
public void dispose() {
+ logger.debug("Disposing of server");
if (server != null) {
server.stop();
server = null;
@@ -334,6 +341,10 @@ public void dispose() {
* created {@link Channel} object
*/
private Channel createChannelForControl(LxControl control) {
+
+ logger.trace("Creating channel for control: {}, {}", control.getClass().getSimpleName(),
+ control.getUuid().toString());
+
String channelLabel;
String itemType = null;
ChannelTypeUID typeId = null;
@@ -403,6 +414,16 @@ private Channel createChannelForControl(LxControl control) {
return null;
}
+ /**
+ * Builds {@link StateDescription} for channel type, that has multiple options to select from
+ *
+ * @param options
+ * collection of options, where key is option ID (number in reality) and value is option name
+ * @param lastOption
+ * maximum value an option ID can have
+ * @return
+ * state description to be used for creating channel type
+ */
private StateDescription buildStateDescription(Map options, int lastOption) {
if (options != null) {
List optionsList = new ArrayList();
@@ -416,43 +437,13 @@ private StateDescription buildStateDescription(Map options, int
}
/**
- * Create and register a new channel type
+ * Update thing's channel state with current control's state
*
- * @param controlType
- * type of Loxone control (e.g. switch, jalousie)
- * @param itemType
- * type of OpenHAB item
- * @param label
- * label for the channel type
- * @param description
- * description of the channel type
- * @param options
- * map of options for drop down lists (can be null)
- * @param lastOption
- * index of last option
- * @param controlUuid
- * UUID of Loxone control object (can be null if channel type is generic)
- * @return
- * channel type ID of newly created type
+ * @param channelUID
+ * channel ID to be updated
+ * @param control
+ * control to take state from
*/
- private ChannelTypeUID addNewChannelType(String controlType, String itemType, String label, String description,
- Map options, int lastOption, String controlUuid) {
- String name = getThing().getUID().getAsString() + ":" + controlType;
- if (controlUuid != null) {
- name += ":" + controlUuid;
- }
- ChannelTypeUID typeId = new ChannelTypeUID(name);
- ChannelType type = new ChannelType(typeId, false, itemType, label, description, null, null,
- buildStateDescription(options, lastOption), null);
- factory.removeChannelType(typeId);
- factory.addChannelType(type);
- return typeId;
- }
-
- private ChannelTypeUID addNewChannelType(String controlType, String itemType, String label, String description) {
- return addNewChannelType(controlType, itemType, label, description, null, 0, null);
- }
-
private void updateChannelState(ChannelUID channelUID, LxControl control) {
if (control instanceof LxControlSwitch) {
double value = ((LxControlSwitch) control).getState();
@@ -506,6 +497,54 @@ private void updateChannelState(ChannelUID channelUID, LxControl control) {
}
}
+ /**
+ * Create and register a new channel type
+ *
+ * @param controlType
+ * type of Loxone control (e.g. switch, jalousie)
+ * @param itemType
+ * type of OpenHAB item
+ * @param label
+ * label for the channel type
+ * @param description
+ * description of the channel type
+ * @param options
+ * map of options for drop down lists (can be null)
+ * @param lastOption
+ * index of last option
+ * @param controlUuid
+ * UUID of Loxone control object (can be null if channel type is generic)
+ * @return
+ * channel type ID of newly created type
+ */
+ private ChannelTypeUID addNewChannelType(String controlType, String itemType, String label, String description,
+ Map options, int lastOption, String controlUuid) {
+ logger.trace("Creating a new channel type for {}, {}", controlType, itemType);
+
+ String name = getThing().getUID().getAsString() + ":" + controlType;
+ if (controlUuid != null) {
+ name += ":" + controlUuid;
+ }
+ ChannelTypeUID typeId = new ChannelTypeUID(name);
+ ChannelType type = new ChannelType(typeId, false, itemType, label, description, null, null,
+ buildStateDescription(options, lastOption), null);
+ factory.removeChannelType(typeId);
+ factory.addChannelType(type);
+ return typeId;
+ }
+
+ private ChannelTypeUID addNewChannelType(String controlType, String itemType, String label, String description) {
+ return addNewChannelType(controlType, itemType, label, description, null, 0, null);
+ }
+
+ /**
+ * Based on channel ID, return corresponding {@link LxControl} object
+ *
+ * @param channelUID
+ * channel ID of the control to find
+ * @return
+ * control corresponding to the channel ID or null if not found
+ */
private LxControl getControlFromChannelUID(ChannelUID channelUID) {
String channelId = channelUID.getIdWithoutGroup();
return server.findControl(new LxUuid(channelId));