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.dmx.internal.handler;
15 import static org.openhab.binding.dmx.internal.DmxBindingConstants.THING_TYPE_LIB485_BRIDGE;
17 import java.io.IOException;
18 import java.net.Socket;
19 import java.util.HashMap;
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.dmx.internal.DmxBridgeHandler;
26 import org.openhab.binding.dmx.internal.config.Lib485BridgeHandlerConfiguration;
27 import org.openhab.binding.dmx.internal.dmxoverethernet.IpNode;
28 import org.openhab.binding.dmx.internal.multiverse.Universe;
29 import org.openhab.core.thing.Bridge;
30 import org.openhab.core.thing.ThingStatus;
31 import org.openhab.core.thing.ThingStatusDetail;
32 import org.openhab.core.thing.ThingTypeUID;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
37 * The {@link Lib485BridgeHandler} is responsible for communication with
40 * @author Jan N. Klug - Initial contribution
43 public class Lib485BridgeHandler extends DmxBridgeHandler {
44 public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_LIB485_BRIDGE);
45 public static final int MIN_UNIVERSE_ID = 0;
46 public static final int MAX_UNIVERSE_ID = 0;
47 public static final int DEFAULT_PORT = 9020;
49 private final Logger logger = LoggerFactory.getLogger(Lib485BridgeHandler.class);
50 private final Map<IpNode, @Nullable Socket> receiverNodes = new HashMap<>();
52 public Lib485BridgeHandler(Bridge lib485Bridge) {
57 protected void openConnection() {
58 if (getThing().getStatus() != ThingStatus.ONLINE) {
59 for (IpNode receiverNode : receiverNodes.keySet()) {
60 Socket socket = receiverNodes.get(receiverNode);
63 socket = new Socket(receiverNode.getAddressString(), receiverNode.getPort());
64 } catch (IOException e) {
65 logger.debug("Could not connect to {} in {}: {}", receiverNode, this.thing.getUID(),
67 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
68 "could not connect to " + receiverNode.toString());
73 if (socket.isConnected()) {
74 receiverNodes.put(receiverNode, socket);
76 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
77 receiverNodes.put(receiverNode, null);
81 updateStatus(ThingStatus.ONLINE);
86 protected void closeConnection() {
87 for (IpNode receiverNode : receiverNodes.keySet()) {
88 Socket socket = receiverNodes.get(receiverNode);
89 if ((socket != null) && (!socket.isClosed())) {
92 } catch (IOException e) {
93 logger.warn("Could not close socket {} in {}: {}", receiverNode, this.thing.getUID(),
97 receiverNodes.put(receiverNode, null);
102 protected void sendDmxData() {
103 if (getThing().getStatus() == ThingStatus.ONLINE) {
104 long now = System.currentTimeMillis();
105 universe.calculateBuffer(now);
106 for (IpNode receiverNode : receiverNodes.keySet()) {
107 Socket socket = receiverNodes.get(receiverNode);
108 if (socket != null && socket.isConnected()) {
110 socket.getOutputStream().write(universe.getBuffer());
111 } catch (IOException e) {
112 logger.debug("Could not send to {} in {}: {}", receiverNode, this.thing.getUID(),
114 closeConnection(ThingStatusDetail.COMMUNICATION_ERROR, "could not send DMX data");
118 closeConnection(ThingStatusDetail.NONE, "reconnect");
128 protected void updateConfiguration() {
129 Lib485BridgeHandlerConfiguration configuration = getConfig().as(Lib485BridgeHandlerConfiguration.class);
131 universe = new Universe(MIN_UNIVERSE_ID);
133 receiverNodes.clear();
134 if (configuration.address.isEmpty()) {
135 receiverNodes.put(new IpNode("localhost:9020"), null);
136 logger.debug("sending to {} for {}", receiverNodes, this.thing.getUID());
139 for (IpNode receiverNode : IpNode.fromString(configuration.address, DEFAULT_PORT)) {
140 receiverNodes.put(receiverNode, null);
141 logger.debug("sending to {} for {}", receiverNode, this.thing.getUID());
143 } catch (IllegalArgumentException e) {
144 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
148 super.updateConfiguration();
150 updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE);
152 logger.debug("updated configuration for Lib485 bridge {}", this.thing.getUID());
156 public void initialize() {
157 logger.debug("initializing Lib485 bridge {}", this.thing.getUID());
159 updateConfiguration();