]> git.basschouten.com Git - openhab-addons.git/blob
f6d652575ee1318fd200130740a6b5e9f392a34d
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 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.velbus.internal.handler;
14
15 import static org.openhab.binding.velbus.internal.VelbusBindingConstants.COMMAND_SENSOR_TEMPERATURE;
16
17 import java.util.concurrent.ScheduledFuture;
18 import java.util.concurrent.TimeUnit;
19
20 import javax.measure.quantity.Temperature;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.binding.velbus.internal.config.VelbusSensorConfig;
25 import org.openhab.binding.velbus.internal.packets.VelbusPacket;
26 import org.openhab.binding.velbus.internal.packets.VelbusSensorTemperatureRequestPacket;
27 import org.openhab.core.library.types.QuantityType;
28 import org.openhab.core.library.unit.SIUnits;
29 import org.openhab.core.thing.ChannelUID;
30 import org.openhab.core.thing.Thing;
31 import org.openhab.core.thing.ThingStatus;
32 import org.openhab.core.thing.ThingStatusDetail;
33 import org.openhab.core.types.Command;
34 import org.openhab.core.types.RefreshType;
35
36 /**
37  * The {@link VelbusTemperatureSensorHandler} is responsible for handling commands, which are
38  * sent to one of the channels.
39  *
40  * @author Cedric Boon - Initial contribution
41  */
42 @NonNullByDefault
43 public abstract class VelbusTemperatureSensorHandler extends VelbusSensorWithAlarmClockHandler {
44     private @Nullable ScheduledFuture<?> refreshJob;
45     private @NonNullByDefault({}) VelbusSensorConfig sensorConfig;
46     private ChannelUID temperatureChannel;
47
48     public VelbusTemperatureSensorHandler(Thing thing, int numberOfSubAddresses, ChannelUID temperatureChannel) {
49         super(thing, numberOfSubAddresses);
50
51         this.temperatureChannel = temperatureChannel;
52     }
53
54     @Override
55     public void initialize() {
56         this.sensorConfig = getConfigAs(VelbusSensorConfig.class);
57
58         super.initialize();
59
60         initializeAutomaticRefresh();
61     }
62
63     private void initializeAutomaticRefresh() {
64         int refreshInterval = this.sensorConfig.refresh;
65
66         if (refreshInterval > 0) {
67             startAutomaticRefresh(refreshInterval);
68         }
69     }
70
71     @Override
72     public void dispose() {
73         final ScheduledFuture<?> refreshJob = this.refreshJob;
74         if (refreshJob != null) {
75             refreshJob.cancel(true);
76         }
77     }
78
79     private void startAutomaticRefresh(int refreshInterval) {
80         VelbusBridgeHandler velbusBridgeHandler = getVelbusBridgeHandler();
81         if (velbusBridgeHandler == null) {
82             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
83             return;
84         }
85
86         refreshJob = scheduler.scheduleWithFixedDelay(() -> {
87             sendSensorReadoutRequest(velbusBridgeHandler);
88         }, 0, refreshInterval, TimeUnit.SECONDS);
89     }
90
91     @Override
92     public void handleCommand(ChannelUID channelUID, Command command) {
93         super.handleCommand(channelUID, command);
94
95         VelbusBridgeHandler velbusBridgeHandler = getVelbusBridgeHandler();
96         if (velbusBridgeHandler == null) {
97             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
98             return;
99         }
100
101         if (command instanceof RefreshType) {
102             if (channelUID.equals(temperatureChannel)) {
103                 sendSensorReadoutRequest(velbusBridgeHandler);
104             }
105         }
106     }
107
108     protected void sendSensorReadoutRequest(VelbusBridgeHandler velbusBridgeHandler) {
109         VelbusSensorTemperatureRequestPacket packet = new VelbusSensorTemperatureRequestPacket(
110                 getModuleAddress().getAddress());
111
112         byte[] packetBytes = packet.getBytes();
113         velbusBridgeHandler.sendPacket(packetBytes);
114     }
115
116     @Override
117     public void onPacketReceived(byte[] packet) {
118         super.onPacketReceived(packet);
119
120         logger.trace("onPacketReceived() was called");
121
122         if (packet[0] == VelbusPacket.STX && packet.length >= 5) {
123             byte command = packet[4];
124
125             if (command == COMMAND_SENSOR_TEMPERATURE && packet.length >= 6) {
126                 byte highByteCurrentSensorTemperature = packet[5];
127                 byte lowByteCurrentSensorTemperature = packet[6];
128
129                 boolean negative = (highByteCurrentSensorTemperature & 0x80) == 0x80;
130                 double temperature = ((((highByteCurrentSensorTemperature & 0x7f) << 3)
131                         + ((lowByteCurrentSensorTemperature & 0xff) >> 5)) - (negative ? 0x400 : 0)) * 0.0625;
132                 QuantityType<Temperature> state = new QuantityType<>(temperature, SIUnits.CELSIUS);
133                 updateState(temperatureChannel, state);
134             }
135         }
136     }
137 }