-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[knx] Mods to enable the KNX ‘ETS’ Binding #3500
Conversation
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.
Here are a few comments while I casually scrolled through the code. :-)
return Collections.unmodifiableSet(new HashSet<>(Arrays.asList(values))); | ||
} | ||
|
||
protected abstract @NonNull Set<@NonNull String> getAllGAKeys(); |
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 should annotate the class with @NonNullByDefault
and use @Nullable
where needed.
See also the ESH documentation.
/** stores the default Item Type to use for each openHAB type */ | ||
private final Map<Class<? extends Type>, Class<? extends GenericItem>> defaulItemTypeMap; | ||
|
||
private HashMap<Class<? extends GenericItem>, String> itemTypeStringMap; |
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.
Can you change the type from HashMap to Map here?
@@ -116,6 +131,9 @@ public KNXCoreTypeMapper() { | |||
|
|||
dptTypeMap = new HashMap<String, Class<? extends Type>>(); | |||
dptMainTypeMap = new HashMap<Integer, Class<? extends Type>>(); | |||
defaultDptMap = new HashMap<Class<? extends Type>, String>(); | |||
defaulItemTypeMap = new HashMap<Class<? extends Type>, Class<? extends GenericItem>>(); | |||
itemTypeStringMap = new HashMap<Class<? extends GenericItem>, String>(); |
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.
Can you use the diamond operator here?
* | ||
* @author Karel Goderis - Initial contribution | ||
*/ | ||
public enum LoadState { |
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.
Is this Enum used? I couldn't find any references to it.
I re-added this as it got lost during the refactoring into the basic binding. There are a few other classes that are part of the knx spec that are already in the basic binding and that will serve for any follow up binding
…Sent from my iPhone
On 21 Apr 2018, at 09:03, Wouter Born ***@***.***> wrote:
@wborn commented on this pull request.
In addons/binding/org.openhab.binding.knx/src/main/java/org/openhab/binding/knx/internal/handler/LoadState.java:
> +/**
+ * Copyright (c) 2010-2018 by the respective copyright holders.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.openhab.binding.knx.internal.handler;
+
+/**
+ * Enumeration containing the load states
+ *
+ * @author Karel Goderis - Initial contribution
+ */
+public enum LoadState {
Is this Enum used? I couldn't find any references to it.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or mute the thread.
|
L5(5, "Load Completing"); | ||
|
||
private int code; | ||
private String name; |
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.
@kgoderis I was searching for uses of this Enum to find out how the name
property was used. The name
property and getName(..)
methods of this Enum are confusing because an Enum already has a .name()
method. Maybe the property can be renamed to something else so there will be no confusion?
Signed-off-by: Karel Goderis <[email protected]>
@SJKA Simon, any thoughts on this PR? |
return defaulItemTypeMap.get(toTypeClass(dpt)); | ||
} | ||
|
||
public String toItemType(String dpt) { |
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 is neither part of the public API (i.e. interface) nor is it used internally. Therefore this method is dead code and can be deleted.
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.
It is used in the advanced binding, and in that context its natural place is in the KNXCoreTypeMapper (it can be potentially be used by other knx binding derivaties), but if it is really an issue I will put it in an inheriting class.
return defaulItemTypeMap.get(typeClass); | ||
} | ||
|
||
public Class<? extends GenericItem> toItemTypeClass(String dpt) { |
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.
dead code - see below
@@ -534,6 +551,25 @@ public KNXCoreTypeMapper() { | |||
defaultDptMap.put(DateTimeType.class, DPTXlatorTime.DPT_TIMEOFDAY.getID()); | |||
defaultDptMap.put(StringType.class, DPTXlatorString.DPT_STRING_8859_1.getID()); | |||
defaultDptMap.put(HSBType.class, DPTXlatorRGB.DPT_RGB.getID()); | |||
|
|||
defaulItemTypeMap.put(DateTimeType.class, DateTimeItem.class); |
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 are effectively duplicating (partially) the information from acceptedItemTypes/acceptedCommandTypes here. Not sure if that's a good idea...
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.
In the advanced binding I do implement I use a ChannelBuilder to create Channels based on the information stored in the ETS5 files. ChannelBuilder::create() takes an acceptedItemType as input, which is provided by the defaulItemTypeMap you mention, and for which in turn the Key is provided by KNXCoreTypeMapper::toTypeClass() based on the DPT that is derived from the ETS5 data.
@@ -11,6 +11,8 @@ Import-Package: gnu.io;resolution:=optional, | |||
org.eclipse.smarthome.config.discovery, | |||
org.eclipse.smarthome.core.common, | |||
org.eclipse.smarthome.core.i18n, | |||
org.eclipse.smarthome.core.items, |
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 think we had this discussion a couple of times already: Bindings must be agnostic of items. Otherwise the whole functional abstraction won't work. So I hope you'll understand this won't pass without a single word of explanation?
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 https://github.com/openhab/openhab2-addons/pull/3500#discussion_r189028969
I do not use Items directly, but I need their class definitions for the TypeMapper.
} | ||
|
||
@Nullable | ||
protected abstract ChannelConfiguration parse(@Nullable String fancy); |
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.
The ChannelConfiguration
class is something internal to the "basic" KNX binding and therefore must not "leak" out of the API.
Most of the methods below have the same "issue": They are specific to the way the basic binding configures channels and therefore cannot reside in a commonly shared abstract class.
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.
My main objective was to re-use as much as possible existing classes without re-inventing the wheel. The only part that is specific for each binding is the parsing of the configuration String. In fact, in the advanced binding I do construct a configuration String based on ETS5 information that is similar (but not the same) as the basic binding's configuration Strings
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
*/ | ||
package org.openhab.binding.knx.internal.channel; |
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.
If you plan to extend it, then this must not be in an "internal" package. I don't think though this is a good idea at all (see below).
if (ga != null) { | ||
return new GroupAddress(ga.getGA()); | ||
} else { | ||
throw new IllegalArgumentException("GroupAddressConfiguration should contain a group address"); |
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.
Why did you change the signature to be @Nullable
and then throw a IAE in case null
is passed?
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 should revert this and do the null check before calling this. Underlying to this is that in the advanced binding there can be ChannelConfigurations that do not have a MainGA (toGroupAddress is called in ReadResponseSpecImpl)
@@ -26,10 +27,10 @@ | |||
public class ChannelConfiguration { | |||
|
|||
private final @Nullable String dpt; | |||
private final GroupAddressConfiguration mainGA; | |||
private final @Nullable GroupAddressConfiguration mainGA; |
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, that's a pretty fundamental assumption: the first one is the "main" GA - and IF there is a configuration, it MUST contain an address.
Are you maybe changing the meaning of "main GA"? Then please don't do so for the basic binding.
Actually, I don't think it is a good idea to reuse this class. Advanced binding(s) may make their own choices how a channels is configured. That's why this is in an "internal" package - it is internal to the basic binding.
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.
mmh.. It is related to https://github.com/openhab/openhab2-addons/pull/3500#discussion_r189029968 . Maybe some of the internal classes of the basic binding should be exposed in order to facilitate re-usage elsewhere.
if (expectedTypeClass != null) { | ||
logger.trace("The expected Type class for dpt '{}' is '{}'", dpt, | ||
expectedTypeClass.getSimpleName()); | ||
Type convertedType = convertType(command, configuration); |
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.
How is this related to the "ETS" binding? Aren't you changing the basic binding's behavior here?
Don't get me wrong, potentially this makes sense. I'm just not quite sure yet about the side-effects this might have. In any case, I'm just trying to understand the reason for this change.
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.
For the basic binding this function returns the Type is was fed without any modification. In the advanced binding I overload it to do something meaningful. See for example TypeRollerShutter.java on how I do use this functionality.
@@ -26,12 +28,13 @@ | |||
private final Type type; | |||
private final @Nullable GroupAddress groupAddress; | |||
|
|||
private final Logger logger = LoggerFactory.getLogger(WriteSpecImpl.class); |
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.
what do you need this one for?
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.
Debugging artefact. It should be removed indeed
@kgoderis, the review of sjka is complete. I personally think that without extensions in the basic binding, we will not get along. Duplication of source code is much more complicated and error-prone. I would suggest to mark the parts required for extensions. A short Comment with the reason in the places as a dead code appear and in the classes which should not be internal. That would be the easiest way to get ahead? |
In order to be able to abstract the 'basic' knx binding better from extended bindings, it must be clarified which classes should be internally which should be available as extensions. This is a copy of kgoderis PR 'knx-api' # 3500. It is the first step, further delimitations come in another PR. Signed-off-by: lewie <[email protected]>
Any news on this? This would be a really nice feature for the KNX integration into OH! |
Given the discussion here it seems a valuable addition. But due too long time no activity closing this pr. if someone wants to pick this up please open a new pr. |
This PR contains all the changes to the KNX Basic binding that are required by https://github.com/openhab/openhab2-addons/pull/3451.
Signed-Off-By: Karel Goderis [email protected]