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.Collections;
20 import java.util.HashMap;
24 import org.openhab.binding.dmx.internal.DmxBridgeHandler;
25 import org.openhab.binding.dmx.internal.config.Lib485BridgeHandlerConfiguration;
26 import org.openhab.binding.dmx.internal.dmxoverethernet.IpNode;
27 import org.openhab.binding.dmx.internal.multiverse.Universe;
28 import org.openhab.core.thing.Bridge;
29 import org.openhab.core.thing.ThingStatus;
30 import org.openhab.core.thing.ThingStatusDetail;
31 import org.openhab.core.thing.ThingTypeUID;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
36 * The {@link Lib485BridgeHandler} is responsible for communication with
39 * @author Jan N. Klug - Initial contribution
42 public class Lib485BridgeHandler extends DmxBridgeHandler {
43 public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_LIB485_BRIDGE);
44 public static final int MIN_UNIVERSE_ID = 0;
45 public static final int MAX_UNIVERSE_ID = 0;
46 public static final int DEFAULT_PORT = 9020;
48 private final Logger logger = LoggerFactory.getLogger(Lib485BridgeHandler.class);
49 private final Map<IpNode, Socket> receiverNodes = new HashMap<>();
51 public Lib485BridgeHandler(Bridge lib485Bridge) {
56 protected void openConnection() {
57 if (getThing().getStatus() != ThingStatus.ONLINE) {
58 for (IpNode receiverNode : receiverNodes.keySet()) {
59 Socket socket = receiverNodes.get(receiverNode);
62 socket = new Socket(receiverNode.getAddressString(), receiverNode.getPort());
63 } catch (IOException e) {
64 logger.debug("Could not connect to {} in {}: {}", receiverNode, this.thing.getUID(),
66 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
67 "could not connect to " + receiverNode.toString());
72 if (socket.isConnected()) {
73 receiverNodes.put(receiverNode, socket);
75 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
76 receiverNodes.put(receiverNode, null);
80 updateStatus(ThingStatus.ONLINE);
85 protected void closeConnection() {
86 for (IpNode receiverNode : receiverNodes.keySet()) {
87 Socket socket = receiverNodes.get(receiverNode);
88 if ((socket != null) && (!socket.isClosed())) {
91 } catch (IOException e) {
92 logger.warn("Could not close socket {} in {}: {}", receiverNode, this.thing.getUID(),
96 receiverNodes.put(receiverNode, null);
101 protected void sendDmxData() {
102 if (getThing().getStatus() == ThingStatus.ONLINE) {
103 long now = System.currentTimeMillis();
104 universe.calculateBuffer(now);
105 for (IpNode receiverNode : receiverNodes.keySet()) {
106 Socket socket = receiverNodes.get(receiverNode);
107 if (socket.isConnected()) {
109 socket.getOutputStream().write(universe.getBuffer());
110 } catch (IOException e) {
111 logger.debug("Could not send to {} in {}: {}", receiverNode, this.thing.getUID(),
113 closeConnection(ThingStatusDetail.COMMUNICATION_ERROR, "could not send DMX data");
117 closeConnection(ThingStatusDetail.NONE, "reconnect");
127 protected void updateConfiguration() {
128 Lib485BridgeHandlerConfiguration configuration = getConfig().as(Lib485BridgeHandlerConfiguration.class);
130 universe = new Universe(MIN_UNIVERSE_ID);
132 receiverNodes.clear();
133 if (configuration.address.isEmpty()) {
134 receiverNodes.put(new IpNode("localhost:9020"), null);
135 logger.debug("sending to {} for {}", receiverNodes, this.thing.getUID());
138 for (IpNode receiverNode : IpNode.fromString(configuration.address, DEFAULT_PORT)) {
139 receiverNodes.put(receiverNode, null);
140 logger.debug("sending to {} for {}", receiverNode, this.thing.getUID());
142 } catch (IllegalArgumentException e) {
143 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
147 super.updateConfiguration();
149 updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE);
151 logger.debug("updated configuration for Lib485 bridge {}", this.thing.getUID());
155 public void initialize() {
156 logger.debug("initializing Lib485 bridge {}", this.thing.getUID());
158 updateConfiguration();