mihail / game.txt

Last active 2 hours ago

Like 0
game.txt Raw
1 1. Helpers (configuration.yaml, or create them in the UI)
2
3 input_button:
4 station_game_start:
5 name: Start station game
6 icon: mdi:bus-clock
7
8 # One dropdown per player. Options = "-" (no pick) + station names.
9 # Station names must match the keys in the automation's `stations` map.
10 input_select:
11 station_game_alice:
12 name: Alice's station
13 icon: mdi:account
14 options: ["-", "Stratford", "Hackney Wick", "Canning Town", "Bow Road"]
15 station_game_bob:
16 name: Bob's station
17 icon: mdi:account
18 options: ["-", "Stratford", "Hackney Wick", "Canning Town", "Bow Road"]
19 station_game_carol:
20 name: Carol's station
21 icon: mdi:account
22 options: ["-", "Stratford", "Hackney Wick", "Canning Town", "Bow Road"]
23
24 2. Automation
25
26 alias: Station arrival game
27 description: Everyone picks a station; soonest next arrival wins.
28 mode: single
29 triggers:
30 - trigger: state
31 entity_id: input_button.station_game_start
32 not_from: [unavailable, unknown]
33 variables:
34 pick_timeout: 60 # seconds players get to choose
35 departures_attr: departures # attribute holding the arrivals list
36 notify_action: notify.notify
37 stations:
38 Stratford: sensor.stratford_departures
39 Hackney Wick: sensor.hackney_wick_departures
40 Canning Town: sensor.canning_town_departures
41 Bow Road: sensor.bow_road_departures
42 players:
43 Alice: input_select.station_game_alice
44 Bob: input_select.station_game_bob
45 Carol: input_select.station_game_carol
46 actions:
47 # Reset everyone's pick
48 - action: input_select.select_option
49 target:
50 entity_id: "{{ players.values() | list }}"
51 data:
52 option: "-"
53
54 - action: "{{ notify_action }}"
55 data:
56 title: "🚌 Station game!"
57 message: >
58 Pick your station within {{ pick_timeout }}s.
59 Soonest arrival wins. Options: {{ stations.keys() | join(', ') }}
60
61 # Wait until everyone has picked, or time runs out
62 - wait_template: >
63 {{ players.values() | map('states') | select('eq', '-') | list | count == 0 }}
64 timeout:
65 seconds: "{{ pick_timeout }}"
66 continue_on_timeout: true
67
68 # Find each player's soonest future arrival
69 - variables:
70 results: >
71 {% set ns = namespace(r=[]) %}
72 {% for player, sel in players.items() %}
73 {% set station = states(sel) %}
74 {% set sensor = stations.get(station) %}
75 {% if sensor %}
76 {% set best = namespace(t=none, d=none) %}
77 {% for d in state_attr(sensor, departures_attr) or [] %}
78 {% set t = as_datetime(d.expected) if d.expected else none %}
79 {% if t and t > now() and (best.t is none or t < best.t) %}
80 {% set best.t = t %}
81 {% set best.d = d %}
82 {% endif %}
83 {% endfor %}
84 {% if best.t is not none %}
85 {% set ns.r = ns.r + [{
86 'player': player,
87 'station': station,
88 'secs': (best.t - now()).total_seconds() | int,
89 'line': best.d.line.designation if best.d.line is mapping else '?',
90 'mode': best.d.line.transport_mode if best.d.line is mapping else '',
91 'dest': best.d.destination
92 }] %}
93 {% endif %}
94 {% endif %}
95 {% endfor %}
96 {{ ns.r | sort(attribute='secs') }}
97 no_pick: >
98 {{ players.items() | selectattr('1', 'is_state', '-') | map(attribute='0') | list }}
99 winners: >
100 {% if results | count > 0 %}
101 {{ results | selectattr('secs', 'eq', results[0].secs) | map(attribute='player') | list }}
102 {% else %}[]{% endif %}
103
104 - choose:
105 - conditions: "{{ winners | count > 0 }}"
106 sequence:
107 - action: "{{ notify_action }}"
108 data:
109 title: >
110 🏆 {{ winners | join(' & ') }} win{{ 's' if winners | count == 1 }}!
111 message: >
112 {% for r in results -%}
113 {{ loop.index }}. {{ r.player }} – {{ r.station }}:
114 {{ r.mode | lower }} {{ r.line }} → {{ r.dest }}
115 in {{ r.secs // 60 }}m {{ '%02d' % (r.secs % 60) }}s
116 {% endfor -%}
117 {% if no_pick %}Didn't pick: {{ no_pick | join(', ') }}{% endif %}
118 default:
119 - action: "{{ notify_action }}"
120 data:
121 title: "🚌 Station game"
122 message: "No valid picks or no upcoming arrivals. Nobody wins."
123
124 3. Dashboard card (optional)
125
126 type: entities
127 title: Station game
128 entities:
129 - input_button.station_game_start
130 - input_select.station_game_alice
131 - input_select.station_game_bob
132 - input_select.station_game_carol
133
134 How it works
135
136 - Start: press the button. Everyone's pick resets to - and a notification goes out.
137 - Picking: each player sets their own dropdown. The game ends early once all players have picked, otherwise after 60s. Anyone who didn't
138 pick is left out and named in the results.
139 - Winner: for each pick, the automation takes the earliest expected time that is still in the future (it skips past arrivals). The lowest
140 wait wins.
141 - Ties: if two players pick the same station or get identical times, they share the win.
142 - Results: the notification shows the full ranking with mode, line, destination and countdown.