Skip to content

Commit

Permalink
Refactoring of the code, added more debug and trace messages.
Browse files Browse the repository at this point in the history
Fixed issue with processing unsupported sub-controls.
Fixed issue with passing binary message size from configuration.
  • Loading branch information
ppieczul committed Jun 16, 2017
1 parent 1aa38bb commit 28bf02b
Showing 8 changed files with 224 additions and 121 deletions.
2 changes: 1 addition & 1 deletion ESH-INF/thing/thing-types.xml
Original file line number Diff line number Diff line change
@@ -85,7 +85,7 @@
<advanced>true</advanced>
<default>30</default>
</parameter>
<parameter name="maxBinaryMsgSize" type="integer" min="0" max="102400" required="true" groupName="sizes">
<parameter name="maxBinMsgSize" type="integer" min="0" max="102400" required="true" groupName="sizes">
<label>Maximum binary message size (kB)</label>
<description>Websocket client's maximum binary message size in kB</description>
<advanced>true</advanced>
2 changes: 1 addition & 1 deletion META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -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:
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@

<groupId>org.openhab.binding</groupId>
<artifactId>org.openhab.binding.loxone</artifactId>
<version>2.1.0-12</version>
<version>2.1.0-13</version>

<name>Loxone Binding</name>
<packaging>eclipse-plugin</packaging>
47 changes: 36 additions & 11 deletions src/main/java/org/openhab/binding/loxone/core/LxControl.java
Original file line number Diff line number Diff line change
@@ -35,10 +35,10 @@ public abstract class LxControl {
private LxContainer room;
private LxCategory category;
private Map<String, LxControlState> states = new HashMap<String, LxControlState>();
Logger logger = LoggerFactory.getLogger(LxControl.class);

LxUuid uuid;
LxWsClient socketClient;
Logger logger = LoggerFactory.getLogger(LxControl.class);
Map<LxUuid, LxControl> subControls = new HashMap<LxUuid, LxControl>();

/**
@@ -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<String, JsonElement> 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;
Original file line number Diff line number Diff line change
@@ -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<String, String> sceneNames = new TreeMap<String, String>();
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<LxUuid> toRemove = new ArrayList<LxUuid>(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);
}
}

/**
67 changes: 47 additions & 20 deletions src/main/java/org/openhab/binding/loxone/core/LxServer.java
Original file line number Diff line number Diff line change
@@ -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<LxServerEvent> queue = new LinkedBlockingQueue<LxServerEvent>();

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) {
Loading

0 comments on commit 28bf02b

Please sign in to comment.