--- /dev/null
+//Create a class for SmartThing
+package SmartThing
+
+//JPF's Verify API
+import gov.nasa.jpf.vm.Verify
+
+//Importing mutable integer class
+import MutableInteger.MutableInteger
+
+public class SmartThing {
+ List nonStoredDevices = ["aeonKeyFob", "appTouch", "button", "momentary", "nfcTouch"] // Devices with no stored value
+ def sendEventSmartThings
+
+ StringBuilder idSmartThing = new StringBuilder()
+ StringBuilder labelSmartThing = new StringBuilder()
+ StringBuilder displayNameSmartThing = new StringBuilder()
+ HashMap<String, StringBuilder> deviceValueSmartThing = new HashMap<String, StringBuilder>()
+ HashMap<String, MutableInteger> deviceIntValueSmartThing = new HashMap<String, MutableInteger>()
+ List<StringBuilder> possibleValuesSmartThings = new ArrayList<StringBuilder>();
+
+ // Method for handling events
+ def setValue(LinkedHashMap eventDataMap) {
+ def name = eventDataMap["name"]
+ def tmpID = eventDataMap["deviceId"]
+ def value = eventDataMap["value"]
+
+ if (deviceValueSmartThing.containsKey(name)) {
+ StringBuilder tmpStr = deviceValueSmartThing.get(name)
+ if (!value.equals(tmpStr.toString())) {
+ tmpStr.replace(0, tmpStr.length(), value)
+ println("the $name with id:$tmpID is triggered to $value!")
+ sendEventSmartThings(eventDataMap)
+ }
+ } else if (deviceIntValueSmartThing.containsKey(name)) {
+ MutableInteger tmpInt = deviceIntValueSmartThing.get(name)
+ if (!value.equals(tmpInt.getValue())) {
+ tmpInt.setValue(value)
+ println("the $name with id:$tmpID is triggered to $value!")
+ sendEventSmartThings(eventDataMap)
+ }
+ } else if (nonStoredDevices.contains(name)) {
+ println("the $name with id:$tmpID is triggered to $value!")
+ sendEventSmartThings(eventDataMap)
+ }
+ }
+
+ def statesSince() {
+ eventsSince()
+ }
+
+ def eventsSince() {
+ if (labelSmartThing.toString().equals("humidity") || labelSmartThing.toString().equals("temperature")) {
+ sendCurrentValue()
+ } else {
+ sendPossibleValues()
+ }
+ }
+
+ def sendCurrentValue() {
+ def label = labelSmartThing.toString()
+ def evtTemp = [[name: label, value: deviceIntValueSmartThing.get(label).getValue(), deviceId: idSmartThing.toString(), descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}']]
+ def init = Verify.getInt(0,1)
+ def evtToSend = []
+ if (init == 0) {// return empty set
+ return evtToSend
+ } else if (init == 1) {// send one open event
+ evtTemp.each{
+ evtToSend.add(it)
+ }
+ return evtToSend
+ }
+ }
+
+ def sendPossibleValues() {
+ def evtA = [[name: labelSmartThing.toString(), value: possibleValuesSmartThings[0].toString(), deviceId: idSmartThing.toString(), descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}']]
+ def evtB = [[name: labelSmartThing.toString(), value: possibleValuesSmartThings[1].toString(), deviceId: idSmartThing.toString(), descriptionText: "",
+ displayed: true, linkText: "", isStateChange: false, unit: "", data: '{"info": "info"}']]
+ def init = Verify.getInt(0,4)
+ def evtToSend = []
+ if (init == 0) {// return empty set
+ return evtToSend
+ } else if (init == 1) {// send one event A
+ evtA.each{
+ evtToSend.add(it)
+ }
+ return evtToSend
+ } else if (init == 2) {// send two events A
+ evtA.each{
+ evtToSend.add(it)
+ }
+ evtA.each{
+ evtToSend.add(it)
+ }
+ return evtToSend
+ } else if (init == 3) {// send one event B
+ evtB.each{
+ evtToSend.add(it)
+ }
+ return evtToSend
+ } else if (init == 4) {// send two events B
+ evtB.each{
+ evtToSend.add(it)
+ }
+ evtB.each{
+ evtToSend.add(it)
+ }
+ return evtToSend
+ }
+ }
+
+ // Methods to return values
+ def currentState(String deviceFeature) {
+ return [rawDateCreated: [time: System.currentTimeMillis()]]
+ }
+
+ def currentValue(String deviceFeature) {
+ if (deviceValueSmartThing.containsKey(deviceFeature)) {
+ return deviceValueSmartThing.get(deviceFeature).toString()
+ } else if (deviceIntValueSmartThing.containsKey(deviceFeature)) {
+ return deviceIntValueSmartThing.get(deviceFeature).getValue()
+ } else {
+ println("Wrong device feature is sent to this method!")
+ }
+ }
+
+ def latestValue(String deviceFeature) {
+ currentValue(deviceFeature)
+ }
+
+ def getId() {
+ return idSmartThing.toString()
+ }
+
+ def getLabel() {
+ return labelSmartThing.toString()
+ }
+
+ def getDisplayName() {
+ return displayNameSmartThing.toString()
+ }
+}
--- /dev/null
+//Create a class for SmartThings
+package SmartThing
+
+//Importing mutable integer class
+import MutableInteger.MutableInteger
+
+class SmartThings {
+ List smartThings = new ArrayList()
+
+ // Methods for closures
+ def count(Closure Input) {
+ smartThings.count(Input)
+ }
+
+ def size() {
+ smartThings.size()
+ }
+
+ def each(Closure Input) {
+ smartThings.each(Input)
+ }
+
+ def find(Closure Input) {
+ smartThings.find(Input)
+ }
+
+ def sort(Closure Input) {
+ smartThings.sort(Input)
+ }
+
+ def collect(Closure Input) {
+ smartThings.collect(Input)
+ }
+
+ // Methods to handle events
+ def eventsSince(Date dateObj) {
+ return smartThings[0].eventsSince()
+ }
+
+ def statesSince(String info, Date dateObj) {
+ return smartThings[0].statesSince()
+ }
+
+ // Methods to return states of the devices
+ def currentState(String deviceFeature) {
+ List tmpValues = new ArrayList()
+ tmpValues.add(smartThings[0].currentState(deviceFeature))
+ return tmpValues
+ }
+
+ def currentValue(String deviceFeature) {
+ List tmpValues = new ArrayList()
+ tmpValues.add(smartThings[0].currentValue(deviceFeature))
+ return tmpValues
+ }
+
+ def latestValue(String deviceFeature) {
+ List tmpValues = new ArrayList()
+ tmpValues.add(smartThings[0].latestValue(deviceFeature))
+ return tmpValues
+ }
+
+ def getAt(int ix) {
+ smartThings[ix]
+ }
+}