@mxpicture/tesla-superchargers-mate 0.1.44 → 0.1.46

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mxpicture/tesla-superchargers-mate",
3
- "version": "0.1.44",
3
+ "version": "0.1.46",
4
4
  "description": "TeslaMate integration",
5
5
  "type": "module",
6
6
  "author": "MXPicture",
@@ -49,7 +49,7 @@
49
49
  "access": "public"
50
50
  },
51
51
  "dependencies": {
52
- "@mxpicture/tesla-superchargers-generated": "^0.1.44",
52
+ "@mxpicture/tesla-superchargers-generated": "^0.1.46",
53
53
  "postgres": "^3.4.9",
54
54
  "short-uuid": "^6.0.3",
55
55
  "zod": "^4.3.6"
package/sql/reset.sql CHANGED
@@ -16,11 +16,11 @@ DROP VIEW IF EXISTS pic_cp_inv_prep_v;
16
16
 
17
17
  DROP VIEW IF EXISTS pic_cp_sc_v;
18
18
 
19
- DROP VIEW IF EXISTS pic_pricebooks_tesla_ui_v;
19
+ DROP VIEW IF EXISTS pic_price_map_ui_v;
20
20
 
21
- DROP VIEW IF EXISTS pic_pricebooks_tesla_condensed_v;
21
+ DROP VIEW IF EXISTS pic_price_map_condensed_v;
22
22
 
23
- DROP VIEW IF EXISTS pic_pricebooks_tesla_v;
23
+ DROP VIEW IF EXISTS pic_price_map_v;
24
24
 
25
25
  DROP VIEW IF EXISTS pic_chargers_v;
26
26
 
package/sql/setup.sql CHANGED
@@ -151,18 +151,34 @@ END $$;
151
151
  ALTER TABLE pic_pricebooks
152
152
  ADD COLUMN IF NOT EXISTS fetched_at TIMESTAMPTZ;
153
153
 
154
- -- backfill: the current group was confirmed by the charger's last fetch (both
155
- -- carry that fetch's uuid); a superseded group was only ever seen at its own
156
- -- valid_since.
154
+ -- backfill: the current group was confirmed by the charger's last fetch; a
155
+ -- superseded group was only ever seen at its own valid_since. The current
156
+ -- group is the one with the max valid_since — resolving it via
157
+ -- c.last_fetch_uuid = p.last_fetch_uuid (as this first did) silently missed
158
+ -- every charger whose uuid had drifted off its pricebooks, and those fell
159
+ -- through to the fallback below: fetched_at = valid_since, which
160
+ -- pic_price_bound_v then reads as "last confirmed the day the price changed"
161
+ -- and truncates the site's history to that single day.
162
+ -- GREATEST over COALESCE keeps fetched_at >= valid_since even if the charger
163
+ -- row somehow predates its own current group (a zero-day interval would drop
164
+ -- the site from the history views entirely), and covers a NULL c.fetched_at
165
+ -- the same way COALESCE did.
157
166
  UPDATE pic_pricebooks p
158
167
  SET
159
- fetched_at = COALESCE(c.fetched_at, p.valid_since)
168
+ fetched_at = GREATEST(c.fetched_at, p.valid_since)
160
169
  FROM
161
170
  pic_chargers c
162
171
  WHERE
163
172
  c.id = p.pic_chargers_id
164
- AND c.last_fetch_uuid = p.last_fetch_uuid
165
- AND p.fetched_at IS NULL;
173
+ AND p.fetched_at IS NULL
174
+ AND p.valid_since = (
175
+ SELECT
176
+ max(cur.valid_since)
177
+ FROM
178
+ pic_pricebooks cur
179
+ WHERE
180
+ cur.pic_chargers_id = p.pic_chargers_id
181
+ );
166
182
 
167
183
  UPDATE pic_pricebooks
168
184
  SET
@@ -174,6 +190,35 @@ ALTER TABLE pic_pricebooks
174
190
  ALTER COLUMN fetched_at
175
191
  SET NOT NULL;
176
192
 
193
+ -- repair for databases the uuid-joined backfill above already ran on: it left
194
+ -- every drifted charger's current group at fetched_at = valid_since, and the
195
+ -- guard it used (fetched_at IS NULL) no longer holds, so re-running setup
196
+ -- cannot heal them. Raise those to the charger's last contact — the value the
197
+ -- corrected backfill would have written. Idempotent: after this runs
198
+ -- fetched_at > valid_since, so the row no longer matches; a no-op on a fresh
199
+ -- database (no rows) and on one that was migrated correctly (the current group
200
+ -- already carries the charger's fetched_at). A group whose only contact really
201
+ -- was its own creation is raised to the charger's last fetch too, which is at
202
+ -- worst the same claim the backfill makes; the next successful re-fetch
203
+ -- overwrites it with a real confirmation either way.
204
+ UPDATE pic_pricebooks p
205
+ SET
206
+ fetched_at = c.fetched_at
207
+ FROM
208
+ pic_chargers c
209
+ WHERE
210
+ c.id = p.pic_chargers_id
211
+ AND p.fetched_at = p.valid_since
212
+ AND c.fetched_at > p.fetched_at
213
+ AND p.valid_since = (
214
+ SELECT
215
+ max(cur.valid_since)
216
+ FROM
217
+ pic_pricebooks cur
218
+ WHERE
219
+ cur.pic_chargers_id = p.pic_chargers_id
220
+ );
221
+
177
222
  CREATE INDEX IF NOT EXISTS pic_pricebooks_loc_idx ON pic_pricebooks (pic_chargers_id);
178
223
 
179
224
  -- group lookups: current group / group at a point in time. Resolved by
@@ -184,21 +229,20 @@ DROP INDEX IF EXISTS pic_pricebooks_charger_time_idx;
184
229
 
185
230
  CREATE INDEX IF NOT EXISTS pic_pricebooks_charger_time_idx ON pic_pricebooks (pic_chargers_id, valid_since DESC);
186
231
 
187
- -- // todo add currency code for ui/grafana
188
232
  -- Dropped instead of CREATE OR REPLACE: these views SELECT p.* / c.* / v.* and
189
233
  -- then add more columns, so growing or renaming a column of the upstream
190
234
  -- relation (e.g. adding pic_chargers.favourite, or the fetched_at → valid_since
191
235
  -- split above) shifts a later column's position — which OR REPLACE rejects
192
236
  -- (42P16 "cannot change name of view column"). Views hold no data, so dropping
193
- -- is idempotent. Dropped in dependency order: pic_pricebooks_tesla_ui_v reads
194
- -- the condensed view, which reads pic_pricebooks_tesla_v.
195
- DROP VIEW IF EXISTS pic_pricebooks_tesla_ui_v;
237
+ -- is idempotent. Dropped in dependency order: pic_price_map_ui_v reads
238
+ -- the condensed view, which reads pic_price_map_v.
239
+ DROP VIEW IF EXISTS pic_price_map_ui_v;
196
240
 
197
- DROP VIEW IF EXISTS pic_pricebooks_tesla_condensed_v;
241
+ DROP VIEW IF EXISTS pic_price_map_condensed_v;
198
242
 
199
- DROP VIEW IF EXISTS pic_pricebooks_tesla_v;
243
+ DROP VIEW IF EXISTS pic_price_map_v;
200
244
 
201
- CREATE VIEW pic_pricebooks_tesla_v AS
245
+ CREATE VIEW pic_price_map_v AS
202
246
  SELECT
203
247
  *
204
248
  FROM
@@ -211,7 +255,7 @@ ORDER BY
211
255
  p.is_tou,
212
256
  p.start_time;
213
257
 
214
- CREATE VIEW pic_pricebooks_tesla_condensed_v AS
258
+ CREATE VIEW pic_price_map_condensed_v AS
215
259
  SELECT
216
260
  c.*,
217
261
  base.start_time AS base_start_time,
@@ -244,29 +288,29 @@ SELECT
244
288
  s5.uom AS s5_uom
245
289
  FROM
246
290
  pic_chargers_v AS c
247
- LEFT JOIN pic_pricebooks_tesla_v base ON base.pic_chargers_id = c.id
291
+ LEFT JOIN pic_price_map_v base ON base.pic_chargers_id = c.id
248
292
  AND base.last_fetch_uuid = c.last_fetch_uuid
249
293
  AND base.sort_order IS NULL
250
- LEFT JOIN pic_pricebooks_tesla_v s0 ON s0.pic_chargers_id = c.id
294
+ LEFT JOIN pic_price_map_v s0 ON s0.pic_chargers_id = c.id
251
295
  AND s0.last_fetch_uuid = c.last_fetch_uuid
252
296
  AND s0.sort_order = 0
253
- LEFT JOIN pic_pricebooks_tesla_v s1 ON s1.pic_chargers_id = c.id
297
+ LEFT JOIN pic_price_map_v s1 ON s1.pic_chargers_id = c.id
254
298
  AND s1.last_fetch_uuid = c.last_fetch_uuid
255
299
  AND s1.sort_order = 1
256
- LEFT JOIN pic_pricebooks_tesla_v s2 ON s2.pic_chargers_id = c.id
300
+ LEFT JOIN pic_price_map_v s2 ON s2.pic_chargers_id = c.id
257
301
  AND s2.last_fetch_uuid = c.last_fetch_uuid
258
302
  AND s2.sort_order = 2
259
- LEFT JOIN pic_pricebooks_tesla_v s3 ON s3.pic_chargers_id = c.id
303
+ LEFT JOIN pic_price_map_v s3 ON s3.pic_chargers_id = c.id
260
304
  AND s3.last_fetch_uuid = c.last_fetch_uuid
261
305
  AND s3.sort_order = 3
262
- LEFT JOIN pic_pricebooks_tesla_v s4 ON s4.pic_chargers_id = c.id
306
+ LEFT JOIN pic_price_map_v s4 ON s4.pic_chargers_id = c.id
263
307
  AND s4.last_fetch_uuid = c.last_fetch_uuid
264
308
  AND s4.sort_order = 4
265
- LEFT JOIN pic_pricebooks_tesla_v s5 ON s5.pic_chargers_id = c.id
309
+ LEFT JOIN pic_price_map_v s5 ON s5.pic_chargers_id = c.id
266
310
  AND s5.last_fetch_uuid = c.last_fetch_uuid
267
311
  AND s5.sort_order = 5;
268
312
 
269
- CREATE VIEW pic_pricebooks_tesla_ui_v AS
313
+ CREATE VIEW pic_price_map_ui_v AS
270
314
  SELECT
271
315
  v.*,
272
316
  CASE
@@ -339,7 +383,7 @@ SELECT
339
383
  )
340
384
  END AS s5_timeslot
341
385
  FROM
342
- pic_pricebooks_tesla_condensed_v AS v;
386
+ pic_price_map_condensed_v AS v;
343
387
 
344
388
  -- charging process states ------------------------------------------------------------------------------
345
389
  CREATE TABLE IF NOT EXISTS pic_charging_process_states (
@@ -660,6 +704,10 @@ SELECT
660
704
  h.start_uuid AS last_fetch_uuid,
661
705
  h.is_tou,
662
706
  h.time_zone,
707
+ -- how far this snapshot is actually known: its successor's valid_since, or
708
+ -- the last fetch that confirmed it. Carried through so a consumer can stop a
709
+ -- series where the knowledge stops instead of extending the last value on.
710
+ h."end" AS valid_until,
663
711
  EXTRACT(
664
712
  DOW
665
713
  FROM
@@ -681,6 +729,10 @@ FROM
681
729
  CREATE VIEW pic_price_history_v AS
682
730
  SELECT
683
731
  ((k.date + b.start_time) AT TIME ZONE k.time_zone) AS TIMESTAMP,
732
+ -- the instant this row's snapshot stops being known — see
733
+ -- pic_price_history_key_v. A panel drawing a step series must stop there;
734
+ -- carrying the last value past it claims a price nobody checked.
735
+ k.valid_until,
684
736
  k.pic_chargers_id,
685
737
  c.location_url_slug,
686
738
  k.last_fetch_uuid,