OH4 CEN Configuration does not work

  • Platform information:
    • Hardware: Lenovo 910, 8GB, 250GB SSD
    • OS: Windows 10
    • Java Runtime Environment: Zulu 21.36.17
    • openHAB version: 4.2.2
  • Issue of the topic:
    I have set up things and rules to try CEN, but somehow it does not work. I have read through the openhab integration documentation and have followed the instructions, then proceeded to forums and still I am stuck.
    For a test, I have a scenario switch HS4680 with all four buttons configured WHERE=91. Some buttons have extended press in CEN (currently configured in an MH300N), and I wanted to move the whole scenario thing away from the MH to open HAB.
    To make sure I have understood how that all works, I found that the UI configuration will not have an option to configure EXTENDED PRESS on CEN switches.
    So I decided to dig into the .things and .rules files of openhab and am planning to completely configure the system there instead of the UI, just for consistency.

Now I have configured the following things in the .things file for testing CEN:

Bridge openwebnet:bus_gateway:MH200N "MH200N" [ host="192.168.xxx.xxx", passwd="xxxxx", port=xxxxx, discoveryByActivation=true ] {

	bus_on_off_switch			licht_OG_westzimmer_decke			"Deckenlicht Westzimmer OG"				[ where="38" ]
	bus_on_off_switch			licht_OG_westzimmer_ostwand			"Deckenlicht Westzimmer Wand O"			[ where="39" ]
	bus_on_off_switch			licht_OG_westzimmer_westwand		"Deckenlicht Westzimmer Wand W"			[ where="41" ]
	bus_cen_scenario_control	schlafzimmer_szenario 				"Schlafzimmer Szenario"					[ where="91", buttons="1,2,3,4"]
		
}

I can see the switches and they do work, the lights turn on and off if I use them in a model.

Now I have set up a rule in .rules to try the CEN EXTENDED PRESS. I also checked the OPEN command with the discovery tool to make sure it is available (its only commented in the rule file)

rule "Test"

when
	Channel "openwebnet:bus_cen_scenario_control:MH200N:91:button#2" triggered EXTENDED_PRESS
	// Event: command OPEN = *15*02#3*91##
then
	licht_OG_westzimmer_decke.sendCommand(ON)
	licht_OG_westzimmer_ostwand.sendCommand(ON)
end

I would expect according to the documentation that the rule listens to the channel CEN address 91 and reacts if the button #2 is pressed long by switching on the two lights. But this does not happen.

What do I overlook?

I don’t know this binding nor the technology involved and I don’t do file based configs any more. So the only things I can recommend are:

  1. verify the event from that Channel is occuring. It should be sufficient to watch events.log I think.
  2. look at the Thing in the UI and double check the docs to verify that you ahve the correct Channel ID
  3. put the binding into debug level logging and verify that the binding is receiving the event in the first place
1 Like

its already long time ago that i used cen commands, and i see that your code is at it is described in the docu.

i found a old dsl rule where i used cen commands, perhaps try the thing name instead of the cen numer in your when condition:

Channel "openwebnet:bus_cen_scenario_control:MH200N:schlafzimmer_szenario:button#2" triggered EXTENDED_PRESS

if still does not work, then try with START_PRESS instead of EXTENDED_PRESS as this i know it worked for me.

Hi all and first of all thanks for your ideas. It indeed helped.

I figured out that it seems the .items file also needs configuration to make sure OH4 understands the bindings (even though it is mentioned in the rule channel).

When this was done the hint with the log files helped. I am not sure if I misunderstood the documentation or if it has some minor flaws.

What does not work:

Channel "openwebnet:bus_cen_scenario_control:MH200N:91:button#4" triggered EXTENDED_PRESS

What worked, eventually:

Channel "openwebnet:bus_cen_scenario_control:MH200N:CEN_schlafzimmer_scenario_91:button#4" triggered EXTENDED_PRESS

I had to mention the complete .thing ID of the scenario which is defined as:

bus_cen_scenario_control	CEN_schlafzimmer_scenario_91							"Schlafzimmer Szenario 91       [ where="91", buttons="1,2,3,4"]"	

Only adding the channel 91 defined under WHERE between button and bridge is not sufficient. This made it work also with EXTENDED_PRESS.

Cheers!

1 Like

i tried a bit to investigate at another instalation from my mother where i use cenplus commands, but it should be similar with cen commands. only important that you have to add a 2 at the beginning of the where. in my case i use cenplus command 1 so i have to note where=21

i now setup two dsl rules to test. i use this things entry:

    bus_cenplus_scenario_control  EK_Flur_CenPlus_PIr         "EK_Flur_CenPlus_PIr"           @ "Cen/CenPlus" [ where="21", buttons="0,1,2,3,4" ]

if you only want to trigger commands you can use this rule (without need of an item):

rule "CenPlus channel test"
when
	Channel "openwebnet:bus_cenplus_scenario_control:bticino:EK_Flur_CenPlus_PIr:button#0" triggered EXTENDED_PRESS
	// Event: command OPEN = *25*23#0*21##
then
    logError("denplus.rules", "CenPlus channel test fired")
end

you also can define an item, i do it in items-file like this:

String iCenTest "CenTest" { channel="openwebnet:bus_cenplus_scenario_control:bticino:EK_Flur_CenPlus_PIr:button#1" }

then you can trigger the defined button with this rule:

rule "CenPlus item test"
when
	Item iCenTest received command "EXTENDED_PRESS"
	// Item iCenTest changed to "EXTENDED_PRESS"
	// Event: command OPEN = *25*23#1*21##
then
    logError("denplus.rules", "CenPlus item test fired")
end

and the advantage of defining an item is that you even can send a cen command from a rule then with

iCenTest.sendCommand("PRESSED")

i now tried to send the cen command with an item as i described above and realize it does not work. i think some times ago i used it that way.

but i cold get this to work, i just tried it (in dsl rules):

        val cenActions = getActions("openwebnet","openwebnet:bus_cen_scenario_control:MH200N:CEN_schlafzimmer_scenario_91")
        cenActions.virtualPress("EXTENDED_PRESS", 1)    // send "EXTENDED_PRESS" to button 1

thats even better because you do not need an item, just the thing. i tried it with a cenplus command and now inserted your variables, i hope this will also work with cen.

Thanks everyone. CEN works fine now. I currently struggle with other things of the programming language. I wonder if there is any good documentation on it. Between the basics wiki at openHAB and the code shown in the forum is a huge learning gap. I am willing to learn, but I am really missing some guidance on coding. For example the time handling was changed in OH4. It was quite straight forward before, and now to me it looks like you have to scratch your right ear with the left small toe while hanging upside down on a soaped rope. Is there any wiki with all the code explanations, syntax and things? I was not able to find something comprehensive to get started with the more complicated things (like the new time handling)

There hasn’t been a wiki for docs in OH since OH 1.x. All the docs can be found at Introduction | openHAB. The syntax for Rules DSL in specific can be found at Textual Rules | openHAB.

There have been some postings on the forum for working with ZonedDateTimes. DateTime Conversion (openHAB 2.x) is a tutorial that covers how DateTimes work in Rules DSL since OH 3.

During the lifetime of OH 2 the Joda library, which is what OH used, became deprecated. One of the breaking changes between OH 2 and OH 3 was a move to use the standard java.time library for DateTime instead. They are very similar but not identical, hence the breaking change.You can find the docs for java.time.ZonedDateTime at ZonedDateTime (Java SE 17 & JDK 17).

I’m not sure what you mean by it being straight forward before as the old Joda library and the new library work almost exactly the same but the names of the methods are slightly different.

In pretty much all of the other rules langauges OH now supports, working with DateTimes is usually even easier. For example, in JS Scripting to get a DateTime one week, three hours and 25 seconds from now you’d use time.toZDT('P1WT3H25S'). In Rules DSL that would be now.plusDays(7).plusHours(3).plusSeconds(25). In JS Scripting, to sumtract an hour from a DateTime stored in a DateTime Item you’s use time.toZDT(items.MyDateTimeItem).minusHours(1) and in Rules DSL it would be (MyDateTimeItem.state as DateTimeType).zonedDateTime.minusHours(1).

This is probably the least reason why I recommend against new development of rules in Rules DSL. Rules DSL has a bunch of problems and it’s no longer easier to work in than the other rules languages options. So you end up suffering through it’s half assed type system and lack of features but don’t even get the benefit of having a simpler and easier programming enviornmnet to learn in.

Hey Rich,

Thanks for posting all this. I have read through the Textual Rules and also the DateTimeConversion. I only got lost while trying to understand the conversion, not in principle but when it comes to the code provided. For me it always feels like textural rules understood, conversion principle understood, but what has the code to do with it. I found the HourOfDay and such much more catchy than having to convert information to be able to compare and trigger a rule. Even reading through some examples I have no idea what happens and why people approach it that way. This is why I meant for me there is a gap from the basic principle to how actually convert it into code and understand why I have do do it like this. Simple rules are not an issue like sunset/raise and then switching on/off lights and such.

I’m not sure what you mean by this, but OH 4+ has anew rule trigger which in Rules DSL renders as

when
    Time is MyDateTimeItem timeOnly
then

That will trigger the Rule at the time held by the DateTime Item MyDateTimeItem. Omit the timeOnly part and it willtrigger at the date and time held be that Item.

In manged rules (i.e. in the UI) you can also set a rule trigger based on time of day, type of day (from Ephemeris) directly without needing to resort to a cron expression.

You don’t need to do any conversion of anything to trigger a rule.

Ok. What I am looking for is to trigger a rule only between two times, for example during night hours after 10pm and before 5am it should do one thing, and between 5am and 10pm another thing. Astro timing will not help in this case and is only another condition which I have already implemented with an isNight item.

I am not sure how I can derive the current time from the system, compare with the trigger to start the rule. the timeoftheday and cron expressions seemed more straight forward. And I cannot find any examples to get a starting point. What I already established was to trigger a rule at a certain time, but not within a time frame as mentioned above.

How would that work in OH4? something like

when
time is after 10pm and before 5am
then
do this

That’s a condition, not a trigger.

So what triggers this rule? What event triggers the rule? What do you really mean by “after 10pm and 5am”? Every minute? When an Item changes state? When an Item receives and update or command? Something else?

So what ever triggers this rule continues to trigger the rule.

Then you add an if statement in the rule to check the time. In Rules DSL this would be something like:

rule "Some description"
when
    Item SomeItem changed
then
    // It's not night
    if(!now.isAfter(now.withHour(22).withMinute(0).withSecond(0) && !now.isBefore(now.withHour(5).witrhMinute(0).withSecond(0)) {
        return;
    }

    // code goes here
}

But none of this has really changed even back as far os OH 1.x except the ZDT syntax is slightly different.

In JS Scripting it’s much simpler:

if(time.toZDT().isBetween("10:00pm", "5:00am")) 

In the UI yo can create a condition with takes the place of that if statement above (the But only if… section).

In Rules DSL it’s simply now. That’s a ZonedDateTime of right now.

That’s what I don’t understand. The rule was triggered right now. now is the time the rule was triggered.

Those all still work pretty much the same as they always have. None of that basic concept has changed. An event happens and then in the action of the rule you test to see if the time is right.

UI/managed rules have an additional condition clause where you can do the tests. The time conditions have an “inside a time range” option.

But file based rules don’t have separate conditions so you have to test inside the rule.

Thanks for clarification, especially on trigger and condition. It will help me to get clearer with my questions.

I have tried the code in a DSL rule and it technically works. Though I have one more question.

I have put this code in a rule for test purposes:

rule "testtiming"
when
		Time cron "0 0/1 21 ? * * *"
then
	if ( !now.isAfter(now.withHour(21).withMinute(0).withSecond(0)) && !now.isBefore(now.withHour(5).withMinute(0).withSecond(0) ) ) {
		return;
	}
	
	SomeLight.sendCommand(OFF)

end

So the trigger is every minute int he hour 21. then the condition is in the if statement, in this case if time is later than 21h and earlier than 5h, the condition is fulfilled it shall turn off the SomeLight.

Shouldn’t be the SomeLight be turned off when it is written between the {} of the if condition? It now actually turns off when the sendCommand(OFF) is after the {} of the condition.

My understanding was

a) if ( some defined condition is met) { do this } else { do that }

here it looks like

b) if ( time between 22 and 5 ) { return } code

but
a) does not work, b) does. And I have no idea why and what the “return;” line does to make it work.

And that’s what is happening to happen here. The “do this” is return, meaning immediately exit the rule without doing anything. You don’t need an else here because the rule will exit. You can put in an else if you want to

	if ( !now.isAfter(now.withHour(21).withMinute(0).withSecond(0)) && !now.isBefore(now.withHour(5).withMinute(0).withSecond(0) ) ) {
		return;
	}
	else {
	    SomeLight.sendCommand(OFF)
    }

The code is equivalent.

So if it is after 21:00 or before 05:00 the rule does nothing (! means not). The return; causes the rule to exit immediately.

If it is after 21:00 and before 05:00 the if condition is false so the rule does not immediately exit and has opportunity to sendCommand(OFF) to the Item.

OMG, I missed the ! In the Code. Now it perfectly makes sense.

Why do you suggest to work with a NOT condition? To avoid two conditions since time runs across midnight?

Because I wanted to demonstrate how to implement the equivalent of a rule condition in Rules DSL using return;. You only want the rule to run when it’s between 21:00 and 05:00 which means the rule needs to exit when it is not between 21:00 and 05:00.

It’s all just for demonstration. You can create the condition however you want using what ever criteria makes sense.