]> git.basschouten.com Git - openhab-addons.git/blob
0dffcb1cf7290ae3e188cabc21ada45ff691d8b8
[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.modbus.sbc.internal;
14
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.openhab.binding.modbus.handler.BaseModbusThingHandler;
18 import org.openhab.core.io.transport.modbus.AsyncModbusFailure;
19 import org.openhab.core.io.transport.modbus.AsyncModbusReadResult;
20 import org.openhab.core.io.transport.modbus.ModbusBitUtilities;
21 import org.openhab.core.io.transport.modbus.ModbusReadFunctionCode;
22 import org.openhab.core.io.transport.modbus.ModbusReadRequestBlueprint;
23 import org.openhab.core.library.types.QuantityType;
24 import org.openhab.core.thing.ChannelUID;
25 import org.openhab.core.thing.Thing;
26 import org.openhab.core.thing.ThingStatus;
27 import org.openhab.core.thing.ThingStatusDetail;
28 import org.openhab.core.types.Command;
29 import org.openhab.core.types.RefreshType;
30
31 /**
32  * The {@link ALD1Handler} is responsible for handling commands, which are
33  * sent to one of the channels.
34  *
35  * @author Fabian Wolter - Initial contribution
36  */
37 @NonNullByDefault
38 public class ALD1Handler extends BaseModbusThingHandler {
39     private static final int FIRST_READ_REGISTER = 28;
40     private static final int READ_LENGTH = 13;
41     private static final int TRIES = 1;
42     private ALD1Configuration config = new ALD1Configuration();
43     private @Nullable ModbusReadRequestBlueprint blueprint;
44
45     public ALD1Handler(Thing thing) {
46         super(thing);
47     }
48
49     @Override
50     public void handleCommand(ChannelUID channelUID, Command command) {
51         ModbusReadRequestBlueprint localBlueprint = blueprint;
52         if (command instanceof RefreshType && localBlueprint != null) {
53             submitOneTimePoll(localBlueprint, this::readSuccessful, this::readError);
54         }
55     }
56
57     @Override
58     public void modbusInitialize() {
59         config = getConfigAs(ALD1Configuration.class);
60
61         if (config.pollInterval <= 0) {
62             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
63                     "Invalid poll interval: " + config.pollInterval);
64             return;
65         }
66
67         ModbusReadRequestBlueprint localBlueprint = blueprint = new ModbusReadRequestBlueprint(getSlaveId(),
68                 ModbusReadFunctionCode.READ_MULTIPLE_REGISTERS, FIRST_READ_REGISTER - 1, READ_LENGTH, TRIES);
69
70         updateStatus(ThingStatus.UNKNOWN);
71
72         registerRegularPoll(localBlueprint, config.pollInterval, 0, this::readSuccessful, this::readError);
73     }
74
75     private void readSuccessful(AsyncModbusReadResult result) {
76         result.getRegisters().ifPresent(registers -> {
77             if (getThing().getStatus() != ThingStatus.ONLINE) {
78                 updateStatus(ThingStatus.ONLINE);
79             }
80
81             for (ALD1Registers channel : ALD1Registers.values()) {
82                 int index = channel.getRegisterNumber() - FIRST_READ_REGISTER;
83
84                 ModbusBitUtilities.extractStateFromRegisters(registers, index, channel.getType())
85                         .map(d -> d.toBigDecimal().multiply(channel.getMultiplier()))
86                         .map(bigDecimal -> new QuantityType<>(bigDecimal, channel.getUnit()))
87                         .ifPresent(v -> updateState(createChannelUid(channel), v));
88             }
89         });
90     }
91
92     private void readError(AsyncModbusFailure<ModbusReadRequestBlueprint> error) {
93         updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
94                 "Failed to retrieve data: " + error.getCause().getMessage());
95     }
96
97     private ChannelUID createChannelUid(ALD1Registers channel) {
98         return new ChannelUID(thing.getUID(), channel.toString().toLowerCase());
99     }
100 }