Advertisement
Guest User

Rule Machine 1.9.0a

a guest
Apr 13th, 2016
234
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Groovy 21.23 KB | None | 0 0
  1. /**
  2.  *  Rule Machine
  3.  *
  4.  *  Copyright 2015, 2016 Bruce Ravenel
  5.  *
  6.  *  Version 1.9.0a   25 Mar 2016
  7.  *
  8.  *  Version History
  9.  *
  10.  *  1.9.0   24 Mar 2016     Updates for Rule, small bug fixes
  11.  *  1.8.2   9 Mar 2016      Changed startup page for installation
  12.  *  1.8.1   3 Mar 2016      Changed method of getting Rule version
  13.  *  1.8.0   2 Mar 2016      Clean up, added Door control
  14.  *  1.7.6   24 Feb 2016     Added User Guide link, fixed Rule truth mechanism
  15.  *  1.7.5   21 Feb 2016     Improved custom command selection
  16.  *  1.7.4   20 Feb 2016     Added saved command display, UI improvements
  17.  *  1.7.3   14 Feb 2016     Improved Rule Machine initialization, fixed Delete custom commands bug
  18.  *  1.7.2   8 Feb 2016      Added set Boolean for Rules
  19.  *  1.7.1   5 Feb 2016      Added update Rule
  20.  *  1.7.0   31 Jan 2016     Added run Rule actions
  21.  *  1.6.6   10 Jan 2016     Improved method of getting custom device commands
  22.  *  1.6.5   1 Jan 2016      Added version numbers to main page
  23.  *  1.6.4   30 Dec 2015     Multi-commands
  24.  *  1.6.3   26 Dec 2015     UI improvements and icon per Michael Struck
  25.  *  1.6.2   25 Dec 2015     null parameter value patch in expert, maxwell
  26.  *  1.6.1   24 Dec 2015     UI improvement
  27.  *  1.6.0   23 Dec 2015     Added expert commands per Mike Maxwell
  28.  *
  29.  *  This software if free for Private Use. You may use and modify the software without distributing it.
  30.  *  
  31.  *  This software and derivatives may not be used for commercial purposes.
  32.  *  You may not modify, distribute or sublicense this software.
  33.  *  You may not grant a sublicense to modify and distribute this software to third parties not included in the license.
  34.  *
  35.  *  Software is provided without warranty and the software author/license owner cannot be held liable for damages.
  36.  *
  37.  */
  38.  
  39. definition(
  40.     name: "Rule Machine",
  41.     singleInstance: true,
  42.     namespace: "bravenel",
  43.     author: "Bruce Ravenel and Mike Maxwell",
  44.     description: "Rule Machine",
  45.     category: "My Apps",
  46.     iconUrl: "https://raw.githubusercontent.com/bravenel/Rule-Trigger/master/smartapps/bravenel/RuleMachine.png",
  47.     iconX2Url: "https://raw.githubusercontent.com/bravenel/Rule-Trigger/master/smartapps/bravenel/RuleMachine%402x.png",
  48.     iconX3Url: "https://raw.githubusercontent.com/bravenel/Rule-Trigger/master/smartapps/bravenel/RuleMachine%402x.png"
  49. )
  50.  
  51. preferences {
  52.     page(name: "mainPage")
  53.     page(name: "firstPage")
  54.     page(name: "removePage")
  55.     //expert pages
  56.     page(name: "customCommandsPAGE")
  57.     page(name: "generalApprovalPAGE")
  58.     page(name: "addCustomCommandPAGE")
  59.     page(name: "customParamsPAGE")
  60. }
  61.  
  62. def mainPage() {
  63.     if(!state.setup) firstRun()
  64.     else {
  65.         if(state.ruleState) state.ruleState = null  // obsolete
  66.         def nApps = childApps.size()
  67.         dynamicPage(name: "mainPage", title: "Installed Rules, Triggers and Actions " + (nApps > 0 ? "[$nApps]" : ""), install: true, uninstall: false) {
  68.             section {
  69.                 app(name: "childRules", appName: "Rule", namespace: "bravenel", title: "Create New Rule...", multiple: true)
  70.             }
  71.             section ("Expert Features") {
  72.                 href("customCommandsPAGE", title: null, description: anyCustom() ? "Custom Commands..." : "Tap to create Custom Commands", state: anyCustom())
  73.             }
  74.             section ("Rule Machine User Guide") {
  75.                 href url:"https://community.smartthings.com/t/rule-machine-user-guide/40176", style:"embedded", required:false, description:"Tap to view User Guide", title: ""
  76.             }
  77.             section ("Remove Rule Machine"){
  78.                 href "removePage", description: "Tap to remove Rule Machine and Rules", title: ""
  79.             }
  80.             section ("Version 1.9.0a/" + (nApps > 0 ? "${childApps[0].appVersion()}" : "---")) { }
  81.         }
  82.     }
  83. }
  84.  
  85. def removePage() {
  86.     dynamicPage(name: "removePage", title: "Remove Rule Machine And All Rules", install: false, uninstall: true) {
  87.         section ("WARNING!\n\nRemoving Rule Machine also removes all Rules\n") {
  88.         }
  89.     }
  90. }
  91.  
  92. def installed() {
  93. }
  94.  
  95. def updated() {
  96. }
  97.  
  98. def firstRun() {
  99.     state.setup = true
  100.     state.ruleSubscribers = [:]
  101.     dynamicPage(name: "firstPage", title: "Hit Done to install Rule Machine", install: true, uninstall: false) { }
  102. }
  103.  
  104. def childVersion() {
  105.     def result = "---"
  106.     if(childApps.size() > 0) result = childApps[0].appVersion()
  107.     return result
  108. }
  109.  
  110. def ruleList(appLabel) {
  111.     def result = []
  112.     childApps.each { child ->
  113.         if(child.name == "Rule" && child.label != appLabel) result << child.label
  114.     }
  115.     return result
  116. }
  117.  
  118. def subscribeRule(appLabel, ruleName, ruleTruth, childMethod) {
  119. //  log.debug "subscribe: $appLabel, $ruleName, $ruleTruth, $childMethod"
  120.     ruleName.each {name ->
  121.         state.ruleSubscribers[name].each {if(it == appLabel) return}
  122.         if(state.ruleSubscribers[name] == null) state.ruleSubscribers[name] = ["$appLabel":ruleTruth]
  123.         else state.ruleSubscribers[name] << ["$appLabel":ruleTruth]
  124.     }
  125. }
  126.  
  127. def setRuleTruth(appLabel, ruleTruth) {
  128. //  log.debug "setRuleTruth: $appLabel, $ruleTruth, ${state.ruleState[appLabel]}"
  129.     def thisList = state.ruleSubscribers[appLabel]
  130.     thisList.each {
  131.         if(it.value == null || "$it.value" == "$ruleTruth") {
  132.             childApps.each { child ->
  133.                 if(child.label == it.key) child.ruleHandler(appLabel, ruleTruth)
  134.             }
  135.         }
  136.     }
  137. }
  138.  
  139. def setRuleBoolean(rule, ruleBoolean, appLabel) {
  140. //  log.debug "setRuleBoolean: $appLabel, $ruleBoolean"
  141.     childApps.each { child ->
  142.         rule.each {
  143.             if(child.label == it) child.setBoolean(ruleBoolean, appLabel)
  144.         }
  145.     }  
  146. }
  147.  
  148. def currentRule(appLabel) {
  149.     def result
  150.     childApps.each { child ->
  151.         if(child.label == appLabel) result = child.revealSuccess()
  152.     }
  153.     return result
  154. }
  155.  
  156. def childUninstalled() {
  157. //  log.debug "childUninstalled called"
  158. }
  159.  
  160. def removeChild(appLabel) {
  161. //  log.debug "removeChild: $appLabel"
  162.     unSubscribeRule(appLabel)
  163.     if(state.ruleSubscribers[appLabel] != null) state.ruleSubscribers.remove(appLabel)
  164. }
  165.  
  166. def unSubscribeRule(appLabel) {
  167. //  log.debug "unSubscribeRule: $appLabel"
  168.     state.ruleSubscribers.each { rule ->
  169.         def newList = [:]
  170.         rule.value.each {list ->
  171.             if(list.key != appLabel) newList << list
  172.         }
  173.         rule.value = newList
  174.     }
  175. }
  176.  
  177. def runRule(rule, appLabel) {
  178. //  log.debug "runRule: $rule, $appLabel"
  179.     childApps.each { child ->
  180.         rule.each {
  181.             if(child.label == it) child.ruleEvaluator(appLabel)
  182.         }
  183.     }
  184. }
  185.  
  186. def runRuleAct(rule, appLabel) {
  187. //  log.debug "runRuleAct: $rule, $appLabel"
  188.     childApps.each { child ->
  189.         rule.each {
  190.             if(child.label == it) child.ruleActions(appLabel)
  191.         }
  192.     }
  193. }
  194.  
  195. def runUpdate(rule) {
  196. //  log.debug "runUpdate: $rule"
  197.     childApps.each { child ->
  198.         rule.each {
  199.             if(child.label == it) child.updated()
  200.         }
  201.     }
  202. }
  203.  
  204. /*****custom command specific pages *****/
  205. def generalApprovalPAGE(params){
  206.     def title = params.title
  207.     def method = params.method
  208.     def result
  209.     dynamicPage(name: "generalApprovalPAGE", title: title ){
  210.         section() {
  211.             if (method) {
  212.                 result = app."${method}"()
  213.                 paragraph "${result}"
  214.             }
  215.         }
  216.     }
  217. }
  218.  
  219. def customCommandsPAGE() {
  220.     if (!state.lastCmdIDX) state.lastCmdIDX = 0
  221.     def savedCommands = getMyCommands()
  222.     dynamicPage(name: "customCommandsPAGE", title: "Custom Commands", uninstall: false, install: false) {
  223.         def hasCommands = savedCommands.size() != 0
  224.         def result = ""
  225.         if (hasCommands){
  226.             def cmdMaps = state.customCommands ?: []
  227.             cmdMaps.each{ cmd ->
  228.                 def cont = cmd.value.text.size() > 30 ? "..." : ""
  229.                 result = result + "\n\t" + cmd.value.text.take(30) + cont
  230.             }
  231.         } else state.lastCmdIDX = 0
  232.         section(hasCommands ? "Saved commands:\n" + result : "") {
  233.             if (hasCommands) {
  234.                 input(
  235.                     name            : "deleteCmds"
  236.                     ,title          : "Delete saved commands"
  237.                     ,multiple       : true
  238.                     ,required       : false
  239.                     ,description    : ""
  240.                     ,type           : "enum"
  241.                     ,options        : savedCommands
  242.                     ,submitOnChange : true
  243.                 )
  244.                 if (isValidCommand(deleteCmds)){
  245.                     href( "generalApprovalPAGE"
  246.                         ,title          : "Delete commands now"
  247.                         ,description    : ""
  248.                         ,state          : null
  249.                         ,params         : [method:"deleteCommands",title:"Delete commands"]
  250.                         ,submitOnChange : true
  251.                     )
  252.                 }
  253.                 paragraph("")
  254.             }
  255.             getCapab()
  256.             if(myCapab) getDevs()
  257.             if(devices && hasCommands) {
  258.                 input(
  259.                     name            : "testCmd"
  260.                     ,title          : "Test saved command on\n$devices"
  261.                     ,multiple       : false
  262.                     ,required       : false
  263.                     ,description    : ""
  264.                     ,type           : "enum"
  265.                     ,options        : savedCommands
  266.                     ,submitOnChange : true
  267.                 )
  268.                 def res = execCommand(settings.testCmd)
  269.                 if (res) paragraph("${result}")
  270.             }
  271.         }
  272.         section(){
  273.             if (devices){
  274.                 href( "addCustomCommandPAGE"
  275.                     ,title      : "New custom command..."
  276.                     ,description: ""
  277.                     ,state      : null
  278.                 )
  279.             }
  280.         }
  281.     }
  282. }
  283.  
  284. def getCapab() {  
  285.     def myOptions = ["Acceleration", "Actuator", "Button", "Carbon monoxide detector", "Contact", "Dimmer", "Door", "Energy meter", "Garage door", "Humidity", "Illuminance",
  286.         "Lock", "Motion", "Power meter", "Presence", "Smoke detector", "Switch", "Temperature", "Thermostat", "Water sensor", "Music player"]
  287.     def result = input "myCapab", "enum", title: "Select capability for test device", required: false, options: myOptions.sort(), submitOnChange: true
  288. }
  289.  
  290. def getDevs() {
  291.     def multi = false
  292.     def thisName = ""
  293.     def thisCapab = ""
  294.     switch(myCapab) {
  295.         case "Switch":
  296.             thisName = "switch"
  297.             thisCapab = "switch"
  298.             break
  299.         case "Actuator":
  300.             thisName = "actuator"
  301.             thisCapab = "actuator"
  302.             break
  303.         case "Motion":
  304.             thisName = "motion sensor"
  305.             thisCapab = "motionSensor"
  306.             break
  307.         case "Button":
  308.             thisName = "button device"
  309.             thisCapab = "button"
  310.             break
  311.         case "Acceleration":
  312.             thisName = "acceleration sensor"
  313.             thisCapab = "accelerationSensor"
  314.             break        
  315.         case "Contact":
  316.             thisName = "contact sensor"
  317.             thisCapab = "contactSensor"
  318.             break
  319.         case "Presence":
  320.             thisName = "presence sensor"
  321.             thisCapab = "presenceSensor"
  322.             break
  323.         case "Garage door":
  324.             thisName = "garage door"
  325.             thisCapab = "garageDoorControl"
  326.             break
  327.         case "Door":
  328.             thisName = "door"
  329.             thisCapab = "doorControl"
  330.             break
  331.         case "Lock":
  332.             thisName = "lock"
  333.             thisCapab = "lock"
  334.             break
  335.         case "Dimmer":
  336.             thisName = "dimmer" + (multi ? "s" : "")
  337.             thisCapab = "switchLevel"
  338.             break
  339.         case "Temperature":
  340.             thisName = "temperature sensor" + (multi ? "s" : "")
  341.             thisCapab = "temperatureMeasurement"
  342.             break
  343.         case "Thermostat":
  344.             thisName = "thermostat" + (multi ? "s" : "")
  345.             thisCapab = "thermostat"
  346.             break
  347.         case "Humidity":
  348.             thisName = "humidity sensor" + (multi ? "s" : "")
  349.             thisCapab = "relativeHumidityMeasurement"
  350.             break
  351.         case "Illuminance":
  352.             thisName = "illuminance sensor" + (multi ? "s" : "")
  353.             thisCapab = "illuminanceMeasurement"
  354.             break
  355.         case "Energy meter":
  356.             thisName = "energy meter" + (multi ? "s" : "")
  357.             thisCapab = "energyMeter"
  358.             break
  359.         case "Power meter":
  360.             thisName = "power meter" + (multi ? "s" : "")
  361.             thisCapab = "powerMeter"
  362.             break
  363.         case "Carbon monoxide detector":
  364.             thisName = "CO detector" + (multi ? "s" : "")
  365.             thisCapab = "carbonMonoxideDetector"
  366.             break
  367.         case "Smoke detector":
  368.             thisName = "smoke detector" + (multi ? "s" : "")
  369.             thisCapab = "smokeDetector"
  370.             break
  371.         case "Water sensor":
  372.             thisName = "water sensor"
  373.             thisCapab = "waterSensor"
  374.             break
  375.         case "Music player":
  376.             thisName = "music player"
  377.             thisCapab = "musicPlayer"
  378.             break
  379.     }
  380.     def result = input "devices", "capability.$thisCapab", title: "Select $thisName to test for commands", required: false, multiple: multi, submitOnChange: true
  381. }
  382.  
  383. def addCustomCommandPAGE(){
  384.     def cmdLabel = getCmdLabel()
  385.     def complete = ""
  386.     def test = false
  387.     def rest = getDeviceCommands()
  388.     rest = "$rest"[1..-2]
  389.     def pageTitle = "Create new custom command from\n\n${devices}\n\nAvailable commands:\n\n" + rest
  390.     if (cmdLabel){
  391.         complete = "complete"
  392.         test = true
  393.     }
  394.     dynamicPage(name: "addCustomCommandPAGE", title: pageTitle, uninstall: false, install: false) {
  395.         section(){
  396.             input(
  397.                 name            : "cCmd"
  398.                 ,title          : "Select custom command"
  399.                 ,multiple       : false
  400.                 ,required       : false
  401.                 ,type           : "enum"
  402.                 ,options        : getDeviceCommands()
  403.                 ,submitOnChange : true
  404.             )
  405.             href( "customParamsPAGE"
  406.                 ,title: "Parameters"
  407.                 ,description: parameterLabel()
  408.                 ,state: null
  409.             )
  410.         }
  411.         if (cCmd){
  412.             def result = execTestCommand()
  413.             section("Configured command: ${cmdLabel}\n${result}"){
  414.                 if (result == "succeeded"){
  415.                     if (!commandExists(cmdLabel)){
  416.                         href( "generalApprovalPAGE"
  417.                             ,title      : "Save command now"
  418.                             ,description: ""
  419.                             ,state      : null
  420.                             ,params     : [method:"addCommand",title:"Add Command"]
  421.                         )
  422.                     }
  423.                 }
  424.             }
  425.         }
  426.     }
  427. }
  428.  
  429. def customParamsPAGE(p){
  430.     def ct = settings.findAll{it.key.startsWith("cpType_")}
  431.     state.howManyP = ct.size() + 1
  432.     def howMany = state.howManyP
  433.     dynamicPage(name: "customParamsPAGE", title: "Select parameters", uninstall: false) {
  434.         if(howMany) {
  435.             for (int i = 1; i <= howMany; i++) {
  436.                 def thisParam = "cpType_" + i
  437.                 def myParam = ct.find {it.key == thisParam}
  438.                 section("Parameter #${i}") {
  439.                     getParamType(thisParam, i != howMany)
  440.                     if(myParam) {
  441.                         def pType = myParam.value
  442.                         getPvalue(pType, i)
  443.                     }
  444.                 }
  445.             }
  446.         }
  447.     }
  448. }
  449.  
  450. /***** child specific methods *****/
  451.  
  452. def getCommandMap(cmdID){
  453.     return state.customCommands["${cmdID}"]
  454. }
  455.  
  456.  
  457. /***** local custom command specific methods *****/
  458. def anyCustom(){
  459.     def result = null
  460.     if (getCommands()) result = "complete"
  461.     return result
  462. }
  463.  
  464. def getParamType(myParam,isLast){  
  465.     def myOptions = ["string", "number", "decimal"]
  466.     def result = input (
  467.                     name            : myParam
  468.                     ,type           : "enum"
  469.                     ,title          : "parameter type"
  470.                     ,required       : isLast
  471.                     ,options        : myOptions
  472.                     ,submitOnChange : true
  473.                 )
  474.     return result
  475. }
  476.  
  477. def getPvalue(myPtype, n){
  478.     def myVal = "cpVal_" + n
  479.     def result = null
  480.     if (myPtype == "string"){
  481.         result = input(
  482.                     name        : myVal
  483.                     ,title      : "string value"
  484.                     ,type       : "text"
  485.                     ,required   : false
  486.                 )
  487.     } else if (myPtype == "number"){
  488.         result = input(
  489.                     name        : myVal
  490.                     ,title      : "integer value"
  491.                     ,type       : "number"
  492.                     ,required   : false
  493.                 )
  494.     } else if (myPtype == "decimal"){
  495.         result = input(
  496.                     name        : myVal
  497.                     ,title      : "decimal value"
  498.                     ,type       : "decimal"
  499.                     ,required   : false
  500.                 )
  501.     }
  502.     return result
  503. }
  504.  
  505. def getCmdLabel(){
  506.     def cmd
  507.     if (settings.cCmd) cmd = settings.cCmd.value
  508.     def cpTypes = settings.findAll{it.key.startsWith("cpType_")}.sort()
  509.     def result = null
  510.     if (cmd) {
  511.         result = "${cmd}("
  512.         if (cpTypes.size() == 0){
  513.             result = result + ")"
  514.         } else {
  515.             def r = getParams(cpTypes)
  516.             if (r == "") result = r
  517.             else result = "${result}${r})"
  518.         }
  519.     }
  520.     return result
  521. }
  522.  
  523. def getParams(cpTypes){
  524.     def result = ""
  525.     def cpValue
  526.     def badParam = false
  527.     cpTypes.each{ cpType ->
  528.         def i = cpType.key.replaceAll("cpType_","")
  529.         def cpVal = settings.find{it.key == "cpVal_${i}"}
  530.         if (cpVal){
  531.             cpValue = cpVal.value
  532.             if (cpType.value == "string"){
  533.                 result = result + "'${cpValue}',"
  534.             } else {
  535.                 if (cpValue.isNumber()){
  536.                     result = result + "${cpValue},"
  537.                 } else {
  538.                     result = result + "[${cpValue}]: is not a number,"
  539.                 }
  540.             }
  541.         } else {
  542.             badParam = true
  543.         }
  544.     }
  545.     if (badParam) result = ""
  546.     else result = result[0..-2]  
  547.     return result
  548. }
  549.  
  550. def parameterLabel(){
  551.     def howMany = (state.howManyP ?: 1) - 1
  552.     def result = ""
  553.     if (howMany) {
  554.         for (int i = 1; i <= howMany; i++) {
  555.             result = result + parameterLabelN(i) + "\n"
  556.         }
  557.         result = result[0..-2]
  558.     }
  559.     return result
  560. }
  561.  
  562. def parameterLabelN(i){
  563.     def result = ""
  564.     def cpType = settings.find{it.key == "cpType_${i}"}
  565.     def cpVal = settings.find{it.key == "cpVal_${i}"}
  566.     def cpValue
  567.     if (cpVal) cpValue = cpVal.value
  568.     else cpValue = "missing value"
  569.     if (cpType){
  570.         result = "p${i} - type:${cpType.value}, value:${cpValue}"
  571.     }
  572.     return result
  573. }
  574.  
  575. def getParamsAsList(cpTypes){
  576.     def result = []
  577.     cpTypes.each{ cpType ->
  578.         def i = cpType.key.replaceAll("cpType_","")
  579.         def cpVal = settings.find{it.key == "cpVal_${i}"}
  580.         if (cpVal){
  581.             if (cpType.value == "string"){
  582.                 result << "${cpVal.value}"
  583.             } else if (cpType.value == "decimal"){
  584.                 result << cpVal.value.toBigDecimal()
  585.             } else { // if (cpType.value == "number" && cpVal.value.isInteger()){
  586.                 result << cpVal.value.toInteger()
  587.             }
  588.         } else {
  589.             result << "missing value"
  590.         }
  591.     }
  592.     return result
  593. }
  594.  
  595. def getCommands(){
  596.     def result = []
  597.     def cmdMaps = state.customCommands ?: []
  598.     cmdMaps.each{ cmd ->
  599.         def option = [(cmd.key):([cmd.value.text, cmd.value.capab == null ? "actuator" : cmd.value.capab])]
  600.         result.push(option)
  601.     }
  602.     return result
  603. }
  604.  
  605. def getMyCommands(){
  606.     def result = []
  607.     def cmdMaps = state.customCommands ?: []
  608.     cmdMaps.each{ cmd ->
  609.         def option = [(cmd.key):(cmd.value.text)]
  610.         result.push(option)
  611.     }
  612.     return result
  613. }
  614.  
  615. def isValidCommand(cmdIDS){
  616.     def result = false
  617.     cmdIDS.each{ cmdID ->
  618.         def cmd = state.customCommands["${cmdID}"]
  619.         if (cmd) result = true
  620.     }
  621.     return result
  622. }
  623.  
  624. def deleteCommands(){
  625.     def result
  626.     def cmdMaps = state.customCommands
  627.     if (deleteCmds.size() == 1) result = "Command removed"
  628.     else result = "Commands removed"
  629.     deleteCmds.each{ it ->
  630.         cmdMaps.remove(it)
  631.     }
  632.     return result
  633. }
  634. def commandExists(cmd){
  635.     def result = false
  636.     if (state.customCommands){
  637.         result = state.customCommands.find{ it.value.text == "${cmd}" }
  638.     }
  639.     return result
  640. }
  641. def addCommand(){
  642.     def capabs = [  "Acceleration" :                "accelerationSensor",
  643.                     "Button" :                      "button",
  644.                     "Carbon monoxide detector" :    "carbonMonoxideDetector",
  645.                     "Contact" :                     "contactSensor",
  646.                     "Dimmer" :                      "switchLevel",
  647.                     "Door" :                        "doorControl",
  648.                     "Energy meter" :                "energyMeter",
  649.                     "Garage door" :                 "garageDoorControl",
  650.                     "Humidity" :                    "humiditySensor",
  651.                     "Illuminance" :                 "illuminanceSensor",
  652.                     "Lock" :                        "lock",
  653.                     "Motion" :                      "motionSensor",
  654.                     "Power meter" :                 "powerMeter",
  655.                     "Presence" :                    "presenceSensor",
  656.                     "Smoke detector" :              "smokeDetector",
  657.                     "Switch" :                      "switch",
  658.                     "Temperature" :                 "temperatureMeasurement",
  659.                     "Thermostat" :                  "thermostat",
  660.                     "Water sensor" :                "waterSensor",
  661.                     "Music player" :                "musicPlayer",
  662.                     "Actuator" :                    "actuator"]
  663.     def result
  664.     def newCmd = getCmdLabel()
  665.     def found = commandExists(newCmd)
  666.     def cmdMaps = state.customCommands
  667.     //only update if not found...
  668.     if (!found) {
  669.         state.lastCmdIDX = state.lastCmdIDX + 1
  670.         def nextIDX = state.lastCmdIDX
  671.         def cmd = [text:"${newCmd}",cmd:"${cCmd}"]
  672.         def params = [:]
  673.         def cpTypes = settings.findAll{it.key.startsWith("cpType_")}.sort()
  674.         cpTypes.each{ cpType ->
  675.             def i = cpType.key.replaceAll("cpType_","")
  676.             def cpVal = settings.find{it.key == "cpVal_${i}"}
  677.             def param = ["type":"${cpType.value}","value":"${cpVal.value}"]
  678.             params.put(i, param)
  679.         }  
  680.         cmd.put("params",params)
  681.         if(myCapab) cmd.put("capab", capabs[myCapab]) else cmd.put("capab", "actuator")
  682.         if (cmdMaps) cmdMaps.put((nextIDX),cmd)
  683.         else state.customCommands = [(nextIDX):cmd]
  684.         result = "command: ${newCmd} was added"
  685.     } else {
  686.         result = "command: ${newCmd} was not added, it already exists."
  687.     }
  688.     return result
  689. }
  690.  
  691. def execTestCommand(){
  692.     def result
  693.     def cTypes = settings.findAll{it.key.startsWith("cpType_")}
  694.     def p = getParamsAsList(cTypes.sort()) as Object[]
  695.     devices.each { device ->
  696.         try {
  697.             device."${cCmd}"(p)
  698.             result = "succeeded"
  699.         }
  700.         catch (IllegalArgumentException e){
  701.             def em = e as String
  702.             def ems = em.split(":")
  703.             ems = ems[2].replace(" [","").replace("]","")
  704.             ems = ems.replaceAll(", ","\n")
  705. //          result = "failed, valid commands:\n${ems}"
  706.             result = "failed"
  707.         }
  708.         catch (e){
  709.             result = "failed with:\n${e}"
  710.         }
  711.     }
  712.     return result
  713. }
  714.  
  715. def execCommand(cmdID){
  716.     def result = ""
  717.     def pList = []
  718.     if (cmdID){
  719.         def cmdMap = state.customCommands["${cmdID}"]
  720.         if (testCmd && cmdMap) {
  721.             def params = cmdMap.params.sort()
  722.             params.each{ p ->
  723.                 if (p.value.type == "string"){
  724.                     pList << "${p.value.value}"
  725.                 } else if (p.value.type == "decimal"){
  726.                     pList << p.value.value.toBigDecimal()
  727.                 } else {
  728.                     pList << p.value.value.toInteger()
  729.                 }
  730.             }
  731.             def p = pList as Object[]
  732.             devices.each { device ->
  733.                 try {
  734.                     device."${cmdMap.cmd}"(p)
  735.                     result = "Command succeeded"
  736.                 }
  737.                 catch (IllegalArgumentException e){
  738.                     def em = e as String
  739.                     def ems = em.split(":")
  740.                     ems = ems[2].replace(" [","").replace("]","")
  741.                     ems = ems.replaceAll(", ","\n")
  742.                     result = "Command failed, valid commands:\n${ems}"
  743.                 }
  744.                 catch (e){
  745.                     result = "failed with:\n${e}"
  746.                 }
  747.             }
  748.             return result
  749.         }
  750.     }
  751. }
  752.  
  753. def getDeviceCommands(){
  754.     def result = ""
  755.     devices.each { device ->
  756.         result = device.supportedCommands.collect{ it as String }
  757.         //log.debug "supportedCommands:${result}"
  758.     }
  759.     return result
  760. }
  761.  
  762. def isExpert(){
  763.     return getCommands().size() > 0
  764. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement