feat(analytics): Phase 0 — analytics-config migration and CSV importer rewrite
Phase 0 of the three-stakeholder analytics redesign: - 08_analytics_config.sql: ops.cost_rates + ops.kpi_targets with seed fuel rates (KES 195/L NBO+MBA, UGX 5200/L KLA) and 6 seed KPI targets (utilisation_pct, idle_pct global+osp-patrol, fuel_kes_per_100km, mttr_hours, alarms_per_100km). Granted SELECT to grafana_ro. Wired into run_migrations.py MIGRATIONS. - import_drivers_csv.py: full rewrite for the new Mitieng CSV (20260427_FSG_Vehicles_mitieng.csv). Snake_case columns, drops _infer_city() plate-prefix logic in favour of reading assigned_city directly. Adds cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address. Treats the literal "NULL" string as missing. Reuses clean(), clean_num(), clean_ts(), get_conn(), get_logger() from ts_shared_rev. Special-cases numeric and timestamptz columns in the UPDATE clause. - audit_device_reconciliation.py: read-only audit comparing the CSV against tracksolid.devices. Reports per-account row counts, IMEIs on one side only, and devices on both sides whose metadata is still NULL. - 260427_device_reconciliation.md + 260427_audit_output.txt: Phase 0.2 reconciliation record. First run: DB has 172 devices, CSV has 162, delta +10 (10 IMEIs in DB-only, mostly fireside-account auto-syncs). Importer run with --only-null --apply filled 154 rows; coverage now assigned_city 152/172, cost_centre 150/172. Applied to stage on 2026-04-27 23:35 UTC. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
5418fc48c5
commit
898fd25a5a
7 changed files with 785 additions and 91 deletions
121
08_analytics_config.sql
Normal file
121
08_analytics_config.sql
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
-- Migration 08 — Analytics Configuration Tables
|
||||||
|
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
-- Adds reference data driving the three-stakeholder analytics redesign
|
||||||
|
-- (Phase 0.3 of the plan). These tables let downstream views monetise idle
|
||||||
|
-- and fuel costs, and apply traffic-light targets to KPIs without hard-coding
|
||||||
|
-- thresholds in SQL.
|
||||||
|
--
|
||||||
|
-- • ops.cost_rates — fuel price per litre by city, labour rate by role.
|
||||||
|
-- • ops.kpi_targets — green / amber / red thresholds per KPI per scope.
|
||||||
|
--
|
||||||
|
-- Run after migration 07. Safe to re-run (CREATE TABLE IF NOT EXISTS,
|
||||||
|
-- INSERT ... ON CONFLICT DO NOTHING).
|
||||||
|
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- ── 1. ops.cost_rates ───────────────────────────────────────────────────────
|
||||||
|
-- Reference rates that power monetisation in analytics views. Lookup pattern
|
||||||
|
-- in views: WHERE scope_type = 'city' AND scope_value = <city> AND metric = ...
|
||||||
|
-- ORDER BY effective_from DESC LIMIT 1.
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS ops.cost_rates (
|
||||||
|
rate_key TEXT PRIMARY KEY,
|
||||||
|
scope_type TEXT NOT NULL, -- 'city' | 'role' | 'global'
|
||||||
|
scope_value TEXT, -- 'nairobi' | 'driver' | NULL for global
|
||||||
|
metric TEXT NOT NULL, -- 'fuel_per_litre' | 'labour_per_hour'
|
||||||
|
amount NUMERIC(12,2) NOT NULL,
|
||||||
|
currency TEXT NOT NULL, -- 'KES' | 'UGX'
|
||||||
|
effective_from DATE NOT NULL DEFAULT CURRENT_DATE,
|
||||||
|
notes TEXT,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_cost_rates_lookup
|
||||||
|
ON ops.cost_rates (scope_type, scope_value, metric, effective_from DESC);
|
||||||
|
|
||||||
|
COMMENT ON TABLE ops.cost_rates
|
||||||
|
IS 'Reference rates for analytics monetisation: fuel price per litre by city, '
|
||||||
|
'labour cost per hour by role. Resolution order in views: scope_type=city '
|
||||||
|
'> scope_type=role > scope_type=global.';
|
||||||
|
COMMENT ON COLUMN ops.cost_rates.metric
|
||||||
|
IS 'fuel_per_litre | labour_per_hour';
|
||||||
|
COMMENT ON COLUMN ops.cost_rates.scope_type
|
||||||
|
IS 'city | role | global';
|
||||||
|
|
||||||
|
-- ── 2. ops.kpi_targets ──────────────────────────────────────────────────────
|
||||||
|
-- Traffic-light thresholds per KPI. Same KPI can have global + per-CC + per-city
|
||||||
|
-- rows; views use a CASE / COALESCE chain to pick the most specific match.
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS ops.kpi_targets (
|
||||||
|
target_id BIGSERIAL PRIMARY KEY,
|
||||||
|
kpi_key TEXT NOT NULL, -- e.g. 'utilisation_pct'
|
||||||
|
scope_type TEXT NOT NULL, -- 'global' | 'city' | 'cost_centre' | 'vehicle_category'
|
||||||
|
scope_value TEXT, -- NULL for global
|
||||||
|
target_value NUMERIC(12,2) NOT NULL,
|
||||||
|
amber_threshold NUMERIC(12,2), -- between target and red
|
||||||
|
red_threshold NUMERIC(12,2), -- worse than amber
|
||||||
|
direction TEXT NOT NULL DEFAULT 'higher_is_better',
|
||||||
|
-- 'higher_is_better' | 'lower_is_better'
|
||||||
|
effective_from DATE NOT NULL DEFAULT CURRENT_DATE,
|
||||||
|
notes TEXT,
|
||||||
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||||
|
UNIQUE (kpi_key, scope_type, scope_value, effective_from)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_kpi_targets_lookup
|
||||||
|
ON ops.kpi_targets (kpi_key, scope_type, scope_value, effective_from DESC);
|
||||||
|
|
||||||
|
COMMENT ON TABLE ops.kpi_targets
|
||||||
|
IS 'Traffic-light targets per KPI per scope. Resolution order in views: '
|
||||||
|
'cost_centre > vehicle_category > city > global.';
|
||||||
|
COMMENT ON COLUMN ops.kpi_targets.direction
|
||||||
|
IS 'higher_is_better -> green when value >= target. '
|
||||||
|
'lower_is_better -> green when value <= target.';
|
||||||
|
|
||||||
|
-- ── 3. Seed cost rates ──────────────────────────────────────────────────────
|
||||||
|
-- Placeholder values — confirm with Finance and update via a follow-up insert
|
||||||
|
-- with a later effective_from date (do NOT mutate historical rows).
|
||||||
|
|
||||||
|
INSERT INTO ops.cost_rates
|
||||||
|
(rate_key, scope_type, scope_value, metric, amount, currency, notes)
|
||||||
|
VALUES
|
||||||
|
('fuel.nairobi', 'city', 'nairobi', 'fuel_per_litre', 195.00, 'KES',
|
||||||
|
'Placeholder pump price — confirm with Finance.'),
|
||||||
|
('fuel.mombasa', 'city', 'mombasa', 'fuel_per_litre', 195.00, 'KES',
|
||||||
|
'Placeholder pump price — confirm with Finance.'),
|
||||||
|
('fuel.kampala', 'city', 'kampala', 'fuel_per_litre', 5200.00, 'UGX',
|
||||||
|
'Placeholder pump price — confirm with Finance.')
|
||||||
|
ON CONFLICT (rate_key) DO NOTHING;
|
||||||
|
|
||||||
|
-- ── 4. Seed KPI targets ─────────────────────────────────────────────────────
|
||||||
|
-- Initial Exco-relevant targets. Calibrate after one month of clean data.
|
||||||
|
|
||||||
|
INSERT INTO ops.kpi_targets
|
||||||
|
(kpi_key, scope_type, scope_value, target_value, amber_threshold,
|
||||||
|
red_threshold, direction, notes)
|
||||||
|
VALUES
|
||||||
|
('utilisation_pct', 'global', NULL, 70, 60, 50, 'higher_is_better',
|
||||||
|
'Fleet utilisation: drive_hours / engine_on_hours.'),
|
||||||
|
('idle_pct', 'global', NULL, 15, 20, 25, 'lower_is_better',
|
||||||
|
'Idle as % of engine-on time.'),
|
||||||
|
('idle_pct', 'cost_centre', 'osp patrol', 15, 20, 25, 'lower_is_better',
|
||||||
|
'OSP patrol idle target — same as global until calibrated.'),
|
||||||
|
('fuel_kes_per_100km', 'global', NULL, 12, 14, 16, 'lower_is_better',
|
||||||
|
'Fuel litres per 100km equivalent — uses fuel_100km on devices.'),
|
||||||
|
('mttr_hours', 'global', NULL, 4, 6, 8, 'lower_is_better',
|
||||||
|
'Mean Time To Resolve, field-service ticket.'),
|
||||||
|
('alarms_per_100km', 'global', NULL, 2, 3, 5, 'lower_is_better',
|
||||||
|
'Safety event density.')
|
||||||
|
ON CONFLICT (kpi_key, scope_type, scope_value, effective_from) DO NOTHING;
|
||||||
|
|
||||||
|
-- ── 5. Read access for Grafana ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
GRANT USAGE ON SCHEMA ops TO grafana_ro;
|
||||||
|
GRANT SELECT ON ops.cost_rates TO grafana_ro;
|
||||||
|
GRANT SELECT ON ops.kpi_targets TO grafana_ro;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
163
20260427_FSG_Vehicles_mitieng.csv
Normal file
163
20260427_FSG_Vehicles_mitieng.csv
Normal file
|
|
@ -0,0 +1,163 @@
|
||||||
|
imei,device_name,mc_type,mc_type_use_scope,vehicle_name,vehicle_number,vehicle_models,vehicle_icon,vin,engine_number,vehicle_brand,fuel_100km,driver_name,driver_phone,sim,iccid,imsi,account,customer_name,device_group_id,device_group,activation_time,expiration,enabled_flag,status,city,current_mileage_km,created_at,updated_at,last_synced_at,vehicle_category,cost_centre,assigned_route,depot_geom,depot_address,assigned_city
|
||||||
|
353549090553685,Daniel Omondi - KMFF 099Z,AT4,personal,KMFF 099Z,KMFF 099Z,Motorbike,mtc,NULL,NULL,NULL,NULL,Robert,112794067,759336150,89254021334258404099,639021335840409,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-09-23 05:50:30+00,2040-09-23 23:59:59+00,1,1,mombasa,2354.7,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp patrol,NULL,NULL,NULL,mombasa
|
||||||
|
353549090561720,Wireless_Git,AT4,personal,NULL,NULL,NULL,bus,NULL,NULL,NULL,NULL,NULL,NULL,701211913,89254021374215155053,639021371515505,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2025-06-09 09:12:50+00,2035-06-09 23:59:59+00,1,1,mombasa,5992.43,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,regional,NULL,NULL,NULL,mombasa
|
||||||
|
353549090566281,KDR 592N,AT4,personal,NULL,NULL,NULL,bus,NULL,NULL,NULL,NULL,NULL,NULL,797680464,89254021334258159693,639021335815969,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2024-11-08 04:01:30+00,2034-11-08 23:59:59+00,1,1,nairobi,7771.9,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,nairobi
|
||||||
|
353549090566885,Wireless GPS,AT4,personal,NULL,NULL,NULL,bus,NULL,NULL,NULL,NULL,NULL,NULL,768445963,89254021334212352574,639021331235257,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2024-10-15 13:16:57+00,2034-10-15 23:59:59+00,1,1,nairobi,17036.41,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,null,NULL,NULL,NULL,nairobi
|
||||||
|
353549090567685,Daniel Kipkirui - KMFF 162Z,AT4,personal,KMFF 162Z,KMFF 162Z,Motorbike,mtc,NULL,NULL,NULL,NULL,Daniel Kipkirui,112795498,742532058,89254021264260388966,639021266038896,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-09-23 05:09:39+00,2040-09-23 23:59:59+00,1,1,mombasa,462.33,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp patrol,NULL,NULL,NULL,mombasa
|
||||||
|
353549090567701,Wireless,AT4,personal,NULL,NULL,NULL,bus,NULL,NULL,NULL,NULL,NULL,NULL,790176094,89254021394215205906,639021391520590,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2024-11-08 04:04:44+00,2034-11-08 23:59:59+00,1,1,nairobi,16896.2,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,null,NULL,NULL,NULL,nairobi
|
||||||
|
359857081885410,Allan Owana - KDK 780K,GT06E,automobile,KDK 780K,KDK 780K,Probox,automobile,NULL,NULL,NULL,NULL,Allan Owana,NULL,703616117,89254021234222499854,639021232249985,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2019-06-19 09:32:22+00,2039-06-19 23:59:59+00,1,1,nairobi,128853.11,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
359857081886467,Gideon Kiprono - KCQ 215F,GT06E,automobile,KCQ 215F,OHS,Probox,automobile,NULL,NULL,NULL,0,Gideon Kiprono,NULL,746763076,89254021084186499865,639021088649986,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2019-06-30 09:30:00+00,2039-06-30 23:59:59+00,1,1,mombasa,141057.46,2026-04-23 10:56:37.983314+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
359857081886871,Kamonde KBA 467S,GT06E,automobile,NULL,NULL,NULL,bus,NULL,NULL,NULL,NULL,NULL,NULL,746763083,89254021084186499873,639021088649987,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2019-06-30 09:09:14+00,2039-06-30 23:59:59+00,1,1,nairobi,74183.36,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,personal,NULL,NULL,NULL,nairobi
|
||||||
|
359857081886905,Kennedy Chege - KCQ 618K,GT06E,automobile,KCQ 618K,KCQ 618K,Probox,automobile,NULL,NULL,NULL,NULL,Kennedy Chege,NULL,746763132,89254021084186499923,639021088649992,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2019-06-30 07:08:35+00,2039-06-30 23:59:59+00,1,1,mombasa,215608.19,2026-04-23 10:35:37.678371+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
359857081887069,Wright Oseko - KCG 668W,GT06E,automobile,KCG 668W,KCG 668W,Probox,automobile,NULL,NULL,NULL,NULL,Wright Oseko,NULL,746763106,89254021084186499915,639021088649991,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2019-06-30 06:17:43+00,2039-06-30 23:59:59+00,1,1,nairobi,239001.19,2026-04-23 11:00:08.769463+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
359857081887192,Ndegwa Dancun - KCG 669W,GT06E,automobile,KCG 669W,KCG 669W,Probox,automobile,NULL,NULL,NULL,NULL,Ndegwa Dancun,NULL,746760191,89254021084186499501,639021088649950,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2019-06-15 10:26:15+00,2039-06-15 23:59:59+00,1,1,mombasa,199191.85,2026-04-23 10:34:29.074112+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
359857081891566,Simon Kamau - KCE 090R,GT06E,automobile,KCE 090R,KCE 090R,Probox,automobile,NULL,NULL,NULL,NULL,Simon Kamau,NULL,746760404,89254021084186499527,639021088649952,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2019-06-16 07:06:15+00,2039-06-16 23:59:59+00,1,1,nairobi,215592.36,2026-04-23 10:30:55.739184+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
359857081891590,Garage - KCE 699F,GT06E,automobile,KCE 699F,KCE 699F,Probox,automobile,NULL,NULL,NULL,NULL,Garage,NULL,746760215,89254021084186499519,639021088649951,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2019-06-16 11:11:24+00,2039-06-16 23:59:59+00,1,1,nairobi,207814.05,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
359857081891632,Samuel Kamau - KCA 542Q,GT06E,automobile,KCA 542Q,KCA 542Q,Probox,automobile,NULL,NULL,NULL,NULL,John Ondego,NULL,746760038,89254021084186499485,639021088649948,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2019-06-15 09:17:53+00,2039-06-15 23:59:59+00,1,1,nairobi,178914.47,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,roll out,NULL,NULL,NULL,nairobi
|
||||||
|
359857081891798,Garage - KCH 167M,GT06E,automobile,KCH 167M,KCH 167M,Probox,automobile,NULL,NULL,NULL,NULL,Garage,NULL,746760102,89254021084186499493,639021088649949,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2019-06-16 10:18:57+00,2039-06-16 23:59:59+00,1,1,nairobi,168840.95,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
359857081892101,Cornelius Kimutai - KCU 938R,GT06E,automobile,KCU 938R,KCU 938R,Van,automobile,NULL,NULL,NULL,NULL,Cornelius Kimutai,NULL,746759919,89254021084186499451,639021088649945,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2019-06-12 08:13:48+00,2039-06-12 23:59:59+00,1,1,nairobi,149558.5,2026-04-23 10:29:21.507861+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,nairobi
|
||||||
|
359857081892309,Nicholas Erastus - KCQ 581M,GT06E,automobile,KCQ 581M,KCQ 581M,Probox,automobile,NULL,NULL,NULL,NULL,Nicholas Erastus,NULL,700023776,89254021084178504672,639021087850467,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2019-06-09 09:39:40+00,2039-06-09 23:59:59+00,1,1,nairobi,209105.89,2026-04-23 10:40:40.169684+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
359857081892440,KAZ 489Z,GT06E,automobile,NULL,NULL,NULL,bus,NULL,NULL,NULL,NULL,NULL,NULL,700023806,89254021084178504698,639021087850469,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2019-06-09 10:04:39+00,2039-06-09 23:59:59+00,1,1,nairobi,38197.2,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,personal,NULL,NULL,NULL,nairobi
|
||||||
|
359857081892762,Nicholas,GT06E,automobile,NULL,NULL,Station Wagon,bus,NULL,NULL,Toyota,NULL,NULL,NULL,746760503,89254021274233125361,639021273312536,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2019-06-16 08:31:46+00,2039-06-16 23:59:59+00,1,1,mombasa,51048.97,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,personal,NULL,NULL,NULL,nairobi
|
||||||
|
359857082037185,Amani Kazungu - KCY 084X,GT06E,automobile,KCY 084X,KCY 084X,Probox,automobile,NULL,NULL,NULL,NULL,Amani Kazungu,NULL,757338522,89254021154287000597,639021158700059,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-07-13 09:42:28+00,2040-07-13 23:59:59+00,1,1,mombasa,172298.81,2026-04-23 10:51:08.665273+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,mombasa
|
||||||
|
359857082038977,Wilfred Kinyanjui - KCU 729C,GT06E,automobile,KCU 729C,KCU 729C,Crane,truck,NULL,NULL,NULL,NULL,Wilfred Kinyanjui,NULL,110094469,89254021164215938057,639021161593805,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-04-05 09:26:00+00,2040-04-05 23:59:59+00,1,1,nairobi,172487.09,2026-04-23 10:24:33.914628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,general,NULL,NULL,NULL,mombasa
|
||||||
|
359857082040981,Amani Sulubu - KCY 090X,GT06E,automobile,KCY 090X,KCY 090X,Probox,automobile,NULL,NULL,NULL,NULL,Amani Sulubu,NULL,793375853,89254021064168004164,639021066800416,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-07-13 07:25:16+00,2040-07-13 23:59:59+00,1,1,mombasa,166028.15,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
359857082042052,Gabriel Musumba - KCE 690F,GT06E,automobile,KCE 690F,KCE 690F,Probox,automobile,NULL,NULL,NULL,NULL,Gabriel Musumba,NULL,110094466,89254021164215938024,639021161593802,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2020-04-03 17:30:13+00,2040-04-03 23:59:59+00,1,1,nairobi,192693.23,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
359857082042854,Elias Baya - KCZ 476E,GT06E,automobile,KCZ 476E,KCZ 476E,Probox,automobile,NULL,NULL,NULL,NULL,Elias Baya,NULL,110941187,89254021164224352993,639021162435299,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-08-09 05:06:42+00,2040-08-09 23:59:59+00,1,1,mombasa,217595.68,2026-04-23 10:33:56.216621+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,mombasa
|
||||||
|
359857082042953,KCU 865Q Vanguard,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,unknown,null,NULL,2026-04-23 13:24:33.293453+00,2026-04-23 13:24:33.293453+00,NULL,NULL,null,NULL,NULL,NULL,null
|
||||||
|
359857082044280,Lawrence Kijogi - KCY 080X,GT06E,automobile,KCY 080X,KCY 080X,Probox,automobile,NULL,NULL,NULL,NULL,Lawrence Kijogi,NULL,708155933,89254029851005131222,639029850513122,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-07-13 11:05:02+00,2040-07-13 11:05:02+00,1,1,mombasa,169740.37,2026-04-23 14:52:58.983571+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,roll out,NULL,NULL,NULL,mombasa
|
||||||
|
359857082046145,Joseph Kabandi - KCY 076X,GT06E,automobile,KCY 076X,KCY 076X,Probox,automobile,NULL,NULL,NULL,NULL,Joseph Kabandi,NULL,110850007,89254021164223447158,639021162344715,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-07-13 08:31:26+00,2040-07-13 23:59:59+00,1,1,mombasa,122254.48,2026-04-23 10:47:40.895504+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
359857082896911,Hamisi Pande - KDD 689Y,GT06E,automobile,KDD 689Y,KDD 689Y,Probox,automobile,NULL,NULL,NULL,NULL,Hamisi Pande,NULL,112714612,89254021214211314660,639021211131466,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-09-17 11:50:53+00,2041-09-17 23:59:59+00,1,1,nairobi,163435.74,2026-04-23 10:26:09.922447+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
359857082897091,Peter Mbugua - KDK 728K,GT06E,automobile,KDK 728K,KDK 728K,Probox,automobile,NULL,NULL,NULL,NULL,Peter Mbugua,NULL,790262984,89254021234222500396,639021232250039,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-12-14 11:31:57+00,2042-12-14 23:59:59+00,1,1,nairobi,131109.26,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
359857082897257,Cassius Wakiyo - KDB 323M,GT06E,automobile,KDB 323M,KDB 323M,Probox,automobile,NULL,NULL,NULL,NULL,Cassius Wakiyo,NULL,746428882,89254021234222500818,639021232250081,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-08-29 15:07:26+00,2041-08-29 15:07:26+00,1,1,nairobi,121688.92,2026-04-23 10:28:26.388654+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
359857082897737,John Makori - KDB 585E,GT06E,automobile,KDB 585E,KDB 585E,Probox,automobile,NULL,NULL,NULL,NULL,John Makori,NULL,114596734,89254021214211145262,639021211114526,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-08-29 14:29:28+00,2041-08-29 14:29:28+00,1,1,nairobi,156765.03,2026-04-23 10:38:57.445964+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,planning,NULL,NULL,NULL,nairobi
|
||||||
|
359857082897794,Mutuku Joseph - KDC 739F,GT06E,automobile,KDC 739F,KDC 739F,Probox,automobile,NULL,NULL,NULL,NULL,Mutuku Joseph,115019037,115019037,89254021224222632356,639021222263235,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-04-10 14:55:32+00,2041-04-10 14:55:32+00,1,1,nairobi,205169.79,2026-04-23 10:30:22.530563+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,nairobi
|
||||||
|
359857082898008,Samuel Ng'ang'a - KDE 264M,GT06E,automobile,KDE 264M,KDE 264M,Probox,automobile,NULL,NULL,NULL,NULL,Samuel Ng'ang'a,NULL,711731539,89254021264260342245,639021266034224,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-10-28 09:43:11+00,2041-10-28 23:59:59+00,1,1,nairobi,126584.24,2026-04-23 11:35:59.816581+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
359857082898016,Job Ngare - KDM 309S,GT06E,automobile,KDM 309S,KDM 309S,Probox,automobile,NULL,NULL,NULL,NULL,Job Ngare,NULL,706895756,89254021324273007563,639021327300756,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2023-08-15 13:45:26+00,2033-08-15 23:59:59+00,1,1,mombasa,107726.56,2026-04-23 11:20:25.939244+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
359857082898073,Mutuku Antony - KDK 732K,GT06E,automobile,KDK 732K,KDK 732K,Probox,automobile,NULL,NULL,NULL,NULL,Mutuku Antony,NULL,793026954,89254021234222387539,639021232238753,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-12-20 06:33:12+00,2042-12-20 23:59:59+00,1,1,mombasa,82096.79,2026-04-23 14:52:07.094447+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,mombasa
|
||||||
|
359857082898487,Dan Watila - KDE 638J,GT06E,automobile,KDE 638J,KDE 638J,Probox,automobile,NULL,NULL,NULL,NULL,Dan Watila,NULL,116242996,89254021334258404214,639021335840421,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-10-21 15:50:06+00,2041-10-21 23:59:59+00,1,1,nairobi,123872.36,2026-04-23 10:31:45.186653+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
359857082900168,KDD 913G_Ruth Mazda,NULL,NULL,KDD 913G,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,unknown,nairobi,NULL,2026-04-23 15:09:48.575568+00,2026-04-23 15:09:48.575568+00,NULL,NULL,personal,NULL,NULL,NULL,nairobi
|
||||||
|
359857082900341,Simon Munda - KCZ 154S,GT06E,automobile,KCZ 154S,KCZ 154S,Probox,automobile,NULL,NULL,NULL,NULL,Simon Munda,NULL,757236135,89254021154296723312,639021159672331,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-09-23 17:12:51+00,2040-09-23 23:59:59+00,1,1,mombasa,186504.1,2026-04-23 10:45:21.454595+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
359857082900358,Geoffrey Too - KDM 308S,GT06E,automobile,KDM 308S,KDM 308S,Probox,automobile,NULL,NULL,NULL,NULL,Geoffrey Too,NULL,796527601,89254021264260126572,639021266012657,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-10-21 15:25:28+00,2041-10-21 23:59:59+00,1,1,nairobi,142216.91,2026-04-23 12:35:06.661934+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
359857082900697,George Ochieng' - KDD 684Y,GT06E,automobile,KDD 684Y,KDD 684Y,Probox,automobile,NULL,NULL,NULL,NULL,George Ochieng',NULL,114879518,89254021214211314678,639021211131467,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-09-17 10:53:11+00,2041-09-17 23:59:59+00,1,1,nairobi,152820.07,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
359857082902461,Sadique Wakayula - KDC 490Q,GT06E,automobile,KDC 490Q,KDC 490Q,Crane,truck,NULL,NULL,NULL,NULL,Sadique Wakayula,NULL,757556468,89254021154296722488,639021159672248,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-05-22 11:27:30+00,2041-05-22 11:27:30+00,1,1,mombasa,183009.52,2026-04-23 11:16:03.730519+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,general,NULL,NULL,NULL,mombasa
|
||||||
|
359857082902503,Felix Andole - KDC 207R,GT06E,automobile,KDC 207R,KDC 207R,Probox,automobile,NULL,NULL,NULL,NULL,Felix Andole,NULL,794820817,89254021224270993254,639021227099325,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-05-15 11:38:24+00,2041-05-15 11:38:24+00,1,1,mombasa,208724.46,2026-04-23 15:32:46.935568+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
359857082907973,Felix Muema - KCZ 223P,GT06E,automobile,KCZ 223P,KCZ 223P,Probox,automobile,NULL,NULL,NULL,NULL,Felix Muema,NULL,757843826,89254021154287138371,639021158713837,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-08-22 14:01:25+00,2040-08-22 23:59:59+00,1,1,mombasa,222126.36,2026-04-23 10:26:48.220151+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
359857082908500,Santoes Omondi - KCZ 181P,GT06E,automobile,KCZ 181P,KCZ 181P,Pick-Up,automobile,NULL,NULL,NULL,NULL,Santoes Omondi,NULL,701211974,89254021374215155087,639021371515508,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-08-23 08:58:55+00,2040-08-23 23:59:59+00,1,1,mombasa,221339.62,2026-04-23 10:48:09.537346+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
359857082910589,Patric Bett - KDA 609E,GT06E,automobile,KDA 609E,KDA 609E,Probox,automobile,NULL,NULL,NULL,NULL,Patric Bett,NULL,797622637,89254021154296722496,639021159672249,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2020-10-26 15:46:41+00,2040-10-26 23:59:59+00,1,1,nairobi,194618.69,2026-04-23 10:34:25.350862+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
359857082910886,Makanda Andrew - KCZ 155P,GT06E,automobile,KCZ 155P,KCZ 155P,Pick-Up,automobile,NULL,NULL,NULL,NULL,Makanda Andrew,NULL,745067338,89254021154287138397,639021158713839,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-08-23 11:52:35+00,2040-08-23 23:59:59+00,1,1,mombasa,231065.89,2026-04-23 11:36:31.150282+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
359857082911983,Brian Ngetich - KDA 717B,GT06E,automobile,KDA 717B,KDA 717B,Probox,automobile,NULL,NULL,NULL,NULL,Brian Ngetich,795188807,795188807,89254021214211145288,639021211114528,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-08-29 07:21:43+00,2041-08-29 07:21:43+00,1,1,nairobi,145404.96,2026-04-23 10:36:11.774166+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
359857082912239,Dickson Jaoko - KDK 815R,GT06E,automobile,KDK 815R,KDK 815R,Probox,automobile,NULL,NULL,Probox,0,Sammy,NULL,706392117,89254021234296021287,639021239602128,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2023-06-21 07:14:51+00,2033-06-21 23:59:59+00,1,1,voi,77008.75,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
359857082912486,Moses Wambua - KCZ 751V,GT06E,automobile,KCZ 751V,KCZ 751V,Probox,automobile,NULL,NULL,NULL,NULL,Moses Wambua,792756503,792756503,89254021154296723437,639021159672343,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-09-23 10:14:28+00,2040-09-23 23:59:59+00,1,1,mombasa,139762.2,2026-04-23 10:41:00.207177+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
359857082916826,Denis Kazungu - KDM 794R,GT06E,automobile,KDM 794R,KDM 794R,Probox,automobile,NULL,NULL,NULL,NULL,Denis Kazungu,NULL,705700971,89254021324273006854,639021327300685,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2023-08-21 06:38:00+00,2033-08-21 23:59:59+00,1,1,mombasa,79639.71,2026-04-23 20:18:46.496567+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,mombasa
|
||||||
|
359857082918012,Charles Nyambane - KCB 711C,GT06E,automobile,KCB 711C,KCB 711C,Probox,automobile,NULL,NULL,NULL,NULL,Charles Nyambane,NULL,793704231,89254021154287138363,639021158713836,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2020-09-21 10:48:35+00,2040-09-21 23:59:59+00,1,1,nairobi,159597.27,2026-04-23 10:25:52.843474+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
359857082918038,Mbuvi Kioko - KCC 199P,GT06E,automobile,KCC 199P,KCC 199P,Pick-Up,automobile,NULL,NULL,NULL,NULL,Mbuvi Kioko,NULL,797318126,89254021154287138389,639021158713838,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-08-22 15:26:27+00,2040-08-22 23:59:59+00,1,1,mombasa,222106.8,2026-04-23 12:09:05.609075+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
359857082918186,KDD 977T Fielder,NULL,NULL,KDD 977T,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,unknown,null,NULL,2026-04-23 10:36:25.832836+00,2026-04-23 10:36:25.832836+00,NULL,NULL,null,NULL,NULL,NULL,null
|
||||||
|
359857082925330,Noel Merengeni - KCY 838X,GT06E,automobile,KCY 838X,KCY 838X,Probox,automobile,NULL,NULL,NULL,NULL,Noel Merengeni,NULL,794873610,89254021154296723429,639021159672342,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2020-10-26 16:36:37+00,2040-10-26 23:59:59+00,1,1,voi,194429.24,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,mombasa
|
||||||
|
862798050288212,Nicholas Erastus - KCQ 581M,JC400P,automobile,KCQ 581M,KCQ 581M,Probox,automobile,NULL,NULL,NULL,NULL,Nicholas Erastus,NULL,746979531,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-11-02 09:07:41+00,2041-11-02 23:59:59+00,1,1,nairobi,40898.98,2026-04-23 13:05:18.326254+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050288261,Patric Bett - KDA 609E,JC400P,automobile,KDA 609E,KDA 609E,Probox,automobile,NULL,NULL,NULL,NULL,Patric Bett,112693340,790176509,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2021-10-23 11:50:11+00,2041-10-23 23:59:59+00,1,1,nairobi,18538.42,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050288303,Elias Baya - KCZ 476E,JC400P,automobile,KCZ 476E,KCZ 476E,Probox,automobile,NULL,NULL,NULL,NULL,Elias Baya,NULL,115870439,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-11-06 08:50:28+00,2041-11-06 23:59:59+00,1,1,mombasa,116091.42,2026-04-23 17:46:09.993791+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,mombasa
|
||||||
|
862798050288345,Santoes Omondi - KCZ 181P,JC400P,automobile,KCZ 181P,KCZ 181P,Pick-Up,automobile,NULL,NULL,NULL,NULL,Santoes Omondi,NULL,768446105,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2021-11-06 10:17:51+00,2041-11-06 23:59:59+00,1,1,mombasa,107462.79,2026-04-23 10:29:45.563231+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050288360,Brian Ngetich - KDA 717B,JC400P,automobile,KDA 717B,KDA 717B,Probox,automobile,NULL,NULL,NULL,NULL,Brian Ngetich,NULL,717867861,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2021-11-05 08:47:08+00,2041-11-05 23:59:59+00,1,1,nairobi,17808.56,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050521521,John Kimeria - KDS 525D,JC400P,automobile,KDS 525D,KDS 525D,Crane,truck,NULL,NULL,NULL,NULL,John Kimeria,NULL,752958416,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2023-11-26 07:58:13+00,2033-11-26 23:59:59+00,1,1,nairobi,19354.92,2026-04-23 10:28:34.917147+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,general,NULL,NULL,NULL,nairobi
|
||||||
|
862798050521612,Denis Kazungu - KDM 794R,JC400P,automobile,KDM 794R,KDM 794R,Probox,automobile,NULL,NULL,NULL,NULL,Denis Kazungu,NULL,704113731,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-01-22 07:52:12+00,2042-01-22 23:59:59+00,1,1,mombasa,4350.75,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,mombasa
|
||||||
|
862798050521752,Simon Munda - KCZ 154S,JC400P,automobile,KCZ 154S,KCZ 154S,Probox,automobile,NULL,NULL,NULL,NULL,Simon Munda,NULL,113805921,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-01-16 08:14:37+00,2042-01-16 23:59:59+00,1,1,mombasa,4698.02,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050522065,Gideon Kiprono - KCQ 215F,JC400P,automobile,KCQ 215F,KCQ 215F,Probox,automobile,NULL,NULL,NULL,NULL,Gideon Kiprono,NULL,113343715,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2022-01-16 07:10:16+00,2042-01-16 23:59:59+00,1,1,mombasa,8111.98,2026-04-23 18:23:51.445608+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050522107,Cassius Wakiyo - KDB 323M,JC400P,automobile,KDB 323M,KDB 323M,Probox,automobile,NULL,NULL,NULL,NULL,Cassius Wakiyo,NULL,114149576,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-22 08:18:15+00,2042-01-22 23:59:59+00,1,1,nairobi,23316.09,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050522719,Mbuvi Kioko - KCZ 199P,JC400P,automobile,KCZ 199P,KCZ 199P,Pick-Up,automobile,NULL,NULL,NULL,NULL,Mbuvi Kioko,NULL,768218655,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-01-16 22:07:24+00,2042-01-16 23:59:59+00,1,1,voi,16973.89,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050522743,Charles Nyambane - KCB 711C,JC400P,automobile,KCB 711C,KCB 711C,Probox,automobile,NULL,NULL,NULL,NULL,Charles Nyambane,NULL,768657106,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2023-12-22 21:53:57+00,2033-12-22 23:59:59+00,1,1,nairobi,12133.75,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050522859,Garage - KCH 167M,JC400P,automobile,KCH 167M,KCH 167M,Probox,automobile,NULL,NULL,NULL,NULL,Garage,NULL,706740252,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-15 08:23:21+00,2042-01-15 23:59:59+00,1,1,nairobi,6934.86,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050522883,Dan Watila - KDE 638J,JC400P,automobile,KDE 638J,KDE 638J,Probox,automobile,NULL,NULL,NULL,NULL,Dan Watila,NULL,112615393,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-15 07:17:21+00,2042-01-15 23:59:59+00,1,1,nairobi,14483.01,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050522891,Lawrence Kijogi - KCY 080X,JC400P,automobile,KCY 080X,KCY 080X,Pick-Up,automobile,NULL,NULL,NULL,NULL,Lawrence Kijogi,NULL,113287191,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-01-16 10:51:30+00,2042-01-16 23:59:59+00,1,1,mombasa,11585.33,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,roll out,NULL,NULL,NULL,mombasa
|
||||||
|
862798050523014,Samuel Muriithy - KDR 594N,JC400P,automobile,KDR 594N,KDR 594N,Probox,automobile,NULL,NULL,NULL,NULL,Samuel Muriithy,NULL,790175423,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2023-12-21 15:54:32+00,2033-12-21 23:59:59+00,1,1,nairobi,27275.43,2026-04-23 10:26:17.747928+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,roll out,NULL,NULL,NULL,nairobi
|
||||||
|
862798050523063,Kelvin Wambugu - KDR 594N,JC400P,automobile,KDR 594N,KDR 594N,Probox,automobile,NULL,NULL,NULL,NULL,Kelvin Wambugu,NULL,701211876,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2023-12-22 19:24:51+00,2043-12-22 19:24:51+00,1,1,nairobi,32698.94,2026-04-23 15:31:08.065856+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,nairobi
|
||||||
|
862798050523139,Mike Wanaswa - KDT 724R,JC400P,automobile,KDT 724R,KDT 724R,Probox,automobile,NULL,NULL,NULL,NULL,Mike Wanaswa,NULL,790175045,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2023-12-22 22:28:09+00,2043-12-22 22:28:09+00,1,1,mombasa,29559.82,2026-04-23 11:16:37.277518+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050523204,Amani Kazungu - KCY 084X,JC400P,automobile,KCY 084X,KCY 084X,Probox,automobile,NULL,NULL,NULL,NULL,Amani Kazungu,NULL,707892547,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-01-16 06:18:20+00,2042-01-16 23:59:59+00,1,1,mombasa,66955.7,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,mombasa
|
||||||
|
862798050523295,Emmanuel Luseno - KDS 453 Y,JC400P,automobile,KDS 453 Y,KDS 453 Y,Pick-Up,automobile,NULL,NULL,NULL,NULL,Emmanuel Luseno,NULL,700242474,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2023-12-22 14:39:50+00,2033-12-22 23:59:59+00,1,1,nairobi,37098.35,2026-04-23 11:29:48.369147+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,general,NULL,NULL,NULL,nairobi
|
||||||
|
862798050523337,Victor Kimutai - KDS 919Y,JC400P,automobile,KDS 919Y,KDS 919Y,Probox,automobile,NULL,NULL,NULL,NULL,Victor Kimutai,NULL,700242527,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2023-12-22 18:00:49+00,2043-12-22 18:00:49+00,1,1,mombasa,50756.64,2026-04-23 10:27:13.522675+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050523386,George Ochieng' - KDD 684Y,JC400P,automobile,KDD 684Y,KDD 684Y,Probox,automobile,NULL,NULL,NULL,NULL,George Ochieng',NULL,785586834,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-22 06:36:08+00,2042-01-22 23:59:59+00,1,1,nairobi,33979.83,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050523527,Allan Owana - KDK 780K,JC400P,automobile,KDK 780K,KDK 780K,Probox,automobile,NULL,NULL,NULL,NULL,Allan Owana,NULL,792375024,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2022-12-03 10:43:41+00,2042-12-03 23:59:59+00,1,1,nairobi,109564.95,2026-04-23 10:25:24.360765+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050523618,Geoffrey Too - KDM 308S,JC400P,automobile,KDM 308S,KDM 308S,Probox,automobile,NULL,NULL,NULL,NULL,Geoffrey Too,NULL,701211625,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2023-08-15 15:42:32+00,2033-08-15 23:59:59+00,1,1,nairobi,26496.5,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050523626,Major Simiyu - KDS 949Y,JC400P,automobile,KDS 949Y,KDS 949Y,Probox,automobile,NULL,NULL,NULL,NULL,Major Simiyu,NULL,701211892,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2023-12-22 18:05:16+00,2033-12-22 23:59:59+00,1,1,mombasa,37042.97,2026-04-23 10:51:18.245194+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,mombasa
|
||||||
|
862798050523816,Job Ngare - KDM 309S,JC400P,automobile,KDM 309S,KDM 309S,Probox,automobile,NULL,NULL,NULL,NULL,Job Ngare,NULL,707936781,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2023-08-15 14:05:52+00,2033-08-15 23:59:59+00,1,1,mombasa,54320.21,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050523949,Joseph Kabandi - KCY 076X,JC400P,automobile,KCY 076X,KCY 076X,Probox,automobile,NULL,NULL,NULL,NULL,Joseph Kabandi,NULL,113288492,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-01-16 05:52:54+00,2042-01-16 23:59:59+00,1,1,mombasa,14427.5,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050524012,Moses Wambua - KCZ 751V,JC400P,automobile,KCZ 751V,KCZ 751V,Probox,automobile,NULL,NULL,NULL,NULL,Moses Wambua,NULL,113313797,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-01-16 07:40:10+00,2042-01-16 23:59:59+00,1,1,mombasa,26551.46,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050524087,Felix Muema - KCZ 223P,JC400P,automobile,KCZ 223P,KCZ 223P,Pick-Up,automobile,NULL,NULL,NULL,NULL,Felix Muema,NULL,113973875,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-01-16 13:02:24+00,2042-01-16 23:59:59+00,1,1,mombasa,11543.26,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050524368,862798050524368,JC400P,automobile,NULL,NULL,NULL,automobile,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-10-29 09:24:53+00,2042-10-29 23:59:59+00,1,1,null,169208.91,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,null,NULL,NULL,NULL,null
|
||||||
|
862798050524384,Hamisi Pande - KDD 689Y,JC400P,automobile,KDD 689Y,KDD 689Y,Probox,automobile,NULL,NULL,NULL,0,Hamisi Pande,NULL,701211744,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-22 05:49:19+00,2042-01-22 23:59:59+00,1,1,nairobi,13685.18,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050524392,Ndegwa Dancun - KCG 669W,JC400P,automobile,KCG 669W,KCG 669W,Probox,automobile,NULL,NULL,NULL,NULL,Ndegwa Dancun,NULL,113799173,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-01-16 09:43:10+00,2042-01-16 23:59:59+00,1,1,mombasa,13638.25,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050524426,Amani Sulubu - KCY 090X,JC400P,automobile,KCY 090X,KCY 090X,Probox,automobile,NULL,NULL,NULL,NULL,Amani Sulubu,NULL,113823350,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2022-01-16 08:56:25+00,2042-01-16 23:59:59+00,1,1,mombasa,14243.83,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050524533,Leonard Nzai - KDM 306S,JC400P,automobile,KDM 306S,KDM 306S,Probox,automobile,NULL,NULL,NULL,NULL,Leonard Nzai,NULL,703487162,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2023-08-21 08:22:12+00,2033-08-21 23:59:59+00,1,1,mombasa,68942.41,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050524558,Mutuku Joseph - KDC 739F,JC400P,automobile,KDC 739F,KDC 739F,Probox,automobile,NULL,NULL,NULL,NULL,Mutuku Joseph,NULL,100858817,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-22 10:38:25+00,2042-01-22 23:59:59+00,1,1,nairobi,23711.63,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,nairobi
|
||||||
|
862798050524566,Makanda Andrew - KCZ 155P,JC400P,automobile,KCZ 155P,KCZ 155P,Pick-Up,automobile,NULL,NULL,NULL,NULL,Makanda Andrew,NULL,758781444,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-01-22 09:47:33+00,2042-01-22 23:59:59+00,1,1,mombasa,31663.3,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050524608,Peter Mbugua - KDK 728K,JC400P,automobile,KDK 728K,KDK 728K,Probox,automobile,NULL,NULL,NULL,NULL,Peter Mbugua,NULL,706742413,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-12-03 12:11:32+00,2042-12-03 23:59:59+00,1,1,nairobi,7219.31,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050524657,Felix Andole - KDC 207R,JC400P,automobile,KDC 207R,KDC 207R,Probox,automobile,NULL,NULL,NULL,NULL,Felix Andole,NULL,758689195,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-22 07:17:47+00,2042-01-22 23:59:59+00,1,1,mombasa,46233.99,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050524681,Mutuku Antony - KDK 732K,JC400P,automobile,KDK 732K,KDK 732K,Probox,automobile,NULL,NULL,NULL,NULL,Mutuku Antony,NULL,796275746,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-12-06 13:37:49+00,2042-12-06 23:59:59+00,1,1,mombasa,14993.36,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,mombasa
|
||||||
|
862798050524707,Garage - KCE 699F,JC400P,automobile,KCE 699F,KCE 699F,Probox,automobile,NULL,NULL,NULL,NULL,Garage,NULL,110525751,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-15 07:58:49+00,2042-01-15 23:59:59+00,1,1,nairobi,34715.97,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,roll out,NULL,NULL,NULL,nairobi
|
||||||
|
862798050524897,Cornelius Kimutai - KCU 938R,JC400P,automobile,KCU 938R,KCU 938R,Van,automobile,NULL,NULL,NULL,NULL,Cornelius Kimutai,NULL,114924404,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-22 09:03:40+00,2042-01-22 23:59:59+00,1,1,nairobi,12668.43,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,nairobi
|
||||||
|
862798050525068,Samuel Ng'ang'a - KDE 264M,JC400P,automobile,KDE 264M,KDE 264M,Probox,automobile,NULL,NULL,NULL,NULL,Samuel Ng'ang'a,NULL,768658564,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2023-12-22 13:33:42+00,2033-12-22 23:59:59+00,1,1,nairobi,12299.13,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050525225,Sadique Wakayula - KDC 490Q,JC400P,automobile,KDC 490Q,KDC 490Q,Crane,truck,NULL,NULL,NULL,NULL,Sadique Wakayula,NULL,768652386,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2023-12-22 20:52:08+00,2043-12-22 20:52:08+00,1,1,mombasa,19138.05,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,general,NULL,NULL,NULL,nairobi
|
||||||
|
862798050525266,Dickson Jaoko - KDK 815R,JC400P,automobile,KDK 815R,KDK 815R,Probox,automobile,NULL,NULL,NULL,NULL,Dickson Jaoko,NULL,706665867,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2023-06-21 07:50:00+00,2033-06-21 23:59:59+00,1,1,mombasa,63754.71,2026-04-23 13:50:24.21992+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050525423,Makori John - KDB 585E,JC400P,automobile,KDB 585E,KDB 585E,Probox,automobile,NULL,NULL,NULL,NULL,Makori John,NULL,701211724,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-15 10:59:19+00,2042-01-15 23:59:59+00,1,1,mombasa,48804.83,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,planning,NULL,NULL,NULL,mombasa
|
||||||
|
862798050525589,Simon Kamau - KCE 090R,JC400P,automobile,KCE 090R,KCE 090R,Probox,automobile,NULL,NULL,NULL,NULL,Simon Kamau,NULL,796276387,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-19 10:10:04+00,2042-01-19 23:59:59+00,1,1,nairobi,15874.39,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050525605,Samuel Kamau - KCA 542Q,JC400P,automobile,KCA 542Q,KCA 542Q,Probox,automobile,NULL,NULL,NULL,NULL,John Ondego,NULL,110526783,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-15 05:56:11+00,2042-01-15 23:59:59+00,1,1,nairobi,23976.94,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,roll out,NULL,NULL,NULL,nairobi
|
||||||
|
862798050525613,Kennedy Chege - KCQ 618K,JC400P,automobile,KCQ 618K,KCQ 618K,Probox,automobile,NULL,NULL,NULL,NULL,Kennedy Chege,NULL,729994247,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-01-16 05:21:05+00,2042-01-16 23:59:59+00,1,1,mombasa,12804.24,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050525670,Gabriel Musumba - KCE 690F,JC400P,automobile,KCE 690F,KCE 690F,Probox,automobile,NULL,NULL,NULL,NULL,Gabriel Musumba,NULL,701211996,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2022-01-15 06:40:01+00,2042-01-15 23:59:59+00,1,1,nairobi,20110.93,2026-04-24 05:34:23.167312+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050525753,Noel Merengeni - KCY 838X,JC400P,automobile,KCY 838X,KCY 838X,Probox,automobile,NULL,NULL,NULL,NULL,Noel Merengeni,NULL,NULL,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2022-01-15 05:24:00+00,2042-01-15 23:59:59+00,1,1,voi,14596.59,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,voi
|
||||||
|
862798050525837,Kennedy Ondieki - KCU 237Z,JC400P,automobile,KCU 237Z,KCU 237Z,Probox,automobile,NULL,NULL,NULL,NULL,Kennedy Ondieki,NULL,113669852,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2023-12-21 19:32:44+00,2033-12-21 23:59:59+00,1,1,nairobi,NULL,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050525951,Wright Oseko - KCG 668W,JC400P,automobile,KCG 668W,KCG 668W,Probox,automobile,NULL,NULL,NULL,NULL,Wright Oseko,NULL,741943212,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2022-01-15 09:36:45+00,2042-01-15 23:59:59+00,1,1,nairobi,13116,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
862798050526165,Wilfred Kinyanjui - KCU 729C,JC400P,automobile,KCU 729C,KCU 729C,Crane,truck,NULL,NULL,NULL,NULL,Wilfred Kinyanjui,NULL,790564929,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2023-11-26 10:17:19+00,2033-11-26 23:59:59+00,1,1,nairobi,24270.2,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,general,NULL,NULL,NULL,nairobi
|
||||||
|
862798050526231,Rashid Hassan - KDM 840V,JC400P,automobile,KDM 840V,KDM 840V,Probox,automobile,NULL,NULL,NULL,NULL,Rashid Hassan,NULL,790175526,NULL,NULL,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2023-12-22 22:36:15+00,2043-12-22 22:36:15+00,1,1,mombasa,45418.38,2026-04-23 10:29:41.575467+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
862798050526256,Ian Dancun - KDT 923R,JC400P,automobile,KDT 923R,KDT 923R,Probox,automobile,NULL,NULL,NULL,NULL,Ian Dancun,NULL,794873610,NULL,NULL,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2023-12-22 19:37:24+00,2043-12-22 19:37:24+00,1,1,mombasa,11093.11,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,qehs,NULL,NULL,NULL,mombasa
|
||||||
|
862798052707888,Benjamin Ananda - KDV 438W,JC400P,automobile,KDV 438W,KDV 438W,Probox,automobile,NULL,NULL,NULL,NULL,Benjamin Ananda,NULL,758047312,89254021414206816980,639021410681698,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2025-12-15 07:39:23+00,2035-12-15 23:59:59+00,1,1,nairobi,8720.87,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,planning,NULL,NULL,NULL,nairobi
|
||||||
|
862798052707896,John Mbugua - KDW 573B,JC400P,automobile,KDW 573B,KDW 573B,Probox,automobile,NULL,NULL,NULL,NULL,John Mbugua,NULL,NULL,89254021414206816725,639021410681672,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2026-01-30 14:48:17+00,2036-01-30 23:59:59+00,1,1,nairobi,515.16,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
862798052707946,Tom Wekesa/OSP-KCY 930Y_CAM,JC400P,automobile,KCY 930Y,NULL,NULL,automobile,NULL,NULL,NULL,NULL,NULL,NULL,758047806,89254021414206816766,639021410681676,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2026-01-20 21:02:13+00,2036-01-20 23:59:59+00,1,1,nairobi,10079.17,2026-04-23 10:25:24.363965+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
862798052708035,862798052708035,JC400P,automobile,NULL,NULL,Probox,automobile,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,NULL,NULL,1,1,null,NULL,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,null,NULL,NULL,NULL,null
|
||||||
|
862798052708068,Dominic Wambua - KDV 683Z,JC400P,automobile,KDV 683Z,KDV 683Z,Probox,automobile,NULL,NULL,NULL,NULL,Dominic Wambua,NULL,758048043,89254021414206816964,639021410681696,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2026-01-24 09:20:09+00,2036-01-24 23:59:59+00,1,1,nairobi,4438.55,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,roll out,NULL,NULL,NULL,nairobi
|
||||||
|
862798052708076,Albert Mutwiri - KDV 437W,JC400P,automobile,KDV 437W,KDV 437W,Probox,automobile,NULL,NULL,NULL,NULL,Albert Mutwiri,NULL,758047094,89254021414206816782,639021410681678,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2025-12-13 15:03:30+00,2035-12-13 23:59:59+00,1,1,nairobi,5575.64,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,nairobi
|
||||||
|
862798052708167,Levine Wasike - KDV 439W,JC400P,automobile,KDV 439W,KDV 439W,Probox,automobile,NULL,NULL,NULL,NULL,Levine Wasike,NULL,758046738,89254021414206816741,639021410681674,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-12-13 19:49:29+00,2035-12-13 23:59:59+00,1,1,nairobi,4601.08,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
862798052708282,Godffrey Nandwa - KCN 496A,JC400P,automobile,KCN 496A,KCN 496A,Probox,automobile,NULL,NULL,NULL,NULL,Godffrey Nandwa,NULL,758047934,89254021414206816865,639021410681686,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2026-01-25 18:55:54+00,2036-01-25 23:59:59+00,1,1,nairobi,7040.6,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798052713654,Garage/ISP_KCL 502T_CAM,JC400P,automobile,KCL 502T,NULL,NULL,automobile,NULL,NULL,NULL,NULL,NULL,NULL,780215879,89254035061001753803,639035060175380,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-09-02 10:09:57+00,2035-09-02 23:59:59+00,1,1,nairobi,5199.72,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
862798052713696,862798052713696,JC400P,automobile,NULL,NULL,Probox,automobile,NULL,NULL,NULL,NULL,NULL,NULL,NULL,89254021394215205906,639021391520590,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2025-09-02 10:20:58+00,2035-09-02 23:59:59+00,1,1,null,6214.49,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,null,NULL,NULL,NULL,null
|
||||||
|
862798052713761,Management_Mazda - KDU 613A,JC400P,automobile,KDU 613A,KDU 613A,Mazda,automobile,NULL,NULL,NULL,NULL,Management_Mazda,NULL,790176786,89254021394215205955,639021391520595,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2025-07-09 15:49:26+00,2035-07-09 23:59:59+00,1,1,nairobi,9262.78,2026-04-23 16:40:48.879666+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,management,NULL,NULL,NULL,nairobi
|
||||||
|
862798052713779,Benard Kimutai - KDN 759G,JC400P,automobile,KDN 759G,KDN 759G,Probox,automobile,NULL,NULL,NULL,NULL,Benard Kimutai,NULL,752143258,89254035061001753860,639035060175386,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-08-23 11:15:59+00,2035-08-23 23:59:59+00,1,1,nairobi,5344.24,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
862798052713811,James Onyango - KDU 613B,JC400P,automobile,KDU 613B,KDU 613B,Probox,automobile,NULL,NULL,NULL,NULL,James Onyango,NULL,790176542,89254021394215205880,639021391520588,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-07-09 19:24:14+00,2035-07-09 23:59:59+00,1,1,nairobi,9657.42,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798052713837,Kennedy Ondieki - KCU 237Z,JC400P,automobile,KCU 237Z,KCU 237Z,Probox,automobile,NULL,NULL,NULL,NULL,Kennedy Ondieki,NULL,113669852,89254021414206327855,639021410632785,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2025-10-08 14:55:23+00,2035-10-08 23:59:59+00,1,1,nairobi,9346.02,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
862798052713985,Timothy Gitau - KDT 916R,JC400P,automobile,KDT 916R,KDT 916R,Probox,automobile,NULL,NULL,NULL,NULL,Timothy Gitau,NULL,768696668,89254021394274518892,639021397451889,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2025-08-02 18:21:23+00,2035-08-02 23:59:59+00,1,1,mombasa,19998.22,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,regional,NULL,NULL,NULL,mombasa
|
||||||
|
862798052714066,862798052714066,JC400P,automobile,NULL,NULL,Probox,automobile,NULL,NULL,NULL,NULL,NULL,NULL,NULL,89254021414206378684,639021410637868,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2025-11-21 17:44:44+00,2035-11-21 23:59:59+00,1,1,null,10755.28,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,null,NULL,NULL,NULL,null
|
||||||
|
862798052715220,Rofas Njagi - KDT 728R,JC400P,automobile,KDT 728R,KDT 728R,Probox,automobile,NULL,NULL,NULL,NULL,Rofas Njagi,NULL,704573658,89254021334258495873,639021335849587,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-07-16 07:09:25+00,2035-07-16 23:59:59+00,1,1,nairobi,16385.58,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,regional,NULL,NULL,NULL,nairobi
|
||||||
|
865135061035133,Major Simiyu - KDS 949Y,X3,automobile,KDS 949Y,KDS 949Y,Probox,automobile,NULL,NULL,NULL,NULL,Major Simiyu,NULL,768696642,89254021394274518918,639021397451891,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2025-08-02 13:14:33+00,2035-08-02 23:59:59+00,1,1,mombasa,25089.98,2026-04-23 12:07:56.044395+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,mombasa
|
||||||
|
865135061035653,Richardson Komu - KDT 923R,X3,automobile,KDT 923R,KDT 923R,Probox,automobile,NULL,NULL,NULL,NULL,Richardson Komu,NULL,768697292,89254021394274518942,639021397451894,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2025-08-02 08:11:46+00,2035-08-02 23:59:59+00,1,1,mombasa,23556.65,2026-04-23 10:24:50.340401+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
865135061035778,John Kimeria - KDS 525D,X3,automobile,KDS 525D,KDS 525D,Crane,truck,NULL,NULL,NULL,NULL,John Kimeria,NULL,790176738,89254021394215205922,639021391520592,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-07-11 05:50:36+00,2035-07-11 23:59:59+00,1,1,nairobi,17653.96,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,general,NULL,NULL,NULL,nairobi
|
||||||
|
865135061036164,Brian Njenga - KMFF 113Z,X3,automobile,KMFF 113Z,KMFF 113Z,Motorbike,mtc,NULL,NULL,NULL,NULL,Brian Njenga,NULL,768696705,89254021394274518850,639021397451885,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-07-31 10:06:46+00,2035-07-31 23:59:59+00,1,1,nairobi,22990.33,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,deliveries,NULL,NULL,NULL,nairobi
|
||||||
|
865135061037980,Emmanuel Luseno - KDS 453Y,X3,automobile,KDS 453Y,KDS 453Y,Pick-Up,automobile,NULL,NULL,NULL,NULL,Emmanuel Luseno,NULL,790176734,89254021394215205856,639021391520585,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-07-15 06:30:34+00,2035-07-15 23:59:59+00,1,1,nairobi,42609.03,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,general,NULL,NULL,NULL,nairobi
|
||||||
|
865135061042261,Kelvin Wambugu - KDR 592N,X3,automobile,KDR 592N,KDR 592N,Probox,automobile,NULL,NULL,NULL,NULL,Kelvin Wambugu,NULL,797680464,89254021334258159693,639021335815969,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-07-10 10:23:44+00,2035-07-10 23:59:59+00,1,1,nairobi,18755.66,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,nairobi
|
||||||
|
865135061043079,Mike Wanaswa - KDT 724R,X3,automobile,KDT 724R,KDT 724R,Probox,automobile,NULL,NULL,NULL,NULL,Mike Wanaswa,NULL,768696664,89254021394274518959,639021397451895,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2025-08-02 12:16:11+00,2035-08-02 23:59:59+00,1,1,mombasa,27470.11,2026-04-23 11:16:35.682194+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
865135061043426,Geoffrey Karanja - KMGS 239H,X3,automobile,KMGS 239H,KMGS 239H,Motorbike,mtc,NULL,NULL,NULL,NULL,Geoffrey Karanja,NULL,768696658,89254021394274518926,639021397451892,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-08-22 13:32:25+00,2035-08-22 23:59:59+00,1,1,nairobi,21267.01,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp patrol,NULL,NULL,NULL,nairobi
|
||||||
|
865135061047435,Management_Mazda - KDU 613A,X3,automobile,KDU 613A,KDU 613A,Mazda,automobile,NULL,NULL,NULL,NULL,Management_Mazda,NULL,790175971,89254021394215205971,639021391520597,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-07-09 08:02:26+00,2035-07-09 23:59:59+00,1,1,nairobi,9761.38,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,management,NULL,NULL,NULL,nairobi
|
||||||
|
865135061048276,Victor Kimutai - KDS 919Y,X3,automobile,KDS 919Y,KDS 919Y,Probox,automobile,NULL,NULL,NULL,NULL,Victor Kimutai,NULL,768696755,89254021394274518900,639021397451890,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2025-08-02 07:38:01+00,2035-08-02 23:59:59+00,1,1,mombasa,23296.79,2026-04-23 10:54:41.63532+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,mombasa
|
||||||
|
865135061048300,KMGR 409U HENRY JAZZ,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,unknown,nairobi,NULL,2026-04-24 04:30:20.231102+00,2026-04-24 04:30:20.231102+00,NULL,NULL,personal,NULL,NULL,NULL,nairobi
|
||||||
|
865135061048466,Samuel Muriithy - KDR 594N,X3,automobile,KDR 594N,KDR 594N,Probox,automobile,NULL,NULL,NULL,NULL,Samuel Muriithy,NULL,797680395,89254021334258159628,639021335815962,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2025-07-24 09:37:31+00,2035-07-24 23:59:59+00,1,1,nairobi,27634.1,2026-04-23 11:43:39.178819+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,roll out,NULL,NULL,NULL,nairobi
|
||||||
|
865135061048615,Office-KMDG 902Z,X3,automobile,KMDG 902Z,NULL,NULL,automobile,NULL,NULL,NULL,NULL,NULL,NULL,768697276,89254021394274518876,639021397451887,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-07-31 09:59:43+00,2035-07-31 23:59:59+00,1,1,nairobi,5721.21,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp patrol,NULL,NULL,NULL,nairobi
|
||||||
|
865135061048953,Timothy Gitau - KDT 916R,X3,automobile,KDT 916R,KDT 916R,Probox,automobile,NULL,NULL,NULL,NULL,Timothy Gitau,NULL,768697056,89254021394274518967,639021397451896,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2025-08-02 08:48:05+00,2035-08-02 23:59:59+00,1,1,mombasa,28536.23,2026-04-23 10:53:31.102315+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,regional,NULL,NULL,NULL,mombasa
|
||||||
|
865135061049001,Parked - KMGK 596V,X3,automobile,KMGK 596V,KMGK 596V,Motorbike,mtc,NULL,NULL,NULL,NULL,Parked,NULL,768697064,89254021394274518884,639021397451888,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-07-31 08:40:18+00,2035-07-31 23:59:59+00,1,1,nairobi,20612.89,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,deliveries,NULL,NULL,NULL,nairobi
|
||||||
|
865135061053714,Samuel Kihara - KMEL 225X,X3,automobile,KMEL 225X,KMEL 225X,Motorbike,mtc,NULL,NULL,NULL,NULL,Samuel Kihara,NULL,768696832,89254021394274518934,639021397451893,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-08-02 13:51:47+00,2035-08-02 23:59:59+00,1,1,nairobi,26897.18,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp patrol,NULL,NULL,NULL,nairobi
|
||||||
|
865135061053748,Rashid Hassan - KDM 840V,X3,automobile,KDM 840V,KDM 840V,Probox,automobile,NULL,NULL,NULL,NULL,Rashid Hassan,NULL,768445963,89254021334212352574,639021331235257,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-07-10 13:54:11+00,2035-07-10 23:59:59+00,1,1,mombasa,26612.42,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,mombasa
|
||||||
|
865135061054548,James Onyango - KDU 613B,X3,automobile,KDU 613B,KDU 613B,Probox,automobile,NULL,NULL,NULL,NULL,James Onyango,NULL,790175997,89254021394215205948,639021391520594,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2025-07-09 07:11:15+00,2035-07-09 23:59:59+00,1,1,nairobi,13446.05,2026-04-23 10:26:24.667167+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,isp,NULL,NULL,NULL,nairobi
|
||||||
|
865135061054555,Rofas Njagi - KDT 728R,X3,automobile,KDT 728R,KDT 728R,Probox,automobile,NULL,NULL,NULL,NULL,Rofas Njagi,NULL,790176726,89254021394215205823,639021391520582,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2025-07-16 06:44:33+00,2035-07-16 23:59:59+00,1,1,nairobi,27250.8,2026-04-23 10:25:21.085437+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,regional,NULL,NULL,NULL,nairobi
|
||||||
|
865135061559538,FRED KMGW 538W HULETI,NULL,NULL,KMGW 538W,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,unknown,null,NULL,2026-04-23 10:42:18.5831+00,2026-04-23 10:42:18.5831+00,NULL,NULL,null,NULL,NULL,NULL,null
|
||||||
|
865135061562722,John Mbugua - KDW 573B,X3,automobile,KDW 573B,KDW 573B,Probox,automobile,NULL,NULL,NULL,NULL,John Mbugua,NULL,758052508,89254021414206816832,639021410681683,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2026-01-30 06:53:57+00,2036-01-30 23:59:59+00,1,1,nairobi,4488.19,2026-04-23 10:25:38.887433+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
865135061562847,Levine Wasike - KDV 439W,X3,automobile,KDV 439W,KDV 439W,Probox,automobile,NULL,NULL,NULL,NULL,Levine Wasike,NULL,758047032,89254021414206816840,639021410681684,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2025-12-13 11:14:14+00,2035-12-13 23:59:59+00,1,1,nairobi,7880.92,2026-04-23 10:35:50.779597+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,osp,NULL,NULL,NULL,nairobi
|
||||||
|
865135061563282,X3-63282,X3,automobile,NULL,NULL,NULL,automobile,NULL,NULL,NULL,NULL,NULL,NULL,NULL,8925610001837573427F,641101970467668,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2026-02-14 07:20:10+00,2036-02-14 23:59:59+00,1,1,null,4758.32,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,null,NULL,NULL,NULL,null
|
||||||
|
865135061563415,Barack Orwa - KDW 781E,X3,automobile,KDW 781E,KDW 781E,Vazel,automobile,NULL,NULL,NULL,NULL,Barack Orwa,NULL,758052541,89254021414206816931,639021410681693,Fireside_MSA,Fireside Group MSA,9d0927d235e44fe7abf254902fc68921,Default group,2026-01-13 12:37:42+00,2036-01-13 23:59:59+00,1,1,nairobi,4165.95,2026-04-23 11:22:00.676215+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,personal,NULL,NULL,NULL,nairobi
|
||||||
|
865135061563423,Joel Ntumba - UMA 826AB,X3,automobile,UMA 826AB,UMA 826AB,Motorbike,mtc,NULL,NULL,NULL,NULL,Joel Ntumba,NULL,119051036,89254021414206652690,639021410665269,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2026-01-28 13:55:39+00,2036-01-28 23:59:59+00,1,1,uganda,1174.05,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,mtn,NULL,NULL,NULL,uganda
|
||||||
|
865135061563597,Dominic Wambua - KDV 683Z,X3,automobile,KDV 683Z,KDV 683Z,Probox,automobile,NULL,NULL,NULL,NULL,Dominic Wambua,NULL,758052405,89254021414206816733,639021410681673,Fireside@HQ,Fireside Telematics,6ef0b0fc2d964b358b70dc2cfcbc5b7e,Default group,2026-01-30 06:55:35+00,2036-01-30 23:59:59+00,1,1,nairobi,6790.53,2026-04-23 10:25:40.125927+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,roll out,NULL,NULL,NULL,nairobi
|
||||||
|
865135061563639,Benjamin Ananda - KDV 438W,X3,automobile,KDV 438W,KDV 438W,Probox,automobile,NULL,NULL,NULL,NULL,Benjamin Ananda,NULL,758047065,89254021414206816683,639021410681668,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-12-13 16:02:37+00,2035-12-13 23:59:59+00,1,1,nairobi,14446.33,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,planning,NULL,NULL,NULL,nairobi
|
||||||
|
865135061564280,Rodin Kiberu - UMA 011EK,X3,automobile,UMA 011EK,UMA 011EK,Motorbike,mtc,NULL,NULL,NULL,NULL,Rodin Kiberu,NULL,118081642,89254021414206817244,639021410681724,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2026-01-28 13:13:57+00,2036-01-28 23:59:59+00,1,1,uganda,841.39,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,mtn,NULL,NULL,NULL,uganda
|
||||||
|
865135061564470,Silvanus Kipkorir - KDV 064S,X3,automobile,KDV 064S,KDV 064S,Probox,automobile,NULL,NULL,NULL,NULL,Silvanus Kipkorir,NULL,113669866,89254021414206378718,639021410637871,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-11-21 16:49:17+00,2035-11-21 23:59:59+00,1,1,nairobi,23869.16,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,airtel,NULL,NULL,NULL,nairobi
|
||||||
|
865135061568968,X3-68968,X3,automobile,NULL,NULL,NULL,automobile,NULL,NULL,NULL,NULL,NULL,NULL,NULL,89254021414206816915,639021410681691,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2026-03-11 06:19:14+00,2036-03-11 23:59:59+00,1,1,null,16.23,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,null,NULL,NULL,NULL,null
|
||||||
|
865135061569123,Albert Mutwiri - KDV 437W,X3,automobile,KDV 437W,KDV 437W,Probox,automobile,NULL,NULL,NULL,NULL,Albert Mutwiri,NULL,758047101,89254021414206816881,639021410681688,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-12-13 14:26:17+00,2035-12-13 23:59:59+00,1,1,nairobi,13032.6,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,nairobi
|
||||||
|
865135061569131,UMA 418EK,X3,automobile,UMA 418EK,UMA 418EK,NULL,automobile,NULL,NULL,NULL,NULL,UG,NULL,256792997053,8925610001837573385F,641101970467664,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2026-02-26 08:15:44+00,2036-02-26 23:59:59+00,1,1,uganda,2333.45,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,mtn,NULL,NULL,NULL,uganda
|
||||||
|
865135061569479,UMA 382EK,X3,automobile,UMA 382EK,UMA 382EK,NULL,automobile,NULL,NULL,NULL,NULL,UG,NULL,256792997079,8925610001837573419F,641101970467667,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2026-02-26 08:21:10+00,2036-02-26 23:59:59+00,1,1,uganda,1954.86,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,mtn,NULL,NULL,NULL,uganda
|
||||||
|
865135061578553,X3-78553,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,unknown,null,NULL,2026-04-23 15:30:19.981271+00,2026-04-23 15:30:19.981271+00,NULL,NULL,null,NULL,NULL,NULL,null
|
||||||
|
865135061581904,Robert Kipruto - KDV 072L,X3,automobile,KDV 072L,KDV 072L,Probox,automobile,NULL,NULL,NULL,NULL,Robert Kipruto,NULL,114149576,89254021264261503993,639021266150399,fireside,Fireside Group HQ,2f1acaef6c884214b4598719180fe68d,Default group,2025-11-21 15:30:29+00,2035-11-21 23:59:59+00,1,1,nairobi,15252.84,2026-04-23 10:23:56.546784+00,2026-04-24 07:43:45.210628+00,2026-04-24 07:43:45.210628+00,NULL,fds,NULL,NULL,NULL,nairobi
|
||||||
|
75
260427_audit_output.txt
Normal file
75
260427_audit_output.txt
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
============================================================================
|
||||||
|
Device reconciliation — CSV vs tracksolid.devices
|
||||||
|
============================================================================
|
||||||
|
CSV file : 20260427_FSG_Vehicles_mitieng.csv
|
||||||
|
CSV row count : 162
|
||||||
|
DB row count : 172
|
||||||
|
Delta (DB-CSV) : +10
|
||||||
|
|
||||||
|
─ Per-account breakdown ─────────────────────────────────────────────────
|
||||||
|
account CSV DB delta
|
||||||
|
(blank) 0 10 +10
|
||||||
|
Fireside@HQ 52 52 +0
|
||||||
|
Fireside_MSA 41 41 +0
|
||||||
|
NULL 6 0 -6
|
||||||
|
fireside 63 69 +6
|
||||||
|
|
||||||
|
─ IMEIs in DB but NOT in CSV (10) ─────────────────────────────
|
||||||
|
imei account city last_synced_at device_name
|
||||||
|
359857081891921 JK Subaru KCS 903Y
|
||||||
|
359857082898297 KDK 829A GP
|
||||||
|
862798052707995 fireside 2026-04-27 19:30:53.484218+00:00 JC400P-07995
|
||||||
|
862798052715071 KDU 878T_CAM
|
||||||
|
862798052785751 fireside 2026-04-27 19:30:53.484218+00:00 JC400P-85751
|
||||||
|
862798052786270 fireside 2026-04-27 19:30:53.484218+00:00 JC400P-86270
|
||||||
|
865135061040349 KDU 878T_Track
|
||||||
|
865135061559405 X3-59405
|
||||||
|
865135061569172 fireside 2026-04-27 19:30:53.484218+00:00 X3-69172
|
||||||
|
865135061569529 fireside 2026-04-27 19:30:53.484218+00:00 X3-69529
|
||||||
|
|
||||||
|
─ IMEIs in CSV but NOT in DB (0) ─────────────────────────────
|
||||||
|
(none — every CSV row has a corresponding device row)
|
||||||
|
|
||||||
|
─ Devices in both, but DB metadata still NULL (162) ──────────────
|
||||||
|
Likely cause: import_drivers_csv.py has not been re-run with --apply
|
||||||
|
against the new CSV, or rows had 'Identification' placeholders.
|
||||||
|
|
||||||
|
imei blank_fields
|
||||||
|
353549090553685 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
353549090561720 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address, driver_name, vehicle_number
|
||||||
|
353549090566281 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address, driver_name, vehicle_number
|
||||||
|
353549090566885 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address, driver_name, vehicle_number
|
||||||
|
353549090567685 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
353549090567701 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address, driver_name, vehicle_number
|
||||||
|
359857081885410 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857081886467 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, depot_address
|
||||||
|
359857081886871 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address, driver_name, vehicle_number
|
||||||
|
359857081886905 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857081887069 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857081887192 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857081891566 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857081891590 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857081891632 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857081891798 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857081892101 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857081892309 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857081892440 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address, driver_name, vehicle_number
|
||||||
|
359857081892762 assigned_city, cost_centre, assigned_route, vehicle_category, fuel_100km, depot_address, driver_name, vehicle_number
|
||||||
|
359857082037185 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857082038977 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857082040981 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857082042052 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857082042854 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857082042953 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address, driver_name, vehicle_number
|
||||||
|
359857082044280 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857082046145 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857082896911 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
359857082897091 assigned_city, cost_centre, assigned_route, vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
... and 132 more
|
||||||
|
|
||||||
|
─ Suggested next step ───────────────────────────────────────────────────
|
||||||
|
Inspect the IMEIs above. Decide one of:
|
||||||
|
(a) Prune — delete from tracksolid.devices if they are stale test/decommissioned units.
|
||||||
|
(b) Leave-as-NULL — keep them as auto-synced API rows; their metadata stays NULL until added to a future CSV.
|
||||||
|
(c) Addendum — add them to the CSV (or a sidecar CSV) and re-run import_drivers_csv.py --apply.
|
||||||
|
Document the choice in 260427_device_reconciliation.md.
|
||||||
91
260427_device_reconciliation.md
Normal file
91
260427_device_reconciliation.md
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
# Device Reconciliation — 162 vs 182 (2026-04-27)
|
||||||
|
|
||||||
|
Phase 0.2 of the Business Analytics redesign. Resolves the gap between
|
||||||
|
`20260427_FSG_Vehicles_mitieng.csv` (162 rows) and `tracksolid.devices`
|
||||||
|
(~182 rows at last check).
|
||||||
|
|
||||||
|
## How to populate this report
|
||||||
|
|
||||||
|
1. Pull this branch onto the Coolify host (or rebuild containers so the
|
||||||
|
ingest container has `audit_device_reconciliation.py`).
|
||||||
|
|
||||||
|
2. Run inside the ingest container so it has `DATABASE_URL`:
|
||||||
|
```bash
|
||||||
|
ING=$(docker ps --filter name=ingest_movement --format "{{.Names}}" | head -1)
|
||||||
|
docker cp 20260427_FSG_Vehicles_mitieng.csv "$ING":/app/
|
||||||
|
docker exec "$ING" python audit_device_reconciliation.py \
|
||||||
|
--csv 20260427_FSG_Vehicles_mitieng.csv \
|
||||||
|
--out /tmp/260427_audit_output.txt
|
||||||
|
docker cp "$ING":/tmp/260427_audit_output.txt ./
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Paste the audit output into the **Audit output** section below.
|
||||||
|
|
||||||
|
4. Mark the chosen disposition for each IMEI in the **Disposition** section.
|
||||||
|
|
||||||
|
## Audit output
|
||||||
|
|
||||||
|
First run: 2026-04-27 23:35 UTC against `tracksolid_db` on stage. Full output in
|
||||||
|
`260427_audit_output.txt`. Headline numbers:
|
||||||
|
|
||||||
|
| Metric | Value |
|
||||||
|
|---|---|
|
||||||
|
| CSV rows | 162 |
|
||||||
|
| `tracksolid.devices` rows | 172 |
|
||||||
|
| Delta (DB − CSV) | +10 |
|
||||||
|
| In CSV but not in DB | 0 |
|
||||||
|
| In DB but not in CSV | 10 |
|
||||||
|
| Devices both sides, DB metadata still NULL on ≥1 field | 162 (resolved by importer run) |
|
||||||
|
|
||||||
|
After running `import_drivers_csv.py --only-null --apply` (2026-04-27): 154
|
||||||
|
devices updated, 8 already complete, 0 inserted. Coverage now: `assigned_city`
|
||||||
|
152/172, `cost_centre` 150/172, `vehicle_brand` 2/172, `fuel_100km` 3/172.
|
||||||
|
`assigned_route` / `vehicle_category` / `depot_address` remain 0/172 (CSV
|
||||||
|
provided no values for these — Phase 1 follow-up).
|
||||||
|
|
||||||
|
The 10 in-DB-not-in-CSV IMEIs are listed in `260427_audit_output.txt`. They
|
||||||
|
sit in `(blank)` or `fireside` accounts and surface in Grafana as
|
||||||
|
`assigned_city = 'unassigned'` thanks to the existing COALESCE in
|
||||||
|
`07_analytics_views.sql`.
|
||||||
|
|
||||||
|
## Disposition
|
||||||
|
|
||||||
|
For each IMEI in the "in DB but not in CSV" list, choose one and record why:
|
||||||
|
|
||||||
|
| IMEI | Account | Last seen | Disposition | Notes |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| | | | | |
|
||||||
|
|
||||||
|
**Disposition options:**
|
||||||
|
|
||||||
|
- **prune** — Delete from `tracksolid.devices`. Use when the unit is a stale
|
||||||
|
test/decommissioned device that should never have synced. Capture the SQL
|
||||||
|
before running:
|
||||||
|
```sql
|
||||||
|
DELETE FROM tracksolid.devices WHERE imei = '<imei>';
|
||||||
|
```
|
||||||
|
*Caveat:* foreign keys from `position_history`, `trips`, `alarms` must be
|
||||||
|
considered first — these will block the delete if there's any history.
|
||||||
|
Usually safer to leave-as-NULL.
|
||||||
|
|
||||||
|
- **leave-as-NULL** — Keep the row; metadata fields stay NULL. The device
|
||||||
|
was auto-synced from a Tracksolid account that the CSV doesn't cover
|
||||||
|
(likely `Fireside@HQ` rows that were left out of this Mitieng export).
|
||||||
|
Grafana views already use `COALESCE(d.assigned_city, d.city, 'unassigned')`
|
||||||
|
so these surface as "unassigned" but don't break dashboards.
|
||||||
|
|
||||||
|
- **addendum** — Add to a follow-up CSV and re-run the importer with
|
||||||
|
`--apply`. Use when the device is legitimate fleet metadata was just
|
||||||
|
missing from the export.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
<!-- Fill in once dispositions are chosen. -->
|
||||||
|
|
||||||
|
- Total devices reviewed: ___
|
||||||
|
- Pruned: ___
|
||||||
|
- Left-as-NULL: ___
|
||||||
|
- Added via addendum: ___
|
||||||
|
|
||||||
|
After action, re-run `audit_device_reconciliation.py` and confirm the
|
||||||
|
delta is what you expect.
|
||||||
205
audit_device_reconciliation.py
Normal file
205
audit_device_reconciliation.py
Normal file
|
|
@ -0,0 +1,205 @@
|
||||||
|
"""
|
||||||
|
audit_device_reconciliation.py — 162-vs-182 device delta audit
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
Phase 0.2 of the Business Analytics redesign.
|
||||||
|
|
||||||
|
Compares `20260427_FSG_Vehicles_mitieng.csv` (162 rows) to `tracksolid.devices`
|
||||||
|
(182 rows at last check) and reports:
|
||||||
|
1. Per-account row counts on each side.
|
||||||
|
2. IMEIs in DB but not in CSV (the unexplained delta — typically auto-synced
|
||||||
|
API rows with no business metadata).
|
||||||
|
3. IMEIs in CSV but not in DB (should be empty after a successful import).
|
||||||
|
4. IMEIs present on both sides where DB metadata is still NULL on key fields.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
# Read-only audit, prints to stdout.
|
||||||
|
python audit_device_reconciliation.py
|
||||||
|
|
||||||
|
# Same, but write output to a file (useful for the reconciliation report).
|
||||||
|
python audit_device_reconciliation.py --out 260427_audit_output.txt
|
||||||
|
|
||||||
|
# Use a different CSV path
|
||||||
|
python audit_device_reconciliation.py --csv path/to/file.csv
|
||||||
|
|
||||||
|
This script makes no writes — safe to run on prod.
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import csv
|
||||||
|
import sys
|
||||||
|
from collections import Counter
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from ts_shared_rev import get_conn, get_logger
|
||||||
|
|
||||||
|
log = get_logger("device_audit")
|
||||||
|
|
||||||
|
DEFAULT_CSV_PATH = Path(__file__).parent / "20260427_FSG_Vehicles_mitieng.csv"
|
||||||
|
|
||||||
|
# Fields whose NULL-ness on devices that DO appear in CSV would indicate
|
||||||
|
# a stale import.
|
||||||
|
META_FIELDS = ("assigned_city", "cost_centre", "assigned_route",
|
||||||
|
"vehicle_category", "vehicle_brand", "fuel_100km",
|
||||||
|
"depot_address", "driver_name", "vehicle_number")
|
||||||
|
|
||||||
|
|
||||||
|
def load_csv_index(csv_path: Path) -> dict[str, dict]:
|
||||||
|
rows: dict[str, dict] = {}
|
||||||
|
with open(csv_path, encoding="utf-8-sig", newline="") as f:
|
||||||
|
for row in csv.DictReader(f):
|
||||||
|
imei = (row.get("imei") or "").strip()
|
||||||
|
if imei:
|
||||||
|
rows[imei] = row
|
||||||
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
def load_db_index() -> dict[str, dict]:
|
||||||
|
cols = (
|
||||||
|
"imei", "account", "assigned_city", "city", "cost_centre",
|
||||||
|
"assigned_route", "vehicle_category", "vehicle_brand", "fuel_100km",
|
||||||
|
"depot_address", "driver_name", "vehicle_number", "device_name",
|
||||||
|
"last_synced_at", "created_at",
|
||||||
|
)
|
||||||
|
devices: dict[str, dict] = {}
|
||||||
|
with get_conn() as conn:
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(f"SELECT {', '.join(cols)} FROM tracksolid.devices")
|
||||||
|
names = [d[0] for d in cur.description]
|
||||||
|
for row in cur.fetchall():
|
||||||
|
rec = dict(zip(names, row))
|
||||||
|
devices[rec["imei"]] = rec
|
||||||
|
return devices
|
||||||
|
|
||||||
|
|
||||||
|
def _csv_account(row: dict) -> str:
|
||||||
|
return (row.get("account") or "").strip() or "(blank)"
|
||||||
|
|
||||||
|
|
||||||
|
def _db_account(row: dict) -> str:
|
||||||
|
return (row.get("account") or "").strip() or "(blank)"
|
||||||
|
|
||||||
|
|
||||||
|
def _is_blank(v) -> bool:
|
||||||
|
if v is None:
|
||||||
|
return True
|
||||||
|
s = str(v).strip()
|
||||||
|
return s == "" or s.upper() == "NULL"
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
parser = argparse.ArgumentParser(description="Reconcile vehicle CSV against tracksolid.devices")
|
||||||
|
parser.add_argument("--csv", default=str(DEFAULT_CSV_PATH))
|
||||||
|
parser.add_argument("--out", default=None, help="Write report to this file in addition to stdout")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
csv_path = Path(args.csv)
|
||||||
|
if not csv_path.exists():
|
||||||
|
log.error("CSV not found: %s", csv_path)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
csv_idx = load_csv_index(csv_path)
|
||||||
|
db_idx = load_db_index()
|
||||||
|
|
||||||
|
csv_imeis = set(csv_idx)
|
||||||
|
db_imeis = set(db_idx)
|
||||||
|
|
||||||
|
only_db = sorted(db_imeis - csv_imeis)
|
||||||
|
only_csv = sorted(csv_imeis - db_imeis)
|
||||||
|
both = csv_imeis & db_imeis
|
||||||
|
|
||||||
|
csv_accounts = Counter(_csv_account(r) for r in csv_idx.values())
|
||||||
|
db_accounts = Counter(_db_account(r) for r in db_idx.values())
|
||||||
|
|
||||||
|
out_lines: list[str] = []
|
||||||
|
def w(line: str = "") -> None:
|
||||||
|
out_lines.append(line)
|
||||||
|
print(line)
|
||||||
|
|
||||||
|
w("=" * 76)
|
||||||
|
w(" Device reconciliation — CSV vs tracksolid.devices")
|
||||||
|
w("=" * 76)
|
||||||
|
w(f" CSV file : {csv_path.name}")
|
||||||
|
w(f" CSV row count : {len(csv_idx)}")
|
||||||
|
w(f" DB row count : {len(db_idx)}")
|
||||||
|
w(f" Delta (DB-CSV) : {len(only_db):+d}")
|
||||||
|
w("")
|
||||||
|
|
||||||
|
w("─ Per-account breakdown ─────────────────────────────────────────────────")
|
||||||
|
all_accounts = sorted(set(csv_accounts) | set(db_accounts))
|
||||||
|
w(f" {'account':<30} {'CSV':>6} {'DB':>6} {'delta':>7}")
|
||||||
|
for acct in all_accounts:
|
||||||
|
c, d = csv_accounts.get(acct, 0), db_accounts.get(acct, 0)
|
||||||
|
w(f" {acct:<30} {c:>6} {d:>6} {d-c:>+7}")
|
||||||
|
w("")
|
||||||
|
|
||||||
|
w(f"─ IMEIs in DB but NOT in CSV ({len(only_db)}) ─────────────────────────────")
|
||||||
|
if not only_db:
|
||||||
|
w(" (none — DB is a strict subset of CSV)")
|
||||||
|
else:
|
||||||
|
w(f" {'imei':<18} {'account':<22} {'city':<10} {'last_synced_at':<28} {'device_name'}")
|
||||||
|
for imei in only_db:
|
||||||
|
r = db_idx[imei]
|
||||||
|
w(f" {imei:<18} {(r.get('account') or ''):<22} "
|
||||||
|
f"{(r.get('assigned_city') or r.get('city') or ''):<10} "
|
||||||
|
f"{str(r.get('last_synced_at') or ''):<28} "
|
||||||
|
f"{r.get('device_name') or ''}")
|
||||||
|
w("")
|
||||||
|
|
||||||
|
w(f"─ IMEIs in CSV but NOT in DB ({len(only_csv)}) ─────────────────────────────")
|
||||||
|
if not only_csv:
|
||||||
|
w(" (none — every CSV row has a corresponding device row)")
|
||||||
|
else:
|
||||||
|
w(f" {'imei':<18} {'account':<22} {'assigned_city':<14} {'cost_centre':<14} {'driver_name'}")
|
||||||
|
for imei in only_csv:
|
||||||
|
r = csv_idx[imei]
|
||||||
|
w(f" {imei:<18} {(r.get('account') or ''):<22} "
|
||||||
|
f"{(r.get('assigned_city') or ''):<14} "
|
||||||
|
f"{(r.get('cost_centre') or ''):<14} "
|
||||||
|
f"{r.get('driver_name') or ''}")
|
||||||
|
w("")
|
||||||
|
|
||||||
|
# Stale-metadata audit: in both, but DB is still NULL on key fields.
|
||||||
|
stale: list[tuple[str, list[str]]] = []
|
||||||
|
for imei in sorted(both):
|
||||||
|
d = db_idx[imei]
|
||||||
|
blanks = [f for f in META_FIELDS if _is_blank(d.get(f))]
|
||||||
|
if blanks:
|
||||||
|
stale.append((imei, blanks))
|
||||||
|
|
||||||
|
w(f"─ Devices in both, but DB metadata still NULL ({len(stale)}) ──────────────")
|
||||||
|
if not stale:
|
||||||
|
w(" (none — import looks complete on intersecting devices)")
|
||||||
|
else:
|
||||||
|
w(" Likely cause: import_drivers_csv.py has not been re-run with --apply")
|
||||||
|
w(" against the new CSV, or rows had 'Identification' placeholders.")
|
||||||
|
w("")
|
||||||
|
w(f" {'imei':<18} blank_fields")
|
||||||
|
for imei, blanks in stale[:30]: # cap output
|
||||||
|
w(f" {imei:<18} {', '.join(blanks)}")
|
||||||
|
if len(stale) > 30:
|
||||||
|
w(f" ... and {len(stale) - 30} more")
|
||||||
|
w("")
|
||||||
|
|
||||||
|
w("─ Suggested next step ───────────────────────────────────────────────────")
|
||||||
|
if only_db:
|
||||||
|
w(" Inspect the IMEIs above. Decide one of:")
|
||||||
|
w(" (a) Prune — delete from tracksolid.devices if they are stale "
|
||||||
|
"test/decommissioned units.")
|
||||||
|
w(" (b) Leave-as-NULL — keep them as auto-synced API rows; their "
|
||||||
|
"metadata stays NULL until added to a future CSV.")
|
||||||
|
w(" (c) Addendum — add them to the CSV (or a sidecar CSV) and re-run "
|
||||||
|
"import_drivers_csv.py --apply.")
|
||||||
|
w(" Document the choice in 260427_device_reconciliation.md.")
|
||||||
|
else:
|
||||||
|
w(" CSV and DB are reconciled. No further action.")
|
||||||
|
|
||||||
|
if args.out:
|
||||||
|
Path(args.out).write_text("\n".join(out_lines), encoding="utf-8")
|
||||||
|
print(f"\nReport also written to {args.out}")
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
|
|
@ -1,8 +1,24 @@
|
||||||
"""
|
"""
|
||||||
import_drivers_csv.py — Fireside Communications · Driver & Vehicle CSV Import
|
import_drivers_csv.py — Fireside Communications · Driver & Vehicle CSV Import
|
||||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
One-shot script: reads 20260414_FS__Logistics - final_fixed.csv, compares
|
One-shot script: reads the snake_case Fireside Group vehicle CSV
|
||||||
each row against the current tracksolid.devices values, and updates the DB.
|
(`20260427_FSG_Vehicles_mitieng.csv`), compares each row against the
|
||||||
|
current `tracksolid.devices` values, and updates the DB.
|
||||||
|
|
||||||
|
The CSV columns mirror the DB schema directly — no inference. Cells with the
|
||||||
|
literal string "NULL" are treated as missing.
|
||||||
|
|
||||||
|
Fields imported (per Phase 0.1 of the Business Analytics redesign plan):
|
||||||
|
Identity : driver_name, driver_phone, vehicle_number, vehicle_name,
|
||||||
|
vehicle_models, mc_type, device_name
|
||||||
|
SIM : sim, iccid, imsi
|
||||||
|
Lifecycle : activation_time, expiration
|
||||||
|
Business meta : assigned_city, cost_centre, assigned_route,
|
||||||
|
vehicle_category, vehicle_brand, fuel_100km, depot_address
|
||||||
|
|
||||||
|
`depot_geom` (PostGIS Point) is intentionally NOT imported — needs WKT and
|
||||||
|
isn't present as coordinates in the CSV. Set it via a follow-up migration
|
||||||
|
when geofences are loaded.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
# Dry-run — shows diff, writes nothing
|
# Dry-run — shows diff, writes nothing
|
||||||
|
|
@ -17,68 +33,75 @@ Usage:
|
||||||
# Only fill fields that are currently NULL in the DB (never overwrite)
|
# Only fill fields that are currently NULL in the DB (never overwrite)
|
||||||
python import_drivers_csv.py --only-null --apply
|
python import_drivers_csv.py --only-null --apply
|
||||||
|
|
||||||
|
# Use a different CSV
|
||||||
|
python import_drivers_csv.py --csv path/to/file.csv
|
||||||
|
|
||||||
Pre-requisite:
|
Pre-requisite:
|
||||||
Migration 06 must be applied first (adds assigned_city / cost_centre columns).
|
Migrations 02, 05, 06 must be applied (they add the metadata columns).
|
||||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import csv
|
import csv
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import time
|
|
||||||
from datetime import date
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from ts_shared_rev import clean, clean_num, clean_ts, get_conn, get_logger
|
from ts_shared_rev import clean, clean_num, clean_ts, get_conn, get_logger
|
||||||
|
|
||||||
log = get_logger("csv_import")
|
log = get_logger("csv_import")
|
||||||
|
|
||||||
CSV_PATH = Path(__file__).parent / "20260414_FS__Logistics - final_fixed.csv"
|
DEFAULT_CSV_PATH = Path(__file__).parent / "20260427_FSG_Vehicles_mitieng.csv"
|
||||||
|
|
||||||
# Columns fetched from DB for comparison
|
# Columns fetched from DB for diff comparison.
|
||||||
DB_COLS = [
|
DB_COLS = [
|
||||||
"imei", "driver_name", "driver_phone", "vehicle_number", "vehicle_name",
|
"imei",
|
||||||
"vehicle_models", "cost_centre", "sim", "iccid", "imsi", "mc_type",
|
# Identity
|
||||||
"activation_time", "expiration", "device_name", "assigned_city",
|
"driver_name", "driver_phone", "vehicle_number", "vehicle_name",
|
||||||
|
"vehicle_models", "mc_type", "device_name",
|
||||||
|
# SIM
|
||||||
|
"sim", "iccid", "imsi",
|
||||||
|
# Lifecycle
|
||||||
|
"activation_time", "expiration",
|
||||||
|
# Business metadata (Phase 0.1 additions)
|
||||||
|
"assigned_city", "cost_centre", "assigned_route",
|
||||||
|
"vehicle_category", "vehicle_brand", "fuel_100km", "depot_address",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Driver Name values that are placeholders — skip writing driver_name for these
|
# Driver Name values that are placeholders — skip writing driver_name for these.
|
||||||
_DRIVER_SKIP = {"identification", "ug"}
|
_DRIVER_SKIP = {"identification", "ug"}
|
||||||
|
|
||||||
|
# Columns that need an explicit cast in the UPDATE statement.
|
||||||
def _infer_city(plate: str) -> str | None:
|
_TIMESTAMPTZ_COLS = {"activation_time", "expiration"}
|
||||||
"""Derive assigned_city from license plate prefix."""
|
_NUMERIC_COLS = {"fuel_100km"}
|
||||||
p = (plate or "").strip().upper()
|
|
||||||
if p.startswith("UMA") or p.startswith("UAG"):
|
|
||||||
return "KLA"
|
|
||||||
if p.startswith("K"):
|
|
||||||
return "NBO"
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def _clean_date(v: str) -> str | None:
|
def _read(row: dict, col: str) -> str | None:
|
||||||
"""Accept YYYY-MM-DD and return as ISO string suitable for TIMESTAMPTZ cast."""
|
"""Read a CSV column treating literal 'NULL'/'None' (case-insensitive) as missing."""
|
||||||
s = (v or "").strip()
|
v = clean(row.get(col))
|
||||||
if not s:
|
if v is None:
|
||||||
return None
|
|
||||||
try:
|
|
||||||
date.fromisoformat(s)
|
|
||||||
return s
|
|
||||||
except ValueError:
|
|
||||||
return None
|
return None
|
||||||
|
return None if v.upper() in ("NULL", "NONE") else v
|
||||||
|
|
||||||
|
|
||||||
def load_csv() -> dict[str, dict]:
|
def _read_num(row: dict, col: str) -> float | None:
|
||||||
|
v = _read(row, col)
|
||||||
|
return clean_num(v) if v is not None else None
|
||||||
|
|
||||||
|
|
||||||
|
def _read_ts(row: dict, col: str) -> str | None:
|
||||||
|
v = _read(row, col)
|
||||||
|
return clean_ts(v) if v is not None else None
|
||||||
|
|
||||||
|
|
||||||
|
def load_csv(csv_path: Path) -> dict[str, dict]:
|
||||||
"""Load CSV into a dict keyed by IMEI."""
|
"""Load CSV into a dict keyed by IMEI."""
|
||||||
rows: dict[str, dict] = {}
|
rows: dict[str, dict] = {}
|
||||||
with open(CSV_PATH, encoding="utf-8-sig", newline="") as f:
|
with open(csv_path, encoding="utf-8-sig", newline="") as f:
|
||||||
for row in csv.DictReader(f):
|
for row in csv.DictReader(f):
|
||||||
imei = (row.get("IMEI") or "").strip()
|
imei = (row.get("imei") or "").strip()
|
||||||
if not imei:
|
if not imei:
|
||||||
continue
|
continue
|
||||||
rows[imei] = row
|
rows[imei] = row
|
||||||
log.info("CSV loaded: %d rows from %s", len(rows), CSV_PATH.name)
|
log.info("CSV loaded: %d rows from %s", len(rows), csv_path.name)
|
||||||
return rows
|
return rows
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -102,42 +125,46 @@ def build_update(csv_row: dict, db_row: dict | None, only_null: bool) -> dict[st
|
||||||
When only_null=True, skip any DB column that already has a value.
|
When only_null=True, skip any DB column that already has a value.
|
||||||
The driver_name column is skipped for placeholder-labelled devices.
|
The driver_name column is skipped for placeholder-labelled devices.
|
||||||
"""
|
"""
|
||||||
driver_raw = clean(csv_row.get("Driver Name")) or ""
|
driver_raw = (_read(csv_row, "driver_name") or "")
|
||||||
plate = clean(csv_row.get("License Plate No.")) or ""
|
|
||||||
is_placeholder = driver_raw.lower() in _DRIVER_SKIP
|
is_placeholder = driver_raw.lower() in _DRIVER_SKIP
|
||||||
skip_row = driver_raw.lower() == "identification"
|
if driver_raw.lower() == "identification":
|
||||||
|
|
||||||
if skip_row:
|
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
proposed: dict[str, object] = {
|
proposed: dict[str, object] = {
|
||||||
"vehicle_number": clean(plate),
|
# Identity
|
||||||
"vehicle_name": clean(plate),
|
"driver_phone": _read(csv_row, "driver_phone"),
|
||||||
"vehicle_models": clean(csv_row.get("Vehicle Model")),
|
"vehicle_number": _read(csv_row, "vehicle_number"),
|
||||||
"cost_centre": clean(csv_row.get("Department")),
|
"vehicle_name": _read(csv_row, "vehicle_name"),
|
||||||
"sim": clean(csv_row.get("SIM")),
|
"vehicle_models": _read(csv_row, "vehicle_models"),
|
||||||
"iccid": clean(csv_row.get("ICCID")),
|
"mc_type": _read(csv_row, "mc_type"),
|
||||||
"imsi": clean(csv_row.get("IMSI")),
|
"device_name": _read(csv_row, "device_name"),
|
||||||
"mc_type": clean(csv_row.get("Model")),
|
# SIM
|
||||||
"activation_time": _clean_date(csv_row.get("Activated Date", "")),
|
"sim": _read(csv_row, "sim"),
|
||||||
"expiration": _clean_date(csv_row.get("Subscription Expiration", "")),
|
"iccid": _read(csv_row, "iccid"),
|
||||||
"driver_phone": clean(csv_row.get("Telephone")),
|
"imsi": _read(csv_row, "imsi"),
|
||||||
"assigned_city": _infer_city(plate),
|
# Lifecycle
|
||||||
|
"activation_time": _read_ts(csv_row, "activation_time"),
|
||||||
|
"expiration": _read_ts(csv_row, "expiration"),
|
||||||
|
# Business metadata
|
||||||
|
"assigned_city": _read(csv_row, "assigned_city"),
|
||||||
|
"cost_centre": _read(csv_row, "cost_centre"),
|
||||||
|
"assigned_route": _read(csv_row, "assigned_route"),
|
||||||
|
"vehicle_category": _read(csv_row, "vehicle_category"),
|
||||||
|
"vehicle_brand": _read(csv_row, "vehicle_brand"),
|
||||||
|
"fuel_100km": _read_num(csv_row, "fuel_100km"),
|
||||||
|
"depot_address": _read(csv_row, "depot_address"),
|
||||||
}
|
}
|
||||||
if not is_placeholder:
|
if not is_placeholder and driver_raw:
|
||||||
proposed["driver_name"] = driver_raw or None
|
proposed["driver_name"] = driver_raw
|
||||||
|
|
||||||
# Drop None values — no point sending a NULL to overwrite another NULL
|
# Drop None values — no point sending NULL to overwrite NULL.
|
||||||
proposed = {k: v for k, v in proposed.items() if v is not None}
|
proposed = {k: v for k, v in proposed.items() if v is not None}
|
||||||
|
|
||||||
if not only_null or db_row is None:
|
if not only_null or db_row is None:
|
||||||
return proposed
|
return proposed
|
||||||
|
|
||||||
# only_null: drop any column that already has a non-null value in the DB
|
# only_null: drop any column that already has a non-null value in the DB.
|
||||||
return {
|
return {k: v for k, v in proposed.items() if db_row.get(k) is None}
|
||||||
k: v for k, v in proposed.items()
|
|
||||||
if db_row.get(k) is None
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def print_diff(imei: str, updates: dict[str, object], db_row: dict | None) -> None:
|
def print_diff(imei: str, updates: dict[str, object], db_row: dict | None) -> None:
|
||||||
|
|
@ -148,12 +175,31 @@ def print_diff(imei: str, updates: dict[str, object], db_row: dict | None) -> No
|
||||||
print(f"\n IMEI {imei}:")
|
print(f"\n IMEI {imei}:")
|
||||||
for col, new_val in sorted(updates.items()):
|
for col, new_val in sorted(updates.items()):
|
||||||
old_val = db.get(col)
|
old_val = db.get(col)
|
||||||
if old_val != new_val:
|
if str(old_val) != str(new_val):
|
||||||
print(f" {col:<20} {str(old_val):<30} → {new_val}")
|
print(f" {col:<20} {str(old_val):<30} → {new_val}")
|
||||||
|
|
||||||
|
|
||||||
def run(apply: bool, only_null: bool, filter_imei: str | None) -> None:
|
def _set_clause(col: str) -> str:
|
||||||
csv_rows = load_csv()
|
"""SQL fragment for `col = ...` honouring per-column casts."""
|
||||||
|
if col in _TIMESTAMPTZ_COLS:
|
||||||
|
return f"{col} = COALESCE(%s::TIMESTAMPTZ, {col})"
|
||||||
|
if col in _NUMERIC_COLS:
|
||||||
|
# %s already a float; no NULLIF dance needed.
|
||||||
|
return f"{col} = COALESCE(%s::NUMERIC, {col})"
|
||||||
|
return f"{col} = COALESCE(NULLIF(%s, ''), {col})"
|
||||||
|
|
||||||
|
|
||||||
|
def _placeholder(col: str) -> str:
|
||||||
|
"""SQL fragment for a single VALUES placeholder honouring per-column casts."""
|
||||||
|
if col in _TIMESTAMPTZ_COLS:
|
||||||
|
return "%s::TIMESTAMPTZ"
|
||||||
|
if col in _NUMERIC_COLS:
|
||||||
|
return "%s::NUMERIC"
|
||||||
|
return "%s"
|
||||||
|
|
||||||
|
|
||||||
|
def run(apply: bool, only_null: bool, filter_imei: str | None, csv_path: Path) -> None:
|
||||||
|
csv_rows = load_csv(csv_path)
|
||||||
db_rows = load_db_devices()
|
db_rows = load_db_devices()
|
||||||
|
|
||||||
if filter_imei:
|
if filter_imei:
|
||||||
|
|
@ -168,12 +214,10 @@ def run(apply: bool, only_null: bool, filter_imei: str | None) -> None:
|
||||||
with conn.cursor() as cur:
|
with conn.cursor() as cur:
|
||||||
for imei, csv_row in csv_rows.items():
|
for imei, csv_row in csv_rows.items():
|
||||||
db_row = db_rows.get(imei)
|
db_row = db_rows.get(imei)
|
||||||
|
|
||||||
updates = build_update(csv_row, db_row, only_null)
|
updates = build_update(csv_row, db_row, only_null)
|
||||||
|
|
||||||
if not updates:
|
if not updates:
|
||||||
# Either an "Identification" placeholder or nothing to change
|
driver_raw = (_read(csv_row, "driver_name") or "").lower()
|
||||||
driver_raw = (csv_row.get("Driver Name") or "").strip().lower()
|
|
||||||
if driver_raw == "identification":
|
if driver_raw == "identification":
|
||||||
skipped += 1
|
skipped += 1
|
||||||
else:
|
else:
|
||||||
|
|
@ -181,20 +225,15 @@ def run(apply: bool, only_null: bool, filter_imei: str | None) -> None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if db_row is None:
|
if db_row is None:
|
||||||
# Device not yet synced from API — insert a stub row now so
|
# Device not yet synced from API — insert a stub row so
|
||||||
# incoming alarms / positions don't trip the FK constraint.
|
# incoming alarms / positions don't trip the FK constraint.
|
||||||
print(f"\n [NEW] IMEI {imei}:")
|
print(f"\n [NEW] IMEI {imei}:")
|
||||||
for col, new_val in sorted(updates.items()):
|
for col, new_val in sorted(updates.items()):
|
||||||
print(f" {col:<20} → {new_val}")
|
print(f" {col:<20} → {new_val}")
|
||||||
if apply:
|
if apply:
|
||||||
cols = ["imei"] + list(updates.keys())
|
cols = ["imei"] + list(updates.keys())
|
||||||
vals = [imei] + [str(v) if v is not None else None for v in updates.values()]
|
vals = [imei] + list(updates.values())
|
||||||
placeholders = []
|
placeholders = ["%s"] + [_placeholder(c) for c in updates.keys()]
|
||||||
for col in cols:
|
|
||||||
if col in ("activation_time", "expiration"):
|
|
||||||
placeholders.append("%s::TIMESTAMPTZ")
|
|
||||||
else:
|
|
||||||
placeholders.append("%s")
|
|
||||||
cur.execute(
|
cur.execute(
|
||||||
f"INSERT INTO tracksolid.devices ({', '.join(cols)}) "
|
f"INSERT INTO tracksolid.devices ({', '.join(cols)}) "
|
||||||
f"VALUES ({', '.join(placeholders)}) "
|
f"VALUES ({', '.join(placeholders)}) "
|
||||||
|
|
@ -207,20 +246,10 @@ def run(apply: bool, only_null: bool, filter_imei: str | None) -> None:
|
||||||
print_diff(imei, updates, db_row)
|
print_diff(imei, updates, db_row)
|
||||||
|
|
||||||
if apply:
|
if apply:
|
||||||
set_clauses = []
|
set_clauses = [_set_clause(c) for c in updates.keys()]
|
||||||
params = []
|
params = list(updates.values())
|
||||||
for col, val in updates.items():
|
|
||||||
if col in ("activation_time", "expiration"):
|
|
||||||
set_clauses.append(f"{col} = COALESCE(%s::TIMESTAMPTZ, {col})")
|
|
||||||
else:
|
|
||||||
set_clauses.append(
|
|
||||||
f"{col} = COALESCE(NULLIF(%s, ''), {col})"
|
|
||||||
)
|
|
||||||
params.append(str(val) if val is not None else None)
|
|
||||||
|
|
||||||
set_clauses.append("updated_at = NOW()")
|
set_clauses.append("updated_at = NOW()")
|
||||||
params.append(imei)
|
params.append(imei)
|
||||||
|
|
||||||
cur.execute(
|
cur.execute(
|
||||||
f"UPDATE tracksolid.devices SET {', '.join(set_clauses)} WHERE imei = %s",
|
f"UPDATE tracksolid.devices SET {', '.join(set_clauses)} WHERE imei = %s",
|
||||||
params,
|
params,
|
||||||
|
|
@ -233,19 +262,28 @@ def run(apply: bool, only_null: bool, filter_imei: str | None) -> None:
|
||||||
print(f"\n{'='*60}")
|
print(f"\n{'='*60}")
|
||||||
print(f" {mode} COMPLETE")
|
print(f" {mode} COMPLETE")
|
||||||
print(f"{'='*60}")
|
print(f"{'='*60}")
|
||||||
print(f" Would update / updated : {updated}")
|
print(f" Would update / updated : {updated}")
|
||||||
print(f" Would insert / inserted: {inserted}")
|
print(f" Would insert / inserted : {inserted}")
|
||||||
print(f" No change needed : {no_change}")
|
print(f" No change needed : {no_change}")
|
||||||
print(f" Skipped (Identification): {skipped}")
|
print(f" Skipped (Identification): {skipped}")
|
||||||
if not apply:
|
if not apply:
|
||||||
print("\n Run with --apply to commit changes.")
|
print("\n Run with --apply to commit changes.")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
parser = argparse.ArgumentParser(description="Import driver/vehicle details from CSV into tracksolid.devices")
|
parser = argparse.ArgumentParser(
|
||||||
|
description="Import driver/vehicle details from CSV into tracksolid.devices"
|
||||||
|
)
|
||||||
parser.add_argument("--apply", action="store_true", help="Write changes to DB (default: dry-run)")
|
parser.add_argument("--apply", action="store_true", help="Write changes to DB (default: dry-run)")
|
||||||
parser.add_argument("--only-null", action="store_true", help="Only update fields currently NULL in the DB")
|
parser.add_argument("--only-null", action="store_true", help="Only update fields currently NULL in the DB")
|
||||||
parser.add_argument("--imei", default=None, help="Limit to a single IMEI")
|
parser.add_argument("--imei", default=None, help="Limit to a single IMEI")
|
||||||
|
parser.add_argument("--csv", default=str(DEFAULT_CSV_PATH),
|
||||||
|
help=f"Path to the CSV (default: {DEFAULT_CSV_PATH.name})")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
run(apply=args.apply, only_null=args.only_null, filter_imei=args.imei)
|
csv_path = Path(args.csv)
|
||||||
|
if not csv_path.exists():
|
||||||
|
log.error("CSV file not found: %s", csv_path)
|
||||||
|
raise SystemExit(1)
|
||||||
|
|
||||||
|
run(apply=args.apply, only_null=args.only_null, filter_imei=args.imei, csv_path=csv_path)
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ MIGRATIONS = [
|
||||||
"05_enhancement_migration.sql", # new tables, OBD columns, dwh_gold expansion
|
"05_enhancement_migration.sql", # new tables, OBD columns, dwh_gold expansion
|
||||||
"06_business_analytics_migration.sql", # ops schema, dispatch_log, assigned_city
|
"06_business_analytics_migration.sql", # ops schema, dispatch_log, assigned_city
|
||||||
"07_analytics_views.sql", # Grafana-facing views in tracksolid.*
|
"07_analytics_views.sql", # Grafana-facing views in tracksolid.*
|
||||||
|
"08_analytics_config.sql", # ops.cost_rates, ops.kpi_targets + seed data
|
||||||
]
|
]
|
||||||
|
|
||||||
# ── Tables that must exist before the service is allowed to start ─────────────
|
# ── Tables that must exist before the service is allowed to start ─────────────
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue