Take what a tile can do, its tap actions, words and icons from Home Assistant (0.2.67)
GitHub issue #7 asked for cover.toggle on tap. ESP Screens now asks Home Assistant which actions each entity has instead of keeping lists: the editor offers On / off (covers included), sliders, controls and displays only where Home Assistant has the action, and refuses only new unsupported settings. Perform action runs any action Home Assistant offers for the tile's entity, under its own names and fields; the screen sends it with a call id and says Refused when Home Assistant refuses. Sensors round by display precision, and tiles, the top bar, timelines, vacuum chips and the inspector use Home Assistant's words where they showed raw states. Tiles show Home Assistant's icons, picked as its frontend does (the fonts grow to 309 glyphs). Existing screens keep every setting and tap as before: stored layouts load leniently, legacy taps route the same (1020 combinations), and messages are byte-identical without Home Assistant's words and icons. Firmware 0.2.58. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -370,4 +370,34 @@ inline Action edit_action(const Tile &t, float value) {
|
||||
if (d == "number" || d == "input_number") return {d + ".set_value", "value", text};
|
||||
return {};
|
||||
}
|
||||
|
||||
// ---- What a finger on a tile does ----
|
||||
// The tile's own `tap` choice comes first. `toggle` sends <domain>.toggle on every domain (firmware 0.2.58+): the app
|
||||
// only offers it where Home Assistant lists that action for the entity, such as a cover, which stops while it moves.
|
||||
// Otherwise the domain decides, as before: holding or `detail` opens a card, a short tap switches, runs or presses.
|
||||
// CARD is the runtime detail card (show_detail), OVERLAY the board's own light, fan and climate card; `busy` marks the
|
||||
// tile busy for a moment while the card opens.
|
||||
// CUSTOM (firmware 0.2.58+) is an action of the tile's own choosing from Home Assistant's list, with its data.
|
||||
enum class TapRoute : uint8_t { NONE, ACTION, CARD, OVERLAY, CUSTOM };
|
||||
struct Tap { TapRoute route = TapRoute::NONE; std::string service; bool busy = false; };
|
||||
inline bool runtime_card_domain(const std::string &d) {
|
||||
return d == "sensor" || d == "binary_sensor" || d == "weather" || d == "number" || d == "input_number" || d == "select" ||
|
||||
d == "input_select" || d == "media_player" || d == "vacuum" || d == "cover" || d == "sun" || d == "person" || d == "timer";
|
||||
}
|
||||
inline Tap tap_route(const Tile &t, bool hold) {
|
||||
const std::string d = t.domain();
|
||||
if (t.tap == "none") return {};
|
||||
// A tile whose action didn't arrive (an app before 0.2.67) taps automatically, as older firmware does.
|
||||
if (!hold && t.tap == "action" && !t.extra().action.empty()) return {TapRoute::CUSTOM, t.extra().action};
|
||||
if (!hold && t.tap == "toggle") return {TapRoute::ACTION, d + ".toggle"};
|
||||
bool open = hold || t.tap == "detail" || d == "climate" || d == "vacuum" || d == "cover";
|
||||
// A short tap runs or pauses the timer; holding opens the card with a cancel button.
|
||||
if (d == "timer" && !open) return {TapRoute::ACTION, t.state == "active" ? "timer.pause" : "timer.start"};
|
||||
if (runtime_card_domain(d)) return {TapRoute::CARD, "", true};
|
||||
if (open) return d == "light" || d == "climate" || d == "fan" ? Tap{TapRoute::OVERLAY, "", true} : Tap{TapRoute::CARD, "", false};
|
||||
if (d == "light" || d == "switch" || d == "input_boolean" || d == "fan") return {TapRoute::ACTION, d + ".toggle"};
|
||||
if (d == "scene" || d == "script") return {TapRoute::ACTION, d + ".turn_on"};
|
||||
if (d == "button" || d == "input_button") return {TapRoute::ACTION, d + ".press"};
|
||||
return {};
|
||||
}
|
||||
} // namespace tile_controls
|
||||
|
||||
Reference in New Issue
Block a user