]> git.basschouten.com Git - openhab-addons.git/blob
a15564f39ba505fbb7fe583c8b979050449901aa
[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.onewire.internal.device;
14
15 import static org.openhab.binding.onewire.internal.OwBindingConstants.*;
16
17 import java.util.ArrayList;
18 import java.util.BitSet;
19 import java.util.List;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.openhab.binding.onewire.internal.DigitalIoConfig;
23 import org.openhab.binding.onewire.internal.OwDynamicStateDescriptionProvider;
24 import org.openhab.binding.onewire.internal.OwException;
25 import org.openhab.binding.onewire.internal.SensorId;
26 import org.openhab.binding.onewire.internal.handler.OwBaseThingHandler;
27 import org.openhab.binding.onewire.internal.handler.OwserverBridgeHandler;
28 import org.openhab.binding.onewire.internal.owserver.OwserverDeviceParameter;
29 import org.openhab.core.config.core.Configuration;
30 import org.openhab.core.library.types.OnOffType;
31 import org.openhab.core.thing.Channel;
32 import org.openhab.core.thing.Thing;
33 import org.openhab.core.types.Command;
34 import org.openhab.core.types.State;
35 import org.openhab.core.types.StateDescription;
36 import org.openhab.core.types.StateDescriptionFragmentBuilder;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  * The {@link AbstractDigitalOwDevice} class defines an abstract digital I/O device
42  *
43  * @author Jan N. Klug - Initial contribution
44  */
45 @NonNullByDefault
46 public abstract class AbstractDigitalOwDevice extends AbstractOwDevice {
47     private final Logger logger = LoggerFactory.getLogger(AbstractDigitalOwDevice.class);
48
49     protected @NonNullByDefault({}) OwserverDeviceParameter fullInParam;
50     protected @NonNullByDefault({}) OwserverDeviceParameter fullOutParam;
51
52     protected final List<DigitalIoConfig> ioConfig = new ArrayList<>();
53
54     public AbstractDigitalOwDevice(SensorId sensorId, OwBaseThingHandler callback) {
55         super(sensorId, callback);
56     }
57
58     @Override
59     public void configureChannels() throws OwException {
60         Thing thing = callback.getThing();
61         OwDynamicStateDescriptionProvider dynamicStateDescriptionProvider = callback
62                 .getDynamicStateDescriptionProvider();
63
64         for (Integer i = 0; i < ioConfig.size(); i++) {
65             String channelId = ioConfig.get(i).getChannelId();
66             Channel channel = thing.getChannel(channelId);
67
68             if (channel != null) {
69                 Configuration channelConfig = channel.getConfiguration();
70
71                 try {
72                     if (channelConfig.get(CONFIG_DIGITAL_MODE) != null) {
73                         ioConfig.get(i).setIoMode((String) channelConfig.get(CONFIG_DIGITAL_MODE));
74                     }
75                     if (channelConfig.get(CONFIG_DIGITAL_LOGIC) != null) {
76                         ioConfig.get(i).setIoLogic((String) channelConfig.get(CONFIG_DIGITAL_LOGIC));
77                     }
78                 } catch (IllegalArgumentException e) {
79                     throw new OwException(channelId + " has invalid configuration");
80                 }
81
82                 if (dynamicStateDescriptionProvider != null) {
83                     StateDescription stateDescription = StateDescriptionFragmentBuilder.create()
84                             .withReadOnly(ioConfig.get(i).isInput()).build().toStateDescription();
85                     if (stateDescription != null) {
86                         dynamicStateDescriptionProvider.setDescription(ioConfig.get(i).getChannelUID(),
87                                 stateDescription);
88                     } else {
89                         logger.warn("Failed to create state description in thing {}", thing.getUID());
90                     }
91                 } else {
92                     logger.debug(
93                             "state description may be inaccurate, state description provider not available in thing {}",
94                             thing.getUID());
95                 }
96
97                 logger.debug("configured {} channel {}: {}", thing.getUID(), i, ioConfig.get(i));
98             } else {
99                 throw new OwException(channelId + " not found");
100             }
101         }
102
103         isConfigured = true;
104     }
105
106     /**
107      * refreshes this sensor - note that the update interval check is not performed as its and i/o device
108      */
109     @Override
110     public void refresh(OwserverBridgeHandler bridgeHandler, Boolean forcedRefresh) throws OwException {
111         logger.trace("refresh of sensor {} started", sensorId);
112         if (isConfigured) {
113             State state;
114
115             BitSet statesSensed = bridgeHandler.readBitSet(sensorId, fullInParam);
116             BitSet statesPIO = bridgeHandler.readBitSet(sensorId, fullOutParam);
117
118             for (int i = 0; i < ioConfig.size(); i++) {
119                 if (ioConfig.get(i).isInput()) {
120                     state = ioConfig.get(i).convertState(statesSensed.get(i));
121                     logger.trace("{} IN{}: raw {}, final {}", sensorId, i, statesSensed, state);
122                 } else {
123                     state = ioConfig.get(i).convertState(statesPIO.get(i));
124                     logger.trace("{} OUT{}: raw {}, final {}", sensorId, i, statesPIO, state);
125                 }
126                 callback.postUpdate(ioConfig.get(i).getChannelId(), state);
127             }
128         }
129     }
130
131     /**
132      * get the number of channels
133      *
134      * @return number of channels
135      */
136     public int getChannelCount() {
137         return ioConfig.size();
138     }
139
140     public boolean writeChannel(OwserverBridgeHandler bridgeHandler, Integer ioChannel, Command command) {
141         if (ioChannel < getChannelCount()) {
142             try {
143                 if (ioConfig.get(ioChannel).isOutput()) {
144                     bridgeHandler.writeDecimalType(sensorId, ioConfig.get(ioChannel).getParameter(),
145                             ioConfig.get(ioChannel).convertState((OnOffType) command));
146                     return true;
147                 } else {
148                     return false;
149                 }
150             } catch (OwException e) {
151                 logger.info("could not write {} to {}: {}", command, ioChannel, e.getMessage());
152                 return false;
153             }
154         } else {
155             throw new IllegalArgumentException("channel number out of range");
156         }
157     }
158 }