import iotruntime.slave.IoTSet;
import iotruntime.slave.IoTRelation;
import iotruntime.slave.IoTAddress;
-//import iotcode.annotation.*;
+import iotcode.annotation.*;
// IoT Driver Packages
import iotcode.interfaces.*;
import iotcode.WeatherPhoneGateway.*;
-// Checker annotations
-import iotchecker.qual.*;
-
public class IrrigationController extends UnicastRemoteObject implements WeatherGatewayCallback {
private Date hibernationRecoveryModeStartDate = null;
private boolean isHibernationMode = false;
private Date hibernationModeStartDate = null;
- private List<@LocalRemote LawnState> lawns = new ArrayList<@LocalRemote LawnState>();
+ private List<LawnState> lawns = new ArrayList<LawnState>();
private WeatherGrabber weatherGrabber = null;
// used to block until gui is done and the settings are ready to be polled
private int daysToWaterOn = 0;
private List<Double> inchesPerMinute;
+ private static int sensorId = 0;
/*******************************************************************************************************************************************
**
*******************************************************************************************************************************************/
@config private IoTSet<IoTAddress> weatherDataAddresses;
@config private IoTSet<IoTAddress> weatherDataAddressMain;
- @config private IoTSet<@NonLocalRemote WeatherGateway> gwSet;
- @config private IoTSet<@NonLocalRemote Lawn> lawnSet;
- @config private IoTSet<@NonLocalRemote MoistureSensor> moistureSensorsSet;
- @config private IoTSet<@NonLocalRemote Camera> cameraSet;
- @config private IoTRelation<@NonLocalRemote Lawn, @NonLocalRemote Camera> lawnCameraRelation;
- @config private IoTRelation<@NonLocalRemote Lawn, @NonLocalRemote Sprinkler> lawnSprinklerRelation;
- @config private IoTRelation<@NonLocalRemote Lawn, @NonLocalRemote MoistureSensor> lawnMoistureSensorRelation;
+ @config private IoTSet<WeatherGatewaySmart> gwSet;
+ @config private IoTSet<LawnSmart> lawnSet;
+ @config private IoTSet<MoistureSensorSmart> moistureSensorsSet;
+ @config private IoTSet<CameraSmart> cameraSet;
+ @config private IoTRelation<LawnSmart, CameraSmart> lawnCameraRelation;
+ @config private IoTRelation<LawnSmart, SprinklerSmart> lawnSprinklerRelation;
+ @config private IoTRelation<LawnSmart, MoistureSensorSmart> lawnMoistureSensorRelation;
public IrrigationController() throws RemoteException {
monthOfLastCheck = currentDate.getMonth();
// update the lawn states everyday
- for (@LocalRemote LawnState ls : lawns) {
+ for (LawnState ls : lawns) {
ls.updateLawn(currentDate);
}
// check if we are in hibernation mode and do the correct loop action
/** Callback method for when the information is retrieved.
*
- * @param _wgw [WeatherGateway].
+ * @param _inchesPerWeek [double].
+ * @param _weatherZipCode [int].
+ * @param _daysToWaterOn [int].
+ * @param _inchesPerMinute [double].
* @return [void] None.
*/
- public void informationRetrieved(@NonLocalRemote WeatherGateway _wgw) {
+ public void informationRetrieved(double _inchesPerWeek, int _weatherZipCode, int _daysToWaterOn, double _inchesPerMinute) {
-// System.out.println("DEBUG: Information is retrieved from phone!!!");
- try {
+ System.out.println("DEBUG: Information is retrieved from phone!!!");
+ /*try {
// get the parameters that the interface (phone app) reads from the user
inchesPerWeek = _wgw.getInchesPerWeek();
weatherZipCode = _wgw.getWeatherZipCode();
inchesPerMinute.add(_wgw.getInchesPerMinute());
} catch(RemoteException ex) {
ex.printStackTrace();
- }
+ }*/
+
+ inchesPerWeek = _inchesPerWeek;
+ weatherZipCode = _weatherZipCode;
+ daysToWaterOn = _daysToWaterOn;
+ inchesPerMinute.add(_inchesPerMinute);
// the gui is done so release the spin wait that was waiting for the gui
waitingForInterface.set(false);
inchesPerMinute = new ArrayList<Double>();
// We setup a Gateway object to get information from the phone app
- for (@NonLocalRemote WeatherGateway gw : gwSet.values()) {
+ for (WeatherGatewaySmart gw : gwSet.values()) {
gw.init();
gw.registerCallback(this);
gw.start();
weatherGrabber.setNumberOfDays(16);
// Setup the cameras, start them all and assign each one a motion detector
- for (@NonLocalRemote Camera cam : cameraSet.values()) {
- try {
+ for (CameraSmart cam : cameraSet.values()) {
+ //try {
// initialize the camera, might need to setup some stuff internally
cam.init();
// set the camera parameters.
cam.setFPS(CAMERA_FPS);
- cam.setResolution(Camera.Resolution.RES_VGA);
+ cam.setResolution(Resolution.RES_VGA);
// Start the camera (example is start the HTTP stream if it is a network camera)
cam.start();
System.out.println("DEBUG: Init camera! " + cam.toString());
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ //} catch (RemoteException e) {
+ // e.printStackTrace();
+ //}
}
// counter so that we can match the lawn inches per min data with the specific lawn
int counter = 0;
- for (@NonLocalRemote Lawn l : lawnSet.values()) {
+ for (LawnSmart l : lawnSet.values()) {
// create a motionDetector for each lawn object
- @LocalRemote MotionDetection mo = new @LocalRemote MotionDetection(12, 0.5f, 10, 10);
+ MotionDetection mo = new MotionDetection(12, 0.5f, 10, 10);
// for 1 camera, if there are any then register the camera for that lawn
- HashSet<@NonLocalRemote Camera> cameras = lawnCameraRelation.get(l);
+ HashSet<CameraSmart> cameras = lawnCameraRelation.get(l);
System.out.println("DEBUG: Camera.size(): " + cameras.size());
if (cameras.size() >= 1) {
// we only need 1 camera per lawn so get the first one in the list
Iterator camIt = cameras.iterator();
- @NonLocalRemote Camera cam = (@NonLocalRemote Camera)camIt.next();
+ CameraSmart cam = (CameraSmart)camIt.next();
System.out.println("DEBUG: Registering callback to camera: " + cam.toString());
- try {
+ //try {
// setup the callback
cam.registerCallback(mo);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ //} catch (RemoteException e) {
+ // e.printStackTrace();
+ //}
}
// we also only need 1 sprinkler controller per lawn so grab the first one
- HashSet<@NonLocalRemote Sprinkler> sprinklers = lawnSprinklerRelation.get(l);
+ HashSet<SprinklerSmart> sprinklers = lawnSprinklerRelation.get(l);
Iterator sprinklersIt = sprinklers.iterator();
- @NonLocalRemote Sprinkler spr = (@NonLocalRemote Sprinkler)sprinklersIt.next();
+ SprinklerSmart spr = (SprinklerSmart)sprinklersIt.next();
// init the sprinkler controller, do it here since it only needs to be done once per controller
try {
System.out.println("DEBUG: Init sprinkler: " + spr.toString());
// get and init the moisture sensors for this specific lawn
- HashSet<@NonLocalRemote MoistureSensor> sensors = lawnMoistureSensorRelation.get(l);
- for (@NonLocalRemote MoistureSensor sen : sensors) {
+ HashSet<MoistureSensorSmart> sensors = lawnMoistureSensorRelation.get(l);
+ for (MoistureSensorSmart sen : sensors) {
System.out.println("DEBUG: Init sensors: " + sen.toString());
try {
sen.init();
+ sen.setId(sensorId++);
} catch (Exception e) {
e.printStackTrace();
}
// create the lawn objects
System.out.println("DEBUG: Creating a LawnState object");
- @LocalRemote LawnState ls =
- new @LocalRemote LawnState(l, daysToWaterOn, mo, inchesPerMinute.get(counter), inchesPerWeek, spr, counter, sensors);
+ LawnState ls =
+ new LawnState(l, daysToWaterOn, mo, inchesPerMinute.get(counter), inchesPerWeek, spr, counter, sensors);
lawns.add(ls);
// dont forget to increment the counter
// List<DayWeather> weatherData = new ArrayList<DayWeather>();
// Go through each lawn and check if we should water it and if we should, water it
- for (@LocalRemote LawnState ls : lawns) {
+ for (LawnState ls : lawns) {
// water for specific lawn
waterLawn(ls, _currentDate, weatherData);
List<DayWeather> weatherData = weatherGrabber.getWeatherData();
// Go through each lawn and check if we should water it and if we should, water it
- for (@LocalRemote LawnState ls : lawns) {
+ for (LawnState ls : lawns) {
boolean lawnHasMotion = ls.lawnHasSufficientMotion();
List<DayWeather> weatherData = weatherGrabber.getWeatherData();
// Go through each lawn and check if we should water it and if we should, water it
- for (@LocalRemote LawnState ls : lawns) {
+ for (LawnState ls : lawns) {
// System.out.println("DEBUG: We water the lawn! (hibernationRecoveryLoop)");
// water specific lawn since it has motion
*
* @return [void] None.
*/
- private void waterLawn(@LocalRemote LawnState _ls, Date _currentDate, List<DayWeather> _weatherData) {
+ private void waterLawn(LawnState _ls, Date _currentDate, List<DayWeather> _weatherData) {
// check if today or tomorrow is a wet day
boolean todayIsWetDay = _weatherData.get(0).getIsWetDay();
--- /dev/null
+package IrrigationController;
+
+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 LawnSmart_Stub implements LawnSmart {
+
+ private IoTRMICall rmiCall;
+ private String callbackAddress;
+ private int[] ports;
+
+ private final static int objectId = 0;
+
+
+ public LawnSmart_Stub(int _port, String _skeletonAddress, String _callbackAddress, int _rev, int[] _ports) throws Exception {
+ callbackAddress = _callbackAddress;
+ ports = _ports;
+ rmiCall = new IoTRMICall(_port, _skeletonAddress, _rev);
+ }
+
+}
import iotcode.interfaces.*;
// Checker annotations
-import iotchecker.qual.*;
+//import iotchecker.qual.*;
/** Class LawnState that represents the state of the lawn, also help calculate if the lawn needs to be watered.
*
private boolean didWaterSinceLastSchedualedDate = false;
private List<Date> daysRained = new ArrayList<Date>();
private int daysToWaterOn = 0;
- @NonLocalRemote private Lawn iotLawnObject;
- @NonLocalRemote private MotionDetection motionDetector;
+ private LawnSmart iotLawnObject;
+ private MotionDetection motionDetector;
private double inchesPerMinute = 0;
private double inchesPerWeek = 0;
private double timePerWatering = 0;
private double timePerWeek = 0;
private double timeWateredSoFar = 0;
- @NonLocalRemote private Sprinkler sprinkler;
+ private SprinklerSmart sprinkler;
private int zone = 0;
private Date lastMotionDetectedTime = null;
private Date startOfThisMotion = null;
private long numberOfMotionsOnLawnToday = 0;
private boolean lawnIsActive = false;
private Date lawnBecameActiceDate = null;
- private Map<@NonLocalRemote MoistureSensor, Double> moistureSensorReadings =
- new ConcurrentHashMap<@NonLocalRemote MoistureSensor, Double>();
- private Map<@NonLocalRemote MoistureSensor, Date> moistureSensorUpdateTimes =
- new ConcurrentHashMap<@NonLocalRemote MoistureSensor, Date>();
+ private Map<Integer, Double> moistureSensorReadings =
+ new ConcurrentHashMap<Integer, Double>();
+ private Map<Integer, Date> moistureSensorUpdateTimes =
+ new ConcurrentHashMap<Integer, Date>();
// 0th bit = Monday, 1th bit = Tuesday ext
- public LawnState(@NonLocalRemote Lawn _l, int _daysToWaterOn, @NonLocalRemote MotionDetection _mo,
- double _inchesPerMinute, double _inchesPerWeek, @NonLocalRemote Sprinkler _sprinkler,
- int _zone, Set<@NonLocalRemote MoistureSensor> _moistureSensors) throws RemoteException {
+ public LawnState(LawnSmart _l, int _daysToWaterOn, MotionDetection _mo,
+ double _inchesPerMinute, double _inchesPerWeek, SprinklerSmart _sprinkler,
+ int _zone, Set<MoistureSensorSmart> _moistureSensors) throws RemoteException {
iotLawnObject = _l;
daysToWaterOn = _daysToWaterOn;
inchesPerMinute = _inchesPerMinute;
_mo.registerCallback(this);
// register callback to self
- for (@NonLocalRemote MoistureSensor sen : _moistureSensors) {
+ for (MoistureSensorSmart sen : _moistureSensors) {
try {
sen.registerCallback(this);
*
* @return [void] None.
*/
- public void motionDetected(@NonLocalRemote MotionDetection _md) {
+ public void motionDetected(long timeStampOfLastMotion) {
- Date currMotTime = _md.getTimestampOfLastMotion();
+ Date currMotTime = new Date(timeStampOfLastMotion);
if (lastMotionDetectedTime == null) {
lastMotionDetectedTime = currMotTime;
*
* @return [void] None.
*/
- public void newReadingAvailable(@NonLocalRemote MoistureSensor _sensor) {
+ public void newReadingAvailable(int sensorId, float moisture, long timeStampOfLastReading) {
- try {
- // update the saved readings
- moistureSensorReadings.put(_sensor, (double)_sensor.getMoisture());
- moistureSensorUpdateTimes.put(_sensor, _sensor.getTimestampOfLastReading());
- } catch(RemoteException ex) {
- ex.printStackTrace();
- }
+ moistureSensorReadings.put(sensorId, (double) moisture);
+ moistureSensorUpdateTimes.put(sensorId, new Date(timeStampOfLastReading));
}
double total = 0;
int numberOfReadings = 0;
- for (@NonLocalRemote MoistureSensor sen : moistureSensorReadings.keySet()) {
+ for (Integer sen : moistureSensorReadings.keySet()) {
// check the timestamp of the watering of the lawn
Date readingTimestamp = moistureSensorUpdateTimes.get(sen);
System.out.println("DEBUG: Sensor reading value: " + moistureSensorReadings.get(sen) + " with total: " + total);
}
+
// if no readings were valid then return -1 so that we can signal that moisture cannot be used for now
if (numberOfReadings == 0) {
return -1;
JFLAGS = -d $(BIN_DIR) -cp $(BOOFJARS):$(BIN_DIR):.
JARFLAGS = cf
-# checker option
-#
-CHECKER_OPT = -processor iotchecker.IoTJavaChecker
+all: irrigation
-ASTUBS = -Astubs=../../checker/astubs/
-
-all: check
-
-PHONY += check
-check:
+PHONY += irrigation
+irrigation:
$(JAVAC) $(JFLAGS) $(CHECKER_OPT) $(ASTUBS) *.java
cd $(BIN_DIR)/IrrigationController; $(JAR) $(JARFLAGS) IrrigationController.jar ../IrrigationController/*.class ../iotcode/interfaces/*.class
cp IrrigationController.config $(BIN_DIR)/IrrigationController
cp -rf ./resources ./help_files $(BIN_DIR)/IrrigationController
cd $(BIN_DIR)/IrrigationController; zip -r IrrigationController.zip ./resources ./help_files
-PHONY += nocheck
-
-nocheck:
- $(JAVAC) $(JFLAGS) *.java
- cd $(BIN_DIR)/IrrigationController; $(JAR) $(JARFLAGS) IrrigationController.jar ../IrrigationController/*.class ../iotcode/interfaces/*.class
- cp IrrigationController.config $(BIN_DIR)/IrrigationController
- cp -rf ./resources ./help_files $(BIN_DIR)/IrrigationController
- cd $(BIN_DIR)/IrrigationController; zip -r IrrigationController.zip ./resources ./help_files
-
.PHONY: $(PHONY)
--- /dev/null
+package IrrigationController;
+
+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 MoistureSensorCallback_CallbackSkeleton implements MoistureSensorCallback {
+
+ private MoistureSensorCallback mainObj;
+ private int objectId = 0;
+ private String callbackAddress;
+
+
+ public MoistureSensorCallback_CallbackSkeleton(MoistureSensorCallback _mainObj, String _callbackAddress, int _objectId) throws Exception {
+ callbackAddress = _callbackAddress;
+ mainObj = _mainObj;
+ objectId = _objectId;
+ }
+
+ public void newReadingAvailable(int sensorId, float moisture, long timeStampOfLastReading) {
+ mainObj.newReadingAvailable(sensorId, moisture, timeStampOfLastReading);
+ }
+
+ public void ___newReadingAvailable(IoTRMIObject rmiObj) {
+ Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class, float.class, long.class },
+ new Class<?>[] { null, null, null });
+ newReadingAvailable((int) paramObj[0], (float) paramObj[1], (long) 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!");
+ }
+ }
+
+}
--- /dev/null
+package IrrigationController;
+
+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 MoistureSensorSmart_Stub implements MoistureSensorSmart {
+
+ private IoTRMICall rmiCall;
+ private String callbackAddress;
+ private int[] ports;
+
+ private final static int objectId = 0;
+ // Callback properties
+ private IoTRMIObject rmiObj;
+ List<MoistureSensorCallback> listCallbackObj;
+ private int objIdCnt = 0;
+ private final static int object0Id = 0; //MoistureSensorSmartCallback
+ private static Integer[] object0Permission = { 0 };
+ private static List<Integer> set0Allowed;
+
+
+ public MoistureSensorSmart_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<MoistureSensorCallback>();
+ set0Allowed.add(-9999);
+ ___initCallBack();
+ }
+
+ public long getTimestampOfLastReading() {
+ int methodId = 2;
+ 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 int getId() {
+ int methodId = 4;
+ 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(MoistureSensorCallback _callbackTo) {
+ try {
+ MoistureSensorCallback_CallbackSkeleton skel0 = new MoistureSensorCallback_CallbackSkeleton(_callbackTo, callbackAddress, objIdCnt++);
+ listCallbackObj.add(skel0);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new Error("Exception when generating skeleton objects!");
+ }
+
+ int methodId = 5;
+ 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);
+ MoistureSensorCallback_CallbackSkeleton skel = (MoistureSensorCallback_CallbackSkeleton) listCallbackObj.get(objId);
+ if (skel != null) {
+ int methodId = IoTRMIObject.getMethodId(method);
+ if (!set0Allowed.contains(methodId)) {
+ throw new Error("Callback object for MoistureSensorCallback is not allowed to access method: " + methodId);
+ }
+ skel.invokeMethod(rmiObj);
+ } else {
+ throw new Error("MoistureSensorCallback: Object with Id " + objId + " not found!");
+ }
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new Error("Error instantiating class MoistureSensorCallback_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 float getMoisture() {
+ int methodId = 1;
+ Class<?> retType = float.class;
+ Class<?>[] paramCls = new Class<?>[] { };
+ Object[] paramObj = new Object[] { };
+ Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+ return (float)retObj;
+ }
+
+ public void setId(int id) {
+ int methodId = 3;
+ 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);
+ }
+
+}
import java.rmi.server.UnicastRemoteObject;
// Checker annotations
-import iotchecker.qual.*;
+//import iotchecker.qual.*;
private Lock imageWriteLock = imageReadWriteLock.writeLock();
// List of objects wishing to receive callbacks from this class.
- private List<@NonLocalRemote MotionDetectionCallback> callbackList = new ArrayList<@NonLocalRemote MotionDetectionCallback>();
+ private List<MotionDetectionCallback> callbackList = new ArrayList<MotionDetectionCallback>();
// Variables to help with motion detection
private ConfigBackgroundGaussian configGaussian = null;
*
* @return [Date] timestamp of last motion or null if no motion was ever detected.
*/
- public Date getTimestampOfLastMotion() {
+ public long getTimestampOfLastMotion() {
Date ret = null;
// Be safe because multithread
}
timestampReadLock.unlock();
+ long retLong = ret.getTime();
- return ret;
+ return retLong;
}
*
* @return [void] None.
*/
- public void registerCallback(@NonLocalRemote MotionDetectionCallback _mdc) {
+ public void registerCallback(MotionDetectionCallback _mdc) {
callbackList.add(_mdc);
}
// Motion was detected so issue callbacks to all objects that registered
// to receive callback from this class.
- for (@NonLocalRemote MotionDetectionCallback c : callbackList) {
+ for (MotionDetectionCallback c : callbackList) {
try {
- c.motionDetected(this);
+ c.motionDetected(this.getTimestampOfLastMotion());
} catch (RemoteException re) {
}
}
*/
// Checker annotations
-import iotchecker.qual.*;
import java.rmi.Remote;
import java.rmi.RemoteException;
*
* @return [void] None.
*/
- public void motionDetected(@NonLocalRemote MotionDetection _wg) throws RemoteException;
+ //public void motionDetected(@NonLocalRemote MotionDetection _wg) throws RemoteException;
+ public void motionDetected(long timeStampOfLastMotion) throws RemoteException;
}
--- /dev/null
+package IrrigationController;
+
+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 SprinklerSmart_Stub implements SprinklerSmart {
+
+ private IoTRMICall rmiCall;
+ private String callbackAddress;
+ private int[] ports;
+
+ private final static int objectId = 0;
+
+
+ public SprinklerSmart_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;
+ }
+
+}
--- /dev/null
+package IrrigationController;
+
+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 WeatherGatewayCallback_CallbackSkeleton implements WeatherGatewayCallback {
+
+ private WeatherGatewayCallback mainObj;
+ private int objectId = 0;
+ private String callbackAddress;
+
+
+ public WeatherGatewayCallback_CallbackSkeleton(WeatherGatewayCallback _mainObj, String _callbackAddress, int _objectId) throws Exception {
+ callbackAddress = _callbackAddress;
+ mainObj = _mainObj;
+ objectId = _objectId;
+ }
+
+ public void informationRetrieved(double _inchesPerWeek, int _weatherZipCode, int _daysToWaterOn, double _inchesPerMinute) {
+ mainObj.informationRetrieved(_inchesPerWeek, _weatherZipCode, _daysToWaterOn, _inchesPerMinute);
+ }
+
+ public void ___informationRetrieved(IoTRMIObject rmiObj) {
+ Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { double.class, int.class, int.class, double.class },
+ new Class<?>[] { null, null, null, null });
+ informationRetrieved((double) paramObj[0], (int) paramObj[1], (int) paramObj[2], (double) paramObj[3]);
+ }
+
+ public void invokeMethod(IoTRMIObject rmiObj) throws IOException {
+ int methodId = rmiObj.getMethodId();
+ switch (methodId) {
+ case 0: ___informationRetrieved(rmiObj); break;
+ default:
+ throw new Error("Method Id " + methodId + " not recognized!");
+ }
+ }
+
+}
--- /dev/null
+package IrrigationController;
+
+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 WeatherGatewaySmart_Stub implements WeatherGatewaySmart {
+
+ private IoTRMICall rmiCall;
+ private String callbackAddress;
+ private int[] ports;
+
+ private final static int objectId = 0;
+ // Callback properties
+ private IoTRMIObject rmiObj;
+ List<WeatherGatewayCallback> listCallbackObj;
+ private int objIdCnt = 0;
+ private final static int object0Id = 0; //WeatherGatewaySmartCallback
+ private static Integer[] object0Permission = { 0 };
+ private static List<Integer> set0Allowed;
+
+
+ public WeatherGatewaySmart_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<WeatherGatewayCallback>();
+ set0Allowed.add(-9999);
+ ___initCallBack();
+ }
+
+ public double getInchesPerWeek() {
+ int methodId = 3;
+ Class<?> retType = double.class;
+ Class<?>[] paramCls = new Class<?>[] { };
+ Object[] paramObj = new Object[] { };
+ Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+ return (double)retObj;
+ }
+
+ public double getInchesPerMinute() {
+ int methodId = 6;
+ Class<?> retType = double.class;
+ Class<?>[] paramCls = new Class<?>[] { };
+ Object[] paramObj = new Object[] { };
+ Object retObj = rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+ return (double)retObj;
+ }
+
+ public int getDaysToWaterOn() {
+ 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(WeatherGatewayCallback _callbackTo) {
+ try {
+ WeatherGatewayCallback_CallbackSkeleton skel0 = new WeatherGatewayCallback_CallbackSkeleton(_callbackTo, callbackAddress, objIdCnt++);
+ listCallbackObj.add(skel0);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new Error("Exception when generating skeleton objects!");
+ }
+
+ int methodId = 7;
+ 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);
+ WeatherGatewayCallback_CallbackSkeleton skel = (WeatherGatewayCallback_CallbackSkeleton) listCallbackObj.get(objId);
+ if (skel != null) {
+ int methodId = IoTRMIObject.getMethodId(method);
+ if (!set0Allowed.contains(methodId)) {
+ throw new Error("Callback object for WeatherGatewayCallback is not allowed to access method: " + methodId);
+ }
+ skel.invokeMethod(rmiObj);
+ } else {
+ throw new Error("WeatherGatewayCallback: Object with Id " + objId + " not found!");
+ }
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ throw new Error("Error instantiating class WeatherGatewayCallback_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 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 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 int getWeatherZipCode() {
+ int methodId = 4;
+ 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;
+ }
+
+}
include $(BASE)/common.mk
-all: interfaces annotation drivers Lifxtest SmartLights
+all: interfaces annotation drivers Lifxtest SmartLights Irrigation
PHONY += interfaces
interfaces:
--- /dev/null
+INTERFACE_CLASS=Sprinkler
--- /dev/null
+package iotcode.EspSprinkler;
+
+// 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.Sprinkler;
+import iotcode.annotation.*;
+
+//import iotchecker.qual.*;
+
+/** Class EspSprinkler for the ESP8266 plrg Sprinkler.
+ *
+ * @author Ali Younis <ayounis @ uci.edu>
+ * @version 1.0
+ * @since 2016-03-31
+ */
+
+public class EspSprinkler implements Sprinkler {
+
+ /*******************************************************************************************************************************************
+ **
+ ** 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> spr_Addresses;
+
+ /*public EspSprinkler(IoTUDP _udp) {
+ communicationSockect = _udp;
+ }*/
+
+ public EspSprinkler() {
+ 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 = spr_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) {
+
+ }
+ }
+ }
+
+}
+
+
+
+
+
+
+
+
--- /dev/null
+package iotcode.EspSprinkler;
+
+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 Sprinkler_Skeleton implements Sprinkler {
+
+ private Sprinkler mainObj;
+ private IoTRMIObject rmiObj;
+
+ private String callbackAddress;
+ private final static int object0Id = 0; //SprinklerSmart
+ private static Integer[] object0Permission = { 4, 2, 0, 1, 3 };
+ private static List<Integer> set0Allowed;
+
+
+ public Sprinkler_Skeleton(Sprinkler _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!");
+ }
+ }
+ }
+
+}
--- /dev/null
+INTERFACE_CLASS=Lawn
--- /dev/null
+package iotcode.GreenLawn;
+
+import iotcode.interfaces.Lawn;
+
+public class GreenLawn implements Lawn {
+
+ public GreenLawn() {
+
+ }
+}
--- /dev/null
+package iotcode.GreenLawn;
+
+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 Lawn_Skeleton implements Lawn {
+
+ private Lawn mainObj;
+ private IoTRMIObject rmiObj;
+
+ private String callbackAddress;
+ private final static int object0Id = 0; //LawnSmart
+ private static Integer[] object0Permission = { };
+ private static List<Integer> set0Allowed;
+
+
+ public Lawn_Skeleton(Lawn _mainObj, String _callbackAddress, int _port) throws Exception {
+ mainObj = _mainObj;
+ callbackAddress = _callbackAddress;
+ rmiObj = new IoTRMIObject(_port);
+ set0Allowed = new ArrayList<Integer>(Arrays.asList(object0Permission));
+ ___waitRequestInvokeMethod();
+ }
+
+ 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) {
+ default:
+ throw new Error("Method Id " + methodId + " not recognized!");
+ }
+ }
+ }
+
+}
JARFLAGS = cf
INTFACE_DIR = iotcode/interfaces
-all: light camera labroom
+all: light camera labroom greenlawn sprinkler moisture weathergateway
# Compile
#
cp LabRoom/LabRoom.config $(BIN_DIR)/iotcode/LabRoom
cd $(BIN_DIR)/iotcode/LabRoom; $(JAR) $(JARFLAGS) LabRoom.jar ../../iotcode/LabRoom/*.class ../../iotcode/interfaces/Room*.class
+PHONY += greenlawn
+greenlawn:
+ $(JAVAC) $(JFLAGS) GreenLawn/*.java
+ cp GreenLawn/GreenLawn.config $(BIN_DIR)/iotcode/GreenLawn
+ cd $(BIN_DIR)/iotcode/GreenLawn; $(JAR) $(JARFLAGS) GreenLawn.jar ../../iotcode/GreenLawn/*.class ../../iotcode/interfaces/Lawn*.class
+
+PHONY += sprinkler
+sprinkler:
+ $(JAVAC) $(JFLAGS) EspSprinkler/*.java
+ cp EspSprinkler/EspSprinkler.config $(BIN_DIR)/iotcode/EspSprinkler
+ cd $(BIN_DIR)/iotcode/EspSprinkler; $(JAR) $(JARFLAGS) EspSprinkler.jar ../../iotcode/EspSprinkler/*.class ../../iotcode/interfaces/Sprinkler*.class ../../iotcode/interfaces/ZoneState*.class
+
+PHONY += moisture
+moisture:
+ $(JAVAC) $(JFLAGS) SpruceSensor/*.java
+ cp SpruceSensor/SpruceSensor.config $(BIN_DIR)/iotcode/SpruceSensor
+ cd $(BIN_DIR)/iotcode/SpruceSensor; $(JAR) $(JARFLAGS) SpruceSensor.jar ../../iotcode/SpruceSensor/*.class ../../iotcode/interfaces/MoistureSensor*.class ../../iotcode/
+
+PHONY += weathergateway
+weathergateway:
+ $(JAVAC) $(JFLAGS) WeatherPhoneGateway/*.java
+ cp WeatherPhoneGateway/WeatherPhoneGateway.config $(BIN_DIR)/iotcode/WeatherPhoneGateway
+ cd $(BIN_DIR)/iotcode/WeatherPhoneGateway; $(JAR) $(JARFLAGS) WeatherPhoneGateway.jar ../../iotcode/WeatherPhoneGateway/*.class ../../iotcode/interfaces/WeatherGateway*.class
+
.PHONY: $(PHONY)
--- /dev/null
+package iotcode.SpruceSensor;
+
+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 MoistureSensorSmartCallback_CallbackStub implements MoistureSensorSmartCallback {
+
+ private IoTRMICall rmiCall;
+ private String callbackAddress;
+ private int[] ports;
+
+ private int objectId = 0;
+
+
+ public MoistureSensorSmartCallback_CallbackStub(IoTRMICall _rmiCall, String _callbackAddress, int _objectId, int[] _ports) throws Exception {
+ callbackAddress = _callbackAddress;
+ objectId = _objectId;
+ rmiCall = _rmiCall;
+ ports = _ports;
+ }
+
+ public void newReadingAvailable(int sensorId, float moisture, long timeStampOfLastReading) {
+ int methodId = 0;
+ Class<?> retType = void.class;
+ Class<?>[] paramCls = new Class<?>[] { int.class, float.class, long.class };
+ Object[] paramObj = new Object[] { sensorId, moisture, timeStampOfLastReading };
+ rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+ }
+
+}
--- /dev/null
+package iotcode.SpruceSensor;
+
+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 MoistureSensor_Skeleton implements MoistureSensor {
+
+ private MoistureSensor mainObj;
+ private IoTRMIObject rmiObj;
+
+ private String callbackAddress;
+ private int objIdCnt = 0;
+ private IoTRMICall rmiCall;
+ private int[] ports;
+
+ private final static int object0Id = 0; //MoistureSensorSmart
+ private static Integer[] object0Permission = { 2, 4, 5, 1, 3, 0 };
+ private static List<Integer> set0Allowed;
+
+
+ public MoistureSensor_Skeleton(MoistureSensor _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 float getMoisture() {
+ return mainObj.getMoisture();
+ }
+
+ public long getTimestampOfLastReading() {
+ return mainObj.getTimestampOfLastReading();
+ }
+
+ public void setId(int id) {
+ mainObj.setId(id);
+ }
+
+ public int getId() {
+ return mainObj.getId();
+ }
+
+ public void registerCallback(MoistureSensorSmartCallback _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 ___getMoisture() throws IOException {
+ Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { },
+ new Class<?>[] { });
+ Object retObj = getMoisture();
+ 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 {
+ MoistureSensorSmartCallback stub0 = new MoistureSensorSmartCallback_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: ___getMoisture(); break;
+ case 2: ___getTimestampOfLastReading(); break;
+ case 3: ___setId(); break;
+ case 4: ___getId(); break;
+ case 5: ___registerCallback(); break;
+ case -9998: ___regCB(); break;
+ default:
+ throw new Error("Method Id " + methodId + " not recognized!");
+ }
+ }
+ }
+
+}
--- /dev/null
+INTERFACE_CLASS=MoistureSensor
--- /dev/null
+package iotcode.SpruceSensor;
+
+// Standard Java Packages
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Semaphore;
+
+
+// Checker annotations
+//import iotchecker.qual.*;
+
+// IoT Packages
+import iotruntime.slave.*;
+import iotcode.interfaces.MoistureSensor;
+import iotcode.interfaces.MoistureSensorSmartCallback;
+import iotruntime.zigbee.*;
+import iotcode.annotation.*;
+
+public class SpruceSensor implements IoTZigbeeCallback, MoistureSensor {
+
+ private final int TIMEOUT_FOR_RESEND_MSEC = 1000;
+
+ private IoTZigbee zigConnection = null;
+ private boolean didClose; // make sure that the clean up was done correctly
+
+ private float humidity = 0;
+ private Date timestampOfLastHumidity = null;
+
+ private AtomicBoolean didBind = new AtomicBoolean(false);
+ private AtomicBoolean didConfigureReporting = new AtomicBoolean(false);
+ private AtomicBoolean didAlreadyInit = new AtomicBoolean(false);
+ private AtomicBoolean didAlreadyClose = new AtomicBoolean(true);
+ static Semaphore gettingLatestDataMutex = new Semaphore(1);
+
+ private List < MoistureSensorSmartCallback > callbackList = new CopyOnWriteArrayList < MoistureSensorSmartCallback > ();
+
+ private int sensorId = 0;
+
+ @config private IoTSet<IoTDeviceAddress> devUdpAddress;
+ @config private IoTSet<IoTZigbeeAddress> devZigbeeAddress;
+
+ public SpruceSensor() {
+ }
+
+ 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!");
+
+ while (!didBind.get()) {
+ zigConnection.sendBindRequest(0x0001, 0x0405, 0x01);
+ try {
+ Thread.sleep(TIMEOUT_FOR_RESEND_MSEC);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ while (!didConfigureReporting.get()) {
+ zigConnection.sendConfigureReportingCommand(0x0001, 0x0405, 0x0104, 0x01, 0x0000, 0x21, 0x0001, 0x0001, null);
+ try {
+ Thread.sleep(TIMEOUT_FOR_RESEND_MSEC);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ } 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 float getMoisture() {
+
+ float tmp = 0;
+ try {
+ gettingLatestDataMutex.acquire();
+ tmp = humidity;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ gettingLatestDataMutex.release();
+
+ return tmp;
+ }
+
+ public long getTimestampOfLastReading() {
+
+ Date tmp = null;
+ try {
+ gettingLatestDataMutex.acquire();
+ tmp = (Date)timestampOfLastHumidity.clone();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ gettingLatestDataMutex.release();
+ long retLong = tmp.getTime();
+
+ return retLong;
+ }
+
+ public void newMessageAvailable(IoTZigbeeMessage _zm) {
+
+ if (_zm instanceof IoTZigbeeMessageZdoBindResponse) {
+ IoTZigbeeMessageZdoBindResponse message = (IoTZigbeeMessageZdoBindResponse)_zm;
+ if (message.getSucceeded()) {
+ didBind.set(true);
+ }
+
+ } else if (_zm instanceof IoTZigbeeMessageZclConfigureReportingResponse) {
+ IoTZigbeeMessageZclConfigureReportingResponse message = (IoTZigbeeMessageZclConfigureReportingResponse)_zm;
+ if (message.getAllSuccess()) {
+ didConfigureReporting.set(true);
+ }
+
+ } else if (_zm instanceof IoTZigbeeMessageZclReportAttributes) {
+ IoTZigbeeMessageZclReportAttributes message = (IoTZigbeeMessageZclReportAttributes)_zm;
+ List <IoTZigbeeMessageZclReportAttributes.Attribute> attrList = message.getAttributes();
+
+ if (attrList.size() == 1) {
+ if (attrList.get(0).getAttributeId() == 0) {
+ byte[] data = attrList.get(0).getData();
+
+ int value = (data[0] * 256) + data[1];
+
+ try {
+ gettingLatestDataMutex.acquire();
+ humidity = (float)value / (float)100.0;
+ timestampOfLastHumidity = new Date();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ gettingLatestDataMutex.release();
+
+ try {
+ for (MoistureSensorSmartCallback cb : callbackList) {
+ cb.newReadingAvailable(this.getId(), this.getMoisture(), this.getTimestampOfLastReading());
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ }
+ }
+
+ public void registerCallback(MoistureSensorSmartCallback _callbackTo) {
+ callbackList.add(_callbackTo);
+ }
+}
--- /dev/null
+package iotcode.WeatherPhoneGateway;
+
+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 WeatherGatewaySmartCallback_CallbackStub implements WeatherGatewaySmartCallback {
+
+ private IoTRMICall rmiCall;
+ private String callbackAddress;
+ private int[] ports;
+
+ private int objectId = 0;
+
+
+ public WeatherGatewaySmartCallback_CallbackStub(IoTRMICall _rmiCall, String _callbackAddress, int _objectId, int[] _ports) throws Exception {
+ callbackAddress = _callbackAddress;
+ objectId = _objectId;
+ rmiCall = _rmiCall;
+ ports = _ports;
+ }
+
+ public void informationRetrieved(double _inchesPerWeek, int _weatherZipCode, int _daysToWaterOn, double _inchesPerMinute) {
+ int methodId = 0;
+ Class<?> retType = void.class;
+ Class<?>[] paramCls = new Class<?>[] { double.class, int.class, int.class, double.class };
+ Object[] paramObj = new Object[] { _inchesPerWeek, _weatherZipCode, _daysToWaterOn, _inchesPerMinute };
+ rmiCall.remoteCall(objectId, methodId, retType, null, paramCls, paramObj);
+ }
+
+}
--- /dev/null
+package iotcode.WeatherPhoneGateway;
+
+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 WeatherGateway_Skeleton implements WeatherGateway {
+
+ private WeatherGateway mainObj;
+ private IoTRMIObject rmiObj;
+
+ private String callbackAddress;
+ private int objIdCnt = 0;
+ private IoTRMICall rmiCall;
+ private int[] ports;
+
+ private final static int object0Id = 0; //WeatherGatewaySmart
+ private static Integer[] object0Permission = { 3, 6, 5, 7, 2, 1, 0, 4 };
+ private static List<Integer> set0Allowed;
+
+
+ public WeatherGateway_Skeleton(WeatherGateway _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 void start() {
+ mainObj.start();
+ }
+
+ public void stop() {
+ mainObj.stop();
+ }
+
+ public double getInchesPerWeek() {
+ return mainObj.getInchesPerWeek();
+ }
+
+ public int getWeatherZipCode() {
+ return mainObj.getWeatherZipCode();
+ }
+
+ public int getDaysToWaterOn() {
+ return mainObj.getDaysToWaterOn();
+ }
+
+ public double getInchesPerMinute() {
+ return mainObj.getInchesPerMinute();
+ }
+
+ public void registerCallback(WeatherGatewaySmartCallback _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 ___start() {
+ Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { },
+ new Class<?>[] { });
+ start();
+ }
+
+ public void ___stop() {
+ Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { },
+ new Class<?>[] { });
+ stop();
+ }
+
+ public void ___getInchesPerWeek() throws IOException {
+ Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { },
+ new Class<?>[] { });
+ Object retObj = getInchesPerWeek();
+ rmiObj.sendReturnObj(retObj);
+ }
+
+ public void ___getWeatherZipCode() throws IOException {
+ Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { },
+ new Class<?>[] { });
+ Object retObj = getWeatherZipCode();
+ rmiObj.sendReturnObj(retObj);
+ }
+
+ public void ___getDaysToWaterOn() throws IOException {
+ Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { },
+ new Class<?>[] { });
+ Object retObj = getDaysToWaterOn();
+ rmiObj.sendReturnObj(retObj);
+ }
+
+ public void ___getInchesPerMinute() throws IOException {
+ Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { },
+ new Class<?>[] { });
+ Object retObj = getInchesPerMinute();
+ rmiObj.sendReturnObj(retObj);
+ }
+
+ public void ___registerCallback() {
+ Object[] paramObj = rmiObj.getMethodParams(new Class<?>[] { int.class },
+ new Class<?>[] { null });
+ try {
+ WeatherGatewaySmartCallback stub0 = new WeatherGatewaySmartCallback_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: ___start(); break;
+ case 2: ___stop(); break;
+ case 3: ___getInchesPerWeek(); break;
+ case 4: ___getWeatherZipCode(); break;
+ case 5: ___getDaysToWaterOn(); break;
+ case 6: ___getInchesPerMinute(); break;
+ case 7: ___registerCallback(); break;
+ case -9998: ___regCB(); break;
+ default:
+ throw new Error("Method Id " + methodId + " not recognized!");
+ }
+ }
+ }
+
+}
--- /dev/null
+package iotcode.WeatherPhoneGateway;
+
+/** WeatherInfo that implements WeatherInfoInterface
+ *
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @version 1.0
+ * @since 2016-04-26
+ */
+public class WeatherInfo implements WeatherInfoInterface {
+
+ /**
+ * WeatherInfo class properties
+ */
+ private Double dInchesPerWeek;
+ private Integer iWeatherZipCode;
+ private Integer iDaysToWaterOn;
+ private Double dInchesPerMinute;
+ private boolean bNewDataAvailable;
+
+ /**
+ * Constructor
+ */
+ public WeatherInfo() {
+ this.dInchesPerWeek = 0.0;
+ this.iWeatherZipCode = 0;
+ this.iDaysToWaterOn = 0;
+ this.dInchesPerMinute = 0.0;
+ this.bNewDataAvailable = false;
+ }
+
+ /**
+ * Get irrigation info from the phone app using IoTRemoteCall
+ *
+ * @param dInchesPerWeek Rainfall information (inches per week)
+ * @param iWeatherZipCode Area zip code for weather info
+ * @param iDaysToWaterOn Number of days to water the lawn
+ * @param dInchesPerMinute Rainfall information (inches per minute)
+ * @
+ */
+ public String getIrrigationInfo(Double dInchesPerWeek, Integer iWeatherZipCode,
+ Integer iDaysToWaterOn, Double dInchesPerMinute) {
+
+ this.dInchesPerWeek = dInchesPerWeek;
+ this.iWeatherZipCode = iWeatherZipCode;
+ this.iDaysToWaterOn = iDaysToWaterOn;
+ this.dInchesPerMinute = dInchesPerMinute;
+ this.bNewDataAvailable = true;
+ System.out.println("DEBUG: We are getting data from phone!");
+ System.out.println("DEBUG: New data available?" + bNewDataAvailable);
+
+ return "info sent";
+ }
+
+ /**
+ * Simply return this.dInchesPerWeek
+ */
+ public Double getInchesPerWeek() {
+
+ return this.dInchesPerWeek;
+ }
+
+ /**
+ * Simply return this.iWeatherZipCode
+ */
+ public Integer getWeatherZipCode() {
+
+ return this.iWeatherZipCode;
+ }
+
+ /**
+ * Simply return this.iDaysToWaterOn
+ */
+ public Integer getDaysToWaterOn() {
+
+ return this.iDaysToWaterOn;
+ }
+
+ /**
+ * Simply return this.dInchesPerMinute
+ */
+ public Double getInchesPerMinute() {
+
+ return this.dInchesPerMinute;
+ }
+
+ /**
+ * Simply return this.bNewDataAvailable
+ */
+ public boolean isNewDataAvailable() {
+
+ return this.bNewDataAvailable;
+ }
+
+ /**
+ * Set this.bNewDataAvailable
+ */
+ public void setNewDataAvailable(boolean bValue) {
+
+ this.bNewDataAvailable = bValue;
+ }
+}
--- /dev/null
+package iotcode.WeatherPhoneGateway;
+
+/** WeatherInfoInterface interface to be implemented by a real class
+ *
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @version 1.0
+ * @since 2016-04-26
+ */
+public interface WeatherInfoInterface {
+
+ /**
+ * WeatherPhoneGateway takes 4 inputs
+ * - inchesPerWeek (double)
+ * - weatherZipCode (int)
+ * - daysToWaterOn (int)
+ * - inchesPerMinute (double)
+ */
+ String getIrrigationInfo(Double dInchesPerWeek, Integer iWeatherZipCode,
+ Integer iDaysToWaterOn, Double dInchesPerMinute);
+}
--- /dev/null
+INTERFACE_CLASS=WeatherGateway
--- /dev/null
+package iotcode.WeatherPhoneGateway;
+
+// Java standard library
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.Iterator;
+import java.util.List;
+import java.net.UnknownHostException;
+
+// RMI Packages
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+// IoTRuntime library
+import iotruntime.stub.IoTRemoteCall;
+import iotruntime.slave.IoTSet;
+import iotruntime.slave.IoTDeviceAddress;
+import iotcode.annotation.*;
+import iotcode.interfaces.*;
+
+// Checker annotations
+//import iotchecker.qual.*;
+
+/** WeatherPhoneProxy that uses IoTRemoteCall and WeatherInfo class
+ * to get information from a phone app
+ *
+ * @author Rahmadi Trimananda <rahmadi.trimananda @ uci.edu>
+ * @version 1.0
+ * @since 2016-04-26
+ */
+public class WeatherPhoneGateway implements WeatherGateway {
+
+ /**
+ * PhoneGateway class properties
+ */
+ private WeatherInfo weatherInfo;
+ private IoTRemoteCall iotRemCall;
+ private List<WeatherGatewaySmartCallback> listPGWCallback;
+ private AtomicBoolean doEnd;
+ private Thread callbackThread;
+ private Thread workerThread;
+ private IoTDeviceAddress iotDevAdd;
+
+ @config private IoTSet<IoTDeviceAddress> ph_address;
+
+ /**
+ * Constructor
+ */
+ /*public WeatherPhoneGateway() throws RemoteException, UnknownHostException {
+
+ iotDevAdd = new IoTDeviceAddress("192.168.2.101", 1234, 8000);
+ weatherInfo = new WeatherInfo();
+
+ // Launch IoTRemoteCall server in a separate thread
+ workerThread = new Thread(new Runnable() {
+ public void run() {
+ iotRemCall = new IoTRemoteCall(WeatherInfoInterface.class,
+ weatherInfo, iotDevAdd.getDestinationPortNumber());
+ }
+ });
+ workerThread.start();
+
+ System.out.println("PhoneGateway is started");
+
+ }*/
+ public WeatherPhoneGateway() {
+ }
+
+ /**
+ * Init() function
+ */
+ public void init() {
+
+ // Get address
+ Iterator it = ph_address.iterator();
+ iotDevAdd = (IoTDeviceAddress) it.next();
+// try {
+// iotDevAdd = new IoTDeviceAddress("192.168.2.101", 1234, 8000);
+// } catch (Exception ex) {
+// }
+ System.out.println("Address: " + iotDevAdd.getCompleteAddress());
+ System.out.println("Source port: " + iotDevAdd.getSourcePortNumber());
+ System.out.println("Destination port: " + iotDevAdd.getDestinationPortNumber());
+
+ // Get server
+ weatherInfo = new WeatherInfo();
+ System.out.println("DEBUG: Is new data available: " + weatherInfo.isNewDataAvailable());
+ listPGWCallback = new ArrayList<WeatherGatewaySmartCallback>();
+ doEnd = new AtomicBoolean(false);
+
+ // Threads
+ callbackThread = null;
+ workerThread = null;
+ }
+
+ /**
+ * Start() function to start threads
+ */
+ public void start() {
+ doEnd.set(false);
+
+ // Launch IoTRemoteCall server in a separate thread
+ workerThread = new Thread(new Runnable() {
+ public void run() {
+ iotRemCall = new IoTRemoteCall(WeatherInfoInterface.class,
+ weatherInfo, iotDevAdd.getDestinationPortNumber(),
+ IoTDeviceAddress.getLocalHostAddress());
+ }
+ });
+ workerThread.start();
+ System.out.println("DEBUG: Started IoTRemoteCall object!!!");
+
+ callbackThread = new Thread(new Runnable() {
+ public void run() {
+ doCallbacks();
+ }
+ });
+ callbackThread.start();
+ System.out.println("DEBUG: Do Callbacks!!!");
+ }
+
+ /**
+ * Stop() function to stop threads
+ */
+ public void stop() {
+ doEnd.set(true);
+
+ try {
+ callbackThread.join();
+ workerThread.join();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Register callbacks
+ */
+ public void registerCallback(WeatherGatewaySmartCallback _c) {
+ listPGWCallback.add(_c);
+ }
+
+ /**
+ * Do callbacks
+ */
+ private void doCallbacks() {
+
+ while (!doEnd.get()) {
+ // Only call back if there is new data
+ if (weatherInfo.isNewDataAvailable()) {
+ System.out.println("We get into doCallbacks!");
+ System.out.println("weatherInfo.isNewDataAvailable(): " + weatherInfo.isNewDataAvailable());
+ for (WeatherGatewaySmartCallback c : listPGWCallback) {
+ //try {
+ //c.informationRetrieved(this);
+ c.informationRetrieved(this.getInchesPerWeek(), this.getWeatherZipCode(), this.getDaysToWaterOn(), this.getInchesPerMinute());
+ //} catch (RemoteException ex) {
+ // ex.printStackTrace();
+ //}
+ // We have read data - set this back to false
+ }
+ weatherInfo.setNewDataAvailable(false);
+ }
+ }
+ }
+
+ /**
+ * Simply return this.dInchesPerWeek
+ */
+ public double getInchesPerWeek() {
+
+ return weatherInfo.getInchesPerWeek();
+ }
+
+ /**
+ * Simply return this.iWeatherZipCode
+ */
+ public int getWeatherZipCode() {
+
+ return weatherInfo.getWeatherZipCode();
+ }
+
+ /**
+ * Simply return this.iDaysToWaterOn
+ */
+ public int getDaysToWaterOn() {
+
+ return weatherInfo.getDaysToWaterOn();
+ }
+
+ /**
+ * Simply return this.dInchesPerMinute
+ */
+ public double getInchesPerMinute() {
+
+ return weatherInfo.getInchesPerMinute();
+ }
+
+
+// public static void main(String[] args) throws UnknownHostException, RemoteException {
+
+// @LocalRemote WeatherPhoneGateway wpg = new @LocalRemote WeatherPhoneGateway();
+// wpg.init();
+// wpg.start();
+// }
+}
--- /dev/null
+package iotcode.interfaces;
+
+public interface Lawn {
+
+}
--- /dev/null
+package iotcode.interfaces;
+
+public interface LawnSmart {
+
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface MoistureSensor {
+ public void init();
+ public float getMoisture();
+ public long getTimestampOfLastReading();
+ public void setId(int id);
+ public int getId();
+ public void registerCallback(MoistureSensorSmartCallback _callbackTo);
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface MoistureSensorCallback {
+ public void newReadingAvailable(int sensorId, float moisture, long timeStampOfLastReading);
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface MoistureSensorSmart {
+
+ public long getTimestampOfLastReading();
+ public int getId();
+ public void registerCallback(MoistureSensorCallback _callbackTo);
+ public float getMoisture();
+ public void setId(int id);
+ public void init();
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface MoistureSensorSmartCallback {
+
+ public void newReadingAvailable(int sensorId, float moisture, long timeStampOfLastReading);
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface Sprinkler {
+ public void init();
+ public void setZone(int _zone, boolean _onOff, int _onDurationSeconds);
+ public List<ZoneState> getZoneStates();
+ public int getNumberOfZones();
+ public boolean doesHaveZoneTimers();
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface SprinklerSmart {
+
+ public boolean doesHaveZoneTimers();
+ public List<ZoneState> getZoneStates();
+ public void init();
+ public void setZone(int _zone, boolean _onOff, int _onDurationSeconds);
+ public int getNumberOfZones();
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface WeatherGateway {
+ public void init();
+ public void start();
+ public void stop();
+ public double getInchesPerWeek();
+ public int getWeatherZipCode();
+ public int getDaysToWaterOn();
+ public double getInchesPerMinute();
+ public void registerCallback(WeatherGatewaySmartCallback _callbackTo);
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface WeatherGatewayCallback {
+ public void informationRetrieved(double _inchesPerWeek, int _weatherZipCode, int _daysToWaterOn, double _inchesPerMinute);
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface WeatherGatewaySmart {
+
+ public double getInchesPerWeek();
+ public double getInchesPerMinute();
+ public int getDaysToWaterOn();
+ public void registerCallback(WeatherGatewayCallback _callbackTo);
+ public void stop();
+ public void start();
+ public void init();
+ public int getWeatherZipCode();
+}
--- /dev/null
+package iotcode.interfaces;
+
+import java.util.List;
+import java.util.ArrayList;
+
+public interface WeatherGatewaySmartCallback {
+
+ public void informationRetrieved(double _inchesPerWeek, int _weatherZipCode, int _daysToWaterOn, double _inchesPerMinute);
+}
--- /dev/null
+package iotcode.interfaces;
+
+public class ZoneState {
+ public static int zoneNumber;
+ public static boolean onOffState;
+ public static int duration;
+}
+
cp ../localconfig/iotpolicy/LifxLightBulb/*.req $(BIN_DIR)/iotpolicy/
cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler lifxlightbulb.pol lifxtest.req -java Java
+# SmartLightsController
PHONY += run-compiler-lifx
run-compiler-lifx:
cp ../localconfig/iotpolicy/LifxLightBulb/*.pol $(BIN_DIR)/iotpolicy/
cp ../localconfig/iotpolicy/AmcrestCamera/*.req $(BIN_DIR)/iotpolicy/
cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler amcrestcamera.pol smartlightscam.req motiondetection.pol motiondetection.req -java Java
+# IrrigationController
+PHONY += run-compiler-lawn
+run-compiler-lawn:
+ cp ../localconfig/iotpolicy/GreenLawn/*.pol $(BIN_DIR)/iotpolicy/
+ cp ../localconfig/iotpolicy/GreenLawn/*.req $(BIN_DIR)/iotpolicy/
+ cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler greenlawn.pol smartlawn.req -java Java
+
+PHONY += run-compiler-sprk
+run-compiler-sprk:
+ cp ../localconfig/iotpolicy/EspSprinkler/*.pol $(BIN_DIR)/iotpolicy/
+ cp ../localconfig/iotpolicy/EspSprinkler/*.req $(BIN_DIR)/iotpolicy/
+ cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler espsprinkler.pol smartsprinkler.req -java Java
+
+PHONY += run-compiler-wgw
+run-compiler-wgw:
+ cp ../localconfig/iotpolicy/WeatherPhoneGateway/*.pol $(BIN_DIR)/iotpolicy/
+ cp ../localconfig/iotpolicy/WeatherPhoneGateway/*.req $(BIN_DIR)/iotpolicy/
+ cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler weatherphonegateway.pol smartweathergateway.req weathergatewaycallback.pol smartweathergatewaycallback.req -java Java
+
+PHONY += run-compiler-moist
+run-compiler-moist:
+ cp ../localconfig/iotpolicy/SpruceSensor/*.pol $(BIN_DIR)/iotpolicy/
+ cp ../localconfig/iotpolicy/SpruceSensor/*.req $(BIN_DIR)/iotpolicy/
+ cd $(BIN_DIR)/iotpolicy; $(JAVA) -cp .:..:../$(PARSERJARS):../$(BIN_DIR) iotpolicy.IoTCompiler sprucesensor.pol smartsensor.req moisturesensorcallback.pol moisturesensorcallback.req -java Java
+
# TODO: Can remove this later - just to test-compile the resulted files from the compiler
PHONY += compile
compile:
--- /dev/null
+
+requires Sprinkler with Initialize, Zone as interface SprinklerSmart;
+
+++ /dev/null
-
-requires Sprinkler with Initialize, Zone as interface SprinklerSmart;
-
+++ /dev/null
-
-requires Lawn with Empty as interface LawnSmart;
-
--- /dev/null
+
+requires Lawn with Empty as interface LawnSmart;
+
--- /dev/null
+public interface MoistureSensorCallback {
+
+ public void newReadingAvailable(int sensorId, float moisture, long timeStampOfLastReading);
+
+ capability Callback {
+ description = "Callback method";
+ method = "newReadingAvailable(int sensorId, float moisture, long timeStampOfLastReading)";
+ }
+}
+
+
--- /dev/null
+
+requires MoistureSensorCallback with Callback as interface MoistureSensorSmartCallback;
+
+++ /dev/null
-public interface MoistureSensorCallback {
-
- public void newReadingAvailable(int sensorId, float moisture, long timeStampOfLastReading);
-
- capability Callback {
- description = "Callback method";
- method = "newReadingAvailable(int sensorId, float moisture, long timeStampOfLastReading)";
- }
-}
-
-
+++ /dev/null
-
-requires MoistureSensorCallback with Callback as interface SensorSmartCallback;
-
+++ /dev/null
-
-requires MoistureSensor with Initialize, Moisture, SensorId as interface SensorSmart;
-
--- /dev/null
+
+requires MoistureSensor with Initialize, Moisture, SensorId as interface MoistureSensorSmart;
+
--- /dev/null
+
+requires WeatherGateway with Initialize, WeatherUpdate as interface WeatherGatewaySmart;
+
--- /dev/null
+
+requires WeatherGatewayCallback with Callback as interface WeatherGatewaySmartCallback;
+
+++ /dev/null
-
-requires WeatherGatewayCallback with Callback as interface WeatherGWSmartCallback;
-
+++ /dev/null
-
-requires WeatherGateway with Initialize, WeatherUpdate as interface WeatherGatewaySmart;
-