[SOLVED] TV Volume Adjustment Rule

I’ve created the rule below in the hope of adjusting my Living Room TV volume depending on what I’m watching, but get the following error and need another pair of eyes to point me in the right direction.

Happy for any input.

Script execution of rule with UID 'Livingroom-8' failed: An error occurred during the script execution: Couldn't invoke 'assignValueTo' for feature JvmVoid:  (eProxyURI: Livingroom.rules#|::0.2.7.2.0.1.1.0.0.1.0.5.1.0.0.2.0::0::/1) in Livingroom

rule "LIVING ROOM: Current App"
when
    Item LivingRoom_TV_App changed
then
    logInfo(logName, "Current app changed: {}", LivingRoom_TV_App.state)
    if (LivingRoom_TV_Volume !== null) {
        if (LivingRoom_TV_Volume.state !== null) {
            val currentVolume = LivingRoom_TV_Volume.state as Number
            logInfo(logName, "Current volume: {}", currentVolume)
            val desiredVolume = if (LivingRoom_TV_App.state.toString == "com.google.android.youtube.tv") {
                20
            } else if (LivingRoom_TV_App.state.toString == "com.sony.dtv.tvx") {
                32
            } else if (LivingRoom_TV_App.state.toString == "com.plexapp.android" || LivingRoom_TV_App.state.toString == "com.amazon.amazonvideo.livingroom") {
                24
            } else {
                currentVolume.intValue
            }
            logInfo(logName, "Desired volume: {}", desiredVolume)
            val stepsToAdjustVolume = desiredVolume - currentVolume.intValue
            if (stepsToAdjustVolume > 0) {
                for (i = 1; i <= stepsToAdjustVolume; i++) {
                    val newVolume = currentVolume.intValue + 1
					logInfo(logName, "Increasing volume to: {}", newVolume)
                    LivingRoom_TV_Volume.sendCommand(newVolume.toString)
                    Thread::sleep(1000)
                }
            } else if (stepsToAdjustVolume < 0) {
                for (i = 1; i <= Math.abs(stepsToAdjustVolume); i++) {
                    val newVolume = currentVolume.intValue - 1
                    logInfo(logName, "Decreasing volume to: {}", newVolume)
                    LivingRoom_TV_Volume.sendCommand(newVolume.toString)
                    Thread::sleep(1000)
                }
            }
        } else {
            logWarn(logName, "LivingRoom_TV_Volume state is null")
        }
    } else {
        logWarn(logName, "LivingRoom_TV_Volume item does not exist or is null")
    }
end

It’s not entirely clear but here it looks like you are trying to use a if/else if statement as of it were a ternary operator. You can’t do that. There is no else if in a ternary operation. Since the regular if statement doesn’t return anything (i.e. void) you get this error.

val desiredVolume = if (LivingRoom_TV_App.state.toString == "com.google.android.youtube.tv") {
                20
            } else if (LivingRoom_TV_App.state.toString == "com.sony.dtv.tvx") {
                32
            } else if (LivingRoom_TV_App.state.toString == "com.plexapp.android" || LivingRoom_TV_App.state.toString == "com.amazon.amazonvideo.livingroom") {
                24
            } else {
                currentVolume.intValue
            }

needs to be

var desiredVolume = currentVolume.intValue

if (LivingRoom_TV_App.state.toString == "com.google.android.youtube.tv") {
                desiredVolume = 20
            } else if (LivingRoom_TV_App.state.toString == "com.sony.dtv.tvx") {
                desiredVolume = 32
            } else if (LivingRoom_TV_App.state.toString == "com.plexapp.android" || LivingRoom_TV_App.state.toString == "com.amazon.amazonvideo.livingroom") {
                desiredVolume = 24
            }

You could chain a bunch of ternary operations together I think but it’ll be harder to read and maintain.

Or use a switch statement instead:

var desiredVolume = currentVolume.intValue

switch(LivingRoom_TV_App.state.toString) {
    case "com.google.android.youtube.tv"     : desiredVolume = 20
    case "com.sony.dtv.tvx"                  : desiredVolume = 32
    case "com.plexapp.android"               : desiredVolume = 24
    case "com.amazon.amazonvideo.livingroom" : desiredVolume = 24
}
1 Like

Thanks both, I’ve now resolved the issue. I needed to add:

val i = 0

I’ll be honest and say that I tried using ChatGPT to help me with updating my existing rule, it’s clearly not as clever as people think or expect.

Certainly not for OH code. However there have been some reports of success with custom ChatGPT bots specially trained on the OH docs and known working examples.