Finnished major refactoring of Telstick plugin
This commit is contained in:
parent
3bdb4ea043
commit
a9b8799f21
17 changed files with 284 additions and 142 deletions
|
|
@ -102,7 +102,7 @@ public class ControllerManager implements HalSensorReportListener,
|
|||
}
|
||||
|
||||
@Override
|
||||
public void reportReceived(HalSensorConfig sensorConfig, HalSensorData sensorData) {
|
||||
public void reportReceived(HalSensorConfig sensorConfig, HalDeviceData sensorData) {
|
||||
try{
|
||||
DBConnection db = HalContext.getDB();
|
||||
Sensor sensor = findSensor(sensorConfig, registeredSensors);
|
||||
|
|
@ -191,7 +191,7 @@ public class ControllerManager implements HalSensorReportListener,
|
|||
}
|
||||
|
||||
@Override
|
||||
public void reportReceived(HalEventConfig eventConfig, HalEventData eventData) {
|
||||
public void reportReceived(HalEventConfig eventConfig, HalDeviceData eventData) {
|
||||
try {
|
||||
DBConnection db = HalContext.getDB();
|
||||
Event event = findEvent(eventConfig, registeredEvents);
|
||||
|
|
@ -234,7 +234,7 @@ public class ControllerManager implements HalSensorReportListener,
|
|||
public void send(Event event){
|
||||
HalEventController controller = getControllerInstance(event.getController());
|
||||
if(controller != null) {
|
||||
controller.send(event.getDeviceConfig());
|
||||
controller.send(event.getDeviceConfig(), event.getDeviceData());
|
||||
reportReceived(event.getDeviceConfig(), event.getDeviceData()); // save action to db
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -24,9 +24,10 @@ public interface HalEventController {
|
|||
void deregister(HalEventConfig event);
|
||||
|
||||
/**
|
||||
* @param event transmit this event if possible.
|
||||
* @param eventConfig the event configuration to target when sending
|
||||
* @param eventData the data to send
|
||||
*/
|
||||
void send(HalEventConfig event); // TODO: where to put data?
|
||||
void send(HalEventConfig eventConfig, HalEventData eventData);
|
||||
|
||||
/**
|
||||
* @return the number of registered objects
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@ package se.hal.intf;
|
|||
|
||||
public interface HalEventReportListener {
|
||||
|
||||
void reportReceived(HalEventConfig e, HalEventData d);
|
||||
void reportReceived(HalEventConfig e, HalDeviceData d);
|
||||
|
||||
}
|
||||
|
|
@ -2,6 +2,6 @@ package se.hal.intf;
|
|||
|
||||
public interface HalSensorReportListener {
|
||||
|
||||
void reportReceived(HalSensorConfig s, HalSensorData d);
|
||||
void reportReceived(HalSensorConfig s, HalDeviceData d);
|
||||
|
||||
}
|
||||
13
src/se/hal/plugin/tellstick/TellstickDevice.java
Executable file
13
src/se/hal/plugin/tellstick/TellstickDevice.java
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
package se.hal.plugin.tellstick;
|
||||
|
||||
/**
|
||||
* This interface represents a device configuration and links it to a protocol.
|
||||
*
|
||||
* Created by Ziver on 2016-08-18.
|
||||
*/
|
||||
public interface TellstickDevice {
|
||||
|
||||
|
||||
String getProtocolName(); // TODO: could be implemented in a better way
|
||||
String getModelName(); // TODO: could be implemented in a better way
|
||||
}
|
||||
|
|
@ -28,16 +28,11 @@ package se.hal.plugin.tellstick;
|
|||
* Indicates that the implementing class is a protocol that can have group events.
|
||||
* More specifically that on transmission will affect multiple devices.
|
||||
*/
|
||||
public interface TellstickGroupProtocol {
|
||||
public interface TellstickDeviceGroup {
|
||||
|
||||
/**
|
||||
* Protocols should extend this method if it has group functionality.
|
||||
* @return true if this object an the input is in the same group.
|
||||
* @return true if this object and the input object belongs to the same group.
|
||||
*/
|
||||
public boolean equalsGroup(TellstickGroupProtocol obj);
|
||||
|
||||
/**
|
||||
* Copy the state data from the group to this object.
|
||||
*/
|
||||
public void copyGroupData(TellstickGroupProtocol groupProtocol);
|
||||
public boolean equalsGroup(TellstickDeviceGroup obj);
|
||||
}
|
||||
|
|
@ -22,12 +22,15 @@
|
|||
|
||||
package se.hal.plugin.tellstick;
|
||||
|
||||
import se.hal.plugin.tellstick.TellstickProtocol.TellstickDecodedEntry;
|
||||
import se.hal.plugin.tellstick.protocol.NexaSelfLearningProtocol;
|
||||
import se.hal.plugin.tellstick.protocol.Oregon0x1A2DProtocol;
|
||||
import zutil.converter.Converter;
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
|
@ -38,7 +41,7 @@ import java.util.logging.Logger;
|
|||
*/
|
||||
public class TellstickParser {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
private static HashMap<String, Class<? extends TellstickProtocol>> protocolMap;
|
||||
private static HashMap<String, TellstickProtocol> protocolMap;
|
||||
|
||||
static {
|
||||
registerProtocol(NexaSelfLearningProtocol.class);
|
||||
|
|
@ -48,8 +51,12 @@ public class TellstickParser {
|
|||
private int firmwareVersion = -1;
|
||||
|
||||
|
||||
|
||||
public TellstickProtocol decode(String data) {
|
||||
/**
|
||||
* Will decode the given data and return a list with device and data objects
|
||||
* @param data
|
||||
* @return a list with decoded objects or empty list if there was an error
|
||||
*/
|
||||
public List<TellstickDecodedEntry> decode(String data) {
|
||||
if (data.startsWith("+W")) {
|
||||
data = data.substring(2);
|
||||
HashMap<String, String> map = new HashMap<String, String>();
|
||||
|
|
@ -59,19 +66,16 @@ public class TellstickParser {
|
|||
map.put(keyValue[0], keyValue[1]);
|
||||
}
|
||||
|
||||
Class<? extends TellstickProtocol> protClass =
|
||||
getProtocolClass(map.get("protocol"), map.get("model"));
|
||||
if (protClass != null) {
|
||||
try {
|
||||
TellstickProtocol protocol = protClass.newInstance();
|
||||
String binData = map.get("data");
|
||||
TellstickProtocol protocol =
|
||||
getProtocolInstance(map.get("protocol"), map.get("model"));
|
||||
if (protocol != null) {
|
||||
String binData = map.get("data");
|
||||
|
||||
protocol.decode(Converter.hexToByte(binData));
|
||||
logger.finest("Decoded: " + protocol);
|
||||
return protocol;
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, null, e);
|
||||
}
|
||||
logger.finest("Decoding: " + protocol);
|
||||
List<TellstickDecodedEntry> list = protocol.decode(Converter.hexToByte(binData));
|
||||
if (list == null)
|
||||
list = Collections.EMPTY_LIST;
|
||||
return list;
|
||||
} else {
|
||||
logger.warning("Unknown protocol: " + data);
|
||||
}
|
||||
|
|
@ -87,9 +91,12 @@ public class TellstickParser {
|
|||
logger.severe("Unknown prefix: " + data);
|
||||
}
|
||||
|
||||
return null;
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method blocks until a send command confirmation is received.
|
||||
*/
|
||||
public void waitSendConformation(){
|
||||
try {
|
||||
this.wait();
|
||||
|
|
@ -104,20 +111,23 @@ public class TellstickParser {
|
|||
}
|
||||
|
||||
|
||||
|
||||
public static void registerProtocol(Class<? extends TellstickProtocol> protClass) {
|
||||
try {
|
||||
if (protocolMap == null)
|
||||
protocolMap = new HashMap<>();
|
||||
TellstickProtocol tmp = protClass.newInstance();
|
||||
protocolMap.put(
|
||||
tmp.getProtocolName() + "-" + tmp.getModelName(),
|
||||
protClass);
|
||||
registerProtocol( protClass.newInstance() );
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
public static void registerProtocol(TellstickProtocol protObj) {
|
||||
if (protocolMap == null)
|
||||
protocolMap = new HashMap<>();
|
||||
protocolMap.put(
|
||||
protObj.getProtocolName() + "-" + protObj.getModelName(),
|
||||
protObj);
|
||||
}
|
||||
|
||||
public static Class<? extends TellstickProtocol> getProtocolClass(String protocol, String model) {
|
||||
public static TellstickProtocol getProtocolInstance(String protocol, String model) {
|
||||
return protocolMap.get(protocol + "-" + model);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,12 @@
|
|||
*/
|
||||
package se.hal.plugin.tellstick;
|
||||
|
||||
import se.hal.intf.HalDeviceData;
|
||||
import se.hal.intf.HalEventConfig;
|
||||
import se.hal.intf.HalEventData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-02-18.
|
||||
*/
|
||||
|
|
@ -47,6 +50,24 @@ public abstract class TellstickProtocol {
|
|||
}
|
||||
|
||||
public String encode(HalEventConfig deviceConfig, HalEventData deviceData){ return null; }
|
||||
public abstract void decode(byte[] data);
|
||||
public abstract List<TellstickDecodedEntry> decode(byte[] data);
|
||||
|
||||
|
||||
|
||||
public static class TellstickDecodedEntry {
|
||||
private TellstickDevice device;
|
||||
private HalDeviceData data;
|
||||
|
||||
public TellstickDecodedEntry(TellstickDevice device, HalDeviceData data){
|
||||
this.device = device;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public TellstickDevice getDevice(){
|
||||
return device;
|
||||
}
|
||||
public HalDeviceData getData(){
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ package se.hal.plugin.tellstick;
|
|||
import com.fazecast.jSerialComm.SerialPort;
|
||||
import se.hal.HalContext;
|
||||
import se.hal.intf.*;
|
||||
import se.hal.plugin.tellstick.TellstickProtocol.TellstickDecodedEntry;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.struct.TimedHashSet;
|
||||
|
||||
|
|
@ -51,20 +52,20 @@ public class TellstickSerialComm implements Runnable,
|
|||
private SerialPort serial;
|
||||
private InputStream in;
|
||||
private OutputStream out;
|
||||
private TimedHashSet set; // To check for duplicate transmissions
|
||||
private TimedHashSet<String> set; // To check for duplicate transmissions
|
||||
|
||||
protected TellstickParser parser;
|
||||
private HalSensorReportListener sensorListener;
|
||||
private HalEventReportListener eventListener;
|
||||
|
||||
private List<TellstickProtocol> registeredDevices;
|
||||
private List<TellstickDevice> registeredDevices;
|
||||
|
||||
|
||||
|
||||
public TellstickSerialComm() {
|
||||
set = new TimedHashSet(TRANSMISSION_UNIQUENESS_TTL);
|
||||
set = new TimedHashSet<>(TRANSMISSION_UNIQUENESS_TTL);
|
||||
parser = new TellstickParser();
|
||||
registeredDevices = Collections.synchronizedList(new ArrayList<TellstickProtocol>());
|
||||
registeredDevices = Collections.synchronizedList(new ArrayList<TellstickDevice>());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -122,21 +123,17 @@ public class TellstickSerialComm implements Runnable,
|
|||
logger.log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
private void reportEvent(TellstickProtocol protocol){
|
||||
if (sensorListener != null && protocol instanceof HalSensorConfig)
|
||||
sensorListener.reportReceived((HalSensorConfig) protocol);
|
||||
else if (eventListener != null && protocol instanceof HalEventConfig)
|
||||
eventListener.reportReceived((HalEventConfig) protocol);
|
||||
}
|
||||
|
||||
/**
|
||||
* There seems to be an issue with read(...) methods, only read() is working
|
||||
*/
|
||||
private String readLine() throws IOException {
|
||||
StringBuilder str = new StringBuilder(50);
|
||||
char c = 0;
|
||||
while((c = (char)in.read()) >= 0){
|
||||
int c;
|
||||
while((c = in.read()) >= 0){
|
||||
switch(c) {
|
||||
case -1:
|
||||
return null;
|
||||
case '\n':
|
||||
case '\r':
|
||||
if(str.length() > 0)
|
||||
|
|
@ -149,48 +146,58 @@ public class TellstickSerialComm implements Runnable,
|
|||
return str.toString();
|
||||
}
|
||||
protected void handleLine(String data){
|
||||
TellstickProtocol protocol = parser.decode(data);
|
||||
if(protocol != null) {
|
||||
if (protocol.getTimestamp() < 0)
|
||||
protocol.setTimestamp(System.currentTimeMillis());
|
||||
List<TellstickDecodedEntry> decodeList = parser.decode(data);
|
||||
for (TellstickDecodedEntry entry : decodeList) {
|
||||
if (entry.getData().getTimestamp() < 0)
|
||||
entry.getData().setTimestamp(System.currentTimeMillis());
|
||||
|
||||
boolean registered = registeredDevices.contains(protocol);
|
||||
if(registered && !set.contains(data) || // check for duplicates transmissions of registered devices
|
||||
boolean registered = registeredDevices.contains(entry.getDevice());
|
||||
if (registered && !set.contains(data) || // check for duplicates transmissions of registered devices
|
||||
!registered && set.contains(data)) { // required duplicate transmissions before reporting unregistered devices
|
||||
|
||||
//Check for registered device that are in the same group
|
||||
if(protocol instanceof TellstickGroupProtocol) {
|
||||
TellstickGroupProtocol groupProtocol = (TellstickGroupProtocol) protocol;
|
||||
for (int i=0; i<registeredDevices.size(); ++i) { // Don't use foreach for concurrency reasons
|
||||
TellstickProtocol childProtocol = registeredDevices.get(i);
|
||||
if (childProtocol instanceof TellstickGroupProtocol &&
|
||||
groupProtocol.equalsGroup(childProtocol) &&
|
||||
!protocol.equals(childProtocol)) {
|
||||
((TellstickGroupProtocol) childProtocol).copyGroupData(groupProtocol);
|
||||
childProtocol.setTimestamp(protocol.getTimestamp());
|
||||
reportEvent(childProtocol);
|
||||
if (entry.getDevice() instanceof TellstickDeviceGroup) {
|
||||
TellstickDeviceGroup groupProtocol = (TellstickDeviceGroup) entry.getDevice();
|
||||
for (int i = 0; i < registeredDevices.size(); ++i) { // Don't use foreach for concurrency reasons
|
||||
TellstickDevice childDevice = registeredDevices.get(i);
|
||||
if (childDevice instanceof TellstickDeviceGroup &&
|
||||
groupProtocol.equalsGroup((TellstickDeviceGroup)childDevice) &&
|
||||
!entry.getDevice().equals(childDevice)) {
|
||||
reportEvent(childDevice, entry.getData());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Report source event
|
||||
reportEvent(protocol);
|
||||
reportEvent(entry.getDevice(), entry.getData());
|
||||
}
|
||||
set.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
private void reportEvent(TellstickDevice tellstickDevice, HalDeviceData deviceData){
|
||||
if (sensorListener != null) {
|
||||
if (tellstickDevice instanceof HalSensorConfig)
|
||||
sensorListener.reportReceived((HalSensorConfig) tellstickDevice, deviceData);
|
||||
else if (tellstickDevice instanceof HalEventConfig)
|
||||
eventListener.reportReceived((HalEventConfig) tellstickDevice, deviceData);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(HalEventConfig event) {
|
||||
if(event instanceof TellstickProtocol)
|
||||
write((TellstickProtocol) event);
|
||||
}
|
||||
public synchronized void write(TellstickProtocol prot) {
|
||||
write(prot.encode());
|
||||
parser.waitSendConformation();
|
||||
prot.setTimestamp(System.currentTimeMillis());
|
||||
public void send(HalEventConfig deviceConfig, HalEventData deviceData) {
|
||||
if(deviceConfig instanceof TellstickDevice) {
|
||||
TellstickDevice tellstickDevice = (TellstickDevice) deviceConfig;
|
||||
TellstickProtocol prot = TellstickParser.getProtocolInstance(
|
||||
tellstickDevice.getProtocolName(),
|
||||
tellstickDevice.getModelName());
|
||||
write(prot.encode(deviceConfig, deviceData));
|
||||
|
||||
parser.waitSendConformation();
|
||||
deviceData.setTimestamp(System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
private void write(String data) {
|
||||
if (data == null)
|
||||
return;
|
||||
try {
|
||||
for(int i=0; i<data.length();i++)
|
||||
out.write(0xFF & data.charAt(i));
|
||||
|
|
@ -204,24 +211,24 @@ public class TellstickSerialComm implements Runnable,
|
|||
|
||||
@Override
|
||||
public void register(HalEventConfig event) {
|
||||
if(event instanceof TellstickProtocol)
|
||||
registeredDevices.add((TellstickProtocol) event);
|
||||
if(event instanceof TellstickDevice)
|
||||
registeredDevices.add((TellstickDevice) event);
|
||||
}
|
||||
@Override
|
||||
public void register(HalSensorConfig sensor) {
|
||||
if(sensor instanceof TellstickProtocol)
|
||||
registeredDevices.add((TellstickProtocol) sensor);
|
||||
if(sensor instanceof TellstickDevice)
|
||||
registeredDevices.add((TellstickDevice) sensor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregister(HalEventConfig event) {
|
||||
if(event instanceof TellstickProtocol)
|
||||
registeredDevices.remove((TellstickProtocol) event);
|
||||
if(event instanceof TellstickDevice)
|
||||
registeredDevices.remove(event);
|
||||
}
|
||||
@Override
|
||||
public void deregister(HalSensorConfig sensor) {
|
||||
if(sensor instanceof TellstickProtocol)
|
||||
registeredDevices.remove((TellstickProtocol) sensor);
|
||||
if(sensor instanceof TellstickDevice)
|
||||
registeredDevices.remove(sensor);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -24,38 +24,37 @@ package se.hal.plugin.tellstick.device;
|
|||
|
||||
import se.hal.intf.HalEventConfig;
|
||||
import se.hal.intf.HalEventController;
|
||||
import se.hal.plugin.tellstick.TellstickGroupProtocol;
|
||||
import se.hal.plugin.tellstick.TellstickProtocol;
|
||||
import se.hal.plugin.tellstick.TellstickDevice;
|
||||
import se.hal.plugin.tellstick.TellstickDeviceGroup;
|
||||
import se.hal.plugin.tellstick.TellstickSerialComm;
|
||||
import zutil.ByteUtil;
|
||||
import se.hal.plugin.tellstick.protocol.NexaSelfLearningProtocol;
|
||||
import zutil.parser.binary.BinaryStruct;
|
||||
import zutil.parser.binary.BinaryStructInputStream;
|
||||
import zutil.parser.binary.BinaryStructOutputStream;
|
||||
import zutil.ui.Configurator;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-02-18.
|
||||
*/
|
||||
public class NexaSelfLearning implements HalEventConfig,TellstickGroupProtocol,BinaryStruct {
|
||||
public class NexaSelfLearning implements HalEventConfig,TellstickDevice,TellstickDeviceGroup {
|
||||
|
||||
@BinaryField(index=1, length=26)
|
||||
@Configurator.Configurable("House code")
|
||||
private int house = 0;
|
||||
|
||||
@BinaryField(index=2, length=1)
|
||||
@Configurator.Configurable("Group code")
|
||||
private boolean group = false;
|
||||
|
||||
@BinaryField(index=3, length=1)
|
||||
private boolean enable = false;
|
||||
|
||||
@BinaryField(index=4, length=4)
|
||||
@Configurator.Configurable("Unit code")
|
||||
private int unit = 0;
|
||||
|
||||
|
||||
public NexaSelfLearning() { }
|
||||
public NexaSelfLearning(int house, boolean group, int unit) {
|
||||
this.house = house;
|
||||
this.group = group;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getHouse() {
|
||||
return house;
|
||||
}
|
||||
|
|
@ -80,8 +79,7 @@ public class NexaSelfLearning implements HalEventConfig,TellstickGroupProtocol,B
|
|||
public String toString(){
|
||||
return "house:"+house+
|
||||
", group:"+group+
|
||||
", unit:"+unit+
|
||||
", method:"+enable;
|
||||
", unit:"+unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -93,20 +91,21 @@ public class NexaSelfLearning implements HalEventConfig,TellstickGroupProtocol,B
|
|||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean equalsGroup(TellstickGroupProtocol obj) {
|
||||
public boolean equalsGroup(TellstickDeviceGroup obj) {
|
||||
if(obj instanceof NexaSelfLearning)
|
||||
return ((NexaSelfLearning) obj).house == house &&
|
||||
(((NexaSelfLearning) obj).group || group );
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public void copyGroupData(TellstickGroupProtocol group) {
|
||||
if(group instanceof NexaSelfLearning)
|
||||
this.enable = ((NexaSelfLearning) group).enable;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Class<? extends HalEventController> getEventController() {
|
||||
return TellstickSerialComm.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocolName() { return NexaSelfLearningProtocol.PROTOCOL; }
|
||||
@Override
|
||||
public String getModelName() { return NexaSelfLearningProtocol.MODEL; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,10 @@ package se.hal.plugin.tellstick.device;
|
|||
import se.hal.intf.HalEventController;
|
||||
import se.hal.intf.HalSensorConfig;
|
||||
import se.hal.intf.HalSensorController;
|
||||
import se.hal.plugin.tellstick.TellstickDevice;
|
||||
import se.hal.plugin.tellstick.TellstickProtocol;
|
||||
import se.hal.plugin.tellstick.TellstickSerialComm;
|
||||
import se.hal.plugin.tellstick.protocol.Oregon0x1A2DProtocol;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.ui.Configurator;
|
||||
|
||||
|
|
@ -13,7 +15,7 @@ import java.util.logging.Logger;
|
|||
/**
|
||||
* Created by Ziver on 2015-11-19.
|
||||
*/
|
||||
public class Oregon0x1A2D implements HalSensorConfig {
|
||||
public class Oregon0x1A2D implements HalSensorConfig,TellstickDevice {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
@Configurator.Configurable("Address")
|
||||
|
|
@ -23,6 +25,11 @@ public class Oregon0x1A2D implements HalSensorConfig {
|
|||
|
||||
|
||||
|
||||
public Oregon0x1A2D() { }
|
||||
public Oregon0x1A2D(int address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj){
|
||||
|
|
@ -52,4 +59,9 @@ public class Oregon0x1A2D implements HalSensorConfig {
|
|||
return TellstickSerialComm.class;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getProtocolName() { return Oregon0x1A2DProtocol.PROTOCOL; }
|
||||
@Override
|
||||
public String getModelName() { return Oregon0x1A2DProtocol.MODEL; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,29 +23,66 @@
|
|||
package se.hal.plugin.tellstick.protocol;
|
||||
|
||||
import se.hal.intf.HalEventConfig;
|
||||
import se.hal.plugin.tellstick.TellstickGroupProtocol;
|
||||
import se.hal.intf.HalEventData;
|
||||
import se.hal.plugin.tellstick.TellstickProtocol;
|
||||
import se.hal.plugin.tellstick.device.NexaSelfLearning;
|
||||
import se.hal.struct.devicedata.SwitchEventData;
|
||||
import zutil.ByteUtil;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.parser.binary.BinaryStruct;
|
||||
import zutil.parser.binary.BinaryStructInputStream;
|
||||
import zutil.parser.binary.BinaryStructOutputStream;
|
||||
import zutil.ui.Configurator;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-02-18.
|
||||
*/
|
||||
public class NexaSelfLearningProtocol extends TellstickProtocol {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
public static final String PROTOCOL = "arctech";
|
||||
public static final String MODEL = "selflearning";
|
||||
|
||||
|
||||
private static class NexaSLTransmissionStruct implements BinaryStruct{
|
||||
@BinaryField(index=1, length=26)
|
||||
int house = 0;
|
||||
|
||||
@BinaryField(index=2, length=1)
|
||||
boolean group = false;
|
||||
|
||||
@BinaryField(index=3, length=1)
|
||||
boolean enable = false;
|
||||
|
||||
@BinaryField(index=4, length=4)
|
||||
int unit = 0;
|
||||
}
|
||||
|
||||
|
||||
public NexaSelfLearningProtocol() {
|
||||
super("arctech", "selflearning");
|
||||
super(PROTOCOL, MODEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encode(){
|
||||
public String encode(HalEventConfig deviceConfig, HalEventData deviceData){
|
||||
if ( ! (deviceConfig instanceof NexaSelfLearning)){
|
||||
logger.severe("Device config is not instance of NexaSelfLearning: "+deviceConfig.getClass());
|
||||
return null;
|
||||
}
|
||||
if ( ! (deviceData instanceof SwitchEventData)){
|
||||
logger.severe("Device data is not instance of SwitchEventData: "+deviceData.getClass());
|
||||
return null;
|
||||
}
|
||||
NexaSLTransmissionStruct struct = new NexaSLTransmissionStruct();
|
||||
struct.house = ((NexaSelfLearning) deviceConfig).getHouse();
|
||||
struct.group = ((NexaSelfLearning) deviceConfig).getGroup();
|
||||
struct.enable = ((SwitchEventData) deviceData).isOn();
|
||||
struct.unit = ((NexaSelfLearning) deviceConfig).getUnit();
|
||||
|
||||
try {
|
||||
// T[t0][t1][t2][t3][length][d1]..[dn]+
|
||||
StringBuilder enc = new StringBuilder(90); // Tellstick supports max 74 bytes
|
||||
|
|
@ -54,7 +91,7 @@ public class NexaSelfLearningProtocol extends TellstickProtocol {
|
|||
|
||||
enc.append((char)0b0000_1001); // preamble
|
||||
int length = 4;
|
||||
byte[] data = BinaryStructOutputStream.serialize(this);
|
||||
byte[] data = BinaryStructOutputStream.serialize(struct);
|
||||
for (byte b : data){
|
||||
for (int i=7; i>=0; --i){
|
||||
if (ByteUtil.getBits(b, i, 1) == 0)
|
||||
|
|
@ -70,15 +107,16 @@ public class NexaSelfLearningProtocol extends TellstickProtocol {
|
|||
|
||||
enc.append("+");
|
||||
return enc.toString();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
}
|
||||
|
||||
return "";
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] data){
|
||||
public List<TellstickDecodedEntry> decode(byte[] data){
|
||||
// Data positions
|
||||
// house = 0xFFFFFFC0
|
||||
// group = 0x00000020
|
||||
|
|
@ -88,7 +126,15 @@ public class NexaSelfLearningProtocol extends TellstickProtocol {
|
|||
// 0x2CE81990 - 00101100_11101000_00011001_10 0 1 0000 - ON
|
||||
// 0x2CE81980 - 00101100_11101000_00011001_10 0 0 0000 - OFF
|
||||
|
||||
BinaryStructInputStream.read(this, data);
|
||||
NexaSLTransmissionStruct struct = new NexaSLTransmissionStruct();
|
||||
BinaryStructInputStream.read(struct, data);
|
||||
|
||||
ArrayList<TellstickDecodedEntry> list = new ArrayList<>();
|
||||
list.add(new TellstickDecodedEntry(
|
||||
new NexaSelfLearning(struct.house, struct.group, struct.unit),
|
||||
new SwitchEventData(struct.enable)
|
||||
));
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
package se.hal.plugin.tellstick.protocol;
|
||||
|
||||
import se.hal.intf.HalSensorConfig;
|
||||
import se.hal.plugin.tellstick.TellstickProtocol;
|
||||
import se.hal.plugin.tellstick.device.Oregon0x1A2D;
|
||||
import se.hal.struct.devicedata.HumiditySensorData;
|
||||
import se.hal.struct.devicedata.TemperatureSensorData;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.ui.Configurator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
|
|
@ -12,20 +15,22 @@ import java.util.logging.Logger;
|
|||
*/
|
||||
public class Oregon0x1A2DProtocol extends TellstickProtocol {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
public static final String PROTOCOL = "oregon";
|
||||
public static final String MODEL = "0x1A2D";
|
||||
|
||||
|
||||
|
||||
public Oregon0x1A2DProtocol(){
|
||||
super("oregon", "0x1A2D");
|
||||
super(PROTOCOL, MODEL);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void decode(byte[] data) {
|
||||
public List<TellstickDecodedEntry> decode(byte[] data) {
|
||||
//class:sensor;protocol:oregon;model:0x1A2D;data:20BA000000002700;
|
||||
|
||||
// int channel = (data[0] >> 4) & 0x7; // channel not used
|
||||
address = data[1] & 0xFF;
|
||||
int address = data[1] & 0xFF;
|
||||
int temp3 = (data[2] >> 4) & 0xF;
|
||||
int temp1 = (data[3] >> 4) & 0xF;
|
||||
int temp2 = data[3] & 0xF;
|
||||
|
|
@ -44,14 +49,24 @@ public class Oregon0x1A2DProtocol extends TellstickProtocol {
|
|||
|
||||
if (calcChecksum != checksum) {
|
||||
logger.fine("Checksum failed, address: "+address);
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0;
|
||||
double temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0;
|
||||
if (negative)
|
||||
temperature = -temperature;
|
||||
humidity = (hum1 * 10.0) + hum2;
|
||||
double humidity = (hum1 * 10.0) + hum2;
|
||||
|
||||
// Create return objects
|
||||
ArrayList<TellstickDecodedEntry> list = new ArrayList<>();
|
||||
Oregon0x1A2D device = new Oregon0x1A2D(address);
|
||||
list.add(new TellstickDecodedEntry(
|
||||
device, new TemperatureSensorData(temperature)
|
||||
));
|
||||
list.add(new TellstickDecodedEntry(
|
||||
device, new HumiditySensorData(humidity)
|
||||
));
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,12 @@ public class HumiditySensorData extends HalSensorData {
|
|||
private double humidity;
|
||||
|
||||
|
||||
public HumiditySensorData() { }
|
||||
public HumiditySensorData(double humidity) {
|
||||
this.humidity = humidity;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double getData() {
|
||||
return humidity;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,11 @@ public class SwitchEventData extends HalEventData {
|
|||
private boolean enabled;
|
||||
|
||||
|
||||
public SwitchEventData() { }
|
||||
public SwitchEventData(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public void turnOn(){
|
||||
enabled = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,11 @@ public class TemperatureSensorData extends HalSensorData {
|
|||
private double temperature;
|
||||
|
||||
|
||||
public TemperatureSensorData(){}
|
||||
public TemperatureSensorData(double temperature){
|
||||
this.temperature = temperature;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param data the temperature to set in degrees C
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -22,9 +22,14 @@
|
|||
|
||||
package se.hal.plugin.tellstick.protocol;
|
||||
|
||||
import se.hal.plugin.tellstick.TellstickProtocol;
|
||||
import se.hal.plugin.tellstick.TellstickProtocol.TellstickDecodedEntry;
|
||||
import se.hal.plugin.tellstick.device.NexaSelfLearning;
|
||||
import se.hal.struct.devicedata.SwitchEventData;
|
||||
import zutil.converter.Converter;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
|
@ -32,10 +37,11 @@ public class NexaSelfLearningTest {
|
|||
|
||||
@org.junit.Test
|
||||
public void testEncode() throws Exception {
|
||||
NexaSelfLearningProtocol nexa = new NexaSelfLearningProtocol();
|
||||
nexa.setHouse(11_772_006);
|
||||
nexa.setUnit(0);
|
||||
nexa.turnOn();
|
||||
NexaSelfLearning nexaDevice = new NexaSelfLearning();
|
||||
nexaDevice.setHouse(11_772_006);
|
||||
nexaDevice.setUnit(0);
|
||||
SwitchEventData nexaData = new SwitchEventData();
|
||||
nexaData.turnOn();
|
||||
|
||||
byte[] expected = Converter.toBytes(new char[]{
|
||||
84, // T
|
||||
|
|
@ -50,7 +56,8 @@ public class NexaSelfLearningTest {
|
|||
0x00, // postemble
|
||||
|
||||
43}); // +
|
||||
byte[] actual = nexa.encode().getBytes(StandardCharsets.ISO_8859_1);
|
||||
NexaSelfLearningProtocol nexaProt = new NexaSelfLearningProtocol();
|
||||
byte[] actual = nexaProt.encode(nexaDevice, nexaData).getBytes(StandardCharsets.ISO_8859_1);
|
||||
|
||||
System.out.println("Expected: "+Converter.toHexString(expected).toUpperCase());
|
||||
System.out.println("Actual : "+Converter.toHexString(actual).toUpperCase());
|
||||
|
|
@ -60,25 +67,25 @@ public class NexaSelfLearningTest {
|
|||
|
||||
@org.junit.Test
|
||||
public void decode_ON() throws Exception {
|
||||
NexaSelfLearningProtocol nexa = decode("0x2CE81990");
|
||||
TellstickDecodedEntry nexa = decode("0x2CE81990");
|
||||
|
||||
assertEquals("House Code", 11772006, nexa.getHouse());
|
||||
assertEquals("Unit Code", 0, nexa.getUnit());
|
||||
assertTrue("Enabled", nexa.isOn());
|
||||
assertEquals("House Code", 11772006, ((NexaSelfLearning)nexa.getDevice()).getHouse());
|
||||
assertEquals("Unit Code", 0, ((NexaSelfLearning)nexa.getDevice()).getUnit());
|
||||
assertTrue("Enabled", ((SwitchEventData)nexa.getData()).isOn());
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void decode_OFF() throws Exception {
|
||||
NexaSelfLearningProtocol nexa = decode("0x2CE81980");
|
||||
TellstickDecodedEntry nexa = decode("0x2CE81980");
|
||||
|
||||
assertEquals("House Code", 11772006, nexa.getHouse());
|
||||
assertEquals("Unit Code", 0, nexa.getUnit());
|
||||
assertFalse("Enabled", nexa.isOn());
|
||||
assertEquals("House Code", 11772006, ((NexaSelfLearning)nexa.getDevice()).getHouse());
|
||||
assertEquals("Unit Code", 0, ((NexaSelfLearning)nexa.getDevice()).getUnit());
|
||||
assertFalse("Enabled", ((SwitchEventData)nexa.getData()).isOn());
|
||||
}
|
||||
|
||||
private NexaSelfLearningProtocol decode(String data){
|
||||
NexaSelfLearningProtocol nexa = new NexaSelfLearningProtocol();
|
||||
nexa.decode(Converter.hexToByte(data));
|
||||
return nexa;
|
||||
private TellstickDecodedEntry decode(String data){
|
||||
NexaSelfLearningProtocol nexaProt = new NexaSelfLearningProtocol();
|
||||
List<TellstickDecodedEntry> list = nexaProt.decode(Converter.hexToByte(data));
|
||||
return list.get(0);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue