pipish/render.h

89 lines
2.9 KiB
C++

inline int measure_width(const char* text, esphome::display::BaseFont& font) {
int width;
int x_offset;
int baseline;
int height;
font.measure(text, &width, &x_offset, &baseline, &height);
return width;
}
inline int measure_height(const char* text, esphome::display::BaseFont& font) {
int width;
int x_offset;
int baseline;
int height;
font.measure(text, &width, &x_offset, &baseline, &height);
return height;
}
inline void render_sensor(esphome::display::Display& it, int x, int y,
float value, std::string unit,
const std::string& label) {
int normal_height = measure_height("X", id(normal_font));
char formatted[20];
if (std::isnan(value)) {
it.print(x, y, &id(normal_font), TextAlign::TOP_CENTER, "--");
} else {
char value_text[20];
if (std::abs(value) >= 1000) {
unit = "k" + unit;
value /= 1000;
}
if (std::abs(value) < 10) {
sprintf(value_text, "%.1f", value);
} else {
sprintf(value_text, "%.0f", value);
}
int value_width = measure_width(value_text, id(normal_font));
int unit_width = measure_width(unit.c_str(), id(small_font));
int width = value_width + unit_width + 3;
it.print(x - width / 2, y + normal_height, &id(normal_font),
TextAlign::BASELINE_LEFT, value_text);
it.print(x + width / 2 - unit_width, y + normal_height, &id(small_font),
TextAlign::BASELINE_LEFT, unit.c_str());
}
it.print(x, y + normal_height + 3, &id(small_font), TextAlign::TOP_CENTER,
label.c_str());
}
inline void render(esphome::display::Display& it) {
constexpr int kHeight = 540;
constexpr int kWidth = 960;
// Clock
it.strftime(25, 25, &id(clock_font), TextAlign::TOP_LEFT, "%H:%M",
id(rtc_time).now());
int right_width = measure_width("123||", id(normal_font));
render_sensor(it, kWidth - right_width / 2, kHeight * 0 / 10,
id(outside_temperature).state, "°C", "Outside");
render_sensor(it, kWidth - right_width / 2, kHeight * 3 / 10,
id(lounge_temperature).state, "°C", "Lounge");
render_sensor(it, kWidth - right_width / 2, kHeight * 6 / 10,
id(solar_power).state, "W", "Solar");
render_sensor(it, right_width / 2, kHeight * 6 / 10, id(uptime_sensor).state,
"s", "Uptime");
static const struct {
float level;
std::string icon;
} battery_levels[] = {
{10, "mdi-battery-alert-variant-outline"},
{40, "mdi-battery-low"},
{70, "mdi-battery-medium"},
{std::numeric_limits<float>::max(), "mdi-battery-high"},
};
// Battery
float battery_level = id(m5paper_battery_level).state;
if (!std::isnan(battery_level)) {
for (const auto& level : battery_levels) {
if (battery_level <= level.level) {
it.print(910, 10, &id(battery_font),
id(material_icons_map)[level.icon].c_str());
break;
}
}
}
}