[WIP] Ephemeris Documentation

The Ephemeris docs are now live.

I’m closing this wiki for further edits. Please refer to the above link for the latest docs for Ephemeris.


Besides @glhopital and @cweitkamp I think I’m among the first to use and apply the new Ephemeris capability built into OH. Correct me if I’m wrong, but I believe it is best to use OH 2.5 M4 or later as there were some bugs fixed prior to that milestone release. There are some new features being added as well so upgrading will be recommended as well when the next milestone becomes available.

Anyway, this post is going to be a first cut at documentation for Ephemeris. @Confectrician, I believe this most appropriately would be included on the Actions page, as it is something built into OH and therefore not an add-on and besides configuration, all interaction with it is done through Rule Actions. It’s a lot like the sendHttpXRequest Actions in that respect, but unlike all the rest of the built in Actions, this one requires come configuration. Do you agree? I’d like to know the best place to put this before creating a PR.

I’ll make this a wiki so anyone can contribute.

The below would be a subsection under “Core Actions” on the Actions page.


Ephemeris

Ephemeris is a way to determine what type of day today or a number of days before or after today is. For example, to determine if today is a weekend, a bank holiday, someone’s birthday, trash day, etc.

Rules DSL

  • isWeekend: returns true if today is a weekend
  • isWeekend(<offset>): returns true if the day <offset> days from now is the weekend. Use a negative offset to check days in the past. <offset> must be an integer.
  • isInDayset("<set>"): returns true if today is in the custom dayset <set>(see below), example, isInDayset("school").
  • isInDayset("<set>", <offset>): returns true if the day <offset> days from now is in the custom dayset <set>.
  • isBankHoliday: returns true if today is a bank holiday.
  • isBankHoliday(<offset>): returns true if the day <offset> days from now is a bank holiday
  • isBankHoliday(<offset>, <file>): returns true if the day <offset> days from now is a bank holiday defined in <file>.
  • getBankHolidayName: returns the name of the holiday if today is a bank holiday, null if today is not a bank holiday.
  • getBankHolidayName(<offset>): returns the name of the holiday <offset> days from today, null if that day isn’t a bank holiday.
  • getBankHolidayName(<offset>, <file>): returns the name of the holiday <offset> days from today defined in the custom list of holidays in the <file>.
  • isWeekend(<datetime>): returns true if the passed in date time is a weekend.
  • isInDayset("<set>", <datetime>): returns true if the passed in date time is in the custom dayset.
  • isBankHoliday(<datetime>): returns true if <datetime> is a bank holiday.
  • isBankHoliday(<datetime>, <file>): returns true if <datetime> is a bank holiday defined in <file>.
  • getBankHolidayName(<datetime>): returns the name of the holiday on the passed in date time, null if that day is not a holiday.
  • getBankHolidayName(<datetime>, <file>): returns the name of the holiday on the passed in date time defined in the custom list of days in <file>: null if that date is not defined in <file>.
  • getHolidayDescription(<holiday name>): returns the localized holiday description for the given <holiday name>.
  • getDaysUntil(<holiday name>): returns the number of days from today to the next <holiday name>
  • getDaysUntil(<datetime>, <holiday name>): returns the number of days between <datetime> and <holiday name>.
  • getDaysUntil(<holiday name>, <file>): returns the number of days from today to the next <holiday name> defined in the custom <file>.
  • getDaysUntil(<datetime>, <holiday name>, <file>): returns the number of days from <datetime> to <holiday name> defined in the custom <file>.
  • getNextBankHoliday: returns the name of the next bank holiday
  • getNextBankHoliday(<offset>): returns the name of the next bank holiday after today plus <offset>.
  • getNextBankHoliday(<datetime>): returns the name of the next bank holiday after <datetime>.
  • getNextBankHoliday(<file>): returns the name of the next bank holiday defined in <file>.
  • getNextBankHoliday(<offset>, <file>): returns the name of the next bank holiday after today + <offset> defined in <file>.
  • getNextBankHoliday(<datetime>, <file>): returns the name of the next bank holiday after <datetime> defined in <file>.

Scripted Automation:

One must import the Ephemeris Action and then call the above functions using Ephemeris.<function>, for example Ephemeris.getNextBankHoliday().

Configuration:

If your initial installation of openHAB was version 2.5 M4 or later, a default configuration for Ephemeris will exist in $OH_CONF/services/runtime.cfg.

org.openhab.ephemeris:dayset-weekend = [SATURDAY,SUNDAY]
org.openhab.ephemeris:dayset-school = [MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY]

Because upgrades do not replace files in /etc/openhab2, if your initial installation of OH was prior to OH 2.5 M4, you will not have these values in runtime.cfg. It is important that you have at a minimum dayset-weekend defined or the isWeekend Action will generate errors. Therefore you should manually add at least dayset-weekend using one of the two configuration methods described below. If you installed OH after OH 2.5 M4 and need to define new daysets, remove the above two lines from runtime.cfg and add them to ephemeris.cfg as described below along with your new ones. Failure to do this may generate a race condition where sometimes the daysets in runtime.cfg take precedence and other times the ones defined in ephemeris.cfg takes precedence.

PaperUI Configs:
In PaperUI one has the ability to configure which days of the week are considered weekends and set your country, region, and city. If no country is provided the service uses your system default locale settings. Browse to Configuration and System and scroll down to the Ephemeris section. Setting the country, region and optionally city will cause Ephemeris to use the list of bank holidays defined for that location by Jollyday. You can find the XML file for your country here and the localized mapping files that map between the holiday name in the XML and your preferred language are located here.

When filling in the country, region and city, if there isn’t a drop down list for one after choosing the one(s) higher up (e.g. there is no drop down list for city after choosing country and region), leave that field blank. There are no special bank holidays defined by Jollyday for that level.

ephemeris.cfg:
By default Ephemeris supports a weekend dayset and a school dayset. You can define additional daysets or modify the school dayset. If you need to define custom daysets, you must do all your configuration through the ephemeris.cfg file instead of using PaperUI as described above so make sure to redefine the weekend dayset.

Config file location: $OH_CONF/services/ephemeris.cfg.

Fields:

  • country: country to use to get the built in list of bank holidays, uses the standard two letter country code.
  • region: uses the appropriate two letter region code.
  • dayset-<name>: list of the days of that are in this dayset

If in doubt on what values to use, see the links above to find the XML file for your country, open the XML file, and find the tns:SubConfigurations for your region and use the “hierarchy” value for region.

For example:

country=de
region=nw
dayset-workday=Monday,Tuesday,Wednesday,Thursday,Friday
dayset-weekend=Saturday,Sunday
dayset-trash=Monday

NOTE: if you do not define dayset-weekend, the isWeekend Action will generate errors.

Custom days of the year:
In addition to the ability to define daysets, one can define a custom list of holidays. If you’ve opened the Jollyday XML file for your country already you know what your custom file needs to look like. The following is an example listing some custom days.

<?xml version="1.0" encoding="UTF-8"?>
<tns:Configuration hierarchy="us" description="United States"
    xmlns:tns="http://www.example.org/Holiday" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.example.org/Holiday /Holiday.xsd">
    <tns:Holidays>
        <tns:Fixed month="MARCH" day="20" descriptionPropertiesKey="Rich Birthday" />
        <tns:Fixed month="MARCH" day="27" descriptionPropertiesKey="Son's Birthday" />
        <tns:Fixed month="JUNE" day="12" descriptionPropertiesKey="Wife's Birthday" />
        <tns:Fixed month="DECEMBER" day="27" descriptionPropertiesKey="Anniversary" />
        <tns:FixedWeekday which="FIRST" weekday="TUESDAY" month="NOVEMBER" descriptionPropertiesKey="Election Day"/>
    </tns:Holidays>
</tns:Configuration>

These should give you enough examples to do almost anything but if you want to dig deeper, look at the xsd that defines the structure of the XML here.

You can place this file anywhere on your file system that OH has access to. Use the full path to the file in your calls to the Actions.

9 Likes

From what i read quickly now, i would agree. :slight_smile:

1 Like

Great work Rick ! You’ll be my writer from now on :grin:

@cweitkamp, how are the days in the school dayset defined? PaperUI only provides the ability to define the days for dayset-weekend and when I look in ephemeris.config in $OH_USERDATA there is no dayset-school defined. I’ve not yet created an ephemeris.cfg file. I think I tried to test for a school dayset when I played with the Actions but now I’m not so sure.

My mistake in a previous thread. Only weekend is required by the bundle.

@rlkoshak Currently a new OH2 installation (OH2.5.M4 or later) will be delivered with the following default configuration in the runtime.cfg inside $OPENHAB_CONF/services/ folder:

org.openhab.ephemeris:dayset-weekend = [SATURDAY,SUNDAY]
org.openhab.ephemeris:dayset-school = [MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY]

dayset-weekend is mandatory to guarantee working isWeekend related methods / actions. dayset-school is optional, because we have no related built-in methods / actions. It can be replaced / extended by any other dayset of ones needs. Additionally there is no proper way to define other daysets via UIs.

I’ve tried it with the example-xml file:

        <tns:Holidays>
            <tns:Fixed month="JANUARY" day="6" descriptionPropertiesKey="EPIPHANY"/>
            <tns:Fixed month="OCTOBER" day="31" descriptionPropertiesKey="REFORMATION_DAY"/>
            <tns:Fixed month="NOVEMBER" day="1" descriptionPropertiesKey="ALL_SAINTS"/>
            <tns:ChristianHoliday type="CORPUS_CHRISTI"/>
        </tns:Holidays>

But both,
Ephemeris.getBankHolidayName(0,’/etc/openhab2/ephemeris/Holidays_de.xml’)
and
Ephemeris.getBankHolidayName(1,’/etc/openhab2/ephemeris/Holidays_de.xml’)
only returns null

Why runtime.cfg instead of ephemeris.cfg?

That’s not a complete XML file. Try:

<?xml version="1.0" encoding="UTF-8"?>
<tns:Configuration hierarchy="us" description="United States"
    xmlns:tns="http://www.example.org/Holiday" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.example.org/Holiday /Holiday.xsd">
        <tns:Holidays>
            <tns:Fixed month="JANUARY" day="6" descriptionPropertiesKey="EPIPHANY"/>
            <tns:Fixed month="OCTOBER" day="31" descriptionPropertiesKey="REFORMATION_DAY"/>
            <tns:Fixed month="NOVEMBER" day="1" descriptionPropertiesKey="ALL_SAINTS"/>
            <tns:ChristianHoliday type="CORPUS_CHRISTI"/>
        </tns:Holidays>
</tns:Configuration>

See Failed to install artifact: /var/lib/openhab2/etc/org.openhab.ephemeris.cfg and https://github.com/openhab/openhab-core/issues/1121

OK, so these are just defaults and users are still expected to put their customization in ephemeris.cfg.

What happens when a user creates ephemeris.cfg? Are they required to redefine dayset-weekend, or does ephemeris.cfg only add to what’s in runtime.cfg? I want to make sure the docs are clear about what must be in ephemeris.cfg.

It was just an extract of my file…
this is the full xml:

<?xml version="1.0" encoding="UTF-8"?>
<tns:Configuration hierarchy="de" description="Germany" xmlns:tns="http://www.example.org/Holiday" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/Holiday /Holiday.xsd">
    <tns:Holidays>
        <tns:Fixed month="JANUARY" day="1" descriptionPropertiesKey="NEW_YEAR"/>
        <tns:Fixed month="MAY" day="1" descriptionPropertiesKey="LABOUR_DAY"/>
        <tns:Fixed month="OCTOBER" day="3" validFrom="1990" descriptionPropertiesKey="UNIFICATION_GERMANY"/>
        <tns:Fixed month="DECEMBER" day="25" descriptionPropertiesKey="FIRST_CHRISTMAS_DAY"/>
        <tns:Fixed month="DECEMBER" day="26" descriptionPropertiesKey="SECOND_CHRISTMAS_DAY"/>
        <tns:ChristianHoliday type="GOOD_FRIDAY"/>
        <tns:ChristianHoliday type="EASTER_MONDAY"/>
        <tns:ChristianHoliday type="ASCENSION_DAY"/>
        <tns:ChristianHoliday type="WHIT_MONDAY"/>
    </tns:Holidays>
    <tns:SubConfigurations hierarchy="bw" description="Baden-Württemberg">
        <tns:Holidays>
            <tns:Fixed month="JANUARY" day="6" descriptionPropertiesKey="EPIPHANY"/>
            <tns:Fixed month="OCTOBER" day="31" descriptionPropertiesKey="REFORMATION_DAY"/>
            <tns:Fixed month="NOVEMBER" day="1" descriptionPropertiesKey="ALL_SAINTS"/>
            <tns:ChristianHoliday type="CORPUS_CHRISTI"/>
        </tns:Holidays>
    </tns:SubConfigurations>
</tns:Configuration>

Is the xml-file read on each acces or cached?

You catched it. The xml file is cached upon first read.

And to refresh it’s enough to restart openhab?
Or better rename the xml-file?

Yes, rename the xml file is the easiest while debugging.

    status += ", 'isWeekend': " + Ephemeris.isWeekend
    status += ", 'isBankHoliday': " + Ephemeris.isBankHoliday(0,'/etc/openhab2/ephemeris/Holidays_de2.xml')
    status += ", 'getBankHolidayName': " + Ephemeris.getBankHolidayName(1,'/etc/openhab2/ephemeris/Holidays_de2.xml')
    status += ", 'isInDayset(school)': " + Ephemeris.isInDayset("school")
...
    logInfo("Observation_Check", status)

results in

2019-10-31 16:16:00.017 [INFO ] [thome.model.script.Observation_Check] - {'status': 'OK', 'isWeekend': false, 'isBankHoliday': false, 'getBankHolidayName': null, 'isInDayset(school)': true }

So the Holiday-xml seems to be ignored.

Can you try to remove “subconfigurations” hierarchy tags from your xml ? I have none in mine and it works.

1 Like

Long story short: We used the ephemeris.cfg at the beginning. But because of a bug in the Apache fileinstall we had to move the default configuration to different location.

I guess the same thing like every time. You are able to add an ephemeris.cfg file and it will override existing configurations. But you have to be aware of that the latest edit will win - thus we maybe should recommend to remove the default configuration from runtime.cfg at the time one will add a different config file for Ephemeris service.

How would I go to define shool holiday periods like from 23rd Dec 2019 until 3rd January 2020?
Thanks

From what I can tell so far, the only way to do that is enter a separate entry for each of those days. There is no way that I could find by studying the XSD to define something that stretches across multiple days. Looking at some of the examples and the religious holidays in the schema I notice Jollyday defines a separate entry for each day. There is no way to define a number of days.

It’s also worth noting though, that many religious holidays are also built into Jollyday so even if your country doesn’t give a bank holiday for a given religious holiday, you don’t necessarily need to manually calculate the date yourself. But as with most things like this, you will need to look at the code to verify if the calculation is correct (e.g. Orthodox Christians and Roman Catholic and Protestants calculate the date for Easter differently and I’m not knowledgeable enough to tell if the code handles it correctly).

I’ve updated the docs to cover this rutime.cfg stuff. It strikes me as kind of awkward.

Did anyone consider just having isWeekend return null if there isn’t a weekend dayset? Then we can just say “add a isWeekend dayset to ephemeris.cfg or configure it in PaperUI if that happens.” Then we don’t have to worry at all about runtime.cfg and there is only the two standard ways to config it. Hopefully the UI in OH 3 will let us create daysets that way.