Added Junit test for Tellstick Controller and reverted equals(Hal...) as it was causing unforeseen issues.

This commit is contained in:
Ziver Koc 2016-08-15 17:36:46 +02:00
parent 2c1ccb8b57
commit 21ab281ec6
10 changed files with 155 additions and 86 deletions

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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(),

View file

@ -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,14 +115,40 @@ 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();
handleLine(data);
}
} catch (IOException e) {
logger.log(Level.SEVERE, null, e);
}
}
else {
private void reportEvent(TellstickProtocol protocol){
if (sensorListener != null && protocol instanceof HalSensorData)
sensorListener.reportReceived((HalSensorData) protocol);
else if (eventListener != null && protocol instanceof HalEventData)
eventListener.reportReceived((HalEventData) 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){
switch(c) {
case '\n':
case '\r':
if(str.length() > 0)
return str.toString();
break;
default:
str.append(c);
}
}
return str.toString();
}
protected void handleLine(String data){
TellstickProtocol protocol = parser.decode(data);
if(protocol != null) {
if (protocol.getTimestamp() < 0)
@ -152,37 +178,6 @@ public class TellstickSerialComm implements Runnable,
set.add(data);
}
}
}
} catch (IOException e) {
logger.log(Level.SEVERE, null, e);
}
}
private void reportEvent(TellstickProtocol protocol){
if (sensorListener != null && protocol instanceof HalSensorData)
sensorListener.reportReceived((HalSensorData) protocol);
else if (eventListener != null && protocol instanceof HalEventData)
eventListener.reportReceived((HalEventData) 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){
switch(c) {
case '\n':
case '\r':
if(str.length() > 0)
return str.toString();
break;
default:
str.append(c);
}
}
return str.toString();
}
@Override
@ -192,14 +187,10 @@ public class TellstickSerialComm implements Runnable,
}
public synchronized void write(TellstickProtocol prot) {
write(prot.encode());
try {
this.wait();
parser.waitSendConformation();
prot.setTimestamp(System.currentTimeMillis());
} catch (InterruptedException e) {
logger.log(Level.SEVERE, null, e);
}
}
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));

View file

@ -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 &&

View file

@ -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;

View file

@ -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() {
//############# 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 unregisteredEvent(){
// Setup
TellstickSerialComm tellstick = new TellstickSerialComm();
final ArrayList<HalEventData> list = new ArrayList<>();
tellstick.setListener(new HalEventReportListener() {
@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();
}
}
public void reportReceived(HalEventData e) {
list.add(e);
}
});
comm.initialize("COM5");
//comm.connect("/dev/ttyUSB1");
// 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());
}
logger.info("Up and Running");
} catch (Exception e) {
e.printStackTrace();
}
@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;}
}
}