RM Help: Warmest or coldest room

I have temperature sensors in most rooms of the house. I would like a simple method to determine the warmest and coldest rooms and update a global variable with the specific name of that room. I started down the LONG path of a conditional statement and this will be a painfully long method!

I'm gonna bet there's no clean way to do this in RM. I did a quick search of the forum hoping there would be a third party app that did something close but I don't see anything obvious. I'm sure you could do this in Groovy with a simple bubble sort but that requires more knowledge than I have.

One thing I was mulling over, and this is only a half-baked thought... you could use hub variables and write a separate rule that just compared 1 variable to the entire set, and then run the rule actions of that secondary rule like a subroutine against all 9 rooms. That might reduce the complexity of the master rule. But it would still be ugly.

2 Likes

Yeah, I can't find a "pretty" solution either. I think I had something like this ages ago in a rule that progressively compared readings to a variable but I thought it ground the hub to a halt, but that was early in my HE days, so things may have changed...

I'm expecting an app may be better placed to deal with this... but I would have thought someone would have done this already...

Simon

1 Like

This should be easy in webcore

Threw this together. Simple app but may give you some ideas:

Room Temperature App
/*

 */

static String version()	{  return '0.0.0'  }


definition (
	name: 			"Room Temperatures", 
	namespace: 		"thebearmay", 
	author: 		"Jean P. May, Jr.",
	description: 	"Logic Check .",
	category: 		"Utility",
	importUrl: "https://raw.githubusercontent.com/thebearmay/hubitat/main/apps/xxxxx.groovy",
	oauth: 			false,
    iconUrl:        "",
    iconX2Url:      ""
) 

preferences {
   page name: "mainPage"
   page name: "currentTemps"
}

def installed() {
//	log.trace "installed()"
    state?.isInstalled = true
    initialize()
}

def updated(){
//	log.trace "updated()"
    if(!state?.isInstalled) { state?.isInstalled = true }
	if(debugEnable) runIn(1800,logsOff)
}

def initialize(){
}

void logsOff(){
     app.updateSetting("debugEnable",[value:"false",type:"bool"])
}

def mainPage(){
    dynamicPage (name: "mainPage", title: "", install: true, uninstall: true) {
      	if (app.getInstallationState() == 'COMPLETE') {   
	    	section("Main")
		    {
                input "qryDevice", "capability.temperatureMeasurement", title: "Devices of Interest:", multiple: true, required: true, submitOnChange: true
                if (qryDevice != null) href "currentTemps", title: "Current Room Tempertaures", required: false
		    }
	    } else {
		    section("") {
			    paragraph title: "Click Done", "Please click Done to install app before continuing"
		    }
	    }
    }
}

def currentTemps(){
    dynamicPage (name: "currentTemps", title: "", install: false, uninstall: false) {
	  section("Rooms by Temperature"){
          LinkedHashMap devTable = [:]
          qryDevice.each{
              devTable.put(it.displayName, it.currentValue("temperature"))
          }
          wrkStr = "<table>"
          tempSorted = devTable.sort { -it.value }
          tempSorted.each{
              wrkStr+="<tr><td>${it.key}</td><td>${it.value}</td></tr>"
          }
          wrkStr+="</table>"
          maxValue = devTable.max{it.value}
          minValue = devTable.min{it.value}

          paragraph "Warmest $maxValue<br>Coolest $minValue<br><br>$wrkStr"
       }
    }
}

def appButtonHandler(btn) {
    switch(btn) {
          default: 
              log.error "Undefined button $btn pushed"
              break
      }
}

def intialize() {

}
3 Likes

WOW! Yes, this works beautifully! Thank you so much for putting this together for me. This app works flawlessly and shows the warmest and coldest rooms. I am not a developer so the next step isn't really clear for me. Is there something I can do to get this to periodically run and update two hub variables? Is that what the appButtonHandler is for?

Thanks Again!! Jeff

I can make those mods pretty quick. To run peridiocally we just need to add a runIn or schedule command; as for the hub variables if you create the connectors for them they will show up as devices which can be used by the app. Looks like you just want the names of the Warmest and Coldest to go to the variables?

Updated Code
/*

 */

static String version()	{  return '0.0.0'  }


definition (
	name: 			"Room Temperatures", 
	namespace: 		"thebearmay", 
	author: 		"Jean P. May, Jr.",
	description: 	"Logic Check .",
	category: 		"Utility",
	importUrl: "https://raw.githubusercontent.com/thebearmay/hubitat/main/apps/xxxxx.groovy",
	oauth: 			false,
    iconUrl:        "",
    iconX2Url:      ""
) 

preferences {
   page name: "mainPage"
   page name: "currentTemps"
}

def installed() {
//	log.trace "installed()"
    state?.isInstalled = true
    initialize()
}

def updated(){
//	log.trace "updated()"
    if(!state?.isInstalled) { state?.isInstalled = true }
	if(debugEnable) runIn(1800,logsOff)
}

def initialize(){
}

void logsOff(){
     app.updateSetting("debugEnable",[value:"false",type:"bool"])
}

def mainPage(){
    dynamicPage (name: "mainPage", title: "", install: true, uninstall: true) {
      	if (app.getInstallationState() == 'COMPLETE') {   
	    	section("Main")
		    {
                input "qryDevice", "capability.temperatureMeasurement", title: "Devices of Interest:", multiple: true, required: true, submitOnChange: true
                if (qryDevice != null){
                    href "currentTemps", title: "Current Room Tempertaures", required: false
                    input "warmDev", "capability.variable", title: "Hub Variable Connector for Warmest", multiple: false, submitOnChange:true
                    input "coldDev", "capability.variable", title: "Hub Variable Connector for Coldest", multiple: false, submitOnChange:true
                    input "pollInterval", "number", title: "Polling Interval in Seconds (Zero to disable)", submitOnChange: true, defaultValue:0
                    if(pollInterval>0){
                      unschedule()
                      runIn(pollInterval, "currentTemps")
                    }
                }
		    }
	    } else {
		    section("") {
			    paragraph title: "Click Done", "Please click Done to install app before continuing"
		    }
	    }
    }
}

def currentTemps(){
    dynamicPage (name: "currentTemps", title: "", install: false, uninstall: false) {
	  section("Rooms by Temperature"){
          LinkedHashMap devTable = [:]
          qryDevice.each{
              devTable.put(it.displayName, it.currentValue("temperature"))
          }
          wrkStr = "<table>"
          tempSorted = devTable.sort { -it.value }
          tempSorted.each{
              wrkStr+="<tr><td>${it.key}</td><td>${it.value}</td></tr>"
          }
          wrkStr+="</table>"
          maxValue = devTable.max{it.value}
          minValue = devTable.min{it.value}

          paragraph "Warmest $maxValue<br>Coolest $minValue<br><br>$wrkStr"
          if(warmDev) warmDev.setVariable(maxValue.toString().substring(0,maxValue.toString().indexOf('=')))
          if(coldDev) coldDev.setVariable(minValue.toString().substring(0,minValue.toString().indexOf('=')))
          if(pollInterval>0){
              unschedule()
              runIn(pollInterval, "currentTemps")
          }
       }
    }
}

def appButtonHandler(btn) {
    switch(btn) {
          default: 
              log.error "Undefined button $btn pushed"
              break
      }
}

def intialize() {

}

Edit: Updated the code and added to this post - @jwzimms

2 Likes

THANK YOU! You rock!
This little app works perfectly for my needs. I REALLY appreciate you putting this together for me.

Thanks,
Jeff

1 Like