Skip to content
Snippets Groups Projects
Commit bc94880d authored by René Schöne's avatar René Schöne
Browse files

Add option to change handling of mqtt message between byte-based and string-based.

parent a85c23cf
No related branches found
No related tags found
No related merge requests found
......@@ -4,7 +4,7 @@
xsi:schemaLocation="http://eclipse.org/smarthome/schemas/binding/v1.0.0 http://eclipse.org/smarthome/schemas/binding-1.0.0.xsd">
<name>OpenLicht Binding</name>
<description>This is the binding for OpenLicht (Last Update: 2019-03-08 16:38).</description>
<description>This is the binding for OpenLicht (Last Update: 2019-04-08 16:03).</description>
<author>René Schöne</author>
</binding:binding>
......@@ -7,15 +7,20 @@
<config-description uri="thing-type:openlicht:mqttdevice">
<parameter name="brokerName" type="text" required="true">
<label>Broker Name</label>
<description>Name of the broker as defined in the &lt;broker&gt;.url in services/mqtt.cfg. See the MQTT Binding for more information on how to configure MQTT broker connections.</description>
<description>Name of the broker as defined in the name of the broker thing. See the MQTT Binding for more information on how to create a MQTT broker thing.</description>
<context>service</context>
<default>mosquitto</default>
<default>embedded-mqtt-broker</default>
</parameter>
<parameter name="base-topic" type="text" required="true">
<label>Base-Topic</label>
<description>Base topic for publishing updates. Do not include a trailing slash.</description>
<default>sensors</default>
</parameter>
<parameter name="byte-based-messages" type="boolean" required="false">
<label>Byte-based MQTT Messages</label>
<description>Interpret MQTT messages as raw bytes. If false, interpret the messages as Strings containing numbers.</description>
<default>false</default>
</parameter>
<parameter name="unsupported-category-reset" type="integer" required="false">
<label>MQTT Unsupported Category Reset Timeout</label>
<description>Timeout in seconds to log again unsupported MQTT categories. Set to zero to disable (default).</description>
......
......@@ -29,6 +29,7 @@ public class BindingConstants {
// Configuration keys
public static final String CONFIG_BROKER_NAME = "brokerName";
public static final String CONFIG_BASE_TOPIC = "base-topic";
public static final String CONFIG_BYTE_BASED_MESSAGES = "byte-based-messages";
public static final String CONFIG_TIMEOUT_MQTT_UNSUPPORTED_CATEGORIES = "unsupported-category-reset";
// List of all Thing Type UIDs
......
......@@ -39,6 +39,7 @@ public abstract class AbstractMqttHandler extends BaseThingHandler
private Version version;
private Lock configUpdateLock;
private String myBrokerName;
protected boolean byteBaseMessages;
public AbstractMqttHandler(Thing thing, ConfigurationHolder configurationHolder) {
super(thing);
......@@ -93,6 +94,7 @@ public abstract class AbstractMqttHandler extends BaseThingHandler
new Thread(() -> {
try {
configUpdateLock.lock();
this.byteBaseMessages = getConfigValueAsBoolean(CONFIG_BYTE_BASED_MESSAGES);
String brokerName = getConfigValueAsString(CONFIG_BROKER_NAME);
if (brokerName == null) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "BrokerName not set");
......@@ -121,6 +123,10 @@ public abstract class AbstractMqttHandler extends BaseThingHandler
return bd == null ? null : bd.intValue();
}
protected boolean getConfigValueAsBoolean(String key) {
return (boolean) getThing().getConfiguration().get(key);
}
public void myBrokerAdded(MqttBrokerConnection broker) {
this.logger.info("Got correct broker, subscribing to topic {}", getTopic());
currentBrokerConnection = broker;
......@@ -216,7 +222,7 @@ public abstract class AbstractMqttHandler extends BaseThingHandler
* @param input the buffer to read from
* @param output the array to write in
*/
protected void writeFloatArray(ByteBuffer input, float[] output) {
protected static void writeFloatArray(ByteBuffer input, float[] output) {
for (int i = 0; i < output.length; i++) {
output[i] = input.getFloat();
}
......
......@@ -15,6 +15,7 @@ package org.openhab.binding.openlicht.handler;
import static org.openhab.binding.openlicht.BindingConstants.*;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
......@@ -79,27 +80,42 @@ public abstract class AbstractSmartWatchHandler extends AbstractMqttHandler {
public void processMessage(String topic, byte[] payload) {
// switch category of message (last part of topic after last slash)
String category = topic.substring(getTopicLength());
if (byteBaseMessages) {
ByteBuffer buffer = ByteBuffer.wrap(payload);
float[] values;
FloatBuffer floatBuffer;
switch (category) {
case MQTT_CATEGORY_BRIGHTNESS:
updateState(CHANNEL_BRIGHTNESS, new DecimalType(buffer.getFloat()));
break;
case MQTT_CATEGORY_ACCELERATION:
values = new float[3];
writeFloatArray(buffer, values);
updateState(CHANNEL_ACCELERATION_X, new DecimalType(values[0]));
updateState(CHANNEL_ACCELERATION_Y, new DecimalType(values[1]));
updateState(CHANNEL_ACCELERATION_Z, new DecimalType(values[2]));
floatBuffer = buffer.asFloatBuffer();
updateState(CHANNEL_ACCELERATION_X, new DecimalType(floatBuffer.get(0)));
updateState(CHANNEL_ACCELERATION_Y, new DecimalType(floatBuffer.get(1)));
updateState(CHANNEL_ACCELERATION_Z, new DecimalType(floatBuffer.get(2)));
case MQTT_CATEGORY_ROTATION:
values = new float[3];
writeFloatArray(buffer, values);
updateState(CHANNEL_ROTATION_X, new DecimalType(values[0]));
updateState(CHANNEL_ROTATION_Y, new DecimalType(values[1]));
updateState(CHANNEL_ROTATION_Z, new DecimalType(values[2]));
floatBuffer = buffer.asFloatBuffer();
updateState(CHANNEL_ROTATION_X, new DecimalType(floatBuffer.get(0)));
updateState(CHANNEL_ROTATION_Y, new DecimalType(floatBuffer.get(1)));
updateState(CHANNEL_ROTATION_Z, new DecimalType(floatBuffer.get(2)));
default:
logUnsupportedCategory(category);
}
} else {
String message = new String(payload);
switch (category) {
case MQTT_CATEGORY_BRIGHTNESS:
updateState(CHANNEL_BRIGHTNESS, new DecimalType(Float.parseFloat(message)));
break;
case MQTT_CATEGORY_ACCELERATION:
MqttUtils.handleAcceleration(message, this::updateState);
break;
case MQTT_CATEGORY_ROTATION:
MqttUtils.handleRotation(message, this::updateState);
break;
default:
logUnsupportedCategory(category);
}
}
}
private void logUnsupportedCategory(String category) {
......
......@@ -59,6 +59,7 @@ public abstract class AbstractSmartphoneHandler extends AbstractMqttHandler {
public void processMessage(String topic, byte[] payload) {
// switch category of message (last part of topic after last slash)
String category = topic.substring(getTopicLength());
if (byteBaseMessages) {
ByteBuffer buffer = ByteBuffer.wrap(payload);
FloatBuffer floatBuffer;
switch (category) {
......@@ -73,6 +74,19 @@ public abstract class AbstractSmartphoneHandler extends AbstractMqttHandler {
default:
logUnsupportedCategory(category);
}
} else {
String message = new String(payload);
switch (category) {
case MQTT_CATEGORY_BRIGHTNESS:
updateState(CHANNEL_BRIGHTNESS, new DecimalType(Float.parseFloat(message)));
break;
case MQTT_CATEGORY_ROTATION:
MqttUtils.handleRotation(message, this::updateState);
break;
default:
logUnsupportedCategory(category);
}
}
}
private void logUnsupportedCategory(String category) {
......
package org.openhab.binding.openlicht.handler;
import static org.openhab.binding.openlicht.BindingConstants.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.BiConsumer;
import org.eclipse.smarthome.core.library.types.DecimalType;
import org.eclipse.smarthome.core.types.State;
public class MqttUtils {
@FunctionalInterface
public interface UpdateState extends BiConsumer<String, State> {
}
public static Map<String, DecimalType> handleSimpleJsonMessage(final String message) {
Map<String, DecimalType> result = new HashMap<>();
String content = message.substring(1, message.length() - 1);
String[] tokens = content.split(",");
for (String tok : tokens) {
String[] keyValue = tok.split("=");
String key = keyValue[0].trim();
DecimalType value = new DecimalType(Float.parseFloat(keyValue[1].trim()));
result.put(key, value);
}
return result;
}
public static void handleRotation(String message, UpdateState updateState) {
// state has the form "{z=$FLOAT, x=$FLOAT, y=$FLOAT}"
Map<String, DecimalType> json = MqttUtils.handleSimpleJsonMessage(message);
String channelId;
for (Entry<String, DecimalType> entry : json.entrySet()) {
switch (entry.getKey()) {
case "x":
channelId = CHANNEL_ROTATION_X;
break;
case "y":
channelId = CHANNEL_ROTATION_Y;
break;
case "z":
channelId = CHANNEL_ROTATION_Z;
break;
default:
System.err.print("Unknown JSON key: " + entry.getKey());
continue;
}
updateState.accept(channelId, entry.getValue());
}
}
public static void handleAcceleration(String message, UpdateState updateState) {
// state has the form "{z=$FLOAT, x=$FLOAT, y=$FLOAT}"
Map<String, DecimalType> json = MqttUtils.handleSimpleJsonMessage(message);
String channelId;
for (Entry<String, DecimalType> entry : json.entrySet()) {
switch (entry.getKey()) {
case "x":
channelId = CHANNEL_ACCELERATION_X;
break;
case "y":
channelId = CHANNEL_ACCELERATION_Y;
break;
case "z":
channelId = CHANNEL_ACCELERATION_Z;
break;
default:
System.err.print("Unknown JSON key: " + entry.getKey());
continue;
}
updateState.accept(channelId, entry.getValue());
}
}
}
......@@ -20,7 +20,7 @@ package org.openhab.binding.openlicht.internal;
public class OpenLichtConfiguration {
/**
* Name of the broker as defined in the &lt;broker&gt;.url in services/mqtt.cfg.
* Name of the broker as defined in the name of the broker thing.
*/
public String brokerName;
......@@ -29,6 +29,12 @@ public class OpenLichtConfiguration {
*/
public String baseTopic;
/**
* Interpret MQTT messages as raw bytes. If <code>false</code>, interpret the messages as Strings containing
* numbers.
*/
public boolean byteBasedMessages;
/**
* Timeout in seconds to log again unsupported MQTT categories. Set to zero to disable (default).
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment