Issue Converting Driver from ST to HE: Cannot get property 'label' on null object

Hello!

I'm converting my home from ST to HE, and first off, man, Loving HE! So fast, and so easy! Everything just works! = )

But I'm having issues porting a driver over from ST. I wrote it for a App I wrote "Smart Room". My App ported over just fine, but when I try to save the Driver, I get the error:

Cannot get property 'label' on null object on line 19

I searched the forum for that error, but wasn't able to pull anything applicable from what I read. Line 19 is the 'metadata' line in the below code.

Does anyone have any insights into what I'm doing wrong?

Thanks for your time,
Nick

/**
 *  Smart Room
 *
 *  Copyright 2015 Nick Albright
 *
 *  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:
 *
 *      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, 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.
 *
 */
public static String version() { return "v1.0.0" }


metadata {
	definition (name: "Smart Room", namespace: "albrnick", author: "Nick Albright") {
		capability "Presence Sensor"	// For Occupied
		capability "Switch"   			// For Lights auto on and off
        capability "Motion Sensor"		// For triggering the room externally
        capability "Thermostat Mode"	// Hack for displaying the tile
        capability "ContactSensor"				// For communicating ligths on or off to room app
        
        attribute "lights", "enum", ["on", "off"]
        
        command "on"					// Turn on Lights auto on and off
        command "off"					// Turn off Lights auto on and off
		command "active"
		command "inactive"       
        command "isOccupied"			// Is the room occupied?
        command "lightsOn"				// Turn the room's lights on
        command "lightsOff"				// Turn the room's lights off
	}

	simulator {
		// TODO: define status and reply messages here
	}

	// hack
	// heat -> Lights Changable & Occupied
    // cool -> Lights Changable & UnOccupied
    // emergency heat -> Lights Not Changable & UnOccupied
    // auto -> Lights Not Changable & Occupied

	tiles {
		standardTile("thermostatMode", "device.thermostatMode", width: 2, height: 2, canChangeIcon: true ) {
			state("heat", label: "occ heat", action: "auto", icon: "st.doors.garage.garage-closed", backgroundColor: "#ffffff", nextState: "auto")
			state("cool", label: "${device.label}", action: "emergencyHeat", icon: "st.doors.garage.garage-open", backgroundColor: "#ffffff", nextState: "emergency heat", defaultState: true)
			state("emergency heat", label: "c", action: "cool", icon: "st.doors.garage.garage-open", backgroundColor: "#bbbbbb", nextState: "cool")
			state("auto", label: "occ auto", action: "heat", icon: "st.doors.garage.garage-closed", backgroundColor: "#bbbbbb", nextState: "heat")
		}
		standardTile("state", "device.state", width: 2, height: 2, canChangeIcon: true ) {
			state("on", label: 'On', action: "switch.off", icon: "st.switches.switch.on", backgroundColor: "#79b821", nextState: "off")
			state("off", label: 'Off', action: "switch.on", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "on")
        }
        
		standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
			state("default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh")
		}
		main "thermostatMode"
		details(["thermostatMode", "state", "refresh"])
	}
}

// parse events into attributes
def parse(String description) {
	log.debug "xParsing '${description}'"
	// TODO: handle 'presence' attribute
	// TODO: handle 'switch' attribute

}

def poll() {
	log.debug('polled!')
}

def set_state( occupied, no_trigger_lights ) {
	log.debug("${device.label} set_state")
    
    def s = null
	if (no_trigger_lights) {
    	if ( occupied ) {
        	s = 'auto'
        } else {
        	s = 'emergency heat'
        }        	
    } else {	// Triggerable lights!
    	if ( occupied ) {
        	s = 'heat'
        } else {
        	s = 'cool'
        }        	
    }
    if (s) {
      	sendEvent( name: 'thermostatMode', value: s, isStateChange: true  )
    }
    log.debug("${device.label} set state to ${s}")
}

def tell_parent_auto_lights() {
	log.debug('allowing lights 2')
    // Seems to fix a bug where the parent doesn't get like the first event 
    log.debug("${parent.state.occupied}")
    sendEvent(name: 'state', value: 'on')
}

def tell_parent_no_auto_lights() {
	log.debug('disallowing lights 2')
    // Seems to fix a bug where the parent doesn't get like the first event 
    log.debug("${parent.state.occupied}")
	sendEvent(name: 'state', value: 'off')
}

def lightsOn() {
	log.debug( 'Sending lights on')
	sendEvent(name: 'lights', value: "on", isStateChange: true )
}

def lightsOff() {
	log.debug( 'Sending lights off')
	sendEvent(name: 'lights', value: "off", isStateChange: true )

}

// handle commands
// Switch - turn on/off auto lights
def on() {
	log.debug("on")

    log.debug("state ${state}")
    tell_parent_auto_lights() 
}

def off() {
	log.debug("off")

    tell_parent_no_auto_lights() 
}


// 
def isOccupied() {
	return( parent.state.occupied )
}

// Motion sensing
def active() {
	log.trace "active() 2"
	sendEvent(name: "motion", value: "active")
    runIn(1, inactive)
}

def inactive() {
	log.trace "inactive() 2"
    sendEvent(name: "motion", value: "inactive")
}



def emergencyHeat() { 
	log.debug("emergencyHeat..2")


    tell_parent_no_auto_lights()

	sendEvent(name: 'thermostatMode', value: 'emergency heat', isStateChange: true)

}

def auto() { 
	log.debug('auto..2')
    tell_parent_no_auto_lights()

	sendEvent(name: 'thermostatMode', value: 'auto', isStateChange: true)

}

def heat() { 
	log.debug('heat..2')
    tell_parent_auto_lights()

	sendEvent(name: 'thermostatMode', value: 'heat', isStateChange: true)
    

}
def cool() { 
	log.debug('cool..2')
    tell_parent_auto_lights()
    
	sendEvent(name: 'thermostatMode', value: 'cool', isStateChange: true)
    
}

There are no tiles in Hubitat drivers. You should remove (or comment out) all of that.

at the least, you will want to remove or comment out the simulator and tiles sections of metadata as those aren't used.

check out this thread that has more details about the differences between ST and Hubitat drivers and what the minimum changes are needed to get it to load without errors:

Commenting out the tiles and simulator sections worked! :slight_smile: Thanks!

Thanks for the link to that thread, I had read the first post, but didn't realize there was good information spread below!

Much Appreciated! :slight_smile: Thanks!

1 Like

Download the Hubitat app