Some robustness fixes and:
- Fixed Nexa send command - Added UPS plugin for power consumption - Added Autostartable Controller interface
This commit is contained in:
parent
5f0800897c
commit
7109abeea2
17 changed files with 219 additions and 32 deletions
|
|
@ -2,4 +2,6 @@ http_port=8080
|
|||
sync_port=6666
|
||||
|
||||
# Plugin configurations
|
||||
tellstick.com_port=COM5
|
||||
#tellstick.com_port=COM5
|
||||
#nutups.host=
|
||||
#nutups.port=
|
||||
|
|
@ -28,7 +28,7 @@ public class ControllerManager implements HalSensorReportListener,
|
|||
private static ControllerManager instance;
|
||||
|
||||
|
||||
/** All available sensor plugins **/
|
||||
/** All isAvailable sensor plugins **/
|
||||
private List<Class<?>> availableSensors = new ArrayList<>();
|
||||
/** List of all registered sensors **/
|
||||
private List<Sensor> registeredSensors = new ArrayList<>();
|
||||
|
|
@ -38,7 +38,7 @@ public class ControllerManager implements HalSensorReportListener,
|
|||
private List<Sensor> limboSensors = new LinkedList<>();
|
||||
|
||||
|
||||
/** All available event plugins **/
|
||||
/** All isAvailable event plugins **/
|
||||
private List<Class<?>> availableEvents = new ArrayList<>();
|
||||
/** List of all registered events **/
|
||||
private List<Event> registeredEvents = new ArrayList<>();
|
||||
|
|
@ -61,7 +61,7 @@ public class ControllerManager implements HalSensorReportListener,
|
|||
return;
|
||||
}
|
||||
if(!availableSensors.contains(sensor.getDeviceData().getClass())) {
|
||||
logger.warning("Sensor data plugin not available: "+ sensor.getDeviceData().getClass());
|
||||
logger.warning("Sensor data plugin not isAvailable: "+ sensor.getDeviceData().getClass());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +146,7 @@ public class ControllerManager implements HalSensorReportListener,
|
|||
return;
|
||||
}
|
||||
if(!availableEvents.contains(event.getDeviceData().getClass())) {
|
||||
logger.warning("Sensor data plugin not available: "+ event.getDeviceData().getClass());
|
||||
logger.warning("Sensor data plugin not isAvailable: "+ event.getDeviceData().getClass());
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -234,6 +234,11 @@ public class ControllerManager implements HalSensorReportListener,
|
|||
}
|
||||
|
||||
/////////////////////////////// GENERAL ///////////////////////////////////
|
||||
public void initializeScannableControllers(){
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void preConfigurationAction(Configurator configurator, Object obj) {
|
||||
if(obj instanceof HalSensorData) {
|
||||
|
|
@ -276,9 +281,15 @@ public class ControllerManager implements HalSensorReportListener,
|
|||
controller = controllerMap.get(c);
|
||||
else {
|
||||
// Instantiate controller
|
||||
logger.info("Instantiating new controller: " + c.getName());
|
||||
try {
|
||||
controller = c.newInstance();
|
||||
if (controller instanceof HalAutoScannableController &&
|
||||
! ((HalAutoScannableController)controller).isAvailable()) {
|
||||
logger.warning("Controller not available: "+c.getName());
|
||||
return null;
|
||||
}
|
||||
logger.info("Instantiating new controller: " + c.getName());
|
||||
|
||||
if(controller instanceof HalSensorController) {
|
||||
((HalSensorController) controller).setListener(this);
|
||||
((HalSensorController) controller).initialize();
|
||||
|
|
@ -292,13 +303,16 @@ public class ControllerManager implements HalSensorReportListener,
|
|||
controllerMap.put(c, controller);
|
||||
} catch (Exception e){
|
||||
logger.log(Level.SEVERE, "Unable to instantiate controller: "+c.getName(), e);
|
||||
controller = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return (T)controller;
|
||||
}
|
||||
|
||||
private void removeControllerIfEmpty(Object controller){
|
||||
if (controller instanceof HalAutoScannableController)
|
||||
return; // Don't do anything if controller is scannable
|
||||
|
||||
int size = Integer.MAX_VALUE;
|
||||
if(controller instanceof HalSensorController)
|
||||
size = ((HalSensorController) controller).size();
|
||||
|
|
@ -335,6 +349,11 @@ public class ControllerManager implements HalSensorReportListener,
|
|||
while (pluginIt.hasNext()){
|
||||
manager.availableEvents.add(pluginIt.next());
|
||||
}
|
||||
|
||||
pluginIt = plugin.getClassIterator(HalAutoScannableController.class);
|
||||
while (pluginIt.hasNext()){
|
||||
manager.getControllerInstance(pluginIt.next()); // Instantiate controller
|
||||
}
|
||||
}
|
||||
instance = manager;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@ public class HalContext {
|
|||
}
|
||||
else logger.info("No hal.conf file found");
|
||||
|
||||
if (FileUtil.find(DEFAULT_DB_FILE) == null){
|
||||
logger.severe("Unable to find default DB: "+DEFAULT_DB_FILE);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// Init DB
|
||||
File dbFile = FileUtil.find(DB_FILE);
|
||||
db = new DBConnection(DBConnection.DBMS.SQLite, DB_FILE);
|
||||
|
|
|
|||
|
|
@ -31,14 +31,6 @@ public class HalServer {
|
|||
public static void main(String[] args) throws Exception {
|
||||
// init logging
|
||||
LogUtil.readConfiguration("logging.properties");
|
||||
/*CompactLogFormatter formatter = new CompactLogFormatter();
|
||||
LogUtil.setLevel("se.hal", Level.FINEST);
|
||||
LogUtil.setFormatter("se.hal", formatter);
|
||||
LogUtil.setLevel("zutil.db.bean", Level.INFO);
|
||||
LogUtil.setLevel("zutil.net.http.pages", Level.INFO);
|
||||
LogUtil.setLevel("zutil", Level.FINEST);
|
||||
LogUtil.setFormatter("zutil", formatter);
|
||||
LogUtil.setGlobalFormatter(formatter);*/
|
||||
|
||||
// init Managers
|
||||
HalContext.initialize();
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ public class PCDataSynchronizationClient implements HalDaemon {
|
|||
/////////////// DTO ///////////////////////
|
||||
|
||||
/**
|
||||
* Request Peer information and available sensors
|
||||
* Request Peer information and isAvailable sensors
|
||||
*/
|
||||
protected static class PeerDataReqDTO implements Serializable{}
|
||||
|
||||
|
|
|
|||
13
src/se/hal/intf/HalAutoScannableController.java
Executable file
13
src/se/hal/intf/HalAutoScannableController.java
Executable file
|
|
@ -0,0 +1,13 @@
|
|||
package se.hal.intf;
|
||||
|
||||
/**
|
||||
* Created by ezivkoc on 2016-05-25.
|
||||
*/
|
||||
public interface HalAutoScannableController {
|
||||
|
||||
/**
|
||||
* Indicates if the controller has all the configuration
|
||||
* data and resources to be able to initialize
|
||||
*/
|
||||
public boolean isAvailable();
|
||||
}
|
||||
|
|
@ -5,6 +5,11 @@ package se.hal.intf;
|
|||
*/
|
||||
public interface HalEventController {
|
||||
|
||||
/**
|
||||
* The framework might create dummy objects so any type of
|
||||
* resource initialization should be handled in this method
|
||||
* and not in the constructor.
|
||||
*/
|
||||
void initialize() throws Exception;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@ package se.hal.intf;
|
|||
*/
|
||||
public interface HalSensorController {
|
||||
|
||||
/**
|
||||
* The framework might create dummy objects so any type of
|
||||
* resource initialization should be handled in this method
|
||||
* and not in the constructor.
|
||||
*/
|
||||
void initialize() throws Exception;
|
||||
|
||||
/**
|
||||
|
|
|
|||
79
src/se/hal/plugin/nutups/NutUpsController.java
Executable file
79
src/se/hal/plugin/nutups/NutUpsController.java
Executable file
|
|
@ -0,0 +1,79 @@
|
|||
package se.hal.plugin.nutups;
|
||||
|
||||
import se.hal.HalContext;
|
||||
import se.hal.intf.HalAutoScannableController;
|
||||
import se.hal.intf.HalSensorController;
|
||||
import se.hal.intf.HalSensorData;
|
||||
import se.hal.intf.HalSensorReportListener;
|
||||
import zutil.osal.app.linux.NutUPSClient;
|
||||
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2016-05-25.
|
||||
*/
|
||||
public class NutUpsController implements HalSensorController, HalAutoScannableController, Runnable{
|
||||
private static final int SYNC_INTERVAL = 60 * 1000;
|
||||
|
||||
private NutUPSClient client;
|
||||
private ScheduledExecutorService executor;
|
||||
private HalSensorReportListener listener;
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return HalContext.getStringProperty("nutups.host") != null;
|
||||
}
|
||||
@Override
|
||||
public void initialize() throws Exception {
|
||||
if (client == null) {
|
||||
int port = NutUPSClient.DEFAULT_PORT;
|
||||
if (HalContext.getStringProperty("nutups.port") != null)
|
||||
port = Integer.parseInt(HalContext.getStringProperty("nutups.port"));
|
||||
client = new NutUPSClient(HalContext.getStringProperty("nutups.host"), port);
|
||||
|
||||
executor = Executors.newScheduledThreadPool(1);
|
||||
executor.scheduleAtFixedRate(this, 5000, SYNC_INTERVAL, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setListener(HalSensorReportListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if(client != null && listener != null){
|
||||
for (NutUPSClient.UPSDevice ups : client.getUPSList()){
|
||||
listener.reportReceived(new NutUpsDevice(ups));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
client = null;
|
||||
executor.shutdownNow();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void register(HalSensorData sensor) {
|
||||
|
||||
}
|
||||
@Override
|
||||
public void deregister(HalSensorData sensor) {
|
||||
|
||||
}
|
||||
@Override
|
||||
public int size() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
56
src/se/hal/plugin/nutups/NutUpsDevice.java
Executable file
56
src/se/hal/plugin/nutups/NutUpsDevice.java
Executable file
|
|
@ -0,0 +1,56 @@
|
|||
package se.hal.plugin.nutups;
|
||||
|
||||
import se.hal.intf.HalSensorController;
|
||||
import se.hal.intf.HalSensorData;
|
||||
import se.hal.struct.PowerConsumptionSensorData;
|
||||
import zutil.osal.app.linux.NutUPSClient;
|
||||
import zutil.ui.Configurator;
|
||||
|
||||
/**
|
||||
* Created by Ziver on 2016-05-25.
|
||||
*/
|
||||
public class NutUpsDevice implements PowerConsumptionSensorData{
|
||||
|
||||
@Configurator.Configurable("UPS id")
|
||||
private String deviceId;
|
||||
private long timestamp;
|
||||
private int consumption;
|
||||
|
||||
|
||||
public NutUpsDevice(){}
|
||||
|
||||
protected NutUpsDevice(NutUPSClient.UPSDevice ups){
|
||||
this.deviceId = ups.getId();
|
||||
this.timestamp = System.currentTimeMillis();
|
||||
this.consumption = ups.getPowerUsage();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getData() {
|
||||
return consumption;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj){
|
||||
if (obj instanceof NutUpsDevice)
|
||||
return deviceId != null && deviceId.equals(((NutUpsDevice)obj).deviceId);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public AggregationMethod getAggregationMethod() {
|
||||
return AggregationMethod.SUM;
|
||||
}
|
||||
@Override
|
||||
public Class<? extends HalSensorController> getSensorController() {
|
||||
return NutUpsController.class;
|
||||
}
|
||||
}
|
||||
8
src/se/hal/plugin/nutups/plugin.json
Executable file
8
src/se/hal/plugin/nutups/plugin.json
Executable file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"version": 1.0,
|
||||
"name": "NutUps",
|
||||
"interfaces": [
|
||||
{"se.hal.intf.HalAutoScannableController": "se.hal.plugin.nutups.NutUpsController"},
|
||||
{"se.hal.intf.HalSensorData": "se.hal.plugin.nutups.NutUpsDevice"}
|
||||
]
|
||||
}
|
||||
|
|
@ -41,7 +41,8 @@ import java.util.logging.Logger;
|
|||
* This version of the TwoWaySerialComm example makes use of the
|
||||
* SerialPortEventListener to avoid polling.
|
||||
*/
|
||||
public class TellstickSerialComm implements Runnable, HalSensorController, HalEventController {
|
||||
public class TellstickSerialComm implements Runnable,
|
||||
HalSensorController, HalEventController, HalAutoScannableController {
|
||||
private static final long TRANSMISSION_UNIQUENESS_TTL = 1000; // milliseconds
|
||||
private static final Logger logger = LogUtil.getLogger();
|
||||
|
||||
|
|
@ -64,6 +65,10 @@ public class TellstickSerialComm implements Runnable, HalSensorController, HalEv
|
|||
registeredDevices = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return HalContext.getStringProperty("tellstick.com_port") != null;
|
||||
}
|
||||
@Override
|
||||
public void initialize() throws Exception {
|
||||
// Read properties
|
||||
|
|
@ -71,10 +76,10 @@ public class TellstickSerialComm implements Runnable, HalSensorController, HalEv
|
|||
if (port == null)
|
||||
port = "COM1"; // defaults
|
||||
|
||||
connect(port);
|
||||
initialize(port);
|
||||
}
|
||||
|
||||
public void connect(String portName) throws Exception {
|
||||
public void initialize(String portName) throws Exception {
|
||||
logger.info("Connecting to com port... ("+ portName +")");
|
||||
serial = SerialPort.getCommPort(portName);
|
||||
serial.setBaudRate(9600);
|
||||
|
|
@ -85,9 +90,6 @@ public class TellstickSerialComm implements Runnable, HalSensorController, HalEv
|
|||
|
||||
in = serial.getInputStream();
|
||||
out = serial.getOutputStream();
|
||||
//in = new InputStreamLogger(serial.getInputStream());
|
||||
//out = new OutputStreamLogger(serial.getOutputStream());
|
||||
|
||||
|
||||
Executors.newSingleThreadExecutor().execute(this);
|
||||
}
|
||||
|
|
@ -241,4 +243,5 @@ public class TellstickSerialComm implements Runnable, HalSensorController, HalEv
|
|||
public void setListener(HalSensorReportListener listener) {
|
||||
sensorListener = listener;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
"version": 1.0,
|
||||
"name": "Tellstick",
|
||||
"interfaces": [
|
||||
{"se.hal.intf.HalAutoScannableController": "se.hal.plugin.tellstick.TellstickSerialComm"},
|
||||
|
||||
{"se.hal.intf.HalSensorData": "se.hal.plugin.tellstick.protocols.Oregon0x1A2D"},
|
||||
{"se.hal.intf.HalEventData": "se.hal.plugin.tellstick.protocols.NexaSelfLearning"}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public class NexaSelfLearning extends TellstickProtocol
|
|||
enc.append(new char[]{'T', 127, 255, 24, 0});
|
||||
enc.append((char)0); // length
|
||||
|
||||
enc.append((char)0b1111_1001); // preamble
|
||||
enc.append((char)0b0000_1001); // preamble
|
||||
int length = 4;
|
||||
byte[] data = BinaryStructOutputStream.serialize(this);
|
||||
for (byte b : data){
|
||||
|
|
@ -80,6 +80,8 @@ public class NexaSelfLearning extends TellstickProtocol
|
|||
length += 4;
|
||||
}
|
||||
}
|
||||
enc.append((char)0b0000_0000); // postemble
|
||||
length += 2;
|
||||
enc.setCharAt(5, (char)length); // Set calculated length
|
||||
|
||||
enc.append("+");
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ public class TelstickSerialCommNexaOnOffTest {
|
|||
System.out.println("Connecting to db...");
|
||||
TellstickSerialComm comm = new TellstickSerialComm();
|
||||
// http://developer.telldus.com/doxygen/TellStick.html
|
||||
comm.connect("COM5");
|
||||
comm.initialize("COM8");
|
||||
//comm.connect("/dev/ttyUSB1");
|
||||
|
||||
Thread.sleep(1000);
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class TelstickSerialCommTest {
|
|||
}
|
||||
}
|
||||
});
|
||||
comm.connect("COM5");
|
||||
comm.initialize("COM5");
|
||||
//comm.connect("/dev/ttyUSB1");
|
||||
|
||||
logger.info("Up and Running");
|
||||
|
|
|
|||
|
|
@ -41,18 +41,15 @@ public class NexaSelfLearningTest {
|
|||
byte[] expected = Converter.toBytes(new char[]{
|
||||
84, // T
|
||||
127, 255, 24, 0, // timings
|
||||
132, // length
|
||||
134, // length
|
||||
|
||||
0xF9, // preamble
|
||||
168, 168, 138, 168, 138, 138, 168, 168, 138, 138,
|
||||
138, 168, 138, 168, 168, 168, 168, 168, 168, 138,
|
||||
138, 168, 168, 138, 138, 168, 168, 138, 168, 168,
|
||||
168, 168,
|
||||
0x00, // postemble
|
||||
|
||||
/*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}); // +
|
||||
byte[] actual = nexa.encode().getBytes(StandardCharsets.ISO_8859_1);
|
||||
|
||||
|
|
@ -69,9 +66,8 @@ public class NexaSelfLearningTest {
|
|||
assertEquals("House Code", 11772006, nexa.getHouse());
|
||||
assertEquals("Unit Code", 0, nexa.getUnit());
|
||||
assertTrue("Enabled", nexa.isOn());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@org.junit.Test
|
||||
public void decode_OFF() throws Exception {
|
||||
NexaSelfLearning nexa = decode("0x2CE81980");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue