2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.alarmdecoder.internal.handler;
15 import static org.openhab.binding.alarmdecoder.internal.AlarmDecoderBindingConstants.*;
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.openhab.binding.alarmdecoder.internal.config.ZoneConfig;
19 import org.openhab.binding.alarmdecoder.internal.protocol.ADMessage;
20 import org.openhab.binding.alarmdecoder.internal.protocol.EXPMessage;
21 import org.openhab.core.library.types.OpenClosedType;
22 import org.openhab.core.thing.ChannelUID;
23 import org.openhab.core.thing.Thing;
24 import org.openhab.core.thing.ThingStatus;
25 import org.openhab.core.thing.ThingStatusDetail;
26 import org.openhab.core.types.Command;
27 import org.openhab.core.types.UnDefType;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
32 * The {@link ZoneHandler} is responsible for handling wired zones (i.e. REL & EXP messages).
34 * @author Bob Adair - Initial contribution
35 * @author Bill Forsyth - Initial contribution
38 public class ZoneHandler extends ADThingHandler {
40 private final Logger logger = LoggerFactory.getLogger(ZoneHandler.class);
42 private ZoneConfig config = new ZoneConfig();
44 public ZoneHandler(Thing thing) {
48 /** Construct zone id from address and channel */
49 public static String zoneID(int address, int channel) {
50 return String.format("%d-%d", address, channel);
54 public void initialize() {
55 config = getConfigAs(ZoneConfig.class);
57 if (config.address < 0 || config.channel < 0) {
58 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Invalid address/channel setting");
61 logger.debug("Zone handler initializing for address {} channel {}", config.address, config.channel);
63 String id = zoneID(config.address, config.channel);
64 updateProperty(PROPERTY_ID, id); // set representation property used by discovery
67 logger.trace("Zone handler finished initializing");
71 * Set contact channel state to "UNDEF" at init time. The real state will be set either when the first message
72 * arrives for the zone, or it should be set to "CLOSED" the first time the panel goes into the "READY" state.
75 public void initChannelState() {
76 UnDefType state = UnDefType.UNDEF;
77 updateState(CHANNEL_CONTACT, state);
78 firstUpdateReceived.set(false);
82 public void notifyPanelReady() {
83 logger.trace("Zone handler for {},{} received panel ready notification.", config.address, config.channel);
84 if (firstUpdateReceived.compareAndSet(false, true)) {
85 updateState(CHANNEL_CONTACT, OpenClosedType.CLOSED);
90 public void handleCommand(ChannelUID channelUID, Command command) {
91 // All channels are read-only, so ignore all commands.
95 public void handleUpdate(ADMessage msg) {
96 if (!(msg instanceof EXPMessage)) {
99 EXPMessage expMsg = (EXPMessage) msg;
101 if (config.address == expMsg.address && config.channel == expMsg.channel) {
102 logger.trace("Zone handler for {},{} received update: {}", config.address, config.channel, expMsg.data);
104 firstUpdateReceived.set(true);
105 OpenClosedType state = (expMsg.data == 0 ? OpenClosedType.CLOSED : OpenClosedType.OPEN);
106 updateState(CHANNEL_CONTACT, state);