From 2e7f0e061c096abc3acbaadc4ea7afc0e7503ca9 Mon Sep 17 00:00:00 2001 From: Cody Cutrer Date: Thu, 5 Dec 2024 15:27:05 -0700 Subject: [PATCH] [mqtt.homeassistant] Implement Tag Scanner (#17852) Signed-off-by: Cody Cutrer --- .../README.md | 6 ++ .../internal/component/ComponentFactory.java | 2 + .../homeassistant/internal/component/Tag.java | 53 +++++++++++++++ .../internal/component/TagTests.java | 64 +++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Tag.java create mode 100644 bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/TagTests.java diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/README.md b/bundles/org.openhab.binding.mqtt.homeassistant/README.md index 38e1cfc3c6a..205fad3f4b5 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/README.md +++ b/bundles/org.openhab.binding.mqtt.homeassistant/README.md @@ -164,6 +164,12 @@ If a device has multiple device triggers for the same subtype (the particular bu | switch | Switch | R/W | If the device is on or off. | | json-attributes | String | RO | Additional attributes, as a serialized JSON string. | +### [Tag Scanner](https://www.home-assistant.io/integrations/tag.mqtt/) + +| Channel ID | Type | R/W | Description | +|-----------------|---------|-----|---------------------------------| +| tag | Trigger | N/A | The value of the "scanned" tag. | + ### [Text](https://www.home-assistant.io/integrations/text.mqtt/) | Channel ID | Type | R/W | Description | diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/ComponentFactory.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/ComponentFactory.java index 7dc66de6875..192d16e424e 100644 --- a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/ComponentFactory.java +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/ComponentFactory.java @@ -85,6 +85,8 @@ public class ComponentFactory { return new Sensor(componentConfiguration, newStyleChannels); case "switch": return new Switch(componentConfiguration, newStyleChannels); + case "tag": + return new Tag(componentConfiguration, newStyleChannels); case "text": return new Text(componentConfiguration, newStyleChannels); case "update": diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Tag.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Tag.java new file mode 100644 index 00000000000..758ac6c8a6d --- /dev/null +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/main/java/org/openhab/binding/mqtt/homeassistant/internal/component/Tag.java @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2010-2024 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * 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 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.mqtt.homeassistant.internal.component; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.openhab.binding.mqtt.generic.values.TextValue; +import org.openhab.binding.mqtt.homeassistant.internal.ComponentChannelType; +import org.openhab.binding.mqtt.homeassistant.internal.config.dto.AbstractChannelConfiguration; + +/** + * A MQTT Tag scanner, following the https://www.home-assistant.io/integrations/tag.mqtt/ specification. + * + * @author Cody Cutrer - Initial contribution + */ +@NonNullByDefault +public class Tag extends AbstractComponent { + public static final String TAG_CHANNEL_ID = "tag"; + + /** + * Configuration class for MQTT component + */ + public static class ChannelConfiguration extends AbstractChannelConfiguration { + ChannelConfiguration() { + super("MQTT Tag Scanner"); + } + + protected String topic = ""; + } + + public Tag(ComponentFactory.ComponentConfiguration componentConfiguration, boolean newStyleChannels) { + super(componentConfiguration, ChannelConfiguration.class, newStyleChannels); + + buildChannel(TAG_CHANNEL_ID, ComponentChannelType.TRIGGER, new TextValue(), getName(), + componentConfiguration.getUpdateListener()) + .stateTopic(channelConfiguration.topic, channelConfiguration.getValueTemplate()).trigger(true).build(); + finalizeChannels(); + } + + @Override + protected void addJsonAttributesChannel() { + // json_attributes are not supported + } +} diff --git a/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/TagTests.java b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/TagTests.java new file mode 100644 index 00000000000..b9d688eb6c7 --- /dev/null +++ b/bundles/org.openhab.binding.mqtt.homeassistant/src/test/java/org/openhab/binding/mqtt/homeassistant/internal/component/TagTests.java @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2010-2024 Contributors to the openHAB project + * + * See the NOTICE file(s) distributed with this work for additional + * information. + * + * 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 + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.openhab.binding.mqtt.homeassistant.internal.component; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +import java.util.Set; + +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.junit.jupiter.api.Test; +import org.openhab.binding.mqtt.generic.values.TextValue; + +/** + * Tests for {@link Tag} + * + * @author Cody Cutrer - Initial contribution + */ +@NonNullByDefault +public class TagTests extends AbstractComponentTests { + public static final String CONFIG_TOPIC = "tag/0AFFD2"; + + @SuppressWarnings("null") + @Test + public void test() throws InterruptedException { + var component = discoverComponent(configTopicToMqtt(CONFIG_TOPIC), """ + { + "topic": "0AFFD2/tag_scanned", + "value_template": "{{ value_json.PN532.UID }}" + } + """); + + assertThat(component.channels.size(), is(1)); + assertThat(component.getName(), is("MQTT Tag Scanner")); + + assertChannel(component, Tag.TAG_CHANNEL_ID, "0AFFD2/tag_scanned", "", "MQTT Tag Scanner", TextValue.class); + + publishMessage("0AFFD2/tag_scanned", """ + { + "Time": "2020-09-28T17:02:10", + "PN532": { + "UID": "E9F35959", + "DATA":"ILOVETASMOTA" + } + } + """); + assertTriggered(component, Tag.TAG_CHANNEL_ID, "E9F35959"); + } + + @Override + protected Set getConfigTopics() { + return Set.of(CONFIG_TOPIC); + } +}