Added Junit test for Tellstick Controller and reverted equals(Hal...) as it was causing unforeseen issues.
This commit is contained in:
parent
2c1ccb8b57
commit
21ab281ec6
10 changed files with 155 additions and 86 deletions
|
|
@ -15,6 +15,6 @@ public interface HalEventData {
|
|||
* This method needs to be implemented.
|
||||
* NOTE: it should not compare data and timestamp, only static or unique data for the event type.
|
||||
*/
|
||||
boolean equals(HalEventData obj);
|
||||
boolean equals(Object obj);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,5 +35,5 @@ public interface HalSensorData {
|
|||
* NOTE: it should only static or unique data for the sensor type.
|
||||
* This method is used to associate reported data with registered sensors
|
||||
*/
|
||||
boolean equals(HalSensorData obj);
|
||||
boolean equals(Object obj);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public class NutUpsDevice implements PowerConsumptionSensorData{
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(HalSensorData obj){
|
||||
public boolean equals(Object obj){
|
||||
if (obj instanceof NutUpsDevice)
|
||||
return deviceId != null && deviceId.equals(((NutUpsDevice)obj).deviceId);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public class RPiPowerConsumptionSensor implements PowerConsumptionSensorData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(HalSensorData obj){
|
||||
public boolean equals(Object obj){
|
||||
if(!(obj instanceof RPiPowerConsumptionSensor))
|
||||
return false;
|
||||
return ((RPiPowerConsumptionSensor)obj).gpioPin == gpioPin;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class RPiTemperatureSensor implements TemperatureSensorData {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(HalSensorData obj){
|
||||
public boolean equals(Object obj){
|
||||
if(obj instanceof RPiTemperatureSensor)
|
||||
return obj == this;
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ 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();
|
||||
|
|
@ -43,6 +45,9 @@ public class TellstickParser {
|
|||
registerProtocol(Oregon0x1A2D.class);
|
||||
}
|
||||
|
||||
private int firmwareVersion = -1;
|
||||
|
||||
|
||||
|
||||
public TellstickProtocol decode(String data) {
|
||||
if (data.startsWith("+W")) {
|
||||
|
|
@ -72,6 +77,12 @@ public class TellstickParser {
|
|||
}
|
||||
} 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);
|
||||
}
|
||||
|
|
@ -79,12 +90,24 @@ public class TellstickParser {
|
|||
return null;
|
||||
}
|
||||
|
||||
public 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 {
|
||||
if (protocolMap == null)
|
||||
protocolMap = new HashMap<String, Class<? extends TellstickProtocol>>();
|
||||
protocolMap = new HashMap<>();
|
||||
TellstickProtocol tmp = protClass.newInstance();
|
||||
protocolMap.put(
|
||||
tmp.getProtocolName() + "-" + tmp.getModelName(),
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public class TellstickSerialComm implements Runnable,
|
|||
private OutputStream out;
|
||||
private TimedHashSet set; // To check for duplicate transmissions
|
||||
|
||||
private TellstickParser parser;
|
||||
protected TellstickParser parser;
|
||||
private HalSensorReportListener sensorListener;
|
||||
private HalEventReportListener eventListener;
|
||||
|
||||
|
|
@ -115,43 +115,8 @@ public class TellstickSerialComm implements Runnable,
|
|||
public void run() {
|
||||
try {
|
||||
String data;
|
||||
|
||||
while (in != null && (data = readLine()) != null) {
|
||||
if ((data.startsWith("+S") || data.startsWith("+T"))) {
|
||||
synchronized (this) {
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
else {
|
||||
TellstickProtocol protocol = parser.decode(data);
|
||||
if(protocol != null) {
|
||||
if (protocol.getTimestamp() < 0)
|
||||
protocol.setTimestamp(System.currentTimeMillis());
|
||||
|
||||
boolean registered = registeredDevices.contains(protocol);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Report source event
|
||||
reportEvent(protocol);
|
||||
}
|
||||
set.add(data);
|
||||
}
|
||||
}
|
||||
handleLine(data);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
|
|
@ -165,7 +130,7 @@ public class TellstickSerialComm implements Runnable,
|
|||
}
|
||||
|
||||
/**
|
||||
* There seems to be an issue with read(...) methods only read() is working
|
||||
* There seems to be an issue with read(...) methods, only read() is working
|
||||
*/
|
||||
private String readLine() throws IOException {
|
||||
StringBuilder str = new StringBuilder(50);
|
||||
|
|
@ -183,6 +148,36 @@ 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());
|
||||
|
||||
boolean registered = registeredDevices.contains(protocol);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Report source event
|
||||
reportEvent(protocol);
|
||||
}
|
||||
set.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
|
|
@ -192,14 +187,10 @@ public class TellstickSerialComm implements Runnable,
|
|||
}
|
||||
public synchronized void write(TellstickProtocol prot) {
|
||||
write(prot.encode());
|
||||
try {
|
||||
this.wait();
|
||||
prot.setTimestamp(System.currentTimeMillis());
|
||||
} catch (InterruptedException e) {
|
||||
logger.log(Level.SEVERE, null, e);
|
||||
}
|
||||
parser.waitSendConformation();
|
||||
prot.setTimestamp(System.currentTimeMillis());
|
||||
}
|
||||
public void write(String data) {
|
||||
private void write(String data) {
|
||||
try {
|
||||
for(int i=0; i<data.length();i++)
|
||||
out.write(0xFF & data.charAt(i));
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ public class NexaSelfLearning extends TellstickProtocol
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(HalEventData obj){
|
||||
public boolean equals(Object obj){
|
||||
if(obj instanceof NexaSelfLearning)
|
||||
return ((NexaSelfLearning) obj).house == house &&
|
||||
((NexaSelfLearning) obj).group == group &&
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public class Oregon0x1A2D extends TellstickProtocol implements PowerConsumptionS
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(HalSensorData obj){
|
||||
public boolean equals(Object obj){
|
||||
if(! (obj instanceof Oregon0x1A2D))
|
||||
return false;
|
||||
return ((Oregon0x1A2D)obj).address == this.address;
|
||||
|
|
|
|||
|
|
@ -1,59 +1,114 @@
|
|||
package se.hal.plugin.tellstick;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import se.hal.HalContext;
|
||||
import se.hal.intf.HalEventData;
|
||||
import se.hal.intf.HalEventReportListener;
|
||||
import se.hal.intf.HalSensorData;
|
||||
import se.hal.intf.HalSensorReportListener;
|
||||
import se.hal.plugin.tellstick.protocols.Oregon0x1A2D;
|
||||
import zutil.converter.Converter;
|
||||
import zutil.db.DBConnection;
|
||||
import zutil.log.CompactLogFormatter;
|
||||
import zutil.log.LogUtil;
|
||||
import zutil.struct.MutableInt;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2015-11-19.
|
||||
*/
|
||||
public class TelstickSerialCommTest {
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
LogUtil.setGlobalFormatter(new CompactLogFormatter());
|
||||
LogUtil.setGlobalLevel(Level.FINEST);
|
||||
@Before
|
||||
public void init(){
|
||||
TellstickParser.registerProtocol(TestEvent.class);
|
||||
}
|
||||
|
||||
logger.info("Initializing HalContext...");
|
||||
HalContext.initialize();
|
||||
final DBConnection db = HalContext.getDB();
|
||||
|
||||
logger.info("Setting up Tellstick listeners...");
|
||||
TellstickSerialComm comm = new TellstickSerialComm();
|
||||
comm.setListener(new HalSensorReportListener() {
|
||||
@Override
|
||||
public void reportReceived(HalSensorData s) {
|
||||
if(s instanceof Oregon0x1A2D){
|
||||
logger.info("Power used: "+ ((Oregon0x1A2D)s).getTemperature() +" pulses");
|
||||
try {
|
||||
PreparedStatement stmt =
|
||||
db.getPreparedStatement("INSERT INTO sensor_data_raw (timestamp, event_id, data) VALUES(?, ?, ?)");
|
||||
stmt.setLong(1, s.getTimestamp());
|
||||
stmt.setLong(2, 1);
|
||||
stmt.setDouble(3, ((Oregon0x1A2D)s).getTemperature());
|
||||
db.exec(stmt);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
comm.initialize("COM5");
|
||||
//comm.connect("/dev/ttyUSB1");
|
||||
//############# Non crashing TC
|
||||
|
||||
logger.info("Up and Running");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
@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 unregisteredEvent(){
|
||||
// Setup
|
||||
TellstickSerialComm tellstick = new TellstickSerialComm();
|
||||
final ArrayList<HalEventData> list = new ArrayList<>();
|
||||
tellstick.setListener(new HalEventReportListener() {
|
||||
@Override
|
||||
public void reportReceived(HalEventData e) {
|
||||
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 event(){
|
||||
// Setup
|
||||
TellstickSerialComm tellstick = new TellstickSerialComm();
|
||||
final ArrayList<HalEventData> list = new ArrayList<>();
|
||||
tellstick.setListener(new HalEventReportListener() {
|
||||
@Override
|
||||
public void reportReceived(HalEventData e) {
|
||||
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 HalEventData{
|
||||
public int testData;
|
||||
|
||||
public TestEvent(){
|
||||
super("test-prot", "test-model");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] data) {
|
||||
testData = Converter.toInt(data);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String encode() {return null;}
|
||||
@Override
|
||||
public double getData() {return 0;}
|
||||
@Override
|
||||
public boolean equals(Object obj) {return testData == ((TestEvent)obj).testData;}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue