[HELP] Build controller home and boiler heating

Moved to the next stage of project development.
Task: create a rule in which the comparison occurs with the temperature value specified through the settings functionality.
For this purpose, i created and configured a new item “dimmer”, which i applied in the block-scheme already tested above.



Result: the rule works only in Run Now mode, and not in IDLE-state
:thinking:

I apologize, i found my mistake :upside_down_face:
in the new rule for “When” i specified an incorrect item - instead of a temperature sensor i used a temperature setting regulator.
I made the corrections and everything worked correctly

this question is not relevant :slight_smile:

Hello everyone!

Several questions have arisen regarding the implementation of user functionality:

  1. in the main page User interface (not in the settings section!)
    1.1. implement a visual display of information about the name of all existing Rules and their current states at the present time (running / idle / disabled).
    1.2. implement the functionality of manual start / stop of work for each Rule.

  2. on the Basic UI page via the .sitemap configuration file:
    2.1. display the temperature value setting tool, which in my case is implemented as an items-element (Type Dimmer, Category heating, Semantic Class Control, Semantic Property Temperature).
    2.2. display information (name / description) about the Rule / s that are currently active.
    Let me explain: in my case, it is implied that there are several main Rules, of which only one can be active at the present time. At the same time, i admit that in the future, the configuration of my system will require the activity of several Rules at the present time.

Another question arose about the possibility of implementing in OH (using OneWireGPIO Binding?) a functionality/service that in manual (on request) or cyclic mode (the polling period is configurable) will poll the 1Wire GPIO bus on the RPi3 and then display a list of all unique IDs of devices that are connected to the bus ?

This service would be VERY convenient in hypothetical situations when it was necessary to replace a particular faulty device (for example, a DS18B20 digital temperature sensor) and the service will greatly simplify the process of detecting a new device and registering it in OH.

Important clarification: at the moment, OpenHAB learns information about existing (connected) devices to the 1Wire bus from the manual configuration of the .things file in the openHAB-conf\things folder.

Example:

Thing onewiregpio:sensor:solarcollector "Solar Collector" [gpio_bus_file="/sys/bus/w1/devices/28-031097796ffb/w1_slave",refresh_time=5]
Thing onewiregpio:sensor:watertank "Water Tank" [gpio_bus_file="/sys/bus/w1/devices/28-03109779c043/w1_slave",refresh_time=5]
Thing onewiregpio:sensor:indoor "Indoor" [gpio_bus_file="/sys/bus/w1/devices/28-3c01b60700ed/w1_slave",refresh_time=5]

I managed to solve some of the questions in post 23:

  • displaying in UI a list of existing Rules, as well as the functionality of starting them - solved.

so far, no solution has been found for the functionality: displaying in the UI the name of the Rule that is currently active

What are you trying to accomplish with this? Seeing the rules and when they are running is mainly an administration function, not something you’d expose to the suers of your home automation. They shouldn’t know or care about the names and status of the rules and if there is some functionality they need to control that functionality should be modeled and exposed as Items.

You’d have to create a rule that triggers on RuleStatusInfoEvents (a generic trigger with a filter, note this is really advanced stuff but you can find an example that works with ThinStatusInfoEvents at Thing Status Reporting [4.0.0.0;5.9.9.9].

This rule will then need to update an Item(s) that gets shown on the UI. You’ll have to figure out when/how to cancel out the state of that Item(s). Properly written rules shouldn’t take more than a few hundred milliseconds to be triggered, run and then exit. For the most part one would have to be lucky to see anything change at all in the browser when a rule is running.

If you do infact have long running rules, you probably need to reassess those rules and consider using Timers instead of sleeps if that’s the root cause of the length.

Hi Rich! You absolutely right! Only for administrative control about which particular rule scenario is currently being executed.
At the moment, the functionality of displaying the name of a scenario within a rule is not yet relevant.

Resumed my work on the controller logic. Over the past time, i have achieved the main success in that i rethought the approach to compiling the rules of the logic i needed. The logic began to work correctly.

I decided to implement the “Seasonality” and “Part of the day” conditions through Switch-items states. Each state has its own Rule that determines its state.

I encountered difficulties:
It may look stupid, but i can’t make item-DateTime, which displays the current date and time, based on the local, system time of the Raspberry.
Neither with the UI functionality, nor with the help of manual compilation of the .items file, with the following code:

String CurrentDateTime "Current Date & Time [%s]" <calendar>

Such Item displays the NULL state :confused:

How can i make an item (preferably via a manually created file, but UI will do too) that would display the local date and time?
I need this so that the controller logic can work autonomously, without relying on data from the Internet.

When creating the Seasonality state determination rule, i encountered the fact that when extracting data from the now block via a pattern, i cannot create the mask i need in the DD.MM format (without a year, hours, minutes, seconds).
What i need: i need to compare the current day/month (obtained from the system date) in this rule for compliance or non-compliance with the day/month in the specified range: starting day/month, ending day/month).

The current (non-working) rule code is composed as follows:

if (((time.ZonedDateTime.now()).format(time.DateTimeFormatter.ofPattern('DD.MM'))) >= '01.DECEMBER' && ((time.ZonedDateTime.now()).format(time.DateTimeFormatter.ofPattern('DD.MM'))) < '28.FEBRUARY') {
  item += 'WINTER';
}
if (((time.ZonedDateTime.now()).format(time.DateTimeFormatter.ofPattern('DD.MM'))) >= '01.MARCH' && ((time.ZonedDateTime.now()).format(time.DateTimeFormatter.ofPattern('DD.MM'))) < '31.MAY') {
  item += 'SPRING';
}
if (((time.ZonedDateTime.now()).format(time.DateTimeFormatter.ofPattern('DD.MM'))) >= '01.JUNE' && ((time.ZonedDateTime.now()).format(time.DateTimeFormatter.ofPattern('DD.MM'))) < '31.AUGUST') {
  item += 'SUMMER';
}
if (((time.ZonedDateTime.now()).format(time.DateTimeFormatter.ofPattern('DD.MM'))) >= '01.SEPTEMBER' && ((time.ZonedDateTime.now()).format(time.DateTimeFormatter.ofPattern('DD.MM'))) < '30.NOVEMBER') {
  item += 'AUTUMN';
}

NULL means those Items have never been updated. It doesn’t have a state.

How are you updating this Item?

First of all it should be a DateTime Item. Then, if you don’t want to use the NTP add-on just create a rule to update the Item periodically (once a minute or once a second) with the current time.

DateTime CurrentDateTime "Current Date & Time [%1t$tH:%1t$M %1t$A %1t$m %1t%d]" <calendar>

See Items | openHAB and Formatter (Java SE 17 & JDK 17) for details on how to use the formatter to display the date and time how you want.

Then in your rule it’s just:

items.CurrentDateTime.postUpdate(time.toZDT());

This is the full rule? It doesn’t make sense as written.

  • This is an Inline Script Action in a UI rule?
  • What’s item? If this is your CurrentDateTime Item?
  • You are just comparing Strings. >= means that the left side is first alphabetically, not that it represents a later date. You need to compare the DateTimes, not strings.
  • Are you aware that the Astro binding has a season Channel? Astro - Bindings | openHAB There’s a settings to have it use meterological dates instead of equinox dates.

Season calculation can be switched from equinox based calculation to meteorological based (starting on the first day of the given month). This is done by setting useMeteorologicalSeason to true in the advanced setting of the sun.

The best way to implment this is to:

  • install the Astro binding
  • create/accept from the inbox the local sun Thing
  • click “show advanced” and check the “use meterological season”
  • link this Channel to what ever item is

That’s all you need to do. Note that Astro is calculated 100% locally, no dependency on any internet service. And it handles leap years and doesn’t require any code.

But if for some reason you needed to compare between two dates in a rule you would do it as follows:

// see https://www.openhab.org/addons/automation/jsscripting/#time-tozdt
var year = time.toZDT().year();
var winterStart = time.toZDT(year+"-12-01");
var springStart = time.toZDT(year+"-03-01");
var summerStart = time.toZDT(year+"-06-01");
var autumnStart = time.toZDT(year+"-09-01");
var now = time.toZDT();

// see https://www.openhab.org/addons/automation/jsscripting/#isbetweendates-start-end
var currSeason = items.Season.state;
if(now.isBetweenDates(winterStart, springStart.minusDays(1)) currSeason = "WINTER";
else if(now.isBetweenDates(springStart, summerStart.minusDays(1)) currSeason = "SPRING";
else if(now.isBetweenDates(summerStart, autumnStart.minusDays(1)) currSeason = "SUMMER";
else currSeason = "AUTUMN";

// see https://www.openhab.org/addons/automation/jsscripting/#getitem-name-nullifmissing
items.Season.sendCommandIfDiffernt(currSeason);

But again, you don’t need this for the seasons. This sort of thing is why the Astro binding exists. And you can’t just do complicated date time comparisons using Strings but time.toZDT() can convert Strings into a ZonedDateTime that you can do such comparisons with.

1 Like

I didn’t update it at all. My mistake.

I followed your instructions:

  • manually created an .items file with the code:
DateTime CurrentDateTime "Current Date & Time [%1t$tH:%1t$M %1t$A %1t$m %1t%d]" <calendar>
  • created a Rule with a cron trigger every 5 seconds and Then:
console.info(items.getItem('CurrentDateTime').state);
items.getItem('CurrentDateTime').postUpdate('time.toZDT()');

Full code Rule:

configuration: {}
triggers:
  - id: "1"
    configuration:
      cronExpression: 0/5 * * * * ?
    type: timer.GenericCronTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      blockSource: <xml xmlns="https://developers.google.com/blockly/xml"><block
        type="oh_log" id="g(3KSk+?pTyJ-iLTm,%B" x="-5073" y="-1915"><field
        name="severity">info</field><value name="message"><shadow type="text"
        id="qqF!g!$%yz!Cuy=wiiDl"><field name="TEXT">abc</field></shadow><block
        type="oh_getitem_state" id="(cee/q+(#%JQwMU1y8nP"><value
        name="itemName"><shadow type="oh_item"
        id="(v`7LGh$|?_hw^}h(JU6"><mutation itemName="MyItem"
        itemLabel="MyItem"></mutation><field
        name="itemName">MyItem</field></shadow><block type="oh_item"
        id="#8S8J=~a|wQH`|kC#7`|"><mutation itemName="CurrentDateTime"
        itemLabel="Current Date &amp; Time"></mutation><field
        name="itemName">CurrentDateTime</field></block></value></block></value><next><block
        type="oh_event" id="T2@?@S#AEUi$|CKmwtu^"><field
        name="eventType">postUpdate</field><value name="value"><shadow
        type="text" id="krOok(W.xp%KGYS[_(X_"><field
        name="TEXT">value</field></shadow><block type="text"
        id="c_sZ$}gcs]RCe:7lo/70"><field
        name="TEXT">time.toZDT()</field></block></value><value
        name="itemName"><shadow type="oh_item"
        id="Jw6kb-Zzqs[)Z8;lj27`"><mutation itemName="MyItem"
        itemLabel="MyItem"></mutation><field
        name="itemName">MyItem</field></shadow><block type="oh_item"
        id=".4Mb/-q05^)71h(s,K-$"><mutation itemName="CurrentDateTime"
        itemLabel="Current Date &amp; Time"></mutation><field
        name="itemName">CurrentDateTime</field></block></value></block></next></block></xml>
      type: application/javascript
      script: |
        console.info(items.getItem('CurrentDateTime').state);
        items.getItem('CurrentDateTime').postUpdate('time.toZDT()');
    type: script.ScriptAction

Result: rule does not work. Error log:

2025-02-19 21:45:46.580 [INFO ] [tomation.script.ui.current_date_time] - NULL
2025-02-19 21:45:46.585 [WARN ] [rnal.defaultscope.ScriptBusEventImpl] - State 'time.toZDT()' cannot be parsed for item 'CurrentDateTime'.

As for Seasonality, yes - i know about Astro Bindings.I’ll try to use it, as you recommended.
Thanks a lot ! :handshake:

Look again, that’s not the code I posted above.

No quotes.

That’s Blockly code, not just a JS code.

These are very important details.

The update block should look like this:

image

You’ll find now and all date and time related blocks under the Dates & Times category. Obviously select your Item for the Item.

1 Like

Everything worked out well! :+1:
Seasonality data is coming from Astro binding
Date and time are also now displayed correctly in items

PS. I have a slight fever, so my thought process is a bit slow (( Sorry

Attached is a screenshot of part of my Blockly rule, in which i have marked two logic scenarios (Mode 1, Mode 2).
Question - how is it possible in Blockly to pass information about the currently running scenario to the item i need?

I’m not sure I understand the question. To “pass information to an item” one either uses postUpdate or sendCommand. You have several blocks that send command here. Are you talking about something else?

1 Like

…i think you gave me a great hint! :+1:

I’m delighted!
With your help, i made a functionality for informing about which scenario is being executed in real time:

  • made an item, to which information about the scenario from the Rule is transferred. I set the item to auto-update mode (using Metadata).
  • added a post update block with an individual name to the Rule for each scenario

I’m glad you got it working. Since this rule mainly just sends commands to Items are you aware of Scenes?

You can define a Scene for each of your cases under MainUI → Settings → Scenes which is a list of Items and the commands you want to send to those Items. Then in your Blockly rule above, instead of commanding each Item individually, you can call the Scene using the following block:

image

Leave the context empty and click on the “ruleUID” and select the scene you want to call. That can often be easier to manage than doing so in Blockly code.

I haven’t paid enough attention to the design of the UI page yet. Right now it’s purely informational (not for the end user). Don’t judge me too harshly ))
And yes, the UI does provide information about which scenario is currently running.

I managed to make the functionality of determining the “Time/part of day” (Night/Morning/Day/Evening) by individual ranges.
I’m not sure that my approach is optimal, but i couldn’t implement it through Time Based State Machine (i simply got confused in the sequence of actions and got stuck on Metadata).

First: created an item of string-type. The status of this item will display the name of the time of day, updated by the Rule, which defines the required parts/fragments of the day, each of which is defined by an individual time range (hours:minutes).

Second: created a Rule that is launched by a trigger (for myself I defined every minute) and a scenario for assigning a name to each part of the day.

Correction of the rule for the NIGHT block:
instead of the AND operator there should be an OR operator