Files
EMS-ESP32/src/core/emsdevicevalue.h

244 lines
8.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* EMS-ESP - https://github.com/emsesp/EMS-ESP
* Copyright 2020-2025 emsesp.org
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef EMSESP_EMSDEVICEVALUE_H_
#define EMSESP_EMSDEVICEVALUE_H_
#include <Arduino.h>
#include <ArduinoJson.h>
#include "helpers.h" // for conversions
#include "default_settings.h" // for enum types
namespace emsesp {
// DeviceValue holds the information for a device entity
class DeviceValue {
public:
enum DeviceValueType : uint8_t {
BOOL,
INT8,
UINT8,
INT16,
UINT16,
UINT24,
TIME, // same as ULONG (32 bits)
UINT32,
ENUM,
STRING,
CMD // special for commands only
};
// Unit Of Measurement mapping - maps to DeviceValueUOM_s in emsdevicevalue.cpp. Sequence is important!!
// also used with HA as uom
// shows also the HA device class being used
enum DeviceValueUOM : uint8_t {
NONE = 0, // 0
DEGREES, // 1 - °C - temperature
DEGREES_R, // 2 - °C (relative temperature) - temperature
PERCENT, // 3 - % - power factor
LMIN, // 4 - l/min - volume flow rate
KWH, // 5 - kWh - energy
WH, // 6 - Wh - energy
HOURS, // 7 - h - duration
MINUTES, // 8 - m - duration
UA, // 9 - µA - current
BAR, // 10 - bar - pressure
KW, // 11 - kW - power
W, // 12 - W - power
KB, // 13 - kB - data size
SECONDS, // 14 - s - duration
DBM, // 15 - dBm - signal strength
FAHRENHEIT, // 16 - °F - temperature
MV, // 17 - mV - voltage
SQM, // 18 - m² - area
M3, // 19 - m³ - volume
L, // 20 - L - volume
KMIN, // 21 - K*min
K, // 22 - K - temperature
VOLTS, // 23 - V - voltage
MBAR, // 24 - mbar - atmospheric pressure
LH, // 25 - l/h - volume flow rate
CTKWH, // 26 - ct/kWh - monetary
HERTZ, // 27 - Hz - frequency
CONNECTIVITY, // 28 - used in HA - connectivity
TIMESTAMP, // 29 - used in HA - timestamp
};
// TAG mapping - maps to DeviceValueTAG_s in emsdevicevalue.cpp
enum DeviceValueTAG : int8_t {
TAG_NONE = -1, // wild card
TAG_DEVICE_DATA = 0,
TAG_HC1,
TAG_HC2,
TAG_HC3,
TAG_HC4,
TAG_HC5,
TAG_HC6,
TAG_HC7,
TAG_HC8,
TAG_DHW1,
TAG_DHW2,
TAG_DHW3,
TAG_DHW4,
TAG_DHW5,
TAG_DHW6,
TAG_DHW7,
TAG_DHW8,
TAG_DHW9,
TAG_DHW10,
TAG_AHS1,
TAG_HS1,
TAG_HS2,
TAG_HS3,
TAG_HS4,
TAG_HS5,
TAG_HS6,
TAG_HS7,
TAG_HS8,
TAG_HS9,
TAG_HS10,
TAG_HS11,
TAG_HS12,
TAG_HS13,
TAG_HS14,
TAG_HS15,
TAG_HS16,
TAG_SRC1,
TAG_SRC2,
TAG_SRC3,
TAG_SRC4,
TAG_SRC5,
TAG_SRC6,
TAG_SRC7,
TAG_SRC8,
TAG_SRC9,
TAG_SRC10,
TAG_SRC11,
TAG_SRC12,
TAG_SRC13,
TAG_SRC14,
TAG_SRC15,
TAG_SRC16
};
// states of a device value
enum DeviceValueState : uint8_t {
// low nibble active state of the device value
DV_DEFAULT = 0, // 0 - does not yet have a value
DV_ACTIVE = (1 << 0), // 1 - has a validated real value
DV_HA_CONFIG_CREATED = (1 << 1), // 2 - set if the HA config topic has been created
DV_HA_CLIMATE_NO_RT = (1 << 2), // 4 - climate created without roomTemp
// high nibble as mask for exclusions & special functions
DV_WEB_EXCLUDE = (1 << 4), // 16 - not shown on web
DV_API_MQTT_EXCLUDE = (1 << 5), // 32 - not shown on mqtt, API
DV_READONLY = (1 << 6), // 64 - read only
DV_FAVORITE = (1 << 7) // 128 - marked as a favorite
};
// numeric operators
// negative numbers used for multipliers
enum DeviceValueNumOp : int8_t {
DV_NUMOP_NONE = 0, // default
DV_NUMOP_DIV2 = 2,
DV_NUMOP_DIV10 = 10,
DV_NUMOP_DIV60 = 60,
DV_NUMOP_DIV100 = 100,
DV_NUMOP_MUL5 = -5,
DV_NUMOP_MUL10 = -10,
DV_NUMOP_MUL15 = -15,
DV_NUMOP_MUL50 = -50
};
// Layout chosen for compact packing AND cache locality on 32-bit ESP32.
// pointers — 5 × 4 bytes, all naturally aligned
void * value_p; // pointer to variable of any type
const char * const short_name; // used in MQTT and API
const char * const * fullname; // used in Web and Console, is translated
const char * const ** options; // options as a flash char array
const char * const * options_single; // options are not translated
// single-byte fields packed together — hot fields, share cache line 0 with the pointers above
uint8_t device_type; // EMSdevice::DeviceType
int8_t tag; // DeviceValueTAG::*
uint8_t type; // DeviceValueType::*
uint8_t state; // DeviceValueState::*
int8_t numeric_operator; // DeviceValueNumOp::*
uint8_t uom; // DeviceValueUOM::*
bool has_cmd; // true if there is a Console/MQTT command which matches the short_name
uint8_t options_size; // number of options in the char array, calculated at class initialization
// wider numeric range fields
int16_t min; // min range
uint32_t max; // max range
// largest member last (cold path: only read during customization save/load and web display)
std::string custom_fullname; // optional, from customization
DeviceValue(uint8_t device_type, // EMSdevice::DeviceType
int8_t tag, // DeviceValueTAG::*
void * value_p, // pointer to variable of any type
uint8_t type, // DeviceValueType::*
const char * const ** options, // options as a flash char array
const char * const * options_single, // options are not translated
int8_t numeric_operator,
const char * const short_name, // used in MQTT and API
const char * const * fullname, // used in Web and Console, is translated
std::string & custom_fullname, // optional, from customization
uint8_t uom, // DeviceValueUOM::*
bool has_cmd, // true if there is a Console/MQTT command which matches the short_name
int16_t min, // min range
uint32_t max, // max range
uint8_t state // DeviceValueState::* (also known as the mask)
);
bool hasValue() const;
bool has_tag() const;
bool get_min_max(int16_t & dv_set_min, uint32_t & dv_set_max);
void set_custom_minmax();
bool get_custom_min(int16_t & val);
bool get_custom_max(uint32_t & val);
std::string get_custom_fullname() const;
std::string get_fullname() const;
static std::string get_name(const std::string & entity);
// dv state flags
void add_state(uint8_t s) {
state |= s;
}
bool has_state(uint8_t s) const {
return (state & s) == s;
}
void remove_state(uint8_t s) {
state &= ~s;
}
uint8_t get_state() const {
return state;
}
static const char * DeviceValueUOM_s[];
static const char * const * DeviceValueTAG_s[];
static const char * const DeviceValueTAG_mqtt[];
static uint8_t NUM_TAGS; // # tags
};
}; // namespace emsesp
#endif