Files
arduino-home-assistant/tests/SensorTest/SensorTest.ino
T
Dawid ChyrzyńskiandDawid Chyrzynski 0fc32a5bad ArduinoHA 2.0.0 🔥 (#81)
* added tests for HADeviceTracker

* added support for progmem property value in the HASerializer

* codebase update

* add support for source type in HADeviceTracker

* added support for HACamera

* added support for HALock

* rename HABinarySensor::getState to getCurrentState

* standardize sender name in all callback headers

* remove duplicate serializer field protection (reduce flash usage)

* optimize HAUtils

* minor improvements

* optimize writing progmem payload

* optimize HAUtils:numberToStr

* remove relloc from HASerializer

* optimize HASerializerArray

* remove includeNullTerminator arg from the topics size generators

* optimize HASerializer

* replace dtostrf with custom implementation

* optimize BaseDeviceType

* removed relloc from the HAMqtt

* removed support for floats

* removed vtable for HADevice, HAMqtt, HASerializer and HASerializerArray

* implemented HASwitch with tests

* implemented basic HADeviceTrigger

* added support for built-in triggers

* finished HADeviceTrigger

* update changelog

* implemented base HASensor

* implemented HASensorInteger

* finished HASensorFloat

* override onMqttConnected in HASensorInteger and HASensorFloat

* add more tests for HASensorInteger and HASensorFloat

* optimize HASensorFloat

* update changelog

* standardize constructor of the HABinarySensor

* update readme

* readme

* readme

* standardize HADeviceTracker API

* standardize HASwitch API

* update docs README

* move Sphinx files to docsrc directory

* type in HASwitch

* test docs

* add .nojekyll to the docs directory

* update makefile of the docs

* wip: docs

* docs: fix html title

* docs: update styling and sidebar

* docs: add "Basics" section

* docs: device configuration

* docs: availability

* docs: MQTT discovery

* docs: MQTT security

* docs: MQTT advanced features

* rename BaseDeviceType to HABaseDeviceType

* update gitignore

* add API reference

* update gitignore

* HADevice doxygen

* doxygen css

* HADevice doxygen typos

* docs: update links

* docs: HAUtils doxygen

* HAMqtt and HADevice doxygen

* docs: device types

* docs: HABaseDeviceType

* reduced flash usage by 190 bytes

* fix tests

* move HAUtils class to the utils directory

* make HADevice const in HAMqtt

* HABinarySensor docs

* doxygen

* HADeviceTrigger doxygen

* HALock doxygen

* HASensor doxygen

* HASensor doxygen

* HASwitch doxygen

* HATagScanner doxygen

* HASerializer doxygen

* fix SAMD compile error

* add HAMqtt::publish method

* update examples

* add HAButton example

* update changelog

* added support for the optimistic property in the HACover

* do not set optimistic property in the HASwitch if it's set to default value

* update examples list

* update HASensor example

* update MQTT docs

* fix device trigger example link

* fix search form style on the search result page

* added support for the optimistic property in the HALock

* update readme

* change readme icon

* added HALock example

* MDNS example

* added HASensorFloat and HASensorInteger examples

* update readme

* update examples

* fix crash in the HABaseDeviceType

* add support for storing RAM elements in the HASerializerArray

* update tests cases in the CoverTest

* finished tests for HASelect

* added support for HASelect

* update README, CHANGELOG and examples list

* DeviceTest typos

* add more tests to SelectTest

* optimize HASelect command's handler

* improve CoverTest

* optimize HACover command's handler

* optimize HALock command's handler

* update SerializerTest

* remove HAMqtt::writePayload_P method

* remove FlagInternalType from the HASerializer

* added support for __FlashStringHelper in the topics related functions

* migrated serializer to use __FlashStringHelper

* add __FlashStringHelper to the HABaseDeviceType::publishOnDataTopic method

* move component name to flash memory

* update docs

* fix debug logs

* fix memory leaks

* monitor memory leaks in all test cases

* optimize tests (RAM)

* fix HALock states

* fix bug in the HASensor (invalid serialization of the value template property)

* fix memory leak in the HASelect

* fix crash in HASelect

* fix memory leak in the HADeviceTrigger

* fix memory leak in the HADevice

* tests: add support for ESP8266 and ESP32 envs

* update docs

* add multi-switch example

* update docs structure

* update MQTT advanced example in the docs

* HADevice: fix _uniqueId memory release

* wip: HANumber

* add HANumber to defines

* refactor HASensor implementation for numbers (again)

* update docs

* wip: HANumber

* wip: add support for number's precision in the HASerializer

* add support for float numbers in the HASerializer

* optimize vtables in the HASensor

* wip: HANumber

* fix crash in the float serialization

* handle another edge case in the float serialization

* replace int32_t with HAUtils::Number type

* HANumber fixes

* tests for HANumber

* change HAUtils::Number type to int64_t

* implemented HAUtils::strToNumber

* finished HANumber command handler

* finished HANumber

* update docs

* add number example

* added support for HAScene

* add scene example, update docs

* update doxygen

* remove memset from the codebase

* micro optimizations

* fix commands handlers

* update HACover code

* codebase cleanup

* finished HAFan implementation

* update docs, added fan example

* make json readable in all tests

* make position configurable in the HACover

* docs

* added support for HALight

* implement default values as static HAFan members

* update docs, added light example

* added support for color temperature in the HALight

* update light example

* update docs

* wip: HVAC

* improve all tests with callbacks

* update logs

* add HVAC to the docs

* optimize HANumber

* add current temperature to the HVAC

* started work on HVAC tests

* added action feature to the HVAC

* add temperature unit to the HVAC

* add more tests to UtilsTest

* fix fake MQTT messages mock - message shouldn't include null terminator

* fix HAUtils::strToNumber

* optimize HAFan, HACover and HALight

* add min/max temp to the HVAC

* added temp step property to the HVAC

* rename HASensorNumber::getCurrentValueAsFloat to getCurrentValueFloat

* update docs

* added support for aux heating in the HVAC

* added power command to the HVAC

* add subscriptions to the HVAC

* added fan mode to the HVAC

* update examples

* update command handlers in all device types

* added swing mode to the HVAC

* finished HVAC

* update docs

* fix memory leak in the HVAC

* added support for the target temperature in the HVAC

* add HVAC example

* update docs

* remove unnecessary checks from some device types

* added support for RGB in the HALight

* update docs

* standardize HAHVAC code

* rename HAButton::onPress method to onCommand

* rename HAScene::onActivate method to onCommand

* fix seg fault in the HAUtils

* HASensorNumber: do not publish default value on connect

* add return uint16_t to the HAUtils::numberToStr method

* simplify logic in the HALight::publishRGBColor

* optimize numbers serialization in the HASerializer

* update README, added LICENSE.md

* rename license file

* added tag-scanner example

* update publishOnDataTopic methods

* added esp32-cam example

* update docs

* add examples to the README.md

* update examples

* update HAMqtt.h for latest SAMD core, update aunier

* update README, fix auniter settings for esp32

* update README

* added documentation link to the README

* final tweaks in the HACover

* fix logic of the speed feature in the HAFan

* fix mdns example

* fix bug in the DeviceTrigger (invalid serialization of the progmem type/subtype)

* implemented HANumeric

* update HASensorNumber

* update HANumber

* update HALight

* update HAHVAC

* update HAFan

* update HACover

* update examples

* update tests

* update docs

* fix HANumeric constructor bug

* update HANumeric for SAMD

* update readme and docs

* add payload_on to the scene config (HA throws an exception if this property is missing)

* update sensor-analog example

* update sensor-integer example

* HVAC fixes

* update docs

Co-authored-by: Dawid Chyrzynski <dawid.chyrzynski@gmail.com>
2022-10-14 19:10:38 +02:00

497 lines
14 KiB
Arduino

#include <AUnit.h>
#include <ArduinoHA.h>
using aunit::TestRunner;
static const char* testDeviceId = "testDevice";
static const char* testUniqueId = "uniqueSensor";
const char ConfigTopic[] PROGMEM = {"homeassistant/sensor/testDevice/uniqueSensor/config"};
const char StateTopic[] PROGMEM = {"testData/testDevice/uniqueSensor/stat_t"};
const char DummyTemplateStr[] PROGMEM = {"dummyTemplate"};
AHA_TEST(SensorTest, invalid_unique_id) {
initMqttTest(testDeviceId)
HASensor sensor(nullptr);
sensor.buildSerializerTest();
HASerializer* serializer = sensor.getSerializer();
assertTrue(serializer == nullptr);
}
AHA_TEST(SensorTest, default_params) {
initMqttTest(testDeviceId)
HASensor sensor(testUniqueId);
assertEntityConfig(
mock,
sensor,
(
"{"
"\"uniq_id\":\"uniqueSensor\","
"\"dev\":{\"ids\":\"testDevice\"},"
"\"stat_t\":\"testData/testDevice/uniqueSensor/stat_t\""
"}"
)
)
}
AHA_TEST(SensorTest, availability) {
initMqttTest(testDeviceId)
HASensor sensor(testUniqueId);
sensor.setAvailability(true);
mqtt.loop();
// availability is published after config in HASensor
assertMqttMessage(
1,
F("testData/testDevice/uniqueSensor/avty_t"),
"online",
true
)
}
AHA_TEST(SensorTest, name_setter) {
initMqttTest(testDeviceId)
HASensor sensor(testUniqueId);
sensor.setName("testName");
assertEntityConfig(
mock,
sensor,
(
"{"
"\"name\":\"testName\","
"\"uniq_id\":\"uniqueSensor\","
"\"dev\":{\"ids\":\"testDevice\"},"
"\"stat_t\":\"testData/testDevice/uniqueSensor/stat_t\""
"}"
)
)
}
AHA_TEST(SensorTest, device_class_setter) {
initMqttTest(testDeviceId)
HASensor sensor(testUniqueId);
sensor.setDeviceClass("testClass");
assertEntityConfig(
mock,
sensor,
(
"{"
"\"uniq_id\":\"uniqueSensor\","
"\"dev_cla\":\"testClass\","
"\"dev\":{\"ids\":\"testDevice\"},"
"\"stat_t\":\"testData/testDevice/uniqueSensor/stat_t\""
"}"
)
)
}
AHA_TEST(SensorTest, force_update_setter) {
initMqttTest(testDeviceId)
HASensor sensor(testUniqueId);
sensor.setForceUpdate(true);
assertEntityConfig(
mock,
sensor,
(
"{"
"\"uniq_id\":\"uniqueSensor\","
"\"frc_upd\":true,"
"\"dev\":{\"ids\":\"testDevice\"},"
"\"stat_t\":\"testData/testDevice/uniqueSensor/stat_t\""
"}"
)
)
}
AHA_TEST(SensorTest, icon_setter) {
initMqttTest(testDeviceId)
HASensor sensor(testUniqueId);
sensor.setIcon("testIcon");
assertEntityConfig(
mock,
sensor,
(
"{"
"\"uniq_id\":\"uniqueSensor\","
"\"ic\":\"testIcon\","
"\"dev\":{\"ids\":\"testDevice\"},"
"\"stat_t\":\"testData/testDevice/uniqueSensor/stat_t\""
"}"
)
)
}
AHA_TEST(SensorTest, unit_of_measurement_setter) {
initMqttTest(testDeviceId)
HASensor sensor(testUniqueId);
sensor.setUnitOfMeasurement("%");
assertEntityConfig(
mock,
sensor,
(
"{"
"\"uniq_id\":\"uniqueSensor\","
"\"unit_of_meas\":\"%\","
"\"dev\":{\"ids\":\"testDevice\"},"
"\"stat_t\":\"testData/testDevice/uniqueSensor/stat_t\""
"}"
)
)
}
AHA_TEST(SensorTest, publish_value) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensor sensor(testUniqueId);
assertTrue(sensor.setValue("test123"));
assertSingleMqttMessage(AHATOFSTR(StateTopic), "test123", true)
}
test(SensorNumberTest, publish_value_on_connect) {
initMqttTest(testDeviceId)
HASensorNumber sensor(testUniqueId);
sensor.setCurrentValue(520);
mqtt.loop();
assertMqttMessage(1, AHATOFSTR(StateTopic), "520", true)
}
test(SensorNumberTest, dont_publish_default_value_on_connect) {
initMqttTest(testDeviceId)
HASensorNumber sensor(testUniqueId);
mqtt.loop();
assertFalse(sensor.getCurrentValue().isSet());
assertEqual(mock->getFlushedMessagesNb(), 1); // config only
}
test(SensorNumberTest, publish_debounce) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId);
uint16_t value = 1555;
sensor.setCurrentValue(value);
assertTrue(sensor.setValue(value));
assertTrue(sensor.getCurrentValue().isSet());
assertEqual(value, sensor.getCurrentValue().toUInt16());
assertEqual(mock->getFlushedMessagesNb(), 0);
}
test(SensorNumberTest, publish_force) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId);
uint16_t value = 1555;
sensor.setCurrentValue(value);
assertTrue(sensor.setValue(value, true));
assertTrue(sensor.getCurrentValue().isSet());
assertEqual(value, sensor.getCurrentValue().toUInt16());
assertSingleMqttMessage(AHATOFSTR(StateTopic), "1555", true)
}
test(SensorNumberTest, publish_int_zero) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId);
sensor.setCurrentValue(50);
int8_t value = 0;
assertTrue(sensor.setValue(value));
assertTrue(sensor.getCurrentValue().isSet());
assertEqual(value, sensor.getCurrentValue().toInt8());
assertSingleMqttMessage(AHATOFSTR(StateTopic), "0", true)
}
test(SensorNumberTest, publish_int8) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId);
int8_t value = 127;
assertTrue(sensor.setValue(value));
assertTrue(sensor.getCurrentValue().isSet());
assertEqual(value, sensor.getCurrentValue().toInt8());
assertSingleMqttMessage(AHATOFSTR(StateTopic), "127", true)
}
test(SensorNumberTest, publish_uint8) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId);
uint8_t value = 50;
assertTrue(sensor.setValue(value));
assertTrue(sensor.getCurrentValue().isSet());
assertEqual(value, sensor.getCurrentValue().toUInt8());
assertSingleMqttMessage(AHATOFSTR(StateTopic), "50", true)
}
test(SensorNumberTest, publish_int16) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId);
int16_t value = 32766;
assertTrue(sensor.setValue(value));
assertTrue(sensor.getCurrentValue().isSet());
assertEqual(value, sensor.getCurrentValue().toInt16());
assertSingleMqttMessage(AHATOFSTR(StateTopic), "32766", true)
}
test(SensorNumberTest, publish_uint16) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId);
uint16_t value = 65534;
assertTrue(sensor.setValue(value));
assertTrue(sensor.getCurrentValue().isSet());
assertEqual(value, sensor.getCurrentValue().toUInt16());
assertSingleMqttMessage(AHATOFSTR(StateTopic), "65534", true)
}
test(SensorNumberTest, publish_int32) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId);
int32_t value = 2147483646;
assertTrue(sensor.setValue(value));
assertTrue(sensor.getCurrentValue().isSet());
assertEqual(value, sensor.getCurrentValue().toInt32());
assertSingleMqttMessage(AHATOFSTR(StateTopic), "2147483646", true)
}
test(SensorNumberTest, publish_int32_signed) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId);
int32_t value = -2147483646;
assertTrue(sensor.setValue(value));
assertTrue(sensor.getCurrentValue().isSet());
assertEqual(value, sensor.getCurrentValue().toInt32());
assertSingleMqttMessage(AHATOFSTR(StateTopic), "-2147483646", true)
}
test(SensorNumberTest, publish_uint32) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId);
uint32_t value = 4294967295;
assertTrue(sensor.setValue(value));
assertTrue(sensor.getCurrentValue().isSet());
assertEqual(value, sensor.getCurrentValue().toUInt32());
assertSingleMqttMessage(AHATOFSTR(StateTopic), "4294967295", true)
}
test(SensorNumberTest, publish_p0) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP0);
assertTrue(sensor.setValue(173.5426f));
assertFalse(sensor.getCurrentValue().isFloat());
assertEqual((uint16_t)173, sensor.getCurrentValue().toUInt16());
assertSingleMqttMessage(AHATOFSTR(StateTopic), "173", true)
}
test(SensorNumberTest, publish_p0_zero_unsigned) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP0);
assertTrue(sensor.setValue(0.050f, true));
assertFalse(sensor.getCurrentValue().isFloat());
assertEqual((uint16_t)0, sensor.getCurrentValue().toUInt16());
assertSingleMqttMessage(AHATOFSTR(StateTopic), "0", true)
}
test(SensorNumberTest, publish_p0_zero_signed) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP0);
assertTrue(sensor.setValue(-0.050f, true));
assertFalse(sensor.getCurrentValue().isFloat());
assertEqual((uint16_t)0, sensor.getCurrentValue().toUInt16());
assertSingleMqttMessage(AHATOFSTR(StateTopic), "0", true)
}
test(SensorNumberTest, publish_p1) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP1);
assertTrue(sensor.setValue(173.5426f));
assertTrue(sensor.getCurrentValue().isFloat());
assertNear(173.5f, sensor.getCurrentValue().toFloat(), 0.1);
assertSingleMqttMessage(AHATOFSTR(StateTopic), "173.5", true)
}
test(SensorNumberTest, publish_p1_zero_unsigned) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP1);
assertTrue(sensor.setValue(0.123f, true));
assertTrue(sensor.getCurrentValue().isFloat());
assertNear(0.1f, sensor.getCurrentValue().toFloat(), 0.1);
assertSingleMqttMessage(AHATOFSTR(StateTopic), "0.1", true)
}
test(SensorNumberTest, publish_p1_zero_signed) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP1);
assertTrue(sensor.setValue(-0.123f, true));
assertTrue(sensor.getCurrentValue().isFloat());
assertNear(-0.1f, sensor.getCurrentValue().toFloat(), 0.1);
assertSingleMqttMessage(AHATOFSTR(StateTopic), "-0.1", true)
}
test(SensorNumberTest, publish_p2) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP2);
assertTrue(sensor.setValue(173.1534f));
assertTrue(sensor.getCurrentValue().isFloat());
assertNear(173.15f, sensor.getCurrentValue().toFloat(), 0.1);
assertSingleMqttMessage(AHATOFSTR(StateTopic), "173.15", true)
}
test(SensorNumberTest, publish_p2_zero_unsigned) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP2);
assertTrue(sensor.setValue(0.123f, true));
assertTrue(sensor.getCurrentValue().isFloat());
assertNear(0.12f, sensor.getCurrentValue().toFloat(), 0.1);
assertSingleMqttMessage(AHATOFSTR(StateTopic), "0.12", true)
}
test(SensorNumberTest, publish_p2_zero_signed) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP2);
assertTrue(sensor.setValue(-0.123f, true));
assertTrue(sensor.getCurrentValue().isFloat());
assertNear(-0.12f, sensor.getCurrentValue().toFloat(), 0.1);
assertSingleMqttMessage(AHATOFSTR(StateTopic), "-0.12", true)
}
test(SensorNumberTest, publish_p3) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP3);
assertTrue(sensor.setValue(173.333f));
assertTrue(sensor.getCurrentValue().isFloat());
assertNear(173.333f, sensor.getCurrentValue().toFloat(), 0.1);
assertSingleMqttMessage(AHATOFSTR(StateTopic), "173.333", true)
}
test(SensorNumberTest, publish_p3_zero_unsigned) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP3);
assertTrue(sensor.setValue(0.123f, true));
assertTrue(sensor.getCurrentValue().isFloat());
assertNear(0.123f, sensor.getCurrentValue().toFloat(), 0.1);
assertSingleMqttMessage(AHATOFSTR(StateTopic), "0.123", true)
}
test(SensorNumberTest, publish_p3_zero_signed) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP3);
assertTrue(sensor.setValue(-0.123f, true));
assertTrue(sensor.getCurrentValue().isFloat());
assertNear(-0.123f, sensor.getCurrentValue().toFloat(), 0.1);
assertSingleMqttMessage(AHATOFSTR(StateTopic), "-0.123", true)
}
test(SensorNumberTest, publish_p3_smaller) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP3);
assertTrue(sensor.setValue(173.3f));
assertTrue(sensor.getCurrentValue().isFloat());
assertNear(173.3f, sensor.getCurrentValue().toFloat(), 0.1);
assertSingleMqttMessage(AHATOFSTR(StateTopic), "173.300", true)
}
test(SensorNumberTest, publish_precision_mismatch) {
initMqttTest(testDeviceId)
mock->connectDummy();
HASensorNumber sensor(testUniqueId, HASensorNumber::PrecisionP3);
assertFalse(sensor.setValue(HANumeric(25.0f, 1)));
assertFalse(sensor.getCurrentValue().isSet());
assertEqual(mock->getFlushedMessagesNb(), 0);
}
void setup()
{
delay(1000);
Serial.begin(115200);
while (!Serial);
}
void loop()
{
TestRunner::run();
delay(1);
}