Millheat local API development questions

I’ve been a user for many years, and I don’t use any. But then I guess I’m not that typical :wink:

I’m not “arguing” with what you’re saying, I just need some more input to understand. I’ve never used blocky, but I thought it was just a UI based system for users that don’t want to write textual rules?

What I don’t understand is, if we take the “vacation” setting as an example, how does the user actually use this? Do the users make a “rule” where they hard-code the dates for their vacation and then send it? Or do they somehow use these rules as a “bridge” between the UI and the binding? If the latter, I’m afraid I don’t understand how that would look/be implemented.

Can you give me some more info that can set me on the right path to understand how this can be used?

No idea, personally I just use a few like cloud notifications.

Correct. Had to go back to the code to check as I didn’t really depend on the vacation code that much. I kept a “shadow” model layer between the cloud API and the OH channels, almost like a cache; openhab-addons/bundles/org.openhab.binding.millheat/src/main/java/org/openhab/binding/millheat/internal/handler/MillheatAccountHandler.java at 10048bc6257236af10bc6e7813c67a0bbd15f508 · openhab/openhab-addons · GitHub

In the ESPHome binding for i.e. the climate component, I keep a very shortlived cache/buffer to avoid multiple commands being sent to the AC rapidly. Many AC remotes seems to be designed around sending a complete state, and thus the slow ESP<->AC connection doesn’t like it (misses commands in my case). The cache has a 400ms timespan, long enough to allow rules to update 5-6 items in succession but short enough that it feels like immediate response when a single attribute is changed via UI. Code is here if you are curious; openhab-esphome/src/main/java/no/seime/openhab/binding/esphome/internal/message/ClimateMessageHandler.java at 1333c114b136dca4fcfe610ca16634e7af71d89e · seime/openhab-esphome · GitHub

OH supports creating rules in a number of ways:

  1. Simple UI Rules: Rules - Basic | openHAB, great for very simple “when x do y” but limited, obviously UI only.
  2. Scenes: A special UI rule that just consists of a list of Items and what state you want to command/update those Items to.
  3. Blockly: Rules Blockly | openHAB, great for users who are not already well versed in programming, UI only
  4. Rules DSL: Textual Rules | openHAB, traditional OH rules, I consider them deprecated since pretty must all of the other options are better. UI and file based are rules are supported.
  5. One of any of the automation add-ons: JS Scripting is probably the most commonly used with jRuby a close second. Groovy, Jython, and Java are options as well.

It really depends on what the end user wants really.

In JS Scripting it would be something like:

actions.getAction("millheat", "id:of:millheat:thing").setVacation(startTime, endTime);

startTime and endTime should be a ZonedDateTime since that’s what everything in rules use. But that means either or both can come from Items, hard coded, Item metadata, the cache some other binding (e.g. iCal) or anywhere makes sense to the end user.

For example, let’s say you have iCal set up with entries for your vacation. The iCal binding can populate two DateTime Items with the start and end. You can have a widget on MainUI that calls a rule that has the one line:

actions.getAction("millheat", "uid:of:millgheat:thing").setVacation(time.toZDT(items.VacationStart), time.toZDT(items.VacationEnd));

Or the rule can trigger based on changes to the two Items.

The rule can be triggered based on a cron job, time, command, update, or change to another Item.

The rule can be called directly from another rule.

But essentially yes, they use the rule to bridge between the UI and the binding through the Action.

If you’ve never used rule Actions I’m afraid you are missing out. Some bindings are not even useful without rule Actions like the Mail, Telegram, and other push notification add-ons. MQTT, HTTP, and Exec would be greatly hindered without Actions but at least still useable. Notifications to the phone apps require Rule Actions. Even the Astro binding has Rule Actions.

I’ve not done a survey but I believe the majority of add-ons provide at least one Action.

Graphically:

Item Event------------------>|
                             |
Time Event------------------>|
                             |---->Rule or Script---->Binding---->Device
Called from UI Widget------->|
                             |
Called from Another Rule---->|

I’d just like to add that I don’t consider the “vacation mode” especially important. I think a better approach is to use OH rules or similar to control the device according to your needs than to program the device to “behave in a special way” during your vacation. The reason I use the “vacation mode” in this discussion is that it’s the simplest command with this “challenge”. More relevant real-world use might be configuring the PID controller for example.

Yes, that’s what I thought - it doesn’t really matter how you write the rules, the rules are still pretty much “hard-coding” of some functionality that you want. That’s fine for some tasks (I only use Rules DSL because it’s file based and not likely to break when upgrading versions etc. Syntax is a PITA though) where you want to automate certain behavior. But, it doesn’t give you much of “generic”, “dynamic” functionality. You’re still bound by what the UI can offer, unless you want to rely on external services for providing the information you need…? That has kind of been my point all along, that whether you implement something in the binding itself, or using rules, you are limited by the UI capabilities. The exception is of course external services, which a binding can’t make presumptions about but that a rule can, which makes actions relevant. But it still doesn’t “help” if you want to use OH standalone, without those external services.

I get how you would use actions from rules, my question was rather if it made it particularly “usable”. The iCal example is an actual example for what I couldn’t quite image, so thank you for that, but I would say that it would be a lot of work to achieve a very “marginal benefit”. As far as I know, the “vacation mode” only makes the device use a different temperature setpoint (the documentation doesn’t really say what it does), so I’d rather just change the setpoint manually in the OH UI. If I did this regularly, I would probably come up with some rules that changed the setpoint in a suitable way. I would still consider that quicker and more reliable than having to integrate with an external service - where so many things can break. You’d also have to come up with some way to make the rule “know” what was a vacation, a tag of some sort or similar. And, the device can only store one vacation at a time, so there would be some challenges.

As I said, I picked “vacation mode” as an example because it was a simple concept with two parameters that “doesn’t work” without each other. But, one that might be more actually useful, is the setting of the PID parameters that decide how the temperature regulation behaves. It looks like this:

{
    "kp": 70,
    "ki": 0.02,
    "kd": 4500,
    "kd_filter_N": 60,
    "windup_limit_percentage": 95,
}

…or the paramters for the “window open” function:

{
    "drop_temperature_threshold": 5,
    "drop_time_range": 900,
    "enabled": true,
    "increase_temperature_threshold": 3,
    "increase_time_range": 900,
    "max_time": 3600
}

These might not make sense as channels, and might better fit as configuration parameters. But my “challenge” remains somewhat the same - how to make sure that they are sent together. That said, for these two, I guess I could query the device for the parameters not specified and use them when I send. It’s just not quite clear to me how to implement these things.

There’s no principle involved that I won’t use Actions. I’ve simply never needed one, and I think I see a “pattern”. My goal with using OH is that everything is offline - that it runs independently of Internet access and that it doesn’t rely on external services that might change their rules, might change the cost of use, might simply cease to exist and that might share your data (or lose them when being hacked). I don’t use any “cloud services” for anything, and it’s a goal for me not to. Most of the examples you mention are for exactly the kind of use I try to avoid :wink:

But, back on topic - I’m considering to not implement “vacation mode”, “weekly program” or any of the other API functions that “programs the device” to follow a certain schedule. The supported schedules are very rudimentary anyway, and you can probably make much more flexible and better suiting schedules using OH and its rules etc. I get why they make it when used with their “cloud” solution, as they have to send the data to the device and make the device itself do it, they can’t keep connections to the devices and micro-manage them. But, OH can.

So, if I take all the schedule functions of the table, I think it pretty much boils down to the two functions mentioned above, the regulator and “window open” configurations. And they probably don’t make sense as actions… so I’d have to find a way to integrate it into the configuration. I’ve already experimented with ConfigStatusProvider and ConfigStatusMessage which enables me to give the user some feedback when the configuration is in an invalid state. That helps.

What I find problematic with the configuration is that there’s no change notification available as far as I can tell, and that instead, the thing handler will be destroyed and recreated on every configuration change. It’s probably doable, but you kind of have to handle any changes in the initialization, and it seems a bit hard to have a “meaningful dialog” with the user during configuration. Is there really no way to make the Thing handler receive “configuration updates” instead of being teared down and rebuilt?

But, the worst problem I have with using the configuration is that I can’t test any of it, due to the this bug:

It basically means that while developing/debugging, I can’t use managed Things - they must be file-based. And that means that the Thing configuration is read-only, so I can’t modify the configuration from the UI and test how my code responds.

I’ve postponed working on the configuration because of the above bug, but it doesn’s seem like much is happening on that front, so I’m not sure how to proceed. I can’t make a lot of code that I don’t get to test at all, and then just expect it to behave like I imagined.

Rules DSL is no more or less likely to break between versions than any other option. In fact, it’s kind of more likely to break these days because there are not as many people maintaining it as the other options. For instance, in OH 4.3 M4 the sharedCache and privateCache appear to be broken.

JS Scripting, jRuby, et al have a larger community of maintainers and are much more complete when it comes to making available all that OH has to offer (Item metadata, access to the Things and Rules Registries, calling another rule, being called by another rule with arguments, etc. are all not possible in Rules DSL). All of these can be written in files or managed rules through the UI. They all also support third party libraries and standard libraries (e.g. is there some Ruby gem that does what you need in a rule, you can use it!).

I’m not sure what you mean by that. Even Rules DSL, as incomplete and limited as it is, is Turing Complete. If it can be coded, you can write an OH Rule to do it, as statically or as dynamically as desired.

You don’t have to use the UI to write rules. But again, if using a Script Action or Script Condition, the code you use is Turing Complete. If it can be coded at all, you can code it in a rule.

Either I’m completely missing what you are saying or you completly miss what rules are capable of and what they are for. Because the whole “external services” stuff is irrelevant to what rules can or cannot do or when it is or is not appropiate to use an Action. I pointed out some examples and some of those examples do require a cloud server but there are tons of Actions that do not:

  • executeCommandLine
  • mqtt.publishMQTT
  • HTTP.sendHttpXRequest
  • Ephemeris.isBankHolidy
  • astro.getElevation

etc.

Actions are a convenient way to interact a Thing/config in OH when:

  1. the timing/events that should initiate that interaction are not fixed or need to be flexible
  2. the amount of information required by the event is more than can be captured by a Channel
  3. it’s something that may need to have some logic applied before being called

Kind of the whole point of OH is to be able to make all these closed systems work together. Note that the iCal binding works with NextCloud and OwnCloud and any other standard self hosted calendaring service.

Configuration parameters don’t get “set” until you save the changes on the Things page. The Thing gets reloaded at that point so maybe make it part of the INITALIZING phase of the Thing’s status. The Zwave binding accepts configuration updates and acts upon them. That might be an example you can look at. Though the Zwave binding only supports config parameter changes when using managed Things, not file based Things. But I don’t know if there is a general limitation with OH that causes that or if it’s something specific to Zwave.

Based on my experience changing the config of a Thing always causes it to become reset and go through the INITIALIZING stage on through. If there’s an error, the Thing usually ends up in an ERROR stage where there’s a status and a description and the meaningfull error information is usually part of the description (e.g. “Connection timed out”). That’s the feedback mechanism for config errors (these are seen both in the UI and in events.log. Usually when there is an error like that the binding itself logs something meaningful to openhab.log at the WARN or ERROR level.

I think one of the reasons it works this way is that with file based configs, when a .things file is unloaded, all the Things associated defined in it gets deleted. Then when the file is loaded the Things are created anew. So there is never an opportunity to “update”. It’s always “hey! here’s a new Thing!”. I’m just speculating though. I wasn’t involved when these sorts of design choices.

I can’t help with that. But OH 4.3 isn’t completely broken since early October. The bug report indicates that the error is dependent on startup order. It shouldn’t happen every time all the time and I suspect if you’ve only the one binding and a few Things this error doesn’t occur at all. If it does, please add information to that issue (don’t need to provide signoff to comment on an issue) since the originator states they cannot reproduce the error.

I think we’re talking about “breaking” from different points of view. I don’t mean “being broken by a OH update” (although that would suck too), I mean being broken by some dependency stop working, Java dropping support for ECMAScript, which means that suddenly you need a new add-on to make it work, and with a different flavor with different syntax etc. In short, I want as low a “vertical stack” as possible. But, this isn’t an important point, I use Rules DSL as long as it does what I need - when it doesn’t, I’ll have to look at one of the other options.

Yes, sorry, I kind of knew that it was unclear when I wrote it, but didn’t know how to say what I wanted to say without a long explanation. As with most here (I guess), English isn’t my native language, so sometimes it’s hard to find ways to explain.

I didn’t mean that the rules themselves were “limited”, but that they don’t make the UI itself more “flexible”. You’re still bound by the same limitations whether the “backend” is a rule or a binding, so you can’t for example make a “UI form” where you have to fill in a certain amount of data and then “submit” it. If you don’t understand what I mean, forget it, as it’s not important.

We’re talking past each other. I’m not talking about what rules can and cannot do, but about the whole “solution” from where the user enters the data to when the resulting action is actually being performed. So, with “external service” I meant that you use some system outside of OH to provide the UI for what you can’t do in OH’s UI. You can’t (or maybe you can if you do a lot of UI tricks) have a calendar in OH’s UI where you specify your vacation, so you use an external service to do that, like some online calendar service. I’m not saying that this is the only use case for Actions, I’m merely saying that I see why they probably become “a more handy tool” when using OH to integrate with external services.

I think we’re looking at OH from slightly different angles. For me, the main value is the ability to integrate control of “everything” into once place (as opposed to using dozens of different “apps” or other solutions offered by each manufacturer). This, combined with having full control of the system and making it as robust and reliable as possible. I don’t need to access it from mobile devices, and if I were to, I would simply set up a VPN connection to my firewall and operate it like I do locally.

If your use case is different, if you see it primarily as a way to “tie together” a lot of different “external services”, we will obviously come to different conclusions about how to use things and what’s desirable.

I’m not saying that any way is wrong or that a binding shouldn’t be useful for those with other use patterns than me, I’m just trying to explain what I think is the reason that we view some things so differently.

If people think that having actions for things like “vacation mode” is useful, I’ll gladly make it, even if I will never use it. What I’m trying to avoid is spending time implementing something that nobody will ever use.

I guess the same applies to my idea to skip implementing all the “schedule” functions. I don’t see that as useful because I think it’s more practical to control things and make rules one place and in one system, than to spread it around all kind of different services. To me, it’s also obvious that I would never use the “Mill cloud” solution, for all the previously explained reasons. This means that I don’t see the need to use these device implemented schedules. But, for a user that wishes to use OH and “Mill cloud” in combination, the calculus might be different. In this case, I would suggest that the official binding that does use the “Mill cloud” might be a more appropriate solution for such use.

I tried to look at the ZWave binding, but there’s so much going on there that it might require more time to figure out exactly how it does this than I’m willing to invest. There might also be a difference in it being a Bridge instead of a Thing. The Bridge handler probably doesn’t get teared down in the way the Thing handler does, so it might enable the binding to have some control that this binding doesn’t.

When it comes to ZWave only supporting configuration changes for managed Things, I’m pretty sure that’s a “limitation” of OH itself. I’m not sure if it’s really a limitation though, because I don’t have the overview to know if there is another viable way. Regardless, OH makes the configuration read-only as soon as the Thing is file-based. I get the underlying “logic” here - the configuration is a part of the Thing file, and OH is not to try to edit that file. There probably is no “suitable location” to persist configuration changes for file-based Things since trying to “combine” configuration parameters from the file and another, managed storage would just make a complete mess.

What this logic fails to recognize is that some times there are configuration parameters that doesn’t need to be persisted in OH. They can be stored in the device itself instead, and OH can retrieve them to populate the configuration. There are Java methods for programatically extending the configuration in this way, so you can add parameters that aren’t defined in the files. But, because of the “rule” that file based configurations are read-only, this kind of use becomes impossible with file-based Things.

I guess one could have a long discussion about wether such “settings” are a part of the configuration, or if they should be channels. But, I find that some of these things definitely “makes more sense” from the user’s perspective when a part of the configuration than when they are presented as channels that you have to link to “regular UI elements”. To me, configuration is the things you set up when you decide how the device should work, the channels are the things you interact with “during regular use”. This way of looking at it clashes slightly with the idea that configuration is information that OH persists, while everything else is “not configuration”. I think the ZWave binding (and probably others) have faced this dilemma and had to find some kind of “workarounds”, with the caveat that you can’t really use file-based ZWave Things for example.

As to my wish for a subscription service for configuration changes instead of the handler being recycled, I can see why such a solution could have been chosen to make bindings “simpler” - or at least less error-prone. I was just wondering if there was a way to override/change this behavior, but I’ll probably find a way to make it work with the current scheme too.

I’m not so sure that it’s actually the same bug that I, and other developers, are experiencing. But, I think they are somewhat closely related. The symptoms/behavior is the same, but I suspect that the cause isn’t. Thus, the bug referred to might be caused by changes that have been made later, or if it is timing based, it can simply be due to some seeming unrelated change that slightly affect the timing.

But, this issue when running the “demo.app” from Eclipse is 100% consistent. It’s there all time, and I’ve found no other “workaround” than to use file-based Things. For all I know, this problem has been around since OH 4 was released. It’s hard to find a lot of information about this, all I’ve managed to find is small bits here and there. But, it seems that it has been a problem for some time. I tried to compile 4.2.2 to see if that helped, but compiling core takes hours and hours so it’s not that tempting to just try lots of different snapshots. From what I could see, this problem was also there in 4.2.2, although I won’t be too assertive about it because I tried so many different things that I can’t say with complete confidence that what I was actually running was 4.2.2. But, I think so.

Regardless of the cause, it’s hard for someone like me, that knows very little of what goes on inside core, to try to figure it out. I think it’s a shame that some of those that do have the requred knowledge about core don’t try to figure it out, because it’s a somewhat significant obstacle to binding development as I see it. But, others might use a completely different development setup and as a result not be affected. I don’t know.

Actually I think this can be done in MainUI. But I spend a lot of effort to not depend on any UI so I can’t say for sure. But I think I’ve seen something like this on the Widget Mareketplace.

For me it’s not to control everything. I don’t want a universal control.

I want automation. I want a home that knows what to do and when to do it without needing to be manually told to do it.

If an “external” (not native to OH) service helps make this happen, I’m OK with that. Though I will note that with two exceptions, those external services that I use are self hosted, not provided by a third party. But given kind of the whole point of OH is to make a bunch of third party stuff work together I don’t really make any distinction between that. It’s all about states and events. If those can get into OH, how ever that happens, OH can do some automation based on them.

From the end user side of things it appears to. But there are lots of Things with configs. Even the Astro local sun and local moon have config parameters. I can’t imagine a simpler binding than that to look at as an example.

I mainly brought up Zwave to mention that there might be a limitation that makes dealing with .things files not as straight forward.

But to spell out the limitation a little more, many Zwave devices have some properties that can be set. For example, a wall switch might have a status light you can turn oon or off through a Thing config parameter. File based Zwave Things have no way to set these parameters at all. Now that I spell it out it may not be as close to what you are doing as I first thought.

The rule of thumb is if it’s something that is likely to be used to drive an automation in OH or an end user (i.e. someone in your home) will want to change in the normal course of using the home (i.e. shown on a Sitemap or MainUI Page) it should be a Channel. If not, Actions or Thing configurations are good options though not necessarily the only options. These are interfaces that the OH admin user will have access to and know how to use but Channels linked to Items can also be used to configure an end device. What’s setting the setpoint on a thermostat if not setting a configuration on the device?

It’s not “just a universal remote” the way I use it either. It’s also monitoring, that is, collecting the information I need to make decisions. I also use some automation, and might increase that in the future, but I don’t bother to try to automate things where the decisions are either complex where a significant part of the information needed comes from “outside the realm of OH”. If things depend on what I want to do right then, for example, it makes no sense to try to automate it. It would be more work to figure out a way to “inform” the automation with the data it needed to make the right decisions than it is for me to just control it. So, I don’t think we’re that far apart, but the focus is probably slightly different.

I don’t have a problem with integrating things in itself, especially self-hosted things, but I’m somewhat obsessive about not having things break “all the time”, so I’m very skeptical of things that rely on many “fragile” elements. The more scripts, glue and chewing gum needed to hold things together, the more fragile I consider it. And, let’s face it - even though we both are people that self-host stuff, most people don’t. Most people don’t have servers running throughout the house, that much I’ve learned about people :wink:

Really off-topic: I’ve test both ownCloud and Nextcloud, and I wasn’t a fan. I’m currently using Seafile - while it offers a lot less functionality, it does what it does more reliably and with fewer hurdles. I haven’t checked for “integrations” between Seafile and OH though, because I can’t quite see what benefit that could bring.

I’m not talking about figuring out how to do a simple configuration. This binding already has that, a hostname and a refreshInterval that can be configured and is used by the binding.

What I’m talking about, and where the need for debugging comes in, is to use the configuration for more “complex cases”, typically where it’s not about configuring the Thing handler itself, but the device. That’s where errors can be returned from the device, and the user needs to be informed if the configuration is working or not, or if some other setting must be set in conjunction etc. This is where I’ve figured out that I can use ConfigStatusProvider and ConfigStatusMessage to try to achieve that, but this must be tested as I go. To do that, I need the ability to modify the configuration from the UI and make sure that the binding reacts appropriately, sends the correct feedback etc., and that’s very hard to do with a read-only configuration.

I have quite a few Zwave devices, so I both use the binding and know this fairly well. I think this is very similar to what I’m talking about, to me it seems like the Zwave binding use the “configuration part of the UI” to actually configure the devices themselves. So, instead of, or in addition to, storing the configuration in OH, it sends commands to the devices to configure them accordingly. That’s exactly what I’m looking to do here with configuring the PID controller in the devices for example.

While there might also be other reasons, but to me, it looks obvious that the very limitation of making the whole configuration read-only if it’s file based, will prevent the use of file-based Things with ZWave. It will make them impossible to configure, exactly because OH core has “decided” that the whole configuration is uneditable if the thing is file-based. The same will be the case for this binding if I chose that solution.

I’d say that a more elegant solution was if the whole configuration wasn’t made read-only, but only those parameters that were specified in the Thing file. Or better, that there were some way to configure/tag a parameter when you make the binding that tells the framework that a particular parameter doesn’t have to be stored, the binding will store it in some other way (in the device for example), and can thus still be editable in the UI even if the Thing is file based.

I agree with that definition, most of the time it’s pretty clear if something should be a configuration parameter or a channel, from a user and use perspective. But, the “limitations” in OH core, which restarts the things for every configuration change, and that makes the whole configuration unmodifiable if it’s file based, throws some rocks in the cogs for that logic. To me, it seems like the scenario we’re talking about here, configuring the device itself, wasn’t really considered when this was designed.

I’m pretty sure that you’ll find quite a few bindings where you have channels that really should have been configuration parameters for this reason. That is the simplest way to “get around” this limitation, as long as the configuration parameters are independent. It gets harder when they aren’t independent of each other.

Some testing revealed something potentially useful: It seems that the Thing handler isn’t actually recycled, it’s not actually a new instance that is started. The framework simply calls dispose() and then initialize() on the existing instance. That probably means that information stored in class fields persist - which will make handling this easier. I don’t know if that’s always the case though, or if it depends on what the framework finds “convenient” at that moment.

I suspect the main part that is differnet is the risk calculation. I heavily weigh opportunity costs in addition to the risk of something failing.

But for the record, I’m rarely rushing around fixing things. My whole environment is pretty stable. Maybe once a quarter I’ll need to move a container around because it’s grown in resources and doesn’t fit on the machine it’s running on anymore.

I don’t use Nextcloud for file storage really. I use the Calendar, Contacts, Chat, and a couple of other features. I use file sync the least, just a few things I might need on the go. Most of my file management stuff uses special purpose services:

  1. documents: PaperlessNG
  2. STLs and other 3D printing files: Manyfold
  3. Photos and Videos Storage: PhotoPrism
  4. eBooks: Calibre
  5. code: Gitea
  6. Calendar, contacts, recipies, file sharing with others, chat: Nextcloud
  7. Backup: NAS

For practical purposes I don’t see the difference.There is no distinction between a config that controls the behavior of the Thing or a config that gets sent out to the device to the end user nor to the UIs nor in .things files.

That’s what the Thing Status is for.

If, for example, I go and change the config for one of my things to be a bad configuration, once I hit save the Thing goes through some states until is settles on an ERROR state.

That’s where you’ll report the feedback to the end user.

You will only and ever be able to modify config parameters on a Thing if that Thing was create in the UI in the first place. You will never be able to set any parameters on a Thing from a .things file.

PRs are always welcome. File based configs are somewhat contentious. There was an aborted attempt to normalize the formatting so what you see in the code tab matches what you’d put in a .things file (e.g.) which would greatly facilitate moving between file based configs and managed configs. But the perfict became the enemy of the good enough and the effort was aborted.

As it stands, there is no such thing as a writer for the OH file based configs and XText is particularly hard to work with so much so that over the decade that OH has been around no one has even attempted to create a writer.

But your proposed solution is not too far from how Item metadata works and I can say that it’s not really that elegant in practice. Orphaned metadata is only one of the problems.

:+1:

That’s a lot more elaborat than my setup. Different needs I guess. I still have my Nextcloud VM running, but it’s not being used and I plan to just rescue whatever data is in there and delete it.

I don’t think you understand what I mean. I’ll try to explain again.

First, if there’s an issue with the configuration that causes the Thing to not work properly, this binding already use the updateStatus() mechanism for that:

That doesn’t need any further testing/debugging and isn’t a problem for me.

What I want to do is to also use the configuration for a slightly different purpose - to configure the device itself. For a Mill heater, that means things like configuring the control parameters for the PID algorithm that governs the heating power, or configuring the parameters for when the device should “detect” that a window is open, and how it should respond, like turning off for a given period etc.

This “configuration” will not need to be stored in OH itself, it will instead be sent to the device directly and stored there. This is where I feel that there’s a need to give some more detailed feedback, and it should be done without taking the Thing offline.

There already is a mechanism for this in OH, ConfigStatusProvider and ConfigStatusMessage. It looks like this when used:

The idea here is that if there’s a problem with the configuration parameter, it won’t be stored in the device - so the user should know and be given the opportunity to correct it.

OH also already offers the possibility for the binding to create additional configuration parameters “dynamically” - that is, programmatically as needed. So, these configuration parameters won’t reside in the thing.xml file, they will be created by the binding when the capabilities of the device has been established. If the device doesn’t support setting a certain parameter, it will never show up in the UI’s configuration section. This is also already there and works just fine as far as I can tell.

The problem I face is two-fold:

  1. When developing OH from Eclipse using the “demo.app” (the documented way), Things that are managed doesn’t work. They stay forever in NOT_YET_READY status, except when they are first created. As soon as you have to restart the debugging, they are “dead” - and can’t even be removed except by editing the JSON DB manually. Creating a new Thing for every launch, including configuring it, is extremely inconvenient. You are thus effectively “forced to” use file-based things when developing using “demo.app” because unlike managed Things, file-based Things actually work.
  2. Because a design decision has been made in OH at some stage that the whole configuration is read-only if the Think is file-based, it’s not even possible to fill in the configuration parameters that are created programatically. Even though they don’t need to be saved in the Thing file.

So, to develop and test using this feedback system and “dynamic configuration parameters” I MUST use a managed Thing - but the bug in OH core maks that impossible. This is the dilemma I’ve been trying to describe.

I think the bug should be fixed regardless, there could be many other reasons why people need to use managed Things when developing in Eclipse, but it’s a particular problem for me in this situation. In addition, I think it would be nice it the whole configuration wasn’t “locked” just because the Thing was file-based, which is where my suggestion came in. If it stays like it is, it effectively means that any Thing that use “dynamic configuration parameters” CANNOT use file-based definitions.

I can’t make PRs remember :wink:

It’s a shame that the effort to “improve” the file-based configurations, I like the fact that they are read-only and can’t be “corrupted” from the UI, but that’s not directly related to the challenge I face here. I’m not suggesting that there should be a writer for file-based configs, in fact I think that one take away one of their foremost benefits (immutability).

I don’t know how Item metadata works, but I’m not sure I managed to communicate my suggestion sufficiently. My “suggestion” would give no opportunity for orphaned data. In short, I would like for there to be configuration parameters that OH does not store - not in the Thing file, not in the JSON DB or anywhere else. The binding would have the responsibility to store the data, if at all relevant. In the use-case I have in mind, you would use these configuration parameters to configure the device itself, and the binding would fetch and populate these parameters during initialization. They would thus not have to be persisted by OH or the binding.

OK, in that case I can’t offer any advice or help. I don’t do OH add-on development so can offer no more on that front except comiseration.

I do spend a whole lot my my contributions to OH helping end users so have a somewhat informed ability to coment on how certain approaches impact end users.

I agree the bug should be fixed.

Since you are unwilling to contribute such a PR :man_shrugging: . The amount of effort to make these changes would be somewhat significant. You’ll have to find someone willing to volunteer to take it on.

I remember but am making a poiint that you can have the best ideas in the world but if you can’t or won’t volunteer to do it, it basically amounts to navel gazing.

There is a separate registry that stores Item metadata. Item metadata is how configuration stuff related to the Item is stored (e.g. state description, default MainUI widgets, expire configurations, etc). They are stored separately from the Item and therefore even if an Item is read only because it’s file based, metadata can be added to the Item through the UI.

I don’t ask the questions just to you. That said, I think you’ve given me the answer to quite a few of the things I’ve wondered, so your knowledge has absolutely been helpful. I generally have an easier time figuring out the “coding details” than I have figuring out structure, logic, relationships etc.

I’d just like to state once again that I am not unwilling. I’m unable without compromising what for me is a very important principle. And, from my point of view, without good reason.

I have no problems with the CLA itself, there is nothing particularly “secret” about me or my identity. But I strongly believe that the trend of all kind of information being collected by big companies and stored in databases is a very bad one. How this can be abused is a huge topic with many variants, but I think the bombing of homes in Gaza based on “AI processing” of such collected data is a very good example of why this should not be allowed.

As a consequence, I live by the rule that I don’t give information that’s not needed for whatever the task is. In addition to that, I go a long way to prevent identifying data ending up in search engines. I don’t think this should only apply to me, in fact it has very limited effect if only I do it, but I can’t decide what others do. I just have to do what I think is right, and advocate for it when I get the chance. I am appalled by how careless most people treat their information these days, I don’t quite understand what - or if - they are thinking.

As I’ve said before, I think posting full name and e-mail addresses on public forums, in Git repositories etc. breaks important principles. In addition, I question the “legal validity” of such a textual signature anyway, as I can claim to be Elvis Presley if I so want to and nobody can really verify that. If there’s a way I can sign the CLA that doesn’t result in publicizing my personal identifiable information, I’ll do so in a heartbeat.

So, whatever you choose to call it, please refrain from calling it unwilling because that simply isn’t true.

All that said, in this particular case, I don’t think it would help much if the CLA issue wasn’t there. The reason is that I wouldn’t feel comfortable modifying these things without knowing a lot more about both Core and the UIs. It doesn’t sound like it would be a big change to me, in principle, but since I don’t know how things are actually implemented, that could be completely wrong. In any case, it would need UI support to work. It’s simply well beyond something I could accomplish without investing a lot of time to get to know the inner details.

So, when I make such a suggestion, it isn’t a request. I know that this most likely will never be implemented, and I certainly know that it won’t be implemented in time for this binding to finish. It is an idea of a way I think I see that could solve some issues that I’m sure applies much more broadly than this binding in particular. As I see it, it would help “bridge the gap” between Channels and configuration parameters. My whole purpose with making such a suggestion is that maybe, if I’m really lucky, somebody else has a problem that could also be solved by this or something similar, now or in the future, and that my “suggestion” can contribute as an input to solve the problem.

I see how “mixing the two systems” can lead to orphans. It’s hard to judge if the number of such orphans would “grow” to be a significant problem, but I don’t like waste in general, so I see the problem. One could make some kind of manually triggered “cleanup” that deleted metadata for all Items that wasn’t currently registered, either “managed” or file-based. But, it would still require users to know about the problem and to know that this function existed, so it’s far from ideal. My suggestion don’t involve storing anything outside the Thing file, thus it wouldn’t have this problem.

Just for information, I discovered that it’s easy to prevent the dispose()/initialize() cycle on configuration updates by overriding BaseThingHandler.handleConfigurationUpdate(). This makes handling configuration changes “smoother”, with no need to take the Thing offline each time.

I specifically said “can’t or won’t”. That covers both being unwilling and unable for whatever reason.

It’s enough of a problem for Links which are also stored separately from the Item and the Channel that automatic checks and automatic cleanups had to be added. Periodically OH scans for orphaned links and will bring up a warning in MainUI if some are found.

Item metadata will just build up though if you ever reuse an Item name in the future, that orphaned Item metadata will pop right back up and apply to that Item. That should be a rare occurance.

Because of the way OH manages file based Items though, it can’t just delete the metadata when the Item is deleted because when using file based Items, all Items get deleted when the file is reloaded. So in that case, every time you edit a .items file, all that Item’s metadata would get deleted.

I referred to this sentence:

I see the situation. You could get around it by not using item name as the unique identifier/primary index, but a generated one for managed Items. The identifier could be made so that it would always be the same for file based Items (based on the path or whatever). But, this can also be seen as a “feature”. If you need to delete and recreate an Item for some reason, or you end up deleting it by mistake, it’s very convenient that the metadata are still there as soon as you recreate the Item.

But yeah, it’s not easy to make things be optimal for all scenarios.

I might have misunderstood what kind of metadata you both are talking about, but in general, metadata can be defined in .items files as well.

Group gCorridorFirstfloor "Corridor 1.OG" <corridor> (gFirstFloor) ["Corridor"] {uiSemantics="uiSemantics"[preposition=" im", equipment="Corridor", location="Obergeschoss"],widgetOrder="22"}

This adds the custom metadata uiSemantics and the default widget order. You can add other metadata as well, if you get the syntax right.
Unfortunately, this will make the defined metadata read only in the UI.

Indeed. But in that case, the metadata gets deleted along with the Item and recreated on a . items file reload. If you stick to .items files exclusively there are no left overs. But if you mix .items files with UI added metadata, that cleanup doesn’t happen.

In general, if it’s defnied in a text config file, upon unload what ever the entity is gets destroyed. Upon load the entity gets created anew. This goes for Links and Metadata also even though these get defined in the .items file only.

Where it gets complicated is when, for example, the Items are defined in the .items file but the Links and Metadata are created through the UI. This mix of managed and unmanaged configs gets complicated. OH cannot tell the difference between the Items being deleted because it was deliberately removed or because the .items file was merely edited and reloaded, so it can’t really clean up those managed configs for that Item; the Item might come back really soon.

Of course, but don’t we advise people not to mix file configs with managed configs.:wink: