Implementation of level and color data types
This commit is contained in:
parent
a89b418350
commit
234125bc35
30 changed files with 664 additions and 113 deletions
|
|
@ -27,15 +27,14 @@ package se.hal.plugin.mqtt;
|
|||
import se.hal.daemon.HalMulticastDnsDaemon;
|
||||
import se.hal.intf.*;
|
||||
import se.hal.plugin.mqtt.device.HalMqttDeviceConfig;
|
||||
import se.hal.plugin.mqtt.device.HalMqttDeviceData;
|
||||
import zutil.InetUtil;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.net.dns.MulticastDnsServer;
|
||||
import zutil.net.mqtt.MqttBroker;
|
||||
import zutil.net.mqtt.MqttSubscriptionListener;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
|
@ -47,7 +46,7 @@ public class HalMqttController implements HalAutostartController, MqttSubscripti
|
|||
|
||||
private MqttBroker mqttBroker;
|
||||
|
||||
private HashMap<String, HalMqttDeviceConfig> topics = new HashMap<>();
|
||||
private HashMap<String, List<HalMqttDeviceConfig>> topics = new HashMap<>();
|
||||
private List<HalDeviceReportListener> deviceListeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
// --------------------------
|
||||
|
|
@ -67,6 +66,7 @@ public class HalMqttController implements HalAutostartController, MqttSubscripti
|
|||
|
||||
logger.info("Starting up MQTT Server");
|
||||
mqttBroker = new MqttBroker();
|
||||
mqttBroker.addGlobalSubscriber(this);
|
||||
mqttBroker.start();
|
||||
|
||||
} catch (IOException e) {
|
||||
|
|
@ -96,14 +96,16 @@ public class HalMqttController implements HalAutostartController, MqttSubscripti
|
|||
|
||||
@Override
|
||||
public void dataPublished(String topic, byte[] data) {
|
||||
HalMqttDeviceConfig eventConfig = topics.get(topic);
|
||||
List<HalMqttDeviceConfig> devices = topics.get(topic);
|
||||
|
||||
if (eventConfig != null && data.length > 0) {
|
||||
HalMqttDeviceData eventData = new HalMqttDeviceData(data);
|
||||
if (devices != null && data.length > 0) {
|
||||
for (HalMqttDeviceConfig deviceConfig : devices) {
|
||||
HalDeviceData deviceData = deviceConfig.getDeviceData(data);
|
||||
|
||||
if (deviceListeners != null) {
|
||||
for (HalDeviceReportListener deviceListener : deviceListeners) {
|
||||
deviceListener.reportReceived(eventConfig, eventData);
|
||||
if (deviceListeners != null) {
|
||||
for (HalDeviceReportListener deviceListener : deviceListeners) {
|
||||
deviceListener.reportReceived(deviceConfig, deviceData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -121,7 +123,10 @@ public class HalMqttController implements HalAutostartController, MqttSubscripti
|
|||
public void register(HalDeviceConfig deviceConfig) {
|
||||
if (deviceConfig instanceof HalMqttDeviceConfig) {
|
||||
HalMqttDeviceConfig mqttEvent = (HalMqttDeviceConfig) deviceConfig;
|
||||
topics.put(mqttEvent.getTopic(), mqttEvent);
|
||||
|
||||
if (!topics.containsKey(mqttEvent.getTopic()))
|
||||
topics.put(mqttEvent.getTopic(), new ArrayList<>());
|
||||
topics.get(mqttEvent.getTopic()).add(mqttEvent);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Device config is not an instance of " + HalMqttDeviceConfig.class + ": " + deviceConfig.getClass());
|
||||
|
|
@ -132,7 +137,8 @@ public class HalMqttController implements HalAutostartController, MqttSubscripti
|
|||
public void deregister(HalDeviceConfig deviceConfig) {
|
||||
if (deviceConfig instanceof HalMqttDeviceConfig) {
|
||||
HalMqttDeviceConfig mqttEvent = (HalMqttDeviceConfig) deviceConfig;
|
||||
topics.remove(mqttEvent.getTopic());
|
||||
if (topics.containsKey(mqttEvent.getTopic()))
|
||||
topics.get(mqttEvent.getTopic()).remove(deviceConfig);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +153,11 @@ public class HalMqttController implements HalAutostartController, MqttSubscripti
|
|||
|
||||
@Override
|
||||
public int size() {
|
||||
return topics.size();
|
||||
int size = 0;
|
||||
for (List<HalMqttDeviceConfig> devices : topics.values()) {
|
||||
size += devices.size();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -48,23 +48,34 @@
|
|||
|
||||
package se.hal.plugin.mqtt.device;
|
||||
|
||||
import se.hal.intf.HalEventConfig;
|
||||
import se.hal.intf.HalDeviceData;
|
||||
import se.hal.intf.HalEventController;
|
||||
import se.hal.intf.HalEventData;
|
||||
import se.hal.intf.HalSensorConfig;
|
||||
import se.hal.plugin.mqtt.HalMqttController;
|
||||
import zutil.ui.conf.Configurator;
|
||||
|
||||
public class HalMqttDeviceConfig implements HalEventConfig {
|
||||
private final String topic;
|
||||
|
||||
|
||||
public HalMqttDeviceConfig(String topic) {
|
||||
this.topic = topic;
|
||||
}
|
||||
public abstract class HalMqttDeviceConfig implements HalSensorConfig {
|
||||
@Configurator.Configurable(value = "MQTT Topic")
|
||||
private String topic;
|
||||
@Configurator.Configurable(value = "JSON Path", description = "If the value of the topic is a JSON then this parameter can be used to specify the path to the e.g. temperature value." +
|
||||
"<br>THe parameter uses the JSON-Path syntax where it always starts with $ and object fields can be accessed by .<key> and a array element by [index]")
|
||||
private String jsonPath;
|
||||
|
||||
|
||||
public String getTopic() {
|
||||
return topic;
|
||||
}
|
||||
public void setTopic(String topic) {
|
||||
this.topic = topic;
|
||||
}
|
||||
|
||||
public String getJsonPath() {
|
||||
return jsonPath;
|
||||
}
|
||||
public void setJsonPath(String jsonPath) {
|
||||
this.jsonPath = jsonPath;
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
// Hal Methods
|
||||
|
|
@ -75,15 +86,25 @@ public class HalMqttDeviceConfig implements HalEventConfig {
|
|||
return HalMqttController.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends HalEventData> getDeviceDataClass() {
|
||||
return HalMqttDeviceData.class;
|
||||
}
|
||||
/**
|
||||
* @param data the data published to the MQTT topic.
|
||||
* @return a new data object instance containing the device data based on the input data.
|
||||
*/
|
||||
public abstract HalDeviceData getDeviceData(byte[] data);
|
||||
|
||||
// --------------------------
|
||||
// Java Methods
|
||||
// --------------------------
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof HalMqttDeviceConfig)
|
||||
return topic.equals(((HalMqttDeviceConfig) obj).topic);
|
||||
return topic.equals(((HalMqttDeviceConfig) obj).topic) && jsonPath.equals(((HalMqttDeviceConfig) obj).jsonPath);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Topic: " + topic + ", JSON Path: " + jsonPath;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Ziver Koc
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package se.hal.plugin.mqtt.device;
|
||||
|
||||
import se.hal.intf.HalEventData;
|
||||
import zutil.StringUtil;
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class HalMqttDeviceData extends HalEventData {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
private double data;
|
||||
|
||||
|
||||
public HalMqttDeviceData(byte[] byteData) {
|
||||
String str = new String(byteData);
|
||||
|
||||
if (StringUtil.isDecimalNumber(str)) {
|
||||
data = Double.parseDouble(str);
|
||||
} else {
|
||||
logger.warning("Received non numeric MQTT data.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setData(double data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Ziver Koc
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2020 Ziver Koc
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package se.hal.plugin.mqtt.device;
|
||||
|
||||
import se.hal.intf.HalDeviceData;
|
||||
import se.hal.intf.HalEventController;
|
||||
import se.hal.plugin.mqtt.HalMqttController;
|
||||
import se.hal.struct.devicedata.TemperatureSensorData;
|
||||
import zutil.ObjectUtil;
|
||||
import zutil.converter.Converter;
|
||||
import zutil.parser.DataNode;
|
||||
import zutil.parser.DataNodePath;
|
||||
import zutil.parser.json.JSONParser;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class HalMqttParticularMatterDeviceConfig extends HalMqttDeviceConfig {
|
||||
|
||||
// --------------------------
|
||||
// Hal Methods
|
||||
// --------------------------
|
||||
|
||||
@Override
|
||||
public Class<? extends HalEventController> getDeviceControllerClass() {
|
||||
return HalMqttController.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends HalDeviceData> getDeviceDataClass() {
|
||||
return TemperatureSensorData.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HalDeviceData getDeviceData(byte[] data) {
|
||||
if (!ObjectUtil.isEmpty(getJsonPath())) {
|
||||
String dataStr = new String(data, StandardCharsets.UTF_8);
|
||||
DataNode json = JSONParser.read(dataStr);
|
||||
DataNode deviceDataValue = DataNodePath.search(getJsonPath(), json);
|
||||
|
||||
if (deviceDataValue != null)
|
||||
return new TemperatureSensorData(deviceDataValue.getDouble(), System.currentTimeMillis());
|
||||
else
|
||||
return null;
|
||||
}
|
||||
return new TemperatureSensorData(Converter.toInt(data), System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public AggregationMethod getAggregationMethod() {
|
||||
return AggregationMethod.AVERAGE;
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@
|
|||
"interfaces": [
|
||||
{"se.hal.intf.HalAutostartController": "se.hal.plugin.mqtt.HalMqttController"},
|
||||
|
||||
{"se.hal.intf.HalSensorConfig": "se.hal.plugin.mqtt.device.HalMqttParticularMatterDeviceConfig"},
|
||||
|
||||
{"se.hal.intf.HalWebPage": "se.hal.plugin.mqtt.page.MqttOverviewPage"}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue