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.onewire.internal.device;
15 import static org.openhab.binding.onewire.internal.OwBindingConstants.*;
17 import java.util.ArrayList;
18 import java.util.BitSet;
19 import java.util.List;
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;
41 * The {@link AbstractDigitalOwDevice} class defines an abstract digital I/O device
43 * @author Jan N. Klug - Initial contribution
46 public abstract class AbstractDigitalOwDevice extends AbstractOwDevice {
47 private final Logger logger = LoggerFactory.getLogger(AbstractDigitalOwDevice.class);
49 protected @NonNullByDefault({}) OwserverDeviceParameter fullInParam;
50 protected @NonNullByDefault({}) OwserverDeviceParameter fullOutParam;
52 protected final List<DigitalIoConfig> ioConfig = new ArrayList<>();
54 public AbstractDigitalOwDevice(SensorId sensorId, OwBaseThingHandler callback) {
55 super(sensorId, callback);
59 public void configureChannels() throws OwException {
60 Thing thing = callback.getThing();
61 OwDynamicStateDescriptionProvider dynamicStateDescriptionProvider = callback
62 .getDynamicStateDescriptionProvider();
64 for (Integer i = 0; i < ioConfig.size(); i++) {
65 String channelId = ioConfig.get(i).getChannelId();
66 Channel channel = thing.getChannel(channelId);
68 if (channel != null) {
69 Configuration channelConfig = channel.getConfiguration();
72 if (channelConfig.get(CONFIG_DIGITAL_MODE) != null) {
73 ioConfig.get(i).setIoMode((String) channelConfig.get(CONFIG_DIGITAL_MODE));
75 if (channelConfig.get(CONFIG_DIGITAL_LOGIC) != null) {
76 ioConfig.get(i).setIoLogic((String) channelConfig.get(CONFIG_DIGITAL_LOGIC));
78 } catch (IllegalArgumentException e) {
79 throw new OwException(channelId + " has invalid configuration");
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(),
89 logger.warn("Failed to create state description in thing {}", thing.getUID());
93 "state description may be inaccurate, state description provider not available in thing {}",
97 logger.debug("configured {} channel {}: {}", thing.getUID(), i, ioConfig.get(i));
99 throw new OwException(channelId + " not found");
107 * refreshes this sensor - note that the update interval check is not performed as its and i/o device
110 public void refresh(OwserverBridgeHandler bridgeHandler, Boolean forcedRefresh) throws OwException {
111 logger.trace("refresh of sensor {} started", sensorId);
115 BitSet statesSensed = bridgeHandler.readBitSet(sensorId, fullInParam);
116 BitSet statesPIO = bridgeHandler.readBitSet(sensorId, fullOutParam);
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);
123 state = ioConfig.get(i).convertState(statesPIO.get(i));
124 logger.trace("{} OUT{}: raw {}, final {}", sensorId, i, statesPIO, state);
126 callback.postUpdate(ioConfig.get(i).getChannelId(), state);
132 * get the number of channels
134 * @return number of channels
136 public int getChannelCount() {
137 return ioConfig.size();
140 public boolean writeChannel(OwserverBridgeHandler bridgeHandler, Integer ioChannel, Command command) {
141 if (ioChannel < getChannelCount()) {
143 if (ioConfig.get(ioChannel).isOutput()) {
144 bridgeHandler.writeDecimalType(sensorId, ioConfig.get(ioChannel).getParameter(),
145 ioConfig.get(ioChannel).convertState((OnOffType) command));
150 } catch (OwException e) {
151 logger.info("could not write {} to {}: {}", command, ioChannel, e.getMessage());
155 throw new IllegalArgumentException("channel number out of range");