-
Notifications
You must be signed in to change notification settings - Fork 11
Add support for actions and events #56
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
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
39272a6
Add support for actions and events
ccutrer 38a2012
Add actions device test
ccutrer 1d8392d
adjust source to prefix it with the package
ccutrer 46e6cc8
correct spelling of homeassistant in trigger docs
ccutrer 9936abc
correct javadocs in EventFactory
ccutrer File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
52 changes: 52 additions & 0 deletions
52
src/main/java/no/seime/openhab/binding/esphome/events/AbstractESPHomeEvent.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| /** | ||
| * Copyright (c) 2023 Contributors to the Seime Openhab Addons project | ||
| * <p> | ||
| * See the NOTICE file(s) distributed with this work for additional | ||
| * information. | ||
| * <p> | ||
| * This program and the accompanying materials are made available under the | ||
| * terms of the Eclipse Public License 2.0 which is available at | ||
| * http://www.eclipse.org/legal/epl-2.0 | ||
| * <p> | ||
| * SPDX-License-Identifier: EPL-2.0 | ||
| */ | ||
| package no.seime.openhab.binding.esphome.events; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| import org.eclipse.jdt.annotation.NonNullByDefault; | ||
| import org.openhab.core.events.AbstractEvent; | ||
|
|
||
| /** | ||
| * Abstract base class for both action and event events. | ||
| * | ||
| * @author Cody Cutrer - Initial contribution | ||
| */ | ||
| @NonNullByDefault | ||
| public abstract class AbstractESPHomeEvent extends AbstractEvent { | ||
| protected final String action; | ||
| private final Map<String, String> data; | ||
| private final Map<String, String> data_template; | ||
| private final Map<String, String> variables; | ||
|
|
||
| public AbstractESPHomeEvent(String topic, String payload, String deviceId, String action, Map<String, String> data, | ||
| Map<String, String> data_template, Map<String, String> variables) { | ||
| super(topic, payload, deviceId); | ||
| this.action = action; | ||
| this.data = data; | ||
| this.data_template = data_template; | ||
| this.variables = variables; | ||
| } | ||
|
|
||
| public Map<String, String> getData() { | ||
| return data; | ||
| } | ||
|
|
||
| public Map<String, String> getDataTemplate() { | ||
| return data_template; | ||
| } | ||
|
|
||
| public Map<String, String> getVariables() { | ||
| return variables; | ||
| } | ||
| } |
46 changes: 46 additions & 0 deletions
46
src/main/java/no/seime/openhab/binding/esphome/events/ActionEvent.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| /** | ||
| * Copyright (c) 2023 Contributors to the Seime Openhab Addons project | ||
| * <p> | ||
| * See the NOTICE file(s) distributed with this work for additional | ||
| * information. | ||
| * <p> | ||
| * This program and the accompanying materials are made available under the | ||
| * terms of the Eclipse Public License 2.0 which is available at | ||
| * http://www.eclipse.org/legal/epl-2.0 | ||
| * <p> | ||
| * SPDX-License-Identifier: EPL-2.0 | ||
| */ | ||
| package no.seime.openhab.binding.esphome.events; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| import org.eclipse.jdt.annotation.NonNullByDefault; | ||
|
|
||
| /** | ||
| * This class represents an action request sent from an ESPHome device. | ||
| * | ||
| * @author Cody Cutrer - Initial contribution | ||
| */ | ||
| @NonNullByDefault | ||
| public class ActionEvent extends AbstractESPHomeEvent { | ||
| public static final String TYPE = "esphome.ActionEvent"; | ||
|
|
||
| public ActionEvent(String topic, String payload, String deviceId, String action, Map<String, String> data, | ||
| Map<String, String> data_template, Map<String, String> variables) { | ||
| super(topic, payload, deviceId, action, data, data_template, variables); | ||
| } | ||
|
|
||
| @Override | ||
| public String getType() { | ||
| return TYPE; | ||
| } | ||
|
|
||
| public String getAction() { | ||
| return action; | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return String.format("Device '%s' requested action '%s'", getSource(), action); | ||
| } | ||
| } |
172 changes: 172 additions & 0 deletions
172
src/main/java/no/seime/openhab/binding/esphome/events/ESPHomeEventFactory.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| /** | ||
| * Copyright (c) 2023 Contributors to the Seime Openhab Addons project | ||
| * <p> | ||
| * See the NOTICE file(s) distributed with this work for additional | ||
| * information. | ||
| * <p> | ||
| * This program and the accompanying materials are made available under the | ||
| * terms of the Eclipse Public License 2.0 which is available at | ||
| * http://www.eclipse.org/legal/epl-2.0 | ||
| * <p> | ||
| * SPDX-License-Identifier: EPL-2.0 | ||
| */ | ||
| package no.seime.openhab.binding.esphome.events; | ||
|
|
||
| import java.util.Map; | ||
| import java.util.Set; | ||
|
|
||
| import org.eclipse.jdt.annotation.NonNullByDefault; | ||
| import org.eclipse.jdt.annotation.Nullable; | ||
| import org.openhab.core.events.AbstractEventFactory; | ||
| import org.openhab.core.events.Event; | ||
| import org.openhab.core.events.EventFactory; | ||
| import org.osgi.service.component.annotations.Component; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| /** | ||
| * This class represents an action request sent from an ESPHome device. | ||
| * | ||
| * @author Cody Cutrer - Initial contribution | ||
| */ | ||
| @NonNullByDefault | ||
| @Component(service = EventFactory.class, immediate = true) | ||
| public class ESPHomeEventFactory extends AbstractEventFactory { | ||
| private static final String ACTION_IDENTIFIER = "{action}"; | ||
| private static final String ACTION_EVENT_TOPIC = "openhab/esphome/action/" + ACTION_IDENTIFIER; | ||
| private static final String EVENT_EVENT_TOPIC = "openhab/esphome/event/" + ACTION_IDENTIFIER; | ||
| private static final String TAG_SCANNED_EVENT_TOPIC = "openhab/esphome/tag_scanned"; | ||
| private static final String SOURCE_PREFIX = "no.seime.openhab.binding.esphome$"; | ||
|
|
||
| private final Logger logger = LoggerFactory.getLogger(ESPHomeEventFactory.class); | ||
|
|
||
| private static final Set<String> SUPPORTED_TYPES = Set.of(ActionEvent.TYPE, EventEvent.TYPE, TagScannedEvent.TYPE); | ||
|
|
||
| public ESPHomeEventFactory() { | ||
| super(SUPPORTED_TYPES); | ||
| } | ||
|
|
||
| @Override | ||
| protected Event createEventByType(String eventType, String topic, String payload, @Nullable String source) | ||
| throws Exception { | ||
| logger.trace("creating ruleEvent of type: {}", eventType); | ||
| if (source == null) { | ||
| throw new IllegalArgumentException("'source' must not be null for ESPHome events"); | ||
| } | ||
| if (ActionEvent.TYPE.equals(eventType)) { | ||
| return createActionEvent(topic, payload, source); | ||
| } else if (EventEvent.TYPE.equals(eventType)) { | ||
| return createEventEvent(topic, payload, source); | ||
| } else if (TagScannedEvent.TYPE.equals(eventType)) { | ||
| return new TagScannedEvent(topic, payload, source); | ||
| } | ||
| throw new IllegalArgumentException("The event type '" + eventType + "' is not supported by this factory."); | ||
| } | ||
|
|
||
| private Event createActionEvent(String topic, String payload, String source) { | ||
| String action = getAction(topic); | ||
| ActionEventPayloadBean bean = deserializePayload(payload, ActionEventPayloadBean.class); | ||
|
|
||
| return new ActionEvent(topic, payload, source, action, bean.getData(), bean.getDataTemplate(), | ||
| bean.getVariables()); | ||
| } | ||
|
|
||
| private Event createEventEvent(String topic, String payload, String source) { | ||
| String action = getAction(topic); | ||
| ActionEventPayloadBean bean = deserializePayload(payload, ActionEventPayloadBean.class); | ||
|
|
||
| return new EventEvent(topic, payload, source, action, bean.getData(), bean.getDataTemplate(), | ||
| bean.getVariables()); | ||
| } | ||
|
|
||
| private String getAction(String topic) { | ||
| String[] topicElements = getTopicElements(topic); | ||
| if (topicElements.length < 4) { | ||
| throw new IllegalArgumentException("Event creation failed, invalid topic: " + topic); | ||
| } | ||
|
|
||
| return topicElements[3]; | ||
| } | ||
|
|
||
| /** | ||
| * Creates an {@link ActionEvent} | ||
| * | ||
| * @param deviceId the device requesting the action | ||
| * @param action the action to perform | ||
| * @param data the data for the action | ||
| * @param data_template the data template for the action | ||
| * @param variables variables for the use in the templates | ||
| * @return the created event | ||
| */ | ||
| public static ActionEvent createActionEvent(String deviceId, String action, Map<String, String> data, | ||
| Map<String, String> data_template, Map<String, String> variables) { | ||
| String topic = ACTION_EVENT_TOPIC.replace(ACTION_IDENTIFIER, action); | ||
| ActionEventPayloadBean bean = new ActionEventPayloadBean(data, data_template, variables); | ||
| String payload = serializePayload(bean); | ||
| return new ActionEvent(topic, payload, SOURCE_PREFIX + deviceId, action, data, data_template, variables); | ||
| } | ||
|
|
||
| /** | ||
| * Creates an {@link EventEvent} | ||
| * | ||
| * @param deviceId the device emitting the event | ||
| * @param event the event identifier | ||
| * @param data the data for the action | ||
| * @param data_template the data template for the action | ||
| * @param variables variables for the use in the templates | ||
| * @return the created event | ||
| */ | ||
| public static EventEvent createEventEvent(String deviceId, String event, Map<String, String> data, | ||
| Map<String, String> data_template, Map<String, String> variables) { | ||
| String topic = EVENT_EVENT_TOPIC.replace(ACTION_IDENTIFIER, event); | ||
| ActionEventPayloadBean bean = new ActionEventPayloadBean(data, data_template, variables); | ||
| String payload = serializePayload(bean); | ||
| return new EventEvent(topic, payload, SOURCE_PREFIX + deviceId, event, data, data_template, variables); | ||
| } | ||
|
|
||
| /** | ||
| * Creates a {@link TagScannedEvent} | ||
| * | ||
| * @param deviceId the device emitting the event | ||
| * @param tagId the tag identifier | ||
| * @return the created event | ||
| */ | ||
| public static TagScannedEvent createTagScannedEvent(String deviceId, String tagId) { | ||
| return new TagScannedEvent(TAG_SCANNED_EVENT_TOPIC, tagId, SOURCE_PREFIX + deviceId); | ||
| } | ||
|
|
||
| /** | ||
| * This is a java bean that is used to serialize/deserialize action event payload. | ||
| */ | ||
| private static class ActionEventPayloadBean { | ||
| private @NonNullByDefault({}) Map<String, String> data; | ||
| private @NonNullByDefault({}) Map<String, String> data_template; | ||
| private @NonNullByDefault({}) Map<String, String> variables; | ||
|
|
||
| /** | ||
| * Default constructor for deserialization e.g. by Gson. | ||
| */ | ||
| @SuppressWarnings("unused") | ||
| protected ActionEventPayloadBean() { | ||
| } | ||
|
|
||
| public ActionEventPayloadBean(Map<String, String> data, Map<String, String> data_template, | ||
| Map<String, String> variables) { | ||
| this.data = data; | ||
| this.data_template = data_template; | ||
| this.variables = variables; | ||
| } | ||
|
|
||
| public Map<String, String> getData() { | ||
| return data; | ||
| } | ||
|
|
||
| public Map<String, String> getDataTemplate() { | ||
| return data_template; | ||
| } | ||
|
|
||
| public Map<String, String> getVariables() { | ||
| return variables; | ||
| } | ||
| } | ||
| } | ||
46 changes: 46 additions & 0 deletions
46
src/main/java/no/seime/openhab/binding/esphome/events/EventEvent.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| /** | ||
| * Copyright (c) 2023 Contributors to the Seime Openhab Addons project | ||
| * <p> | ||
| * See the NOTICE file(s) distributed with this work for additional | ||
| * information. | ||
| * <p> | ||
| * This program and the accompanying materials are made available under the | ||
| * terms of the Eclipse Public License 2.0 which is available at | ||
| * http://www.eclipse.org/legal/epl-2.0 | ||
| * <p> | ||
| * SPDX-License-Identifier: EPL-2.0 | ||
| */ | ||
| package no.seime.openhab.binding.esphome.events; | ||
|
|
||
| import java.util.Map; | ||
|
|
||
| import org.eclipse.jdt.annotation.NonNullByDefault; | ||
|
|
||
| /** | ||
| * This class represents an event sent from an ESPHome device. | ||
| * | ||
| * @author Cody Cutrer - Initial contribution | ||
| */ | ||
| @NonNullByDefault | ||
| public class EventEvent extends AbstractESPHomeEvent { | ||
| public static final String TYPE = "esphome.EventEvent"; | ||
|
|
||
| public EventEvent(String topic, String payload, String deviceId, String event, Map<String, String> data, | ||
| Map<String, String> data_template, Map<String, String> variables) { | ||
| super(topic, payload, deviceId, event, data, data_template, variables); | ||
| } | ||
|
|
||
| @Override | ||
| public String getType() { | ||
| return TYPE; | ||
| } | ||
|
|
||
| public String getEvent() { | ||
| return action; | ||
| } | ||
|
|
||
| @Override | ||
| public String toString() { | ||
| return String.format("Device '%s' sent event '%s'", getSource(), action); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.