diff --git a/esphome/components/esp32_ble_tracker/__init__.py b/esphome/components/esp32_ble_tracker/__init__.py index 4aa5b1610a..3d48eafde4 100644 --- a/esphome/components/esp32_ble_tracker/__init__.py +++ b/esphome/components/esp32_ble_tracker/__init__.py @@ -6,7 +6,7 @@ from esphome.const import CONF_ID, ESP_PLATFORM_ESP32, CONF_INTERVAL, \ from esphome.core import coroutine ESP_PLATFORMS = [ESP_PLATFORM_ESP32] -AUTO_LOAD = ['xiaomi_ble'] +AUTO_LOAD = ['xiaomi_ble', 'ruuvi_ble'] CONF_ESP32_BLE_ID = 'esp32_ble_id' CONF_SCAN_PARAMETERS = 'scan_parameters' diff --git a/esphome/components/ruuvi_ble/__init__.py b/esphome/components/ruuvi_ble/__init__.py new file mode 100644 index 0000000000..05ba008dd0 --- /dev/null +++ b/esphome/components/ruuvi_ble/__init__.py @@ -0,0 +1,18 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import esp32_ble_tracker +from esphome.const import CONF_ID + +DEPENDENCIES = ['esp32_ble_tracker'] + +ruuvi_ble_ns = cg.esphome_ns.namespace('ruuvi_ble') +RuuviListener = ruuvi_ble_ns.class_('RuuviListener', esp32_ble_tracker.ESPBTDeviceListener) + +CONFIG_SCHEMA = cv.Schema({ + cv.GenerateID(): cv.declare_id(RuuviListener), +}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA) + + +def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + yield esp32_ble_tracker.register_ble_device(var, config) diff --git a/esphome/components/ruuvi_ble/ruuvi_ble.cpp b/esphome/components/ruuvi_ble/ruuvi_ble.cpp new file mode 100644 index 0000000000..28a689fee4 --- /dev/null +++ b/esphome/components/ruuvi_ble/ruuvi_ble.cpp @@ -0,0 +1,147 @@ +#include "ruuvi_ble.h" +#include "esphome/core/log.h" + +#ifdef ARDUINO_ARCH_ESP32 + +namespace esphome { +namespace ruuvi_ble { + +static const char *TAG = "ruuvi_ble"; + +bool parse_ruuvi_data_byte(uint8_t data_type, uint8_t data_length, const uint8_t *data, RuuviParseResult &result) { + switch (data_type) { + case 0x03: { // RAWv1 + if (data_length != 16) + return false; + + const uint8_t temp_sign = (data[1] >> 7) & 1; + const float temp_val = (data[1] & 0x7F) + (data[2] / 100.0f); + const float temperature = temp_sign == 0 ? temp_val : -1 * temp_val; + + const float humidity = data[0] * 0.5f; + const float pressure = (uint16_t(data[3] << 8) + uint16_t(data[4]) + 50000.0f) / 100.0f; + const float acceleration_x = (int16_t(data[5] << 8) + int16_t(data[6])) / 1000.0f; + const float acceleration_y = (int16_t(data[7] << 8) + int16_t(data[8])) / 1000.0f; + const float acceleration_z = (int16_t(data[9] << 8) + int16_t(data[10])) / 1000.0f; + const float battery_voltage = (uint16_t(data[11] << 8) + uint16_t(data[12])) / 1000.0f; + + result.humidity = humidity; + result.temperature = temperature; + result.pressure = pressure; + result.acceleration_x = acceleration_x; + result.acceleration_y = acceleration_y; + result.acceleration_z = acceleration_z; + result.acceleration = + sqrt(acceleration_x * acceleration_x + acceleration_y * acceleration_y + acceleration_z * acceleration_z); + result.battery_voltage = battery_voltage; + + return true; + } + case 0x05: { // RAWv2 + if (data_length != 26) + return false; + + const float temperature = (int16_t(data[0] << 8) + int16_t(data[1])) * 0.005f; + const float humidity = (uint16_t(data[2] << 8) | uint16_t(data[3])) / 400.0f; + const float pressure = ((uint16_t(data[4] << 8) | uint16_t(data[5])) + 50000.0f) / 100.0f; + const float acceleration_x = (int16_t(data[6] << 8) + int16_t(data[7])) / 1000.0f; + const float acceleration_y = (int16_t(data[8] << 8) + int16_t(data[9])) / 1000.0f; + const float acceleration_z = (int16_t(data[10] << 8) + int16_t(data[11])) / 1000.0f; + + const uint8_t power_info = (data[12] << 8) | data[13]; + const float battery_voltage = ((power_info >> 5) + 1600.0f) / 1000.0f; + const float tx_power = ((power_info & 0x1F) * 2.0f) - 40.0f; + + const float movement_counter = float(data[14]); + const float measurement_sequence_number = float(uint16_t(data[15] << 8) | uint16_t(data[16])); + + result.temperature = data[0] == 0x7F && data[1] == 0xFF ? NAN : temperature; + result.humidity = data[2] == 0xFF && data[3] == 0xFF ? NAN : humidity; + result.pressure = data[4] == 0xFF && data[5] == 0xFF ? NAN : pressure; + result.acceleration_x = data[6] == 0xFF && data[7] == 0xFF ? NAN : acceleration_x; + result.acceleration_y = data[8] == 0xFF && data[9] == 0xFF ? NAN : acceleration_y; + result.acceleration_z = data[10] == 0xFF && data[11] == 0xFF ? NAN : acceleration_z; + result.acceleration = result.acceleration_x == NAN || result.acceleration_y == NAN || result.acceleration_z == NAN + ? NAN + : sqrt(acceleration_x * acceleration_x + acceleration_y * acceleration_y + + acceleration_z * acceleration_z); + result.battery_voltage = (power_info >> 5) == 0x7FF ? NAN : battery_voltage; + result.tx_power = (power_info & 0x1F) == 0x1F ? NAN : tx_power; + result.movement_counter = movement_counter; + result.measurement_sequence_number = measurement_sequence_number; + + return true; + } + default: + return false; + } +} +optional parse_ruuvi(const esp32_ble_tracker::ESPBTDevice &device) { + const auto *raw = reinterpret_cast(device.get_manufacturer_data().data()); + + bool is_ruuvi = raw[0] == 0x99 && raw[1] == 0x04; + + if (!is_ruuvi) { + return {}; + } + + const uint8_t data_length = device.get_manufacturer_data().size(); + const uint8_t format = raw[2]; + const uint8_t *data = &raw[3]; + + RuuviParseResult result; + + bool success = parse_ruuvi_data_byte(format, data_length, data, result); + if (!success) + return {}; + return result; +} + +bool RuuviListener::parse_device(const esp32_ble_tracker::ESPBTDevice &device) { + auto res = parse_ruuvi(device); + if (!res.has_value()) + return false; + + ESP_LOGD(TAG, "Got RuuviTag (%s):", device.address_str().c_str()); + + if (res->humidity.has_value()) { + ESP_LOGD(TAG, " Humidity: %.2f%%", *res->humidity); + } + if (res->temperature.has_value()) { + ESP_LOGD(TAG, " Temperature: %.2f°C", *res->temperature); + } + if (res->pressure.has_value()) { + ESP_LOGD(TAG, " Pressure: %.2fhPa", *res->pressure); + } + if (res->acceleration.has_value()) { + ESP_LOGD(TAG, " Acceleration: %.3fG", *res->acceleration); + } + if (res->acceleration_x.has_value()) { + ESP_LOGD(TAG, " Acceleration X: %.3fG", *res->acceleration_x); + } + if (res->acceleration_y.has_value()) { + ESP_LOGD(TAG, " Acceleration Y: %.3fG", *res->acceleration_y); + } + if (res->acceleration_z.has_value()) { + ESP_LOGD(TAG, " Acceleration Z: %.3fG", *res->acceleration_z); + } + if (res->battery_voltage.has_value()) { + ESP_LOGD(TAG, " Battery Voltage: %.3fV", *res->battery_voltage); + } + if (res->tx_power.has_value()) { + ESP_LOGD(TAG, " TX Power: %.0fdBm", *res->tx_power); + } + if (res->movement_counter.has_value()) { + ESP_LOGD(TAG, " Movement Counter: %.0f", *res->movement_counter); + } + if (res->measurement_sequence_number.has_value()) { + ESP_LOGD(TAG, " Measurement Sequence Number: %.0f", *res->measurement_sequence_number); + } + + return true; +} + +} // namespace ruuvi_ble +} // namespace esphome + +#endif diff --git a/esphome/components/ruuvi_ble/ruuvi_ble.h b/esphome/components/ruuvi_ble/ruuvi_ble.h new file mode 100644 index 0000000000..848004f3d7 --- /dev/null +++ b/esphome/components/ruuvi_ble/ruuvi_ble.h @@ -0,0 +1,37 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h" + +#ifdef ARDUINO_ARCH_ESP32 + +namespace esphome { +namespace ruuvi_ble { + +struct RuuviParseResult { + optional humidity; + optional temperature; + optional pressure; + optional acceleration; + optional acceleration_x; + optional acceleration_y; + optional acceleration_z; + optional battery_voltage; + optional tx_power; + optional movement_counter; + optional measurement_sequence_number; +}; + +bool parse_ruuvi_data_byte(uint8_t data_type, const uint8_t *data, uint8_t data_length, RuuviParseResult &result); + +optional parse_ruuvi(const esp32_ble_tracker::ESPBTDevice &device); + +class RuuviListener : public esp32_ble_tracker::ESPBTDeviceListener { + public: + bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override; +}; + +} // namespace ruuvi_ble +} // namespace esphome + +#endif diff --git a/esphome/components/ruuvitag/__init__.py b/esphome/components/ruuvitag/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/esphome/components/ruuvitag/ruuvitag.cpp b/esphome/components/ruuvitag/ruuvitag.cpp new file mode 100644 index 0000000000..2963b777d1 --- /dev/null +++ b/esphome/components/ruuvitag/ruuvitag.cpp @@ -0,0 +1,29 @@ +#include "ruuvitag.h" +#include "esphome/core/log.h" + +#ifdef ARDUINO_ARCH_ESP32 + +namespace esphome { +namespace ruuvitag { + +static const char *TAG = "ruuvitag"; + +void RuuviTag::dump_config() { + ESP_LOGCONFIG(TAG, "RuuviTag"); + LOG_SENSOR(" ", "Humidity", this->humidity_); + LOG_SENSOR(" ", "Temperature", this->temperature_); + LOG_SENSOR(" ", "Pressure", this->pressure_); + LOG_SENSOR(" ", "Acceleration", this->acceleration_); + LOG_SENSOR(" ", "Acceleration X", this->acceleration_x_); + LOG_SENSOR(" ", "Acceleration Y", this->acceleration_y_); + LOG_SENSOR(" ", "Acceleration Z", this->acceleration_z_); + LOG_SENSOR(" ", "Battery Voltage", this->battery_voltage_); + LOG_SENSOR(" ", "TX Power", this->tx_power_); + LOG_SENSOR(" ", "Movement Counter", this->movement_counter_); + LOG_SENSOR(" ", "Measurement Sequence Number", this->measurement_sequence_number_); +} + +} // namespace ruuvitag +} // namespace esphome + +#endif diff --git a/esphome/components/ruuvitag/ruuvitag.h b/esphome/components/ruuvitag/ruuvitag.h new file mode 100644 index 0000000000..863c5775c2 --- /dev/null +++ b/esphome/components/ruuvitag/ruuvitag.h @@ -0,0 +1,84 @@ +#pragma once + +#include "esphome/core/component.h" +#include "esphome/components/sensor/sensor.h" +#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h" +#include "esphome/components/ruuvi_ble/ruuvi_ble.h" + +#ifdef ARDUINO_ARCH_ESP32 + +namespace esphome { +namespace ruuvitag { + +class RuuviTag : public Component, public esp32_ble_tracker::ESPBTDeviceListener { + public: + void set_address(uint64_t address) { address_ = address; } + + bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override { + if (device.address_uint64() != this->address_) + return false; + + auto res = ruuvi_ble::parse_ruuvi(device); + if (!res.has_value()) + return false; + + if (res->humidity.has_value() && this->humidity_ != nullptr) + this->humidity_->publish_state(*res->humidity); + if (res->temperature.has_value() && this->temperature_ != nullptr) + this->temperature_->publish_state(*res->temperature); + if (res->pressure.has_value() && this->pressure_ != nullptr) + this->pressure_->publish_state(*res->pressure); + if (res->acceleration.has_value() && this->acceleration_ != nullptr) + this->acceleration_->publish_state(*res->acceleration); + if (res->acceleration_x.has_value() && this->acceleration_x_ != nullptr) + this->acceleration_x_->publish_state(*res->acceleration_x); + if (res->acceleration_y.has_value() && this->acceleration_y_ != nullptr) + this->acceleration_y_->publish_state(*res->acceleration_y); + if (res->acceleration_z.has_value() && this->acceleration_z_ != nullptr) + this->acceleration_z_->publish_state(*res->acceleration_z); + if (res->battery_voltage.has_value() && this->battery_voltage_ != nullptr) + this->battery_voltage_->publish_state(*res->battery_voltage); + if (res->tx_power.has_value() && this->tx_power_ != nullptr) + this->tx_power_->publish_state(*res->tx_power); + if (res->movement_counter.has_value() && this->movement_counter_ != nullptr) + this->movement_counter_->publish_state(*res->movement_counter); + if (res->measurement_sequence_number.has_value() && this->measurement_sequence_number_ != nullptr) + this->measurement_sequence_number_->publish_state(*res->measurement_sequence_number); + return true; + } + + void dump_config() override; + float get_setup_priority() const override { return setup_priority::DATA; } + void set_humidity(sensor::Sensor *humidity) { humidity_ = humidity; } + void set_temperature(sensor::Sensor *temperature) { temperature_ = temperature; } + void set_pressure(sensor::Sensor *pressure) { pressure_ = pressure; } + void set_acceleration(sensor::Sensor *acceleration) { acceleration_ = acceleration; } + void set_acceleration_x(sensor::Sensor *acceleration_x) { acceleration_x_ = acceleration_x; } + void set_acceleration_y(sensor::Sensor *acceleration_y) { acceleration_y_ = acceleration_y; } + void set_acceleration_z(sensor::Sensor *acceleration_z) { acceleration_z_ = acceleration_z; } + void set_battery_voltage(sensor::Sensor *battery_voltage) { battery_voltage_ = battery_voltage; } + void set_tx_power(sensor::Sensor *tx_power) { tx_power_ = tx_power; } + void set_movement_counter(sensor::Sensor *movement_counter) { movement_counter_ = movement_counter; } + void set_measurement_sequence_number(sensor::Sensor *measurement_sequence_number) { + measurement_sequence_number_ = measurement_sequence_number; + } + + protected: + uint64_t address_; + sensor::Sensor *temperature_{nullptr}; + sensor::Sensor *humidity_{nullptr}; + sensor::Sensor *pressure_{nullptr}; + sensor::Sensor *acceleration_{nullptr}; + sensor::Sensor *acceleration_x_{nullptr}; + sensor::Sensor *acceleration_y_{nullptr}; + sensor::Sensor *acceleration_z_{nullptr}; + sensor::Sensor *battery_voltage_{nullptr}; + sensor::Sensor *tx_power_{nullptr}; + sensor::Sensor *movement_counter_{nullptr}; + sensor::Sensor *measurement_sequence_number_{nullptr}; +}; + +} // namespace ruuvitag +} // namespace esphome + +#endif diff --git a/esphome/components/ruuvitag/sensor.py b/esphome/components/ruuvitag/sensor.py new file mode 100644 index 0000000000..3d9c724e7b --- /dev/null +++ b/esphome/components/ruuvitag/sensor.py @@ -0,0 +1,76 @@ +import esphome.codegen as cg +import esphome.config_validation as cv +from esphome.components import sensor, esp32_ble_tracker +from esphome.const import CONF_HUMIDITY, CONF_MAC_ADDRESS, CONF_TEMPERATURE, \ + CONF_PRESSURE, CONF_ACCELERATION, CONF_ACCELERATION_X, CONF_ACCELERATION_Y, \ + CONF_ACCELERATION_Z, CONF_BATTERY_VOLTAGE, CONF_TX_POWER, \ + CONF_MEASUREMENT_SEQUENCE_NUMBER, CONF_MOVEMENT_COUNTER, UNIT_CELSIUS, \ + ICON_THERMOMETER, UNIT_PERCENT, UNIT_VOLT, UNIT_HECTOPASCAL, UNIT_G, \ + UNIT_DECIBEL_MILLIWATT, UNIT_EMPTY, ICON_WATER_PERCENT, ICON_BATTERY, \ + ICON_GAUGE, ICON_ACCELERATION, ICON_ACCELERATION_X, ICON_ACCELERATION_Y, \ + ICON_ACCELERATION_Z, ICON_SIGNAL, CONF_ID + +DEPENDENCIES = ['esp32_ble_tracker'] +AUTO_LOAD = ['ruuvi_ble'] + +ruuvitag_ns = cg.esphome_ns.namespace('ruuvitag') +RuuviTag = ruuvitag_ns.class_( + 'RuuviTag', esp32_ble_tracker.ESPBTDeviceListener, cg.Component) + +CONFIG_SCHEMA = cv.Schema({ + cv.GenerateID(): cv.declare_id(RuuviTag), + cv.Required(CONF_MAC_ADDRESS): cv.mac_address, + cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_THERMOMETER, 2), + cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(UNIT_PERCENT, ICON_WATER_PERCENT, 2), + cv.Optional(CONF_PRESSURE): sensor.sensor_schema(UNIT_HECTOPASCAL, ICON_GAUGE, 2), + cv.Optional(CONF_ACCELERATION): sensor.sensor_schema(UNIT_G, ICON_ACCELERATION, 3), + cv.Optional(CONF_ACCELERATION_X): sensor.sensor_schema(UNIT_G, ICON_ACCELERATION_X, 3), + cv.Optional(CONF_ACCELERATION_Y): sensor.sensor_schema(UNIT_G, ICON_ACCELERATION_Y, 3), + cv.Optional(CONF_ACCELERATION_Z): sensor.sensor_schema(UNIT_G, ICON_ACCELERATION_Z, 3), + cv.Optional(CONF_BATTERY_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_BATTERY, 3), + cv.Optional(CONF_TX_POWER): sensor.sensor_schema(UNIT_DECIBEL_MILLIWATT, ICON_SIGNAL, 0), + cv.Optional(CONF_MOVEMENT_COUNTER): sensor.sensor_schema(UNIT_EMPTY, ICON_GAUGE, 0), + cv.Optional(CONF_MEASUREMENT_SEQUENCE_NUMBER): sensor.sensor_schema(UNIT_EMPTY, ICON_GAUGE, 0), +}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA) + + +def to_code(config): + var = cg.new_Pvariable(config[CONF_ID]) + yield cg.register_component(var, config) + yield esp32_ble_tracker.register_ble_device(var, config) + + cg.add(var.set_address(config[CONF_MAC_ADDRESS].as_hex)) + + if CONF_TEMPERATURE in config: + sens = yield sensor.new_sensor(config[CONF_TEMPERATURE]) + cg.add(var.set_temperature(sens)) + if CONF_HUMIDITY in config: + sens = yield sensor.new_sensor(config[CONF_HUMIDITY]) + cg.add(var.set_humidity(sens)) + if CONF_PRESSURE in config: + sens = yield sensor.new_sensor(config[CONF_PRESSURE]) + cg.add(var.set_pressure(sens)) + if CONF_ACCELERATION in config: + sens = yield sensor.new_sensor(config[CONF_ACCELERATION]) + cg.add(var.set_acceleration(sens)) + if CONF_ACCELERATION_X in config: + sens = yield sensor.new_sensor(config[CONF_ACCELERATION_X]) + cg.add(var.set_acceleration_x(sens)) + if CONF_ACCELERATION_Y in config: + sens = yield sensor.new_sensor(config[CONF_ACCELERATION_Y]) + cg.add(var.set_acceleration_y(sens)) + if CONF_ACCELERATION_Z in config: + sens = yield sensor.new_sensor(config[CONF_ACCELERATION_Z]) + cg.add(var.set_acceleration_z(sens)) + if CONF_BATTERY_VOLTAGE in config: + sens = yield sensor.new_sensor(config[CONF_BATTERY_VOLTAGE]) + cg.add(var.set_battery_voltage(sens)) + if CONF_TX_POWER in config: + sens = yield sensor.new_sensor(config[CONF_TX_POWER]) + cg.add(var.set_tx_power(sens)) + if CONF_MOVEMENT_COUNTER in config: + sens = yield sensor.new_sensor(config[CONF_MOVEMENT_COUNTER]) + cg.add(var.set_movement_counter(sens)) + if CONF_MEASUREMENT_SEQUENCE_NUMBER in config: + sens = yield sensor.new_sensor(config[CONF_MEASUREMENT_SEQUENCE_NUMBER]) + cg.add(var.set_measurement_sequence_number(sens)) diff --git a/esphome/const.py b/esphome/const.py index cde9134eae..2af143984c 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -29,6 +29,9 @@ HEADER_FILE_EXTENSIONS = {'.h', '.hpp', '.tcc'} CONF_ABOVE = 'above' CONF_ACCELERATION = 'acceleration' +CONF_ACCELERATION_X = 'acceleration_x' +CONF_ACCELERATION_Y = 'acceleration_y' +CONF_ACCELERATION_Z = 'acceleration_z' CONF_ACCURACY = 'accuracy' CONF_ACCURACY_DECIMALS = 'accuracy_decimals' CONF_ACTION_ID = 'action_id' @@ -47,6 +50,7 @@ CONF_AVAILABILITY = 'availability' CONF_AWAY = 'away' CONF_AWAY_CONFIG = 'away_config' CONF_BATTERY_LEVEL = 'battery_level' +CONF_BATTERY_VOLTAGE = 'battery_voltage' CONF_BAUD_RATE = 'baud_rate' CONF_BELOW = 'below' CONF_BINARY = 'binary' @@ -239,6 +243,7 @@ CONF_MAX_TEMPERATURE = 'max_temperature' CONF_MAX_VALUE = 'max_value' CONF_MAX_VOLTAGE = 'max_voltage' CONF_MEASUREMENT_DURATION = 'measurement_duration' +CONF_MEASUREMENT_SEQUENCE_NUMBER = 'measurement_sequence_number' CONF_MEDIUM = 'medium' CONF_METHOD = 'method' CONF_MIN_LENGTH = 'min_length' @@ -254,6 +259,7 @@ CONF_MODEL = 'model' CONF_MOISTURE = 'moisture' CONF_MONTHS = 'months' CONF_MOSI_PIN = 'mosi_pin' +CONF_MOVEMENT_COUNTER = 'movement_counter' CONF_MQTT = 'mqtt' CONF_MQTT_ID = 'mqtt_id' CONF_MULTIPLEXER = 'multiplexer' @@ -449,6 +455,7 @@ CONF_TURN_OFF_ACTION = 'turn_off_action' CONF_TURN_ON_ACTION = 'turn_on_action' CONF_TX_BUFFER_SIZE = 'tx_buffer_size' CONF_TX_PIN = 'tx_pin' +CONF_TX_POWER = 'tx_power' CONF_TYPE = 'type' CONF_TYPE_ID = 'type_id' CONF_UART_ID = 'uart_id' @@ -483,6 +490,10 @@ CONF_WIND_SPEED = 'wind_speed' CONF_WINDOW_SIZE = 'window_size' CONF_ZERO = 'zero' +ICON_ACCELERATION = 'mdi:axis-arrow' +ICON_ACCELERATION_X = 'mdi:axis-x-arrow' +ICON_ACCELERATION_Y = 'mdi:axis-y-arrow' +ICON_ACCELERATION_Z = 'mdi:axis-z-arrow' ICON_ARROW_EXPAND_VERTICAL = 'mdi:arrow-expand-vertical' ICON_BATTERY = 'mdi:battery' ICON_BRIEFCASE_DOWNLOAD = 'mdi:briefcase-download' @@ -508,7 +519,7 @@ ICON_ROTATE_RIGHT = 'mdi:rotate-right' ICON_SCALE = 'mdi:scale' ICON_SCREEN_ROTATION = 'mdi:screen-rotation' ICON_SIGN_DIRECTION = 'mdi:sign-direction' -ICON_SIGNAL = 'mdi: signal-distance-variant' +ICON_SIGNAL = 'mdi:signal-distance-variant' ICON_SIGNAL_DISTANCE_VARIANT = 'mdi:signal' ICON_THERMOMETER = 'mdi:thermometer' ICON_TIMER = 'mdi:timer' @@ -522,9 +533,11 @@ ICON_WIFI = 'mdi:wifi' UNIT_AMPERE = 'A' UNIT_CELSIUS = u'°C' UNIT_DECIBEL = 'dB' +UNIT_DECIBEL_MILLIWATT = 'dBm' UNIT_DEGREE_PER_SECOND = u'°/s' UNIT_DEGREES = u'°' UNIT_EMPTY = '' +UNIT_G = 'G' UNIT_HECTOPASCAL = 'hPa' UNIT_HZ = 'hz' UNIT_KELVIN = 'K' diff --git a/tests/test2.yaml b/tests/test2.yaml index 78e1ab149a..935f9edb84 100644 --- a/tests/test2.yaml +++ b/tests/test2.yaml @@ -95,7 +95,7 @@ sensor: temperature: name: "Xiaomi LYWSD02 Temperature" humidity: - name: "Xiaomi LYWSD02 Humidity" + name: "Xiaomi LYWSD02 Humidity" - platform: xiaomi_cgg1 mac_address: 7A:80:8E:19:36:BA temperature: @@ -160,6 +160,28 @@ sensor: name: "Lightning Energy" distance: name: "Distance Storm" + - platform: ruuvitag + mac_address: FF:56:D3:2F:7D:E8 + humidity: + name: "RuuviTag Humidity" + temperature: + name: "RuuviTag Temperature" + pressure: + name: "RuuviTag Pressure" + acceleration_x: + name: "RuuviTag Acceleration X" + acceleration_y: + name: "RuuviTag Acceleration Y" + acceleration_z: + name: "RuuviTag Acceleration Z" + battery_voltage: + name: "RuuviTag Battery Voltage" + tx_power: + name: "RuuviTag TX Power" + movement_counter: + name: "RuuviTag Movement Counter" + measurement_sequence_number: + name: "RuuviTag Measurement Sequence Number" time: - platform: homeassistant @@ -210,10 +232,6 @@ binary_sensor: - platform: as3935 name: "Storm Alert" -remote_receiver: - pin: GPIO32 - dump: [] - esp32_ble_tracker: #esp32_ble_beacon: