openhab / openhab-core

Core framework of openHAB
https://www.openhab.org/
Eclipse Public License 2.0
912 stars 421 forks source link

[RfC] Central UPnP/mDNS thing discovery for suggesting add-ons to install #2645

Closed kaikreuzer closed 9 months ago

kaikreuzer commented 2 years ago

I'm creating this issue as I mentioned an idea over in another discussion. I haven't detailed it out in any way, but we could use this issue to discuss whether it makes any sense to pursue it at all.

The rough outline is: Many "Things" can be discovered nowadays through mDNS+UPnP. openHAB currently only adds them to the Inbox, if the user has already installed the according add-on(s). Especially for new users, it would be very nice if this wouldn't be possible: openHAB could identify supported devices and suggest the user to install certain add-ons instead (e.g. as a step in the setup wizard that @ghys created with the main UI).

There might be different ways to realize this:

  1. The bindings currently implement a DiscoveryParticipant service. These are usually in a separate package and pretty independent of the other binding code. We could create a single new bundle in openhab-core that contains all these DiscoveryParticipants and which is part of the default installation. The problem with this approach would be that add-on specific code would have to be added to openhab-core as well. This is imho neither from an architectural point of view nor from a contribution process a desired setup.
  2. We could come up with some new concept, like additional metadata within the openhab-addons repo, which only contains the discriminators that are required to identify a supported device from a mDNS/UPnP info object. This metadata could be made available as a file (or files in a folder) to the distro and some generic core feature, which evaluates this data and that is capable to provide a list of add-ons to the UI that the user might want to install. While this approach won't be able to directly add Things to the Inbox, it might be a suitable way to also bridge the gap between discovery and still requiring the user to install the add-on before a discovery result can anyhow be accepted.

Let me know what you think!

andrewfg commented 2 years ago

Thanks for this @kaikreuzer. As mentioned earlier I think it is a brilliant idea, and am very willing to contribute. Following are some thoughts concerning such an "auto-disco" module, in no particular sequence..

1. SCOPE OF ADD-ONS

The scope of bindings covered by auto-disco, is a list of binding names. This could be either a) a list maintained by the openhab/add-ons maintainers where only those add-ons that fulfil specific technical requirements are included, or b) where binding developers can opt-in for their binding to be included by adding it to the list, or c) automated based on presence or absence of some metadata in the binding code as implied by @kaikreuzer above.

2. TOOLS & REVIEW PROCESS FOR ADDING BINDINGS TO SCOPE

Perhaps the CI build tools could/should include tests to ensure that a binding (if it is in the scope list) is compliant. Perhaps there should be a JUNIT test class for this functionality; either a common module covering all bindings, or a template to assist developers to create their own JUNIT test class. And openhab/add-ons maintainers / reviewers should be made aware to check results of such tests.

3. TECHNICAL SCOPE OF BINDINGS COVERED

In principle any binding that implements a DiscoveryParticipant can be included. There are probably three sub-classes of these -- namely those that implement UPNPDiscoveryParticipant, those that implement MDNSDiscoveryParticipant, and those that implement a native/other form of DiscoveryParticipant service.

4. LOCATION OF AUTO-DISCO

In principle the auto-disco component could itself be an add-on. But it is probably better to be a part of the OH core (just as the Inbox is part of the core).

5. SOLUTION DEVELOPMENT FRAMEWORK

The solution is an OSGI Component, that..

6. SOLUTION RUNTIME / UI

ghys commented 2 years ago

As suggested above from a UI perspective the step in the setup wizard where you can install add-ons i.e. this:

image

is a low hanging fruit - if there were an API endpoint like /rest/bindings/suggestions to call with at least a list of suggested bindings in return, then the list of add-ons to install in this part of the wizard could be pre-initialized. Details about the discovery results are t.b.d. but could be shown as well if necessary. I believe adding things is out of scope at this stage, when the add-ons are installed and the wizard is finished users can be invited to go to the Inbox to see what they can add.

If the discovery process takes some time, it could be initiated as soon as the wizard starts so that it happens while the user goes through it, and by the time they get to the "Install Add-ons" step the discovery results would be in. I even wanted to eventually add a step to (optionally) initialize the semantic model with a hierarchy of locations, causing the wizard to take even longer to go through (if those steps aren't skipped), allowing more time for the discovery to finish.

wborn commented 2 years ago

I'd go for the add-on metadata (https://github.com/openhab/openhab-core/issues/2058) approach, which can then be aggregated in the add-ons repo and made available for all add-ons without having to install them. This would also allow for some other nice additions like suggesting/filtering country specific add-ons and maybe even localizing the add-on names (https://github.com/openhab/openhab-webui/issues/1213). :wink:

hmerk commented 2 years ago
  1. The problem with this approach would be that add-on specific code would have to be added to openhab-core as well. This is imho neither from an architectural point of view nor from a contribution process a desired setup.

This is exactly the issue we would have with the Wemo binding, as it starts a special UPnP scan at start.

andrewfg commented 2 years ago

I don't know the Wemo but I am pretty sure that 'special scans' would in any case be out of scope. As far as I recall the Velux also has a 'special' hard coded mDNS discovery because the core OH JMDNS discovery did not work for that hub.

splatch commented 2 years ago

Maybe proper approach is going with plugin mechanism. The mdns discovery is part of core bundles, so it is installed by default. The addons provide discovery participants but they could provide also separate descriptors/mappings/filters which could be extracted and embedded while building up final a product (OH distribution). By this way you can keep core clear or addon specific stuff, let addons bring their mdns logic through filters and just pack it up in assembly so runtime does the work. Each part does what it is supposed to do.

openhab-bot commented 1 year ago

This issue has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/openhab-4-0-wishlist/142388/101

openhab-bot commented 1 year ago

This issue has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/openhab-4-0-wishlist/142388/353

openhab-bot commented 1 year ago

This issue has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/openhab-marketing-is-lacking/149280/114

mherwege commented 1 year ago

There has been quite a bit of interest in this in the forum lately (https://community.openhab.org/t/openhab-4-0-wishlist/142388/101). I do think it would be a good idea to have some form of 'addon suggestion service' that takes a light approach to trying to identify bindings that could be of use by scanning the network. We would certainly not be able to discover everything, but a few suggestions would be nice.

I'd go for the add-on metadata (#2058) approach, which can then be aggregated in the add-ons repo and made available for all add-ons without having to install them. This would also allow for some other nice additions like suggesting/filtering country specific add-ons and maybe even localizing the add-on names (openhab/openhab-webui#1213). 😉

I like the idea of additional add-on metadata to drive this. But we would need to come up with a kind of filter syntax that could be used by a core discovery service. The 2 technologies behind the core services we currently have (mDNS and UPnP) each have there own way of doing things. I suspect mDNS might actually be the simpler one. Just filtering with a pattern on device name and service string may be sufficient. Extending the addon metadata with some pattern fields for device name and service may be sufficient to create a binding suggestion list.

Therefore, what about first trying this for mDNS? We would need:

While something similar would be possible for UPnP, I expect the filter criteria needed to be more complex. But it would again be possible to do something like this for UPnP as well.

andrewfg commented 1 year ago

I expect the filter criteria needed to be more complex.

There are probably two main search criteria..

<upnp-discovery>
    <device-type>urn:schemas-upnp-org:device:Basic:1</device-type>
    <filter field-name="Model number" field-value="BSB" exact-match="false"/> // Hue bridge
</upnp-discovery>

<upnp-discovery>
    <device-type>urn:schemas-upnp-org:device:MediaRenderer:1</device-type> // Media renderer
</upnp-discovery>

<upnp-discovery>
    <device-type>urn:custom-org:custom-device:custom:*</device-type> // Custom device
</upnp-discovery>

Note: you would need to do something special with the upnpcontrol binding which is a binding that uses UPnP to find other UPnP things..

mherwege commented 1 year ago

Note: you would need to do something special with the upnpcontrol binding which is a binding that uses UPnP to find other UPnP things..

I don't think there is an exception. The upnpcontrol binding only makes sense when there are UPnP MediaRenderers in the network. So just detecting these would be fine. It is only about suggesting which bindings to install, not about doing the full discovery. At a minimum the media renderers, they could be used as an audio sink. If there are also UPnP MediaServers in the network the full potential of the binding can be used. I do run into something else that is a bit specific to it as well though (and which is not supported by the current upnpcontrol binding). Some media servers/renderers are embedded in other devices. I have a rework of the binding that discovers these as well, but I can't figure out how to make use of the embedded devices (don't get any of the information back). Of course, in the context of binding discovery, it would also mean that, to be complete, the matching might have to look in embedded devices as well.

clinique commented 1 year ago

I suggest that binding suggestions can also be done based on country when bindings are cloud only.

openhab-bot commented 1 year ago

This issue has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/openhab-marketing-is-lacking/149280/200

andrewfg commented 1 year ago

Is anyone writing code for this? If so, please let me know, since otherwise I will start to write something.

mherwege commented 1 year ago

Is anyone writing code for this? If so, please let me know, since otherwise I will start to write something.

I wanted to start with it, but ran into this: https://github.com/openhab/openhab-core/issues/3795#issuecomment-1711226452 The first thing to solve is to get access to all metadata of the available addons before they are installed. That’s where I stopped. I don’t have enough time in the next few weeks to dedicate to this, so it would be great if you can work on it.

andrewfg commented 1 year ago

@mherwege thanks for the info. I am not very experienced on OH core programming, so perhaps you can give me some coaching? Some questions below..

  1. In what core module should we locate this? I am thinking openhab.core.config.discovery ?
  2. I am thinking that the architecture shall consist of a BindingFinder class that a) gets a list of all non installed bindings, b) gets some meta data from them, c) for those that contain a certain tag 'isDiscoverable' say, depending on additional metadata e.g mdns search target, or upnp search target, use the existing core mdns resp. upnp discovery classes to do a search for things, d) for those where a thing is found add them to a list of 'suggested bindings'. Does that make sense?
  3. Can you point me to the existing code that runs thing inbox searches? I would harness the same code to do binding thing searches..
  4. Any other suggestions?
mvalla commented 1 year ago

I strongly suggest to start with an "easy" implementation where just mDNS and UPnP filtering/matching are used. Other cases to find by country or other cloud services could be left for future versions.

Also count on me for testing a first version with the BTicino binding (local connection, UPnP discovery)

andrewfg commented 1 year ago

cases to find by country or other cloud services could be left for future versions

I agree with you. Indeed I am not even convinced about the idea to filter by country since if a user has an actual discoverable device in their house then they probably want to use that device regardless of what country they live in. And the cloud issue is irrelevant because mdns and upnp can only discover local devices.

clinique commented 1 year ago

Using country info (that is provided at beginning of the new install wizard) could help identify general purpose cloud information binding (eg a weather service, trash services...). No upnp neither mdns need here.

mherwege commented 1 year ago

@mherwege thanks for the info. I am not very experienced on OH core programming, so perhaps you can give me some coaching? Some questions below..

  1. In what core module should we locate this? I am thinking openhab.core.config.discovery ?
  2. I am thinking that the architecture shall consist of a BindingFinder class that a) gets a list of all non installed bindings, b) gets some meta data from them, c) for those that contain a certain tag 'isDiscoverable' say, depending on additional metadata e.g mdns search target, or upnp search target, use the existing core mdns resp. upnp discovery classes to do a search for things, d) for those where a thing is found add them to a list of 'suggested bindings'. Does that make sense?
  3. Can you point me to the existing code that runs thing inbox searches? I would harness the same code to do binding thing searches..
  4. Any other suggestions?

I think you can just create a service (AddonSuggestionService) that registers as a participant to MDNSDiscoveryParticipant and UPnPDiscoveryParticipant (I would do it in 2 implementations of an AddonSuggestionService interface). That way, that service will get all MDNS and UPnP discovery messages. The service will than need to filter based on the filters coming from the binding metadata and create a new AddonSuggestion. You could have an AddonSuggestionRegistry keeping track of suggestions. A REST endpoint would list the suggestions. I was also thinking it should probably go into openhab.core.config.discovery, although I could imagine putting it in a new package all together as well. After all, we do not do full discovery, just use some of the infrastructure for MDNS and UPnP. Other discovery mechanisms do not have a core service backing it, and may need to be coded independently. The REST endpoint (rest/addons/suggestions) should go in org.openhab.core.io.rest.core.

All this seems quite feasible and not to hard to me. The key challenge is getting the metadata. If the addon is available from the marketplace, all metadata is available, even when the addon is not installed. However, if the addon is part of the distribution, it is installed through Karaf. After installation, OH has access to the metadata in the .jar file. However, before installation, all that metadata is not available, only some minimal bundle info. To understand that in more detail, have a look at the org.openhab.addon and org.openhab.addon.marketplace packages. You can try the REST API and try the /rest/addons endpoint. You will notice country and connection are only populated for installed addons, not for the others. And that info comes from the metadata in the addon.xml file. Ideally, that is where we should get the info from, also for the non-installed addons. For this to work, a few things would need to happen:

  1. Extend the addon.xml schema to include more fields to support discovery.
  2. Add code in the AddonInfo class, org.openhab.core.addon package that adds these fields.
  3. Extend the REST API to include extra fields that are necessary for discovery. Have a look at this PR to know where to do this: https://github.com/openhab/openhab-core/pull/3797
  4. And the most difficult one: have a build step in the addons repository that extract the relevant fields from all addon.xml files and makes it available to the AddonSuggestionService class in core. I don't know how to do that. It requires more than java, but also an extra build step.

Also, don't call it BindingFinder. It should be about Addons. I think it ultimately would apply for more than bindings, specifically IO services, maybe UI's, but also could also imagine it ultimately applies to rule templates. Don't push it too far just yet though. Let's start small but keep naming open.

mvalla commented 1 year ago

However, before installation, all that metadata is not available, only some minimal bundle info.

You can try the REST API and try the /rest/addons endpoint. You will notice country and connection are only populated for installed addons, not for the others.

How are the current metadata fields (eg. name of the addon and the minimal bundle info you mention) extracted from the addon repository then? It should be done already via a step like the n. 4. you listed, right? Otherwise I cannot understand how a fresh OH isntallation can list all addons available in the distribution. Can one just extend the existing extraction step with the additional metadata needed for discovery?

andrewfg commented 1 year ago

create a service (AddonSuggestionService) that registers as a participant to MDNSDiscoveryParticipant .. That way, that service will get all MDNS and UPnP discovery messages.

Umm. That approach is probably oversimplified: MDNSDiscoveryParticipant has a method getServiceType() which returns a single string that 'Defines the mDNS service type this participant listens to`. So we would need to create multiple MDNSDiscoveryParticipant listener instances to listen to different service types from the meta data. But it is still doable.

mherwege commented 1 year ago

How are the current metadata fields (eg. name of the addon and the minimal bundle info you mention) extracted from the addon repository then? It should be done already via a step like the n. 4. you listed, right?

Karaf only provides id, name and label. And that´s what you see now. I looked at some Karaf doc and didn´t see an easy way to extend that.

andrewfg commented 1 year ago

@mherwege I just committed some initial code here; perhaps you can have a look at it?

The current code creates multiple UpnpDiscoveryParticipant and MDNSDiscoveryParticipant on the fly; but I think this will not work, since multiple dynamically instantiated OSGI components are not allowed. So I have to think of another approach..

https://github.com/andrewfg/openhab-core/tree/binding-finder/bundles/org.openhab.core.config.discovery.addon

mherwege commented 1 year ago

Indeed, it will nor work like that. And the internal UPnP and MDNS discovery services also call thingDiscoverd for each discovered thing. We are not interested in things here. I see two options:

  1. Add functionality to the internal UPnP and MDNS discovery services to call an Addon suggestion service, on top off calling the registered participants.
  2. Create our own services, that directly register to the UPnP and MDNS services, as currently in the discovery services. They can be loosely modelled after the existing discovery services.
andrewfg commented 1 year ago

^ I tend to favour option 2. by talking to MDNSClient and UpnpClient directly. I will have another try tomorrow. This code is obviously only the 'mid end'; as you say, the front end mechanism for providing the search meta data is yet to be defined; and the back end for fulfilling the UI likewise..

andrewfg commented 1 year ago

Ok I just made some new commits, which I think looks a lot better..

https://github.com/andrewfg/openhab-core/tree/binding-finder/bundles/org.openhab.core.config.discovery.addon

The AddonSuggestionFinder supports three external public methods..

The AddonSuggestionFinder also supports a Servlet with the following HTTP methods..

Notes: as mentioned before..

  1. we still need some way to feed the respective XML into loadXML()
  2. we still need some way to process the list of addon Ids returned by getSuggestions()

An example of the XML is as follows. Each addon author would have to add one or more <candidate> entries for their respective addons.

<?xml version='1.0' encoding='UTF-8'?>
<suggested-addon-candidates>
    <candidate>
        <addon-uid>binding.hpprinter</addon-uid>
        <discovery-method>
            <service-type>mdns</service-type>
            <match-property>
                <name>rp</name>
                <regex>/.*\S.*/</regex>
            </match-property>
            <match-property>
                <name>ty</name>
                <regex>^hp</regex>
            </match-property>
            <mdns-service-type>_printer._tcp.local.</mdns-service-type>
        </discovery-method>
    </candidate>
    <candidate>
        <addon-uid>binding.hue</addon-uid>
        <discovery-method>
            <service-type>upnp</service-type>
            <match-property>
                <name>modelName</name>
                <regex>Philips hue bridge</regex>
            </match-property>
        </discovery-method>
        <discovery-method>
            <service-type>mdns</service-type>
            <mdns-service-type>_hue._tcp.local.</mdns-service-type>
        </discovery-method>
    </candidate>
</suggested-addon-candidates>
mherwege commented 1 year ago

I think the backend should be done by creating a rest api for /rest/addons/suggestions in https://github.com/openhab/openhab-core/blob/af4fce1e4f7faf9e5d89ded3ca31a20aac57ecf7/bundles/org.openhab.core.io.rest.core/src/main/java/org/openhab/core/io/rest/core/internal/addons/AddonResource.java. All the rest is the responsability of javascript in MainUI. I don’t think you need a separate servlet. I would think it should be an OSGI service to provide an aggretated view of the addon metadata from the addon repository, or other addon source. So it most likely would need to use the addon service registry to get all of the addon services.

mherwege commented 1 year ago

The POST requirement in the servlet could probably be covered by having all required metadata represented in AddonInfo. What will remain is how to get from the addon xml to AddonInfo in time in the first place. That should be the resposnability of the extra service.

andrewfg commented 1 year ago

^ @mherwege I am not sure if I fully understood your two posts above, so let me just check.

backend should be done by creating a rest api for /rest/addons/suggestions

Ok, I understand that Main UI would simply do a GET on /suggestions to fetch the list of suggested addons. I will make a new commit for that.

I would think it should be an OSGI service to provide an aggretated view of the addon metadata from the addon repository, or other addon source. So it most likely would need to use the addon service registry to get all of the addon services. What will remain is how to get from the addon xml to AddonInfo in time in the first place. That should be the resposnability of the extra service.

Can you please explain more? I think that currently OH does have metadata for the addons which are already loaded. But it does not have metadata for the addons that are NOT loaded. And we precisely need the metadata from the latter, rather than the former. So it seems to me that there are two approaches to get this missing metadata -- namely 1) by loading a single external XML file from some location which contains the missing metadata about potential suggestion candidates, or 2) by doing a wildcard parse of all the individual addons java files (the ones that have not yet been loaded by OH) to extract the candidate metadata individually from those files, and then dynamically assemble them into a common XML package of all candidates. Currently I am working on the hypothesis 1) using a common prefilled XML metadata file; whereas I think you are expecting hypothesis 2) .. which is certainly more challenging. Perhaps we should adopt a two stage approach?

andrewfg commented 1 year ago

@mherwege as you suggested, in my latest commit the Servlet has been removed and replaced by a GET endpoint in the REST API..

EDIT: just converted the class to an AddonService :) but it still cannot work without external XML file :( .. since we would need to agree on changes to the current binding information xml in order to include the additional metadata..

andrewfg commented 1 year ago

^ Apropos the above, we would need to add an additional field to AddonInfo that would contain a list of DiscoveryMethod DTOs which in turn would contain a list of MatchProperty DTOs as follows. => @mherwege any comments?

public class AddonInfo implements Identifiable<String> {
    private static final Set<String> SUPPORTED_ADDON_TYPES = Set.of("automation", "binding", "misc", "persistence",
            "transformation", "ui", "voice");

    private final String id;
    private final String type;
    private final String name;
    private final String description;
    private final @Nullable String connection;
    private final List<String> countries;
    private final @Nullable String configDescriptionURI;
    private final String serviceId;
    private @Nullable String sourceBundle;
    // new field
    private @Nullable List<DiscoveryMethod> discoveryMethods;
}

// new embedded DTO
public class DiscoveryMethod {
    private @Nullable String serviceType;
    private @Nullable List<MatchProperty> matchProperties;
    private @Nullable String mdnsServiceType;
}

// new sub- embedded DTO
public class MatchProperty {
    private @Nullable String name;
    private @Nullable String regex;
}
mherwege commented 1 year ago

EDIT: just converted the class to an AddonService :) but it still cannot work without external XML file :( .. since we would need to agree on changes to the current binding information xml in order to include the additional metadata..

I know. But I was hoping there would be a way to automatically generate it from the addon.xml files during the addons build. That would make it easier to maintain. That would not work for marktetplace addons, but not sure we should auto suggest something that is not in the official repo anyway.

would a new or modified AddonInfoProvider be an option to then read this extra file and make all of the addon info available, instead of waiting for it to become available on bundle installation?

mherwege commented 1 year ago

Apropos the above, we would need to add an additional field to AddonInfo that would contain a list of DiscoveryMethod DTOs which in turn would contain a list of MatchProperty DTOs as follows. => @mherwege any comments?

This looks reasonable to me.

andrewfg commented 1 year ago

hoping there would be a way to automatically generate it from the addon.xml files during the addons build

That would make sense. I don't know anything about the build process so not sure exactly how to implement it. Initially could start with a manual file. And figure out how to auto build it in a subsequent PR.

would a new or modified AddonInfoProvider be an option to then read this extra file and make all of the addon info available

I think so. It certainly would be faster if the data is prebuilt in the distro, rather than waiting to build it dynamically during setup.

This looks reasonable to me.

I am not sure if the data would be in an AddonInfo DTO or an Addon DTO. Not sure why we have both?? But anyway if we preloaded the data as discussed above, then it does not really need to be in either.

mherwege commented 1 year ago

hoping there would be a way to automatically generate it from the addon.xml files during the addons build

That would make sense. I don't know anything about the build process so not sure exactly how to implement it. Initially could start with a manual file. And figure out how to auto build it in a subsequent PR.

would a new or modified AddonInfoProvider be an option to then read this extra file and make all of the addon info available

I think so. It certainly would be faster if the data is prebuilt in the distro, rather than waiting to build it dynamically during setup.

This looks reasonable to me.

I am not sure if the data would be in an AddonInfo DTO or an Addon DTO. Not sure why we have both?? But anyway if we preloaded the data as discussed above, then it does not really need to be in either.

I would think it should be in AddonInfo. What you find in Addon is basic, and corresponds to what is available from the karaf feature.xml. Ax soon as an addon gets installed the AddonInfo gets updated and can get provided from the AddonInfoRegistry. Other sources could also provide the same info and may provide before it installation (I believe the JSON addon provider would). So adding a provider that gets the info from another source (the compounded addon.xml created during build) may do to make the info available earlier. This is just my reading of it, and there may be better solutions.

andrewfg commented 1 year ago

I would think it should be in AddonInfo.

Ok. Understood.

In the meantime, I have modified the service to load from a plain xml resource file within the Jar. Also I have added an xml schema, and an itest module. So I have created a PR #3806 from this. It is not yet fully tested, so it is not yet ready to merge.

andrewfg commented 12 months ago

@mherwege as a first step #3806 loads the suggested addon candidates from a manual xml resource file included in the module jar file -- example suggested-addon-candidates.xml.

I am currently waiting for help from maintainers on how to fix the feature.xml file in #3806 so that the PR can a) be built, and therefore b) be reviewed. However while we wait for that, perhaps we can have a discussion here about how to automatically create suggested-addon-candidates.xml on the fly from the OH build process by parsing metadata embedded in the respective addons Jar files. => Any thoughts?

openhab-bot commented 12 months ago

This issue has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/need-help-to-fix-feature-xml-problem-in-a-new-oh-core-module/149862/1

openhab-bot commented 11 months ago

This issue has been mentioned on openHAB Community. There might be relevant details there:

https://community.openhab.org/t/energi-data-service-binding-4-0-0-0-4-1-0-0/144370/38

kaikreuzer commented 9 months ago

Thanks @andrewfg and @mherwege for making this happen!