Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Archived » Eclipse SmartHome » Dynamically created Channels during initialize()(Is this allowed?)
Dynamically created Channels during initialize() [message #1716799] Tue, 08 December 2015 10:05 Go to next message
Karel Goderis is currently offline Karel GoderisFriend
Messages: 198
Registered: March 2014
Senior Member
I have a binding where, in the initialize() method, I do have the following code:

                    ThingBuilder thingBuilder = editThing();
                    ChannelTypeUID triggerUID = new ChannelTypeUID(BINDING_ID, IO_TRIGGER);

                    Map<String, String> channelProperties = new HashMap<String, String>();
                    channelProperties.put("type", aPort.type);

                    Channel channel = ChannelBuilder
                            .create(new ChannelUID(getThing().getUID(), "io" + aPort.port), "Switch")
                            .withType(triggerUID).withProperties(channelProperties).build();
                    thingBuilder.withChannel(channel);
                    updateThing(thingBuilder.build());


It seems that Handlers, executing that code, stay in the INITIALIZING state. The following (or similar) gets logged

2015-12-08 10:34:58 [WARN ] [.c.c.r.AbstractManagedProvider:138 ] - Could not update element with key helios:ipvario213:prive in ManagedThingProvider, because it does not exists.

so, is this a bug, or is it now allowed by design to call updateThing() within Initialize()?

Karel
Re: Dynamically created Channels during initialize() [message #1717082 is a reply to message #1716799] Wed, 09 December 2015 20:45 Go to previous messageGo to next message
Karel Goderis is currently offline Karel GoderisFriend
Messages: 198
Registered: March 2014
Senior Member
No one? Wink
Re: Dynamically created Channels during initialize() [message #1717167 is a reply to message #1717082] Thu, 10 December 2015 12:05 Go to previous messageGo to next message
Karel Goderis is currently offline Karel GoderisFriend
Messages: 198
Registered: March 2014
Senior Member
IMO calling updateThing(), will trigger eventually thingUpdated() in ThingManager, which in turn will then trigger the following code in BaseThingHandler

@Override
public void thingUpdated(Thing thing) {
dispose();
this.thing = thing;
initialize();
}

So, during initialize(), the ThingHandler is disposed again, keeping it in the UNINITIALIZED state. That means that effectively, it is not recommended/allowed to call updateThing() during initialize() at all, which could be counterintuitive, as normally, during initialise() you could already be reading data from a device, and thus setup additional channels if required.

Am I right that the solution lies into overriding postInitialize() to do any additional updates to the Thing?
Re: Dynamically created Channels during initialize() [message #1717194 is a reply to message #1717167] Thu, 10 December 2015 16:25 Go to previous messageGo to next message
Karel Goderis is currently offline Karel GoderisFriend
Messages: 198
Registered: March 2014
Senior Member
This is a bug - see https://github.com/eclipse/smarthome/issues/713
Re: Dynamically created Channels during initialize() [message #1718011 is a reply to message #1717194] Fri, 18 December 2015 14:27 Go to previous messageGo to next message
Kai Kreuzer is currently offline Kai KreuzerFriend
Messages: 673
Registered: December 2011
Senior Member
Hi Karel,

Sorry for not answering earlier (the problem is that I seem to be still the only one answering here...)

I assume the behavior is different depending on whether the thing is defined in a file or if it is stored in the database (through the managed provider). As discussed in the past, it is only possible to update the thing structure for things that are NOT statically defined in a *.things file.

Regarding the lifecycle behavior: A colleague is currently working on a major refactoring of this, which will remove methods like postInitialize() completely. I would suggest to wait a few more days for his pull request and see if this makes things better in general.
Re: Dynamically created Channels during initialize() [message #1718021 is a reply to message #1718011] Fri, 18 December 2015 15:28 Go to previous messageGo to next message
Karel Goderis is currently offline Karel GoderisFriend
Messages: 198
Registered: March 2014
Senior Member
Kai Kreuzer wrote on Fri, 18 December 2015 09:27
As discussed in the past, it is only possible to update the thing structure for things that are NOT statically defined in a *.things file.


Ok, but that is *really* quite a limitation then. Any chance that this will change in the future? If not, then dynamic device feature discovery is really out of the window.....

K

ps. At least, this aspect is not clear in the current dev. documentation, but I guess we do not want to bother you to write up that topic in the documentation? Wink
Re: Dynamically created Channels during initialize() [message #1718043 is a reply to message #1718021] Fri, 18 December 2015 17:20 Go to previous messageGo to next message
Kai Kreuzer is currently offline Kai KreuzerFriend
Messages: 673
Registered: December 2011
Senior Member
> Any chance that this will change in the future?

If you come up with a good solution to the problem? How would you update something that comes from a read-only source?
I see mainly 4 options:
1. Once there is an interactive update, store the thing in the database and take that as a reference from now on. Problem: The thing defined in the file won't be regarded anymore, which might be confusing for the user
2. We do not "provide" the information from the file, but rather "import" them - i.e. at startup, they are read and written to the database, the files could be deleted then. Any update would only be possible through the UIs - that's a no go for me...
3. We could go and make the Xtext-DSL files writable for the system; this is possible through Xtext, but I fear it could be quite some effort. Since we rather planned to have ESH also work without Xtext at runtime (since it is a bit over-sized for parsing some config files), this is something I am not at all keen on.
4. We could come up with a different parser/serializer implementation, possibly even in the form of a StorageService as a replacement for MapDB. This could write human-readable files, which could be similar (or even equal) to the current syntax.

If you ask me, I think 4 is the best option. But it also means implementing our own parser/printer for the current DSLs as well as implementing our own database (with lazy writing to the file-system, locks, rollbacks and whatever is needed to get it performing well and stable...)

Just my 2 cents,
Kai
Re: Dynamically created Channels during initialize() [message #1718069 is a reply to message #1718043] Fri, 18 December 2015 21:03 Go to previous messageGo to next message
Karel Goderis is currently offline Karel GoderisFriend
Messages: 198
Registered: March 2014
Senior Member
mmh... your vision is going much farther than I had in mind, but I understand your positions because of the application domain you have in mind (e.g. your efforts at DT.de). Now, for one, I never considered the .things to be read/write, in the sense that they are read once at startup (or after a change), and then discarded/neglected, used to instantiate your things. But then afterwards the ThingHandlers can expand the Things based on what they discover in the real world. After a reset of the runtime, they rather repeat their discovery (since, the hardware represented by the Thing would be the same), rather than reading the previous discovery from a database. It is more in the sense that you have dynamically added channels that require no user intervention for further configuration, but that are rather deterministic in nature because you know the hardware in advance. In the example above in the first post, it is for example a physical port on the device that is always of the same nature. You could argue :"why do you want it to be dynamic?". Well, in the use case, it is the Helios IP Videophone, which has an internal web server to configure it, and in this example, the port can be enabled or disabled through that web server, so, you do not know in advance if the port will be present or not.

Karel.
Re: Dynamically created Channels during initialize() [message #1718216 is a reply to message #1718069] Mon, 21 December 2015 11:28 Go to previous messageGo to next message
Kai Kreuzer is currently offline Kai KreuzerFriend
Messages: 673
Registered: December 2011
Senior Member
Quote:
It is more in the sense that you have dynamically added channels that require no user intervention for further configuration, but that are rather deterministic in nature because you know the hardware in advance.


It would be of course possible to allow changes that are not persisted and only live in memory. But the problem with this is that if you restart your runtime and your Thing is not accessible for some reason, you won't be able to update the information dynamically. You will hence only see the persisted information and thus your binding (and user) must be able to handle that circumstance. And it would be difficult to understand, what kind of changes get persisted and which aren't. I think this might lead to many problems, especially for the UX. Hence we need some way of persistence and I don't see many other options than the ones mentioned.
Re: Dynamically created Channels during initialize() [message #1718221 is a reply to message #1718216] Mon, 21 December 2015 12:42 Go to previous messageGo to next message
Andre Fuechsel is currently offline Andre FuechselFriend
Messages: 28
Registered: December 2015
Junior Member

Kai Kreuzer wrote on Mon, 21 December 2015 11:28

It would be of course possible to allow changes that are not persisted and only live in memory.


Is it really all or nothing? We could think about having something like transient configuration properties or channels, making it clear to the user, that these will never be persisted. So you would be able to dynamically changes things during runtime, but you could never rely on the transient features that they are available or not, because you never know, if there was a restart in between.
Re: Dynamically created Channels during initialize() [message #1718419 is a reply to message #1718221] Wed, 23 December 2015 13:54 Go to previous messageGo to next message
Karel Goderis is currently offline Karel GoderisFriend
Messages: 198
Registered: March 2014
Senior Member
Since we always strived to have a Thing represent a physical object as much as possible, I think that persisting everything about a Thing is not a final solution either. I mean, we already have Discovery in place, which is about discovering the Thing in the first place, but it many cases does also a kind of "feature" discovery of the physical device. Sometimes the feature discovery is done by the Handlers. So, for me (and maybe I am not that much UI driven here), but I could perfectly accept that basic information about a Thing is persisted, in order to forego lengthy discovery procedures (if these already exist), and so forth, and then have the Handlers complete the Thing configuration based on what they find in the real world.

Then even, there will always be glitches in any system. If you persist everything, and you physically replace for example a faulty device, or upgrade it hw-wise, or alike, the persistent configuration will not match the physical device. Or, if you do a firmware upgrade of a device, and it does not have the same feature set anymore, don't you want to have the Handler adapt to that new situation?

I can also not envision a world whereby you would define for every possible configuration-combination of a device a new ThingType. That is insane.

Karel
Re: Dynamically created Channels during initialize() [message #1719645 is a reply to message #1718419] Sun, 10 January 2016 23:40 Go to previous messageGo to next message
Dan Cunningham is currently offline Dan CunninghamFriend
Messages: 44
Registered: March 2014
Member
I understand the need for flat files support for OH1 bindings and such, but I wondering how much this is needed for pure ESH/OH2 binding configurations. I know there are strong feelings about being as configurable as possible, especially for devs and power users, but I worry about new users and non developer types. My personal opinion is that having a DB persisted configuration with API access is the far superior choice to the flat file schema of the OH1 days. Would it be possible for bindings to only support this type of configuration backend going forward?

I'll put on my flame retardant suite now Wink
Re: Dynamically created Channels during initialize() [message #1719710 is a reply to message #1719645] Mon, 11 January 2016 15:55 Go to previous messageGo to next message
Kai Kreuzer is currently offline Kai KreuzerFriend
Messages: 673
Registered: December 2011
Senior Member
> We could think about having something like transient configuration properties or channels, making it clear to the user, that these will never be persisted.

So you let the user change configurations on things and channels and he should be fine that all was in vain after a restart? I am not sure how you will be able to convince your users that this a good feature.

> I can also not envision a world whereby you would define for every possible configuration-combination of a device a new ThingType. That is insane.

Nobody said that this is a goal, not at all. The discussion is only about persisting changes to the structure, isn't it?

> My personal opinion is that having a DB persisted configuration

Are you still of the opinion when you read that newer MapDB versions are not backward compatible to the old format? So after a system upgrade, you might end up with a big binary file that you cannot read, edit or use in any way and you can build your system from scratch again... That's why I would very much prefer to go for option 4 before relying purely on a database.

> Would it be possible for bindings to only support this type of configuration backend going forward?

Well, the bindings should in any case be able to handle exceptions if they try to do an update of the thing, but fail. So in general, supporting the case that a thing (from DSL) is exactly as the handler expects it and no changes to it are necessary, should be fairly straight forward and no additional burden, right?
Re: Dynamically created Channels during initialize() [message #1719736 is a reply to message #1719710] Mon, 11 January 2016 18:02 Go to previous messageGo to next message
Dan Cunningham is currently offline Dan CunninghamFriend
Messages: 44
Registered: March 2014
Member
Kai Kreuzer wrote on Mon, 11 January 2016 15:55
>

> My personal opinion is that having a DB persisted configuration

Are you still of the opinion when you read that newer MapDB versions are not backward compatible to the old format? So after a system upgrade, you might end up with a big binary file that you cannot read, edit or use in any way and you can build your system from scratch again... That's why I would very much prefer to go for option 4 before relying purely on a database.

Well the MapDB does not sound very appealing at all, so yes number 4 sounds better. In the end I don't really care what the DB looks like ( traditional or a bunch of files) as long as its safe and the access to it is through the runtime and the runtime can modify them. We are about to have a bunch of new users come over now that 1.8 is out and 2.0 becomes the focus, and my guess is that the auto discovery (inbox) and live configuration of ESH will be very exciting to users and devs (it is to me!). But given the MapDB trouble, I would say auto discovery is not advisable at all, is this not the case?

Kai Kreuzer wrote on Mon, 11 January 2016 15:55
>
> Would it be possible for bindings to only support this type of configuration backend going forward?

Well, the bindings should in any case be able to handle exceptions if they try to do an update of the thing, but fail. So in general, supporting the case that a thing (from DSL) is exactly as the handler expects it and no changes to it are necessary, should be fairly straight forward and no additional burden, right?


I very much want to support both, and it does handle the exception, but the binding becomes not useful without its channel.
Re: Dynamically created Channels during initialize() [message #1719836 is a reply to message #1719710] Tue, 12 January 2016 14:10 Go to previous message
Karel Goderis is currently offline Karel GoderisFriend
Messages: 198
Registered: March 2014
Senior Member
Kai Kreuzer wrote on Mon, 11 January 2016 10:55
>

> My personal opinion is that having a DB persisted configuration

Are you still of the opinion when you read that newer MapDB versions are not backward compatible to the old format? So after a system upgrade, you might end up with a big binary file that you cannot read, edit or use in any way and you can build your system from scratch again... That's why I would very much prefer to go for option 4 before relying purely on a database.


I agree, and preferably a system whereby you can roll-back changes (even if this means copying over files). MapDB is really problematic, as I discovered in my recent coding. It is not only not readable, you only have 1 file for different storage entities, so one cock-up in a bundle can negatively influence other parts if you have to recover by using a backup of the db file.

Since we already serialise a lot for MapDB, ideally it would have to be some service that cranks out json. I am not sure how you can get that part performing well (e.g. large files), and wether you have to cache stuff. I have read on MapDB a long time ago, but did not offer a way to create other storage type plugins? not sure anymore.
Previous Topic:Adding dynamic channels to a manually defined thing
Next Topic:How do I build so I can test the UI
Goto Forum:
  


Current Time: Thu Apr 18 01:32:46 GMT 2024

Powered by FUDForum. Page generated in 0.02448 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top