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.mihome.internal.handler;
15 import static org.openhab.binding.mihome.internal.XiaomiGatewayBindingConstants.*;
17 import org.openhab.core.library.types.DecimalType;
18 import org.openhab.core.library.types.OnOffType;
19 import org.openhab.core.thing.ChannelUID;
20 import org.openhab.core.thing.Thing;
21 import org.openhab.core.types.Command;
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
25 import com.google.gson.JsonObject;
28 * Abstract base class for battery powered Xiaomi sensor devices
30 * @author Dieter Schmidt - Initial contribution
32 public abstract class XiaomiSensorBaseHandler extends XiaomiDeviceBaseHandler {
34 private static final int VOLTAGE_MAX_MILLIVOLTS = 3100;
35 private static final int VOLTAGE_MIN_MILLIVOLTS = 2700;
36 private static final int BATT_LEVEL_LOW = 20;
37 private static final int BATT_LEVEL_LOW_HYS = 5;
39 private static final String STATUS = "status";
40 private static final String VOLTAGE = "voltage";
42 private boolean isBatteryLow = false;
44 private final Logger logger = LoggerFactory.getLogger(XiaomiSensorBaseHandler.class);
46 public XiaomiSensorBaseHandler(Thing thing) {
51 void parseHeartbeat(JsonObject data) {
56 void parseReadAck(JsonObject data) {
61 void parseDefault(JsonObject data) {
62 if (data.get(VOLTAGE) != null) {
63 Integer voltage = data.get(VOLTAGE).getAsInt();
64 calculateBatteryLevelFromVoltage(voltage);
66 if (data.get(STATUS) != null) {
68 "Got status {} - Apart from \"report\" all other status updates for sensors seem not right (Firmware 1.4.1.145)",
73 void calculateBatteryLevelFromVoltage(Integer voltage) {
74 int limVoltage = voltage;
75 limVoltage = Math.min(VOLTAGE_MAX_MILLIVOLTS, limVoltage);
76 limVoltage = Math.max(VOLTAGE_MIN_MILLIVOLTS, limVoltage);
77 Integer battLevel = (int) ((float) (limVoltage - VOLTAGE_MIN_MILLIVOLTS)
78 / (float) (VOLTAGE_MAX_MILLIVOLTS - VOLTAGE_MIN_MILLIVOLTS) * 100);
79 updateState(CHANNEL_BATTERY_LEVEL, new DecimalType(battLevel));
80 int lowThreshold = isBatteryLow ? BATT_LEVEL_LOW + BATT_LEVEL_LOW_HYS : BATT_LEVEL_LOW;
81 if (battLevel <= lowThreshold) {
82 updateState(CHANNEL_LOW_BATTERY, OnOffType.ON);
85 updateState(CHANNEL_LOW_BATTERY, OnOffType.OFF);
91 void execute(ChannelUID channelUID, Command command) {
92 logger.warn("Cannot execute command - Sensors by definition only have read only channels");