Rule to slowly fade in or out any given item based on variables

Well, i did it exactly, like the original creator of the script:

import org.eclipse.smarthome.model.script.ScriptServiceUtil

right at the first line in the rules-file
Is there a way to check whether the import is really successful?
Or is there a dependency which has to be met before? (Java is installed ofcourse)


Also i found another post ([Rules DSL] Get item from string name! which tells, you need to change the import to

import org.openhab.core.model.script.ScriptServiceUtil

And the last part did it! :smiley:
but you need to restart openhab, even the rule is reloaded, as sonn as you save the changes (te log file also shows, that the module is realoaded)

But you’ve shown us a UI entered rule, not a rule from a xxx.rules file as used in 2018? The UI entered rule shares nothing with your import, which is local to the xxx.rules file it is in only.

I don’t think you can do imports like this in UI rules.

But you’ve shown us a UI entered rule, not a rule from a xxx.rules file as used in 2018?

Right.
As described, this is a new rule i created, which calls the text-coded rule, as soon as movement is recognized by the presence sensor :wink:
It’s a bit tricky, but the error was caused by changed import in version 3 in combination with OH not loading the import, when it is not restarted.


Args … the script seems to be not ok anymore (due to changed environment i guess?)
The script runs now, but it’s buggy.

[ERROR] [.internal.handler.ScriptActionHandler] - Script execution of rule with UID 'universaldimmer-1' failed: 'plusMillis' is not a member of 'java.time.ZonedDateTime'; line 69, column 27, length 22 in universaldimmer

The light is dimmed by one step (which is set as the 3rd parameter) and stops then. It’s not repeated until the set destination value (the 1st variable).
So to be precise: when i turn my light on by hand to 40% and start the script with as follows:

Dimmer,0,2000,10,Lampe_Helligkeit

The dimmer is set from 40% to 30%, then 30% to 38%, and again 38% to 30% and the script stops …


Also found a solution for this.
You need to change to lines to make it work nice and smooth :slight_smile:

now.plusMillis(mytime)

must be changed to

now.toInstant().plusMillis(mytime).atZone(now.zone)

You should be able to. If it doesn’t work it’s a bug.

You didn’t mention whose version you were using. The code snippet you mention that needs fixing isn’t in my version. Your symptoms sound like problems I had with the one originally posted.

See my post from Sept 20 for a version that works much better. It has been working flawlessly for me.

I’ve been using your version for months without issues, although upgrading to OpenHAB 3 has broken the universaldimmer script, as it doesn’t seem to work at all.

I receive the following error in my openhab.log file when I attempt to execute a dimming function:

2021-01-23 00:55:01.396 [ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID ‘universaldimmer-1’ failed: The name ‘ScriptServiceUtil’ cannot be resolved to an item or type; line 40, column 20, length 17 in universaldimmer

Thinking it may have been caused by the import line at the very top, I commented out

import org.eclipse.smarthome.model.script.ScriptServiceUtil

and replaced it with

import org.openhab.core.model.script.ScriptServiceUtil

after reading My experience migrating from OH2.5 to OH 3.0 although that made no difference and the same error shows up in my logs when I try to use the universaldimmer command on a light.

The only other thing I’ve noticed that has broken for me as well is googletts, everything appears to be set up the same, although I’m just trying to work out one issue at a time.

I didn’t realise OH3 was out. Will look into upgrading and fixing the script.

Oh that’ll be great, thank you so much! :slight_smile: I wasn’t aware either until 3 or 4 days ago, when I randomly visited the OpenHab blog and saw it came out on Dec 21.

I’ve loved the universalfader script so much because it’s worked so well with my TP-Link Kasa Dimmer Switches to slowly fade certain lights with an offset of when it gets to be dusk, so as it gets dark outside, my office slowly gets brighter over the course of about 12.5 minutes so you don’t even really realize the lights are coming on. :slight_smile:

All done.

  • Revision 4 of the gist supports OH3. :warning: Requires Regex transformation to be installed
  • Revision 3 contains the OH2 version
1 Like

Thanks for such a prompt update! It seems I’m running into a small hiccup where it begins the dimming, but then fails within a 100ms. I seem to already have the Regex transformation installed, but here is what my logs show when I attempt to trigger the dimming:

2021-01-27 15:08:54.793 [INFO ] [el.core.internal.ModelRepositoryImpl] - Loading model 'dimmer.rules'
2021-01-27 15:09:28.997 [INFO ] [ab.core.model.script.UniversalDimmer] - Dim Light_UL_OfficeCeilingBrightness PercentType from 0 => 50 over 5000 ms
2021-01-27 15:09:29.000 [INFO ] [ab.core.model.script.UniversalDimmer] - itemName=Light_UL_OfficeCeilingBrightness set to 0.13, iteration=1, elapsedMs=13
2021-01-27 15:09:29.002 [INFO ] [ab.core.model.script.UniversalDimmer] - itemName=Light_UL_OfficeCeilingBrightness set to 0.15, iteration=2, elapsedMs=15
2021-01-27 15:09:29.003 [INFO ] [ab.core.model.script.UniversalDimmer] - itemName=Light_UL_OfficeCeilingBrightness set to 0.16, iteration=3, elapsedMs=16
2021-01-27 15:09:29.008 [INFO ] [ab.core.model.script.UniversalDimmer] - itemName=Light_UL_OfficeCeilingBrightness set to 0.21, iteration=4, elapsedMs=21
2021-01-27 15:09:29.008 [WARN ] [el.script.internal.actions.TimerImpl] - Rescheduling failed as execution has already started!
2021-01-27 15:10:19.715 [WARN ] [ore.io.rest.auth.internal.AuthFilter] - Unauthorized API request: Invalid Basic authentication credentials
2021-01-27 15:11:36.296 [INFO ] [ab.core.model.script.UniversalDimmer] - Cancelling existing timer for Light_UL_OfficeCeilingBrightness
2021-01-27 15:11:36.296 [INFO ] [ab.core.model.script.UniversalDimmer] - Dim Light_UL_OfficeCeilingBrightness PercentType from 0 => 50 over 5000 ms
2021-01-27 15:11:36.298 [INFO ] [ab.core.model.script.UniversalDimmer] - itemName=Light_UL_OfficeCeilingBrightness set to 0.02, iteration=1, elapsedMs=2
2021-01-27 15:11:36.300 [INFO ] [ab.core.model.script.UniversalDimmer] - itemName=Light_UL_OfficeCeilingBrightness set to 0.04, iteration=2, elapsedMs=4
2021-01-27 15:11:36.304 [INFO ] [ab.core.model.script.UniversalDimmer] - itemName=Light_UL_OfficeCeilingBrightness set to 0.08, iteration=3, elapsedMs=8
2021-01-27 15:11:36.305 [INFO ] [ab.core.model.script.UniversalDimmer] - itemName=Light_UL_OfficeCeilingBrightness set to 0.10, iteration=4, elapsedMs=10
2021-01-27 15:11:36.306 [INFO ] [ab.core.model.script.UniversalDimmer] - itemName=Light_UL_OfficeCeilingBrightness set to 0.11, iteration=5, elapsedMs=11
2021-01-27 15:11:36.307 [INFO ] [ab.core.model.script.UniversalDimmer] - itemName=Light_UL_OfficeCeilingBrightness set to 0.12, iteration=6, elapsedMs=12
2021-01-27 15:11:36.314 [INFO ] [ab.core.model.script.UniversalDimmer] - itemName=Light_UL_OfficeCeilingBrightness set to 0.13, iteration=7, elapsedMs=13
2021-01-27 15:11:36.315 [WARN ] [el.script.internal.actions.TimerImpl] - Rescheduling failed as execution has already started!

That looks like an OH3.0 bug

Oh interesting, I’ll follow that thread to keep an eye on that. With all new things there will be some bugs and kinks to work out, but at least I’ve primed my environment by upgrading and am ready at least. :slight_smile:

Thanks again for updating your script!

1 Like

I fixed a bug - 1,000,000 ns in 1 ms, not 1000. That may/may not help your issue. See revision 5

That’s true! ZonedDateTime is weird not giving a plusMillis or even plusMicros method.

Thank you for this! It’s working well in OH3 for me, after making the changes mentioned further up in the thread, specifically:

import org.eclipse.smarthome.model.script.ScriptServiceUtil
changes to
import org.openhab.core.model.script.ScriptServiceUtil

fade_Timer = createTimer(now.plusMillis(mytime))
changes to
fade_Timer = createTimer(now.plusNanos(mytime*1000000))

fade_Timer.reschedule(now.plusMillis(mytime))
changes to
fade_Timer.reschedule(now.plusNanos(mytime*1000000))

I’m using it to fade up / down the volume for my Sonos when arriving / leaving the house, which is working great.

What changes would need to be made to be able to call several of these concurrently? I’m thinking about using it for a slow fade-in of my lights for sunrise / sunset, and it would be on for 15 mins. Am I better off making another string item and copy / pasting for the specific case?

Thanks again - a great rule!

Using it to control volume is an interesting idea I hadn’t thought of.
You must be using the original one from way up thread.
My version (see linked gist up thread) doesn’t contain fade_timer

Usage in parallel works fine with my version - for example this is my fade out when a video plays on Kodi:

        universaldimmer.sendCommand("light_tv_1_dimmer,0,2000")
        universaldimmer.sendCommand("light_tv_2_dimmer,0,2000")
        
        universaldimmer.sendCommand("light_hallway_dimmer,5,5000")
        universaldimmer.sendCommand("light_hallway_color,26,1000")

It’s a real pain and almost feels deliberately malicious. That’s Oracle for you.

If you want to use milliseconds though it is possible.

import java.time.temporal.ChronoUnit
...

now.plus(500, CronoUnit.MILLIS)

Even though it’s awkward, in many cases it’ll be worth importing CronoUnit and using it for clarity.

Nice to see UniversalDimmer getting better and better :slight_smile:

Here are two suggestions for additional functionalities:

  1. Groups of Devices

To handle groups of devices easily, I use an Item universaldimmer_group and this rule:

rule "UniversalDimmer Group"
when 
    Item universaldimmer_group received command 
then 
    val commandArray            = receivedCommand.toString.split(",")
    val String GroupName        = commandArray.get(0)   // Group of Items to handle
    var String targetValue      = commandArray.get(1)   // where to go to
    val String fadePeriodMs     = commandArray.get(2)   // time for fading
  
    (ScriptServiceUtil.getItemRegistry.getItem(GroupName) as GroupItem).getAllMembers().forEach[i | 
      universaldimmer.sendCommand(i.name + "," + targetValue + "," + fadePeriodMs)
    ]
end

Remark: getAllMembers() returns the direct members of a GroupItem and recursively all members of the potentially contained GroupItems as well

  1. OnOff Devices

To handle the case where there is an OnOff-Device in your group of devices for dimming, I added the following:

val type = transform("REGEX", ".*(PercentType|HSBType).*", item.getAcceptedDataTypes().toString())

val itemType = transform("REGEX", ".*(PercentType|HSBType|OnOffType).*", item.getAcceptedDataTypes().get(0).toString.split(" ").get(1).toString)

As you can link Dimmer- and Switch-Items to a brightness channel resp. Color- and Switch-Items to a color channel, you get potentially ambiguous results from getAcceptedDataTypes(). Therefore, I take only the first entry in the result list from getAcceptedDataTypes to determine the type of the item.

Then you have a third case besides HSBType and PercentType:

…else if (itemType == "OnOffType") {
 		if (targetValue == 100 || targetValue == 0) {
 			if (targetValue == 100) item.sendCommand("ON") else item.sendCommand("OFF")
 		} else {
            // You could implement another logic e.g. targetValue >= 50 -> set to ON, targetValue < 50 -> set to OFF.
 		}	
 		return; // for OnOffType: no further action
 	}

Your revision 5 works! Thank you so very much! :slight_smile: I have dimming lights again! Well, except for one minor thing…

The previous version of the script in the OpenHAB 2.5 days, I actually had the timerTickEveryMs set to 750, because too low of a value seemed to cause issues with my Kasa switches almost locking up or lagging behind almost as if the commands were too frequent and caused some issues. 750 was a good sweet spot, although I’ve just played with 500, and 1000 for the setting as well.

Now for long dimming times (30+ seconds) It appears all good, although anything shorter I’m seeing, that when I initiate a universaldimmer.sendCommand(“Light_UL_OfficeCeilingBrightness,50,10000”)

It actually ends randomly between 45 and 48% rather than 50. No huge deal, a few percent isn’t critical, although when I dim them off…

universaldimmer.sendCommand(“Light_UL_OfficeCeilingBrightness,0,10000”)

It only seems to dim down to 1 or 2%, and never right down to 0 unless I dim over a longer time period, It’s like the script overshoots but because of how my Kasa dimmers lag behind, they don’t get that final update to go right down to 0.

I did find a quick and easy workaround to fix it, and that was duplicating the
item.sendCommand(targetValue)
line, directly above the final logInfo, just after the if(!isAtTarget) so it looks like this:

    timerPool.remove(itemName)
    if (!isAtTarget)
    {
        item.sendCommand(targetValue)
    }
    item.sendCommand(targetValue)
    logInfo("UniversalDimmer", String::format("Finished dimming %s from %d => %d", itemName, startingBrightness, targetValue))

Which appears to do the trick as it sends that final value once more after the script thinks it’s at the target, which pushes it down below the 1-2%, as well as up past that 47-48%.

On a side note, I’ve also just ordered several H801 LED Dimming modules off AliExpress, so I’m sure I’ll be back with questions once I get them and flash them with Tasmota, and hope that your script plays nicely with those too, as my current cheap LED Controllers that came with my LED strips don’t use PWM, so they flicker incredibly badly at anything below 100%, the H801’s seem to have programmable PWM frequencies so I should have less headaches (literally) and a better looking dimmed light on several light strips I have installed. :slight_smile:

Hi guys

ZacR - You uncovered a bug which I hadn’t noticed as I don’t dim to zero. Latest revision fixed :slight_smile:

Joachim

  1. My first thought was the dimmer handles groups - but I noticed you mention recursion - so you mean we could have a hierarchy of lights in a group which are then grouped into downstairs and we can recurse down the tree?

  2. On/off devices now handled. I used a non greedy regex (.*?) which should handle take the first match and solve the ambiguity issue

2 Likes