Public Access
Add conversions for Home Assistant values: duration, time, own texts, auto unit
- Show as number (multiplier, decimals, auto unit W -> kW -> MW, without minus sign), duration (seconds/minutes/hours as 2h 21m, 2:21:00, 2:21 or smart), time (HA timestamps in local time, with weekday or date, or relative: over 34 min / 12 min geleden) or own texts per state. - Page format 3; version 2 pages are converted. Version 2.7.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
93b9bec69a
commit
87e242bf89
11 files changed
+601
-30
No files matched your search
@@ -1739,6 +1739,135 @@ void test_selector_add_to_rotation()
|
||||
TEST_ASSERT_EQUAL_STRING("3D printer", sel2.update(600, CHOSEN_PAGE_SECONDS * 1000).page);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Home Assistant value conversions
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static PageElement haElement(HaShow show, uint8_t format = 0)
|
||||
{
|
||||
PageElement e;
|
||||
e.type = ElementType::HaValue;
|
||||
strcpy(e.entity, "sensor.x");
|
||||
e.show = show;
|
||||
e.format = format;
|
||||
return e;
|
||||
}
|
||||
|
||||
void test_ha_auto_unit_and_absolute()
|
||||
{
|
||||
PageElement e = haElement(HaShow::Number);
|
||||
e.auto_unit = true;
|
||||
strcpy(e.suffix, " W");
|
||||
TEST_ASSERT_EQUAL_STRING("1.3 kW", textOf(e, "1257").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("950 W", textOf(e, "950").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("-2.5 kW", textOf(e, "-2500").c_str());
|
||||
e.absolute = true;
|
||||
TEST_ASSERT_EQUAL_STRING("2.5 kW", textOf(e, "-2500").c_str());
|
||||
strcpy(e.suffix, "Wh");
|
||||
e.decimals = 2;
|
||||
TEST_ASSERT_EQUAL_STRING("26.30kWh", textOf(e, "26300").c_str());
|
||||
strcpy(e.suffix, "kWh");
|
||||
e.decimals = DECIMALS_AS_IS;
|
||||
TEST_ASSERT_EQUAL_STRING("18.6MWh", textOf(e, "18621.326").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("500.0Wh", textOf(e, "0.5").c_str()); // below 1: smaller unit
|
||||
strcpy(e.suffix, "%"); // not a unit it knows
|
||||
TEST_ASSERT_EQUAL_STRING("37%", textOf(e, "37").c_str());
|
||||
}
|
||||
|
||||
void test_ha_duration()
|
||||
{
|
||||
PageElement e = haElement(HaShow::Duration, DURATION_PARTS);
|
||||
TEST_ASSERT_EQUAL_STRING("2h 20m", textOf(e, "8452.2").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("1d 1h 1m", textOf(e, "90061").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("2d", textOf(e, "172800").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("45s", textOf(e, "45").c_str());
|
||||
e.input_unit = UNIT_MINUTES;
|
||||
TEST_ASSERT_EQUAL_STRING("1h 30m", textOf(e, "90").c_str());
|
||||
e.input_unit = UNIT_HOURS;
|
||||
e.format = DURATION_H_MM_SS;
|
||||
TEST_ASSERT_EQUAL_STRING("26:30:00", textOf(e, "26.5").c_str());
|
||||
e.format = DURATION_H_MM;
|
||||
TEST_ASSERT_EQUAL_STRING("26:30", textOf(e, "26.5").c_str());
|
||||
e.input_unit = UNIT_SECONDS;
|
||||
e.format = DURATION_SMART;
|
||||
TEST_ASSERT_EQUAL_STRING("2 uur", textOf(e, "8452").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("1 dag", textOf(e, "90000").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("34 min", textOf(e, "2040").c_str());
|
||||
e.language = Language::English;
|
||||
TEST_ASSERT_EQUAL_STRING("2 hours", textOf(e, "8452").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("--", textOf(e, "unknown").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("idle", textOf(e, "idle").c_str()); // not a number: as is
|
||||
}
|
||||
|
||||
void test_ha_timestamps()
|
||||
{
|
||||
int64_t s = 0;
|
||||
TEST_ASSERT_TRUE(parseTimestamp("2000-01-01T00:00:00+00:00", s));
|
||||
TEST_ASSERT_EQUAL_INT64(0, s);
|
||||
TEST_ASSERT_TRUE(parseTimestamp("2026-10-15T21:07:00+00:00", s));
|
||||
int64_t a = s;
|
||||
TEST_ASSERT_TRUE(parseTimestamp("2026-10-15T23:07:00+02:00", s));
|
||||
TEST_ASSERT_EQUAL_INT64(a, s);
|
||||
TEST_ASSERT_TRUE(parseTimestamp("2026-10-15T21:07:00.515369Z", s));
|
||||
TEST_ASSERT_EQUAL_INT64(a, s);
|
||||
TEST_ASSERT_TRUE(parseTimestamp("2026-10-15 21:07:00", s));
|
||||
TEST_ASSERT_EQUAL_INT64(a, s);
|
||||
TEST_ASSERT_FALSE(parseTimestamp("21:07", s));
|
||||
TEST_ASSERT_FALSE(parseTimestamp("2026-10-15T21:07:00+0200x", s));
|
||||
|
||||
// textOf: Thursday 15 October 2026 08:05:00 local; CEST is UTC+2
|
||||
PageElement e = haElement(HaShow::Time, TIMESTAMP_H_MM);
|
||||
auto at = [&](const char *value) {
|
||||
LocalTime t;
|
||||
t.year = 2026;
|
||||
t.month = 10;
|
||||
t.day = 15;
|
||||
t.weekday = 4;
|
||||
t.hour = 8;
|
||||
t.minute = 5;
|
||||
t.utc_offset = 120;
|
||||
char out[64];
|
||||
ElementValues values;
|
||||
values.ha_value = value;
|
||||
elementText(e, t, values, out, sizeof(out));
|
||||
return std::string(out);
|
||||
};
|
||||
TEST_ASSERT_EQUAL_STRING("23:07", at("2026-10-15T21:07:00+00:00").c_str());
|
||||
e.format = TIMESTAMP_WEEKDAY_H_MM;
|
||||
TEST_ASSERT_EQUAL_STRING("vr 01:30", at("2026-10-15T23:30:00+00:00").c_str()); // the next day
|
||||
e.format = TIMESTAMP_DATE_H_MM;
|
||||
TEST_ASSERT_EQUAL_STRING("16-10 01:30", at("2026-10-15T23:30:00+00:00").c_str());
|
||||
e.format = TIMESTAMP_RELATIVE;
|
||||
TEST_ASSERT_EQUAL_STRING("over 34 min", at("2026-10-15T06:39:00+00:00").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("12 min geleden", at("2026-10-15T05:53:00+00:00").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("nu", at("2026-10-15T06:05:30+00:00").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("over 2 uur", at("2026-10-15T08:30:00+00:00").c_str());
|
||||
e.language = Language::English;
|
||||
TEST_ASSERT_EQUAL_STRING("3 days ago", at("2026-10-12T06:00:00+00:00").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("soon", at("soon").c_str()); // not a timestamp: as is
|
||||
}
|
||||
|
||||
void test_ha_text_map()
|
||||
{
|
||||
PageElement e = haElement(HaShow::Map);
|
||||
strcpy(e.map, "printing=Bezig, standby = Klaar ,paused=Pauze,=leeg");
|
||||
strcpy(e.text, "3D ");
|
||||
TEST_ASSERT_EQUAL_STRING("3D Bezig", textOf(e, "printing").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("3D Klaar", textOf(e, "Standby").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("3D Pauze", textOf(e, "paused").c_str());
|
||||
TEST_ASSERT_EQUAL_STRING("3D error", textOf(e, "error").c_str()); // not in the list: as is
|
||||
TEST_ASSERT_EQUAL_STRING("3D --", textOf(e, "unavailable").c_str());
|
||||
|
||||
DynamicPage page;
|
||||
page.element_count = 1;
|
||||
page.elements[0] = e;
|
||||
TEST_ASSERT_NULL(validatePage(page));
|
||||
page.elements[0].show = HaShow::Count;
|
||||
TEST_ASSERT_NOT_NULL(validatePage(page));
|
||||
page.elements[0] = haElement(HaShow::Duration, DURATION_FORMAT_COUNT);
|
||||
TEST_ASSERT_NOT_NULL(validatePage(page));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
UNITY_BEGIN();
|
||||
@@ -1856,6 +1985,10 @@ int main()
|
||||
RUN_TEST(test_selector_one_block_starts_again_each_day);
|
||||
RUN_TEST(test_selector_take_over_rules);
|
||||
RUN_TEST(test_selector_add_to_rotation);
|
||||
RUN_TEST(test_ha_auto_unit_and_absolute);
|
||||
RUN_TEST(test_ha_duration);
|
||||
RUN_TEST(test_ha_timestamps);
|
||||
RUN_TEST(test_ha_text_map);
|
||||
|
||||
return UNITY_END();
|
||||
}
|
||||
Reference in new issue
Block a user