This app is great! Thanks so much. I’m trying to add a couple functionalities to this app but it seems my programming skills are a bit rusty.
In short, my concept is if I unlock with a certain code, it will update the mode and turn on a particular song on sonos.
I’ve added components from the Sonos Mood Music template to attempt to achieve this.
Here’s the Sonos Mood Music code:
https://searchcode.com/codesearch/view/89517660/
I’ve been receiving this error:
java.lang.NullPointerException: Cannot get property ‘selectedSong’ on null object @ line 69
Highlighted below
Any help of course would be greatly appreciated.
/**
*/
definition(
name: “Door Unlock Triggers with music selection”,
namespace: “garyd9”,
author: “Gary D”,
description: “Triggers switches, door controls, etc based on lock events”,
category: “Convenience”,
iconUrl: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png”,
iconX2Url: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png”,
iconX3Url: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png”)
preferences {
section(“When a door unlocks…”) {
input “lock1”, “capability.lock”, title: “Door Lock?”, required: true
input “mySwitch”, “capability.switch”, title: “Switch? (for debugging)”, required: false
}
section(“And this user code opened the door:”) {
input “User1”, “enum”, title: “User Code”, metadata:[values:[“1”,“2”,“3”,“4”,“5”]]
}
section(“Then…”){
input “doors”, “capability.doorControl”, title: “Close these doors”, multiple: true, required: false
input “switches”, “capability.switch”, title: “Turn on these switches”, multiple: true, required: false
input “newMode”, “mode”, title: “Change to this mode”, multiple: false, required: false
input name: “sendPush”, type: “bool”, title: “Push notification to mobile devices?”, defaultValue: false
input “sonos”, “capability.musicPlayer”, title: “On this Sonos player”, required: false
input “song”, “enum”, title:“Play this track”, required:false, multiple: false, options: songOptions()
label title: “Assign a name”, required: false
}
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
initialize()
}
def initialize() {
// TODO: subscribe to attributes, devices, locations, etc.
subscribe(lock1, “lock.unlocked”, lockHandler)
subscribe(mySwitch, “switch”, switchHandler, [filterEvents: false])
log.debug "about to subscribe to command…"
subscribeToCommand(mySwitch, “on”, switchOnHandler)
saveSelectedSong()
}
private songOptions() {
// Make sure current selection is in the set
def options = new LinkedHashSet()
if (state.selectedSong?.station) { // THIS IS WHERE THE ERROR OCCCURS
options << state.selectedSong.station
}
else if (state.selectedSong?.description) {
// TODO - Remove eventually? ‘description’ for backward compatibility
options << state.selectedSong.description
}
// Query for recent tracks
def states = sonos.statesSince("trackData", new Date(0), [max:30])
def dataMaps = states.collect{it.jsonValue}
options.addAll(dataMaps.collect{it.station})
log.trace "${options.size()} songs in list"
options.take(20) as List
}
private saveSelectedSong() {
try {
def thisSong = song
log.info "Looking for $thisSong"
def songs = sonos.statesSince(“trackData”, new Date(0), [max:30]).collect{it.jsonValue}
log.info “Searching ${songs.size()} records”
def data = songs.find {s -> s.station == thisSong}
log.info "Found ${data?.station}"
if (data) {
state.selectedSong = data
log.debug "Selected song = $state.selectedSong"
}
else if (song == state.selectedSong?.station) {
log.debug "Selected existing entry '$song', which is no longer in the last 20 list"
}
else {
log.warn "Selected song '$song' not found"
}
}
catch (Throwable t) {
log.error t
}
}
def performActions(evt)
{
doors.eachWithIndex {s, i ->
def state = s.latestValue(“door”)
if (state == “open”)
{
log.debug "$s is currently $state. Closing it."
s.close();
}
else
{
log.debug “$s is currently $state. (can’t close it)”
}
}
switches.eachWithIndex {s, i ->
def state = s.latestValue(“switch”)
if (state == “off”)
{
log.debug "$s is currently $state. Turning it on."
s.on()
}
else
{
log.debug “$s is already $state.”
}
}
log.debug "We made it this far!!!“
setLocationMode(newMode)
sonos.playTrack(state.selectedSong)
if (sendPush)
{
sendPushMessage(evt.descriptionText)
}
}
def lockHandler(evt)
{
if (evt.data == null)
{
log.debug “evData is null”
}
else
{
def evData = parseJson(evt.data)
log.debug “evData.usedCode: ${evData.usedCode}. Attempting to find user $User1"
if (”${evData.usedCode}” == “$User1”)
{
log.debug User1 + " unlocked the door!"
performActions(evt)
}
}
}
def switchHandler(evt)
{
// performActions(evt)
log.debug “switchHandler ${evt.value}”
}
def switchOnHandler(evt)
{
log.debug “switchOnHandler ${evt.inspect()}”
}