Current State. What makes it show?

Can anyone shed some light on what triggers the Current State to display when clicking on a device? I am trying to modify a driver to work with the [awesome] pp-Code Temp/Humi sensor and I am SO close. I can get the Temperature to pop in to the Current State window by clicking "Refresh" just fine, but it needs to appear by itself on load.

I don't know squat about Java/Groovy. I have written some stuff in PHP and am decent in that, but I'm not a developer. I'm a network admin
"Dammit Jim! I'm a doctor, not a bricklayer!"

So WTF causes the Current State to just be there when you open a device? I'm assuming the tile will not display anything if that's not the case.

I don't know what your experience is... so I'll assume "a lot" and give you the terse answer:
`

sendEvent(name: "local_sunset", value: state.localSunset, descriptionText: "Sunset today at is $state.localSunset", displayed: true)
`

sendEvent puts values in the internal DB and is then shown in the Current States column.

Writing to the state map, adds to the internal DB and is then shown on the left under State Variables:

`

state.clockSeconds = true
`

Do you have

capability.temperatureMeasurement

in your device driver? That defines the attribute "temperature" and it should be be persistent after it updates.

There is also a capability for humidity and many others documented in Driver Capability List - Hubitat Documentation

Mark

I do have that capability, yes. And I have tried playing around with SendEvent as well. It doesn't error, but it doesn't seem to do anything either.

Where exactly does it need to be placed? Anywhere specific?

How about sharing your driver code here, and we'll help you debug it?

Please be sure to mark the entire section of code as preformatted text (</> symbol in editor window.)

Here is an example Temperature Only driver from my HubDuino project. Ignore the "Tiles Section" of code, as that only works on SmartThings. This will at least provide an example of how to use sendEvent().

Hmmm - your preformmated text did not come out correctly... Did you highlight all of the code and then click the preformatted text button?

Anyway... case matters.... try modifying your two createEvent() lines to use "temperature" instead of "Temperature".

Also, your "LastRefresh" attribute is custom and thus you'll need to declare that attribute right underneath the list of Capabilities near the top of your driver using the following syntax

attribute "LastRefresh", "String"

You can also remove the following chunk of leftover SmartThings code as well... it is not used on Hubitat.

main(["switch"])
details(["switch", "explicitOn", "explicitOff","refresh"])
import groovy.json.*

metadata {
	definition (
		name: "pp-Code Temp",
		namespace: "pgitta",
		author: "pgitta",
		importUrl: ""
		)
	{
	capability "TemperatureMeasurement"
	capability "Sensor"
	capability "Refresh" // refresh command
	capability "Polling"
	}

	
	preferences {
	input("ip", "string", title:"IP", description:"Sensor IP Address", defaultValue:"" , required: false, displayDuringSetup: true)
	input "refreshEvery", "enum", title: "Enable auto refresh every XX Minutes", required: false, defaultValue: false, //RK
			options: [5:"5 minutes",10:"10 minutes",15:"15 minutes",30:"30 minutes"] //RK
	input "locale", "enum", title: "Choose refresh date format", required: true, defaultValue: true, //RK
			options: [US:"US MM/DD/YYYY",UK:"UK DD/MM/YYYY"] //RK
	input name: "debugOutput", type: "bool", title: "Enable debug logging?", defaultValue: true
	input name: "txtEnable", type: "bool", title: "Enable descriptionText logging", defaultValue: true //RK
	}
}

def installed() {
    log.debug "Installed"
    refresh()
}

// App Version   *********************************************************************************
def setVersion(){
	state.InternalName = "pp-CodeTempSensor"
    sendEvent(name: "DriverAuthor", value: "pgitta")
	
}

def updated() {
    log.debug "Updated"
    log.info "Preferences updated..."
    log.warn "Debug logging is: ${debugOutput == true}"
    unschedule()
    // RK start
    if (refreshEvery != null) {
    "runEvery${refreshEvery}Minutes"(autorefresh)
    log.info "Refresh set for every ${refreshEvery} Minutes"
    } else {
    runEvery30Minutes (autorefresh)
    log.info "Refresh set for every 30 Minutes"
    }
    if (debugOutput) runIn(1800,logsOff)
    state.LastRefresh = new Date().format("YYYY/MM/dd \n HH:mm:ss", location.timeZone)
    // RK stop
    version()
    refresh()
}

def parse(description) {
    logDebug "Parsing result $description"
    
    def msg = parseLanMessage(description)
    def headersAsString = msg.header // => headers as a string
    def headerMap = msg.headers      // => headers as a Map
    def body = msg.body              // => request body as a string
    def status = msg.status          // => http status code of the response
    def data = msg.data              // => either JSON or XML in response body (whichever is specified by content-type header in response)
    
    logDebug "Data"
    logDebug data
    
    def evt1 = null
    
    if ( data.Stats.Temp != null ) {
        logDebug "CreateEvent ison=true"
        evt1 = createEvent(name: "Temperature", value: data.Stats.Temp, displayed: false)
        
    } else  {
        logDebug "CreateEvent ison=false"
        evt1 = createEvent(name: "Temperature", value: "null", displayed: false)
    }

    return evt1
    
}

def ping() {
	logDebug "ping"
	poll()
}

def initialize() {
	log.info "initialize"
	if (txtEnable) log.info "initialize" //RK
	refresh()
}

def logsOff(){
	log.warn "debug logging auto disabled..."
	device.updateSetting("debugOutput",[value:"false",type:"bool"])
}

def autorefresh() {
	if (locale == "UK") {
	if (debugOutput) log.info "Get last UK Date DD/MM/YYYY"
	state.LastRefresh = new Date().format("d/MM/YYYY \n HH:mm:ss", location.timeZone)
	sendEvent(name: "LastRefresh", value: state.LastRefresh, descriptionText: "Last refresh performed")
	} 
	if (locale == "US") {
	if (debugOutput) log.info "Get last US Date MM/DD/YYYY"
	state.LastRefresh = new Date().format("MM/d/YYYY \n HH:mm:ss", location.timeZone)
	sendEvent(name: "LastRefresh", value: state.LastRefresh, descriptionText: "Last refresh performed")
	}
	if (txtEnable) log.info "Executing 'auto refresh'" //RK
	refresh()

}

def refresh() {
    logDebug "Refresh - Getting Status"
    sendHubCommand(new hubitat.device.HubAction(
      method: "GET",
      path: "/b1247e052719&Stats/json",
      headers: [
        HOST: getSensorAddress(),
        "Content-Type": "application/x-www-form-urlencoded"
      ]
    ))
}

private logDebug(msg) {
	if (settings?.debugOutput || settings?.debugOutput == null) {
	log.debug "$msg"
	}
}

def sendSwitchCommand(action) {
    if (txtEnable) log.info "Calling /relay/ with $action"
    sendHubCommand(new hubitat.device.HubAction(
      method: "POST",
      path: "/b1247e052719&Stats/json",
      body: action,
      headers: [
        HOST: getSensorAddress(),
        "Content-Type": "application/x-www-form-urlencoded"
      ]
    ))
    refresh()
}


// handle commands
//RK Updated to include last refreshed
def poll() {
	if (locale == "UK") {
	if (debugOutput) log.info "Get last UK Date DD/MM/YYYY"
	state.LastRefresh = new Date().format("d/MM/YYYY \n HH:mm:ss", location.timeZone)
	sendEvent(name: "LastRefresh", value: state.LastRefresh, descriptionText: "Last refresh performed")
	} 
	if (locale == "US") {
	if (debugOutput) log.info "Get last US Date MM/DD/YYYY"
	state.LastRefresh = new Date().format("MM/d/YYYY \n HH:mm:ss", location.timeZone)
	sendEvent(name: "LastRefresh", value: state.LastRefresh, descriptionText: "Last refresh performed")
	}
	if (txtEnable) log.info "Executing 'poll'" //RK
	refresh()
}

private getSensorAddress() {
    def port = 80
    def iphex = ip.tokenize( '.' ).collect { String.format( '%02x', it.toInteger() ) }.join().toUpperCase()
    def porthex = String.format('%04x', port.toInteger())
    def sensorAddress = iphex + ":" + porthex
    if (txtEnable) log.info "Using IP " + ip + ", PORT 80 and HEX ADDRESS " + sensorAddress + " for device: ${device.id}"
	return sensorAddress
}

private dbCleanUp() {
	unschedule()
	state.remove("version")
	state.remove("Version")
}

// Check Version   ***** with great thanks and acknowlegment to Cobra (github CobraVmax) for his original code **************
def version(){
	updatecheck()
	schedule("0 0 18 1/1 * ? *", updatecheck) // Cron schedule
//	schedule("0 0/1 * 1/1 * ? *", updatecheck) // Test Cron schedule
}

You will also need

attribute "DriverAuthor", "String"

However, personally I would not create these two values (LastRefresh and DriverAuthor) as custom attributes, as nothing will ever user them. They will generate useless events in the system. I would simply keep them as 'state' variables only, which are only shown on the device details page.

So, the auto-refresh seems to work, and 5 minutes is ok with me, but the data never shows in the dashboard tile. Isn't the current state where it pulls that from?

The Dashboard gets data from the Device's Attributes (i.e. current status) as well as Events raised by the createEvent() and sendEvent() calls. FYI - createEvent() can only be used in parse(), while sendEvent() can be used in any function of the driver.

Please show a screenshot of your device details page which show the attributes and state variables.

Got it! wow. Case will kill ya.

"Temperature" doesn't work. "temperature" works perfectly. All this grief over a byte.

Thank you to everyone for the hints and tips. When I get the driver all pared down to remove references from the switch driver it originated from, I'll post it in case anyone gets a pp-Code H&T

These things are beasts, run off a USB adaptor, NO BATTERIES! and balls-on accurate. And the people who make them are totally commited to them and customer service. Their REST call didn't send the content-type originally. I emailed them last night, and this morning they sent the files to flash to get it working. Check 'em out: https://www.amazon.com/pp-Code-Temperature-Humidity-monitor-party-detect/dp/B01MV415MP/ref=sr_1_1?keywords=pp-code&qid=1562007617&s=gateway&sr=8-1

Looks like an ESP8266, with an LCD display and a DHT22 Temp/Humidity sensor... Sound about right?

Have you looked at my HubDuino project? You can build the same thing, with code and drivers already written for Hubitat or SmartThings, for about $15 (no LCD). Obviously, it's nice to have a business writing and maintaining the software for you, which it sounds like pp-Code is doing a great job of.

Take a look at HubDuino. It can do temperature measurement, servo motors, contact sensors, alarm sirens/strobes, etc...

1 Like

BTW - Did you miss my earlier post regarding CaSe SeNsItIvItY ?

You may be right. And I will check it out. Right now though, I'm time limited, so I don't mind slipping these guys 35 bucks for something ready to rock 'n roll, but I'm all for DIY usually.

I MUST have missed your cAsE MatTerS post :slight_smile: because I had to learn it the hard way. I'm used to variables requiring it, but that looked like a string and I didn't think it mattered.

Thanks for all your help. Even the parts I missed.

1 Like

Oh, and it looks like an AM2302 T&H sensor

That's actually a pretty decent price, since it comes with the enclosure and power supply as well (and a team a developers!)

Which is just a DHT22 with different packaging, I believe... :wink:

Another option you might be interest in, if you want something smaller and Zigbee, is @iharyadi's Environment Sensor. It does temperature, humidity, barometric pressure, illuminance, and is a Zigbee repeater. If also has some GPIO pins that you can use as you see fit. Very cool device!

1 Like

I'll check that out, thanks. (and i just looked at the numbers on the side of the case. I haven't researched any components) I doubt there are 47 different companies making these sensors.

I don't appreciate my code being rip and all my credits being stripped out. Either restore the credits or create your own code.

Code:
https://raw.githubusercontent.com/sgrayban/Hubitat-Ports/master/Drivers/rpi/Raspberry-Pi-Stats.groovy

/**
 *
 *  Raspberry Pi Stats
 *
 *  Copyright Janos Elohazi
 *  Copyright Scott Grayban
 *
 *  Ported to Hubitat by Scott Grayban with help from ogiewon and royski
 *
 *  Monitor your Raspberry Pi using SmartThings and Raspberry Pi Monitor <https://github.com/sgrayban/raspberrypi.monitor>
 *
 *  *************************************************************************
 *  Licensed under the GNU v3 (https://www.gnu.org/licenses/gpl-3.0.en.html)
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  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.
 *  *************************************************************************
*/

GPLV3 does NOT give you any rights to remove credits and pretend you wrote it. Friggin thieves.

He's not overreacting and you violated the license that he released the code with. You need to include the original license and mentioned what the handler started out as and include the original author. (I usually release under Apache 2 so GPLV3 might be a little different, but I'm sure it requires at least those things)

Borrowing a block of code is not the same as taking someone else's handler, making a few changes, and re-posting it. Developers spend a lot of time writing code and they post it online for free so that others can use it so either respect their license or don't post the modified version at all.

Like you said, you don't have time to write code from scratch, but if you did spend lots of time writing a full handler and then someone removed your name from it and posted it on the forum, I'm sure you'd be upset too...

2 Likes