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