ZW500DM In-wall Smart Meter Dimmer Switch is not working properly

Great. I had to search a little bit more to find out how to send that REFRESH command. If someone reads this thread in the future and wonders how to do it, the critical lines are:

import org.eclipse.smarthome.core.types.RefreshType
sendCommand(item, RefreshType.REFRESH)

I do still have an issue but it should not be difficult to address. Sending the refresh command triggers my rule so that it keeps refreshing ad nauseam (and that would be a big nausea for the whole OpenHAB system if that went on on several devices). I will post my solution once I have it.

Do you really need the imports? Everything in org.eclipse.smarthome.core.types should be imported for you by default.

Use a latch. The example there uses a ReentrantlLock but you could accomplish the same thing with a timestamp for something like this.

Without the import neither REFRESH nor RefreshType.REFRESH is recognized.

I am not too keen on using a latch (as I understand it from the thread you link to) because delays in the system are unpredictable. The rule already is being triggered only once every 3 to 4 seconds. Keeping a lock to avoid continuous update does not seem like a good way to me.

Instead, I think that checking that the power has changed significantly enough would be a better solution. I am hitting two problems however:

  1. I tried to compare with previousState but it seems to be undefined on the power sensor. I can get around it by declaring an outer scoped variable to the rule to hold the last measurement.
  2. The value keeps changing by less than 1W. So I tried to look at the absolute value of difference between the current state and previous one, but trying to take the difference fails with the following error message:

‘<XMemberFeatureCallImplCustom> - <XFeatureCallImplCustom>’ cannot be resolved to an item or type.

Just to be clear, you see the error in openhab.log, or just in ESH Designer when referencing REFRESH without the import?

This appears to be a relatively new type and I want to make sure it makes it into the docs correctly.

From your description above it sounded like you were stuck in an infinite loop. The latch would ignore the rule triggers for a time to avoid the loop. If it is only triggering once every 3 to 4 seconds it doesn’t sound like “sending the refresh command triggers my rule so that it keeps refreshing ad nauseam.”

previousState will only exist in a Rule triggered by changed and it will only contain the previous state for the Item that changed to cause the Rule to trigger. you haven’t posted your rule so I can’t do any more than guess on this point.

It is sooo much easier to spot an error in code with the actual code to look at.

Thanks Rich, one of the things you said already helped. Let me go over your 3 points:

I see it in openhab.log. I write my rules with vi and do not use ESH Designer.

Let’s say I touch the dimmer paddle and it turns on the light. After about 4 second, my rule gets triggered. At the end of the rule it sends a ‘REFRESH’ command and about 4 seconds later, the rule gets triggered again. After the second REFRESH, the rule gets triggered about every second And that continues infinitely. If I turned the device off, then it stops being called because the REFRESH updates the value from 0 to 0, which is not a change. When the load is on, it changes from 35.443 to 35.391 to 35.45 and so on… As you can see, the changes are small. Similarly to the device having a minimum value change before an update is sent, I want my rule to only apply if the power has changed by more than 1W.

Bingo! This was helpful. I had put two rules. One on ‘received update’ and one on ‘changed’ but I was working on the first one. I now got rid of it and only work on ‘changed’. Source code is below.

True. I spend most of my day doing programming and tend to synthesize the issue I see. But here is the code as it is now:

import org.eclipse.smarthome.core.types.RefreshType
rule "Nook power update"
        Item Nook_Power changed // 'received update' is triggered as well but does not define the previousState variable.
        logInfo("power", "State is: "+Nook_Power.state)
        logInfo("power", "previousState is: "+previousState)
        if ( Math.abs( Nook_Power.state - previousState ) > 1.5 ) // This line fails
                sendCommand(Kitchen_NookLight, RefreshType.REFRESH)

I’ve indicated where I get the error noted in my last post. So it seems the type of the variables state and previousState is not numerical and should be converted. I think I saw a thread that had a side discussion about conversion and I seem to remember it was you who wrote that part. Either I find it before you reply to this, or I’ll take your answer here! :grinning:

Here is the final scrip that does what I want:

import org.eclipse.smarthome.core.types.RefreshType
rule "Nook power update"
        Item Nook_Power changed // 'received update' is triggered as well but does not define the previousState variable.
        logInfo("power", "State is: "+Nook_Power.state)
        logInfo("power", "previousState is: "+previousState)
        var currentP = Float::parseFloat(String::format("%s",Nook_Power.state).replace('%',''))
        var previousP = Float::parseFloat(String::format("%s",previousState).replace('%',''))
        if ( (Math.abs( currentP-previousP ) > 1.5 ) || currentP == 0 )
                sendCommand(Kitchen_NookLight, RefreshType.REFRESH)

Note that I request a refresh also if the new value becomes 0 to make sure that the UI will reflect when the light is fully turned off. Otherwise, we could receive a 1W value and then the 0 would not call a refresh, possibly leaving the UI with a state showing the light is still on (at a very low level) when in fact it is not.

Is there something easier than the line I used to convert to a float? I found it in a post by @pensionado. It looks a bit of a complicated way of doing things but at least it works.

You probably have to cast at least previousState, potentially both that and Nook_Power.state to a Number. The Rules DSL has a hard time figuring this out on its own with DecimalType.

Also, you must reference static methods and data members using ::, not ..

As a general rule the sendCommand/postUpdate methods will work better for you than the Actions. The Actions only accept Strings whereas the methods are better able to process commands of different types without doing a lot of background parsing and conversions. For example postUpdate(MyNumberItem, 5) will probably fail but MyNumberItem.postUpdate(5) will work.

if(Math::abs(Nook_Power.state as Number - previousState as Number) > 1.5)

Finally, even if you don’t use ESH Designer to do day to day coding it should be the first place you go for any and all syntax errors you encounter in OH. Even if it smells like a syntax error, load it up in ESH Designer and see what it tells you. You will save a ton of time in the long run.

For example, I just pasted my suggested code above into ESH and discovered it won’t work. By default, the Rules engine puts all calculations into a BigDecimal type but Math::abs needs a primitive. So you must use:

if(Math::abs(Nook_Power.state as Number - previousState as Number).floatValue > 1.5)

The error on the line said something about not being able to convert BigDecimal to int which gave me the clue I needed to find and fix this problem faster than would have been possible with a save, run, watch the logs, interpret the error, find the line in my rule, loop.

ESH Designer also has the usual Eclipse key combos like <ctrl><space> for automatic line completion. This is really handy for learning about the language as you type.

It is now part of the official docs here.

I’m surprised the Math::abs is working. Maybe that method isn’t static or maybe there has been a change recently.

Yes. See my code above and the link above. That example is the most roundabout way to do it I’ve ever seen.

NOTE: all of the above assumes your Item is a Number Item.

I will look into ESH Designer. My system runs on the linux box, my eclipse is on the Mac, getting the two connected will require a bit more work.
However, as a quick feedback, I tried your line:

It gave me an error:

Rule ‘Nook power update’: An error occurred during the script execution: Could not invoke method: java.lang.Math.abs(int) on instance: null

Printing the class of Nook_Power.state gives class org.eclipse.smarthome.core.library.types.DecimalType

Of note is that at system restart, previousState is null. Consequently, I will need to deal with that possibility and treat it as -1 to force a refresh in the first call after a restart.

There are lots of approaches: SAMBA, NFS, Git, rsync, etc. Particularly if you are not planning on doing your main development in ESHD, all you really need is a copy of your /etc/openhab2 folder available on your Mac. It doesn’t have to be the live running config unless you want it to be.

Oops, misplaced parens. It should be:

if(Math::abs((Nook_Power.state as Number - previousState as Number).floatValue) > 1.5)

I needed to convert the result of the calculation to a float, not the result of the abs method call which is already going to return a primitive float which of course wouldn’t have a floatValue method.

Obviously, ESHD isn’t going to catch all the possible errors. :slight_smile:

NOTE: DecimalType is itself of type Number. You will see lots of examples of people casting to DecimalType when doing calculations like this but doing so sets you up to see ambiguous method calls later on when you pass it a DecimalType which is also a Number and there is two versions of the method, one that takes DecimalType and one that takes Number.

Is it null or NULL. The two are distinctly different. null is the usual Java null but NULL is a special State that any Item gets initialized with when it first gets loaded into OH on a restart or .items file reload. It basically means Uninitialized. I would expect previousState to be NULL, not null.

Regardless, this is something you would have to deal with. Personally, I would set up persistence and use restoreOnStartup to initialize my Items with whatever value it had last in the database and use Nook_Power.previousState to get the previous value rather than rely on the previousState variable. This would require less code to handle that NULL state and might make your Rule behave a little more consistently across reboots and .items file reloads.

You are right again, I believe it is NULL. I will have to double check again.

Persistence is probably not the right solution because I can imagine a scenario where the power goes out and when it comes back, somebody could change the dimmer before the machine running OpenHAB is back online. Thus the state could have changed.
I can imagine two solutions:

  1. On boot always trigger a refresh to have the correct value.
  2. Simply accept to refresh if we had no previous value.

Right now, I am doing option 2. Though making sure the system refreshes all the states at boot is not a bad thing.

I have a bit of a complicated way to deal with the NULL. What is the easiest way to test for NULL?

It might be part of the solution. It all depends on your specific use cases. For example, I use persistence on my door entry Items so they come back up in the same state they were in before OH restarted. BUT, I also have a System started triggered rule that sends a command to query the current state of the doors. The restoreOnStartup means that previousState will always have a meaningful value (just skip the rule in cases where previousState == NULL) and the System started Rule makes sure that I get the current true state of the sensors.

For the rest of my Items, they will receive an update naturally within a few seconds anyway so I don’t worry about it.


if(MyItem.state == NULL)

Maybe you should read the Rules docs a bit and I question where you are finding some of these examples. It sounds like you are finding the absolute most round about ways to do very simple tasks in Rules.

Here is my final code. It handles the initial NULL value by making sure we get a refresh and will ask for refresh if the power has changed by more than 1.5W or if it goes down to 0.

import org.eclipse.smarthome.core.types.RefreshType

rule "Nook power update"
        Item Nook_Power changed // 'received update' is triggered as well but does not define the previousState variable.
        logInfo("power", "received update "+Nook_Power)
        logInfo("power", "State is: "+Nook_Power.state)
        var currentP = Nook_Power.state as Number
        var previousP = if (previousState == NULL) -1 else (previousState as Number)
        if ( (Math.abs( (currentP-previousP).floatValue ) > 1.5 ) || currentP == 0 ) {
                logInfo("power", "Sending a refresh order.")

Here we go again… :expressionless::roll_eyes:
I am trying to upgrade to openhab 2.3 and this dimmer is not working again…
When I add it as a thing, the sensor and the two meters channels (watts and kWh) show, but the Dimmer channel isn’t there.

How do I recover it?

After upgrading the zwave binding, you’ll need to delete your zwave Things to get the new definitions. No need to exclude the devices, just delete the Things and rediscover. Hopefully this gets the missing channel back too!

@5iver unfortunately doing this does not help. This is a fresh install, not an upgrade. I used to have a manually installed OpenHAB. I did a fresh install using apt, so it does not have any data from the previous install. Any other idea?

There is no channel for the dimmer in the database, so that would explain it.

Clearly it needs a little TLC…

From what I can tell looking back through the history on Github, there was never a dimmer channel for this device. There used to be a switch channel, but that was deleted last October (I don’t know why or by who).

Anyway, as above, the database is clearly a bit messy so if you have some time, it might be good to try and straighten it out :wink: .

Hi Chris, I think I’m the one who submitted a correction to the database and I believe I had corrected it by changing the switch into a dimmer. There may be another discussion thread on that subject. So I’m puzzled how my 2.1 system got that channel and now it isn’t there.
Can you give me guidance at least? It’s been so long…

PS: Here is the discussion we had on the subject: ZW500DM In-wall Smart Meter Dimmer Switch is not working properly

Down in that thread I describe how I got around going through the database. I guess I’ll be a bit more thorough and this time try to propagate the change to the database…

So am I - as I say, looking at the history on GH, I don’t see that the channel ever existed…

I’ve updated most of the database - if you can take a look at fixing the following errors, then we should be good to go.

That’s this thread :slight_smile: .

I haven’t re-read all of this, but I gather you probably compiled your own version and fixed the database?

Oops. I got confused. There’s also another thread on it, slightly different subject.
Anyways, I only modified the json database locally. Details are in post 12.
To fix the database:
What are parameter labels? And for the image, is an image from Amazon OK?