-
-
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
[mqtt] Have a working Group Id #5156
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,15 +23,19 @@ | |
* followed by the component id, an optional node id and the object id. | ||
* | ||
* This helper class can split up an MQTT topic into such parts. | ||
* <p> | ||
* Implementation note: This is an immutable class. | ||
* | ||
* @author David Graeff - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public class HaID { | ||
final private String baseTopic; | ||
final private String component; | ||
final private String nodeID; | ||
final private String objectID; | ||
public final String baseTopic; | ||
public final String component; | ||
public final String nodeID; | ||
public final String objectID; | ||
|
||
private final String _topic; | ||
|
||
/** | ||
* Creates a {@link HaID} object for a given HomeAssistant MQTT topic. | ||
|
@@ -41,19 +45,25 @@ public class HaID { | |
*/ | ||
public HaID(String mqttTopic) { | ||
String[] strings = mqttTopic.split("/"); | ||
if (strings.length < 3) { | ||
throw new IllegalArgumentException("MQTT topic not a HomeAssistant topic!"); | ||
if (strings.length < 4 || strings.length > 5) { | ||
throw new IllegalArgumentException("MQTT topic not a HomeAssistant topic (wrong length)!"); | ||
} | ||
if (!"config".equals(strings[strings.length - 1])) { | ||
throw new IllegalArgumentException("MQTT topic not a HomeAssistant topic ('config' missing)!"); | ||
} | ||
if (strings.length >= 5) { | ||
component = strings[1]; | ||
|
||
baseTopic = strings[0]; | ||
component = strings[1]; | ||
|
||
if (strings.length == 5) { | ||
nodeID = strings[2]; | ||
objectID = strings[3]; | ||
} else { | ||
component = strings[1]; | ||
nodeID = ""; | ||
objectID = strings[2]; | ||
} | ||
baseTopic = strings[0]; | ||
|
||
this._topic = createTopic(this); | ||
} | ||
|
||
public HaID() { | ||
|
@@ -73,33 +83,64 @@ private HaID(String baseTopic, String objectID, String nodeID, String component) | |
this.objectID = objectID; | ||
this.nodeID = nodeID; | ||
this.component = component; | ||
this._topic = createTopic(this); | ||
} | ||
|
||
private static final String createTopic(HaID id) { | ||
StringBuilder str = new StringBuilder(); | ||
str.append(id.baseTopic).append('/').append(id.component).append('/'); | ||
if (StringUtils.isNotBlank(id.nodeID)) { | ||
str.append(id.nodeID).append('/'); | ||
} | ||
str.append(id.objectID).append('/'); | ||
return str.toString(); | ||
} | ||
|
||
/** | ||
* Extract the HaID information from a channel configuration. | ||
* <p> | ||
* <code>objectid</code>, <code>nodeid</code>, and <code>component</code> values are fetched from the configuration. | ||
* | ||
* @param baseTopic | ||
* @param config | ||
* @return newly created HaID | ||
*/ | ||
public static HaID fromConfig(String baseTopic, Configuration config) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The factory pattern is like public constructors -> a fellow developer would really enjoy javadoc here. |
||
String objectID = (String) config.get("objectid"); | ||
String nodeID = (String) config.getProperties().getOrDefault("nodeid", ""); | ||
String component = (String) config.get("component"); | ||
return new HaID(baseTopic, objectID, nodeID, component); | ||
} | ||
|
||
public void toConfig(Configuration config) { | ||
/** | ||
* Add the HaID information to a channel configuration. | ||
* <p> | ||
* <code>objectid</code>, <code>nodeid</code>, and <code>component</code> values are added to the configuration. | ||
* | ||
* @param config | ||
* @return the modified configuration | ||
*/ | ||
public Configuration toConfig(Configuration config) { | ||
config.put("objectid", objectID); | ||
config.put("nodeid", nodeID); | ||
config.put("component", component); | ||
return config; | ||
} | ||
|
||
public HandlerConfiguration toHandlerConfiguration() { | ||
String objectID = this.objectID; | ||
if (StringUtils.isNotBlank(nodeID)) { | ||
objectID = nodeID + "/" + objectID; | ||
} | ||
|
||
return new HandlerConfiguration(baseTopic, objectID); | ||
} | ||
|
||
/** | ||
* Extract the HaID information from a thing configuration. | ||
* <p> | ||
* <code>basetpoic</code> and <code>objectid</code> are taken from the configuration. | ||
* The <code>objectid</code> string may be in the form <code>nodeid/objectid</code>. | ||
* <p> | ||
* The <code>component</code> component in the resulting HaID will be set to <code>+</code>. | ||
* This enables the HaID to be used as an mqtt subscription topic. | ||
* | ||
* @param config | ||
* @return newly created HaID | ||
*/ | ||
public static HaID fromConfig(HandlerConfiguration config) { | ||
String baseTopic = config.getBasetopic(); | ||
String objectID = config.getObjectid(); | ||
String objectID = config.objectid; | ||
String nodeID = ""; | ||
|
||
if (StringUtils.contains(objectID, '/')) { | ||
|
@@ -112,9 +153,34 @@ public static HaID fromConfig(HandlerConfiguration config) { | |
nodeID = parts[0]; | ||
objectID = parts[1]; | ||
} | ||
return new HaID(baseTopic, objectID, nodeID, "+"); | ||
return new HaID(config.basetopic, objectID, nodeID, "+"); | ||
} | ||
|
||
/** | ||
* Create a new thing configuration which contains the information from this HaID. | ||
* <p> | ||
* <code>objectid</code> in the thing configuration will be | ||
* <code>nodeID/objectID<code> from the HaID, if <code>nodeID</code> is not empty. | ||
* <p> | ||
* <code>component</code> value will not be preserved. | ||
* | ||
* @return the new thing configuration | ||
*/ | ||
public HandlerConfiguration toHandlerConfiguration() { | ||
String objectID = this.objectID; | ||
if (StringUtils.isNotBlank(nodeID)) { | ||
objectID = nodeID + "/" + objectID; | ||
} | ||
|
||
return new HandlerConfiguration(baseTopic, objectID); | ||
} | ||
|
||
/** | ||
* The default group id is the unique_id of the component, given in the config-json. | ||
* If the unique id is not set, then a fallback is constructed from the HaID information. | ||
* | ||
* @return fallback group id | ||
*/ | ||
public String getFallbackGroupId() { | ||
StringBuilder str = new StringBuilder(); | ||
|
||
|
@@ -125,28 +191,18 @@ public String getFallbackGroupId() { | |
return str.toString(); | ||
} | ||
|
||
public String getComponent() { | ||
return component; | ||
} | ||
|
||
public String getObjectID() { | ||
return objectID; | ||
} | ||
|
||
/** | ||
* Return a topic, which can be used for a mqtt subscription. | ||
* Defined values for suffix are: | ||
* <ul> | ||
* <li>config</li> | ||
* <li>state</li> | ||
* </ul> | ||
* | ||
* @return fallback group id | ||
*/ | ||
public String getTopic(String suffix) { | ||
StringBuilder str = new StringBuilder(); | ||
|
||
str.append(baseTopic).append('/').append(component).append('/'); | ||
|
||
if (StringUtils.isNotBlank(nodeID)) { | ||
str.append(nodeID).append('/'); | ||
} | ||
str.append(objectID); | ||
if (StringUtils.isNotBlank(suffix)) { | ||
str.append('/').append(suffix); | ||
} | ||
|
||
return str.toString(); | ||
return _topic + suffix; | ||
} | ||
|
||
@Override | ||
|
@@ -189,6 +245,6 @@ public boolean equals(@Nullable Object obj) { | |
|
||
@Override | ||
public String toString() { | ||
return baseTopic + "/" + component + "/" + nodeID + "/" + objectID; | ||
return _topic; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -132,7 +132,7 @@ public void receivedMessage(ThingUID connectionBridge, MqttBrokerConnection conn | |
// Therefore the components are assembled into a list and given to the DiscoveryResult label for the user to | ||
// easily recognize object capabilities. | ||
HaID topicParts = determineTopicParts(topic); | ||
final String thingID = topicParts.getObjectID(); | ||
final String thingID = topicParts.objectID; | ||
final ThingUID thingUID = new ThingUID(MqttBindingConstants.HOMEASSISTANT_MQTT_THING, connectionBridge, | ||
thingID); | ||
|
||
|
@@ -146,11 +146,11 @@ public void receivedMessage(ThingUID connectionBridge, MqttBrokerConnection conn | |
|
||
// We need to keep track of already found component topics for a specific object_id/node_id | ||
Set<String> components = componentsPerThingID.getOrDefault(thingID, new HashSet<>()); | ||
if (components.contains(topicParts.getComponent())) { | ||
logger.trace("Discovered an already known component {}", topicParts.getComponent()); | ||
if (components.contains(topicParts.component)) { | ||
logger.trace("Discovered an already known component {}", topicParts.component); | ||
return; // If we already know about this object component, ignore the discovered topic. | ||
} | ||
components.add(topicParts.getComponent()); | ||
components.add(topicParts.component); | ||
componentsPerThingID.put(thingID, components); | ||
|
||
final String componentNames = components.stream().map(c -> HA_COMP_TO_NAME.getOrDefault(c, c)) | ||
|
@@ -161,7 +161,7 @@ public void receivedMessage(ThingUID connectionBridge, MqttBrokerConnection conn | |
|
||
Map<String, Object> properties = new HashMap<>(); | ||
HandlerConfiguration handlerConfig = topicParts.toHandlerConfiguration(); | ||
handlerConfig.toProperties(properties); | ||
handlerConfig.appendToProperties(properties); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make it like so: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, should have thought about this... |
||
config.addDeviceProperties(properties); | ||
// First remove an already discovered thing with the same ID | ||
thingRemoved(thingUID); | ||
|
@@ -176,7 +176,7 @@ public void topicVanished(ThingUID connectionBridge, MqttBrokerConnection connec | |
if (!topic.endsWith("/config")) { | ||
return; | ||
} | ||
final String thingID = determineTopicParts(topic).getObjectID(); | ||
final String thingID = determineTopicParts(topic).objectID; | ||
componentsPerThingID.remove(thingID); | ||
thingRemoved(new ThingUID(MqttBindingConstants.HOMEASSISTANT_MQTT_THING, connectionBridge, thingID)); | ||
} | ||
|
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 not a correct name according to the Java / openHAB coding guidelines