Mooved Tellstick plugin to plugin folder and added all targets to build xml
This commit is contained in:
parent
efdbc56859
commit
da290e570f
25 changed files with 155 additions and 11 deletions
96
plugins/tellstick/build.xml
Executable file
96
plugins/tellstick/build.xml
Executable file
|
|
@ -0,0 +1,96 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="Tellstick Plugin" >
|
||||
|
||||
<!-- ________________________ PROPERTIES AND SETTINGS ________________________ -->
|
||||
|
||||
<!--common properties-->
|
||||
<property name="root" value="." />
|
||||
<property name="srcDir" value="${root}/src" />
|
||||
<property name="testDir" value="${root}/test" />
|
||||
<property name="libDir" value="${root}/lib" />
|
||||
|
||||
<property name="buildRoot" value="${root}/build" />
|
||||
<property name="compileDir" value="${buildRoot}/production" />
|
||||
<property name="compileTestDir" value="${buildRoot}/test" />
|
||||
<property name="releaseDir" value="${buildRoot}/release" />
|
||||
<property name="releaseJar" value="tellstick.jar" />
|
||||
<property name="reportsDir" value="../../${buildRoot}/reports" /> <!-- Use Hal reports folder -->
|
||||
|
||||
<!-- ________________________ CLASSPATH ________________________ -->
|
||||
|
||||
<!--define standard arguments for javac-->
|
||||
<presetdef name="javac">
|
||||
<javac includeantruntime="false" />
|
||||
</presetdef>
|
||||
|
||||
<!--classpath included when building-->
|
||||
<path id="classpath.build">
|
||||
<fileset dir="${libDir}">
|
||||
<include name="**/*.jar"/>
|
||||
</fileset>
|
||||
<pathelement location="${compileDir}" />
|
||||
<!-- Hal core -->
|
||||
<pathelement location="../../build/production" />
|
||||
<fileset dir="../../lib">
|
||||
<include name="**/*.jar"/>
|
||||
</fileset>
|
||||
</path>
|
||||
|
||||
<path id="classpath.test">
|
||||
<pathelement location="${compileTestDir}" />
|
||||
<pathelement location="../../${compileTestDir}" />
|
||||
<!--include libraries used for building-->
|
||||
<path refid="classpath.build"/>
|
||||
</path>
|
||||
|
||||
|
||||
<!-- ________________________ EXECUTION TARGETS ________________________ -->
|
||||
|
||||
<target name="test" depends="build-test">
|
||||
<mkdir dir="${reportsDir}" />
|
||||
<junit printsummary="yes" haltonfailure="false" fork="true">
|
||||
<classpath refid="classpath.test" />
|
||||
<formatter type="plain" usefile="false" /> <!-- to screen -->
|
||||
<formatter type="xml" /> <!-- to file -->
|
||||
|
||||
<batchtest todir="${reportsDir}" skipNonTests="true">
|
||||
<fileset dir="${compileTestDir}" includes="**/*Test*.class" />
|
||||
</batchtest>
|
||||
</junit>
|
||||
</target>
|
||||
|
||||
<!-- ________________________ BUILD TARGETS ________________________ -->
|
||||
|
||||
<!--clean all build paths-->
|
||||
<target name="clean">
|
||||
<delete includeemptydirs="true" failonerror="false">
|
||||
<fileset dir="${buildRoot}" includes="**/*"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<!--build product code-->
|
||||
<target name="build">
|
||||
<mkdir dir="${compileDir}" />
|
||||
<javac srcdir="${srcDir}" destdir="${compileDir}" debug="yes" debugLevel="lines,vars,source" fork="yes">
|
||||
<classpath refid="classpath.build" />
|
||||
<include name="**/*.java" />
|
||||
</javac>
|
||||
<copy todir="${compileDir}">
|
||||
<fileset dir="${srcDir}"
|
||||
excludes="**/*.java" />
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<target name="build-test" depends="build">
|
||||
<mkdir dir="${compileTestDir}" />
|
||||
<javac srcdir="${testDir}" destdir="${compileTestDir}" debug="yes" debugLevel="lines,vars,source" fork="yes">
|
||||
<classpath refid="classpath.test" />
|
||||
<include name="**/*.java" />
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="package" depends="build">
|
||||
<jar destfile="${releaseDir}/${releaseJar}" basedir="${compileDir}" />
|
||||
</target>
|
||||
|
||||
</project>
|
||||
13
plugins/tellstick/src/se/hal/plugin/tellstick/TellstickDevice.java
Executable file
13
plugins/tellstick/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
|
||||
}
|
||||
38
plugins/tellstick/src/se/hal/plugin/tellstick/TellstickDeviceGroup.java
Executable file
38
plugins/tellstick/src/se/hal/plugin/tellstick/TellstickDeviceGroup.java
Executable file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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.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 TellstickDeviceGroup {
|
||||
|
||||
/**
|
||||
* Protocols should extend this method if it has group functionality.
|
||||
* @return true if this object and the input object belongs to the same group.
|
||||
*/
|
||||
public boolean equalsGroup(TellstickDeviceGroup obj);
|
||||
}
|
||||
133
plugins/tellstick/src/se/hal/plugin/tellstick/TellstickParser.java
Executable file
133
plugins/tellstick/src/se/hal/plugin/tellstick/TellstickParser.java
Executable file
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Ziver
|
||||
*
|
||||
* 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.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;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-02-18.
|
||||
*
|
||||
* Protocol Specification: http://developer.telldus.com/doxygen/TellStick.html
|
||||
*/
|
||||
public class TellstickParser {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
private static HashMap<String, TellstickProtocol> protocolMap;
|
||||
|
||||
static {
|
||||
registerProtocol(NexaSelfLearningProtocol.class);
|
||||
registerProtocol(Oregon0x1A2DProtocol.class);
|
||||
}
|
||||
|
||||
private int firmwareVersion = -1;
|
||||
|
||||
|
||||
/**
|
||||
* 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>();
|
||||
String[] parameters = data.split(";");
|
||||
for (String parameter : parameters) {
|
||||
String[] keyValue = parameter.split(":");
|
||||
map.put(keyValue[0], keyValue[1]);
|
||||
}
|
||||
|
||||
TellstickProtocol protocol =
|
||||
getProtocolInstance(map.get("protocol"), map.get("model"));
|
||||
if (protocol != null) {
|
||||
String binData = map.get("data");
|
||||
|
||||
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);
|
||||
}
|
||||
} else if (data.startsWith("+S") || data.startsWith("+T")) {
|
||||
// This is confirmation of send commands
|
||||
synchronized (this) {
|
||||
this.notifyAll();
|
||||
}
|
||||
} else if (data.startsWith("+V")) {
|
||||
if (data.length() > 2)
|
||||
firmwareVersion = Integer.parseInt(data.substring(2));
|
||||
}else {
|
||||
logger.severe("Unknown prefix: " + data);
|
||||
}
|
||||
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method blocks until a send command confirmation is received.
|
||||
*/
|
||||
public synchronized void waitSendConformation(){
|
||||
try {
|
||||
this.wait();
|
||||
} catch (InterruptedException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public int getFirmwareVersion() {
|
||||
return firmwareVersion;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static void registerProtocol(Class<? extends TellstickProtocol> protClass) {
|
||||
try {
|
||||
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 TellstickProtocol getProtocolInstance(String protocol, String model) {
|
||||
return protocolMap.get(protocol + "-" + model);
|
||||
}
|
||||
}
|
||||
74
plugins/tellstick/src/se/hal/plugin/tellstick/TellstickProtocol.java
Executable file
74
plugins/tellstick/src/se/hal/plugin/tellstick/TellstickProtocol.java
Executable file
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Ziver
|
||||
*
|
||||
* 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.tellstick;
|
||||
|
||||
import se.hal.intf.HalDeviceData;
|
||||
import se.hal.intf.HalEventConfig;
|
||||
import se.hal.intf.HalEventData;
|
||||
import se.hal.plugin.tellstick.cmd.TellstickCmd;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-02-18.
|
||||
*/
|
||||
public abstract class TellstickProtocol {
|
||||
|
||||
private final String protocol;
|
||||
private final String model;
|
||||
|
||||
|
||||
public TellstickProtocol(String protocol, String model){
|
||||
this.protocol = protocol;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
|
||||
public String getProtocolName(){
|
||||
return protocol;
|
||||
}
|
||||
public String getModelName(){
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
public TellstickCmd encode(HalEventConfig deviceConfig, HalEventData deviceData){ return null; }
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
270
plugins/tellstick/src/se/hal/plugin/tellstick/TellstickSerialComm.java
Executable file
270
plugins/tellstick/src/se/hal/plugin/tellstick/TellstickSerialComm.java
Executable file
|
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Ziver
|
||||
*
|
||||
* 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.tellstick;
|
||||
|
||||
import com.fazecast.jSerialComm.SerialPort;
|
||||
import se.hal.HalContext;
|
||||
import se.hal.intf.*;
|
||||
import se.hal.plugin.tellstick.TellstickProtocol.TellstickDecodedEntry;
|
||||
import se.hal.plugin.tellstick.cmd.TellstickCmd;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.struct.TimedHashSet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
|
||||
/**
|
||||
* Tellstick serial port controller, this class handles all tellstick
|
||||
* communication and reporting to Hal
|
||||
*/
|
||||
public class TellstickSerialComm implements Runnable,
|
||||
HalSensorController, HalEventController, HalAutoScannableController {
|
||||
private static final long TRANSMISSION_UNIQUENESS_TTL = 1000; // milliseconds
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
private static TellstickSerialComm instance; // Todo: Don't like this but it is the best I could come up with
|
||||
|
||||
private SerialPort serial;
|
||||
private InputStream in;
|
||||
private OutputStream out;
|
||||
private TimedHashSet<String> set; // To check for duplicate transmissions
|
||||
|
||||
protected TellstickParser parser;
|
||||
private HalSensorReportListener sensorListener;
|
||||
private HalEventReportListener eventListener;
|
||||
|
||||
private List<TellstickDevice> registeredDevices;
|
||||
|
||||
|
||||
|
||||
public TellstickSerialComm() {
|
||||
set = new TimedHashSet<>(TRANSMISSION_UNIQUENESS_TTL);
|
||||
parser = new TellstickParser();
|
||||
registeredDevices = Collections.synchronizedList(new ArrayList<TellstickDevice>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return HalContext.getStringProperty("tellstick.com_port") != null;
|
||||
}
|
||||
@Override
|
||||
public void initialize() throws Exception {
|
||||
// Read properties
|
||||
String port = HalContext.getStringProperty("tellstick.com_port");
|
||||
if (port == null)
|
||||
port = "COM1"; // defaults
|
||||
|
||||
initialize(port);
|
||||
}
|
||||
|
||||
public void initialize(String portName) throws Exception {
|
||||
if (instance != null)
|
||||
throw new IllegalStateException("There is a previous TellstickSerialComm instance, only one allowed");
|
||||
instance = this;
|
||||
|
||||
logger.info("Connecting to com port... ("+ portName +")");
|
||||
serial = SerialPort.getCommPort(portName);
|
||||
serial.setBaudRate(9600);
|
||||
if(!serial.openPort())
|
||||
throw new IOException("Could not open port: "+portName);
|
||||
serial.setComPortTimeouts(
|
||||
SerialPort.TIMEOUT_READ_BLOCKING, 0, 0);
|
||||
|
||||
in = serial.getInputStream();
|
||||
out = serial.getOutputStream();
|
||||
|
||||
Executors.newSingleThreadExecutor().execute(this);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
if(serial != null) {
|
||||
try {
|
||||
serial.closePort();
|
||||
in.close();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
serial = null;
|
||||
in = null;
|
||||
out = null;
|
||||
instance = null;
|
||||
}
|
||||
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
String data;
|
||||
while (in != null && (data = readLine()) != null) {
|
||||
handleLine(data);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* There seems to be an issue with read(...) methods, only read() is working
|
||||
*/
|
||||
private String readLine() throws IOException {
|
||||
StringBuilder str = new StringBuilder(50);
|
||||
int c;
|
||||
while((c = in.read()) >= 0){
|
||||
switch(c) {
|
||||
case -1:
|
||||
return null;
|
||||
case '\n':
|
||||
case '\r':
|
||||
if(str.length() > 0)
|
||||
return str.toString();
|
||||
break;
|
||||
default:
|
||||
str.append((char)c);
|
||||
}
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
protected void handleLine(String data){
|
||||
List<TellstickDecodedEntry> decodeList = parser.decode(data);
|
||||
for (TellstickDecodedEntry entry : decodeList) {
|
||||
if (entry.getData().getTimestamp() < 0)
|
||||
entry.getData().setTimestamp(System.currentTimeMillis());
|
||||
|
||||
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 (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(entry.getDevice(), entry.getData());
|
||||
}
|
||||
}
|
||||
set.add(data);
|
||||
}
|
||||
private void reportEvent(TellstickDevice tellstickDevice, HalDeviceData deviceData){
|
||||
if (sensorListener != null && tellstickDevice instanceof HalSensorConfig)
|
||||
sensorListener.reportReceived((HalSensorConfig) tellstickDevice, (HalSensorData) deviceData);
|
||||
else if (eventListener != null && tellstickDevice instanceof HalEventConfig)
|
||||
eventListener.reportReceived((HalEventConfig) tellstickDevice, (HalEventData) deviceData);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(HalEventConfig deviceConfig, HalEventData deviceData) {
|
||||
if(deviceConfig instanceof TellstickDevice) {
|
||||
TellstickDevice tellstickDevice = (TellstickDevice) deviceConfig;
|
||||
TellstickProtocol prot = TellstickParser.getProtocolInstance(
|
||||
tellstickDevice.getProtocolName(),
|
||||
tellstickDevice.getModelName());
|
||||
TellstickCmd cmd = prot.encode(deviceConfig, deviceData);
|
||||
if (cmd != null)
|
||||
write(cmd.getTransmissionString());
|
||||
|
||||
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));
|
||||
out.write('\n');
|
||||
out.flush();
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void register(HalEventConfig event) {
|
||||
if(event instanceof TellstickDevice)
|
||||
registeredDevices.add((TellstickDevice) event);
|
||||
else throw new IllegalArgumentException(
|
||||
"Device config is not an instance of "+TellstickDevice.class+": "+event.getClass());
|
||||
}
|
||||
@Override
|
||||
public void register(HalSensorConfig sensor) {
|
||||
if(sensor instanceof TellstickDevice)
|
||||
registeredDevices.add((TellstickDevice) sensor);
|
||||
else throw new IllegalArgumentException(
|
||||
"Device config is not an instance of "+TellstickDevice.class+": "+sensor.getClass());
|
||||
}
|
||||
|
||||
public <T> List<T> getRegisteredDevices(Class<T> clazz){
|
||||
ArrayList<T> list = new ArrayList<>();
|
||||
for (TellstickDevice device : registeredDevices){
|
||||
if (clazz.isAssignableFrom(device.getClass()))
|
||||
list.add((T) device);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregister(HalEventConfig event) {
|
||||
registeredDevices.remove(event);
|
||||
}
|
||||
@Override
|
||||
public void deregister(HalSensorConfig sensor) {
|
||||
registeredDevices.remove(sensor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return registeredDevices.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListener(HalEventReportListener listener) {
|
||||
eventListener = listener;
|
||||
}
|
||||
@Override
|
||||
public void setListener(HalSensorReportListener listener) {
|
||||
sensorListener = listener;
|
||||
}
|
||||
|
||||
|
||||
public static TellstickSerialComm getInstance(){
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
10
plugins/tellstick/src/se/hal/plugin/tellstick/cmd/TellstickCmd.java
Executable file
10
plugins/tellstick/src/se/hal/plugin/tellstick/cmd/TellstickCmd.java
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
package se.hal.plugin.tellstick.cmd;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2016-08-29.
|
||||
*/
|
||||
public interface TellstickCmd {
|
||||
|
||||
String getTransmissionString();
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
package se.hal.plugin.tellstick.cmd;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2016-08-29.
|
||||
*/
|
||||
public class TellstickCmdExtendedSend implements TellstickCmd{
|
||||
private static int OFFSET_TIMINGS = 1;
|
||||
private static int OFFSET_PULSE_LENGTH = 5;
|
||||
private static int OFFSET_PULSES = 6;
|
||||
|
||||
private byte[] cmd = new byte[79];
|
||||
private int length = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @param timing set first timing in us
|
||||
* @return an instance of itself
|
||||
*/
|
||||
public TellstickCmdExtendedSend setPulls0Timing(int timing){
|
||||
setPullsTiming(0, timing); return this;
|
||||
}
|
||||
/**
|
||||
* @param timing set second timing in us
|
||||
* @return an instance of itself
|
||||
*/
|
||||
public TellstickCmdExtendedSend setPulls1Timing(int timing){
|
||||
setPullsTiming(1, timing); return this;
|
||||
}
|
||||
/**
|
||||
* @param timing set third timing in us
|
||||
* @return an instance of itself
|
||||
*/
|
||||
public TellstickCmdExtendedSend setPulls2Timing(int timing){
|
||||
setPullsTiming(2, timing); return this;
|
||||
}
|
||||
/**
|
||||
* @param timing set fourth timing in us
|
||||
* @return an instance of itself
|
||||
*/
|
||||
public TellstickCmdExtendedSend setPulls3Timing(int timing){
|
||||
setPullsTiming(3, timing); return this;
|
||||
}
|
||||
/**
|
||||
* @param i an index from 0 to 3
|
||||
* @param timing set first pulls length in us between 0-2550
|
||||
* @return an instance of itself
|
||||
*/
|
||||
private void setPullsTiming(int i, int timing){ // TODO: should probably have high and low timing to be called pulls
|
||||
if (0 > timing || timing > 2550)
|
||||
throw new IllegalArgumentException("Invalid pulls "+timing+" must be between 0-2550" );
|
||||
cmd[OFFSET_TIMINGS + i] = (byte)(timing/10);
|
||||
}
|
||||
|
||||
|
||||
public TellstickCmdExtendedSend addPulls0(){
|
||||
addPulls(0); return this;
|
||||
}
|
||||
public TellstickCmdExtendedSend addPulls1(){
|
||||
addPulls(1); return this;
|
||||
}
|
||||
public TellstickCmdExtendedSend addPulls2(){
|
||||
addPulls(2); return this;
|
||||
}
|
||||
public TellstickCmdExtendedSend addPulls3(){
|
||||
addPulls(3); return this;
|
||||
}
|
||||
private void addPulls(int i) {
|
||||
if (OFFSET_PULSES+(length/4) > cmd.length)
|
||||
throw new IndexOutOfBoundsException("Maximum length "+cmd.length+" reached");
|
||||
switch (length % 4){
|
||||
case 0:
|
||||
cmd[OFFSET_PULSES+ length/4] |= 0b1100_0000 & (i << 6); break;
|
||||
case 1:
|
||||
cmd[OFFSET_PULSES+ length/4] |= 0b0011_0000 & (i << 4); break;
|
||||
case 2:
|
||||
cmd[OFFSET_PULSES+ length/4] |= 0b0000_1100 & (i << 2); break;
|
||||
case 3:
|
||||
cmd[OFFSET_PULSES+ length/4] |= 0b0000_0011 & (i); break;
|
||||
}
|
||||
length++;
|
||||
}
|
||||
|
||||
|
||||
public String getTransmissionString(){
|
||||
cmd[0] = 'T';
|
||||
cmd[OFFSET_PULSE_LENGTH] = (byte)length;
|
||||
cmd[OFFSET_PULSES+(int)Math.ceil(length/4.0)] = '+';
|
||||
return new String(cmd, 0, OFFSET_PULSES+(int)Math.ceil(length/4.0)+1, StandardCharsets.ISO_8859_1);
|
||||
}
|
||||
}
|
||||
35
plugins/tellstick/src/se/hal/plugin/tellstick/cmd/TellstickCmdSend.java
Executable file
35
plugins/tellstick/src/se/hal/plugin/tellstick/cmd/TellstickCmdSend.java
Executable file
|
|
@ -0,0 +1,35 @@
|
|||
package se.hal.plugin.tellstick.cmd;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2016-08-29.
|
||||
*/
|
||||
public class TellstickCmdSend implements TellstickCmd{
|
||||
private static int OFFSET_PULSES = 1;
|
||||
|
||||
private byte[] cmd = new byte[79];
|
||||
private int length = 0;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param timing adds a pulls timing in us between 0-2550
|
||||
* @return an instance of itself
|
||||
*/
|
||||
private void addPulls(int timing) { // TODO: should probably have high and low timing to be called pulls
|
||||
if (OFFSET_PULSES+length > cmd.length)
|
||||
throw new IndexOutOfBoundsException("Maximum length "+cmd.length+" reached");
|
||||
if (0 > timing || timing > 2550)
|
||||
throw new IllegalArgumentException("Invalid pulls "+timing+" must be between 0-2550" );
|
||||
cmd[OFFSET_PULSES+length] = (byte)(timing/10);
|
||||
length++;
|
||||
}
|
||||
|
||||
|
||||
public String getTransmissionString(){
|
||||
cmd[0] = 'S';
|
||||
cmd[OFFSET_PULSES+length] = '+';
|
||||
return new String(cmd, 0, OFFSET_PULSES+length+1, StandardCharsets.ISO_8859_1);
|
||||
}
|
||||
}
|
||||
119
plugins/tellstick/src/se/hal/plugin/tellstick/device/NexaSelfLearning.java
Executable file
119
plugins/tellstick/src/se/hal/plugin/tellstick/device/NexaSelfLearning.java
Executable file
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Ziver
|
||||
*
|
||||
* 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.tellstick.device;
|
||||
|
||||
import se.hal.intf.HalEventConfig;
|
||||
import se.hal.intf.HalEventController;
|
||||
import se.hal.intf.HalEventData;
|
||||
import se.hal.intf.HalSensorData;
|
||||
import se.hal.plugin.tellstick.TellstickDevice;
|
||||
import se.hal.plugin.tellstick.TellstickDeviceGroup;
|
||||
import se.hal.plugin.tellstick.TellstickSerialComm;
|
||||
import se.hal.plugin.tellstick.protocol.NexaSelfLearningProtocol;
|
||||
import se.hal.struct.devicedata.SwitchEventData;
|
||||
import se.hal.struct.devicedata.TemperatureSensorData;
|
||||
import zutil.parser.binary.BinaryStruct;
|
||||
import zutil.ui.Configurator;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-02-18.
|
||||
*/
|
||||
public class NexaSelfLearning implements HalEventConfig,TellstickDevice,TellstickDeviceGroup {
|
||||
|
||||
@Configurator.Configurable("House code")
|
||||
private int house = 0;
|
||||
|
||||
@Configurator.Configurable("Group code")
|
||||
private boolean group = false;
|
||||
|
||||
@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;
|
||||
}
|
||||
public void setHouse(int house) {
|
||||
this.house = house;
|
||||
}
|
||||
public boolean getGroup() {
|
||||
return group;
|
||||
}
|
||||
public void setGroup(boolean group) {
|
||||
this.group = group;
|
||||
}
|
||||
public int getUnit() {
|
||||
return unit;
|
||||
}
|
||||
public void setUnit(int unit) {
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String toString(){
|
||||
return "house:"+house+
|
||||
", group:"+group+
|
||||
", unit:"+unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj){
|
||||
if(obj instanceof NexaSelfLearning)
|
||||
return ((NexaSelfLearning) obj).house == house &&
|
||||
((NexaSelfLearning) obj).group == group &&
|
||||
((NexaSelfLearning)obj).unit == unit;
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public boolean equalsGroup(TellstickDeviceGroup obj) {
|
||||
if(obj instanceof NexaSelfLearning)
|
||||
return ((NexaSelfLearning) obj).house == house &&
|
||||
(((NexaSelfLearning) obj).group || group );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<? extends HalEventController> getEventControllerClass() {
|
||||
return TellstickSerialComm.class;
|
||||
}
|
||||
@Override
|
||||
public Class<? extends HalEventData> getEventDataClass() {
|
||||
return SwitchEventData.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocolName() { return NexaSelfLearningProtocol.PROTOCOL; }
|
||||
@Override
|
||||
public String getModelName() { return NexaSelfLearningProtocol.MODEL; }
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Ziver
|
||||
*
|
||||
* 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.tellstick.device;
|
||||
|
||||
import se.hal.intf.HalEventConfig;
|
||||
import se.hal.intf.HalEventController;
|
||||
import se.hal.intf.HalEventData;
|
||||
import se.hal.plugin.tellstick.TellstickDevice;
|
||||
import se.hal.plugin.tellstick.TellstickDeviceGroup;
|
||||
import se.hal.plugin.tellstick.TellstickSerialComm;
|
||||
import se.hal.plugin.tellstick.protocol.NexaSelfLearningProtocol;
|
||||
import se.hal.struct.devicedata.DimmerEventData;
|
||||
import se.hal.struct.devicedata.SwitchEventData;
|
||||
import zutil.ui.Configurator;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-02-18.
|
||||
*/
|
||||
public class NexaSelfLearningDimmer implements HalEventConfig,TellstickDevice {
|
||||
|
||||
@Configurator.Configurable("House code")
|
||||
private int house = 0;
|
||||
|
||||
@Configurator.Configurable("Unit code")
|
||||
private int unit = 0;
|
||||
|
||||
|
||||
public NexaSelfLearningDimmer() { }
|
||||
public NexaSelfLearningDimmer(int house, int unit) {
|
||||
this.house = house;
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getHouse() {
|
||||
return house;
|
||||
}
|
||||
public void setHouse(int house) {
|
||||
this.house = house;
|
||||
}
|
||||
public int getUnit() {
|
||||
return unit;
|
||||
}
|
||||
public void setUnit(int unit) {
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String toString(){
|
||||
return "house:"+house+
|
||||
", unit:"+unit;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj){
|
||||
if(obj instanceof NexaSelfLearningDimmer)
|
||||
return ((NexaSelfLearningDimmer) obj).house == house &&
|
||||
((NexaSelfLearningDimmer)obj).unit == unit;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<? extends HalEventController> getEventControllerClass() {
|
||||
return TellstickSerialComm.class;
|
||||
}
|
||||
@Override
|
||||
public Class<? extends HalEventData> getEventDataClass() {
|
||||
return DimmerEventData.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocolName() { return NexaSelfLearningProtocol.PROTOCOL; }
|
||||
@Override
|
||||
public String getModelName() { return NexaSelfLearningProtocol.MODEL; }
|
||||
}
|
||||
101
plugins/tellstick/src/se/hal/plugin/tellstick/device/Oregon0x1A2D.java
Executable file
101
plugins/tellstick/src/se/hal/plugin/tellstick/device/Oregon0x1A2D.java
Executable file
|
|
@ -0,0 +1,101 @@
|
|||
package se.hal.plugin.tellstick.device;
|
||||
|
||||
import se.hal.intf.HalSensorConfig;
|
||||
import se.hal.intf.HalSensorController;
|
||||
import se.hal.intf.HalSensorData;
|
||||
import se.hal.plugin.tellstick.TellstickDevice;
|
||||
import se.hal.plugin.tellstick.TellstickSerialComm;
|
||||
import se.hal.plugin.tellstick.protocol.Oregon0x1A2DProtocol;
|
||||
import se.hal.struct.devicedata.HumiditySensorData;
|
||||
import se.hal.struct.devicedata.LightSensorData;
|
||||
import se.hal.struct.devicedata.PowerConsumptionSensorData;
|
||||
import se.hal.struct.devicedata.TemperatureSensorData;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.ui.Configurator;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-11-19.
|
||||
*/
|
||||
public class Oregon0x1A2D implements HalSensorConfig,TellstickDevice {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
public enum OregonSensorType{
|
||||
HUMIDITY,LIGHT,POWER,TEMPERATURE
|
||||
}
|
||||
|
||||
@Configurator.Configurable("Address")
|
||||
private int address = 0;
|
||||
@Configurator.Configurable("Report Interval(ms)")
|
||||
private int interval = 60*1000; // default 1 min
|
||||
@Configurator.Configurable("Sensor Type")
|
||||
private OregonSensorType sensorType;
|
||||
|
||||
|
||||
|
||||
public Oregon0x1A2D() { }
|
||||
public Oregon0x1A2D(int address, OregonSensorType sensorType) {
|
||||
this.address = address;
|
||||
this.sensorType = sensorType;
|
||||
}
|
||||
|
||||
|
||||
public int getAddress() {
|
||||
return address;
|
||||
}
|
||||
@Override
|
||||
public long getDataInterval() {
|
||||
return interval;
|
||||
}
|
||||
public OregonSensorType getSensorType() {
|
||||
return sensorType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj){
|
||||
if(! (obj instanceof Oregon0x1A2D))
|
||||
return false;
|
||||
return ((Oregon0x1A2D)obj).address == this.address &&
|
||||
((Oregon0x1A2D)obj).sensorType == this.sensorType;
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "address:"+address+",sensorType:"+ sensorType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AggregationMethod getAggregationMethod() {
|
||||
if (sensorType == OregonSensorType.POWER)
|
||||
return AggregationMethod.SUM;
|
||||
return AggregationMethod.AVERAGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends HalSensorController> getSensorControllerClass() {
|
||||
return TellstickSerialComm.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends HalSensorData> getSensorDataClass() {
|
||||
if (sensorType != null) {
|
||||
switch (sensorType) {
|
||||
case HUMIDITY:
|
||||
return HumiditySensorData.class;
|
||||
case LIGHT:
|
||||
return LightSensorData.class;
|
||||
case POWER:
|
||||
return PowerConsumptionSensorData.class;
|
||||
case TEMPERATURE:
|
||||
return TemperatureSensorData.class;
|
||||
}
|
||||
}
|
||||
return TemperatureSensorData.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtocolName() { return Oregon0x1A2DProtocol.PROTOCOL; }
|
||||
@Override
|
||||
public String getModelName() { return Oregon0x1A2DProtocol.MODEL; }
|
||||
}
|
||||
10
plugins/tellstick/src/se/hal/plugin/tellstick/plugin.json
Executable file
10
plugins/tellstick/src/se/hal/plugin/tellstick/plugin.json
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"version": 1.0,
|
||||
"name": "Tellstick",
|
||||
"interfaces": [
|
||||
{"se.hal.intf.HalAutoScannableController": "se.hal.plugin.tellstick.TellstickSerialComm"},
|
||||
|
||||
{"se.hal.intf.HalSensorConfig": "se.hal.plugin.tellstick.device.Oregon0x1A2D"},
|
||||
{"se.hal.intf.HalEventConfig": "se.hal.plugin.tellstick.device.NexaSelfLearning"}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Ziver
|
||||
*
|
||||
* 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.tellstick.protocol;
|
||||
|
||||
import se.hal.intf.HalEventConfig;
|
||||
import se.hal.intf.HalEventData;
|
||||
import se.hal.plugin.tellstick.TellstickSerialComm;
|
||||
import se.hal.plugin.tellstick.cmd.TellstickCmd;
|
||||
import se.hal.plugin.tellstick.cmd.TellstickCmdExtendedSend;
|
||||
import se.hal.plugin.tellstick.TellstickProtocol;
|
||||
import se.hal.plugin.tellstick.device.NexaSelfLearning;
|
||||
import se.hal.plugin.tellstick.device.NexaSelfLearningDimmer;
|
||||
import se.hal.struct.devicedata.DimmerEventData;
|
||||
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 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.
|
||||
* @see <a href="https://github.com/telldus/telldus/blob/master/telldus-core/service/ProtocolNexa.cpp">ProtocolNexa.cpp Tellstick Reference</a>
|
||||
*/
|
||||
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=10, length=26)
|
||||
int house = 0;
|
||||
|
||||
@BinaryField(index=20, length=1)
|
||||
boolean group = false;
|
||||
|
||||
@BinaryField(index = 30, length = 1)
|
||||
boolean enable = false;
|
||||
|
||||
@BinaryField(index=40, length=4)
|
||||
int unit = 0;
|
||||
}
|
||||
private static class NexaSLTransmissionDimmerStruct extends NexaSLTransmissionStruct {
|
||||
@BinaryField(index = 50, length = 4)
|
||||
int dimLevel = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public NexaSelfLearningProtocol() {
|
||||
super(PROTOCOL, MODEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TellstickCmd encode(HalEventConfig deviceConfig, HalEventData deviceData){
|
||||
if ( ! (deviceConfig instanceof NexaSelfLearning || deviceConfig instanceof NexaSelfLearningDimmer)){
|
||||
logger.severe("Device config is not instance of NexaSelfLearning: "+deviceConfig.getClass());
|
||||
return null;
|
||||
}
|
||||
if ( ! (deviceData instanceof SwitchEventData || deviceData instanceof DimmerEventData)){
|
||||
logger.severe("Device data is not an instance of SwitchEventData or DimmerEventData: "+deviceData.getClass());
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create transmission struct
|
||||
NexaSLTransmissionStruct struct;
|
||||
if (deviceData instanceof DimmerEventData) {
|
||||
struct = new NexaSLTransmissionDimmerStruct();
|
||||
struct.house = ((NexaSelfLearningDimmer) deviceConfig).getHouse();
|
||||
struct.unit = ((NexaSelfLearningDimmer) deviceConfig).getUnit();
|
||||
((NexaSLTransmissionDimmerStruct)struct).dimLevel = (int)(deviceData.getData()*16);
|
||||
}
|
||||
else {
|
||||
struct = new NexaSLTransmissionStruct();
|
||||
struct.house = ((NexaSelfLearning) deviceConfig).getHouse();
|
||||
struct.group = ((NexaSelfLearning) deviceConfig).getGroup();
|
||||
struct.unit = ((NexaSelfLearning) deviceConfig).getUnit();
|
||||
struct.enable = ((SwitchEventData) deviceData).isOn();
|
||||
}
|
||||
|
||||
|
||||
// Generate transmission string
|
||||
try {
|
||||
TellstickCmdExtendedSend cmd = new TellstickCmdExtendedSend();
|
||||
cmd.setPulls0Timing(1270);
|
||||
cmd.setPulls1Timing(2550);
|
||||
cmd.setPulls2Timing(240);
|
||||
|
||||
cmd.addPulls2().addPulls1(); // preamble
|
||||
byte[] data = BinaryStructOutputStream.serialize(struct);
|
||||
for (byte b : data){
|
||||
for (int i=7; i>=0; --i){
|
||||
if (ByteUtil.getBits(b, i, 1) == 0) // 0
|
||||
cmd.addPulls2().addPulls2().addPulls2().addPulls0(); // 0b1010_1000
|
||||
else // 1
|
||||
cmd.addPulls2().addPulls0().addPulls2().addPulls2(); // 0b1000_1010
|
||||
}
|
||||
}
|
||||
cmd.addPulls2().addPulls2(); // postemble?
|
||||
return cmd;
|
||||
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TellstickDecodedEntry> decode(byte[] data){
|
||||
// Data positions
|
||||
// house = 0xFFFFFFC0
|
||||
// group = 0x00000020
|
||||
// method = 0x00000010
|
||||
// unit = 0x0000000F
|
||||
// ----------------h------------ g m --u-
|
||||
// 0x2CE81990 - 00101100_11101000_00011001_10 0 1 0000 - ON
|
||||
// 0x2CE81980 - 00101100_11101000_00011001_10 0 0 0000 - OFF
|
||||
|
||||
NexaSLTransmissionStruct struct = new NexaSLTransmissionStruct();
|
||||
BinaryStructInputStream.read(struct, data);
|
||||
|
||||
ArrayList<TellstickDecodedEntry> list = new ArrayList<>();
|
||||
/* for (NexaSelfLearningDimmer device : TellstickSerialComm.getInstance().getRegisteredDevices(NexaSelfLearningDimmer.class)) {
|
||||
if (device.getHouse() == struct.house && device.getUnit() == struct.unit){
|
||||
NexaSLTransmissionDimmerStruct dimmerStruct = new NexaSLTransmissionDimmerStruct();
|
||||
BinaryStructInputStream.read(dimmerStruct, data);
|
||||
|
||||
list.add(new TellstickDecodedEntry(
|
||||
new NexaSelfLearningDimmer(dimmerStruct.house, dimmerStruct.unit),
|
||||
new DimmerEventData(dimmerStruct.dimLevel)
|
||||
));
|
||||
}
|
||||
}
|
||||
if (list.isEmpty()) { // No dimmer stored, we assume it is a switch event then...
|
||||
*/
|
||||
list.add(new TellstickDecodedEntry(
|
||||
new NexaSelfLearning(struct.house, struct.group, struct.unit),
|
||||
new SwitchEventData(struct.enable, System.currentTimeMillis())
|
||||
));
|
||||
/* }*/
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
121
plugins/tellstick/src/se/hal/plugin/tellstick/protocol/Oregon0x1A2DProtocol.java
Executable file
121
plugins/tellstick/src/se/hal/plugin/tellstick/protocol/Oregon0x1A2DProtocol.java
Executable file
|
|
@ -0,0 +1,121 @@
|
|||
package se.hal.plugin.tellstick.protocol;
|
||||
|
||||
import se.hal.intf.HalSensorData;
|
||||
import se.hal.plugin.tellstick.TellstickProtocol;
|
||||
import se.hal.plugin.tellstick.TellstickSerialComm;
|
||||
import se.hal.plugin.tellstick.device.Oregon0x1A2D;
|
||||
import se.hal.plugin.tellstick.device.Oregon0x1A2D.OregonSensorType;
|
||||
import se.hal.struct.devicedata.HumiditySensorData;
|
||||
import se.hal.struct.devicedata.LightSensorData;
|
||||
import se.hal.struct.devicedata.PowerConsumptionSensorData;
|
||||
import se.hal.struct.devicedata.TemperatureSensorData;
|
||||
import zutil.converter.Converter;
|
||||
import zutil.log.LogUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-11-19.
|
||||
* @see <a href="https://github.com/telldus/telldus/blob/master/telldus-core/service/ProtocolOregon.cpp">ProtocolOregon.cpp Tellstick Reference</a>
|
||||
*/
|
||||
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(PROTOCOL, MODEL);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<TellstickDecodedEntry> decode(byte[] data) {
|
||||
/*
|
||||
Nibble(s) Details
|
||||
0..3 Sensor ID This 16-bit value is unique to each sensor, or sometimes a group of sensors.
|
||||
4 Channel Some sensors use the coding 1 << (ch – 1), where ch is 1, 2 or 3.
|
||||
5..6 Rolling Code Value changes randomly every time the sensor is reset
|
||||
7 Flags 1 Bit value 0x4 is the battery low flag
|
||||
8..[n-5] Sensor-specific Data Usually in BCD format
|
||||
[n-3]..[n-4] Checksum The 8-bit sum of nibbles 0..[n-5]
|
||||
*/
|
||||
//Example: class:sensor;protocol:oregon;model:0x1A2D;data:20BA000000002700;
|
||||
|
||||
// int channel = (data[0] >> 4) & 0x7; // channel not used
|
||||
int address = data[1] & 0xFF;
|
||||
int temp3 = (data[2] >> 4) & 0xF;
|
||||
int temp1 = (data[3] >> 4) & 0xF;
|
||||
int temp2 = data[3] & 0xF;
|
||||
int hum2 = (data[4] >> 4) & 0xF;
|
||||
boolean negative = (data[4] & (1 << 3)) > 0;
|
||||
int hum1 = data[5] & 0xF;
|
||||
int checksum = data[6];
|
||||
|
||||
int calcChecksum = 0;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
calcChecksum += ((data[i] >> 4) & 0xF) + (data[i] & 0xF);
|
||||
}
|
||||
calcChecksum += 0x1 + 0xA + 0x2 + 0xD - 0xA;
|
||||
|
||||
if (calcChecksum != checksum) {
|
||||
logger.fine("Checksum failed, address: "+address+", data: "+ Converter.toHexString(data));
|
||||
return null;
|
||||
}
|
||||
|
||||
double temperature = ((temp1 * 100) + (temp2 * 10) + temp3)/10.0;
|
||||
if (negative)
|
||||
temperature = -temperature;
|
||||
double humidity = (hum1 * 10.0) + hum2;
|
||||
|
||||
|
||||
|
||||
// Create return objects
|
||||
long timestamp = System.currentTimeMillis();
|
||||
boolean humidityFound=false, temperatureFound=false;
|
||||
ArrayList<TellstickDecodedEntry> list = new ArrayList<>();
|
||||
for (Oregon0x1A2D device : TellstickSerialComm.getInstance().getRegisteredDevices(Oregon0x1A2D.class)) {
|
||||
if (device.getAddress() != address)
|
||||
continue;
|
||||
HalSensorData dataObj;
|
||||
OregonSensorType sensorType = device.getSensorType();
|
||||
if (sensorType == null)
|
||||
sensorType = OregonSensorType.POWER;
|
||||
switch (sensorType){
|
||||
case HUMIDITY:
|
||||
dataObj = new HumiditySensorData(humidity, timestamp);
|
||||
humidityFound = true;
|
||||
break;
|
||||
case LIGHT:
|
||||
dataObj = new LightSensorData(temperature, timestamp);
|
||||
temperatureFound = true;
|
||||
break;
|
||||
case TEMPERATURE:
|
||||
dataObj = new TemperatureSensorData(temperature, timestamp);
|
||||
temperatureFound = true;
|
||||
break;
|
||||
default:
|
||||
case POWER:
|
||||
dataObj = new PowerConsumptionSensorData(temperature, timestamp);
|
||||
temperatureFound = true;
|
||||
break;
|
||||
|
||||
}
|
||||
list.add(new TellstickDecodedEntry(device, dataObj));
|
||||
}
|
||||
// Add new sensors if we did not find a registered one
|
||||
if (!temperatureFound)
|
||||
list.add(new TellstickDecodedEntry(
|
||||
new Oregon0x1A2D(address, OregonSensorType.TEMPERATURE),
|
||||
new TemperatureSensorData(temperature, timestamp)));
|
||||
if (!humidityFound && humidity>0.0)
|
||||
list.add(new TellstickDecodedEntry(
|
||||
new Oregon0x1A2D(address, OregonSensorType.HUMIDITY),
|
||||
new HumiditySensorData(humidity, timestamp)));
|
||||
|
||||
return list;
|
||||
}
|
||||
}
|
||||
115
plugins/tellstick/test/se/hal/plugin/tellstick/TelstickSerialCommEventTest.java
Executable file
115
plugins/tellstick/test/se/hal/plugin/tellstick/TelstickSerialCommEventTest.java
Executable file
|
|
@ -0,0 +1,115 @@
|
|||
package se.hal.plugin.tellstick;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import se.hal.intf.*;
|
||||
import se.hal.struct.devicedata.DimmerEventData;
|
||||
import se.hal.struct.devicedata.SwitchEventData;
|
||||
import se.hal.struct.devicedata.TemperatureSensorData;
|
||||
import zutil.converter.Converter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-11-19.
|
||||
*/
|
||||
public class TelstickSerialCommEventTest {
|
||||
|
||||
@Before
|
||||
public void init(){
|
||||
TellstickParser.registerProtocol(TestEvent.class);
|
||||
}
|
||||
|
||||
|
||||
//############# Non crashing TC
|
||||
|
||||
@Test
|
||||
public void startup(){
|
||||
TellstickSerialComm tellstick = new TellstickSerialComm();
|
||||
tellstick.handleLine("+V2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unregisteredListener(){
|
||||
TellstickSerialComm tellstick = new TellstickSerialComm();
|
||||
tellstick.handleLine("+Wclass:sensor;protocol:test-prot;model:test-model;data:1234;");
|
||||
}
|
||||
|
||||
|
||||
//############ Normal TCs
|
||||
|
||||
@Test
|
||||
public void receiveUnregisteredEvent(){
|
||||
// Setup
|
||||
TellstickSerialComm tellstick = new TellstickSerialComm();
|
||||
final ArrayList<HalEventConfig> list = new ArrayList<>();
|
||||
tellstick.setListener(new HalEventReportListener() {
|
||||
@Override
|
||||
public void reportReceived(HalEventConfig e, HalEventData d) {
|
||||
list.add(e);
|
||||
}
|
||||
});
|
||||
// Execution
|
||||
tellstick.handleLine("+Wclass:sensor;protocol:test-prot;model:test-model;data:2345;");
|
||||
assertEquals("Events first transmission", 0, list.size());
|
||||
tellstick.handleLine("+Wclass:sensor;protocol:test-prot;model:test-model;data:2345;");
|
||||
assertEquals("Events Second transmission", 1, list.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receiveEvent(){
|
||||
// Setup
|
||||
TellstickSerialComm tellstick = new TellstickSerialComm();
|
||||
final ArrayList<HalEventConfig> list = new ArrayList<>();
|
||||
tellstick.setListener(new HalEventReportListener() {
|
||||
@Override
|
||||
public void reportReceived(HalEventConfig e, HalEventData d) {
|
||||
list.add(e);
|
||||
}
|
||||
});
|
||||
// Execution
|
||||
TestEvent event = new TestEvent();
|
||||
event.testData = 0xAAAA;
|
||||
tellstick.register(event);
|
||||
tellstick.handleLine("+Wclass:sensor;protocol:test-prot;model:test-model;data:AAAA;");
|
||||
// Verification
|
||||
assertEquals("Nr of received events", 1, list.size());
|
||||
assertEquals("Data", event.testData, ((TestEvent)list.get(0)).testData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static class TestEvent extends TellstickProtocol implements HalEventConfig,TellstickDevice {
|
||||
public int testData;
|
||||
|
||||
public TestEvent(){
|
||||
super("test-prot", "test-model");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TellstickDecodedEntry> decode(byte[] data) {
|
||||
testData = Converter.toInt(data);
|
||||
|
||||
ArrayList<TellstickDecodedEntry> list = new ArrayList<>();
|
||||
list.add(new TellstickDecodedEntry(
|
||||
this, new DimmerEventData(testData, System.currentTimeMillis())
|
||||
));
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<? extends HalEventController> getEventControllerClass() { return null; }
|
||||
@Override
|
||||
public Class<? extends HalEventData> getEventDataClass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {return testData == ((TestEvent)obj).testData;}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package se.hal.plugin.tellstick;
|
||||
|
||||
import se.hal.plugin.tellstick.device.NexaSelfLearning;
|
||||
import se.hal.plugin.tellstick.protocol.NexaSelfLearningProtocol;
|
||||
import se.hal.struct.devicedata.SwitchEventData;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-11-19.
|
||||
*/
|
||||
public class TelstickSerialCommNexaOnOffTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
System.out.println("Connecting to db...");
|
||||
TellstickSerialComm comm = new TellstickSerialComm();
|
||||
// http://developer.telldus.com/doxygen/TellStick.html
|
||||
comm.initialize("COM8");
|
||||
//comm.connect("/dev/ttyUSB1");
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
||||
NexaSelfLearning nexaDevice = new NexaSelfLearning();
|
||||
//nexa.setHouse(11772006);
|
||||
nexaDevice.setHouse(14160770);
|
||||
nexaDevice.setGroup(false);
|
||||
nexaDevice.setUnit(1);
|
||||
|
||||
SwitchEventData nexaData = new SwitchEventData();
|
||||
|
||||
System.out.println("Up and Running");
|
||||
while(true) {
|
||||
Thread.sleep(2000);
|
||||
nexaData.turnOn();
|
||||
nexaDevice.setUnit(0);
|
||||
comm.send(nexaDevice, nexaData);
|
||||
Thread.sleep(2000);
|
||||
nexaDevice.setUnit(1);
|
||||
comm.send(nexaDevice, nexaData);
|
||||
Thread.sleep(2000);
|
||||
|
||||
|
||||
nexaData.turnOff();
|
||||
nexaDevice.setUnit(0);
|
||||
comm.send(nexaDevice, nexaData);
|
||||
Thread.sleep(2000);
|
||||
nexaDevice.setUnit(1);
|
||||
comm.send(nexaDevice, nexaData);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
104
plugins/tellstick/test/se/hal/plugin/tellstick/TelstickSerialCommSensorTest.java
Executable file
104
plugins/tellstick/test/se/hal/plugin/tellstick/TelstickSerialCommSensorTest.java
Executable file
|
|
@ -0,0 +1,104 @@
|
|||
package se.hal.plugin.tellstick;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import se.hal.intf.*;
|
||||
import se.hal.struct.devicedata.SwitchEventData;
|
||||
import se.hal.struct.devicedata.TemperatureSensorData;
|
||||
import zutil.converter.Converter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-11-19.
|
||||
*/
|
||||
public class TelstickSerialCommSensorTest {
|
||||
|
||||
@Before
|
||||
public void init(){
|
||||
TellstickParser.registerProtocol(TestSensor.class);
|
||||
}
|
||||
|
||||
|
||||
//############ Normal TCs
|
||||
|
||||
@Test
|
||||
public void receiveUnregisteredSensor(){
|
||||
// Setup
|
||||
TellstickSerialComm tellstick = new TellstickSerialComm();
|
||||
final ArrayList<HalSensorConfig> list = new ArrayList<>();
|
||||
tellstick.setListener(new HalSensorReportListener() {
|
||||
@Override
|
||||
public void reportReceived(HalSensorConfig e, HalSensorData d) {
|
||||
list.add(e);
|
||||
}
|
||||
});
|
||||
// Execution
|
||||
tellstick.handleLine("+Wclass:sensor;protocol:test-prot;model:test-model;data:2345;");
|
||||
assertEquals("Sensors first transmission", 0, list.size());
|
||||
tellstick.handleLine("+Wclass:sensor;protocol:test-prot;model:test-model;data:2345;");
|
||||
assertEquals("Sensors Second transmission", 1, list.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receiveSensor(){
|
||||
// Setup
|
||||
TellstickSerialComm tellstick = new TellstickSerialComm();
|
||||
final ArrayList<HalSensorConfig> list = new ArrayList<>();
|
||||
tellstick.setListener(new HalSensorReportListener() {
|
||||
@Override
|
||||
public void reportReceived(HalSensorConfig e, HalSensorData d) {
|
||||
list.add(e);
|
||||
}
|
||||
});
|
||||
// Execution
|
||||
TestSensor sensor = new TestSensor();
|
||||
sensor.testData = 0xAAAA;
|
||||
tellstick.register(sensor);
|
||||
tellstick.handleLine("+Wclass:sensor;protocol:test-prot;model:test-model;data:AAAA;");
|
||||
// Verification
|
||||
assertEquals("Nr of received sensors", 1, list.size());
|
||||
assertEquals("Data", sensor.testData, ((TestSensor)list.get(0)).testData);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static class TestSensor extends TellstickProtocol implements HalSensorConfig,TellstickDevice {
|
||||
public int testData;
|
||||
|
||||
public TestSensor(){
|
||||
super("test-prot", "test-model");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TellstickDecodedEntry> decode(byte[] data) {
|
||||
testData = Converter.toInt(data);
|
||||
|
||||
ArrayList<TellstickDecodedEntry> list = new ArrayList<>();
|
||||
list.add(new TellstickDecodedEntry(
|
||||
this, new TemperatureSensorData(testData, 0)
|
||||
));
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {return testData == ((TestSensor)obj).testData;}
|
||||
|
||||
|
||||
@Override
|
||||
public long getDataInterval() { return 0; }
|
||||
@Override
|
||||
public AggregationMethod getAggregationMethod() { return null; }
|
||||
@Override
|
||||
public Class<? extends HalSensorController> getSensorControllerClass() { return null; }
|
||||
@Override
|
||||
public Class<? extends HalSensorData> getSensorDataClass() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (c) 2015 Ziver
|
||||
*
|
||||
* 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.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.plugin.tellstick.device.NexaSelfLearningDimmer;
|
||||
import se.hal.struct.devicedata.DimmerEventData;
|
||||
import se.hal.struct.devicedata.SwitchEventData;
|
||||
import zutil.converter.Converter;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class NexaSelfLearningTest {
|
||||
|
||||
@org.junit.Test
|
||||
public void testSwitchEncode() throws Exception {
|
||||
NexaSelfLearning nexaDevice = new NexaSelfLearning();
|
||||
nexaDevice.setHouse(11_772_006);
|
||||
nexaDevice.setUnit(3);
|
||||
SwitchEventData nexaData = new SwitchEventData(true, System.currentTimeMillis());
|
||||
|
||||
byte[] expected = Converter.toBytes(new char[]{
|
||||
84, // T
|
||||
127, 255, 24, 0, // timings
|
||||
132, // length
|
||||
|
||||
154, 138, 136, 170, 136, 168, 170, 138, 136, 168,
|
||||
168, 170, 136, 170, 138, 138, 138, 138, 138, 136,
|
||||
168, 170, 138, 136, 168, 170, 138, 136, 170, 138,
|
||||
136, 168, 170,
|
||||
|
||||
43}); // +
|
||||
NexaSelfLearningProtocol nexaProt = new NexaSelfLearningProtocol();
|
||||
byte[] actual = nexaProt.encode(nexaDevice, nexaData).getTransmissionString()
|
||||
.getBytes(StandardCharsets.ISO_8859_1);
|
||||
|
||||
System.out.println("Expected: "+Converter.toHexString(expected).toUpperCase());
|
||||
System.out.println("Actual : "+Converter.toHexString(actual).toUpperCase());
|
||||
assertArrayEquals(expected, actual);
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void testDimmerEncode() throws Exception {
|
||||
NexaSelfLearningDimmer nexaDevice = new NexaSelfLearningDimmer();
|
||||
nexaDevice.setHouse(11_772_006);
|
||||
nexaDevice.setUnit(3);
|
||||
DimmerEventData nexaData = new DimmerEventData(0.5, System.currentTimeMillis());
|
||||
|
||||
byte[] expected = Converter.toBytes(new char[]{
|
||||
84, // T
|
||||
127, 255, 24, 0, // timings
|
||||
164, // length, 32 extra timings
|
||||
|
||||
154, 138, 136, 170, 136, 168, 170, 138, 136, 168,
|
||||
168, 170, 136, 170, 138, 138, 138, 138, 138, 136,
|
||||
168, 170, 138, 136, 168, 170, 138,
|
||||
138, 138, 138, 136, 168,
|
||||
168, 170, 138, 138, 138, 138, 138, 138, 138, // Dimer value
|
||||
|
||||
43}); // +
|
||||
NexaSelfLearningProtocol nexaProt = new NexaSelfLearningProtocol();
|
||||
byte[] actual = nexaProt.encode(nexaDevice, nexaData).getTransmissionString()
|
||||
.getBytes(StandardCharsets.ISO_8859_1);
|
||||
|
||||
System.out.println("Expected: "+Converter.toHexString(expected).toUpperCase());
|
||||
System.out.println("Actual : "+Converter.toHexString(actual).toUpperCase());
|
||||
assertArrayEquals(expected, actual);
|
||||
}
|
||||
|
||||
|
||||
@org.junit.Test
|
||||
public void decode_ON() throws Exception {
|
||||
TellstickDecodedEntry nexa = decode("0x2CE81990");
|
||||
|
||||
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 {
|
||||
TellstickDecodedEntry nexa = decode("0x2CE81980");
|
||||
|
||||
assertEquals("House Code", 11772006, ((NexaSelfLearning)nexa.getDevice()).getHouse());
|
||||
assertEquals("Unit Code", 0, ((NexaSelfLearning)nexa.getDevice()).getUnit());
|
||||
assertFalse("Enabled", ((SwitchEventData)nexa.getData()).isOn());
|
||||
}
|
||||
|
||||
private TellstickDecodedEntry decode(String data){
|
||||
NexaSelfLearningProtocol nexaProt = new NexaSelfLearningProtocol();
|
||||
List<TellstickDecodedEntry> list = nexaProt.decode(Converter.hexToByte(data));
|
||||
return list.get(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,10 @@
|
|||
</fileset>
|
||||
</path>
|
||||
|
||||
<!-- ________________________ EXECUTION TARGETS ________________________ -->
|
||||
|
||||
<target name="test" />
|
||||
|
||||
<!-- ________________________ BUILD TARGETS ________________________ -->
|
||||
|
||||
<!--clean all build paths-->
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue