From 93fff51c2e6f4749d44c5d327e57ab3d5f259a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Vuchener?= Date: Sun, 28 Apr 2019 15:15:25 +0200 Subject: [PATCH] Add Battery level/status interface for HID++ 2.0 --- src/libhidpp/CMakeLists.txt | 1 + src/libhidpp/hidpp20/IBatteryLevelStatus.cpp | 61 +++++++++++++ src/libhidpp/hidpp20/IBatteryLevelStatus.h | 96 ++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 src/libhidpp/hidpp20/IBatteryLevelStatus.cpp create mode 100644 src/libhidpp/hidpp20/IBatteryLevelStatus.h diff --git a/src/libhidpp/CMakeLists.txt b/src/libhidpp/CMakeLists.txt index c52ce23..3b82504 100644 --- a/src/libhidpp/CMakeLists.txt +++ b/src/libhidpp/CMakeLists.txt @@ -52,6 +52,7 @@ set(LIBHIDPP_SOURCES hidpp20/IMouseButtonSpy.cpp hidpp20/ITouchpadRawXY.cpp hidpp20/ILEDControl.cpp + hidpp20/IBatteryLevelStatus.cpp hidpp20/ProfileDirectoryFormat.cpp hidpp20/ProfileFormat.cpp hidpp20/MemoryMapping.cpp diff --git a/src/libhidpp/hidpp20/IBatteryLevelStatus.cpp b/src/libhidpp/hidpp20/IBatteryLevelStatus.cpp new file mode 100644 index 0000000..1666448 --- /dev/null +++ b/src/libhidpp/hidpp20/IBatteryLevelStatus.cpp @@ -0,0 +1,61 @@ +/* + * Copyright 2019 Clément Vuchener + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "IBatteryLevelStatus.h" + +#include +#include + +using namespace HIDPP20; + +IBatteryLevelStatus::IBatteryLevelStatus (Device *dev): + FeatureInterface (dev, ID, "BatteryLevelStatus") +{ +} + +IBatteryLevelStatus::LevelStatus IBatteryLevelStatus::getLevelStatus () +{ + auto results = call (GetBatteryLevelStatus); + return parseLevelStatus (results.begin ()); +} + +IBatteryLevelStatus::Capability IBatteryLevelStatus::getCapability () +{ + auto results = call (GetBatteryCapability); + return Capability { + results[0], // number of levels + results[1], // flags + readBE(results, 2), // battery life + results[4], + }; +} + +IBatteryLevelStatus::LevelStatus IBatteryLevelStatus::batteryLevelEvent (const HIDPP::Report &event) +{ + assert (event.function () == BatteryLevelEvent); + return parseLevelStatus (event.parameterBegin ()); +} + +IBatteryLevelStatus::LevelStatus IBatteryLevelStatus::parseLevelStatus (std::vector::const_iterator params) +{ + return LevelStatus { + *(params + 0), // level + *(params + 1), // next level + static_cast(*(params + 2)), // status + }; +} diff --git a/src/libhidpp/hidpp20/IBatteryLevelStatus.h b/src/libhidpp/hidpp20/IBatteryLevelStatus.h new file mode 100644 index 0000000..23449f0 --- /dev/null +++ b/src/libhidpp/hidpp20/IBatteryLevelStatus.h @@ -0,0 +1,96 @@ +/* + * Copyright 2019 Clément Vuchener + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef LIBHIDPP_HIDPP20_IBATTERYLEVELSTATUS_H +#define LIBHIDPP_HIDPP20_IBATTERYLEVELSTATUS_H + +#include + +namespace HIDPP20 +{ + +/** + * Battery informations + * + * If Capability::number_of_levels is 4, the levels are + * - 0% - 10%: critical + * - 11% - 30%: low + * - 31% - 80%: good + * - 81% - 100%: full + */ +class IBatteryLevelStatus: public FeatureInterface +{ +public: + static constexpr uint16_t ID = 0x1000; + + enum Function { + GetBatteryLevelStatus = 0, + GetBatteryCapability = 1, + }; + + enum Event { + BatteryLevelEvent = 0, + }; + + IBatteryLevelStatus (Device *dev); + + enum Status: uint8_t + { + Discharging = 0, // in use + Recharging = 1, + ChargeInFinalState = 2, + ChargeComplete = 3, + RechargingBelowOptimalSpeed = 4, + InvalidBatteryType = 5, + ThermalError = 6, + OtherChargingError = 7, + }; + + struct LevelStatus + { + uint8_t discharge_level; ///< current level in %, 0 means unknown + uint8_t discharge_next_level; ///< next level in % when discharging, 0 otherwise + Status status; + }; + + struct Capability + { + uint8_t number_of_levels; ///< min: 2, max: 100, if less than 10 or mileage is disabled, use 4 + enum Flag: uint8_t { + DisableBatteryOSD = 0x01, + EnableMileageCalculation = 0x02, ///< ignored if number_of_level is less than 10 + Rechargeable = 0x04, + }; + uint8_t flags; + uint16_t nominal_battery_life; ///< only used when mileage is enabled. + uint8_t critical_level; ///< in %, only used when mileage is enabled + }; + + LevelStatus getLevelStatus (); + Capability getCapability (); + + static LevelStatus batteryLevelEvent (const HIDPP::Report &event); + +private: + static LevelStatus parseLevelStatus (std::vector::const_iterator params); +}; + +} + +#endif +