]> git.basschouten.com Git - openhab-addons.git/blob
d210ca89653cc3b68c8e8f8b64441d0eb5a96410
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.dmx.internal.handler;
14
15 import static org.openhab.binding.dmx.internal.DmxBindingConstants.THING_TYPE_LIB485_BRIDGE;
16
17 import java.io.IOException;
18 import java.net.Socket;
19 import java.util.Collections;
20 import java.util.HashMap;
21 import java.util.Map;
22 import java.util.Set;
23
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;
34
35 /**
36  * The {@link Lib485BridgeHandler} is responsible for communication with
37  * an Lib485 instance
38  *
39  * @author Jan N. Klug - Initial contribution
40  */
41
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;
47
48     private final Logger logger = LoggerFactory.getLogger(Lib485BridgeHandler.class);
49     private final Map<IpNode, Socket> receiverNodes = new HashMap<>();
50
51     public Lib485BridgeHandler(Bridge lib485Bridge) {
52         super(lib485Bridge);
53     }
54
55     @Override
56     protected void openConnection() {
57         if (getThing().getStatus() != ThingStatus.ONLINE) {
58             for (IpNode receiverNode : receiverNodes.keySet()) {
59                 Socket socket = receiverNodes.get(receiverNode);
60                 if (socket == null) {
61                     try {
62                         socket = new Socket(receiverNode.getAddressString(), receiverNode.getPort());
63                     } catch (IOException e) {
64                         logger.debug("Could not connect to {} in {}: {}", receiverNode, this.thing.getUID(),
65                                 e.getMessage());
66                         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
67                                 "could not connect to " + receiverNode.toString());
68                         return;
69                     }
70                 }
71
72                 if (socket.isConnected()) {
73                     receiverNodes.put(receiverNode, socket);
74                 } else {
75                     updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR);
76                     receiverNodes.put(receiverNode, null);
77                     return;
78                 }
79             }
80             updateStatus(ThingStatus.ONLINE);
81         }
82     }
83
84     @Override
85     protected void closeConnection() {
86         for (IpNode receiverNode : receiverNodes.keySet()) {
87             Socket socket = receiverNodes.get(receiverNode);
88             if ((socket != null) && (!socket.isClosed())) {
89                 try {
90                     socket.close();
91                 } catch (IOException e) {
92                     logger.warn("Could not close socket {} in {}: {}", receiverNode, this.thing.getUID(),
93                             e.getMessage());
94                 }
95             }
96             receiverNodes.put(receiverNode, null);
97         }
98     }
99
100     @Override
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()) {
108                     try {
109                         socket.getOutputStream().write(universe.getBuffer());
110                     } catch (IOException e) {
111                         logger.debug("Could not send to {} in {}: {}", receiverNode, this.thing.getUID(),
112                                 e.getMessage());
113                         closeConnection(ThingStatusDetail.COMMUNICATION_ERROR, "could not send DMX data");
114                         return;
115                     }
116                 } else {
117                     closeConnection(ThingStatusDetail.NONE, "reconnect");
118                     return;
119                 }
120             }
121         } else {
122             openConnection();
123         }
124     }
125
126     @Override
127     protected void updateConfiguration() {
128         Lib485BridgeHandlerConfiguration configuration = getConfig().as(Lib485BridgeHandlerConfiguration.class);
129
130         universe = new Universe(MIN_UNIVERSE_ID);
131
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());
136         } else {
137             try {
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());
141                 }
142             } catch (IllegalArgumentException e) {
143                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
144                 return;
145             }
146         }
147         super.updateConfiguration();
148
149         updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE);
150
151         logger.debug("updated configuration for Lib485 bridge {}", this.thing.getUID());
152     }
153
154     @Override
155     public void initialize() {
156         logger.debug("initializing Lib485 bridge {}", this.thing.getUID());
157
158         updateConfiguration();
159     }
160 }