Zse50

Tell me, what happens when you run Sound Number 2?
I'm still getting a null, with red flashing light.
Have to run another sound to get rid of it.
edit: Plus, right now, I'm not getting anything in logs when I hit Configure, or anything at the moment.
edit2: Plays sounds, except for 2, but logging nothing. Weird.
edit3: Logging now. Had to save preferences.

When I hit Configure now, I get a blinking red light, like when Sound 2 is chosen, and an unending Null logging stream, until I play another sound number:

My number 2 is one of the files with the underscore. When I play it I just get a flashing red light. It eventually turns off or I can hit stop to stop it.

I don't get any of those errors in the log.

Wish @agnes.zooz would chime in about those underscore files. Be nice to get rid of them.

1 Like

I don't get any of those sounds showing up on device states, but I get a slew of sounds when I play an item more than 25 in there. It's like there are duplicates, but they don't show up on the usb file list.

I think I'm giving up on this until the big brains get involved.

1 Like

I ordered a couple and they all paired and worked out of the box (with the exception of the corrupted "3" file).

Anybody able to make use of the LED? If all it can do is flash red when playing a file, i'll probably tape over it.

The LED should be controllable with a custom driver and likely the upcoming built-in driver.

2 Likes

Would these likely make an appearance in the beta group first?

The built-in driver is likely to become part of the 2.4.3 platform beta. A custom driver, of course, would be something anyone can do on their own unrelated to the platform software.

2 Likes

Maybe I'm trying to do things that aren't the primary function it was designed for. I'm not too concerned about the LED as I really don't have a use for that. But I'm trying to use it for voice messages. Which seems to work fine. The problem being if I add a message, mp3 file, it changes the numbers of all of them. Which can mean a bunch of changes to rules, apps, etc. I doubt that is a driver solvable problem, more likely a firmware.

I imagine a driver could be built so you can play the file via the name instead of the number. Then as long as you do not rename the files it would keep working.

1 Like

You are the best at it. Have you got one in the works?

2 Likes

If I did you all would have it too.

4 Likes

Mine is working for what I made it do and I am not adding anything else to it until a more mature product is available. I experienced the adding of a new file moves things around. This certainly should have been seen by the developers before releasing the beta of it. I like it and the price is incredible, but you get what you pay for at the moment.

Hubitat is not the only platform Zooz devices are used on. Just because there's not a ready-made driver for it yet on Hubitat doesn't mean that's true for all other platforms too.

Having been the primary firmware developer for a programmable mp3 playback device in the life-safety industry, indexing of the mp3 files is primary and must be predictable. This is not what seems to be the case on this device. Regardless of driver, the file system needs to be a focus. It appears it was not in this case.

2 Likes

I'm no expert, but I would think the firmware would have to allow for this.

The driver can do it as long as it knows the filenames. The trick would be finding a standard way to do this, as the "Chime" capability specifies that the standard command should take the number (I suppose resorting to assuming name if the input is not a number would work in most cases, or a custom command).

Nah, once you have the list of the tone numbers / names you just use that look up the number from the name inputted (in the driver code), then send the number to the device as expected.

So based on comments above, here is what I did.

I created a separate app for playing the sounds on the device. Then in all my other apps I set a variable from 1 to whatever. In the app I made an array of state variables with the file names. Then I parse out the soundEffects from the device, iterate thru them to match up the file name with my array index, get the key value, which is the sound number, then play the sound.
Once I got past the learning curve on changing a JSON_OBJECT to a MAP, it wasn't too bad.

Now if I change a file or add any I only have to change things once in the one app.

Here is my code if anyone wants to critique it and let me know if there is ways to improve it.

/**
 *  Alert Speech App
 *
 *  Copyright 2025 Jim White
 *
 *  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.
 *
 */
definition(
    name: "Alert Speech",
    namespace: "jwwhite001",
    author: "Jim White",
    description: "Controls Speech To Zooz ZSE50",
    category: "My Apps",
    iconUrl: "",
    iconX2Url: "",
    iconX3Url: "")

    import groovy.json.JsonSlurper 

preferences {
	section("Alert Devices") {
		input "alertChime1", "capability.chime", required: true, multiple: false, title: "Chime 1 To Activate"
//		input "alertChime2", "capability.chime", required: true, multiple: false, title: "Chime 2 To Activate"
   }
}

def installed() {
	log.debug "Installed with settings: ${settings}"

	initialize()
}


def updated() {
	log.debug "Updated with settings: ${settings}"

    unschedule()
	unsubscribe()
	initialize()
}

def initialize() {
   unschedule()
   subscribe(location, "variable:alert1Mess", alert1MessageHandler)  
//   subscribe(location, "variable:alert2Mess", alert2MessageHandler)  
   state.alert1names = [] 
   initValues() 
}

def initValues() {
    state.alert1names[0] = ""
    state.alert1names[1] = "AlarmOff.mp3"
    state.alert1names[2] = "NightMode.mp3"
    state.alert1names[3] = "BackDoor.mp3"
    state.alert1names[4] = "BackRemained.mp3"
    state.alert1names[5] = "BackGarageDoor.mp3"
    state.alert1names[6] = "BackGarageRemained.mp3"
    state.alert1names[7] = "OverheadDoor.mp3"
    state.alert1names[8] = "OverheadRemained.mp3"
    state.alert1names[9] = "DogAlert.mp3"
    state.alert1names[10] = "DogAlert2 .mp3"
    state.alert1names[11] = "DogAlert3.mp3"
    state.alert1names[12] = "DrivewayVisitor.mp3"
    state.alert1names[13] = "FrontporchVisitor.mmp3"
    state.alert1names[14] = "GateClosed.mp3"
    state.alert1names[15] = "GateOpen.mp3"
    state.alert1names[16] = "GateRemainedOpen.mp3"
    state.alert1names[17] = "siren1.mp3"
    state.alert1names[18] = "doorbell1.mp3"
    state.alert1names[19] = "buzzer-alarm.mp3"
    state.alert1names[20] = "ambulance.mp3"
}

def alert1MessageHandler(evt) {
	alertFiles = alertChime1.currentsoundEffects
    def alertMap = parseJson(alertFiles)
    def alertNumber = getGlobalVar("alert1Mess").getValue().toInteger()

//    log.debug "${alertNumber}"	
    if (alertNumber > 0 && alertNumber < 21) {
        def alertMess = state.alert1names[alertNumber]
//        log.debug "${alertMess}"
        for ( e in alertMap ) {
            if (e.value == alertMess) {
//                log.debug "Key = ${e.key}, Value = ${e.value}"
                soundNo = e.key.toInteger()
                alertChime1.playSound(soundNo)
                break
            }
        }
    }
    setGlobalVar("alert1Mess", 0)
}



4 Likes