]> git.basschouten.com Git - openhab-addons.git/blob
04b868c2c2e58293154764285d6889737d5e163b
[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.modbus.internal.handler;
14
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.openhab.binding.modbus.handler.EndpointNotInitializedException;
18 import org.openhab.binding.modbus.handler.ModbusEndpointThingHandler;
19 import org.openhab.binding.modbus.internal.ModbusConfigurationException;
20 import org.openhab.core.io.transport.modbus.ModbusCommunicationInterface;
21 import org.openhab.core.io.transport.modbus.ModbusManager;
22 import org.openhab.core.io.transport.modbus.endpoint.EndpointPoolConfiguration;
23 import org.openhab.core.io.transport.modbus.endpoint.ModbusSlaveEndpoint;
24 import org.openhab.core.thing.Bridge;
25 import org.openhab.core.thing.ChannelUID;
26 import org.openhab.core.thing.ThingStatus;
27 import org.openhab.core.thing.ThingStatusDetail;
28 import org.openhab.core.thing.binding.BaseBridgeHandler;
29 import org.openhab.core.types.Command;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 /**
34  * Base class for Modbus Slave endpoint thing handlers
35  *
36  * @author Sami Salonen - Initial contribution
37  *
38  * @param <E> endpoint class
39  * @param <C> config class
40  */
41 @NonNullByDefault
42 public abstract class AbstractModbusEndpointThingHandler<E extends ModbusSlaveEndpoint, C> extends BaseBridgeHandler
43         implements ModbusEndpointThingHandler {
44
45     protected volatile @Nullable C config;
46     protected volatile @Nullable E endpoint;
47     protected ModbusManager modbusManager;
48     protected volatile @NonNullByDefault({}) EndpointPoolConfiguration poolConfiguration;
49     private final Logger logger = LoggerFactory.getLogger(AbstractModbusEndpointThingHandler.class);
50     private @NonNullByDefault({}) ModbusCommunicationInterface comms;
51
52     public AbstractModbusEndpointThingHandler(Bridge bridge, ModbusManager modbusManager) {
53         super(bridge);
54         this.modbusManager = modbusManager;
55     }
56
57     @Override
58     public void handleCommand(ChannelUID channelUID, Command command) {
59     }
60
61     @Override
62     public void initialize() {
63         synchronized (this) {
64             logger.trace("Initializing {} from status {}", this.getThing().getUID(), this.getThing().getStatus());
65             if (this.getThing().getStatus().equals(ThingStatus.ONLINE)) {
66                 // If the bridge was online then first change it to offline.
67                 // this ensures that children will be notified about the change
68                 updateStatus(ThingStatus.OFFLINE);
69             }
70             try {
71                 configure();
72                 @Nullable
73                 E endpoint = this.endpoint;
74                 if (endpoint == null) {
75                     throw new IllegalStateException("endpoint null after configuration!");
76                 }
77                 try {
78                     comms = modbusManager.newModbusCommunicationInterface(endpoint, poolConfiguration);
79                     updateStatus(ThingStatus.ONLINE);
80                 } catch (IllegalArgumentException e) {
81                     updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
82                             formatConflictingParameterError());
83                 }
84             } catch (ModbusConfigurationException e) {
85                 logger.debug("Exception during initialization", e);
86                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, String.format(
87                         "Exception during initialization: %s (%s)", e.getMessage(), e.getClass().getSimpleName()));
88             } finally {
89                 logger.trace("initialize() of thing {} '{}' finished", thing.getUID(), thing.getLabel());
90             }
91         }
92     }
93
94     @Override
95     public void dispose() {
96         try {
97             ModbusCommunicationInterface localComms = comms;
98             if (localComms != null) {
99                 localComms.close();
100             }
101         } catch (Exception e) {
102             logger.warn("Error closing modbus communication interface", e);
103         } finally {
104             comms = null;
105         }
106     }
107
108     @Override
109     public @Nullable ModbusCommunicationInterface getCommunicationInterface() {
110         return comms;
111     }
112
113     @Nullable
114     public E getEndpoint() {
115         return endpoint;
116     }
117
118     @Override
119     public abstract int getSlaveId() throws EndpointNotInitializedException;
120
121     /**
122      * Must be overriden by subclasses to initialize config, endpoint, and poolConfiguration
123      */
124     protected abstract void configure() throws ModbusConfigurationException;
125
126     /**
127      * Format error message in case some other endpoint has been configured with different
128      * {@link EndpointPoolConfiguration}
129      */
130     protected abstract String formatConflictingParameterError();
131 }