Adjusting files in ZigbeeTest; preparing things for 4th benchmark, i.e. generating...
authorrtrimana <rtrimana@uci.edu>
Fri, 6 Jan 2017 01:08:30 +0000 (17:08 -0800)
committerrtrimana <rtrimana@uci.edu>
Fri, 6 Jan 2017 01:08:30 +0000 (17:08 -0800)
65 files changed:
benchmarks/HomeSecurityController/AlarmSmart_Stub.java [new file with mode: 0644]
benchmarks/HomeSecurityController/CameraCallback_CallbackSkeleton.java [new file with mode: 0644]
benchmarks/HomeSecurityController/CameraSmart_Stub.java [new file with mode: 0644]
benchmarks/HomeSecurityController/HomeSecurityController.config [new file with mode: 0644]
benchmarks/HomeSecurityController/HomeSecurityController.java [new file with mode: 0644]
benchmarks/HomeSecurityController/Makefile [new file with mode: 0644]
benchmarks/HomeSecurityController/MotionDetection.java [new file with mode: 0644]
benchmarks/HomeSecurityController/MotionDetectionCallback.java [new file with mode: 0644]
benchmarks/HomeSecurityController/RoomSmart_Stub.java [new file with mode: 0644]
benchmarks/HomeSecurityController/SmartthingsSensorCallback_CallbackSkeleton.java [new file with mode: 0644]
benchmarks/HomeSecurityController/SmartthingsSensorSmart_Stub.java [new file with mode: 0644]
benchmarks/IrrigationController/MotionDetection.java
benchmarks/IrrigationController/MotionDetectionCallback.java
benchmarks/Makefile
benchmarks/SmartLightsController/MotionDetection.java
benchmarks/SmartLightsController/MotionDetectionCallback.java
benchmarks/drivers/EspAlarm/Alarm_Skeleton.java [new file with mode: 0644]
benchmarks/drivers/EspAlarm/EspAlarm.config [new file with mode: 0644]
benchmarks/drivers/EspAlarm/EspAlarm.java [new file with mode: 0644]
benchmarks/drivers/HomeRoom/HomeRoom.config [new file with mode: 0644]
benchmarks/drivers/HomeRoom/HomeRoom.java [new file with mode: 0644]
benchmarks/drivers/HomeRoom/Room_Skeleton.java [new file with mode: 0644]
benchmarks/drivers/Makefile
benchmarks/drivers/MotionSensor/MotionSensor.config [new file with mode: 0644]
benchmarks/drivers/MotionSensor/MotionSensor.java [new file with mode: 0644]
benchmarks/drivers/MotionSensor/SmartthingsSensorSmartCallback_CallbackStub.java [new file with mode: 0644]
benchmarks/drivers/MotionSensor/SmartthingsSensor_Skeleton.java [new file with mode: 0644]
benchmarks/drivers/MultipurposeSensor/MultipurposeSensor.config [new file with mode: 0644]
benchmarks/drivers/MultipurposeSensor/MultipurposeSensor.java [new file with mode: 0644]
benchmarks/drivers/MultipurposeSensor/SmartthingsSensorSmartCallback_CallbackStub.java [new file with mode: 0644]
benchmarks/drivers/MultipurposeSensor/SmartthingsSensor_Skeleton.java [new file with mode: 0644]
benchmarks/drivers/WaterLeakSensor/SmartthingsSensorSmartCallback_CallbackStub.java [new file with mode: 0644]
benchmarks/drivers/WaterLeakSensor/SmartthingsSensor_Skeleton.java [new file with mode: 0644]
benchmarks/drivers/WaterLeakSensor/WaterLeakSensor.config [new file with mode: 0644]
benchmarks/drivers/WaterLeakSensor/WaterLeakSensor.java [new file with mode: 0644]
benchmarks/interfaces/Alarm.java [new file with mode: 0644]
benchmarks/interfaces/AlarmSmart.java [new file with mode: 0644]
benchmarks/interfaces/SmartthingsSensor.java [new file with mode: 0644]
benchmarks/interfaces/SmartthingsSensorCallback.java [new file with mode: 0644]
benchmarks/interfaces/SmartthingsSensorSmart.java [new file with mode: 0644]
benchmarks/interfaces/SmartthingsSensorSmartCallback.java [new file with mode: 0644]
benchmarks/other/ZigbeeTest/MotionSensor.java
benchmarks/other/ZigbeeTest/MultipurposeSensor.java
benchmarks/other/ZigbeeTest/SmartthingsSensor.java
benchmarks/other/ZigbeeTest/SmartthingsSensorCallback.java
benchmarks/other/ZigbeeTest/WaterLeakSensor.java
benchmarks/other/ZigbeeTest/ZigbeeTest_motion.java
benchmarks/other/ZigbeeTest/ZigbeeTest_multipurpose.java
benchmarks/other/ZigbeeTest/ZigbeeTest_waterleak.java
iotjava/Makefile
localconfig/iotpolicy/AudioRoom/audioroom.pol [deleted file]
localconfig/iotpolicy/AudioRoom/roomsmart.req [deleted file]
localconfig/iotpolicy/EspAlarm/espalarm.pol [new file with mode: 0644]
localconfig/iotpolicy/EspAlarm/smartalarm.req [new file with mode: 0644]
localconfig/iotpolicy/LabRoom/labroom.pol [deleted file]
localconfig/iotpolicy/LabRoom/roomsmart.req [deleted file]
localconfig/iotpolicy/Room/room.pol [new file with mode: 0644]
localconfig/iotpolicy/Room/roomsmart.req [new file with mode: 0644]
localconfig/iotpolicy/SmartthingsSensor/smartthingssensor.pol [new file with mode: 0644]
localconfig/iotpolicy/SmartthingsSensor/smartthingssensor.req [new file with mode: 0644]
localconfig/iotpolicy/SmartthingsSensor/smartthingssensorcallback.pol [new file with mode: 0644]
localconfig/iotpolicy/SmartthingsSensor/smartthingssensorcallback.req [new file with mode: 0644]
localconfig/mysql/roomCameraRelation.config
localconfig/mysql/roomSet.config
others/Mysql/IoTMain.gz

diff --git a/benchmarks/HomeSecurityController/AlarmSmart_Stub.java b/benchmarks/HomeSecurityController/AlarmSmart_Stub.java
new file mode 100644 (file)
index 0000000..3dc3500
--- /dev/null
@@ -0,0 +1,92 @@
+package HomeSecurityController;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.*;
+
+public class AlarmSmart_Stub implements AlarmSmart {
+
+       private IoTRMICall rmiCall;
+       private String callbackAddress;
+       private int[] ports;
+
+       private final static int objectId = 0;
+       
+
+       public AlarmSmart_Stub(int _port, String _skeletonAddress, String _callbackAddress, int _rev, int[] _ports) throws Exception {
+               callbackAddress = _callbackAddress;
+               ports = _ports;
+               rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev);
+       }
+
+       public boolean doesHaveZoneTimers() {
+               int methodId = 4;
+               Class<?> retType = boolean.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (boolean)retObj;
+       }
+
+       public List<ZoneState> getZoneStates() {
+               int methodId = 2;
+               Class<?> retType = int.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retLenObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               int retLen = (int) retLenObj;
+               Class<?>[] retCls = new Class<?>[3*retLen];
+               Class<?>[] retClsVal = new Class<?>[3*retLen];
+               int retPos = 0;
+               for(int i = 0; i < retLen; i++) {
+                       retCls[retPos] = int.class;
+                       retClsVal[retPos++] = null;
+                       retCls[retPos] = boolean.class;
+                       retClsVal[retPos++] = null;
+                       retCls[retPos] = int.class;
+                       retClsVal[retPos++] = null;
+               }
+               Object[] retObj = rmiCall.getStructObjects(retCls, retClsVal);
+               List<ZoneState> structRet = new ArrayList<ZoneState>();
+               int retObjPos = 0;
+               for(int i = 0; i < retLen; i++) {
+                       ZoneState structRetMem = new ZoneState();
+                       structRetMem.zoneNumber = (int) retObj[retObjPos++];
+                       structRetMem.onOffState = (boolean) retObj[retObjPos++];
+                       structRetMem.duration = (int) retObj[retObjPos++];
+                       structRet.add(structRetMem);
+               }
+               return structRet;
+       }
+
+       public void init() {
+               int methodId = 0;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+       public void setZone(int _zone, boolean _onOff, int _onDurationSeconds) {
+               int methodId = 1;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] { int.class, boolean.class, int.class };
+               Object[] paramObj = new Object[] { _zone, _onOff, _onDurationSeconds };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+       public int getNumberOfZones() {
+               int methodId = 3;
+               Class<?> retType = int.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (int)retObj;
+       }
+
+}
diff --git a/benchmarks/HomeSecurityController/CameraCallback_CallbackSkeleton.java b/benchmarks/HomeSecurityController/CameraCallback_CallbackSkeleton.java
new file mode 100644 (file)
index 0000000..a980927
--- /dev/null
@@ -0,0 +1,44 @@
+package HomeSecurityController;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.*;
+
+public class CameraCallback_CallbackSkeleton implements CameraCallback {
+
+       private CameraCallback mainObj;
+       private int objectId = 0;
+       private String callbackAddress;
+       
+
+       public CameraCallback_CallbackSkeleton(CameraCallback _mainObj, String _callbackAddress, int _objectId) throws Exception {
+               callbackAddress = _callbackAddress;
+               mainObj = _mainObj;
+               objectId = _objectId;
+       }
+
+       public void newCameraFrameAvailable(byte latestFrame[], long timeStamp) {
+               mainObj.newCameraFrameAvailable(latestFrame, timeStamp);
+       }
+
+       public void ___newCameraFrameAvailable(IoTRMIObject rmiObj) {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { byte[].class, long.class }, 
+               new Class<?>[] { null, null });
+               newCameraFrameAvailable((byte[]) paramObj[0], (long) paramObj[1]);
+       }
+
+       public void invokeMethod(IoTRMIObject rmiObj) throws IOException {
+               int methodId = rmiObj.getMethodId();
+               switch (methodId) {
+                       case 0: ___newCameraFrameAvailable(rmiObj); break;
+                       default: 
+                       throw new Error("Method Id " + methodId + " not recognized!");
+               }
+       }
+
+}
diff --git a/benchmarks/HomeSecurityController/CameraSmart_Stub.java b/benchmarks/HomeSecurityController/CameraSmart_Stub.java
new file mode 100644 (file)
index 0000000..d58dfba
--- /dev/null
@@ -0,0 +1,184 @@
+package HomeSecurityController;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.*;
+
+public class CameraSmart_Stub implements CameraSmart {
+
+       private IoTRMICall rmiCall;
+       private String callbackAddress;
+       private int[] ports;
+
+       private final static int objectId = 0;
+       // Callback properties
+       private IoTRMIObject rmiObj;
+       List<CameraCallback> listCallbackObj;
+       private static int objIdCnt = 0;
+       private final static int object0Id = 0; //CameraSmartCallback
+       private static Integer[] object0Permission = { 0 };
+       private static List<Integer> set0Allowed;
+       
+
+       public CameraSmart_Stub(int _port, String _skeletonAddress, String _callbackAddress, int _rev, int[] _ports) throws Exception {
+               callbackAddress = _callbackAddress;
+               ports = _ports;
+               rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev);
+               set0Allowed = new ArrayList<Integer>(Arrays.asList(object0Permission));
+               listCallbackObj = new ArrayList<CameraCallback>();
+               set0Allowed.add(-9999);
+               ___initCallBack();
+       }
+
+       public int getMaxFPS() {
+               int methodId = 8;
+               Class<?> retType = int.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (int)retObj;
+       }
+
+       public boolean setFPS(int _fps) {
+               int methodId = 7;
+               Class<?> retType = boolean.class;
+               Class<?>[] paramCls = new Class<?>[] { int.class };
+               Object[] paramObj = new Object[] { _fps };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (boolean)retObj;
+       }
+
+       public int getMinFPS() {
+               int methodId = 9;
+               Class<?> retType = int.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (int)retObj;
+       }
+
+       public boolean setResolution(Resolution _res) {
+               int methodId = 6;
+               Class<?> retType = boolean.class;
+               int paramEnum0[] = new int[1];
+               paramEnum0[0] = _res.ordinal();
+               Class<?>[] paramCls = new Class<?>[] { int[].class };
+               Object[] paramObj = new Object[] { paramEnum0 };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (boolean)retObj;
+       }
+
+       public void stop() {
+               int methodId = 2;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+       public void start() {
+               int methodId = 1;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+       public long getTimestamp() {
+               int methodId = 4;
+               Class<?> retType = long.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (long)retObj;
+       }
+
+       public byte[] getLatestFrame() {
+               int methodId = 3;
+               Class<?> retType = byte[].class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (byte[])retObj;
+       }
+
+       public void init() {
+               int methodId = 0;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+       public void registerCallback(CameraCallback _callbackTo) {
+               try {
+                       CameraCallback_CallbackSkeleton skel0 = new CameraCallback_CallbackSkeleton(_callbackTo, callbackAddress, objIdCnt++);
+                       listCallbackObj.add(skel0);
+               } catch (Exception ex) {
+                       ex.printStackTrace();
+                       throw new Error("Exception when generating skeleton objects!");
+               }
+
+               int methodId = 10;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] { int.class };
+               Object[] paramObj = new Object[] { new Integer(1) };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+       public void ___initCallBack() {
+               Thread thread = new Thread() {
+                       public void run() {
+                               try {
+                                       rmiObj = new IoTRMIObject(ports[0]);
+                                       while (true) {
+                                               byte[] method = rmiObj.getMethodBytes();
+                                               int objId = IoTRMIObject.getObjectId(method);
+                                               CameraCallback_CallbackSkeleton skel = (CameraCallback_CallbackSkeleton) listCallbackObj.get(objId);
+                                               if (skel != null) {
+                                                       int methodId = IoTRMIObject.getMethodId(method);
+                                                       if (!set0Allowed.contains(methodId)) {
+                                                               throw new Error("Callback object for CameraCallback is not allowed to access method: " + methodId);
+                                                       }
+                                                       skel.invokeMethod(rmiObj);
+                                               } else {
+                                                       throw new Error("CameraCallback: Object with Id " + objId + " not found!");
+                                               }
+                                       }
+                               } catch (Exception ex) {
+                                       ex.printStackTrace();
+                                       throw new Error("Error instantiating class CameraCallback_CallbackSkeleton!");
+                               }
+                       }
+               };
+               thread.start();
+
+               int methodId = -9998;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] { int[].class, String.class, int.class };
+               Object[] paramObj = new Object[] { ports, callbackAddress, 0 };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+       public List<Resolution> getSupportedResolutions() {
+               int methodId = 5;
+               Class<?> retType = int[].class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               int[] retEnum = (int[]) retObj;
+               Resolution[] enumVals = Resolution.values();
+               int retLen = retEnum.length;
+               List<Resolution> enumRetVal = new ArrayList<Resolution>();
+               for (int i = 0; i < retLen; i++) {
+                       enumRetVal.add(enumVals[retEnum[i]]);
+               }
+               return enumRetVal;
+       }
+
+}
diff --git a/benchmarks/HomeSecurityController/HomeSecurityController.config b/benchmarks/HomeSecurityController/HomeSecurityController.config
new file mode 100644 (file)
index 0000000..5a44766
--- /dev/null
@@ -0,0 +1 @@
+ADDITIONAL_ZIP_FILE=No
diff --git a/benchmarks/HomeSecurityController/HomeSecurityController.java b/benchmarks/HomeSecurityController/HomeSecurityController.java
new file mode 100644 (file)
index 0000000..5129e4a
--- /dev/null
@@ -0,0 +1,539 @@
+package HomeSecurityController;
+
+// Standard Java Packages
+import java.util.Date;
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import java.util.HashSet;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.ConcurrentHashMap;
+
+// RMI packages
+import java.rmi.RemoteException;
+import java.rmi.server.UnicastRemoteObject;
+
+// IoT Runtime Packages
+import iotruntime.slave.IoTSet;
+import iotruntime.slave.IoTRelation;
+import iotcode.annotation.*;
+
+// IoT Driver Packages
+import iotcode.interfaces.*;
+
+// Checker annotations
+//import iotchecker.qual.*;
+
+/** Class Home Security Controller for the home security application benchmark
+ *
+ * @author      Rahmadi Trimananda <rtrimana @ uci.edu>
+ * @version     1.0
+ * @since       2016-12-14
+ */
+public class HomeSecurityController implements SmartthingsSensorCallback {
+
+       /*
+        *  Constants
+        */
+       private static final int MOTION_TIME_THRESHOLD = 60;    // in seconds
+       private static final int CAMERA_FPS = 15;
+       private static final int CHECK_TIME_WAIT = 1;                   // in seconds
+       private static final int SECOND_TO_TURN_ON = 60;                // in seconds
+
+       /**
+        *  IoT Sets and Relations
+        *  <p>
+        *  Devices involved:
+        *  1) Multipurpose sensor (detect windows open/close) - Smartthings sensor
+        *  2) Motion sensor (detect motion in certain radius) - Smartthings sensor
+        *  3) Water leak sensor (detect leakage) - Smartthings sensor
+        *  4) Camera (detect motion)
+        *  5) Alarm (using ESP board) - assuming 1 house alarm
+        *  6) Room (object as place of device)
+        *
+        *  Additionals (for more extensive home management)
+        *  7) Doorlock (detect open/locked)
+        *  8) Power outlet (detect on/off, monitor watt)
+        */
+       // This comprises multipurpose, motion, and water leak sensors
+       // TODO: Per 01/2017, doorlock and outlet are not ready, ESP board will be used for alarm
+       @config private IoTSet<SmartthingsSensorSmart> smartSensorsSet;
+       @config private IoTSet<CameraSmart> camSet;
+       @config private IoTSet<AlarmSmart> alarmSet;
+       @config private IoTSet<RoomSmart> roomSet;
+       //@config private IoTSet<DoorLock> doorlockSet;
+       //@config private IoTSet<Outlet> outletSet;
+
+       @config private IoTRelation<RoomSmart, SmartthingsSensorSmart> roomSensorRelation;
+       @config private IoTRelation<RoomSmart, CameraSmart> roomCameraRelation;
+       //@config private IoTRelation<RoomSmart, DoorLock> roomDoorLockRelation;
+       //@config private IoTRelation<RoomSmart, Outlet> roomOutletRelation;
+
+       /*******************************************************************************************************************************************
+       **
+       **  Variables
+       **
+       *******************************************************************************************************************************************/
+       long lastTimeChecked = 0;
+
+       private static int sensorId = 0;
+
+       /*******************************************************************************************************************************************
+       **
+       **  States data structures
+       **
+       *******************************************************************************************************************************************/
+       // Camera and motion detection
+       private Map<CameraSmart, MotionDetection> camMotionDetect =
+               new HashMap<CameraSmart, MotionDetection>();
+       // Smartthings sensors (true = motion, leakage, etc.)
+       private Map<Integer, Boolean> senDetectStatus =
+               new ConcurrentHashMap<Integer, Boolean>();
+       // Camera (true = motion)
+       private Map<CameraSmart, Boolean> camDetectStatus =
+               new HashMap<CameraSmart, Boolean>();
+       // Doorlock (true = open - not locked)
+       //private Map<DoorLock, Boolean> doorlockStatus =
+       //      new HashMap<DoorLock, Boolean>();
+       // Outlet (true = on - outlet is used)
+       //private Map<Outlet, Boolean> outletStatus =
+       //      new HashMap<Outlet, Boolean>();
+
+       // Alarm status
+       private Map<Integer, Boolean> alarmStatus =
+               new HashMap<Integer, Boolean>();
+
+       public HomeSecurityController() {
+
+       }
+
+
+       /*******************************************************************************************************************************************
+       **
+       **  Helper Methods
+       **
+       *******************************************************************************************************************************************/
+
+
+       /** Method to initialize Smartthings sensors
+        *
+        *   @return [void] None.
+        */
+       private void initSmartthingsSensors(RoomSmart rm) {
+
+               // Get and init the IAS sensors for this specific room
+               HashSet<SmartthingsSensorSmart> sensors = roomSensorRelation.get(rm);
+               for (SmartthingsSensorSmart sen : sensors) {
+       
+                       try {
+                               // Initialize sensors
+                               sen.init();
+                               sen.setId(sensorId++);
+                               System.out.println("DEBUG: Initialized smartthings sensor!");
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+
+       /** Method to initialize cameras
+        *
+        *   @return [void] None.
+        */
+       private void initCameras(RoomSmart rm) {
+
+               // Get and init the cameras for this specific room
+               HashSet<CameraSmart> cameras = roomCameraRelation.get(rm);
+               // Setup the cameras, start them all and assign each one a motion detector
+               for (CameraSmart cam : camSet.values()) {
+
+                       // Each camera will have a motion detector unique to it since the motion detection has state
+                       MotionDetection mo = new MotionDetection(12, 0.5f, 10, 10);
+
+                       // initialize the camera, might need to setup some stuff internally
+                       cam.init();
+
+                       // set the camera parameters.
+                       cam.setFPS(CAMERA_FPS);
+                       cam.setResolution(Resolution.RES_VGA);
+
+                       // camera will call the motion detector directly with data not this controller
+                       cam.registerCallback(mo);
+
+                       // Start the camera (example is start the HTTP stream if it is a network camera)
+                       cam.start();
+                       System.out.println("DEBUG: Initialized camera!");
+
+                       // Remember which motion detector is for what camera
+                       camMotionDetect.put(cam, mo);
+               }
+       }
+
+
+       /** Method to initialize alarms
+        *
+        *   @return [void] None.
+        */
+       private void initAlarms() {
+
+               // Get and init the alarm (this single alarm set can serve multiple zones / rooms)
+               Iterator alarmIt = alarmSet.iterator();
+               AlarmSmart alm = (AlarmSmart) alarmIt.next();
+               // init the alarm controller, do it here since it only needs to be done once per controller
+               try {
+                       alm.init();
+                       System.out.println("DEBUG: Initialized alarm!");
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+
+       /** Method to initialize doorlocks
+        *
+        *   @return [void] None.
+        */
+       private void initDoorLocks(RoomSmart rm) {
+
+               // Get and init the doorlocks for this specific room
+               /*HashSet<DoorLock> doorlocks = roomDoorLockRelation.get(rm);
+               for (DoorLock doorlock : doorlocks) {
+       
+                       try {
+                               // Initialize doorlocks
+                               doorlock.init();
+                               System.out.println("DEBUG: Initialized doorlock!");
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }*/
+       }
+
+
+       /** Method to initialize power outlets
+        *
+        *   @return [void] None.
+        */
+       private void initOutlets(RoomSmart rm) {
+
+               // Get and init the outlets for this specific room
+               /*HashSet<Outlet> outlets = roomOutletRelation.get(rm);
+               for (Outlet outlet : outlets) {
+       
+                       try {
+                               // Initialize outlets
+                               outlet.init();
+                               System.out.println("DEBUG: Initialized outlet!");
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }*/
+       }
+
+
+       /** Method to detect if a room has seen motion within the last few seconds (time specified as parameter).
+        *   Checks all the motion detectors for the given room
+        *
+        *   @param _room            [RoomSmart] , Room of interest.
+        *   @param _numberOfSeconds [int]  , Number of seconds in the past that we consider recent.
+        *   @param _upperThreshold  [int]  , Number of seconds as an upper bound before we turn off.
+        *
+        *   @return [void] None.
+        */
+       private void updateCameraStatus(RoomSmart _room, int _numberOfSeconds) {
+               long currentTimeSeconds = (new Date()).getTime() / 1000;
+
+               // Loop through all the cameras in the room
+               for (CameraSmart cam : roomCameraRelation.get(_room)) {
+                       long lastDetectedMotionSeconds = currentTimeSeconds;
+
+                       Date motionTime = ((MotionDetection)camMotionDetect.get(cam)).getTimestampOfLastMotion();
+
+                       // Motion was detected at least once
+                       if (motionTime != null) {
+                               lastDetectedMotionSeconds = motionTime.getTime() / 1000;
+                       } else {
+                               // motionTime == null means this is the initialization phase
+                               // so we put false
+                               camDetectStatus.put(cam, false);
+                       }
+
+                       // Did detect motion recently
+                       if (Math.abs(currentTimeSeconds - lastDetectedMotionSeconds) < _numberOfSeconds) {
+                               camDetectStatus.put(cam, true);
+                       }
+               }
+       }
+
+
+       /** Method to update state data structures for Smartthings sensors
+        *
+        *   @return [void] None.
+        */
+       public void newReadingAvailable(int _sensorId, int _value, boolean _activeValue) {
+
+               System.out.println("DEBUG: Sensor reading value: " + _value);
+               if(_activeValue) {
+
+                       senDetectStatus.put(_sensorId, true);
+
+               } else {
+
+                       senDetectStatus.put(_sensorId, false);
+               } 
+       }
+
+
+       /** Method to update state data structures for doorlocks
+        *
+        *   @return [void] None.
+        */
+       private void updateDoorLockStatus(RoomSmart rm) {
+
+               // Get and init the outlets for this specific room
+               /*HashSet<DoorLock> doorlocks = roomDoorLockRelation.get(rm);
+               for (DoorLock doorlock : doorlocks) {
+       
+                       // Change is detected! Set to true for report...
+                       if(isChangeDetected()) {
+
+                               doorlockStatus.put(doorlock, true);
+                       } else {
+
+                               doorlockStatus.put(doorlock, false);
+                       }
+               }*/
+       }
+
+
+       /** Method to update state data structures for outlets
+        *
+        *   @return [void] None.
+        */
+       private void updateOutletStatus(RoomSmart rm) {
+
+               // Get and init the outlets for this specific room
+               /*HashSet<Outlet> outlets = roomOutletRelation.get(rm);
+               for (Outlet outlet : outlets) {
+       
+                       // Change is detected! Set to true for report...
+                       if(isChangeDetected()) {
+
+                               outletStatus.put(outlet, true);
+                       } else {
+
+                               outletStatus.put(outlet, false);
+                       }
+               }*/
+       }
+
+
+       /** Update the status of all devices
+        *
+        *   @return [void] None.
+        */
+       private void updateUniversalStatus() {
+
+               // Check for motion in rooms and if there is motion then report
+               for (RoomSmart room : roomSet.values()) {
+
+                       // Update status of camera
+                       updateCameraStatus(room, MOTION_TIME_THRESHOLD);
+
+                       // Update status of doorlocks
+                       //updateDoorLockStatus(room);
+
+                       // Update status of outlets
+                       //updateOutletStatus(room);
+               }
+       }
+
+
+       /** Method to turn on alarms
+        *
+        *   @return [void] None.
+        */
+       private void turnOnAlarms(int zoneId) {
+
+               // Get and init the alarm (this single alarm set can serve multiple zones / rooms)
+               Iterator alarmIt = alarmSet.iterator();
+               AlarmSmart alm = (AlarmSmart) alarmIt.next();
+               alm.setZone(zoneId, true, SECOND_TO_TURN_ON);
+       }
+
+
+       /** Method to turn off alarms
+        *
+        *   @return [void] None.
+        */
+       private void turnOffAlarms(int zoneId) {
+
+               // Get and init the alarm (this single alarm set can serve multiple zones / rooms)
+               Iterator alarmIt = alarmSet.iterator();
+               AlarmSmart alm = (AlarmSmart) alarmIt.next();
+               // Turn this alarm off indefinitely
+               alm.setZone(zoneId, false, -1);
+       }
+
+
+       /** Check status of devices and turn on alarm accordingly
+        *  <p>
+        *  Simple rule is whenever any sensor or camera detect something unusual
+        *      (sensor/camera becomes active) then we sound the corresponding alarm.
+        *  This means we send the signal to the right zone in the EspAlarm
+        *
+        *   @return [void] None.
+        */
+       private void decideToTurnOnAlarm() {
+
+               int zoneId = 0;
+
+               // Check for motion in rooms and if there is motion then report
+               for (RoomSmart room : roomSet.values()) {
+
+                       // Loop through all the cameras in the room
+                       for (CameraSmart cam : roomCameraRelation.get(room)) {
+
+                               // Get the right camera and the right detection status (true or false)
+                               if (camDetectStatus.get(cam)) {
+                                       zoneId = room.getRoomID();
+                                       turnOnAlarms(zoneId);
+                                       System.out.println("DETECTION: Camera active in room: " + zoneId);
+                               }
+                       }
+
+                       // Loop through all the cameras in the room
+                       for (SmartthingsSensorSmart sensor : roomSensorRelation.get(room)) {
+
+                               // Get the right sensor and the right detection status (true or false)
+                               if (senDetectStatus.get(sensor.getId())) {
+                                       zoneId = room.getRoomID();
+                                       turnOnAlarms(zoneId);
+                                       System.out.println("DETECTION: Sensor active in room: " + zoneId);
+                               }
+                       }
+               }
+       }
+
+
+       /** Check status of devices and turn off alarm accordingly
+        *  <p>
+        *  If everything (camera and sensors) is set back to normal
+        *  then the system will turn off the alarm
+        *
+        *   @return [void] None.
+        */
+       // TODO: Need to fix this part later
+       // TODO: Perhaps we should use a phone app to turn off the alarm
+       /*private void decideToTurnOffAlarm() {
+
+               // Check for motion in rooms and if there is motion then report
+               for (RoomSmart room : roomSet.values()) {
+
+                       int zoneId = room.getRoomID();
+                       // Loop through all the cameras in the room
+                       for (CameraSmart cam : roomCameraRelation.get(room)) {
+
+                               // Get the right camera and the right detection status (true or false)
+                               if (camDetectStatus.get(cam))   // Camera still active so alarm is still on, so false for off-alarm status
+
+                                       alarmStatus.put(zoneId, false);
+
+                               else
+
+                                       alarmStatus.put(zoneId, true);
+                               
+                       }
+
+                       // Loop through all the cameras in the room
+                       for (SmartthingsSensor sensor : roomSensorRelation.get(room)) {
+
+                               // Get the right sensor and the right detection status (true or false)
+                               if (senDetectStatus.get(sensor.getId()))        // Sensor still active so alarm is still on, so false for off-alarm status
+
+                                       alarmStatus.put(zoneId, false);
+
+                               else
+
+                                       alarmStatus.put(zoneId, true);
+                       }
+               }
+
+               // Turn on alarm in the right zone
+               for (Map.Entry<Integer, Boolean> alEnt : alarmStatus.entrySet()) {
+                       if (alEnt.getValue())   // if this zone is true, that means we need to turn off its alarm
+                               turnOffAlarms(alEnt.getKey());
+               }
+       }*/
+
+
+       /*******************************************************************************************************************************************
+       **
+       **  Public Methods
+       **
+       *******************************************************************************************************************************************/
+
+       /** Initialization method, called by the runtime (effectively the main of the controller)
+        *   This method runs a continuous loop and is blocking
+        *
+        *   @return [void] None;
+        */
+       public void init() {
+
+               // Iterate over the set of rooms
+               for (RoomSmart rm : roomSet.values()) {
+
+                       // Init all Smartthings sensors
+                       initSmartthingsSensors(rm);
+
+                       // Init all cameras
+                       initCameras(rm);
+
+                       // Init all doorlocks
+                       //initDoorLocks(rm);
+
+                       // Init all outlets
+                       //initOutlets(rm);
+               }
+
+               // Init all alarms
+               initAlarms();
+
+               // Run the main loop that will keep checking the sensors and cameras periodically
+               while (true) {
+
+                       // Run this code every <specified time>
+                       long currentTimeSeconds = (new Date()).getTime() / 1000;
+                       if ((currentTimeSeconds - lastTimeChecked) > CHECK_TIME_WAIT) {
+                               lastTimeChecked = currentTimeSeconds;
+
+                               // Update the status of all devices
+                               updateUniversalStatus();
+
+                               // Decide to turn on alarm if any of the sensor/camera detects something unusual
+                               decideToTurnOnAlarm();
+
+                               // Decide to turn off alarm if every sensor/camera goes back to normal
+                               //decideToTurnOffAlarm();
+
+                       } else {
+
+                               try {
+
+                                       Thread.sleep(CHECK_TIME_WAIT * 100); // sleep for a tenth of the time
+
+                               } catch (Exception e) {
+
+                                       e.printStackTrace();
+                               }
+                       }
+
+               }
+       }
+}
+
+
diff --git a/benchmarks/HomeSecurityController/Makefile b/benchmarks/HomeSecurityController/Makefile
new file mode 100644 (file)
index 0000000..16ca57a
--- /dev/null
@@ -0,0 +1,19 @@
+BASE = ../..
+
+include $(BASE)/common.mk
+
+BOOFDIR := ../libs/boofcv_libs
+BOOFJARS := $(BOOFDIR)/BoofCV-feature-0.21.jar:$(BOOFDIR)/BoofCV-io-0.21.jar:$(BOOFDIR)/BoofCV-visualize-0.21.jar:$(BOOFDIR)/BoofCV-ip-0.21.jar:$(CHECKERJARS)
+
+JFLAGS = -d $(BIN_DIR) -cp $(BOOFJARS):$(BIN_DIR):.
+JARFLAGS = cf 
+
+all: homesecurity
+
+PHONY += homesecurity
+homesecurity:
+       $(JAVAC) $(JFLAGS) *.java
+       cp HomeSecurityController.config $(BIN_DIR)/HomeSecurityController
+       cd $(BIN_DIR)/HomeSecurityController; $(JAR) $(JARFLAGS) HomeSecurityController.jar ../HomeSecurityController/HomeSecurityController*.class ../HomeSecurityController/MotionDetection*.class ../iotcode/interfaces/SmartthingsSensor*.class ../iotcode/interfaces/Camera*.class ../iotcode/interfaces/Alarm*.class ../iotcode/interfaces/Room*.class  ../iotcode/interfaces/ZoneState*.class
+
+.PHONY: $(PHONY)
diff --git a/benchmarks/HomeSecurityController/MotionDetection.java b/benchmarks/HomeSecurityController/MotionDetection.java
new file mode 100644 (file)
index 0000000..dceeb7f
--- /dev/null
@@ -0,0 +1,463 @@
+package HomeSecurityController;
+
+// IoT packages
+import iotcode.annotation.*;
+import iotcode.interfaces.*;
+
+// BoofCv packages
+import boofcv.alg.background.BackgroundModelStationary;
+import boofcv.factory.background.ConfigBackgroundGaussian;
+import boofcv.factory.background.FactoryBackgroundModel;
+import boofcv.gui.binary.VisualizeBinaryData;
+import boofcv.gui.image.ImageGridPanel;
+import boofcv.gui.image.ShowImages;
+import boofcv.io.MediaManager;
+import boofcv.io.UtilIO;
+import boofcv.io.image.SimpleImageSequence;
+import boofcv.io.image.ConvertBufferedImage;
+import boofcv.io.wrapper.DefaultMediaManager;
+import boofcv.struct.image.ImageBase;
+import boofcv.struct.image.ImageFloat32;
+import boofcv.struct.image.ImageType;
+import boofcv.struct.image.ImageUInt8;
+import boofcv.alg.filter.blur.BlurImageOps;
+
+
+// Standard Java Packages
+import java.awt.image.BufferedImage;
+import java.util.Date;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.awt.image.ColorModel;
+import java.awt.image.WritableRaster;
+import java.util.List;
+import java.util.ArrayList;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import javax.imageio.ImageIO;
+
+// RMI Packages
+import java.rmi.RemoteException;
+
+// For testing
+import java.net.*;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+import java.util.Iterator;
+
+// Checker annotations
+//import iotchecker.qual.*;
+
+/** Class MotionDetection to do motion detection using images
+ *
+ *
+ * @author      Ali Younis <ayounis @ uci.edu>
+ * @version     1.0
+ * @since       2016-03-21
+ */
+class MotionDetection implements CameraCallback {
+
+       // Define Like variables
+       private static boolean DO_GRAPHICAL_USER_INTERFACE = false;
+
+       /*******************************************************************************************************************************************
+       **
+       **  Constants
+       **
+       *******************************************************************************************************************************************/
+       private final float MOTION_DETECTED_THRESHOLD_PERCENTAGE = 15;
+
+
+       /*******************************************************************************************************************************************
+       **
+       **  Variables
+       **
+       *******************************************************************************************************************************************/
+
+       // Timestamp buffer and locks needed for that safety on that buffer
+       // This is the buffer for post-detection algorithm use
+       private Date timestampOfLastMotion = null;
+       private ReadWriteLock timestampReadWriteLock = new ReentrantReadWriteLock();
+       private Lock timestampReadLock = timestampReadWriteLock.readLock();
+       private Lock timestampWriteLock = timestampReadWriteLock.writeLock();
+
+       // Flag for when new data is available and ready for processing
+       private AtomicBoolean newFrameAvailable = new AtomicBoolean(false);
+
+       // Flag for determining if motion has been detected and therefore
+       // the callbacks should be issued
+       private AtomicBoolean motionDetected = new AtomicBoolean(false);
+
+       // Image and timestamp buffers and  locks needed for that safety on those buffers
+       // Timestamp buffer for pre-detection algorithm use
+       private BufferedImage latestImage = null;
+       private Date possibleDate = null;
+       private ReadWriteLock imageReadWriteLock = new ReentrantReadWriteLock();
+       private Lock imageReadLock = imageReadWriteLock.readLock();
+       private Lock imageWriteLock = imageReadWriteLock.writeLock();
+
+       // List of objects wishing to receive callbacks from this class.
+       private List<MotionDetectionCallback>
+       callbackList = new ArrayList<MotionDetectionCallback>();
+
+       // Variables to help with motion detection
+       private ConfigBackgroundGaussian configGaussian = null;
+       private BackgroundModelStationary backgroundDetector = null;
+       private ImageUInt8 segmented = null;
+       private ImageFloat32 newFrameFloat = null;
+
+       // counts the number of frames since a background image is added to algorithm
+       private int frameCounter = 0;
+
+       private CameraSmart _camera;
+
+       /*******************************************************************************************************************************************
+       **
+       **  Threads
+       **
+       *******************************************************************************************************************************************/
+       private Thread workThread = null;
+       private Thread callBackThread = null;
+
+       /*******************************************************************************************************************************************
+       **
+       **  GUI Stuff (Used Only for Testing)
+       **
+       *******************************************************************************************************************************************/
+       ImageGridPanel gui;
+
+       /** Constructor
+        *
+        *   @param _threshold       [float], Variable for gaussian background detector.
+        *   @param _learnSpeed      [float], Variable for gaussian background detector.
+        *   @param _initialVariance [float], Variable for gaussian background detector.
+        *   @param _minDifference   [float], Variable for gaussian background detector.
+        *
+        */
+       public MotionDetection(float _threshold, float _learnSpeed, float _initialVariance, float _minDifference) {
+
+               // Configure the Gaussian model used for background detection
+               configGaussian = new ConfigBackgroundGaussian(_threshold, _learnSpeed);
+               configGaussian.initialVariance = _initialVariance;
+               configGaussian.minimumDifference = _minDifference;
+
+               // setup the background detector
+               ImageType imageType = ImageType.single(ImageFloat32.class);
+               backgroundDetector = FactoryBackgroundModel.stationaryGaussian(configGaussian, imageType);
+
+               // setup the gui if we are going to use it
+               if (DO_GRAPHICAL_USER_INTERFACE) {
+
+                       // create an image grid for images to place on, tile fashion
+                       gui = new ImageGridPanel(1, 2);
+
+                       // make the window large so we dont have to manually resize with the mouse
+                       gui.setSize(1920, 1080);
+
+                       // Make the window visible and set the title
+                       ShowImages.showWindow(gui, "Static Scene: Background Segmentation", true);
+               }
+
+               // Launch the worker thread
+               workThread = new Thread(new Runnable() {
+                       public void run() {
+
+                               while (true) {
+                                       runMotionDetection();
+                               }
+                       }
+               });
+               workThread.start();
+
+
+               // Launch the callback thread
+               callBackThread = new Thread(new Runnable() {
+                       public void run() {
+
+                               while (true) {
+                                       doCallbacks();
+                               }
+                       }
+               });
+               callBackThread.start();
+       }
+
+
+       /*******************************************************************************************************************************************
+       **
+       **  Public Methods
+       **
+       *******************************************************************************************************************************************/
+
+       /** Method to add a new frame to the motion detector.
+        *
+        *   @param _newFrame  [byte[]], Frame data of new frame.
+        *   @param _timestamp [Date]  , Timestamp of new frame.
+        *
+        *   @return [void] None.
+        */
+       public void addFrame(byte[]  _newFrame, Date _timestamp) {
+               BufferedImage img = null;
+
+               try {
+                       // Parse the byte array into a Buffered Image
+                       InputStream in = new ByteArrayInputStream(_newFrame);
+                       img = ImageIO.read(in);
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+                       return;
+               }
+
+               // Save the image and timestamp for use later
+               imageWriteLock.lock();// lock the image and timestamp buffers since multithread
+               latestImage = img;// image into image buffer
+               possibleDate = _timestamp;// timestamp into timestamp buffer
+               imageWriteLock.unlock();// Never forget to unlock
+
+               // flag the worker thread that there is new data ready for processing
+               newFrameAvailable.set(true);
+       }
+
+       /** Method to get the timestamp of the last time motion was detected
+        *
+        *   @return [Date] timestamp of last motion or null if no motion was ever detected.
+        */
+       public Date getTimestampOfLastMotion() {
+               Date ret = null;
+
+               // Be safe because multithread
+               timestampReadLock.lock();
+
+               // Checks if there was ever motion, if not then timestampOfLastMotion
+               // will be null
+               if (timestampOfLastMotion != null) {
+                       // Clone since we don't know what the other person is going to do
+                       // with the timestamp
+                       ret = (Date)timestampOfLastMotion.clone();
+               }
+
+               timestampReadLock.unlock();
+
+               return ret;
+       }
+
+
+       /** Method to add a new frame to the motion detector from a camera
+        *
+        *   @param _camera  [Camera], Camera that has the new data.
+        *
+        *   @return [void] None.
+        */
+       public void newCameraFrameAvailable(byte[] latestFrame, long timeStamp) {
+               BufferedImage img = null;
+
+               try {
+                       // Parse the byte array into a Buffered Image
+                       //InputStream in = new ByteArrayInputStream(_camera.getLatestFrame());
+                       InputStream in = new ByteArrayInputStream(latestFrame);
+                       img = ImageIO.read(in);
+
+               } catch (RemoteException e) {
+                       e.printStackTrace();
+                       return;
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+                       return;
+
+               }
+
+               // Save the image and timestamp for use later
+               imageWriteLock.lock();  // lock the image and timestamp buffers since multithread
+               latestImage = img;              // image into image buffer
+
+               // timestamp from camera into timestamp buffer
+               long dateLong = timeStamp;
+               possibleDate = new Date(dateLong);
+
+               imageWriteLock.unlock();        // Never forget to unlock
+
+               // flag the worker thread that there is new data ready for processing
+               newFrameAvailable.set(true);
+       }
+
+       /** Method to register an object to recieve callbacks from this motion detector
+        *
+        *   @param _mdc  [MotionDetectionCallback], object to recieve callbacks.
+        *
+        *   @return [void] None.
+        */
+       public void registerCallback(MotionDetectionCallback _mdc) {
+               callbackList.add(_mdc);
+       }
+
+       /*******************************************************************************************************************************************
+       **
+       **  Helper Methods
+       **
+       *******************************************************************************************************************************************/
+
+       /** Method that constantly loops checking if new data is available.  If there is
+        *   new data, it is processed.
+        *   This method should be run on a separate thread.
+        *
+        *   @return [void] None.
+        */
+       private void runMotionDetection() {
+
+               // check if there is a new frame availble, only runs detection if there is new data to save
+               // computation time
+               if (!newFrameAvailable.get()) {
+                       return;
+               }
+
+               // Lock since we are accessing the data buffers
+               imageReadLock.lock();
+
+               // processing data so now the buffered data is old
+               newFrameAvailable.set(false);
+
+               // copy from buffer to local for processing
+               Date tmpDate = possibleDate;
+
+               // Allocate space for the segmented image based on the first image we received
+               // cannot pre-allocate this since we do not know what the size of the images is
+               // before the first image arrives
+               if (segmented == null) {
+                       segmented = new ImageUInt8(latestImage.getWidth(), latestImage.getHeight());
+               }
+
+               // copy from data buffers and convert into correct data type for BoofCv libraries
+               newFrameFloat = ConvertBufferedImage.convertFrom(latestImage, newFrameFloat);
+
+               // All done accessing the data buffers
+               imageReadLock.unlock();
+
+               // Run background detection
+               backgroundDetector.segment(newFrameFloat, segmented);
+
+               // Update the background baseline every 10 frames, helps the algorithm
+               frameCounter++;
+               if (frameCounter > 10) {
+                       backgroundDetector.updateBackground(newFrameFloat);
+                       frameCounter = 0;
+               }
+
+               // get the raw pixel data, gray-scale image
+               byte[] frameData = segmented.getData();
+
+               // count the number of pixels of the image that was deemed as "motion"
+               double count = 0;
+               double countMotion = 0;
+               for (byte b : frameData) {
+                       count++;
+                       if (b > 0) {
+                               countMotion++;
+                       }
+               }
+
+               // calculate the percentage of the image that was in motion
+               double percentMotion = (countMotion / count) * 100.0;
+
+               // Check if a high enough percentage of the image was in motion to say that there was motion in this frame of data
+               if (percentMotion > MOTION_DETECTED_THRESHOLD_PERCENTAGE) {
+
+                       // Motion detected so save timestamp of this frame to another buffer
+                       timestampWriteLock.lock();
+                       timestampOfLastMotion = (Date)tmpDate.clone();                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          // clone to a different buffer
+                       timestampWriteLock.unlock();
+
+                       System.out.println("Motion Detected (with percentage: " + Double.toString(percentMotion) + "%)");
+               }
+
+               // Do output to the screen if we are using gui mode
+               if (DO_GRAPHICAL_USER_INTERFACE) {
+
+                       // change image data unto correct type for rendering
+                       BufferedImage visualized1 = new BufferedImage(segmented.width, segmented.height, BufferedImage.TYPE_INT_RGB);
+                       VisualizeBinaryData.renderBinary(segmented, false, visualized1);
+
+                       // change image data unto correct type for rendering
+                       BufferedImage visualized2 = null;
+                       visualized2 = ConvertBufferedImage.convertTo(newFrameFloat, visualized2, true);
+
+                       // place the images into the image grid
+                       gui.setImage(0, 1, visualized1);
+                       gui.setImage(0, 2, visualized2);
+
+                       // trigger rendering
+                       gui.repaint();
+               }
+       }
+
+       /** Method that constantly loops checking if the callbacks should be issues and
+        *   issues the callbacks if they should be issues.
+        *   This method should be run on a separate thread.
+        *
+        *   @return [void] None.
+        */
+       private void doCallbacks() {
+
+               // Keep looping forever for callback
+               while (true) {
+
+                       // If motion detected
+                       if (motionDetected.compareAndSet(true, false)) {
+
+                               // Motion was detected so issue callbacks to all objects that registered
+                               // to receive callback from this class.
+                               for (MotionDetectionCallback c : callbackList) {
+                                       //try {
+                                               c.motionDetected(this);
+                                       //} catch (RemoteException re) {
+                                       //}
+                               }
+
+                       } else {
+
+                               // Sleep for 15 millisec to give time for new frame to arrive
+                               try {
+                                       Thread.sleep(15);
+                               } catch (InterruptedException ie) {
+                               }
+                       }
+               }
+       }
+
+
+
+
+       // /*******************************************************************************************************************************************
+       // **  Main Method used for testing
+       // *******************************************************************************************************************************************/
+       // public static void main(String[] args) {
+       //     MotionDetection mo = new MotionDetection(12, 0.5f, 10, 10);
+
+       //     AmcrestCamera cam = null;
+       //     try {
+
+       //         InetAddress addr = InetAddress.getByName("192.168.1.29");
+       //         cam = new AmcrestCamera(addr, "admin", "55779CatSoundz32");
+       //         cam.registerCallback(mo);
+       //         cam.start();
+       //         // cam.streamDisconnect();
+
+       //     } catch (Exception e) {
+
+       //     }
+
+       //     while (true) {
+
+       //     }
+
+       // }
+}
+
diff --git a/benchmarks/HomeSecurityController/MotionDetectionCallback.java b/benchmarks/HomeSecurityController/MotionDetectionCallback.java
new file mode 100644 (file)
index 0000000..9ee6906
--- /dev/null
@@ -0,0 +1,20 @@
+package HomeSecurityController;
+
+/** Interface MotionDetectionCallback for allowing callbacks from the MotionDetection class.
+ *
+ *
+ * @author      Ali Younis <ayounis @ uci.edu>
+ * @version     1.0
+ * @since       2016-03-21
+ */
+
+public interface MotionDetectionCallback {
+
+       /** Callback method for when motion is detected.
+        *
+        *   @param _md [MotionDetection].
+        *
+        *   @return [void] None.
+        */
+       public void motionDetected(MotionDetection _md);
+}
diff --git a/benchmarks/HomeSecurityController/RoomSmart_Stub.java b/benchmarks/HomeSecurityController/RoomSmart_Stub.java
new file mode 100644 (file)
index 0000000..0c04049
--- /dev/null
@@ -0,0 +1,36 @@
+package HomeSecurityController;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.RoomSmart;
+
+public class RoomSmart_Stub implements RoomSmart {
+
+       private IoTRMICall rmiCall;
+       private String callbackAddress;
+       private int[] ports;
+
+       private final static int objectId = 0;
+       
+
+       public RoomSmart_Stub(int _port, String _skeletonAddress, String _callbackAddress, int _rev, int[] _ports) throws Exception {
+               callbackAddress = _callbackAddress;
+               ports = _ports;
+               rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev);
+       }
+
+       public int getRoomID() {
+               int methodId = 0;
+               Class<?> retType = int.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (int)retObj;
+       }
+
+}
diff --git a/benchmarks/HomeSecurityController/SmartthingsSensorCallback_CallbackSkeleton.java b/benchmarks/HomeSecurityController/SmartthingsSensorCallback_CallbackSkeleton.java
new file mode 100644 (file)
index 0000000..6e09471
--- /dev/null
@@ -0,0 +1,44 @@
+package HomeSecurityController;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.*;
+
+public class SmartthingsSensorCallback_CallbackSkeleton implements SmartthingsSensorCallback {
+
+       private SmartthingsSensorCallback mainObj;
+       private int objectId = 0;
+       private String callbackAddress;
+       
+
+       public SmartthingsSensorCallback_CallbackSkeleton(SmartthingsSensorCallback _mainObj, String _callbackAddress, int _objectId) throws Exception {
+               callbackAddress = _callbackAddress;
+               mainObj = _mainObj;
+               objectId = _objectId;
+       }
+
+       public void newReadingAvailable(int _sensorId, int _value, boolean _activeValue) {
+               mainObj.newReadingAvailable(_sensorId, _value, _activeValue);
+       }
+
+       public void ___newReadingAvailable(IoTRMIObject rmiObj) {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class, int.class, boolean.class }, 
+               new Class<?>[] { null, null, null });
+               newReadingAvailable((int) paramObj[0], (int) paramObj[1], (boolean) paramObj[2]);
+       }
+
+       public void invokeMethod(IoTRMIObject rmiObj) throws IOException {
+               int methodId = rmiObj.getMethodId();
+               switch (methodId) {
+                       case 0: ___newReadingAvailable(rmiObj); break;
+                       default: 
+                       throw new Error("Method Id " + methodId + " not recognized!");
+               }
+       }
+
+}
diff --git a/benchmarks/HomeSecurityController/SmartthingsSensorSmart_Stub.java b/benchmarks/HomeSecurityController/SmartthingsSensorSmart_Stub.java
new file mode 100644 (file)
index 0000000..87eff75
--- /dev/null
@@ -0,0 +1,140 @@
+package HomeSecurityController;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.*;
+
+public class SmartthingsSensorSmart_Stub implements SmartthingsSensorSmart {
+
+       private IoTRMICall rmiCall;
+       private String callbackAddress;
+       private int[] ports;
+
+       private final static int objectId = 0;
+       // Callback properties
+       private IoTRMIObject rmiObj;
+       List<SmartthingsSensorCallback> listCallbackObj;
+       private int objIdCnt = 0;
+       private final static int object0Id = 0; //SmartthingsSensorSmartCallback
+       private static Integer[] object0Permission = { 0 };
+       private static List<Integer> set0Allowed;
+       
+
+       public SmartthingsSensorSmart_Stub(int _port, String _skeletonAddress, String _callbackAddress, int _rev, int[] _ports) throws Exception {
+               callbackAddress = _callbackAddress;
+               ports = _ports;
+               rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev);
+               set0Allowed = new ArrayList<Integer>(Arrays.asList(object0Permission));
+               listCallbackObj = new ArrayList<SmartthingsSensorCallback>();
+               set0Allowed.add(-9999);
+               ___initCallBack();
+       }
+
+       public long getTimestampOfLastReading() {
+               int methodId = 3;
+               Class<?> retType = long.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (long)retObj;
+       }
+
+       public boolean isActiveValue() {
+               int methodId = 2;
+               Class<?> retType = boolean.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (boolean)retObj;
+       }
+
+       public int getId() {
+               int methodId = 5;
+               Class<?> retType = int.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (int)retObj;
+       }
+
+       public void registerCallback(SmartthingsSensorCallback _callbackTo) {
+               try {
+                       SmartthingsSensorCallback_CallbackSkeleton skel0 = new SmartthingsSensorCallback_CallbackSkeleton(_callbackTo, callbackAddress, objIdCnt++);
+                       listCallbackObj.add(skel0);
+               } catch (Exception ex) {
+                       ex.printStackTrace();
+                       throw new Error("Exception when generating skeleton objects!");
+               }
+
+               int methodId = 6;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] { int.class };
+               Object[] paramObj = new Object[] { new Integer(1) };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+       public void ___initCallBack() {
+               Thread thread = new Thread() {
+                       public void run() {
+                               try {
+                                       rmiObj = new IoTRMIObject(ports[0]);
+                                       while (true) {
+                                               byte[] method = rmiObj.getMethodBytes();
+                                               int objId = IoTRMIObject.getObjectId(method);
+                                               SmartthingsSensorCallback_CallbackSkeleton skel = (SmartthingsSensorCallback_CallbackSkeleton) listCallbackObj.get(objId);
+                                               if (skel != null) {
+                                                       int methodId = IoTRMIObject.getMethodId(method);
+                                                       if (!set0Allowed.contains(methodId)) {
+                                                               throw new Error("Callback object for SmartthingsSensorCallback is not allowed to access method: " + methodId);
+                                                       }
+                                                       skel.invokeMethod(rmiObj);
+                                               } else {
+                                                       throw new Error("SmartthingsSensorCallback: Object with Id " + objId + " not found!");
+                                               }
+                                       }
+                               } catch (Exception ex) {
+                                       ex.printStackTrace();
+                                       throw new Error("Error instantiating class SmartthingsSensorCallback_CallbackSkeleton!");
+                               }
+                       }
+               };
+               thread.start();
+
+               int methodId = -9998;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] { int[].class, String.class, int.class };
+               Object[] paramObj = new Object[] { ports, callbackAddress, 0 };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+       public int getValue() {
+               int methodId = 1;
+               Class<?> retType = int.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+               return (int)retObj;
+       }
+
+       public void setId(int id) {
+               int methodId = 4;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] { int.class };
+               Object[] paramObj = new Object[] { id };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+       public void init() {
+               int methodId = 0;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] {  };
+               Object[] paramObj = new Object[] {  };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+}
index 767dd67e39f3034b89f0540c4dfad3a5d51e57cd..0ae1e70ced0155387b072846b3134677401ba570 100644 (file)
@@ -416,10 +416,10 @@ class MotionDetection extends UnicastRemoteObject implements CameraCallback {
                                // Motion was detected so issue callbacks to all objects that registered
                                // to receive callback from this class.
                                for (MotionDetectionCallback c : callbackList) {
-                                       try {
+                                       //try {
                                                c.motionDetected(this.getTimestampOfLastMotion());
-                                       } catch (RemoteException re) {
-                                       }
+                                       //} catch (RemoteException re) {
+                                       //}
                                }
 
                        } else {
index d7dfb8345985c2bd4897d4073b5e92b049fdd7c2..3f89aa23091bd999c64ebf94e9f58bf7d9075503 100644 (file)
@@ -8,19 +8,13 @@ package IrrigationController;
  * @since       2016-03-21
  */
 
-// Checker annotations
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-
-public interface MotionDetectionCallback extends Remote {
+public interface MotionDetectionCallback {
 
        /** Callback method for when motion is detected.
         *
-        *   @param _md [MotionDetection].
+        *   @param timeStampOfLastMotion [long].
         *
         *   @return [void] None.
         */
-       //public void motionDetected(@NonLocalRemote MotionDetection _wg) throws RemoteException;
-       public void motionDetected(long timeStampOfLastMotion) throws RemoteException;
+       public void motionDetected(long timeStampOfLastMotion);
 }
index f4cbd4c69c601c52ccc9c8981c6a634b7338040a..5ed4629ce95a98c029be50ac5b2c66be803e0fbd 100644 (file)
@@ -4,7 +4,7 @@ BOOFJARS := $(BOOFDIR)/BoofCV-feature-0.21.jar:$(BOOFDIR)/BoofCV-io-0.21.jar:$(B
 
 include $(BASE)/common.mk
 
-all: interfaces annotation drivers Lifxtest SmartLights Irrigation Speaker
+all: interfaces annotation drivers Lifxtest SmartLights Irrigation Speaker HomeSecurity
 
 PHONY += interfaces
 interfaces:
@@ -34,4 +34,8 @@ PHONY += Speaker
 Speaker:
        $(MAKE) -C SpeakerController
 
+PHONY += HomeSecurity
+HomeSecurity:
+       $(MAKE) -C HomeSecurityController
+
 .PHONY: $(PHONY)
index d9c608e87c2b2fb1a3eaf026b09772f0a70f7c7c..bd473501808d433f35e2263220414c48e2c9f63c 100644 (file)
@@ -416,10 +416,10 @@ class MotionDetection implements CameraCallback {
                                // Motion was detected so issue callbacks to all objects that registered
                                // to receive callback from this class.
                                for (MotionDetectionCallback c : callbackList) {
-                                       try {
+                                       //try {
                                                c.motionDetected(this);
-                                       } catch (RemoteException re) {
-                                       }
+                                       //} catch (RemoteException re) {
+                                       //}
                                }
 
                        } else {
index 5517abcb008ff75f73df5fc11e6d643d81504fdd..98d96360112a06a00f87e92827b9385036b45c35 100644 (file)
@@ -8,10 +8,7 @@ package SmartLightsController;
  * @since       2016-03-21
  */
 
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-public interface MotionDetectionCallback extends Remote {
+public interface MotionDetectionCallback {
 
        /** Callback method for when motion is detected.
         *
@@ -19,5 +16,5 @@ public interface MotionDetectionCallback extends Remote {
         *
         *   @return [void] None.
         */
-       public void motionDetected(MotionDetection _md) throws RemoteException;
+       public void motionDetected(MotionDetection _md);
 }
diff --git a/benchmarks/drivers/EspAlarm/Alarm_Skeleton.java b/benchmarks/drivers/EspAlarm/Alarm_Skeleton.java
new file mode 100644 (file)
index 0000000..8d8ab89
--- /dev/null
@@ -0,0 +1,123 @@
+package iotcode.EspAlarm;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.*;
+
+public class Alarm_Skeleton implements Alarm {
+
+       private Alarm mainObj;
+       private IoTRMIObject rmiObj;
+
+       private String callbackAddress;
+       private final static int object0Id = 0; //AlarmSmart
+       private static Integer[] object0Permission = { 4, 2, 0, 1, 3 };
+       private static List<Integer> set0Allowed;
+       
+
+       public Alarm_Skeleton(Alarm _mainObj, String _callbackAddress, int _port) throws Exception {
+               mainObj = _mainObj;
+               callbackAddress = _callbackAddress;
+               rmiObj = new IoTRMIObject(_port);
+               set0Allowed = new ArrayList<Integer>(Arrays.asList(object0Permission));
+               ___waitRequestInvokeMethod();
+       }
+
+       public void init() {
+               mainObj.init();
+       }
+
+       public void setZone(int _zone, boolean _onOff, int _onDurationSeconds) {
+               mainObj.setZone(_zone, _onOff, _onDurationSeconds);
+       }
+
+       public List<ZoneState> getZoneStates() {
+               return mainObj.getZoneStates();
+       }
+
+       public int getNumberOfZones() {
+               return mainObj.getNumberOfZones();
+       }
+
+       public boolean doesHaveZoneTimers() {
+               return mainObj.doesHaveZoneTimers();
+       }
+
+       public void ___init() {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               init();
+       }
+
+       public void ___setZone() {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class, boolean.class, int.class }, 
+               new Class<?>[] { null, null, null });
+               setZone((int) paramObj[0], (boolean) paramObj[1], (int) paramObj[2]);
+       }
+
+       public void ___getZoneStates() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               List<ZoneState> retStruct = getZoneStates();
+               int retLen = retStruct.size();
+               Object retLenObj = retLen;
+               rmiObj.sendReturnObj(retLenObj);
+               Class<?>[] retCls = new Class<?>[3*retLen];
+               Object[] retObj = new Object[3*retLen];
+               int retPos = 0;
+               for(int i = 0; i < retLen; i++) {
+                       retCls[retPos] = int.class;
+                       retObj[retPos++] = retStruct.get(i).zoneNumber;
+                       retCls[retPos] = boolean.class;
+                       retObj[retPos++] = retStruct.get(i).onOffState;
+                       retCls[retPos] = int.class;
+                       retObj[retPos++] = retStruct.get(i).duration;
+               }
+               rmiObj.sendReturnObj(retCls, retObj);
+       }
+
+       public void ___getNumberOfZones() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = getNumberOfZones();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___doesHaveZoneTimers() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = doesHaveZoneTimers();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       private void ___waitRequestInvokeMethod() throws IOException {
+               while (true) {
+                       rmiObj.getMethodBytes();
+                       int _objectId = rmiObj.getObjectId();
+                       int methodId = rmiObj.getMethodId();
+                       if (_objectId == object0Id) {
+                               if (!set0Allowed.contains(methodId)) {
+                                       throw new Error("Object with object Id: " + _objectId + "  is not allowed to access method: " + methodId);
+                               }
+                       }
+                       else {
+                               throw new Error("Object Id: " + _objectId + " not recognized!");
+                       }
+                       switch (methodId) {
+                               case 0: ___init(); break;
+                               case 1: ___setZone(); break;
+                               case 2: ___getZoneStates(); break;
+                               case 3: ___getNumberOfZones(); break;
+                               case 4: ___doesHaveZoneTimers(); break;
+                               default: 
+                               throw new Error("Method Id " + methodId + " not recognized!");
+                       }
+               }
+       }
+
+}
diff --git a/benchmarks/drivers/EspAlarm/EspAlarm.config b/benchmarks/drivers/EspAlarm/EspAlarm.config
new file mode 100644 (file)
index 0000000..0912d87
--- /dev/null
@@ -0,0 +1,4 @@
+# Skeleton/original interface
+INTERFACE_CLASS=Alarm
+# Stub
+INTERFACE_STUB_CLASS=AlarmSmart
diff --git a/benchmarks/drivers/EspAlarm/EspAlarm.java b/benchmarks/drivers/EspAlarm/EspAlarm.java
new file mode 100644 (file)
index 0000000..a162ed9
--- /dev/null
@@ -0,0 +1,372 @@
+package iotcode.EspAlarm;
+
+// Standard Java Packages
+import java.io.*;
+import java.net.*;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.security.InvalidParameterException;
+import java.util.Date;
+import java.util.Iterator;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.ArrayList;
+
+// IoT Packages
+import iotruntime.IoTUDP;
+import iotruntime.slave.IoTDeviceAddress;
+import iotruntime.slave.IoTSet;
+import iotcode.interfaces.ZoneState;
+import iotcode.interfaces.Alarm;
+
+//import iotchecker.qual.*;
+import iotcode.annotation.*;
+
+/** Class EspAlarm for the ESP8266 plrg Alarm.
+ *
+ * @author      Ali Younis <ayounis @ uci.edu>, Rahmadi Trimananda <rtrimana @ uci.edu>
+ * @version     1.0
+ * @since       2016-12-21
+ */
+
+public class EspAlarm implements Alarm {
+
+       /*******************************************************************************************************************************************
+       **
+       **  Variables
+       **
+       *******************************************************************************************************************************************/
+
+       private IoTUDP communicationSockect;
+       private Semaphore socketMutex = new Semaphore(1);
+       private AtomicBoolean sendSocketFlag = new AtomicBoolean(false);
+       private AtomicBoolean doingRead = new AtomicBoolean(false);
+       private AtomicBoolean didInit = new AtomicBoolean(false);
+       private Semaphore settingZone = new Semaphore(1);
+
+       /*******************************************************************************************************************************************
+       **
+       **  Threads
+       **
+       *******************************************************************************************************************************************/
+
+       // Main worker thread will do the receive loop
+       Thread workerThread = null;
+
+
+       /*******************************************************************************************************************************************
+       **
+       **  IoT Sets and Relations
+       **
+       *******************************************************************************************************************************************/
+
+       // IoTSet of Device Addresses.
+       // Will be filled with only 1 address.
+       @config private IoTSet<IoTDeviceAddress> alm_Addresses;
+
+       /*public EspSprinkler(IoTUDP _udp) {
+               communicationSockect = _udp;
+       }*/
+
+       public EspAlarm() {
+               communicationSockect = null;
+       }
+
+
+       /*******************************************************************************************************************************************
+       **
+       **  Interface Methods
+       **
+       *******************************************************************************************************************************************/
+
+       /** Method to set the state of a specified zone. Interface implementation.
+        *
+        *   @param _zone [int]             : zone number to set.
+        *   @param _onOff [boolean]        : the state to set the zone to, on or off.
+        *   @param _onDurationSeconds [int]: the duration to set the state on to, if -1 then infinite.
+        *
+        *   @return [void] None.
+        */
+       public void setZone(int _zone, boolean _onOff, int _onDurationSeconds) {
+
+               try {
+                       settingZone.acquire();
+                       String sendString = "SET,";
+                       sendString += Integer.toString(_zone);
+                       sendString += ", ";
+
+                       if (_onOff) {
+                               sendString += "1";
+                       } else {
+                               sendString += "0";
+                       }
+                       sendString += ", ";
+                       sendString += Integer.toString(_onDurationSeconds);
+
+                       sendPacket(sendString.getBytes(StandardCharsets.UTF_8));
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+               settingZone.release();
+       }
+
+
+       /** Method to get the current state of all the zones. Interface implementation.
+        *
+        *   @param None.
+        *
+        *   @return [List<ZoneState>] list of the states for the zones.
+        */
+       public List<ZoneState> getZoneStates() {
+               doingRead.set(true);
+               sendGetInformation();
+
+               try {
+                       Thread.sleep(100);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+               int loopCount = 0;
+               while (true) {
+                       // Communication resource is busy so try again later
+                       if (sendSocketFlag.get()) {
+                               continue;
+                       }
+
+                       try {
+                               socketMutex.acquire();
+                       } catch (InterruptedException e) {
+                       }
+
+                       byte[] dat = null;
+                       try {
+                               dat = communicationSockect.recieveData(1024);
+                       } catch (java.net.SocketTimeoutException e) {
+                               // Timeout occurred
+
+                       } catch (IOException e) {
+                               // Problem but might be able to recover??
+                               e.printStackTrace();
+
+                       }
+
+                       // Never forget to release!
+                       socketMutex.release();
+
+                       // A packed arrived
+                       if (dat != null) {
+                               doingRead.set(false);
+                               return parseGetResponse(dat);
+
+                               // return new ArrayList<ZoneState>();
+                       } else {
+                               try {
+                                       Thread.sleep(100);
+                               } catch (Exception e) {
+                                       e.printStackTrace();
+                               }
+                               loopCount++;
+
+                               if (loopCount > 3) {
+                                       sendGetInformation();
+                                       loopCount = 0;
+                               }
+                       }
+               }
+       }
+
+
+       /** Method to get the number of zones this sprinkler can control. Interface implementation.
+        *
+        *   @param None.
+        *
+        *   @return [int] number of zones that can be controlled.
+        */
+       public int getNumberOfZones() {
+               return 9;
+       }
+
+
+       /** Method to get whether or not this sprinkler can control durations. Interface implementation.
+        *
+        *   @param None.
+        *
+        *   @return [boolean] boolean if this sprinkler can do durations.
+        */
+       public boolean doesHaveZoneTimers() {
+               return true;
+       }
+
+
+       /** Method to initialize the sprinkler. Interface implementation.
+        *
+        *   @param None.
+        *
+        *   @return [void] None.
+        */
+       public void init() {
+
+               if (didInit.compareAndSet(false, true) == false) {
+                       return; // already init
+               }
+
+               try {
+                       Iterator itr = alm_Addresses.iterator();
+                       IoTDeviceAddress deviceAddress = (IoTDeviceAddress)itr.next();
+                       System.out.println("Address: " + deviceAddress.getCompleteAddress());
+
+                       // Create the communication channel
+                       communicationSockect = new IoTUDP(deviceAddress);
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+
+
+               // Launch the worker function in a separate thread.
+               workerThread = new Thread(new Runnable() {
+                       public void run() {
+                               workerFunction();
+                       }
+               });
+               workerThread.start();
+       }
+
+
+       /*******************************************************************************************************************************************
+       **
+       **  Private Handlers
+       **
+       *******************************************************************************************************************************************/
+
+       /** Method to send the get information udp packet to get the latest sprinkler state.
+        *
+        *   @param None.
+        *
+        *   @return [void] None.
+        */
+       public void sendGetInformation() {
+               String sendString = "GET";
+               sendPacket(sendString.getBytes(StandardCharsets.UTF_8));
+       }
+
+
+       /** Method to parse the UDP packet data into a meaningful representation.
+        *
+        *   @param _packetData [byte[]] raw packet data from the udp packet.
+        *
+        *   @return [List<ZoneState>] Parsed zone data.
+        */
+       private List<ZoneState> parseGetResponse(byte[] _packetData) {
+               String recString = new String(_packetData);
+               List<ZoneState> retStates = new ArrayList<ZoneState>();
+
+               String[] lines = recString.split("\n");
+
+               for (int i = 0; i < 9; i++) {
+                       String[] splitSting = lines[i].split(",");
+
+                       int zoneNum = Integer.parseInt(splitSting[0].trim());
+                       int onOffInt = Integer.parseInt(splitSting[1].trim());
+                       boolean onOff = onOffInt != 0;
+                       int duration = Integer.parseInt(splitSting[2].trim());
+
+                       //ZoneState zTmp = new ZoneState(zoneNum, onOff, duration);
+                       ZoneState zTmp = new ZoneState();
+                       zTmp.zoneNumber = zoneNum;
+                       zTmp.onOffState = onOff;
+                       zTmp.duration = duration;
+                       retStates.add(zTmp);
+               }
+
+               return retStates;
+       }
+
+
+       /** Method to parse the UDP packet data into a meaningful representation.
+        *
+        *   @param _packetData [byte[]] bytes to send over the udp channel.
+        *
+        *   @return [void] None.
+        */
+       private void sendPacket(byte[] _packetData) {
+               // System.out.println("About to send");
+               sendSocketFlag.set(true);
+
+               try {
+                       socketMutex.acquire();
+               } catch (InterruptedException e) {
+                       System.out.println("mutex Error");
+               }
+
+               try {
+                       communicationSockect.sendData(_packetData);
+
+               } catch (IOException e) {
+                       System.out.println("Socket Send Error");
+               }
+
+               sendSocketFlag.set(false);
+               socketMutex.release();
+       }
+
+
+       /** Method to constantly flush the udp socket expect when we wish to read the incoming data.
+        *
+        *   @param None.
+        *
+        *   @return [void] None.
+        */
+       private void workerFunction() {
+               try {
+                       // Need timeout on receives since we are not sure if a packet will be available
+                       // for processing so don't block waiting
+                       communicationSockect.setSoTimeout(50);
+               } catch (IOException e) {
+               }
+
+
+
+               while (true) {
+
+                       // Communication resource is busy so try again later
+                       if (sendSocketFlag.get()) {
+                               continue;
+                       }
+
+                       if (doingRead.get()) {
+                               continue;
+                       }
+
+                       try {
+                               socketMutex.acquire();
+                       } catch (InterruptedException e) {
+                       }
+
+                       byte[] dat = null;
+                       try {
+                               dat = communicationSockect.recieveData(1024);
+                       } catch (java.net.SocketTimeoutException e) {
+                               // Timeout occurred
+
+                       } catch (IOException e) {
+                               // Problem but might be able to recover??
+                               e.printStackTrace();
+
+                       }
+
+                       // Never forget to release!
+                       socketMutex.release();
+
+                       // Wait a bit as to not tie up system resources
+                       try {
+                               Thread.sleep(100);
+                       } catch (Exception e) {
+
+                       }
+               }
+       }
+
+}
+
+
diff --git a/benchmarks/drivers/HomeRoom/HomeRoom.config b/benchmarks/drivers/HomeRoom/HomeRoom.config
new file mode 100644 (file)
index 0000000..f10cb63
--- /dev/null
@@ -0,0 +1,4 @@
+# Skeleton/original interface
+INTERFACE_CLASS=Room
+# Stub
+INTERFACE_STUB_CLASS=RoomSmart
diff --git a/benchmarks/drivers/HomeRoom/HomeRoom.java b/benchmarks/drivers/HomeRoom/HomeRoom.java
new file mode 100644 (file)
index 0000000..5a31372
--- /dev/null
@@ -0,0 +1,27 @@
+package iotcode.HomeRoom;
+
+import iotcode.interfaces.Room;
+
+/** AudioRoom holds room ID that tells which room it is
+ *  in association with speakers
+ *
+ * @author      Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @version     1.0                
+ * @since       2016-04-29
+ */
+public class HomeRoom implements Room {
+
+       /**
+        *  AudioRoom class properties
+        */
+       private int iRoomID;
+
+       public HomeRoom(int _iRoomID) {
+               this.iRoomID = _iRoomID;
+               System.out.println("AudioRoom ID: " + this.iRoomID);
+       }
+
+       public int getRoomID() {
+               return this.iRoomID;
+       }
+}
diff --git a/benchmarks/drivers/HomeRoom/Room_Skeleton.java b/benchmarks/drivers/HomeRoom/Room_Skeleton.java
new file mode 100644 (file)
index 0000000..7a02025
--- /dev/null
@@ -0,0 +1,63 @@
+package iotcode.HomeRoom;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.Room;
+
+public class Room_Skeleton implements Room {
+
+       private Room mainObj;
+       private IoTRMIObject rmiObj;
+
+       private String callbackAddress;
+       private final static int object0Id = 0; //RoomSmart
+       private static Integer[] object0Permission = { 0 };
+       private static List<Integer> set0Allowed;
+       
+
+       public Room_Skeleton(Room _mainObj, String _callbackAddress, int _port) throws Exception {
+               mainObj = _mainObj;
+               callbackAddress = _callbackAddress;
+               rmiObj = new IoTRMIObject(_port);
+               set0Allowed = new ArrayList<Integer>(Arrays.asList(object0Permission));
+               ___waitRequestInvokeMethod();
+       }
+
+       public int getRoomID() {
+               return mainObj.getRoomID();
+       }
+
+       public void ___getRoomID() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = getRoomID();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       private void ___waitRequestInvokeMethod() throws IOException {
+               while (true) {
+                       rmiObj.getMethodBytes();
+                       int _objectId = rmiObj.getObjectId();
+                       int methodId = rmiObj.getMethodId();
+                       if (_objectId == object0Id) {
+                               if (!set0Allowed.contains(methodId)) {
+                                       throw new Error("Object with object Id: " + _objectId + "  is not allowed to access method: " + methodId);
+                               }
+                       }
+                       else {
+                               throw new Error("Object Id: " + _objectId + " not recognized!");
+                       }
+                       switch (methodId) {
+                               case 0: ___getRoomID(); break;
+                               default: 
+                               throw new Error("Method Id " + methodId + " not recognized!");
+                       }
+               }
+       }
+
+}
index 08aca6dcf5bb190b65b7e440c78a969408493f5a..46e189daf8794b925516ff0c902533aff6702ab4 100644 (file)
@@ -10,7 +10,7 @@ JFLAGS = -d $(BIN_DIR) -cp $(BIN_DIR):$(PHONEJARS):$(BOOFJARS):$(JLAYERJARS)
 JARFLAGS = cf
 INTFACE_DIR = iotcode/interfaces
 
-all: light camera labroom greenlawn sprinkler moisture weathergateway audioroom gpsgateway ihome
+all: light camera labroom greenlawn sprinkler moisture weathergateway audioroom gpsgateway ihome homeroom alarm motion multipurpose waterleak
 
 # Compile
 #
@@ -74,4 +74,34 @@ ihome:
        cp IHome/IHome.config $(BIN_DIR)/iotcode/IHome
        cd $(BIN_DIR)/iotcode/IHome; $(JAR) $(JARFLAGS) IHome.jar ../../iotcode/IHome/*.class ../../iotcode/interfaces/Speaker*.class
 
+PHONY += homeroom
+homeroom:
+       $(JAVAC) $(JFLAGS) HomeRoom/*.java
+       cp HomeRoom/HomeRoom.config $(BIN_DIR)/iotcode/HomeRoom
+       cd $(BIN_DIR)/iotcode/HomeRoom; $(JAR) $(JARFLAGS) HomeRoom.jar ../../iotcode/HomeRoom/*.class ../../iotcode/interfaces/Room*.class
+
+PHONY += alarm
+alarm:
+       $(JAVAC) $(JFLAGS) EspAlarm/*.java
+       cp EspAlarm/EspAlarm.config $(BIN_DIR)/iotcode/EspAlarm
+       cd $(BIN_DIR)/iotcode/EspAlarm; $(JAR) $(JARFLAGS) EspAlarm.jar ../../iotcode/EspAlarm/*.class ../../iotcode/interfaces/Alarm*.class ../../iotcode/interfaces/ZoneState*.class
+
+PHONY += motion
+motion:
+       $(JAVAC) $(JFLAGS) MotionSensor/*.java
+       cp MotionSensor/MotionSensor.config $(BIN_DIR)/iotcode/MotionSensor
+       cd $(BIN_DIR)/iotcode/MotionSensor; $(JAR) $(JARFLAGS) MotionSensor.jar ../../iotcode/MotionSensor/*.class ../../iotcode/interfaces/SmartthingsSensor*.class ../../iotcode/interfaces/Camera*.class ../../IrrigationController/MotionDetection*.class
+
+PHONY += multipurpose
+multipurpose:
+       $(JAVAC) $(JFLAGS) MultipurposeSensor/*.java
+       cp MultipurposeSensor/MultipurposeSensor.config $(BIN_DIR)/iotcode/MultipurposeSensor
+       cd $(BIN_DIR)/iotcode/MultipurposeSensor; $(JAR) $(JARFLAGS) MultipurposeSensor.jar ../../iotcode/MultipurposeSensor/*.class ../../iotcode/interfaces/SmartthingsSensor*.class ../../iotcode/interfaces/Camera*.class ../../IrrigationController/MotionDetection*.class
+
+PHONY += waterleak
+waterleak:
+       $(JAVAC) $(JFLAGS) WaterLeakSensor/*.java
+       cp MotionSensor/WaterLeakSensor.config $(BIN_DIR)/iotcode/WaterLeakSensor
+       cd $(BIN_DIR)/iotcode/WaterLeakSensor; $(JAR) $(JARFLAGS) WaterLeakSensor.jar ../../iotcode/WaterLeakSensor/*.class ../../iotcode/interfaces/SmartthingsSensor*.class ../../iotcode/interfaces/Camera*.class ../../IrrigationController/MotionDetection*.class
+
 .PHONY: $(PHONY)
diff --git a/benchmarks/drivers/MotionSensor/MotionSensor.config b/benchmarks/drivers/MotionSensor/MotionSensor.config
new file mode 100644 (file)
index 0000000..61eb381
--- /dev/null
@@ -0,0 +1,4 @@
+# Skeleton/original interface
+INTERFACE_CLASS=SmartthingsSensor
+# Stub
+INTERFACE_STUB_CLASS=SmartthingsSensorSmart
diff --git a/benchmarks/drivers/MotionSensor/MotionSensor.java b/benchmarks/drivers/MotionSensor/MotionSensor.java
new file mode 100644 (file)
index 0000000..6520de0
--- /dev/null
@@ -0,0 +1,240 @@
+package iotcode.MotionSensor;
+
+// Standard Java Packages
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Semaphore;
+
+// Checker annotations
+//import iotchecker.qual.*;
+import iotcode.annotation.*;
+
+// IoT Packages
+import iotruntime.slave.*;
+import iotcode.interfaces.*;
+import iotruntime.zigbee.*;
+
+/** Class Smartthings sensor driver for Smartthings sensor devices.
+ *
+ * @author      Changwoo Lee, Rahmadi Trimananda <rtrimana @ uci.edu>
+ * @version     1.0
+ * @since       2016-12-01
+ */
+public class MotionSensor implements IoTZigbeeCallback, SmartthingsSensor {
+
+       private final int TIMEOUT_FOR_RESEND_MSEC = 900;
+
+       private IoTZigbee zigConnection = null;
+       private boolean didClose; // make sure that the clean up was done correctly
+       private boolean detectStatus = false;
+
+       private int detectedValue = 0;
+       private Date timestampOfLastDetecting = null;
+
+       private AtomicBoolean didAlreadyClose = new AtomicBoolean(true);
+       private AtomicBoolean didAlreadyInit = new AtomicBoolean(false);
+       private AtomicBoolean didWriteAttrb = new AtomicBoolean(false);
+       private AtomicBoolean didMatchDscr = new AtomicBoolean(false);
+       static Semaphore gettingLatestDataMutex = new Semaphore(1);
+
+       private List < SmartthingsSensorSmartCallback > callbackList = new CopyOnWriteArrayList < SmartthingsSensorSmartCallback > ();
+
+       private int sensorId = 0;
+
+       @config private IoTSet<IoTDeviceAddress> devUdpAddress;
+       @config private IoTSet<IoTZigbeeAddress> devZigbeeAddress;
+
+       public MotionSensor(IoTSet<IoTDeviceAddress> dSet, IoTSet<IoTZigbeeAddress> zigSet) {
+               //devUdpAddress = dSet;
+               //devZigbeeAddress = zigSet;
+       }
+
+       public void init() {
+
+               if (didAlreadyInit.compareAndSet(false, true) == false) {
+                       return; // already init
+               }
+
+               didAlreadyClose.set(false);
+
+               try {
+                       Iterator itrUdp = devUdpAddress.iterator();
+                       Iterator itrZig = devZigbeeAddress.iterator();
+
+                       zigConnection = new IoTZigbee((IoTDeviceAddress)itrUdp.next(), (IoTZigbeeAddress)itrZig.next());
+
+                       // DEBUG
+                       System.out.println("DEBUG: Allocate iterators to print out addresses!");
+                       Iterator itrDebugUdp = devUdpAddress.iterator();
+                       IoTDeviceAddress iotaddDebug = (IoTDeviceAddress)itrDebugUdp.next();
+                       System.out.println("IP address: " + iotaddDebug.getCompleteAddress());
+                       System.out.println("Source port: " + iotaddDebug.getSourcePortNumber());
+                       System.out.println("Destination port: " + iotaddDebug.getDestinationPortNumber());
+
+                       Iterator itrDebugZig = devZigbeeAddress.iterator();
+                       IoTZigbeeAddress iotzbaddDebug = (IoTZigbeeAddress)itrDebugZig.next();
+                       System.out.println("Zigbee address: " + iotzbaddDebug.getAddress());
+
+                       zigConnection.registerCallback(this);
+                       System.out.println("Register callback!");
+                       zigConnection.init();
+                       System.out.println("Initialized!");
+
+                       //made by changwoo
+                       sleep(10);
+
+                       System.out.println("Sending Management Permit Joining Request");
+                       for(int z=0; z<3; z++){
+                               zigConnection.sendManagementPermitJoiningRequest(0x0001, 0x0036, 0x00);
+                               sleep(0);
+                       }
+                       
+                       //made by changwoo
+                       while (!didWriteAttrb.get()) {
+                               System.out.println("Sending Write Attribute Request");
+                               zigConnection.sendWriteAttributesCommand(0x0002, 0x0500, 0x0104, 0x01);
+                               sleep(0);
+                       }
+
+                       //made by changwoo
+                       System.out.println("Sending Enrollment Reponse");
+                       zigConnection.sendEnrollmentResponse(0x0003, 0x0500, 0x0104, 0x01);
+                       sleep(0);
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       //made by changwoo
+       private void sleep(int multipleTime){
+               if(multipleTime<=0){
+                       multipleTime=1;
+               }
+               try{
+                       Thread.sleep(TIMEOUT_FOR_RESEND_MSEC*multipleTime);
+               } catch(Exception e){
+                       e.printStackTrace();
+               }
+       }
+
+       public void close() {
+
+               if (didAlreadyClose.compareAndSet(false, true) == false) {
+                       return; // already init
+               }
+
+               didAlreadyInit.set(false);
+
+
+               try {
+                       zigConnection.close();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+
+       public void Finalize() {
+               if (!didClose) {
+                       close();
+               }
+       }
+
+       public void setId(int id) {
+
+               sensorId = id;
+
+       }
+
+       public int getId() {
+
+               return sensorId;
+
+       }
+
+       public int getValue() {
+
+               int tmp = 0;
+               try {
+                       gettingLatestDataMutex.acquire();
+                       tmp = detectedValue;
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+               gettingLatestDataMutex.release();
+
+               return tmp;
+       }
+
+       // MotionSensor: 
+       // - 24 = no motion = false
+       // - 26 = motion = true
+       // After getting 26, if there is no motion for ~12 seconds then we get back 24
+       public boolean isActiveValue() {
+
+               int tmp = getValue();
+               if (tmp == 26)
+                       detectStatus = true;
+               else // Getting 24 here
+                       detectStatus = false;
+
+               return detectStatus;
+       }
+
+       public long getTimestampOfLastReading() {
+
+               Date tmp = null;
+               try {
+                       gettingLatestDataMutex.acquire();
+                       tmp = (Date)timestampOfLastDetecting.clone();
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+               gettingLatestDataMutex.release();
+               long retLong = tmp.getTime();
+
+               return retLong;
+       }
+
+       public void newMessageAvailable(IoTZigbeeMessage _zm) {
+
+               //made by changwoo
+               if(_zm instanceof IoTZigbeeMessageZclZoneStatusChangeNotification){
+                       IoTZigbeeMessageZclZoneStatusChangeNotification message = (IoTZigbeeMessageZclZoneStatusChangeNotification)_zm;
+                       if(message.getSuccessOrFail()){
+                               //do something!
+
+                               try {
+                                       gettingLatestDataMutex.acquire();
+                                       detectedValue = message.getStatus();
+                                       timestampOfLastDetecting = new Date();
+                               } catch (Exception e) {
+                                       e.printStackTrace();
+                               }
+                               gettingLatestDataMutex.release();
+                               try {
+                                       for (SmartthingsSensorSmartCallback cb : callbackList) {
+                                               cb.newReadingAvailable(this.getId(), this.getValue(), this.isActiveValue());
+                                       }
+                               } catch (Exception e) {
+                                       e.printStackTrace();
+                               }
+                       }//if
+               
+               //made by changwoo
+               } else if (_zm instanceof IoTZigbeeMessageZclWriteAttributesResponse) {
+                       IoTZigbeeMessageZclWriteAttributesResponse message = (IoTZigbeeMessageZclWriteAttributesResponse)_zm;
+                       if (message.getSuccessOrFail()) {
+                               didWriteAttrb.set(true);
+                       }
+               }
+       }
+
+       public void registerCallback(SmartthingsSensorSmartCallback _callbackTo) {
+               callbackList.add(_callbackTo);
+       }
+}
diff --git a/benchmarks/drivers/MotionSensor/SmartthingsSensorSmartCallback_CallbackStub.java b/benchmarks/drivers/MotionSensor/SmartthingsSensorSmartCallback_CallbackStub.java
new file mode 100644 (file)
index 0000000..037968d
--- /dev/null
@@ -0,0 +1,36 @@
+package iotcode.MotionSensor;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.*;
+
+public class SmartthingsSensorSmartCallback_CallbackStub implements SmartthingsSensorSmartCallback {
+
+       private IoTRMICall rmiCall;
+       private String callbackAddress;
+       private int[] ports;
+
+       private int objectId = 0;
+       
+
+       public SmartthingsSensorSmartCallback_CallbackStub(IoTRMICall _rmiCall, String _callbackAddress, int _objectId, int[] _ports) throws Exception {
+               callbackAddress = _callbackAddress;
+               objectId = _objectId;
+               rmiCall = _rmiCall;
+               ports = _ports;
+       }
+
+       public void newReadingAvailable(int _sensorId, int _value, boolean _activeValue) {
+               int methodId = 0;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] { int.class, int.class, boolean.class };
+               Object[] paramObj = new Object[] { _sensorId, _value, _activeValue };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+}
diff --git a/benchmarks/drivers/MotionSensor/SmartthingsSensor_Skeleton.java b/benchmarks/drivers/MotionSensor/SmartthingsSensor_Skeleton.java
new file mode 100644 (file)
index 0000000..4dc20e1
--- /dev/null
@@ -0,0 +1,151 @@
+package iotcode.MotionSensor;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.*;
+
+public class SmartthingsSensor_Skeleton implements SmartthingsSensor {
+
+       private SmartthingsSensor mainObj;
+       private IoTRMIObject rmiObj;
+
+       private String callbackAddress;
+       private int objIdCnt = 0;
+       private IoTRMICall rmiCall;
+       private int[] ports;
+
+       private final static int object0Id = 0; //SmartthingsSensorSmart
+       private static Integer[] object0Permission = { 3, 2, 5, 6, 1, 4, 0 };
+       private static List<Integer> set0Allowed;
+       
+
+       public SmartthingsSensor_Skeleton(SmartthingsSensor _mainObj, String _callbackAddress, int _port) throws Exception {
+               mainObj = _mainObj;
+               callbackAddress = _callbackAddress;
+               rmiObj = new IoTRMIObject(_port);
+               set0Allowed = new ArrayList<Integer>(Arrays.asList(object0Permission));
+               set0Allowed.add(-9998);
+               ___waitRequestInvokeMethod();
+       }
+
+       public void init() {
+               mainObj.init();
+       }
+
+       public int getValue() {
+               return mainObj.getValue();
+       }
+
+       public boolean isActiveValue() {
+               return mainObj.isActiveValue();
+       }
+
+       public long getTimestampOfLastReading() {
+               return mainObj.getTimestampOfLastReading();
+       }
+
+       public void setId(int id) {
+               mainObj.setId(id);
+       }
+
+       public int getId() {
+               return mainObj.getId();
+       }
+
+       public void registerCallback(SmartthingsSensorSmartCallback _callbackTo) {
+               mainObj.registerCallback(_callbackTo);
+       }
+
+       public void ___regCB() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int[].class, String.class, int.class },new Class<?>[] { null, null, null });
+               ports = (int[]) paramObj[0];
+               rmiCall = new IoTRMICall(ports[0], (String) paramObj[1], (int) paramObj[2]);
+       }
+
+       public void ___init() {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               init();
+       }
+
+       public void ___getValue() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = getValue();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___isActiveValue() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = isActiveValue();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___getTimestampOfLastReading() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = getTimestampOfLastReading();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___setId() {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, 
+               new Class<?>[] { null });
+               setId((int) paramObj[0]);
+       }
+
+       public void ___getId() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = getId();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___registerCallback() {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, 
+               new Class<?>[] { null });
+               try {
+                       SmartthingsSensorSmartCallback stub0 = new SmartthingsSensorSmartCallback_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);
+                       objIdCnt++;
+                       registerCallback(stub0);
+               } catch(Exception ex) {
+                       ex.printStackTrace();
+                       throw new Error("Exception from callback object instantiation!");
+               }
+       }
+
+       private void ___waitRequestInvokeMethod() throws IOException {
+               while (true) {
+                       rmiObj.getMethodBytes();
+                       int _objectId = rmiObj.getObjectId();
+                       int methodId = rmiObj.getMethodId();
+                       if (_objectId == object0Id) {
+                               if (!set0Allowed.contains(methodId)) {
+                                       throw new Error("Object with object Id: " + _objectId + "  is not allowed to access method: " + methodId);
+                               }
+                       }
+                       else {
+                               throw new Error("Object Id: " + _objectId + " not recognized!");
+                       }
+                       switch (methodId) {
+                               case 0: ___init(); break;
+                               case 1: ___getValue(); break;
+                               case 2: ___isActiveValue(); break;
+                               case 3: ___getTimestampOfLastReading(); break;
+                               case 4: ___setId(); break;
+                               case 5: ___getId(); break;
+                               case 6: ___registerCallback(); break;
+                               case -9998: ___regCB(); break;
+                               default: 
+                               throw new Error("Method Id " + methodId + " not recognized!");
+                       }
+               }
+       }
+
+}
diff --git a/benchmarks/drivers/MultipurposeSensor/MultipurposeSensor.config b/benchmarks/drivers/MultipurposeSensor/MultipurposeSensor.config
new file mode 100644 (file)
index 0000000..61eb381
--- /dev/null
@@ -0,0 +1,4 @@
+# Skeleton/original interface
+INTERFACE_CLASS=SmartthingsSensor
+# Stub
+INTERFACE_STUB_CLASS=SmartthingsSensorSmart
diff --git a/benchmarks/drivers/MultipurposeSensor/MultipurposeSensor.java b/benchmarks/drivers/MultipurposeSensor/MultipurposeSensor.java
new file mode 100644 (file)
index 0000000..d2123e3
--- /dev/null
@@ -0,0 +1,237 @@
+package iotcode.MultipurposeSensor;
+
+// Standard Java Packages
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Semaphore;
+
+// Checker annotations
+//import iotchecker.qual.*;
+import iotcode.annotation.*;
+
+// IoT Packages
+import iotruntime.slave.*;
+import iotcode.interfaces.*;
+import iotruntime.zigbee.*;
+
+/** Class Smartthings sensor driver for Smartthings sensor devices.
+ *
+ * @author      Changwoo Lee, Rahmadi Trimananda <rtrimana @ uci.edu>
+ * @version     1.0
+ * @since       2016-12-01
+ */
+public class MultipurposeSensor implements IoTZigbeeCallback, SmartthingsSensor {
+
+       private final int TIMEOUT_FOR_RESEND_MSEC = 900;
+
+       private IoTZigbee zigConnection = null;
+       private boolean didClose; // make sure that the clean up was done correctly
+       private boolean detectStatus = false;
+
+       private int detectedValue = 0;
+       private Date timestampOfLastDetecting = null;
+
+       private AtomicBoolean didAlreadyClose = new AtomicBoolean(true);
+       private AtomicBoolean didAlreadyInit = new AtomicBoolean(false);
+       private AtomicBoolean didWriteAttrb = new AtomicBoolean(false);
+       private AtomicBoolean didMatchDscr = new AtomicBoolean(false);
+       static Semaphore gettingLatestDataMutex = new Semaphore(1);
+
+       private List < SmartthingsSensorSmartCallback > callbackList = new CopyOnWriteArrayList < SmartthingsSensorSmartCallback > ();
+
+       private int sensorId = 0;
+
+       @config private IoTSet<IoTDeviceAddress> devUdpAddress;
+       @config private IoTSet<IoTZigbeeAddress> devZigbeeAddress;
+
+       public MultipurposeSensor(IoTSet<IoTDeviceAddress> dSet, IoTSet<IoTZigbeeAddress> zigSet) {
+               //devUdpAddress = dSet;
+               //devZigbeeAddress = zigSet;
+       }
+
+       public void init() {
+
+               if (didAlreadyInit.compareAndSet(false, true) == false) {
+                       return; // already init
+               }
+
+               didAlreadyClose.set(false);
+
+               try {
+                       Iterator itrUdp = devUdpAddress.iterator();
+                       Iterator itrZig = devZigbeeAddress.iterator();
+
+                       zigConnection = new IoTZigbee((IoTDeviceAddress)itrUdp.next(), (IoTZigbeeAddress)itrZig.next());
+
+                       // DEBUG
+                       System.out.println("DEBUG: Allocate iterators to print out addresses!");
+                       Iterator itrDebugUdp = devUdpAddress.iterator();
+                       IoTDeviceAddress iotaddDebug = (IoTDeviceAddress)itrDebugUdp.next();
+                       System.out.println("IP address: " + iotaddDebug.getCompleteAddress());
+                       System.out.println("Source port: " + iotaddDebug.getSourcePortNumber());
+                       System.out.println("Destination port: " + iotaddDebug.getDestinationPortNumber());
+
+                       Iterator itrDebugZig = devZigbeeAddress.iterator();
+                       IoTZigbeeAddress iotzbaddDebug = (IoTZigbeeAddress)itrDebugZig.next();
+                       System.out.println("Zigbee address: " + iotzbaddDebug.getAddress());
+
+                       zigConnection.registerCallback(this);
+                       System.out.println("Register callback!");
+                       zigConnection.init();
+                       System.out.println("Initialized!");
+
+                       //made by changwoo
+                       sleep(10);
+                       System.out.println("Sending Management Permit Joining Request");
+                       for(int z=0; z<3; z++){
+                               zigConnection.sendManagementPermitJoiningRequest(0x0001, 0x0036, 0x00);
+                               sleep(0);
+                       }
+
+                       //made by changwoo
+                       while (!didWriteAttrb.get()) {
+                               System.out.println("Sending Write Attribute Request");
+                               zigConnection.sendWriteAttributesCommand(0x0002, 0x0500, 0x0104, 0x01);
+                               sleep(0);
+                       }
+
+                       //made by changwoo
+                       System.out.println("Sending Enrollment Reponse");
+                       zigConnection.sendEnrollmentResponse(0x0003, 0x0500, 0x0104, 0x01);
+                       sleep(0);
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       //made by changwoo
+       private void sleep(int multipleTime){
+               if(multipleTime<=0){
+                       multipleTime=1;
+               }
+               try{
+                       Thread.sleep(TIMEOUT_FOR_RESEND_MSEC*multipleTime);
+               } catch(Exception e){
+                       e.printStackTrace();
+               }
+       }
+
+       public void close() {
+
+               if (didAlreadyClose.compareAndSet(false, true) == false) {
+                       return; // already init
+               }
+
+               didAlreadyInit.set(false);
+
+
+               try {
+                       zigConnection.close();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public void Finalize() {
+               if (!didClose) {
+                       close();
+               }
+       }
+
+       public void setId(int id) {
+
+               sensorId = id;
+
+       }
+
+       public int getId() {
+
+               return sensorId;
+
+       }
+
+       public int getValue() {
+
+               int tmp = 0;
+               try {
+                       gettingLatestDataMutex.acquire();
+                       tmp = detectedValue;
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+               gettingLatestDataMutex.release();
+
+               return tmp;
+       }
+
+       // MultipurposeSensor: 
+       // - 24 = close = false
+       // - 25 = open = true
+       public boolean isActiveValue() {
+
+               int tmp = getValue();
+               if (tmp == 25)
+                       detectStatus = true;
+               else // Getting 24 here
+                       detectStatus = false;
+
+               return detectStatus;
+       }
+
+       public long getTimestampOfLastReading() {
+
+               Date tmp = null;
+               try {
+                       gettingLatestDataMutex.acquire();
+                       tmp = (Date)timestampOfLastDetecting.clone();
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+               gettingLatestDataMutex.release();
+               long retLong = tmp.getTime();
+
+               return retLong;
+       }
+
+       public void newMessageAvailable(IoTZigbeeMessage _zm) {
+
+               //made by changwoo
+               if(_zm instanceof IoTZigbeeMessageZclZoneStatusChangeNotification){
+                       IoTZigbeeMessageZclZoneStatusChangeNotification message = (IoTZigbeeMessageZclZoneStatusChangeNotification)_zm;
+                       if(message.getSuccessOrFail()){
+                               //do something!
+                               try {
+                                       gettingLatestDataMutex.acquire();
+                                       detectedValue = message.getStatus();
+                                       timestampOfLastDetecting = new Date();
+                               } catch (Exception e) {
+                                       e.printStackTrace();
+                               }
+                               gettingLatestDataMutex.release();
+                               try {
+                                       for (SmartthingsSensorSmartCallback cb : callbackList) {
+                                               cb.newReadingAvailable(this.getId(), this.getValue(), this.isActiveValue());
+                                       }
+                               } catch (Exception e) {
+                                       e.printStackTrace();
+                               }
+                       }//if
+               
+               //made by changwoo
+               }//if
+               else if (_zm instanceof IoTZigbeeMessageZclWriteAttributesResponse) {
+                       IoTZigbeeMessageZclWriteAttributesResponse message = (IoTZigbeeMessageZclWriteAttributesResponse)_zm;
+                       if (message.getSuccessOrFail()) {
+                               didWriteAttrb.set(true);
+                       }//if
+               }//else if
+       }
+
+       public void registerCallback(SmartthingsSensorSmartCallback _callbackTo) {
+               callbackList.add(_callbackTo);
+       }
+}
diff --git a/benchmarks/drivers/MultipurposeSensor/SmartthingsSensorSmartCallback_CallbackStub.java b/benchmarks/drivers/MultipurposeSensor/SmartthingsSensorSmartCallback_CallbackStub.java
new file mode 100644 (file)
index 0000000..6ed7f31
--- /dev/null
@@ -0,0 +1,36 @@
+package iotcode.MultipurposeSensor;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.*;
+
+public class SmartthingsSensorSmartCallback_CallbackStub implements SmartthingsSensorSmartCallback {
+
+       private IoTRMICall rmiCall;
+       private String callbackAddress;
+       private int[] ports;
+
+       private int objectId = 0;
+       
+
+       public SmartthingsSensorSmartCallback_CallbackStub(IoTRMICall _rmiCall, String _callbackAddress, int _objectId, int[] _ports) throws Exception {
+               callbackAddress = _callbackAddress;
+               objectId = _objectId;
+               rmiCall = _rmiCall;
+               ports = _ports;
+       }
+
+       public void newReadingAvailable(int _sensorId, int _value, boolean _activeValue) {
+               int methodId = 0;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] { int.class, int.class, boolean.class };
+               Object[] paramObj = new Object[] { _sensorId, _value, _activeValue };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+}
diff --git a/benchmarks/drivers/MultipurposeSensor/SmartthingsSensor_Skeleton.java b/benchmarks/drivers/MultipurposeSensor/SmartthingsSensor_Skeleton.java
new file mode 100644 (file)
index 0000000..db2f2d6
--- /dev/null
@@ -0,0 +1,151 @@
+package iotcode.MultipurposeSensor;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.*;
+
+public class SmartthingsSensor_Skeleton implements SmartthingsSensor {
+
+       private SmartthingsSensor mainObj;
+       private IoTRMIObject rmiObj;
+
+       private String callbackAddress;
+       private int objIdCnt = 0;
+       private IoTRMICall rmiCall;
+       private int[] ports;
+
+       private final static int object0Id = 0; //SmartthingsSensorSmart
+       private static Integer[] object0Permission = { 3, 2, 5, 6, 1, 4, 0 };
+       private static List<Integer> set0Allowed;
+       
+
+       public SmartthingsSensor_Skeleton(SmartthingsSensor _mainObj, String _callbackAddress, int _port) throws Exception {
+               mainObj = _mainObj;
+               callbackAddress = _callbackAddress;
+               rmiObj = new IoTRMIObject(_port);
+               set0Allowed = new ArrayList<Integer>(Arrays.asList(object0Permission));
+               set0Allowed.add(-9998);
+               ___waitRequestInvokeMethod();
+       }
+
+       public void init() {
+               mainObj.init();
+       }
+
+       public int getValue() {
+               return mainObj.getValue();
+       }
+
+       public boolean isActiveValue() {
+               return mainObj.isActiveValue();
+       }
+
+       public long getTimestampOfLastReading() {
+               return mainObj.getTimestampOfLastReading();
+       }
+
+       public void setId(int id) {
+               mainObj.setId(id);
+       }
+
+       public int getId() {
+               return mainObj.getId();
+       }
+
+       public void registerCallback(SmartthingsSensorSmartCallback _callbackTo) {
+               mainObj.registerCallback(_callbackTo);
+       }
+
+       public void ___regCB() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int[].class, String.class, int.class },new Class<?>[] { null, null, null });
+               ports = (int[]) paramObj[0];
+               rmiCall = new IoTRMICall(ports[0], (String) paramObj[1], (int) paramObj[2]);
+       }
+
+       public void ___init() {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               init();
+       }
+
+       public void ___getValue() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = getValue();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___isActiveValue() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = isActiveValue();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___getTimestampOfLastReading() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = getTimestampOfLastReading();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___setId() {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, 
+               new Class<?>[] { null });
+               setId((int) paramObj[0]);
+       }
+
+       public void ___getId() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = getId();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___registerCallback() {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, 
+               new Class<?>[] { null });
+               try {
+                       SmartthingsSensorSmartCallback stub0 = new SmartthingsSensorSmartCallback_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);
+                       objIdCnt++;
+                       registerCallback(stub0);
+               } catch(Exception ex) {
+                       ex.printStackTrace();
+                       throw new Error("Exception from callback object instantiation!");
+               }
+       }
+
+       private void ___waitRequestInvokeMethod() throws IOException {
+               while (true) {
+                       rmiObj.getMethodBytes();
+                       int _objectId = rmiObj.getObjectId();
+                       int methodId = rmiObj.getMethodId();
+                       if (_objectId == object0Id) {
+                               if (!set0Allowed.contains(methodId)) {
+                                       throw new Error("Object with object Id: " + _objectId + "  is not allowed to access method: " + methodId);
+                               }
+                       }
+                       else {
+                               throw new Error("Object Id: " + _objectId + " not recognized!");
+                       }
+                       switch (methodId) {
+                               case 0: ___init(); break;
+                               case 1: ___getValue(); break;
+                               case 2: ___isActiveValue(); break;
+                               case 3: ___getTimestampOfLastReading(); break;
+                               case 4: ___setId(); break;
+                               case 5: ___getId(); break;
+                               case 6: ___registerCallback(); break;
+                               case -9998: ___regCB(); break;
+                               default: 
+                               throw new Error("Method Id " + methodId + " not recognized!");
+                       }
+               }
+       }
+
+}
diff --git a/benchmarks/drivers/WaterLeakSensor/SmartthingsSensorSmartCallback_CallbackStub.java b/benchmarks/drivers/WaterLeakSensor/SmartthingsSensorSmartCallback_CallbackStub.java
new file mode 100644 (file)
index 0000000..ac06a99
--- /dev/null
@@ -0,0 +1,36 @@
+package iotcode.WaterLeakSensor;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.*;
+
+public class SmartthingsSensorSmartCallback_CallbackStub implements SmartthingsSensorSmartCallback {
+
+       private IoTRMICall rmiCall;
+       private String callbackAddress;
+       private int[] ports;
+
+       private int objectId = 0;
+       
+
+       public SmartthingsSensorSmartCallback_CallbackStub(IoTRMICall _rmiCall, String _callbackAddress, int _objectId, int[] _ports) throws Exception {
+               callbackAddress = _callbackAddress;
+               objectId = _objectId;
+               rmiCall = _rmiCall;
+               ports = _ports;
+       }
+
+       public void newReadingAvailable(int _sensorId, int _value, boolean _activeValue) {
+               int methodId = 0;
+               Class<?> retType = void.class;
+               Class<?>[] paramCls = new Class<?>[] { int.class, int.class, boolean.class };
+               Object[] paramObj = new Object[] { _sensorId, _value, _activeValue };
+               rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+       }
+
+}
diff --git a/benchmarks/drivers/WaterLeakSensor/SmartthingsSensor_Skeleton.java b/benchmarks/drivers/WaterLeakSensor/SmartthingsSensor_Skeleton.java
new file mode 100644 (file)
index 0000000..e52f126
--- /dev/null
@@ -0,0 +1,151 @@
+package iotcode.WaterLeakSensor;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+import iotrmi.Java.IoTRMICall;
+import iotrmi.Java.IoTRMIObject;
+
+import iotcode.interfaces.*;
+
+public class SmartthingsSensor_Skeleton implements SmartthingsSensor {
+
+       private SmartthingsSensor mainObj;
+       private IoTRMIObject rmiObj;
+
+       private String callbackAddress;
+       private int objIdCnt = 0;
+       private IoTRMICall rmiCall;
+       private int[] ports;
+
+       private final static int object0Id = 0; //SmartthingsSensorSmart
+       private static Integer[] object0Permission = { 3, 2, 5, 6, 1, 4, 0 };
+       private static List<Integer> set0Allowed;
+       
+
+       public SmartthingsSensor_Skeleton(SmartthingsSensor _mainObj, String _callbackAddress, int _port) throws Exception {
+               mainObj = _mainObj;
+               callbackAddress = _callbackAddress;
+               rmiObj = new IoTRMIObject(_port);
+               set0Allowed = new ArrayList<Integer>(Arrays.asList(object0Permission));
+               set0Allowed.add(-9998);
+               ___waitRequestInvokeMethod();
+       }
+
+       public void init() {
+               mainObj.init();
+       }
+
+       public int getValue() {
+               return mainObj.getValue();
+       }
+
+       public boolean isActiveValue() {
+               return mainObj.isActiveValue();
+       }
+
+       public long getTimestampOfLastReading() {
+               return mainObj.getTimestampOfLastReading();
+       }
+
+       public void setId(int id) {
+               mainObj.setId(id);
+       }
+
+       public int getId() {
+               return mainObj.getId();
+       }
+
+       public void registerCallback(SmartthingsSensorSmartCallback _callbackTo) {
+               mainObj.registerCallback(_callbackTo);
+       }
+
+       public void ___regCB() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int[].class, String.class, int.class },new Class<?>[] { null, null, null });
+               ports = (int[]) paramObj[0];
+               rmiCall = new IoTRMICall(ports[0], (String) paramObj[1], (int) paramObj[2]);
+       }
+
+       public void ___init() {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               init();
+       }
+
+       public void ___getValue() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = getValue();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___isActiveValue() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = isActiveValue();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___getTimestampOfLastReading() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = getTimestampOfLastReading();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___setId() {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, 
+               new Class<?>[] { null });
+               setId((int) paramObj[0]);
+       }
+
+       public void ___getId() throws IOException {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] {  }, 
+               new Class<?>[] {  });
+               Object retObj = getId();
+               rmiObj.sendReturnObj(retObj);
+       }
+
+       public void ___registerCallback() {
+               Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class }, 
+               new Class<?>[] { null });
+               try {
+                       SmartthingsSensorSmartCallback stub0 = new SmartthingsSensorSmartCallback_CallbackStub(rmiCall, callbackAddress, objIdCnt, ports);
+                       objIdCnt++;
+                       registerCallback(stub0);
+               } catch(Exception ex) {
+                       ex.printStackTrace();
+                       throw new Error("Exception from callback object instantiation!");
+               }
+       }
+
+       private void ___waitRequestInvokeMethod() throws IOException {
+               while (true) {
+                       rmiObj.getMethodBytes();
+                       int _objectId = rmiObj.getObjectId();
+                       int methodId = rmiObj.getMethodId();
+                       if (_objectId == object0Id) {
+                               if (!set0Allowed.contains(methodId)) {
+                                       throw new Error("Object with object Id: " + _objectId + "  is not allowed to access method: " + methodId);
+                               }
+                       }
+                       else {
+                               throw new Error("Object Id: " + _objectId + " not recognized!");
+                       }
+                       switch (methodId) {
+                               case 0: ___init(); break;
+                               case 1: ___getValue(); break;
+                               case 2: ___isActiveValue(); break;
+                               case 3: ___getTimestampOfLastReading(); break;
+                               case 4: ___setId(); break;
+                               case 5: ___getId(); break;
+                               case 6: ___registerCallback(); break;
+                               case -9998: ___regCB(); break;
+                               default: 
+                               throw new Error("Method Id " + methodId + " not recognized!");
+                       }
+               }
+       }
+
+}
diff --git a/benchmarks/drivers/WaterLeakSensor/WaterLeakSensor.config b/benchmarks/drivers/WaterLeakSensor/WaterLeakSensor.config
new file mode 100644 (file)
index 0000000..61eb381
--- /dev/null
@@ -0,0 +1,4 @@
+# Skeleton/original interface
+INTERFACE_CLASS=SmartthingsSensor
+# Stub
+INTERFACE_STUB_CLASS=SmartthingsSensorSmart
diff --git a/benchmarks/drivers/WaterLeakSensor/WaterLeakSensor.java b/benchmarks/drivers/WaterLeakSensor/WaterLeakSensor.java
new file mode 100644 (file)
index 0000000..ca85856
--- /dev/null
@@ -0,0 +1,238 @@
+package iotcode.WaterLeakSensor;
+
+// Standard Java Packages
+import java.util.*;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Semaphore;
+
+// Checker annotations
+//import iotchecker.qual.*;
+import iotcode.annotation.*;
+
+// IoT Packages
+import iotruntime.slave.*;
+import iotcode.interfaces.*;
+import iotruntime.zigbee.*;
+
+/** Class Smartthings sensor driver for Smartthings sensor devices.
+ *
+ * @author      Changwoo Lee, Rahmadi Trimananda <rtrimana @ uci.edu>
+ * @version     1.0
+ * @since       2016-12-01
+ */
+public class WaterLeakSensor implements IoTZigbeeCallback, SmartthingsSensor {
+
+       private final int TIMEOUT_FOR_RESEND_MSEC = 900;
+
+       private IoTZigbee zigConnection = null;
+       private boolean didClose; // make sure that the clean up was done correctly
+       private boolean detectStatus = false;
+
+       private int detectedValue = 0;
+       private Date timestampOfLastDetecting = null;
+
+       private AtomicBoolean didAlreadyInit = new AtomicBoolean(false);
+       private AtomicBoolean didAlreadyClose = new AtomicBoolean(true);
+       private AtomicBoolean didWriteAttrb = new AtomicBoolean(false);
+       private AtomicBoolean didMatchDscr = new AtomicBoolean(false);
+       static Semaphore gettingLatestDataMutex = new Semaphore(1);
+
+       private List < SmartthingsSensorSmartCallback > callbackList = new CopyOnWriteArrayList < SmartthingsSensorSmartCallback > ();
+
+       private int sensorId = 0;
+
+       @config private IoTSet<IoTDeviceAddress> devUdpAddress;
+       @config private IoTSet<IoTZigbeeAddress> devZigbeeAddress;
+
+       public WaterLeakSensor(IoTSet<IoTDeviceAddress> dSet, IoTSet<IoTZigbeeAddress> zigSet) {
+               //devUdpAddress = dSet;
+               //devZigbeeAddress = zigSet;
+       }
+
+       public void init() {
+
+               if (didAlreadyInit.compareAndSet(false, true) == false) {
+                       return; // already init
+               }
+
+               didAlreadyClose.set(false);
+
+               try {
+                       Iterator itrUdp = devUdpAddress.iterator();
+                       Iterator itrZig = devZigbeeAddress.iterator();
+
+                       zigConnection = new IoTZigbee((IoTDeviceAddress)itrUdp.next(), (IoTZigbeeAddress)itrZig.next());
+
+                       // DEBUG
+                       System.out.println("DEBUG: Allocate iterators to print out addresses!");
+                       Iterator itrDebugUdp = devUdpAddress.iterator();
+                       IoTDeviceAddress iotaddDebug = (IoTDeviceAddress)itrDebugUdp.next();
+                       System.out.println("IP address: " + iotaddDebug.getCompleteAddress());
+                       System.out.println("Source port: " + iotaddDebug.getSourcePortNumber());
+                       System.out.println("Destination port: " + iotaddDebug.getDestinationPortNumber());
+
+                       Iterator itrDebugZig = devZigbeeAddress.iterator();
+                       IoTZigbeeAddress iotzbaddDebug = (IoTZigbeeAddress)itrDebugZig.next();
+                       System.out.println("Zigbee address: " + iotzbaddDebug.getAddress());
+
+                       zigConnection.registerCallback(this);
+                       System.out.println("Register callback!");
+                       zigConnection.init();
+                       System.out.println("Initialized!");
+
+                       //made by changwoo
+                       sleep(10);
+                       System.out.println("Sending Management Permit Joining Request");
+                       for(int z=0; z<3; z++){
+                               zigConnection.sendManagementPermitJoiningRequest(0x0001, 0x0036, 0x00);
+                               sleep(0);
+                       }
+
+                       //made by changwoo
+                       while (!didWriteAttrb.get()) {
+                               System.out.println("Sending Write Attribute Request");
+                               zigConnection.sendWriteAttributesCommand(0x0002, 0x0500, 0x0104, 0x01);
+                               sleep(0);
+                       }
+
+                       //made by changwoo
+                       System.out.println("Sending Enrollment Reponse");
+                       zigConnection.sendEnrollmentResponse(0x0003, 0x0500, 0x0104, 0x01);
+                       sleep(0);
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       //made by changwoo
+       private void sleep(int multipleTime){
+               if(multipleTime<=0){
+                       multipleTime=1;
+               }
+               try{
+                       Thread.sleep(TIMEOUT_FOR_RESEND_MSEC*multipleTime);
+               } catch(Exception e){
+                       e.printStackTrace();
+               }
+       }
+
+       public void close() {
+
+               if (didAlreadyClose.compareAndSet(false, true) == false) {
+                       return; // already init
+               }
+
+               didAlreadyInit.set(false);
+
+
+               try {
+                       zigConnection.close();
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public void Finalize() {
+               if (!didClose) {
+                       close();
+               }
+       }
+
+       public void setId(int id) {
+
+               sensorId = id;
+
+       }
+
+       public int getId() {
+
+               return sensorId;
+
+       }
+
+       public int getValue() {
+
+               int tmp = 0;
+               try {
+                       gettingLatestDataMutex.acquire();
+                       tmp = detectedValue;
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+               gettingLatestDataMutex.release();
+
+               return tmp;
+       }
+
+       // WaterLeakSensor: 
+       // - 24 = no leak = false
+       // - 25 = leak = true
+       public boolean isActiveValue() {
+
+               int tmp = getValue();
+               if (tmp == 25)
+                       detectStatus = true;
+               else // Getting 24 here
+                       detectStatus = false;
+
+               return detectStatus;
+       }
+
+       public long getTimestampOfLastReading() {
+
+               Date tmp = null;
+               try {
+                       gettingLatestDataMutex.acquire();
+                       tmp = (Date)timestampOfLastDetecting.clone();
+
+               } catch (Exception e) {
+                       e.printStackTrace();
+               }
+               gettingLatestDataMutex.release();
+               long retLong = tmp.getTime();
+
+               return retLong;
+       }
+
+       public void newMessageAvailable(IoTZigbeeMessage _zm) {
+
+               //made by changwoo
+               if(_zm instanceof IoTZigbeeMessageZclZoneStatusChangeNotification){
+                       IoTZigbeeMessageZclZoneStatusChangeNotification message = (IoTZigbeeMessageZclZoneStatusChangeNotification)_zm;
+                       if(message.getSuccessOrFail()){
+                               //do something!
+
+                               try {
+                                       gettingLatestDataMutex.acquire();
+                                       detectedValue = message.getStatus();
+                                       timestampOfLastDetecting = new Date();
+                               } catch (Exception e) {
+                                       e.printStackTrace();
+                               }
+                               gettingLatestDataMutex.release();
+                               try {
+                                       for (SmartthingsSensorSmartCallback cb : callbackList) {
+                                               cb.newReadingAvailable(this.getId(), this.getValue(), this.isActiveValue());
+                                       }
+                               } catch (Exception e) {
+                                       e.printStackTrace();
+                               }
+                       }//if
+               
+               //made by changwoo
+               }//if
+               else if (_zm instanceof IoTZigbeeMessageZclWriteAttributesResponse) {
+                       IoTZigbeeMessageZclWriteAttributesResponse message = (IoTZigbeeMessageZclWriteAttributesResponse)_zm;
+                       if (message.getSuccessOrFail()) {
+                               didWriteAttrb.set(true);
+                       }//if
+               }//else if
+       }
+
+       public void registerCallback(SmartthingsSensorSmartCallback _callbackTo) {
+               callbackList.add(_callbackTo);
+       }
+}
diff --git a/benchmarks/interfaces/Alarm.java b/benchmarks/interfaces/Alarm.java
new file mode 100644 (file)
index 0000000..ab55c2b
--- /dev/null
@@ -0,0 +1,12 @@
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface Alarm {
+       public void init();
+       public void setZone(int _zone, boolean _onOff, int _onDurationSeconds);
+       public List<ZoneState> getZoneStates();
+       public int getNumberOfZones();
+       public boolean doesHaveZoneTimers();
+}
diff --git a/benchmarks/interfaces/AlarmSmart.java b/benchmarks/interfaces/AlarmSmart.java
new file mode 100644 (file)
index 0000000..103e29a
--- /dev/null
@@ -0,0 +1,13 @@
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface AlarmSmart {
+
+       public boolean doesHaveZoneTimers();
+       public List<ZoneState> getZoneStates();
+       public void init();
+       public void setZone(int _zone, boolean _onOff, int _onDurationSeconds);
+       public int getNumberOfZones();
+}
diff --git a/benchmarks/interfaces/SmartthingsSensor.java b/benchmarks/interfaces/SmartthingsSensor.java
new file mode 100644 (file)
index 0000000..a951a6c
--- /dev/null
@@ -0,0 +1,14 @@
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface SmartthingsSensor {
+       public void init();
+       public int getValue();
+       public boolean isActiveValue();
+       public long getTimestampOfLastReading();
+       public void setId(int id);
+       public int getId();
+       public void registerCallback(SmartthingsSensorSmartCallback _callbackTo);
+}
diff --git a/benchmarks/interfaces/SmartthingsSensorCallback.java b/benchmarks/interfaces/SmartthingsSensorCallback.java
new file mode 100644 (file)
index 0000000..853dd12
--- /dev/null
@@ -0,0 +1,8 @@
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface SmartthingsSensorCallback {
+       public void newReadingAvailable(int _sensorId, int _value, boolean _activeValue);
+}
diff --git a/benchmarks/interfaces/SmartthingsSensorSmart.java b/benchmarks/interfaces/SmartthingsSensorSmart.java
new file mode 100644 (file)
index 0000000..2c70dbf
--- /dev/null
@@ -0,0 +1,15 @@
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface SmartthingsSensorSmart {
+
+       public long getTimestampOfLastReading();
+       public boolean isActiveValue();
+       public int getId();
+       public void registerCallback(SmartthingsSensorCallback _callbackTo);
+       public int getValue();
+       public void setId(int id);
+       public void init();
+}
diff --git a/benchmarks/interfaces/SmartthingsSensorSmartCallback.java b/benchmarks/interfaces/SmartthingsSensorSmartCallback.java
new file mode 100644 (file)
index 0000000..314d583
--- /dev/null
@@ -0,0 +1,9 @@
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface SmartthingsSensorSmartCallback {
+
+       public void newReadingAvailable(int _sensorId, int _value, boolean _activeValue);
+}
index 2ad54902649989ef9edb738db55908049b70d52a..68dfe29d9def4914971e7842d4257a9c4415a0e5 100644 (file)
@@ -38,6 +38,8 @@ public class MotionSensor implements IoTZigbeeCallback, SmartthingsSensor {
 
        private List < SmartthingsSensorCallback > callbackList = new CopyOnWriteArrayList < SmartthingsSensorCallback > ();
 
+       private int sensorId = 0;
+
        @config private IoTSet<IoTDeviceAddress> devUdpAddress;
        @config private IoTSet<IoTZigbeeAddress> devZigbeeAddress;
 
@@ -138,6 +140,18 @@ public class MotionSensor implements IoTZigbeeCallback, SmartthingsSensor {
                }
        }
 
+       public void setId(int id) {
+
+               sensorId = id;
+
+       }
+
+       public int getId() {
+
+               return sensorId;
+
+       }
+
        public int getValue() {
 
                int tmp = 0;
@@ -202,7 +216,7 @@ public class MotionSensor implements IoTZigbeeCallback, SmartthingsSensor {
                                gettingLatestDataMutex.release();
                                try {
                                        for (SmartthingsSensorCallback cb : callbackList) {
-                                               cb.newReadingAvailable(this.getValue(), this.isActiveValue());
+                                               cb.newReadingAvailable(this.getId(), this.getValue(), this.isActiveValue());
                                        }
                                } catch (Exception e) {
                                        e.printStackTrace();
index a21155fcd3e8423361efe013a16320b54dddb5f2..0243091ededf3cabdbf26eed52bd406ed1ae7e8e 100644 (file)
@@ -38,6 +38,8 @@ public class MultipurposeSensor implements IoTZigbeeCallback, SmartthingsSensor
 
        private List < SmartthingsSensorCallback > callbackList = new CopyOnWriteArrayList < SmartthingsSensorCallback > ();
 
+       private int sensorId = 0;
+
        @config private IoTSet<IoTDeviceAddress> devUdpAddress;
        @config private IoTSet<IoTZigbeeAddress> devZigbeeAddress;
 
@@ -136,6 +138,18 @@ public class MultipurposeSensor implements IoTZigbeeCallback, SmartthingsSensor
                }
        }
 
+       public void setId(int id) {
+
+               sensorId = id;
+
+       }
+
+       public int getId() {
+
+               return sensorId;
+
+       }
+
        public int getValue() {
 
                int tmp = 0;
@@ -198,7 +212,7 @@ public class MultipurposeSensor implements IoTZigbeeCallback, SmartthingsSensor
                                gettingLatestDataMutex.release();
                                try {
                                        for (SmartthingsSensorCallback cb : callbackList) {
-                                               cb.newReadingAvailable(this.getValue(), this.isActiveValue());
+                                               cb.newReadingAvailable(this.getId(), this.getValue(), this.isActiveValue());
                                        }
                                } catch (Exception e) {
                                        e.printStackTrace();
index d739f1922338dbe63d41a5070a84cb4afa9290de..aba8819e76d97c22f3970120981d1e844d3d229f 100644 (file)
@@ -46,6 +46,9 @@ public interface SmartthingsSensor extends Remote {
         */
        public void init() throws RemoteException;
 
+       public void setId(int id);
+
+       public int getId();
 
        /** Register an object to retrieve callbacks when new sensor reading is available
         *
index 2367da172a00de96f781d74136117f9fb7b3cf91..5342538bcb3493c66b4ae21ac6eaf74600b8ebb1 100644 (file)
@@ -11,6 +11,5 @@
 
 public interface SmartthingsSensorCallback {
 
-       //public void newReadingAvailable(@NonLocalRemote SmartthingsSensor _sensor) throws RemoteException;
-       public void newReadingAvailable(int _value, boolean _activeValue);
+       public void newReadingAvailable(int _sensorId, int _value, boolean _activeValue);
 }
index 75923a44171b1241165ee8252565c92ee8c5b115..8a56aabf035be5a9bd8e24cdfb04dfb3f4511bc0 100644 (file)
@@ -41,6 +41,8 @@ public class WaterLeakSensor implements IoTZigbeeCallback, SmartthingsSensor {
        @config private IoTSet<IoTDeviceAddress> devUdpAddress;
        @config private IoTSet<IoTZigbeeAddress> devZigbeeAddress;
 
+       private int sensorId = 0;
+
        public WaterLeakSensor(IoTSet<IoTDeviceAddress> dSet, IoTSet<IoTZigbeeAddress> zigSet) {
                devUdpAddress = dSet;
                devZigbeeAddress = zigSet;
@@ -136,6 +138,18 @@ public class WaterLeakSensor implements IoTZigbeeCallback, SmartthingsSensor {
                }
        }
 
+       public void setId(int id) {
+
+               sensorId = id;
+
+       }
+
+       public int getId() {
+
+               return sensorId;
+
+       }
+
        public int getValue() {
 
                int tmp = 0;
@@ -199,7 +213,7 @@ public class WaterLeakSensor implements IoTZigbeeCallback, SmartthingsSensor {
                                gettingLatestDataMutex.release();
                                try {
                                        for (SmartthingsSensorCallback cb : callbackList) {
-                                               cb.newReadingAvailable(this.getValue(), this.isActiveValue());
+                                               cb.newReadingAvailable(this.getId(), this.getValue(), this.isActiveValue());
                                        }
                                } catch (Exception e) {
                                        e.printStackTrace();
index 832e0be3442b2604728f78c5fd64884705e6a55b..7dde4b15effb7faae56bf2de2c2b3cf30f63dfc5 100644 (file)
@@ -17,7 +17,7 @@ public class ZigbeeTest_motion implements SmartthingsSensorCallback {
 
 //000d6f000bbd5398
 //000d6f00057c92a7
-    public void newReadingAvailable(int _value, boolean _activeValue) {
+    public void newReadingAvailable(int _sensorId, int _value, boolean _activeValue) {
         System.out.println("New Message!!!!");
         System.out.println("motion : "+ _value);
         System.out.println("active? : "+ _activeValue);
index 8265f6b65d80bfefe00652dc233b8772afbe5452..bec2d37535849906c7a7434d532c885b8bd17789 100644 (file)
@@ -15,7 +15,7 @@ public class ZigbeeTest_multipurpose implements SmartthingsSensorCallback {
        private static final String MY_IP_ADDRESS = "192.168.2.108";
        public static final String DEVIDE_MAC_ADDRESS = "000d6f000bbd3413"; //Multipurpose sensor
 
-    public void newReadingAvailable(int _value, boolean _activeValue) {
+    public void newReadingAvailable(int _sensorId, int _value, boolean _activeValue) {
         System.out.println("New Message!!!!");
         System.out.println("multipurpose : "+ _value);
         System.out.println("active? : "+ _activeValue);
index 856fe20bc80041d58ff4678dc878c36d58fed55e..506429092a1d0c13b9e4a7c55153215fc88dcb52 100644 (file)
@@ -16,7 +16,7 @@ public class ZigbeeTest_waterleak implements SmartthingsSensorCallback {
     private static final int PORT_NUMBER = 5959;
     public static final String DEVIDE_MAC_ADDRESS = "000d6f000ada75e3"; //water leak
 
-    public void newReadingAvailable(int _value, boolean _activeValue) {
+    public void newReadingAvailable(int _sensorId, int _value, boolean _activeValue) {
         System.out.println("New Message!!!!");
         System.out.println("water leak : "+ _value);
         System.out.println("active? : "+ _activeValue);
index a0a67f19288bc734f579982cb4cb19988b92d21d..9a5fb1f2f05177c4a0ca13d0f0020f9cf03f94aa 100644 (file)
@@ -41,9 +41,9 @@ run-compiler-lifx:
 
 PHONY += run-compiler-room
 run-compiler-room:
-       cp ../localconfig/iotpolicy/LabRoom/*.pol $(BIN_DIR)/iotpolicy/
-       cp ../localconfig/iotpolicy/LabRoom/*.req $(BIN_DIR)/iotpolicy/
-       cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler labroom.pol roomsmart.req -java Java
+       cp ../localconfig/iotpolicy/Room/*.pol $(BIN_DIR)/iotpolicy/
+       cp ../localconfig/iotpolicy/Room/*.req $(BIN_DIR)/iotpolicy/
+       cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler room.pol roomsmart.req -java Java
 
 PHONY += run-compiler-cam
 run-compiler-cam:
@@ -77,12 +77,6 @@ run-compiler-moist:
        cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler sprucesensor.pol smartsensor.req moisturesensorcallback.pol moisturesensorcallback.req -java Java
 
 # SpeakerController
-PHONY += run-compiler-audiorm
-run-compiler-audiorm:
-       cp ../localconfig/iotpolicy/AudioRoom/*.pol $(BIN_DIR)/iotpolicy/
-       cp ../localconfig/iotpolicy/AudioRoom/*.req $(BIN_DIR)/iotpolicy/
-       cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler audioroom.pol roomsmart.req -java Java
-
 PHONY += run-compiler-spkr
 run-compiler-spkr:
        cp ../localconfig/iotpolicy/IHome/*.pol $(BIN_DIR)/iotpolicy/
@@ -95,6 +89,19 @@ run-compiler-ggw:
        cp ../localconfig/iotpolicy/GPSPhoneGateway/*.req $(BIN_DIR)/iotpolicy/
        cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler gpsphonegateway.pol smartgpsgateway.req gpsgatewaycallback.pol smartgpsgatewaycallback.req -java Java
 
+# HomeSecurityController
+PHONY += run-compiler-alarm
+run-compiler-alarm:
+       cp ../localconfig/iotpolicy/EspAlarm/*.pol $(BIN_DIR)/iotpolicy/
+       cp ../localconfig/iotpolicy/EspAlarm/*.req $(BIN_DIR)/iotpolicy/
+       cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler espalarm.pol smartalarm.req -java Java
+
+PHONY += run-compiler-smart
+run-compiler-smart:
+       cp ../localconfig/iotpolicy/SmartthingsSensor/*.pol $(BIN_DIR)/iotpolicy/
+       cp ../localconfig/iotpolicy/SmartthingsSensor/*.req $(BIN_DIR)/iotpolicy/
+       cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler smartthingssensor.pol smartthingssensor.req smartthingssensorcallback.pol smartthingssensorcallback.req -java Java
+
 # TODO: Can remove this later - just to test-compile the resulted files from the compiler
 PHONY += compile
 compile:
diff --git a/localconfig/iotpolicy/AudioRoom/audioroom.pol b/localconfig/iotpolicy/AudioRoom/audioroom.pol
deleted file mode 100644 (file)
index 17f3bbd..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-public interface Room {
-
-       public int getRoomID();
-
-       capability Basic {
-               description = "Get room ID";
-               method = "getRoomID()";
-       }
-}
-
-
diff --git a/localconfig/iotpolicy/AudioRoom/roomsmart.req b/localconfig/iotpolicy/AudioRoom/roomsmart.req
deleted file mode 100644 (file)
index 71de3c9..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-
-requires Room with Basic as interface RoomSmart;
-
diff --git a/localconfig/iotpolicy/EspAlarm/espalarm.pol b/localconfig/iotpolicy/EspAlarm/espalarm.pol
new file mode 100644 (file)
index 0000000..ce7742f
--- /dev/null
@@ -0,0 +1,29 @@
+public interface Alarm {
+
+       public void init();
+       public void setZone(int _zone, boolean _onOff, int _onDurationSeconds);
+       public List<ZoneState> getZoneStates();
+       public int getNumberOfZones();
+       public boolean doesHaveZoneTimers();
+
+       capability Initialize {
+               description = "Initialize object";
+               method = "init()";
+       }
+
+       capability Zone {
+               description = "Manage zones";
+               method = "setZone(int _zone, boolean _onOff, int _onDurationSeconds)";
+               method = "getZoneStates()";
+               method = "getNumberOfZones()";
+               method = "doesHaveZoneTimers()";
+       }
+
+       struct ZoneState {
+               int zoneNumber;
+               boolean onOffState;
+               int duration;
+       }
+}
+
+
diff --git a/localconfig/iotpolicy/EspAlarm/smartalarm.req b/localconfig/iotpolicy/EspAlarm/smartalarm.req
new file mode 100644 (file)
index 0000000..f703a43
--- /dev/null
@@ -0,0 +1,3 @@
+
+requires Alarm with Initialize, Zone as interface AlarmSmart;
+
diff --git a/localconfig/iotpolicy/LabRoom/labroom.pol b/localconfig/iotpolicy/LabRoom/labroom.pol
deleted file mode 100644 (file)
index 17f3bbd..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-public interface Room {
-
-       public int getRoomID();
-
-       capability Basic {
-               description = "Get room ID";
-               method = "getRoomID()";
-       }
-}
-
-
diff --git a/localconfig/iotpolicy/LabRoom/roomsmart.req b/localconfig/iotpolicy/LabRoom/roomsmart.req
deleted file mode 100644 (file)
index 71de3c9..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-
-requires Room with Basic as interface RoomSmart;
-
diff --git a/localconfig/iotpolicy/Room/room.pol b/localconfig/iotpolicy/Room/room.pol
new file mode 100644 (file)
index 0000000..17f3bbd
--- /dev/null
@@ -0,0 +1,11 @@
+public interface Room {
+
+       public int getRoomID();
+
+       capability Basic {
+               description = "Get room ID";
+               method = "getRoomID()";
+       }
+}
+
+
diff --git a/localconfig/iotpolicy/Room/roomsmart.req b/localconfig/iotpolicy/Room/roomsmart.req
new file mode 100644 (file)
index 0000000..71de3c9
--- /dev/null
@@ -0,0 +1,3 @@
+
+requires Room with Basic as interface RoomSmart;
+
diff --git a/localconfig/iotpolicy/SmartthingsSensor/smartthingssensor.pol b/localconfig/iotpolicy/SmartthingsSensor/smartthingssensor.pol
new file mode 100644 (file)
index 0000000..de3686a
--- /dev/null
@@ -0,0 +1,31 @@
+public interface SmartthingsSensor {
+
+       public void init();
+       public int getValue();
+       public boolean isActiveValue();
+       public long getTimestampOfLastReading();
+       public void setId(int id);
+       public int getId();
+       public void registerCallback(SmartthingsSensorCallback _callbackTo);
+
+       capability Initialize {
+               description = "Initialize object";
+               method = "init()";
+               method = "registerCallback(SmartthingsSensorCallback _callbackTo)";
+       }
+
+       capability Value {
+               description = "Handle value";
+               method = "getValue()";
+               method = "isActiveValue()";
+               method = "getTimestampOfLastReading()";
+       }
+
+       capability SensorId {
+               description = "Manage sensor Id";
+               method = "setId(int id)";
+               method = "getId()";
+       }
+}
+
+
diff --git a/localconfig/iotpolicy/SmartthingsSensor/smartthingssensor.req b/localconfig/iotpolicy/SmartthingsSensor/smartthingssensor.req
new file mode 100644 (file)
index 0000000..8d80d3d
--- /dev/null
@@ -0,0 +1,3 @@
+
+requires SmartthingsSensor with Initialize, Value, SensorId as interface SmartthingsSensorSmart;
+
diff --git a/localconfig/iotpolicy/SmartthingsSensor/smartthingssensorcallback.pol b/localconfig/iotpolicy/SmartthingsSensor/smartthingssensorcallback.pol
new file mode 100644 (file)
index 0000000..0bb4b58
--- /dev/null
@@ -0,0 +1,11 @@
+public interface SmartthingsSensorCallback {
+
+       public void newReadingAvailable(int _sensorId, int _value, boolean _activeValue);
+
+       capability Callback {
+               description = "Callback method";
+               method = "newReadingAvailable(int _sensorId, int _value, boolean _activeValue)";
+       }
+}
+
+
diff --git a/localconfig/iotpolicy/SmartthingsSensor/smartthingssensorcallback.req b/localconfig/iotpolicy/SmartthingsSensor/smartthingssensorcallback.req
new file mode 100644 (file)
index 0000000..87fbe69
--- /dev/null
@@ -0,0 +1,3 @@
+
+requires SmartthingsSensorCallback with Callback as interface SmartthingsSensorSmartCallback;
+
index 32978153fcfb8aff074b59293882269d9c318757..8b82643235abc1e4da2960d876724a214bca1efb 100644 (file)
@@ -3,4 +3,6 @@ FIRST
 Room
 OTHER
 Camera
+WHERE
+TYPE_SOURCE LIKE 'HomeRoom%' 
 ;
index a0852123913162a9f122de1829321a9cd95c99bd..6f5dc607b45eb598b92dfdb09892d5277ea5cf73 100644 (file)
@@ -1,5 +1,5 @@
 SELECT * FROM
 Room
 WHERE
-TYPE='LabRoom'
+TYPE='HomeRoom'
 ;
index 4ae5fee5b2bebd3f7f9b28552470c499fd5dd966..0c9918cbd035331e598ac8cf61d242efc79c8881 100644 (file)
Binary files a/others/Mysql/IoTMain.gz and b/others/Mysql/IoTMain.gz differ