]> git.basschouten.com Git - openhab-addons.git/blob
7ab53f936de3ce65809d97046efc61ad37ffdd18
[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.handler;
14
15 import static org.openhab.binding.onewire.internal.OwBindingConstants.*;
16
17 import java.util.Collections;
18 import java.util.HashSet;
19 import java.util.Map;
20 import java.util.Set;
21 import java.util.stream.Collectors;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.openhab.binding.onewire.internal.OwDynamicStateDescriptionProvider;
25 import org.openhab.binding.onewire.internal.OwException;
26 import org.openhab.binding.onewire.internal.config.BAE091xHandlerConfiguration;
27 import org.openhab.binding.onewire.internal.device.BAE0910;
28 import org.openhab.binding.onewire.internal.device.OwChannelConfig;
29 import org.openhab.binding.onewire.internal.device.OwSensorType;
30 import org.openhab.core.library.types.OnOffType;
31 import org.openhab.core.thing.Bridge;
32 import org.openhab.core.thing.ChannelUID;
33 import org.openhab.core.thing.Thing;
34 import org.openhab.core.thing.ThingStatus;
35 import org.openhab.core.thing.ThingStatusDetail;
36 import org.openhab.core.thing.ThingTypeUID;
37 import org.openhab.core.thing.ThingUID;
38 import org.openhab.core.thing.binding.builder.ThingBuilder;
39 import org.openhab.core.types.Command;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42
43 /**
44  * The {@link BAE091xSensorThingHandler} is responsible for handling BAE0910 based multisensors
45  *
46  * @author Jan N. Klug - Initial contribution
47  */
48 @NonNullByDefault
49 public class BAE091xSensorThingHandler extends OwBaseThingHandler {
50     public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Collections.singleton(THING_TYPE_BAE091X);
51
52     private final Logger logger = LoggerFactory.getLogger(BAE091xSensorThingHandler.class);
53
54     public static final Set<OwSensorType> SUPPORTED_SENSOR_TYPES = Collections.singleton(OwSensorType.BAE0910);
55
56     public BAE091xSensorThingHandler(Thing thing, OwDynamicStateDescriptionProvider dynamicStateDescriptionProvider) {
57         super(thing, dynamicStateDescriptionProvider, SUPPORTED_SENSOR_TYPES);
58     }
59
60     @Override
61     public void handleCommand(ChannelUID channelUID, Command command) {
62         if (command instanceof OnOffType) {
63             if (channelUID.getId().startsWith(CHANNEL_DIGITAL)) {
64                 Bridge bridge = getBridge();
65                 if (bridge != null) {
66                     OwserverBridgeHandler bridgeHandler = (OwserverBridgeHandler) bridge.getHandler();
67                     if (bridgeHandler != null) {
68                         if (!((BAE0910) sensors.get(0)).writeChannel(bridgeHandler, channelUID.getId(), command)) {
69                             logger.debug("writing to channel {} in thing {} not permitted (input channel)", channelUID,
70                                     this.thing.getUID());
71                         }
72                     } else {
73                         logger.warn("bridge handler not found");
74                     }
75                 } else {
76                     logger.warn("bridge not found");
77                 }
78             }
79         }
80         // TODO: PWM channels
81         super.handleCommand(channelUID, command);
82     }
83
84     @Override
85     public void initialize() {
86         if (!super.configureThingHandler()) {
87             return;
88         }
89
90         sensors.add(new BAE0910(sensorId, this));
91
92         scheduler.execute(() -> {
93             configureThingChannels();
94         });
95     }
96
97     @Override
98     protected void configureThingChannels() {
99         ThingUID thingUID = getThing().getUID();
100         logger.debug("configuring sensors for {}", thingUID);
101
102         BAE091xHandlerConfiguration configuration = getConfig().as(BAE091xHandlerConfiguration.class);
103
104         Set<OwChannelConfig> wantedChannel = new HashSet<>();
105         wantedChannel.addAll(SENSOR_TYPE_CHANNEL_MAP.getOrDefault(sensorType, Set.of()));
106
107         // Pin1:
108         switch (configuration.pin1) {
109             case CONFIG_BAE_PIN_DISABLED:
110                 break;
111             case CONFIG_BAE_PIN_COUNTER:
112                 wantedChannel.add(new OwChannelConfig(CHANNEL_COUNTER, CHANNEL_TYPE_UID_BAE_COUNTER));
113                 break;
114             default:
115                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
116                         "unknown configuration option for pin 1");
117                 return;
118         }
119
120         // Pin2:
121         switch (configuration.pin2) {
122             case CONFIG_BAE_PIN_DISABLED:
123                 break;
124             case CONFIG_BAE_PIN_OUT:
125                 wantedChannel.add(
126                         new OwChannelConfig(CHANNEL_DIGITAL2, CHANNEL_TYPE_UID_BAE_DIGITAL_OUT, "Digital Out Pin 2"));
127                 break;
128             case CONFIG_BAE_PIN_PWM:
129                 wantedChannel
130                         .add(new OwChannelConfig(CHANNEL_PWM_DUTY3, CHANNEL_TYPE_UID_BAE_PWM_DUTY, "Duty Cycle PWM 3"));
131                 wantedChannel.add(new OwChannelConfig(CHANNEL_PWM_FREQ1, CHANNEL_TYPE_UID_BAE_PWM_FREQUENCY,
132                         "Frequency PWM 1/3"));
133                 break;
134             default:
135                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
136                         "unknown configuration option for pin 2");
137                 return;
138         }
139
140         // Pin6:
141         switch (configuration.pin6) {
142             case CONFIG_BAE_PIN_DISABLED:
143                 break;
144             case CONFIG_BAE_PIN_PIO:
145                 wantedChannel.add(new OwChannelConfig(CHANNEL_DIGITAL6, CHANNEL_TYPE_UID_BAE_PIO, "PIO Pin 6"));
146                 break;
147             case CONFIG_BAE_PIN_PWM:
148                 wantedChannel
149                         .add(new OwChannelConfig(CHANNEL_PWM_DUTY4, CHANNEL_TYPE_UID_BAE_PWM_DUTY, "Duty Cycle PWM 4"));
150                 wantedChannel.add(new OwChannelConfig(CHANNEL_PWM_FREQ2, CHANNEL_TYPE_UID_BAE_PWM_FREQUENCY,
151                         "Frequency PWM 2/4"));
152                 break;
153             default:
154                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
155                         "unknown configuration option for pin 6");
156                 return;
157         }
158
159         // Pin7:
160         switch (configuration.pin7) {
161             case CONFIG_BAE_PIN_DISABLED:
162                 break;
163             case CONFIG_BAE_PIN_ANALOG:
164                 wantedChannel.add(new OwChannelConfig(CHANNEL_VOLTAGE, CHANNEL_TYPE_UID_BAE_ANALOG, "Analog Input"));
165                 break;
166             case CONFIG_BAE_PIN_OUT:
167                 wantedChannel.add(
168                         new OwChannelConfig(CHANNEL_DIGITAL7, CHANNEL_TYPE_UID_BAE_DIGITAL_OUT, "Digital Out Pin 7"));
169                 break;
170             case CONFIG_BAE_PIN_PWM:
171                 wantedChannel
172                         .add(new OwChannelConfig(CHANNEL_PWM_DUTY2, CHANNEL_TYPE_UID_BAE_PWM_DUTY, "Duty Cycle PWM 2"));
173                 wantedChannel.add(new OwChannelConfig(CHANNEL_PWM_FREQ2, CHANNEL_TYPE_UID_BAE_PWM_FREQUENCY,
174                         "Frequency PWM 2/4"));
175                 break;
176             default:
177                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
178                         "unknown configuration option for pin 7");
179                 return;
180         }
181
182         // Pin8:
183         switch (configuration.pin8) {
184             case CONFIG_BAE_PIN_DISABLED:
185                 break;
186             case CONFIG_BAE_PIN_IN:
187                 wantedChannel.add(new OwChannelConfig(CHANNEL_DIGITAL8, CHANNEL_TYPE_UID_BAE_DIN, "Digital In Pin 8"));
188                 break;
189             case CONFIG_BAE_PIN_OUT:
190                 wantedChannel
191                         .add(new OwChannelConfig(CHANNEL_DIGITAL8, CHANNEL_TYPE_UID_BAE_DOUT, "Digital Out Pin 8"));
192                 break;
193             case CONFIG_BAE_PIN_PWM:
194                 wantedChannel
195                         .add(new OwChannelConfig(CHANNEL_PWM_DUTY1, CHANNEL_TYPE_UID_BAE_PWM_DUTY, "Duty Cycle PWM 1"));
196                 wantedChannel.add(new OwChannelConfig(CHANNEL_PWM_FREQ1, CHANNEL_TYPE_UID_BAE_PWM_FREQUENCY,
197                         "Frequency PWM 1/3"));
198
199                 break;
200             default:
201                 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
202                         "unknown configuration option for pin 8");
203                 return;
204         }
205
206         ThingBuilder thingBuilder = editThing();
207
208         // remove unwanted channels
209         Set<String> existingChannelIds = thing.getChannels().stream().map(channel -> channel.getUID().getId())
210                 .collect(Collectors.toSet());
211         Set<String> wantedChannelIds = wantedChannel.stream().map(channelConfig -> channelConfig.channelId)
212                 .collect(Collectors.toSet());
213         existingChannelIds.stream().filter(channelId -> !wantedChannelIds.contains(channelId))
214                 .forEach(channelId -> removeChannelIfExisting(thingBuilder, channelId));
215
216         // add or update wanted channels
217         wantedChannel.stream().forEach(channelConfig -> {
218             addChannelIfMissingAndEnable(thingBuilder, channelConfig);
219         });
220
221         updateThing(thingBuilder.build());
222
223         try {
224             sensors.get(0).configureChannels();
225         } catch (OwException e) {
226             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
227             return;
228         }
229
230         validConfig = true;
231         updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE);
232     }
233
234     @Override
235     public void updateSensorProperties(OwserverBridgeHandler bridgeHandler) throws OwException {
236         Map<String, String> properties = editProperties();
237
238         sensorType = BAE0910.getDeviceSubType(bridgeHandler, sensorId);
239
240         properties.put(PROPERTY_MODELID, sensorType.toString());
241         properties.put(PROPERTY_VENDOR, "Brain4home");
242
243         updateProperties(properties);
244
245         logger.trace("updated modelid/vendor to {} / {}", sensorType.name(), "Brain4home");
246     }
247 }