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.modbus.sbc.internal;
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;
32 * The {@link ALD1Handler} is responsible for handling commands, which are
33 * sent to one of the channels.
35 * @author Fabian Wolter - Initial contribution
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;
45 public ALD1Handler(Thing thing) {
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);
58 public void modbusInitialize() {
59 config = getConfigAs(ALD1Configuration.class);
61 if (config.pollInterval <= 0) {
62 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
63 "Invalid poll interval: " + config.pollInterval);
67 ModbusReadRequestBlueprint localBlueprint = blueprint = new ModbusReadRequestBlueprint(getSlaveId(),
68 ModbusReadFunctionCode.READ_MULTIPLE_REGISTERS, FIRST_READ_REGISTER - 1, READ_LENGTH, TRIES);
70 updateStatus(ThingStatus.UNKNOWN);
72 registerRegularPoll(localBlueprint, config.pollInterval, 0, this::readSuccessful, this::readError);
75 private void readSuccessful(AsyncModbusReadResult result) {
76 result.getRegisters().ifPresent(registers -> {
77 if (getThing().getStatus() != ThingStatus.ONLINE) {
78 updateStatus(ThingStatus.ONLINE);
81 for (ALD1Registers channel : ALD1Registers.values()) {
82 int index = channel.getRegisterNumber() - FIRST_READ_REGISTER;
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));
92 private void readError(AsyncModbusFailure<ModbusReadRequestBlueprint> error) {
93 updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
94 "Failed to retrieve data: " + error.getCause().getMessage());
97 private ChannelUID createChannelUid(ALD1Registers channel) {
98 return new ChannelUID(thing.getUID(), channel.toString().toLowerCase());