/* * * Licensed Virtual 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: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed * on an "AS IS" BASIS, WIyTHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License * for the specific language governing permissions and limitations under the License. * * Change History: * * Date Who Description * ---------- ------------ ------------------------------------------------ * 24Jun2024 thebearmay Original Code * 25Jun2024 add Restart button, Max/Min/Avg options * 26Jun2024 Fix bug in computed reporting * 27Jun2024 Changes to interface with the UI app, Value interval, purge unused preferences * 01Jul2024 v0.0.6 Make the header optional, optional device column, SDF options for timestamp, fix restart issue * 02Jul2024 v0.0.7 Disable/Enable reporting option, add notification device * v0.0.8 Fix numIter = 1 * 03Jul2024 v0.0.9 Value Change ignoring disable */ static String version() { return '0.0.9' } //import groovy.json.JsonSlurper //import groovy.json.JsonOutput import groovy.transform.Field import java.text.SimpleDateFormat definition ( name: "Device Attribute Iterative Storage - Acquisition", namespace: "thebearmay", author: "Jean P. May, Jr.", description: "Store a set number of attribute values based on pre-determined cycle.", category: "Utility", importUrl: "https://raw.githubusercontent.com/thebearmay/hubitat/main/apps/devAttIterSto.groovy", parent: "thebearmay:Device Attribute Iterative Storage - UI", installOnOpen: true, oauth: false, iconUrl: "", iconX2Url: "" ) preferences { page name: "mainPage" page name: "attrSelect" page name: "compAttr" page name: "optPage" } mappings { } def installed() { // log.trace "installed()" state?.isInstalled = true initialize() } def updated(){ // log.trace "updated()" if(!state?.isInstalled) { state?.isInstalled = true } if(debugEnabled) runIn(1800,logsOff) } def initialize(){ } void logsOff(){ app.updateSetting("debugEnabled",[value:"false",type:"bool"]) } def mainPage(){ dynamicPage (name: "mainPage", title: "", install: true, uninstall: false) { if (app.getInstallationState() == 'COMPLETE') { section(name:"itDetail",title:"Iteration Retention Details", hideable: true, hidden: false){ input "qryDevice", "capability.*", title: "Device Selection:", multiple: false, required: true, submitOnChange: true if (qryDevice != null) { href "attrSelect", title: "Attribute Selection", required: false href "compAttr", title: "Computed Values (Max/Min/Avg)", required: false href "optPage", title: "Advanced Options", required:false input ("numIter","number",title:"Number of Iterations to Retain", submitOnChange: true, width:4) input ("intType", "enum", title:"Reporting Interval Type", options: ["Minutes", "Hours", "Days","Value Change"], submitOnChange: true, width:4) input ("intVal", "number", title: "Reporting Interval Length", submitOnChange: true, width:4) input ("stoLocation","text",title: "Local file name to use for Storage (will add .CSV when file is created)", submitOnChange:true, width:4, defaultValue:"${nameOverride}") if(stoLocation != null) { input ("createFile", "button", title: "Create File", width:4) if(state.fileCreateReq) { purgeOldStates() checkSubscriptions() state.fileCreateReq = false fileInitialize() scheduleReport() } input ("restart", "button", title: "Restart Reporting", width:4) if(state.rptRestart) { state.rptRestart = false scheduleReport() } } input "returnReq", "button", title:"Return to List",backgroundColor:"#007009",textColor:"white" if(state.returnReq){ state.returnReq = false paragraph "" } } } section("Change Application Name", hideable: true, hidden: true){ input "nameOverride", "text", title: "New Name for Application", multiple: false, required: false, submitOnChange: true, defaultValue: app.getLabel() if(nameOverride != app.getLabel()) app.updateLabel(nameOverride) } } else { section("") { paragraph title: "Click Done", "Please click Done to install app before continuing" } } } } def attrSelect(){ dynamicPage (name: "attrSelect", title: "Attribute Selection", install: false, uninstall: false) { section(""){ String strWork = "" dev = qryDevice def attrList=[] dev.supportedAttributes.each{ attrList.add(it.toString()) } sortedList=attrList.sort() sortedList.each{ input "da-$it", "bool", title: "$it", required: false, defaultValue: false, width:4 } paragraph "
$strWork
" } } } def compAttr(){ dynamicPage (name: "compAttr", title: "Computed Values (Max/Min/Avg)", install: false, uninstall: false) { section(""){ String strWork = "" dev = qryDevice def attrList=[] dev.supportedAttributes.each{ if(it.dataType == "NUMBER") attrList.add(it.toString()) } sortedList=attrList.sort() sortedList.each{ input "ca-max-$it", "bool", title: "$it Max", required: false, defaultValue: false, width:4 input "ca-min-$it", "bool", title: "$it Min", required: false, defaultValue: false, width:4 input "ca-avg-$it", "bool", title: "$it Avg", required: false, defaultValue: false, width:4 } paragraph "$strWork
" } } } def optPage(){ dynamicPage (name: "optPage", title: "Advanced Options", install: false, uninstall: false) { section("", hideable: false, hidden: false){ input("sdfPref", "enum", title: "Date/Time Format Timestamp Column", options:sdfList, defaultValue:"Milliseconds", width:4) input("devCol", "bool", title:"Add Column for Device Name", width:4) input("noHeader","bool", title:"Suppress Header Creation", width:4) input("notifyDevice", "capability.notification", title: "Notification Devices:", multiple:true) input("debugEnabled", "bool", title:"Enable Debug Logging",width:4) } } } void checkSubscriptions(){ unsubscribe() settings.each{ if(it.value==true && it.toString().substring(0,3) == 'da-'){ subscribe(qryDevice,"${it.key.substring(3,)}","holdValue") state["${it.key.substring(3,)}"] = qryDevice.currentValue("${it.key.substring(3,)}") } if(it.value==true && it.toString().substring(0,3) == 'ca-'){ subscribe(qryDevice,"${it.key.substring(7,)}","holdValue") state["${it.key.substring(7,)}"] = qryDevice.currentValue("${it.key.substring(7,)}") state["${it.key.substring(3,)}"] = qryDevice.currentValue("${it.key.substring(7,)}") if("${it.key.substring(3,6)}" == "avg") { state["${it.key.substring(3,)}-count"] = 1 } } } subscribe(location, "systemStart","scheduleReport") } void holdValue(evt) { if(degubEnabled) log.debug "entering holdValue