-
Notifications
You must be signed in to change notification settings - Fork 783
Profile API improvements #4516
Profile API improvements #4516
Conversation
e860e1e
to
9675aa4
Compare
This pull request has been mentioned on openHAB Community. There might be relevant details there: https://community.openhab.org/t/enocean-bindings-opencean-or-aleoncean/12493/57 |
9675aa4
to
5dbb680
Compare
* Simplified the API for implementing profiles (at the price of a little more complexity on CommunicationManager side) * Allow implementing profiles without exposing Items and ItemChannelLinks to bindings * Maintain backward-compatibility by making the default master profile forward handleUpdate() calls to ThingHandlers again * Exposing constants in SystemProfiles * Allow for easier evolvement of the API * Having the ProfileCallbacks requires less code within profiles and therefore eliminates the need to export the default profiles for inheritance. Signed-off-by: Simon Kaufmann <simon.kfm@googlemail.com>
5dbb680
to
c25e449
Compare
} | ||
|
||
public void removeProfileAdvisor(ProfileAdvisor profileAdvisor) { | ||
profileAdvisors.remove(profileAdvisor); | ||
public void removeProfileAdvisor(ProfileTypeRegistry profileTypeRegistry) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function and the addProfileAdvisor function should probably be renamed, right?
public static final TriggerProfileType RAWBUTTON_TOGGLE_SWITCH_TYPE = new TriggerProfileType() { | ||
@Override | ||
public ProfileTypeUID getUID() { | ||
return SLAVE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrong UID
} | ||
|
||
private boolean isSupportedChannelType(ProfileType profileType, Channel channel) { | ||
return profileType instanceof StateProfileType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
profileType instanceof TriggerProfileType
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No I think that StateProfileType is what is meant here, but I don't quite understand why a StateProfileType would always support all ChannelTypes. Could there not be profiles that only support a specific channel type?
/** | ||
* Constant for mathing *ANY* item type. | ||
*/ | ||
public static final Collection<String> ANY_ITEM_TYPE = new ArrayList<>(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a minor notice:
We can declare variables in Java interfaces. By default, these are public, final and static.
So, no need to add the default modifiers.
* @author Simon Kaufmann - initial contribution and API. | ||
* | ||
*/ | ||
public interface SystemProfiles { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comments about default modifiers as above.
/** | ||
* Constant for mathing *ANY* channel type. | ||
*/ | ||
public static final Collection<ChannelTypeUID> ANY_CHANNEL_TYPE = new ArrayList<>(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see above (default modifiers)
|
||
private boolean isSupportedChannelType(ProfileType profileType, Channel channel) { | ||
return profileType instanceof StateProfileType | ||
|| ((TriggerProfileType) profileType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While it is currently the case that usually profiles fall within the StateProfileType or the TriggerProfileType group, it would make sense to check if the profile type is an instance of TriggerProfileType here anyways in order to make sure we dont get a problem here later, in case other types are added.
Signed-off-by: Simon Kaufmann <simon.kfm@googlemail.com>
Signed-off-by: Simon Kaufmann <simon.kfm@googlemail.com>
I might have done something wrong, but a working item definition that used the rawbutton channel and a toggle profile stopped working after I merged this patch. |
Signed-off-by: Simon Kaufmann <simon.kfm@googlemail.com>
Thanks, I will have a look. |
What does your item definition look like? |
@@ -107,7 +107,7 @@ private boolean isSupportedItemType(ProfileType profileType, Item item) { | |||
} | |||
|
|||
private boolean isSupportedChannelType(ProfileType profileType, Channel channel) { | |||
return profileType instanceof StateProfileType | |||
return profileType instanceof TriggerProfileType |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This must be wrong now. It would now always return true if profileType is of type TriggerProfileType. That would mean that the rest of the condition is superfluous.
Signed-off-by: Simon Kaufmann <simon.kfm@googlemail.com>
...from master/slave to default/follow Signed-off-by: Simon Kaufmann <simon.kfm@googlemail.com>
Signed-off-by: Simon Kaufmann <simon.kfm@googlemail.com>
Thanks for being compliant with me! 😄 If I get this right there is no need for another ProfileCallback implementation right now (Profiles alone "should" be enough for information flow)? LGTM! |
How do you want to deal with
in ThingManager? I think we should either stay backward-compatible by forwarding handleUpdate() calls (and therefore cancel deprecation?) or drop support for handleUpdate() completely before 1.0. Best regards |
@SJKA I don't have the code at work atm. But it looks something like this: |
That's why I've been asking... It should read |
Right My mistake. So It if the ProfileTypeUID didnt change, then it is still the correct string, being "system:rawbutton-toggle". It did work yesterday before the merge and I was happily toggling my lights. I just made a mistake right now. So I had a working item, and now it no longer works. The exact same message was also printed for my custom enocean profile that I wrote, linked to my custom trigger channel. But that might have potentially other reasons that are unrelated, since this profile didn't work before the merge. |
No, my initial post was wrong (and I corrected it immediately, but that doesn't send out notification mails). The profile ID indeed has changed and got a |
-> to be discussed in #4525. |
Signed-off-by: Simon Kaufmann <simon.kfm@googlemail.com>
After I appended the -switch to the profile name, the toggle profile worked again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a huge simplification for profile implementors (as can be seen at the RawButtonToggleSwitchProfile
).
Some small remarks on the code below.
|
||
@Override | ||
public void onUpdate(State state) { | ||
this.previousState = state; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can omit "this" here (as you do in onTrigger as well)
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* This is the default implementation for a slave profile. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
slave -> follow
* In contrast to the {@link SystemDefaultProfile} it does not forward any commands to the ThingHandler. Instead, it | ||
* turn {@link State} updates into {@link Command}s (if possible) and then forwards those to the {@link ThingHandler}. | ||
* <p> | ||
* This allows devices to be operated as "slaves" of another one directly, without the need to write any rules. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
slaves -> followers
} | ||
|
||
@Override | ||
public Collection<@NonNull ProfileType> getAll() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of using @NonNull
here, shouldn't you use @NonNullByDefault
on the class?
* | ||
* @param command | ||
*/ | ||
void sendCommandEvent(Command command); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove the word "Event" here - after all, you are sending a command, not an event.
* | ||
* @param state the new {@link State} | ||
*/ | ||
void onUpdate(State state); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe better onStateUpdate
?
* | ||
*/ | ||
@NonNullByDefault | ||
public interface ProfileTypeProvider extends Provider<ProfileType> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this provider rather be similar to ThingTypeProvider
etc., i.e. specifically able to provide a profile type for a given locale (such that its label is localisable)?
@@ -19,6 +21,7 @@ | |||
* @author Simon Kaufmann - initial contribution and API. | |||
* | |||
*/ | |||
@NonNullByDefault | |||
public interface Profile { | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect to have a ProfileTypeUID getProfileTypeUID();
method here.
|
||
@Override | ||
public void addProviderChangeListener(ProviderChangeListener<@NonNull ProfileType> listener) { | ||
// TODO Auto-generated method stub |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
replace or delete comment
|
||
@Override | ||
public void removeProviderChangeListener(ProviderChangeListener<@NonNull ProfileType> listener) { | ||
// TODO Auto-generated method stub |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
replace or delete comment
* renamed profile methods * made provider/registry obey obey localization by following the example of ThingTypeProvider * fixed a bug in the provider registration * fixed several typos Signed-off-by: Simon Kaufmann <simon.kfm@googlemail.com>
@@ -24,4 +25,13 @@ | |||
@NonNullByDefault | |||
public interface Profile { | |||
|
|||
ProfileTypeUID getProfileTypeUID(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you also spend it a single line of JavaDoc? :-)
I see several non-null violations
|
Related to: #4516 (comment) Signed-off-by: Markus Rathgeb <maggu2810@gmail.com>
Having had some first feedback and some chats with @kaikreuzer, it obviously made sense to rework and simplify the profile API at some points. This is the current result.
(at the price of a little more complexity on CommunicationManager side)
to bindings
forward handleUpdate() calls to ThingHandlers again (see also CommunicationManager & DefaultMasterProfile : linking items through channels not supported by default #4464 (comment))
eliminates the need to export the default profiles for inheritance.
Although this technically is APIBreaking (and therefore adding the corresponding label), there cannot yet exist a productive usage of this API, therefore I don't see any risks involved here.
Signed-off-by: Simon Kaufmann simon.kfm@googlemail.com