From: amiraj Date: Thu, 25 Jul 2019 19:03:32 +0000 (-0700) Subject: Commit #10: more classes X-Git-Url: http://plrg.eecs.uci.edu/git/?p=smartthings-infrastructure.git;a=commitdiff_plain;h=c3be64e00452e6b9789207f5746ab4089fcf1f0f Commit #10: more classes --- diff --git a/AccelerationSensor/AccelerationSensor.groovy b/AccelerationSensor/AccelerationSensor.groovy new file mode 100644 index 0000000..1bec3cd --- /dev/null +++ b/AccelerationSensor/AccelerationSensor.groovy @@ -0,0 +1,55 @@ +//Create a class for acceleration sensor +package AccelerationSensor +import Timer.SimulatedTimer + +public class AccelerationSensor { + private String id + private String label + private String displayName + private String acceleration + private String currentAcceleration + private String accelerationLatestValue + private List states = [] + private List timeOfStates = [] + + AccelerationSensor(String id, String label, String displayName, String acceleration, String accelerationLatestValue) { + this.id = id + this.label = label + this.displayName = displayName + this.acceleration = acceleration + this.currentAcceleration = acceleration + this.accelerationLatestValue = accelerationLatestValue + } + + def setValue(String value) { + this.accelerationLatestValue = acceleration + println("the acceleration sensor with id:$id is triggered to $value!") + this.acceleration = value + this.currentAcceleration = value + this.states.add(value) + this.timeOfStates.add(System.currentTimeMillis()) + } + + def statesSince(String info, Date dateObj) { + def List happenedStates = [] + def sinceThen = dateObj.time + for (int i = 0;i < timeOfStates.size();i++) { + if (timeOfStates[i]>=sinceThen) + happenedStates.add(states[i]) + } + return happenedStates + } + + + def currentValue(String deviceFeature) { + if (deviceFeature == "acceleration") { + return acceleration + } + } + + def latestValue(String deviceFeature) { + if (deviceFeature == "acceleration") { + return accelerationLatestValue + } + } +} diff --git a/AccelerationSensor/AccelerationSensors.groovy b/AccelerationSensor/AccelerationSensors.groovy new file mode 100644 index 0000000..0d3c14f --- /dev/null +++ b/AccelerationSensor/AccelerationSensors.groovy @@ -0,0 +1,71 @@ +//Create a class for acceleration sensor +package AccelerationSensor +import Timer.SimulatedTimer + +public class AccelerationSensors { + private int deviceNumbers + private List accelerationSensors + def sendEvent + + //For one device(We cannot have obj.id)-> We should have obj[0].id + private String id = "accelerationSensorID0" + private String label = "accelerationSensor0" + private String displayName = "accelerationSensor0" + private String acceleration = "inactive" + private String currentAcceleration = "inactive" + private String accelerationLatestValue = "inactive" + + + AccelerationSensors(Closure sendEvent, int deviceNumbers) { + this.sendEvent = sendEvent + this.deviceNumbers = deviceNumbers + this.accelerationSensors = [] + + accelerationSensors.add(new AccelerationSensor(id, label, displayName, this.acceleration, this.accelerationLatestValue)) + } + + //By Model Checker + def setValue(LinkedHashMap eventDataMap) { + if (eventDataMap["value"] != accelerationSensors[0].acceleration) { + accelerationSensors[0].setValue(eventDataMap["value"]) + this.accelerationLatestValue = accelerationSensors[0].accelerationLatestValue + this.acceleration = accelerationSensors[0].acceleration + this.currentAcceleration = accelerationSensors[0].acceleration + sendEvent(eventDataMap) + } + } + + //Methods for closures + def count(Closure Input) { + accelerationSensors.count(Input) + } + def size() { + accelerationSensors.size() + } + def each(Closure Input) { + accelerationSensors.each(Input) + } + def find(Closure Input) { + accelerationSensors.find(Input) + } + def collect(Closure Input) { + accelerationSensors.collect(Input) + } + + + def currentValue(String deviceFeature) { + accelerationSensors[0].currentValue(deviceFeature)//It is called if we have only one device + } + + def latestValue(String deviceFeature) { + accelerationSensors[0].latestValue(deviceFeature)//It is called if we have only one device + } + + def statesSince(String info, Date dateObj) { + return accelerationSensors[0].statesSince(info, dateObj) + } + + def getAt(int ix) { + accelerationSensors[ix] + } +} diff --git a/Alarm/Alarm.groovy b/Alarm/Alarm.groovy index 00f4169..a78c3c2 100644 --- a/Alarm/Alarm.groovy +++ b/Alarm/Alarm.groovy @@ -24,6 +24,15 @@ public class Alarm { this.alarmLatestValue = alarmLatestValue } + //By model checker + def setValue(String value) { + this.alarmLatestValue = alarm + println("the alarm with id:$id is triggered to $value!") + this.alarm = value + this.currentAlarm = value + } + + //By Apps def both() { println("the alarm with id:$id is changed to both!") diff --git a/Alarm/Alarms.groovy b/Alarm/Alarms.groovy index 9be6569..2eb775e 100644 --- a/Alarm/Alarms.groovy +++ b/Alarm/Alarms.groovy @@ -24,6 +24,17 @@ public class Alarms { alarms.add(new Alarm(sendEvent, id, label, displayName, this.alarm, this.currentAlarm, this.alarmLatestValue)) } + + //By Model Checker + def setValue(LinkedHashMap eventDataMap) { + if (eventDataMap["value"] != alarms[0].alarm) { + alarms[0].setValue(eventDataMap["value"]) + this.alarmLatestValue = alarms[0].alarmLatestValue + this.alarm = alarms[0].alarm + this.currentAlarm = alarms[0].alarm + sendEvent(eventDataMap) + } + } //Methods for closures def count(Closure Input) { diff --git a/Battery/Batteries.groovy b/Battery/Batteries.groovy new file mode 100644 index 0000000..ce4a187 --- /dev/null +++ b/Battery/Batteries.groovy @@ -0,0 +1,61 @@ +//Create a class for battery +package Battery +import Timer.SimulatedTimer + +public class Batteries { + private int deviceNumbers + private List batteries + def sendEvent + + //For one device(We cannot have obj.id)-> We should have obj[0].id + private String id = "batteryID0" + private String label = "battery0" + private String displayName = "battery0" + private int battery = 50 + private String currentBattery = 50 + + + Batteries(Closure sendEvent, int deviceNumbers) { + this.sendEvent = sendEvent + this.deviceNumbers = deviceNumbers + this.batteries = [] + + batteries.add(new Battery(id, label, displayName, this.battery)) + } + + //By Model Checker + def setValue(LinkedHashMap eventDataMap) { + if (eventDataMap["value"] != batteries[0].battery) { + batteries[0].setValue(eventDataMap["value"]) + this.battery = batteries[0].battery + this.currentBattery = batteries[0].battery + sendEvent(eventDataMap) + } + } + + //Methods for closures + def count(Closure Input) { + batteries.count(Input) + } + def size() { + batteries.size() + } + def each(Closure Input) { + batteries.each(Input) + } + def find(Closure Input) { + batteries.find(Input) + } + def collect(Closure Input) { + batteries.collect(Input) + } + + + def currentValue(String deviceFeature) { + batteries[0].currentValue(deviceFeature)//It is called if we have only one device + } + + def getAt(int ix) { + batteries[ix] + } +} diff --git a/Battery/Battery.groovy b/Battery/Battery.groovy new file mode 100644 index 0000000..df299eb --- /dev/null +++ b/Battery/Battery.groovy @@ -0,0 +1,33 @@ +//Create a class for battery +package Battery +import Timer.SimulatedTimer + +public class Battery { + private String id + private String label + private String displayName + private String battery + private String currentBattery + + Battery(String id, String label, String displayName, String battery) { + this.id = id + this.label = label + this.displayName = displayName + this.battery = battery + this.currentBattery = battery + } + + //By Model Checker + def setValue(String value) { + println("the battery level with id:$id is changed to $value!") + this.battery = value.toInteger() + this.currentBattery = value.toInteger() + } + + def currentValue(String deviceFeature) { + if (deviceFeature == "battery") { + return battery + } + } + +} diff --git a/BeaconSensor/BeaconSensor.groovy b/BeaconSensor/BeaconSensor.groovy new file mode 100644 index 0000000..5f07e4c --- /dev/null +++ b/BeaconSensor/BeaconSensor.groovy @@ -0,0 +1,41 @@ +//Create a class for beacon sensor +package BeaconSensor +import Timer.SimulatedTimer + +public class BeaconSensor { + private String id + private String label + private String displayName + private String presence + private String currentPresence + private String presenceLatestValue + + BeaconSensor(String id, String label, String displayName, String presence, String presenceLatestValue) { + this.id = id + this.label = label + this.displayName = displayName + this.presence = presence + this.currentPresence = presence + this.presenceLatestValue = presenceLatestValue + } + + def setValue(String value) { + this.presenceLatestValue = presence + println("the beacon sensor with id:$id is triggered to $value!") + this.presence = value + this.currentPresence = value + } + + + def currentValue(String deviceFeature) { + if (deviceFeature == "beacon") { + return presence + } + } + + def latestValue(String deviceFeature) { + if (deviceFeature == "beacon") { + return presenceLatestValue + } + } +} diff --git a/BeaconSensor/BeaconSensors.groovy b/BeaconSensor/BeaconSensors.groovy new file mode 100644 index 0000000..24bcfc8 --- /dev/null +++ b/BeaconSensor/BeaconSensors.groovy @@ -0,0 +1,67 @@ +//Create a class for beacon sensor +package BeaconSensor +import Timer.SimulatedTimer + +public class BeaconSensors { + private int deviceNumbers + private List beaconSensors + def sendEvent + + //For one device(We cannot have obj.id)-> We should have obj[0].id + private String id = "beaconSensorID0" + private String label = "beaconSensor0" + private String displayName = "beaconSensor0" + private String presence = "not present" + private String currentPresence = "not present" + private String presenceLatestValue = "not present" + + + BeaconSensors(Closure sendEvent, int deviceNumbers) { + this.sendEvent = sendEvent + this.deviceNumbers = deviceNumbers + this.beaconSensors = [] + + beaconSensors.add(new BeaconSensor(id, label, displayName, this.presence, this.presenceLatestValue)) + } + + //By Model Checker + def setValue(LinkedHashMap eventDataMap) { + if (eventDataMap["value"] != beaconSensors[0].presence) { + beaconSensors[0].setValue(eventDataMap["value"]) + this.presenceLatestValue = beaconSensors[0].presenceLatestValue + this.presence = beaconSensors[0].presence + this.currentPresence = beaconSensors[0].presence + sendEvent(eventDataMap) + } + } + + //Methods for closures + def count(Closure Input) { + beaconSensors.count(Input) + } + def size() { + beaconSensors.size() + } + def each(Closure Input) { + beaconSensors.each(Input) + } + def find(Closure Input) { + beaconSensors.find(Input) + } + def collect(Closure Input) { + beaconSensors.collect(Input) + } + + + def currentValue(String deviceFeature) { + beaconSensors[0].currentValue(deviceFeature)//It is called if we have only one device + } + + def latestValue(String deviceFeature) { + beaconSensors[0].latestValue(deviceFeature)//It is called if we have only one device + } + + def getAt(int ix) { + beaconSensors[ix] + } +} diff --git a/CarbonMonoxideDetector/CarbonMonoxideDetector.groovy b/CarbonMonoxideDetector/CarbonMonoxideDetector.groovy new file mode 100644 index 0000000..2943479 --- /dev/null +++ b/CarbonMonoxideDetector/CarbonMonoxideDetector.groovy @@ -0,0 +1,41 @@ +//Create a class for carbon monoxide detector +package CarbonMonoxideDetector +import Timer.SimulatedTimer + +public class CarbonMonoxideDetector { + private String id + private String label + private String displayName + private String carbonMonoxide + private String currentCarbonMonoxideValue + private String carbonMonoxideLatestValue + + CarbonMonoxideDetector(String id, String label, String displayName, String carbonMonoxide, String carbonMonoxideLatestValue) { + this.id = id + this.label = label + this.displayName = displayName + this.carbonMonoxide = carbonMonoxide + this.currentCarbonMonoxideValue = carbonMonoxide + this.carbonMonoxideLatestValue = carbonMonoxideLatestValue + } + + def setValue(String value) { + this.carbonMonoxideLatestValue = carbonMonoxide + println("the carbon monoxide detector with id:$id is triggered to $value!") + this.carbonMonoxide = value + this.currentCarbonMonoxideValue = value + } + + + def currentValue(String deviceFeature) { + if (deviceFeature == "carbonMonoxide") { + return currentCarbonMonoxideValue + } + } + + def latestValue(String deviceFeature) { + if (deviceFeature == "carbonMonoxide") { + return carbonMonoxideLatestValue + } + } +} diff --git a/CarbonMonoxideDetector/CarbonMonoxideDetectors.groovy b/CarbonMonoxideDetector/CarbonMonoxideDetectors.groovy new file mode 100644 index 0000000..7e848e3 --- /dev/null +++ b/CarbonMonoxideDetector/CarbonMonoxideDetectors.groovy @@ -0,0 +1,67 @@ +//Create a class for carbon monoxide detector +package CarbonMonoxideDetector +import Timer.SimulatedTimer + +public class CarbonMonoxideDetectors { + private int deviceNumbers + private List carbonMonoxideDetectors + def sendEvent + + //For one device(We cannot have obj.id)-> We should have obj[0].id + private String id = "carbonMonoxideDetectorID0" + private String label = "carbonMonoxideDetector0" + private String displayName = "carbonMonoxideDetector0" + private String carbonMonoxide = "clear" + private String currentCarbonMonoxideValue = "clear" + private String carbonMonoxideLatestValue = "clear" + + + CarbonMonoxideDetectors(Closure sendEvent, int deviceNumbers) { + this.sendEvent = sendEvent + this.deviceNumbers = deviceNumbers + this.carbonMonoxideDetectors = [] + + carbonMonoxideDetectors.add(new CarbonMonoxideDetector(id, label, displayName, this.currentCarbonMonoxideValue, this.carbonMonoxideLatestValue)) + } + + //By Model Checker + def setValue(LinkedHashMap eventDataMap) { + if (eventDataMap["value"] != carbonMonoxideDetectors[0].currentCarbonMonoxideValue) { + carbonMonoxideDetectors[0].setValue(eventDataMap["value"]) + this.carbonMonoxideLatestValue = carbonMonoxideDetectors[0].carbonMonoxideLatestValue + this.carbonMonoxide = carbonMonoxideDetectors[0].currentCarbonMonoxideValue + this.currentCarbonMonoxideValue = carbonMonoxideDetectors[0].currentCarbonMonoxideValue + sendEvent(eventDataMap) + } + } + + //Methods for closures + def count(Closure Input) { + carbonMonoxideDetectors.count(Input) + } + def size() { + carbonMonoxideDetectors.size() + } + def each(Closure Input) { + carbonMonoxideDetectors.each(Input) + } + def find(Closure Input) { + carbonMonoxideDetectors.find(Input) + } + def collect(Closure Input) { + carbonMonoxideDetectors.collect(Input) + } + + + def currentValue(String deviceFeature) { + carbonMonoxideDetectors[0].currentValue(deviceFeature)//It is called if we have only one device + } + + def latestValue(String deviceFeature) { + carbonMonoxideDetectors[0].latestValue(deviceFeature)//It is called if we have only one device + } + + def getAt(int ix) { + carbonMonoxideDetectors[ix] + } +} diff --git a/ColorControl/ColorControl.groovy b/ColorControl/ColorControl.groovy new file mode 100644 index 0000000..1c2665c --- /dev/null +++ b/ColorControl/ColorControl.groovy @@ -0,0 +1,68 @@ +//Create a class for color control +package ColorControl +import Timer.SimulatedTimer + + +public class ColorControl { + private String id + private String label + private String displayName + private String color + private int hue + private int saturation + + ColorControl(String id, String label, String displayName, String color, int hue, int saturation) { + this.id = id + this.label = label + this.displayName = displayName + this.color = color + this.hue = hue + this.saturation = saturation + } + + //By model checker + def setValue(String value, String name) { + if (name == "color") { + this.color = value + println("the color of the light is changed to $value!") + } else if (name == "hue") { + this.hue = value.toInteger() + println("The hue level of the light is changed to $value!") + } else { + this.saturation = value.toInteger() + println("The saturation level of the light is changed to $value!") + } + } + + //methods + def setColor(String color) { + this.color = color + println("The color of the light is changed to $color!") + sendEvent([name: "color", value: "$color", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "$color"]]) + } + + def setHue(int hue) { + this.hue = hue + println("The hue level of the light is changed to $hue!") + sendEvent([name: "hue", value: "$hue", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "$hue"]]) + } + + def setSaturation(int saturation) { + this.saturation = saturation + println("The saturation level of the light is changed to $saturation!") + sendEvent([name: "saturation", value: "$saturation", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "$saturation"]]) + } + + def currentValue(String deviceFeature) { + if (deviceFeature == "color") { + return color + } else if (deviceFeature == "saturation") { + return saturation + } else if (deviceFeature == "hue") { + return hue + } + } +} diff --git a/ColorControl/ColorControls.groovy b/ColorControl/ColorControls.groovy new file mode 100644 index 0000000..b3a6471 --- /dev/null +++ b/ColorControl/ColorControls.groovy @@ -0,0 +1,92 @@ +//Create a class for color control +package ColorControl +import Timer.SimulatedTimer + + +public class ColorControls { + private int deviceNumbers + private List colorControls + def sendEvent + + //For one device(We cannot have obj.id)-> We should have obj[0].id + private String id = "colorControlID0" + private String label = "colorControl0" + private String displayName = "colorControl0" + private String color = "red" + private int hue = 50 + private int saturation = 50 + + + ColorControls(Closure sendEvent, int deviceNumbers) { + this.sendEvent = sendEvent + this.deviceNumbers = deviceNumbers + this.colorControls = [] + + colorControls.add(new ColorControl(id, label, displayName, this.color, this.hue, this.saturation)) + } + + //Methods for closures + def count(Closure Input) { + colorControls.count(Input) + } + def size() { + colorControls.size() + } + def each(Closure Input) { + colorControls.each(Input) + } + def find(Closure Input) { + colorControls.find(Input) + } + def collect(Closure Input) { + colorControls.collect(Input) + } + + //By model checker + def setValue(LinkedHashMap eventDataMap) { + if (eventDataMap["name"] == "color") { + if (eventDataMap["value"] != colorControls[0].color) { + colorControls[0].setValue(eventDataMap["value"], "color") + this.color = colorControls[0].color + sendEvent(eventDataMap) + } + } else if (eventDataMap["name"] == "hue") { + if (eventDataMap["value"] != colorControls[0].hue) { + colorControls[0].setValue(eventDataMap["value"], "hue") + this.hue = colorControls[0].hue + sendEvent(eventDataMap) + } + } else { + if (eventDataMap["value"] != colorControls[0].saturation) { + colorControls[0].setValue(eventDataMap["value"], "saturation") + this.saturation = colorControls[0].saturation + sendEvent(eventDataMap) + } + } + } + + + //methods + def setColor(String color) { + colorControls[0].setColor(color) + this.color = color + } + + def setHue(int hue) { + colorControls[0].setHue(hue) + this.hue = hue + } + + def setSaturation(int saturation) { + colorControls[0].setSaturation(saturation) + this.saturation = saturation + } + + def currentValue(String deviceFeature) { + colorControls[0].currentValue(deviceFeature) + } + + def getAt(int ix) { + colorControls[ix] + } +} diff --git a/EnergyMeter/EnergyMeter.groovy b/EnergyMeter/EnergyMeter.groovy new file mode 100644 index 0000000..0274eef --- /dev/null +++ b/EnergyMeter/EnergyMeter.groovy @@ -0,0 +1,31 @@ +//Create a class for energy meter +package EnergyMeter +import Timer.SimulatedTimer + +public class EnergyMeter { + private String id + private String label + private String displayName + private String energy + + EnergyMeter(String id, String label, String displayName, String energy) { + this.id = id + this.label = label + this.displayName = displayName + this.energy = energy + } + + //By Model Checker + def setValue(String value) { + println("the enery is changed to $value!") + this.battery = value.toInteger() + this.currentBattery = value.toInteger() + } + + def currentValue(String deviceFeature) { + if (deviceFeature == "energy") { + return energy + } + } + +} diff --git a/EnergyMeter/EnergyMeters.groovy b/EnergyMeter/EnergyMeters.groovy new file mode 100644 index 0000000..caec875 --- /dev/null +++ b/EnergyMeter/EnergyMeters.groovy @@ -0,0 +1,59 @@ +//Create a class for energy meter +package EnergyMeter +import Timer.SimulatedTimer + +public class EnergyMeters { + private int deviceNumbers + private List energyMeters + def sendEvent + + //For one device(We cannot have obj.id)-> We should have obj[0].id + private String id = "energyMeterID0" + private String label = "energyMeter0" + private String displayName = "energyMeter0" + private int energy = 50 + + + EnergyMeters(Closure sendEvent, int deviceNumbers) { + this.sendEvent = sendEvent + this.deviceNumbers = deviceNumbers + this.energyMeters = [] + + energyMeters.add(new EnergyMeter(id, label, displayName, this.energy)) + } + + //By Model Checker + def setValue(LinkedHashMap eventDataMap) { + if (eventDataMap["value"] != energyMeters[0].energy) { + energyMeters[0].setValue(eventDataMap["value"]) + this.energy = energyMeters[0].energy + sendEvent(eventDataMap) + } + } + + //Methods for closures + def count(Closure Input) { + energyMeters.count(Input) + } + def size() { + energyMeters.size() + } + def each(Closure Input) { + energyMeters.each(Input) + } + def find(Closure Input) { + energyMeters.find(Input) + } + def collect(Closure Input) { + energyMeters.collect(Input) + } + + + def currentValue(String deviceFeature) { + energyMeters[0].currentValue(deviceFeature)//It is called if we have only one device + } + + def getAt(int ix) { + energyMeters[ix] + } +} diff --git a/Event/Event.groovy b/Event/Event.groovy index 8c1d1c9..1ef8f77 100644 --- a/Event/Event.groovy +++ b/Event/Event.groovy @@ -13,6 +13,7 @@ public class Event { private String unit private LinkedHashMap data private int integerValue + private List integerValues = ["battery", "hue", "saturation", "energy", "level", "temperature", "heatingSetpoint", "coolingSetpoint", "thermostatSetpoint"] Event(String value, String name, String deviceId, String descriptionText, boolean displayed, String linkText, String displayName, boolean isStateChange, String unit, LinkedHashMap data) { this.deviceId = deviceId @@ -25,7 +26,7 @@ public class Event { this.unit = unit this.data = data this.displayed = displayed - if (name == "battery") + if (integerValues.contains(name)) this.integerValue = value.toInteger() } } diff --git a/Extractor/App1/App1.groovy b/Extractor/App1/App1.groovy index 718d69e..299b494 100644 --- a/Extractor/App1/App1.groovy +++ b/Extractor/App1/App1.groovy @@ -1,5 +1,7 @@ /** - * Copyright 2015 SmartThings + * Lock it at a specific time + * + * Copyright 2014 Erik Thayer * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at: @@ -10,128 +12,75 @@ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License * for the specific language governing permissions and limitations under the License. * - * Make it So - * - * Author: SmartThings - * Date: 2013-03-06 */ definition( - name: "Make It So", - namespace: "smartthings", - author: "SmartThings", - description: "Saves the states of a specified set switches and thermostat setpoints and restores them at each mode change. To use 1) Set the mode, 2) Change switches and setpoint to where you want them for that mode, and 3) Install or update the app. Changing to that mode or touching the app will set the devices to the saved state.", - category: "Convenience", - iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/light_thermo-switch.png", - iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/light_thermo-switch@2x.png" + name: "Lock it at a specific time", + namespace: "user8798", + author: "Erik Thayer", + description: "Make sure a door is locked at a specific time. Option to add door contact sensor to only lock if closed.", + category: "Safety & Security", + iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png", + iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png" ) + preferences { - section("Switches") { - input "switches", "capability.switch", multiple: true, required: false - } - section("Thermostats") { - input "thermostats", "capability.thermostat", multiple: true, required: false - } - section("Locks") { - input "locks", "capability.lock", multiple: true, required: false - } + section("At this time every day") { + input "time", "time", title: "Time of Day" + } + section("Make sure this is locked") { + input "lock","capability.lock" + } + section("Make sure it's closed first..."){ + input "contact", "capability.contactSensor", title: "Which contact sensor?", required: false + } + section( "Notifications" ) { + input "sendPushMessage", "enum", title: "Send a push notification?", metadata:[values:["Yes", "No"]], required: false + input "phone", "phone", title: "Send a text message?", required: false + } } - def installed() { - subscribe(location, changedLocationMode) - subscribe(app, appTouch) - saveState() -} + schedule(time, "setTimeCallback") -def updated() { - unsubscribe() - subscribe(location, changedLocationMode) - subscribe(app, appTouch) - saveState() } -def appTouch(evt) -{ - restoreState(currentMode) +def updated(settings) { + unschedule() + schedule(time, "setTimeCallback") } -def changedLocationMode(evt) -{ - restoreState(evt.value) +def setTimeCallback() { + if (contact) { + doorOpenCheck() + } else { + lockMessage() + lock.lock() + } } - -private restoreState(mode) -{ - log.info "restoring state for mode '$mode'" - def map = state[mode] ?: [:] - switches?.each { - def value = map[it.id] - if (value?.switch == "on") { - def level = value.level - if (level) { - log.debug "setting $it.label level to $level" - it.setLevel(level) - } - else { - log.debug "turning $it.label on" - it.on() - } - } - else if (value?.switch == "off") { - log.debug "turning $it.label off" - it.off() - } - } - - thermostats?.each { - def value = map[it.id] - if (value?.coolingSetpoint) { - log.debug "coolingSetpoint = $value.coolingSetpoint" - it.setCoolingSetpoint(value.coolingSetpoint) - } - if (value?.heatingSetpoint) { - log.debug "heatingSetpoint = $value.heatingSetpoint" - it.setHeatingSetpoint(value.heatingSetpoint) - } - } - - locks?.each { - def value = map[it.id] - if (value) { - if (value?.locked) { - it.lock() - } - else { - it.unlock() - } - } - } -} - - -private saveState() -{ - def mode = currentMode - def map = state[mode] ?: [:] - - switches?.each { - map[it.id] = [switch: it.currentSwitch, level: it.currentLevel] - } - - thermostats?.each { - map[it.id] = [coolingSetpoint: it.currentCoolingSetpoint, heatingSetpoint: it.currentHeatingSetpoint] - } - - locks?.each { - map[it.id] = [locked: it.currentLock == "locked"] - } - - state[mode] = map - log.debug "saved state for mode ${mode}: ${state[mode]}" - log.debug "state: $state" +def doorOpenCheck() { + def currentState = contact.contactState + if (currentState?.value == "open") { + def msg = "${contact.displayName} is open. Scheduled lock failed." + log.info msg + if (sendPushMessage) { + sendPush msg + } + if (phone) { + sendSms phone, msg + } + } else { + lockMessage() + lock.lock() + } } -private getCurrentMode() -{ - location.mode ?: "_none_" +def lockMessage() { + def msg = "Locking ${lock.displayName} due to scheduled lock." + log.info msg + if (sendPushMessage) { + sendPush msg + } + if (phone) { + sendSms phone, msg + } } diff --git a/Extractor/App1/extractedFunctionsApp1.groovy b/Extractor/App1/extractedFunctionsApp1.groovy index 577b4dc..854ab60 100644 --- a/Extractor/App1/extractedFunctionsApp1.groovy +++ b/Extractor/App1/extractedFunctionsApp1.groovy @@ -3,12 +3,8 @@ def installed = this.&installed //Global Object for functions in subscribe method! def updated = this.&updated //Global Object for functions in subscribe method! -def appTouch = this.&appTouch +def setTimeCallback = this.&setTimeCallback //Global Object for functions in subscribe method! -def changedLocationMode = this.&changedLocationMode +def doorOpenCheck = this.&doorOpenCheck //Global Object for functions in subscribe method! -def restoreState = this.&restoreState -//Global Object for functions in subscribe method! -def saveState = this.&saveState -//Global Object for functions in subscribe method! -def getCurrentMode = this.&getCurrentMode +def lockMessage = this.&lockMessage diff --git a/Extractor/App1/extractedObjectsApp1.groovy b/Extractor/App1/extractedObjectsApp1.groovy index 0680408..5d7c3e8 100644 --- a/Extractor/App1/extractedObjectsApp1.groovy +++ b/Extractor/App1/extractedObjectsApp1.groovy @@ -1,6 +1,10 @@ -//Object for class switch! -def switches -//Object for class thermostat! -def thermostats +//Global variable for time! +def time = "15:00" //Object for class lock! -def locks +def lock +//Object for class contactSensor! +def contact +//Global variable for enum! +def sendPushMessage = "Yes" +//Global variable for phone! +def phone = 9495379373 diff --git a/Extractor/App1/extractedObjectsConstructorApp1.groovy b/Extractor/App1/extractedObjectsConstructorApp1.groovy index ebcafcc..7c95ca5 100644 --- a/Extractor/App1/extractedObjectsConstructorApp1.groovy +++ b/Extractor/App1/extractedObjectsConstructorApp1.groovy @@ -1,5 +1,4 @@ -switches = obj.switchObject -thermostats = obj.thermostatObject -locks = obj.lockObject +lock = obj.lockObject +contact = obj.contactObject //Global variable for settings! -settings = [app:app, switches:switches, thermostats:thermostats, locks:locks] +settings = [app:app, time:time, lock:lock, contact:contact, sendPushMessage:sendPushMessage, phone:phone] diff --git a/Extractor/App2/extractedObjectsApp2.groovy b/Extractor/App2/extractedObjectsApp2.groovy index 781ac82..e542362 100644 --- a/Extractor/App2/extractedObjectsApp2.groovy +++ b/Extractor/App2/extractedObjectsApp2.groovy @@ -11,4 +11,4 @@ def masterSwitch = "Yes" //Global variable for enum! def masterLock = "Yes" //Global variable for enum! -def masterDoor = "No" +def masterDoor = "Yes" diff --git a/Extractor/Extractor.groovy b/Extractor/Extractor.groovy index 65dcafa..fe17f71 100644 --- a/Extractor/Extractor.groovy +++ b/Extractor/Extractor.groovy @@ -36,6 +36,18 @@ import Alarm.Alarm import Alarm.Alarms import SpeechSynthesis.SpeechSynthesis import SpeechSynthesis.SpeechSynthesises +import AccelerationSensor.AccelerationSensor +import AccelerationSensor.AccelerationSensors +import Battery.Battery +import Battery.Batteries +import BeaconSensor.BeaconSensor +import BeaconSensor.BeaconSensors +import CarbonMonoxideDetector.CarbonMonoxideDetector +import CarbonMonoxideDetector.CarbonMonoxideDetectors +import ColorControl.ColorControl +import ColorControl.ColorControls +import EnergyMeter.EnergyMeter +import EnergyMeter.EnergyMeters import Timer.SimulatedTimer //GlobalVariables @@ -69,7 +81,6 @@ if (App == "App1") { - //Global objects //Global Object for class Touch Sensor! @Field touchSensorObjects = 0 @@ -111,7 +122,7 @@ if (App == "App1") { @Field def musicPlayerObject0 @Field def musicPlayerObject1 @Field def musicPlayerObject2 -//Global Object for class music player! +//Global Object for class aeon key fob! @Field aeonKeyFobObjects = 0 @Field def aeonKeyFobObject0 @Field def aeonKeyFobObject1 @@ -136,11 +147,42 @@ if (App == "App1") { @Field def alarmObject0 @Field def alarmObject1 @Field def alarmObject2 -//Global Object for class alarm! +//Global Object for class speech synthesis! @Field speechSynthesisObjects = 0 @Field def speechSynthesisObject0 @Field def speechSynthesisObject1 @Field def speechSynthesisObject2 +//Global Object for class acceleration sensor! +@Field accelerationSensorObjects = 0 +@Field def accelerationSensorObject0 +@Field def accelerationSensorObject1 +@Field def accelerationSensorObject2 +//Global Object for class battery! +@Field batteryObjects = 0 +@Field def batteryObject0 +@Field def batteryObject1 +@Field def batteryObject2 +//Global Object for class beacon sensor! +@Field beaconSensorObjects = 0 +@Field def beaconSensorObject0 +@Field def beaconSensorObject1 +@Field def beaconSensorObject2 +//Global Object for class carbon monoxide detector! +@Field carbonMonoxideDetectorObjects = 0 +@Field def carbonMonoxideDetectorObject0 +@Field def carbonMonoxideDetectorObject1 +@Field def carbonMonoxideDetectorObject2 +//Global Object for class color control! +@Field colorControlObjects = 0 +@Field def colorControlObject0 +@Field def colorControlObject1 +@Field def colorControlObject2 +//Global Object for class energy meter! +@Field energyMeterObjects = 0 +@Field def energyMeterObject0 +@Field def energyMeterObject1 +@Field def energyMeterObject2 + //Global variables @@ -304,12 +346,108 @@ def input(LinkedHashMap metaData) { } break case "capability.battery": + if (batteryObjects == 0) { + batteryObject0 = metaData['name'] + this[batteryObject0] = new Batteries({}, 1) + } else if (batteryObjects == 1) { + batteryObject1 = metaData['name'] + this[batteryObject1] = new Batteries({}, 1) + } else if (batteryObjects == 2) { + batteryObject2 = metaData['name'] + this[batteryObject2] = new Batteries({}, 1) + } + + batteryObjects=batteryObjects+1 + + settings.put(metaData['name'], metaData['name']) + + if (App == "App1") { + extractedObjectsApp1.append("//Object for class Battery!\n") + extractedObjectsApp1.append("def "+metaData['name']+"\n") + extractedObjectsConstructorApp1.append(metaData['name']+" = obj.batteryObject\n") + } else { + extractedObjectsApp2.append("//Object for class Battery!\n") + extractedObjectsApp2.append("def "+metaData['name']+"\n") + extractedObjectsConstructorApp2.append(metaData['name']+" = obj.batteryObject\n") + } break case "capability.beacon": + if (beaconSensorObjects == 0) { + beaconSensorObject0 = metaData['name'] + this[beaconSensorObject0] = new BeaconSensors({}, 1) + } else if (beaconSensorObjects == 1) { + beaconSensorObject1 = metaData['name'] + this[beaconSensorObject1] = new BeaconSensors({}, 1) + } else if (beaconSensorObjects == 2) { + beaconSensorObject2 = metaData['name'] + this[beaconSensorObject2] = new BeaconSensors({}, 1) + } + + beaconSensorObjects=beaconSensorObjects+1 + + settings.put(metaData['name'], metaData['name']) + + if (App == "App1") { + extractedObjectsApp1.append("//Object for class beacon sensor!\n") + extractedObjectsApp1.append("def "+metaData['name']+"\n") + extractedObjectsConstructorApp1.append(metaData['name']+" = obj.beaconSensorObject\n") + } else { + extractedObjectsApp2.append("//Object for class beacon sensor!\n") + extractedObjectsApp2.append("def "+metaData['name']+"\n") + extractedObjectsConstructorApp2.append(metaData['name']+" = obj.beaconSensorObject\n") + } break case "capability.carbonMonoxideDetector": + if (carbonMonoxideDetectorObjects == 0) { + carbonMonoxideDetectorObject0 = metaData['name'] + this[carbonMonoxideDetectorObject0] = new CarbonMonoxideDetectors({}, 1) + } else if (carbonMonoxideDetectorObjects == 1) { + carbonMonoxideDetectorObject1 = metaData['name'] + this[carbonMonoxideDetectorObject1] = new CarbonMonoxideDetectors({}, 1) + } else if (carbonMonoxideDetectorObjects == 2) { + carbonMonoxideDetectorObject2 = metaData['name'] + this[carbonMonoxideDetectorObject2] = new CarbonMonoxideDetectors({}, 1) + } + + carbonMonoxideDetectorObjects=carbonMonoxideDetectorObjects+1 + + settings.put(metaData['name'], metaData['name']) + + if (App == "App1") { + extractedObjectsApp1.append("//Object for class carbon monoxide detector!\n") + extractedObjectsApp1.append("def "+metaData['name']+"\n") + extractedObjectsConstructorApp1.append(metaData['name']+" = obj.carbonMonoxideDetectorObject\n") + } else { + extractedObjectsApp2.append("//Object for class carbon monoxide detector!\n") + extractedObjectsApp2.append("def "+metaData['name']+"\n") + extractedObjectsConstructorApp2.append(metaData['name']+" = obj.carbonMonoxideDetectorObject\n") + } break case "capability.colorControl": + if (colorControlObjects == 0) { + colorControlObject0 = metaData['name'] + this[colorControlObject0] = new ColorControls({}, 1) + } else if (colorControlObjects == 1) { + colorControlObject1 = metaData['name'] + this[colorControlObject1] = new ColorControls({}, 1) + } else if (colorControlObjects == 2) { + colorControlObject2 = metaData['name'] + this[colorControlObject2] = new ColorControls({}, 1) + } + + colorControlObjects=colorControlObjects+1 + + settings.put(metaData['name'], metaData['name']) + + if (App == "App1") { + extractedObjectsApp1.append("//Object for class color control!\n") + extractedObjectsApp1.append("def "+metaData['name']+"\n") + extractedObjectsConstructorApp1.append(metaData['name']+" = obj.colorControlObject\n") + } else { + extractedObjectsApp2.append("//Object for class color control!\n") + extractedObjectsApp2.append("def "+metaData['name']+"\n") + extractedObjectsConstructorApp2.append(metaData['name']+" = obj.colorControlObject\n") + } break case "capability.contactSensor": if (contactObjects == 0) { @@ -364,10 +502,58 @@ def input(LinkedHashMap metaData) { } break case "capability.energyMeter": + if (energyMeterObjects == 0) { + energyMeterObject0 = metaData['name'] + this[energyMeterObject0] = new EnergyMeters({}, 1) + } else if (energyMeterObjects == 1) { + energyMeterObject1 = metaData['name'] + this[energyMeterObject1] = new EnergyMeters({}, 1) + } else if (energyMeterObjects == 2) { + energyMeterObject2 = metaData['name'] + this[energyMeterObject2] = new EnergyMeters({}, 1) + } + + energyMeterObjects=energyMeterObjects+1 + + settings.put(metaData['name'], metaData['name']) + + if (App == "App1") { + extractedObjectsApp1.append("//Object for class energy meter!\n") + extractedObjectsApp1.append("def "+metaData['name']+"\n") + extractedObjectsConstructorApp1.append(metaData['name']+" = obj.energyMeterObject\n") + } else { + extractedObjectsApp2.append("//Object for class energy meter!\n") + extractedObjectsApp2.append("def "+metaData['name']+"\n") + extractedObjectsConstructorApp2.append(metaData['name']+" = obj.energyMeterObject\n") + } break case "capability.illuminanceMeasurement": break case "capability.accelerationSensor": + if (accelerationSensorObjects == 0) { + accelerationSensorObject0 = metaData['name'] + this[accelerationSensorObject0] = new AccelerationSensors({}, 1) + } else if (accelerationSensorObjects == 1) { + accelerationSensorObject1 = metaData['name'] + this[accelerationSensorObject1] = new AccelerationSensors({}, 1) + } else if (accelerationSensorObjects == 2) { + accelerationSensorObject2 = metaData['name'] + this[accelerationSensorObject2] = new AccelerationSensors({}, 1) + } + + accelerationSensorObjects=accelerationSensorObjects+1 + + settings.put(metaData['name'], metaData['name']) + + if (App == "App1") { + extractedObjectsApp1.append("//Object for class Acceleration Sensor!\n") + extractedObjectsApp1.append("def "+metaData['name']+"\n") + extractedObjectsConstructorApp1.append(metaData['name']+" = obj.accelerationSensorObject\n") + } else { + extractedObjectsApp2.append("//Object for class Acceleration Sensor!\n") + extractedObjectsApp2.append("def "+metaData['name']+"\n") + extractedObjectsConstructorApp2.append(metaData['name']+" = obj.accelerationSensorObject\n") + } break case "capability.motionSensor": if (motionSensorObjects == 0) { diff --git a/GlobalVariables/GlobalVariablesBothApps.groovy b/GlobalVariables/GlobalVariablesBothApps.groovy index 2110f72..6621df4 100644 --- a/GlobalVariables/GlobalVariablesBothApps.groovy +++ b/GlobalVariables/GlobalVariablesBothApps.groovy @@ -36,3 +36,15 @@ @Field def alarmObject = new Alarms(sendEvent, 1) //Global Object for class speech synthesis! @Field def speechSynthesisObject = new SpeechSynthesises(sendEvent, 1) +//Global Object for class acceleration sensor! +@Field def accelerationSensorObject = new AccelerationSensors(sendEvent, 1) +//Global Object for class Battery! +@Field def batteryObject = new Batteries(sendEvent, 1) +//Global Object for class beacon sensor! +@Field def beaconSensorObject = new BeaconSensors(sendEvent, 1) +//Global Object for class carbon monoxide! +@Field def carbonMonoxideDetectorObject = new CarbonMonoxideDetectors(sendEvent, 1) +//Global Object for class color control! +@Field def colorControlObject = new ColorControls(sendEvent, 1) +//Global Object for class energy meter! +@Field def energyMeterObject = new EnergyMeters(sendEvent, 1) diff --git a/MusicPlayer/MusicPlayer.groovy b/MusicPlayer/MusicPlayer.groovy index 6de93c1..1e4d62c 100644 --- a/MusicPlayer/MusicPlayer.groovy +++ b/MusicPlayer/MusicPlayer.groovy @@ -11,9 +11,10 @@ public class MusicPlayer { private String mute private String status private int trackNumber - private List trackData + private String trackData + private String trackDescription - MusicPlayer(String id, String label, String displayName, int level, String mute, String status, int trackNumber, List trackData) { + MusicPlayer(String id, String label, String displayName, int level, String mute, String status, int trackNumber, String trackData, String trackDescription) { this.id = id this.label = label this.displayName = displayName @@ -22,67 +23,116 @@ public class MusicPlayer { this.status = status this.trackNumber = trackNumber this.trackData = trackData + this.trackDescription = trackDescription + } + + //By model checker + def setValue(String value, String name) { + if (name == "status") { + this.status = value + println("the status of the music player with id:$id is changed to $value!") + } else if (name == "level") { + this.level = value.toInteger() + println("the level sound of the music player with id:$id is changed to $value!") + } else if (name == "trackDescription") { + this.trackDescription = value + println("the trackDescription of the music player with id:$id is changed to $value!") + } else if (name == "trackData") { + this.trackData = value + println("the trackData of the music player with id:$id is changed to $value!") + } else if (name == "mute") { + this.mute = value + println("the mute state of the music player with id:$id is changed to $value!") + } } //methods def mute() { println("the music player with id:$id is muted!") this.mute = "muted" + sendEvent([name: "mute", value: "mute", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "mute"]]) } def nextTrack() { - if (trackNumber != trackData.size()-1) - trackNumber = trackNumber+1 - else - trackNumber = 0 - def trackPlaying = trackData[trackNumber] + trackNumber = trackNumber+1 + def trackPlaying = trackData println("the $trackPlaying is selected!") this.status = "playing" + sendEvent([name: "status", value: "playing", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "playing"]]) + sendEvent([name: "trackDescription", value: "someDescriptions", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "someDescriptions"]]) + sendEvent([name: "trackData", value: "someTrack", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "someTrack"]]) } def pause() { println("the music player with id:$id is paused!") this.status = "paused" + sendEvent([name: "status", value: "paused", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "paused"]]) } def play() { println("the music player with id:$id is starting to play!") this.status = "playing" + sendEvent([name: "status", value: "playing", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "playing"]]) } def playTrack(String trackToPlay) { - trackNumber = list.indexOf(trackToPlay) - def trackPlaying = trackData[trackNumber] + def trackPlaying = trackData println("the $trackPlaying is selected to play!") this.status = "playing" + sendEvent([name: "status", value: "playing", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "playing"]]) + sendEvent([name: "trackDescription", value: "someDescriptions", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "someDescriptions"]]) + sendEvent([name: "trackData", value: "someTrack", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "someTrack"]]) } def previousTrack() { - if (trackNumber != 0) + if (trackNumber != 1) trackNumber = trackNumber-1 - else - trackNumber = trackData.size()-1 - def trackPlaying = trackData[trackNumber] + def trackPlaying = trackData println("the $trackPlaying is selected!") this.status = "playing" + sendEvent([name: "status", value: "playing", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "playing"]]) + sendEvent([name: "trackDescription", value: "someDescriptions", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "someDescriptions"]]) + sendEvent([name: "trackData", value: "someTrack", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "someTrack"]]) } /*def restoreTrack(String trackToRestore) { musicPlayers*.restoreTrack(trackToRestore) }*/ def resumeTrack(String trackToResume) { - trackNumber = list.indexOf(trackToResume) - def trackPlaying = trackData[trackNumber] + def trackPlaying = trackData println("the $trackPlaying is resumed!") this.status = "playing" + sendEvent([name: "status", value: "playing", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "playing"]]) } def setLevel(int level) { this.level = level println("the level of sound is changed to $level!") + sendEvent([name: "level", value: "$level", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "$level"]]) } def setTrack(String trackToSet) { - trackNumber = list.indexOf(trackToSet) - def trackPlaying = trackData[trackNumber] + def trackPlaying = trackData println("the $trackPlaying is set!") this.status = "playing" + sendEvent([name: "status", value: "playing", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "playing"]]) + sendEvent([name: "trackDescription", value: "someDescriptions", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "someDescriptions"]]) + sendEvent([name: "trackData", value: "someTrack", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "someTrack"]]) } def stop() { println("the music player with id:$id is stopped!") this.status = "stopped" + sendEvent([name: "status", value: "stopped", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "stopped"]]) } def currentValue(String deviceFeature) { diff --git a/MusicPlayer/MusicPlayers.groovy b/MusicPlayer/MusicPlayers.groovy index 9cf8f69..bf733db 100644 --- a/MusicPlayer/MusicPlayers.groovy +++ b/MusicPlayer/MusicPlayers.groovy @@ -15,8 +15,9 @@ public class MusicPlayers { private int level = 20 private String mute = "unmuted" private String status = "pause" - private int trackNumber = 0 - private List trackData = ["track1", "track2", "track3", "track4"] + private int trackNumber = 1 + private String trackData = "someTrack" + private String trackDescription = "someDescriptions" @@ -25,7 +26,42 @@ public class MusicPlayers { this.deviceNumbers = deviceNumbers this.musicPlayers = [] - musicPlayers.add(new MusicPlayer(id, label, displayName, this.level, this.mute, this.status, this.trackNumber, this.trackData)) + musicPlayers.add(new MusicPlayer(id, label, displayName, this.level, this.mute, this.status, this.trackNumber, this.trackData, this.trackDescription)) + } + + //By model checker + def setValue(LinkedHashMap eventDataMap) { + if (eventDataMap["name"] == "status") { + if (eventDataMap["value"] != musicPlayers[0].status) { + musicPlayers[0].setValue(eventDataMap["value"], "status") + this.status = musicPlayers[0].status + sendEvent(eventDataMap) + } + } else if (eventDataMap["name"] == "level") { + if (eventDataMap["value"] != musicPlayers[0].level) { + musicPlayers[0].setValue(eventDataMap["value"], "level") + this.level = musicPlayers[0].level + sendEvent(eventDataMap) + } + } else if (eventDataMap["name"] == "trackDescription") { + if (eventDataMap["value"] != musicPlayers[0].trackDescription) { + musicPlayers[0].setValue(eventDataMap["value"], "trackDescription") + this.trackDescription = musicPlayers[0].trackDescription + sendEvent(eventDataMap) + } + } else if (eventDataMap["name"] == "trackData") { + if (eventDataMap["value"] != musicPlayers[0].trackData) { + musicPlayers[0].setValue(eventDataMap["value"], "trackData") + this.trackData = musicPlayers[0].trackData + sendEvent(eventDataMap) + } + } else if (eventDataMap["name"] == "mute") { + if (eventDataMap["value"] != musicPlayers[0].mute) { + musicPlayers[0].setValue(eventDataMap["value"], "mute") + this.mute = musicPlayers[0].mute + sendEvent(eventDataMap) + } + } } //Methods for closures diff --git a/PresenceSensor/PresenceSensor.groovy b/PresenceSensor/PresenceSensor.groovy index 7d0e629..5f15a6f 100644 --- a/PresenceSensor/PresenceSensor.groovy +++ b/PresenceSensor/PresenceSensor.groovy @@ -6,30 +6,30 @@ public class PresenceSensor { private String id private String label private String displayName - private String presenceState + private String presence private String currentPresence private String presenceLatestValue - PresenceSensor(String id, String label, String displayName, String presenceState, String presenceLatestValue) { + PresenceSensor(String id, String label, String displayName, String presence, String presenceLatestValue) { this.id = id this.label = label this.displayName = displayName - this.presenceState = presenceState - this.currentPresence = presenceState + this.presence = presence + this.currentPresence = presence this.presenceLatestValue = presenceLatestValue } def setValue(String value) { - this.presenceLatestValue = presenceState + this.presenceLatestValue = presence println("the presence sensor with id:$id is triggered to $value!") - this.presenceState = value + this.presence = value this.currentPresence = value } def currentValue(String deviceFeature) { if (deviceFeature == "presence") { - return presenceState + return presence } } diff --git a/PresenceSensor/PresenceSensors.groovy b/PresenceSensor/PresenceSensors.groovy index 8fb9161..2408a5a 100644 --- a/PresenceSensor/PresenceSensors.groovy +++ b/PresenceSensor/PresenceSensors.groovy @@ -11,7 +11,7 @@ public class PresenceSensors { private String id = "presenceSensorID0" private String label = "presenceSensor0" private String displayName = "presenceSensor0" - private String presenceState = "not present" + private String presence = "not present" private String currentPresence = "not present" private String presenceLatestValue = "not present" @@ -21,16 +21,16 @@ public class PresenceSensors { this.deviceNumbers = deviceNumbers this.presenceSensors = [] - presenceSensors.add(new PresenceSensor(id, label, displayName, this.presenceState, this.presenceLatestValue)) + presenceSensors.add(new PresenceSensor(id, label, displayName, this.presence, this.presenceLatestValue)) } //By Model Checker def setValue(LinkedHashMap eventDataMap) { - if (eventDataMap["value"] != presenceSensors[0].presenceState) { + if (eventDataMap["value"] != presenceSensors[0].presence) { presenceSensors[0].setValue(eventDataMap["value"]) this.presenceLatestValue = presenceSensors[0].presenceLatestValue - this.presenceState = presenceSensors[0].presenceState - this.currentPresence = presenceSensors[0].presenceState + this.presence = presenceSensors[0].presence + this.currentPresence = presenceSensors[0].presence sendEvent(eventDataMap) } } diff --git a/Runner.py b/Runner.py index d3d7c16..2e34302 100644 --- a/Runner.py +++ b/Runner.py @@ -68,6 +68,18 @@ Out.write("import Alarm.Alarm\n") Out.write("import Alarm.Alarms\n") Out.write("import SpeechSynthesis.SpeechSynthesis\n") Out.write("import SpeechSynthesis.SpeechSynthesises\n") +Out.write("import AccelerationSensor.AccelerationSensor\n") +Out.write("import AccelerationSensor.AccelerationSensors\n") +Out.write("import Battery.Battery\n") +Out.write("import Battery.Batteries\n") +Out.write("import BeaconSensor.BeaconSensor\n") +Out.write("import BeaconSensor.BeaconSensors\n") +Out.write("import CarbonMonoxideDetector.CarbonMonoxideDetector\n") +Out.write("import CarbonMonoxideDetector.CarbonMonoxideDetectors\n") +Out.write("import ColorControl.ColorControl\n") +Out.write("import ColorControl.ColorControls\n") +Out.write("import EnergyMeter.EnergyMeter\n") +Out.write("import EnergyMeter.EnergyMeters\n") Out.write("import Event.Event\n") Out.write("import Timer.SimulatedTimer\n") Out.write("\n") diff --git a/Thermostat/Thermostat.groovy b/Thermostat/Thermostat.groovy index 720ba82..60c1b90 100644 --- a/Thermostat/Thermostat.groovy +++ b/Thermostat/Thermostat.groovy @@ -57,12 +57,16 @@ public class Thermostat { this.coolingSetpoint = coolingSetpoint this.currentCoolingSetpoint = currentCoolingSetpoint println("Cooling set point for the thermostat with id:$id is changed to $coolingSetpoint!") + sendEvent([name: "coolingSetpoint", value: "$coolingSetpoint", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "$coolingSetpoint"]]) } def setHeatingSetpoint(int heatingSetpoint) { this.heatingSetpoint = heatingSetpoint this.currentHeatingSetpoint = currentHeatingSetpoint println("Heating set point for the thermostat with id:$id is changed to $heatingSetpoint!") + sendEvent([name: "heatingSetpoint", value: "$heatingSetpoint", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "$heatingSetpoint"]]) } def setSchedule() { @@ -72,36 +76,48 @@ public class Thermostat { def setThermostatFanMode(String thermostatFanMode) { this.thermostatFanMode = thermostatFanMode println("Fan mode of the thermostat with id:$id is changed to $thermostatFanMode!") + sendEvent([name: "thermostatFanMode", value: "$thermostatFanMode", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "$thermostatFanMode"]]) } def setThermostatMode(String thermostatMode) { this.thermostatMode = thermostatMode this.currentThermostatMode = currentThermostatMode println("Mode of the thermostat with id:$id is changed to $thermostatMode!") + sendEvent([name: "thermostatMode", value: "$thermostatMode", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "$thermostatMode"]]) } def cool() { this.thermostatMode = "cool" this.currentThermostatMode = "cool" println("Mode of the thermostat with id:$id is changed to cool!") + sendEvent([name: "cool", value: "cool", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "cool"]]) } def heat() { this.thermostatMode = "heat" this.currentThermostatMode = "heat" println("Mode of the thermostat with id:$id is changed to heat!") + sendEvent([name: "heat", value: "heat", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "heat"]]) } def auto() { this.thermostatMode = "auto" this.currentThermostatMode = "auto" println("Mode of the thermostat with id:$id is changed to auto!") + sendEvent([name: "auto", value: "auto", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "auto"]]) } def off() { this.thermostatMode = "off" this.currentThermostatMode = "off" println("Mode of the thermostat with id:$id is changed to off!") + sendEvent([name: "off", value: "off", deviceId: this.id, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "off"]]) } def setClimate(String info, String givenClimateName) { @@ -119,10 +135,29 @@ public class Thermostat { } //By Model Checker - def setValue(String value) { - println("the thermostat with id:$id is $value!") - this.thermostatMode = value - this.currentThermostatMode = value + def setValue(String value, String name) { + if (name == "temperature") { + println("the temperature is $value!") + this.temperature = value + } else if (name == "heatingSetpoint") { + println("the heating set point of the thermostat with id:$id is $value!") + this.heatingSetpoint = value + } else if (name == "coolingSetpoint") { + println("the cooling set point of the thermostat with id:$id is $value!") + this.coolingSetpoint = value + } else if (name == "thermostatSetpoint") { + println("the set point of the thermostat with id:$id is $value!") + this.thermostatSetpoint = value + } else if (name == "thermostatMode") { + println("the mode of the thermostat with id:$id is $value!") + this.thermostatMode = value + } else if (name == "thermostatFanMode") { + println("the fan mode of the thermostat with id:$id is $value!") + this.thermostatFanMode = value + } else if (name == "thermostatOperatingState") { + println("the operating state of the thermostat with id:$id is $value!") + this.thermostatOperatingState = value + } } } diff --git a/Thermostat/Thermostats.groovy b/Thermostat/Thermostats.groovy index 9945066..cc955d1 100644 --- a/Thermostat/Thermostats.groovy +++ b/Thermostat/Thermostats.groovy @@ -125,11 +125,49 @@ public class Thermostats{ //By Model Checker def setValue(LinkedHashMap eventDataMap) { - if (eventDataMap["value"] != thermostats[0].thermostatMode) { - thermostats[0].setValue(eventDataMap["value"]) - this.thermostatMode = thermostats[0].thermostatMode - this.currentThermostatMode = thermostats[0].currentThermostatMode - sendEvent(eventDataMap) + if (eventDataMap["name"] == "temperature") { + if (eventDataMap["value"] != thermostats[0].temperature) { + thermostats[0].setValue(eventDataMap["value"], "temperature") + this.temperature = thermostats[0].temperature + sendEvent(eventDataMap) + } + } else if (eventDataMap["name"] == "heatingSetpoint") { + if (eventDataMap["value"] != thermostats[0].heatingSetpoint) { + thermostats[0].setValue(eventDataMap["value"], "heatingSetpoint") + this.heatingSetpoint = thermostats[0].heatingSetpoint + sendEvent(eventDataMap) + } + } else if (eventDataMap["name"] == "coolingSetpoint") { + if (eventDataMap["value"] != thermostats[0].coolingSetpoint) { + thermostats[0].setValue(eventDataMap["value"], "coolingSetpoint") + this.coolingSetpoint = thermostats[0].coolingSetpoint + sendEvent(eventDataMap) + } + } else if (eventDataMap["name"] == "thermostatSetpoint") { + if (eventDataMap["value"] != thermostats[0].thermostatSetpoint) { + thermostats[0].setValue(eventDataMap["value"], "thermostatSetpoint") + this.thermostatSetpoint = thermostats[0].thermostatSetpoint + sendEvent(eventDataMap) + } + } else if (eventDataMap["name"] == "thermostatMode") { + if (eventDataMap["value"] != thermostats[0].thermostatMode) { + thermostats[0].setValue(eventDataMap["value"], "thermostatMode") + this.thermostatMode = thermostats[0].thermostatMode + this.currentThermostatMode = thermostats[0].currentThermostatMode + sendEvent(eventDataMap) + } + } else if (eventDataMap["name"] == "thermostatFanMode") { + if (eventDataMap["value"] != thermostats[0].thermostatFanMode) { + thermostats[0].setValue(eventDataMap["value"], "thermostatFanMode") + this.thermostatFanMode = thermostats[0].thermostatFanMode + sendEvent(eventDataMap) + } + } else if (eventDataMap["name"] == "thermostatOperatingState") { + if (eventDataMap["value"] != thermostats[0].thermostatOperatingState) { + thermostats[0].setValue(eventDataMap["value"], "thermostatOperatingState") + this.thermostatOperatingState = thermostats[0].thermostatOperatingState + sendEvent(eventDataMap) + } } } diff --git a/Variables and events for each device b/Variables and events for each device index d1fc80e..ae4fb25 100644 --- a/Variables and events for each device +++ b/Variables and events for each device @@ -76,11 +76,11 @@ displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "inf String currentMotion or String motion /*events*/ Motion sensor event: motion detected: -doorControlObject.setValue([name: "motion", value: "active", deviceId: "motionSensorID0", descriptionText: "", +motionSensorObject.setValue([name: "motion", value: "active", deviceId: "motionSensorID0", descriptionText: "", displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) ///// Motion sensor event: motion not detected: -doorControlObject.setValue([name: "motion", value: "inactive", deviceId: "motionSensorID0", descriptionText: "", +motionSensorObject.setValue([name: "motion", value: "inactive", deviceId: "motionSensorID0", descriptionText: "", displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) ///// /*events*/ @@ -236,3 +236,84 @@ displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "inf ///// /*events*/ // +------------------------------------------------------------------------------- + + +//For acceleration sensor: +String currentAcceleration or String acceleration +/*events*/ +Acceleration sensor event: acceleration detected: +accelerationSensorObject.setValue([name: "acceleration", value: "active", deviceId: "accelerationSensorID0", descriptionText: "", +displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) +///// +Acceleration sensor event: acceleration not detected: +accelerationSensorObject.setValue([name: "acceleration", value: "inactive", deviceId: "accelerationSensorID0", descriptionText: "", +displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) +///// +/*events*/ +// +------------------------------------------------------------------------------- + + +//For battery: +String currentBattery or String battery +/*events*/ +//No events based on this device +/*events*/ +// +------------------------------------------------------------------------------- + + +//For beacon sensor: +String currentPresence or String presence +/*events*/ +beacon sensor, present event: +beaconSensorObject.setValue([name: "beacon", value: "present", deviceId: "beaconeSensorID0", descriptionText: "", +displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) +///// +beacon sensor, left event: +beaconSensorObject.setValue([name: "beacon", value: "not present", deviceId: "beaconSensorID0", descriptionText: "", +displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) +///// +/*events*/ +// +------------------------------------------------------------------------------- + + +//For carbon monoxide: +String currentCarbonMonoxideValue or String carbonMonoxide +/*events*/ +carbonMonoxide is clear event: +carbonMonoxideDetectorObject.setValue([name: "carbonMonoxide", value: "clear", deviceId: "carbonMonoxideDetectorID0", descriptionText: "", +displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) +///// +carbonMonoxide is detected event: +carbonMonoxideDetectorObject.setValue([name: "carbonMonoxide", value: "detected", deviceId: "carbonMonoxideDetectorID0", descriptionText: "", +displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) +///// +carbonMonoxide is tested event: +carbonMonoxideDetectorObject.setValue([name: "carbonMonoxide", value: "tested", deviceId: "carbonMonoxideDetectorID0", descriptionText: "", +displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) +/*events*/ +// +------------------------------------------------------------------------------- + + +//For color control: +String color +String hue +String saturation +/*events*/ +color changed: +colorControlObject.setValue([name: "color", value: "red", deviceId: "colorControlID0", descriptionText: "", +displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) +///// +hue changed: +colorControlObject.setValue([name: "hue", value: "50", deviceId: "colorControlID0", descriptionText: "", +displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) +///// +saturation changed: +colorControlObject.setValue([name: "saturation", value: "50", deviceId: "colorControlID0", descriptionText: "", +displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) +/*events*/ +// diff --git a/eventSimulator/eventSimulator.groovy b/eventSimulator/eventSimulator.groovy index 6d62806..de20a22 100644 --- a/eventSimulator/eventSimulator.groovy +++ b/eventSimulator/eventSimulator.groovy @@ -4,13 +4,13 @@ while(counter > 0) { def eventNumber = random.nextInt(1) switch(eventNumber) { case 0: - appObject.setValue([name: "Touched", value: "Touched", deviceId: 0, descriptionText: "", - displayed: true, linkText: "", isStateChange: false, unit: "", data: []]) + appObject.setValue([name: "nfcTouch", value: "Touched", deviceId: 0, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "Touched"]]) break case 1: - appObject.setValue([name: "nfcTouch", value: "Touched", deviceId: 0, descriptionText: "", - displayed: true, linkText: "", isStateChange: false, unit: "", data: [value: "Touched"]]) + appObject.setValue([name: "Touched", value: "Touched", deviceId: 0, descriptionText: "", + displayed: true, linkText: "", isStateChange: false, unit: "", data: []]) break } diff --git a/main.groovy b/main.groovy index b28d935..d8f3667 100644 --- a/main.groovy +++ b/main.groovy @@ -114,12 +114,16 @@ class App1 { def app //Extracted objects for App1 - //Object for class switch! - def switches - //Object for class thermostat! - def thermostats + //Global variable for time! + def time = "15:00" //Object for class lock! - def locks + def lock + //Object for class contactSensor! + def contact + //Global variable for enum! + def sendPushMessage = "Yes" + //Global variable for phone! + def phone = 9495379373 //Extracted objects for functions for App1 //Global Object for functions in subscribe method! @@ -127,25 +131,20 @@ class App1 { //Global Object for functions in subscribe method! def updated = this.&updated //Global Object for functions in subscribe method! - def appTouch = this.&appTouch - //Global Object for functions in subscribe method! - def changedLocationMode = this.&changedLocationMode - //Global Object for functions in subscribe method! - def restoreState = this.&restoreState + def setTimeCallback = this.&setTimeCallback //Global Object for functions in subscribe method! - def saveState = this.&saveState + def doorOpenCheck = this.&doorOpenCheck //Global Object for functions in subscribe method! - def getCurrentMode = this.&getCurrentMode + def lockMessage = this.&lockMessage App1(Object obj) { reference = obj location = obj.locationObject app = obj.appObject - switches = obj.switchObject - thermostats = obj.thermostatObject - locks = obj.lockObject + lock = obj.lockObject + contact = obj.contactObject //Global variable for settings! - settings = [app:app, switches:switches, thermostats:thermostats, locks:locks] + settings = [app:app, time:time, lock:lock, contact:contact, sendPushMessage:sendPushMessage, phone:phone] } //Global variables for each app //Global variable for state[mode] @@ -335,102 +334,49 @@ class App1 { } def installed() { - subscribe(location, changedLocationMode) - subscribe(app, appTouch) - saveState() - } + schedule(time, "setTimeCallback") - def updated() { - unsubscribe() - subscribe(location, changedLocationMode) - subscribe(app, appTouch) - saveState() } - def appTouch(evt) - { - restoreState(currentMode) - } - - def changedLocationMode(evt) - { - restoreState(evt.value) - } - - private restoreState(mode) - { - log.info "restoring state for mode '$mode'" - def map = state[mode] ?: [:] - switches?.each { - def value = map[it.id] - if (value?.switch == "on") { - def level = value.level - if (level) { - log.debug "setting $it.label level to $level" - it.setLevel(level) - } - else { - log.debug "turning $it.label on" - it.on() - } - } - else if (value?.switch == "off") { - log.debug "turning $it.label off" - it.off() - } - } - - thermostats?.each { - def value = map[it.id] - if (value?.coolingSetpoint) { - log.debug "coolingSetpoint = $value.coolingSetpoint" - it.setCoolingSetpoint(value.coolingSetpoint) - } - if (value?.heatingSetpoint) { - log.debug "heatingSetpoint = $value.heatingSetpoint" - it.setHeatingSetpoint(value.heatingSetpoint) - } - } - - locks?.each { - def value = map[it.id] - if (value) { - if (value?.locked) { - it.lock() - } - else { - it.unlock() - } - } - } + def updated(settings) { + unschedule() + schedule(time, "setTimeCallback") } - - private saveState() - { - def mode = currentMode - def map = state[mode] ?: [:] - - switches?.each { - map[it.id] = [switch: it.currentSwitch, level: it.currentLevel] - } - - thermostats?.each { - map[it.id] = [coolingSetpoint: it.currentCoolingSetpoint, heatingSetpoint: it.currentHeatingSetpoint] - } - - locks?.each { - map[it.id] = [locked: it.currentLock == "locked"] - } - - state[mode] = map - log.debug "saved state for mode ${mode}: ${state[mode]}" - log.debug "state: $state" + def setTimeCallback() { + if (contact) { + doorOpenCheck() + } else { + lockMessage() + lock.lock() + } } - - private getCurrentMode() - { - location.mode ?: "_none_" + def doorOpenCheck() { + def currentState = contact.contactState + if (currentState?.value == "open") { + def msg = "${contact.displayName} is open. Scheduled lock failed." + log.info msg + if (sendPushMessage) { + sendPush msg + } + if (phone) { + sendSms phone, msg + } + } else { + lockMessage() + lock.lock() + } + } + + def lockMessage() { + def msg = "Locking ${lock.displayName} due to scheduled lock." + log.info msg + if (sendPushMessage) { + sendPush msg + } + if (phone) { + sendSms phone, msg + } } } @@ -455,7 +401,7 @@ class App2 { //Global variable for enum! def masterLock = "Yes" //Global variable for enum! - def masterDoor = "No" + def masterDoor = "Yes" //Extracted objects for functions for App2 //Global Object for functions in subscribe method! @@ -770,13 +716,3 @@ class App2 { app1.installed() app2.installed() -appObject.setValue([name: "nfcTouch", value: "touched", deviceId: "nfcSensorID0", descriptionText: "", -displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) -appObject.setValue([name: "Touched", value: "touched", deviceId: "touchedSensorID0", descriptionText: "", -displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) -locationObject.setValue([name: "Location", value: "away", deviceId: "locationID0", descriptionText: "", -displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) -locationObject.setValue([name: "Location", value: "home", deviceId: "locationID0", descriptionText: "", -displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) -locationObject.setValue([name: "Location", value: "night", deviceId: "locationID0", descriptionText: "", -displayed: true, linkText: "", isStateChange: false, unit: "", data: [info: "info"]]) diff --git a/prgs b/prgs new file mode 100644 index 0000000..2516f13 --- /dev/null +++ b/prgs @@ -0,0 +1,11 @@ +///////////// + input "illuminances", "capability.illuminanceMeasurement", title: "Illuminance Meters", multiple: true, required: false + input "powerMeters", "capability.powerMeter", title: "Power Meters", multiple: true, required: false + input "humidities", "capability.relativeHumidityMeasurement", title: "Humidity Meters", multiple: true, required: false + input "relaySwitches", "capability.relaySwitch", title: "Relay Switches", multiple: true, required: false + input "sleepSensors", "capability.sleepSensor", title: "Sleep Sensors", multiple: true, required: false + input "peds", "capability.stepSensor", title: "Pedometers", multiple: true, required: false + input "switchLevels", "capability.switchLevel", title: "Switch Levels", multiple: true, required: false + input "temperatures", "capability.temperatureMeasurement", title: "Temperature Sensors", multiple: true, required: false + input "valves", "capability.valve", title: "Valves", multiple: true, required: false + input "waterSensors", "capability.waterSensor", title: "Water Sensors", multiple: true, required: false diff --git a/test b/test new file mode 100644 index 0000000..b4acfa4 --- /dev/null +++ b/test @@ -0,0 +1,177 @@ +//// +import groovy.json.JsonSlurper +import groovy.transform.Field + +class Logger { + private boolean printToConsole = true + + def methodMissing(String name, args) { + def messsage = args[0] + if (printToConsole) { + println messsage + } + } +} + +/////////////////////////////////////////////////// +class RequestBuckets { + def jsonSlurper = new JsonSlurper() + def JSON = jsonSlurper.parseText ''' + { + "version": 1.06, + "accessKey": 100, + "bucketKey": 50, + "bucketName": "TEST", + "isBucketCreated": true, + "grokerSubdomain": "DOMAIN" + }''' +} +/////////////////////////////////////////////////// + + +/////////////////////////////////////////////////// +class Atomic { + def version + def accessKey + def bucketKey + def bucketName + def isBucketCreated + def grokerSubdomain +} +/////////////////////////////////////////////////// + +@Field def log = new Logger() +/////////////////////////////////////////////////// +@Field def atomicState = new Atomic() +@Field def request = new RequestBuckets() +/////////////////////////////////////////////////// + + +getAccessKey() +getBucketKey() +setBucketKey() +setAccessKey() +tryCreateBucket() + +/////////////////////////////////////////////////// +def httpError(int errorNumber, String errorReport) { + println("---Just IGNORE---For http connection in a streamer app") +} +def httpPostJson(LinkedHashMap metaData, Closure Input) { + Input(metaData) +} +/////////////////////////////////////////////////// + + + +def getAccessKey() { + log.trace "get access key" + if (atomicState.accessKey == null) { + httpError(404, "Access Key Not Found") + } else { + [ + accessKey: atomicState.accessKey + ] + } +} + +def getBucketKey() { + log.trace "get bucket key" + if (atomicState.bucketKey == null) { + httpError(404, "Bucket key Not Found") + } else { + [ + bucketKey: atomicState.bucketKey, + bucketName: atomicState.bucketName + ] + } +} + +def setBucketKey() { + log.trace "set bucket key" + def newBucketKey = request.JSON?.bucketKey + def newBucketName = request.JSON?.bucketName + + log.debug "bucket name: $newBucketName" + log.debug "bucket key: $newBucketKey" + + if (newBucketKey && (newBucketKey != atomicState.bucketKey || newBucketName != atomicState.bucketName)) { + atomicState.bucketKey = "$newBucketKey" + atomicState.bucketName = "$newBucketName" + atomicState.isBucketCreated = false + } + + tryCreateBucket() +} + +def setAccessKey() { + log.trace "set access key" + def newAccessKey = request.JSON?.accessKey + def newGrokerSubdomain = request.JSON?.grokerSubdomain + + if (newGrokerSubdomain && newGrokerSubdomain != "" && newGrokerSubdomain != atomicState.grokerSubdomain) { + atomicState.grokerSubdomain = "$newGrokerSubdomain" + atomicState.isBucketCreated = false + } + + if (newAccessKey && newAccessKey != atomicState.accessKey) { + atomicState.accessKey = "$newAccessKey" + atomicState.isBucketCreated = false + } +} + + + +def tryCreateBucket() { + + // can't ship events if there is no grokerSubdomain + if (atomicState.grokerSubdomain == null || atomicState.grokerSubdomain == "") { + log.error "streaming url is currently null" + return + } + + // if the bucket has already been created, no need to continue + if (atomicState.isBucketCreated) { + return + } + + if (!atomicState.bucketName) { + atomicState.bucketName = atomicState.bucketKey + } + if (!atomicState.accessKey) { + return + } + def bucketName = "${atomicState.bucketName}" + def bucketKey = "${atomicState.bucketKey}" + def accessKey = "${atomicState.accessKey}" + + def bucketCreateBody = new JsonSlurper().parseText("{\"bucketKey\": \"$bucketKey\", \"bucketName\": \"$bucketName\"}") + + def bucketCreatePost = [ + uri: "https://${atomicState.grokerSubdomain}.initialstate.com/api/buckets", + headers: [ + "Content-Type": "application/json", + "X-IS-AccessKey": accessKey + ], + body: bucketCreateBody + ] + + log.debug bucketCreatePost + + try { + // Create a bucket on Initial State so the data has a logical grouping + httpPostJson(bucketCreatePost) { resp -> + log.debug "bucket posted" + if (resp.status >= 400) { + log.error "bucket not created successfully" + } else { + atomicState.isBucketCreated = true + } + } + } catch (e) { + log.error "bucket creation error: $e" + } + +} + +