@golemio/flow 1.0.8-dev.573594395 → 1.0.8-dev.585575300

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/db/example/.config.json +3 -0
  2. package/db/example/00_truncate_tables.sql +10 -0
  3. package/db/example/01_wifiHistoricData.sql +49 -0
  4. package/db/example/02_countersData.sql +99 -0
  5. package/db/example/03_flowData.sql +343 -0
  6. package/db/example/99_runUpdateProcedure.sql +1 -0
  7. package/db/migrations/postgresql/.config.json +3 -0
  8. package/db/migrations/postgresql/20220616144407-flow.js +53 -0
  9. package/db/migrations/postgresql/20220711123652-analytic.js +53 -0
  10. package/db/migrations/postgresql/package.json +3 -0
  11. package/db/migrations/postgresql/sqls/20220616144407-flow-down.sql +15 -0
  12. package/db/migrations/postgresql/sqls/20220616144407-flow-up.sql +467 -0
  13. package/db/migrations/postgresql/sqls/20220711123652-analytic-down.sql +7 -0
  14. package/db/migrations/postgresql/sqls/20220711123652-analytic-up.sql +415 -0
  15. package/db/migrations/postgresql/sqls/package.json +3 -0
  16. package/dist/integration-engine/CountersWorker.d.ts +14 -0
  17. package/dist/integration-engine/CountersWorker.js +120 -0
  18. package/dist/integration-engine/CountersWorker.js.map +1 -0
  19. package/dist/integration-engine/FlowWorker.js +6 -2
  20. package/dist/integration-engine/FlowWorker.js.map +1 -1
  21. package/dist/integration-engine/queueDefinitions.js +27 -0
  22. package/dist/integration-engine/queueDefinitions.js.map +1 -1
  23. package/dist/integration-engine/transformations/EcoCounterMeasurementsTransformation.d.ts +6 -0
  24. package/dist/integration-engine/transformations/EcoCounterMeasurementsTransformation.js +42 -0
  25. package/dist/integration-engine/transformations/EcoCounterMeasurementsTransformation.js.map +1 -0
  26. package/dist/integration-engine/transformations/EcoCounterTransformation.d.ts +17 -0
  27. package/dist/integration-engine/transformations/EcoCounterTransformation.js +99 -0
  28. package/dist/integration-engine/transformations/EcoCounterTransformation.js.map +1 -0
  29. package/dist/output-gateway/models/PedestriansLocationsModel.js +4 -2
  30. package/dist/output-gateway/models/PedestriansLocationsModel.js.map +1 -1
  31. package/dist/output-gateway/models/PedestriansMeasurementsModel.js +4 -2
  32. package/dist/output-gateway/models/PedestriansMeasurementsModel.js.map +1 -1
  33. package/dist/schema-definitions/index.d.ts +185 -0
  34. package/dist/schema-definitions/index.js +197 -2
  35. package/dist/schema-definitions/index.js.map +1 -1
  36. package/docs/implementation_documentation_CZ.md +6 -6
  37. package/docs/implementation_documentation_Counters.md +166 -0
  38. package/package.json +8 -4
@@ -0,0 +1,415 @@
1
+ CREATE SCHEMA IF NOT EXISTS analytic;
2
+
3
+ CREATE TABLE IF NOT EXISTS analytic.pedestrians_locations_list (
4
+ id serial4 NOT NULL,
5
+ location_name_plain varchar(250) NULL,
6
+ location_name varchar(250) NULL,
7
+ lat numeric NULL,
8
+ lng numeric NULL,
9
+ address varchar(250) NULL,
10
+ city_district varchar(250) NULL,
11
+ tech varchar(250) NULL,
12
+ map_picture varchar(2500) NULL,
13
+ gate_picture varchar(2500) NULL,
14
+ measurement_start timestamptz NULL,
15
+ measurement_end timestamptz NULL,
16
+ id_equiptment varchar(250) NULL,
17
+ cube_id varchar(250) NULL,
18
+ lon varbit NULL,
19
+ map_image varchar(55) NULL,
20
+ place_image varchar(59) NULL,
21
+ "table" varchar(19) NULL,
22
+ CONSTRAINT equipment_list_pkey PRIMARY KEY (id)
23
+ );
24
+ COMMENT ON TABLE analytic.pedestrians_locations_list IS '-- tabulka lokací. obsahuje lokace různých druhů a hodně custom dat, takže ji tvoříme ručně. sporadicky probíhají aktualizace
25
+ -- tabulka se nachází na https://operator.sharepoint.com/:f:/s/Datova_Platforma/EsE5uSdyLzdImWgyrMY8nFcBzwtH7GOr6TXtzNBn3FLIJw?e=fOov5s a jmenuje se locations_list.csv';
26
+
27
+ INSERT INTO analytic.pedestrians_locations_list (location_name_plain,location_name,lat,lng,address,city_district,tech,map_picture,gate_picture,measurement_start,measurement_end,id_equiptment,cube_id,lon,map_image,place_image,"table") VALUES
28
+ ('Výstaviště - viadukt VO 2','107043 - Výstaviště - viadukt VO 2',50.1042106575078,14.431679367811926,'U Výstaviště (viadukt)','Praha 7','kamera',NULL,NULL,'2020-09-02 00:00:00+02',NULL,NULL,'0',NULL,'https://storage.golemio.cz/intenzita-pesi-dopravy/1.png','https://storage.golemio.cz/intenzita-pesi-dopravy/1-map.png','flow_measurements'),
29
+ ('Rytířská 12','101336 - Rytířská 12',50.084781715549276,14.422412102465428,'Na Můstku 12','Praha 1','kamera',NULL,NULL,'2020-09-02 00:00:00+02',NULL,NULL,'1',NULL,'https://storage.golemio.cz/intenzita-pesi-dopravy/2.png','https://storage.golemio.cz/intenzita-pesi-dopravy/2-map.png','flow_measurements'),
30
+ ('Výstaviště - viadukt','Výstaviště - viadukt',50.1042106575078,14.431679367811926,'U Výstaviště (viadukt)','Praha 7','pyro',NULL,NULL,'2020-07-23 00:00:00+02','2020-11-10 00:00:00+01',NULL,'ecoCounter-100061215',NULL,'https://storage.golemio.cz/intenzita-pesi-dopravy/1.png','https://storage.golemio.cz/intenzita-pesi-dopravy/1-map.png','counters_detections'),
31
+ ('Stromovka - U Výstaviště','Stromovka - U Výstaviště',50.10489433551656,14.429609941952332,'U Výstaviště 67','Praha 7','wifi',NULL,NULL,'2020-11-24 00:00:00+01',NULL,NULL,'wifi1',NULL,NULL,'https://storage.golemio.cz/intenzita-pesi-dopravy/4-map.png','xyz'),
32
+ ('Stromovka - U Výstaviště','Stromovka - U Výstaviště',50.10489433551656,14.429609941952332,'U Výstaviště 67','Praha 7','pyro',NULL,NULL,'2020-11-11 00:00:00+01','2021-03-04 00:00:00+01',NULL,'ecoCounter-100065230',NULL,'https://storage.golemio.cz/intenzita-pesi-dopravy/3.png','https://storage.golemio.cz/intenzita-pesi-dopravy/3-map.png','counters_detections'),
33
+ ('Stromovka - U Výstaviště','Stromovka - U Výstaviště',50.10489433551656,14.429609941952332,'U Výstaviště 67','Praha 7','kamera',NULL,NULL,'2020-12-17 00:00:00+01',NULL,NULL,'13',NULL,'https://storage.golemio.cz/intenzita-pesi-dopravy/3.png','https://storage.golemio.cz/intenzita-pesi-dopravy/3-map.png','flow_measurements'),
34
+ ('Staroměstská věž pevná VI','101004 - Staroměstská věž pevná VI',50.08626,14.41301,'Karlův most','Praha 1','kamera',NULL,NULL,'2020-09-02 00:00:00+02',NULL,NULL,'9',NULL,'https://storage.golemio.cz/intenzita-pesi-dopravy/5.png','https://storage.golemio.cz/intenzita-pesi-dopravy/5-map.png','flow_measurements'),
35
+ ('Železniční most - nápl. I (náplavka)','202049 - Železniční most - nápl. I (náplavka)',50.06739,14.41468,'Novoměstská náplavka','Praha 2','kamera',NULL,NULL,'2020-09-02 00:00:00+02',NULL,NULL,'10',NULL,'https://storage.golemio.cz/intenzita-pesi-dopravy/6.png','https://storage.golemio.cz/intenzita-pesi-dopravy/6-map.png','flow_measurements'),
36
+ ('Železniční most - náplavka II','202050 - Železniční most - náplavka II',50.06693,14.41480,'Novoměstská náplavka','Praha 2','kamera',NULL,NULL,'2020-09-02 00:00:00+02',NULL,NULL,'11',NULL,'https://storage.golemio.cz/intenzita-pesi-dopravy/7.png','https://storage.golemio.cz/intenzita-pesi-dopravy/7-map.png','flow_measurements'),
37
+ ('Železniční most - nápl. I (rampa)','202049 - Železniční most - nápl. I (rampa)',50.06739,14.41468,'Novoměstská náplavka','Praha 2','kamera',NULL,NULL,'2020-09-02 00:00:00+02',NULL,NULL,'10',NULL,'https://storage.golemio.cz/intenzita-pesi-dopravy/6.png','https://storage.golemio.cz/intenzita-pesi-dopravy/6-map.png','flow_measurements')
38
+ ON CONFLICT DO NOTHING;
39
+ INSERT INTO analytic.pedestrians_locations_list (location_name_plain,location_name,lat,lng,address,city_district,tech,map_picture,gate_picture,measurement_start,measurement_end,id_equiptment,cube_id,lon,map_image,place_image,"table") VALUES
40
+ ('Železniční most - nápl. I (plný profil)','202049 - Železniční most - nápl. I (plný profil)',50.06739,14.41468,'Novoměstská náplavka','Praha 2','kamera',NULL,NULL,'2020-09-02 00:00:00+02',NULL,NULL,'10',NULL,'https://storage.golemio.cz/intenzita-pesi-dopravy/6.png','https://storage.golemio.cz/intenzita-pesi-dopravy/6-map.png','flow_measurements')
41
+ ON CONFLICT DO NOTHING;
42
+
43
+
44
+ CREATE TABLE IF NOT EXISTS analytic.pedestrians_locations_gates (
45
+ direction_id varchar(250) NOT NULL,
46
+ cube_id varchar(250) NOT NULL,
47
+ location_id int4 NOT NULL,
48
+ name varchar(250) NOT NULL,
49
+ direction_type varchar(250) NOT NULL,
50
+ CONSTRAINT equipment_gates_pkey PRIMARY KEY (direction_id, location_id)
51
+ );
52
+
53
+ INSERT INTO analytic.pedestrians_locations_gates (direction_id,cube_id,location_id,"name",direction_type) VALUES
54
+ ('4','0',1,'Směr pod viadukt','Směr 1'),
55
+ ('7','0',1,'Směr Výstaviště','Směr 2'),
56
+ ('2','1',2,'Směr Můstek','Směr 1'),
57
+ ('3','1',2,'Směr Rytířská','Směr 2'),
58
+ ('5','9',7,'Směr Malá strana','Směr 1'),
59
+ ('8','9',7,'Směr Staré město','Směr 2'),
60
+ ('6','10',8,'Náplavka, směr centrum','Směr 1'),
61
+ ('9','10',10,'Rampa, směr centrum','Směr 1'),
62
+ ('10','10',11,'Plný profil, směr centrum','Směr 1'),
63
+ ('11','10',8,'Náplavka, směr Vyšehrad','Směr 2')
64
+ ON CONFLICT DO NOTHING;
65
+ INSERT INTO analytic.pedestrians_locations_gates (direction_id,cube_id,location_id,"name",direction_type) VALUES
66
+ ('13','10',10,'Rampa, směr Vyšehrad','Směr 2'),
67
+ ('15','10',11,'Plný profil, směr Vyšehrad','Směr 2'),
68
+ ('35','11',9,'Plný profil, směr centrum','Směr 1'),
69
+ ('29','11',9,'Plný profil, směr Vyšehrad','Směr 2'),
70
+ ('7','13',6,'Směr Planetarium','Směr 1'),
71
+ ('8','13',6,'Směr Holešovice','Směr 2'),
72
+ ('ecoCounter-103061215','ecoCounter-100061215',3,'Směr pod viadukt','Směr 1'),
73
+ ('ecoCounter-104061215','ecoCounter-100061215',3,'Směr Výstaviště','Směr 2'),
74
+ ('ecoCounter-353245241','ecoCounter-100065230',5,'Směr Planetarium','Směr 1'),
75
+ ('ecoCounter-102065230','ecoCounter-100065230',5,'Směr Planetarium','Směr 1')
76
+ ON CONFLICT DO NOTHING;
77
+ INSERT INTO analytic.pedestrians_locations_gates (direction_id,cube_id,location_id,"name",direction_type) VALUES
78
+ ('ecoCounter-353240728','ecoCounter-100065230',5,'Směr Planetarium','Směr 1'),
79
+ ('ecoCounter-353235722','ecoCounter-100065230',5,'Směr Planetarium','Směr 1'),
80
+ ('ecoCounter-353231243','ecoCounter-100065230',5,'Směr Planetarium','Směr 1'),
81
+ ('ecoCounter-353245239','ecoCounter-100065230',5,'Směr Holešovice','Směr 2'),
82
+ ('ecoCounter-101065230','ecoCounter-100065230',5,'Směr Holešovice','Směr 2'),
83
+ ('ecoCounter-353240727','ecoCounter-100065230',5,'Směr Holešovice','Směr 2'),
84
+ ('ecoCounter-353235721','ecoCounter-100065230',5,'Směr Holešovice','Směr 2'),
85
+ ('ecoCounter-353231242','ecoCounter-100065230',5,'Směr Holešovice','Směr 2'),
86
+ ('dir1','wifi1',4,'Směr Holešovice','Směr 1'),
87
+ ('dir2','wifi1',4,'Směr Planetarium','Směr 2')
88
+ ON CONFLICT DO NOTHING;
89
+
90
+ COMMENT ON TABLE analytic.pedestrians_locations_gates IS '-- tabulka směrů k jednotlivým lokacím, platí to samé co u lokations_list.
91
+ -- nachází se na https://operator.sharepoint.com/:f:/s/Datova_Platforma/EsE5uSdyLzdImWgyrMY8nFcBzwtH7GOr6TXtzNBn3FLIJw?e=fOov5s a jmenuje se directions_list.csv';
92
+
93
+ COMMENT ON TABLE pedestrians_wifi IS '-- tabulka na primární data wifi měření, jsou pouze jako csv na sharepointu https://operator.sharepoint.com/:f:/s/Datova_Platforma/EroMekiKaJdOtMPeF_Q8wPEBlZm5tLKHCgpK13H6hlc0Zg?e=4RbCkT';
94
+
95
+ -- analytic.v_pedestrians_detections_15min source
96
+
97
+ CREATE OR REPLACE VIEW analytic.v_pedestrians_detections_15min
98
+ AS WITH wifi AS (
99
+ SELECT pedestrians_wifi.location_id AS locations_id,
100
+ pedestrians_wifi.direction_id AS directions_id,
101
+ date_trunc('hour'::text, pedestrians_wifi.measured_from) + (date_part('minute'::text, pedestrians_wifi.measured_from)::integer / 15)::double precision * '00:15:00'::interval AS measured_from,
102
+ sum(pedestrians_wifi.value) AS value,
103
+ count(pedestrians_wifi.value) AS count_n
104
+ FROM flow.pedestrians_wifi
105
+ GROUP BY pedestrians_wifi.location_id, pedestrians_wifi.direction_id, (date_trunc('hour'::text, pedestrians_wifi.measured_from) + (date_part('minute'::text, pedestrians_wifi.measured_from)::integer / 15)::double precision * '00:15:00'::interval)
106
+ ), pyro AS (
107
+ SELECT cd.locations_id,
108
+ lg.first_dir AS directions_id,
109
+ to_timestamp((cd.measured_from / 1000)::double precision) AS measured_from,
110
+ sum(cd.value) AS value,
111
+ count(cd.value) AS count_n
112
+ FROM flow.counters_detections cd
113
+ LEFT JOIN ( SELECT pedestrians_locations_gates.direction_id,
114
+ pedestrians_locations_gates.direction_type,
115
+ min(pedestrians_locations_gates.direction_id::text) OVER (PARTITION BY pedestrians_locations_gates.cube_id, pedestrians_locations_gates.direction_type) AS first_dir
116
+ FROM analytic.pedestrians_locations_gates) lg ON cd.directions_id::text = lg.direction_id::text
117
+ WHERE cd.category::text = 'pedestrian'::text AND (cd.directions_id::text IN ( SELECT DISTINCT pedestrians_locations_gates.direction_id
118
+ FROM analytic.pedestrians_locations_gates))
119
+ GROUP BY cd.locations_id, lg.first_dir, (to_timestamp((cd.measured_from / 1000)::double precision))
120
+ ), flow AS (
121
+ SELECT flow_measurements.cube_id::character varying(50) AS location_id,
122
+ flow_measurements.sink_id::character varying(50) AS direction_id,
123
+ date_trunc('hour'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision)) + (date_part('minute'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision))::integer / 15)::double precision * '00:15:00'::interval AS measured_from,
124
+ sum(flow_measurements.value) AS value,
125
+ count(flow_measurements.value) AS count_n
126
+ FROM flow.flow_measurements
127
+ WHERE ((flow_measurements.cube_id::character varying(50)::text, flow_measurements.sink_id::character varying(50)::text) IN ( SELECT DISTINCT pedestrians_locations_gates.cube_id AS location_id,
128
+ pedestrians_locations_gates.direction_id
129
+ FROM analytic.pedestrians_locations_gates)) AND flow_measurements.category::text = 'pedestrian'::text
130
+ GROUP BY (flow_measurements.cube_id::character varying(50)), (flow_measurements.sink_id::character varying(50)), (date_trunc('hour'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision)) + (date_part('minute'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision))::integer / 15)::double precision * '00:15:00'::interval)
131
+ ORDER BY (date_trunc('hour'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision)) + (date_part('minute'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision))::integer / 15)::double precision * '00:15:00'::interval), (flow_measurements.cube_id::character varying(50)), (flow_measurements.sink_id::character varying(50))
132
+ ), measurements AS (
133
+ SELECT wifi.locations_id,
134
+ wifi.directions_id,
135
+ wifi.measured_from,
136
+ wifi.value,
137
+ wifi.count_n
138
+ FROM wifi
139
+ UNION ALL
140
+ SELECT pyro.locations_id,
141
+ pyro.directions_id,
142
+ pyro.measured_from,
143
+ pyro.value,
144
+ pyro.count_n
145
+ FROM pyro
146
+ UNION ALL
147
+ SELECT flow.location_id,
148
+ flow.direction_id,
149
+ flow.measured_from,
150
+ flow.value,
151
+ flow.count_n
152
+ FROM flow
153
+ ), calendar AS (
154
+ SELECT generate_series(min(measurements.measured_from), max(measurements.measured_from), '00:15:00'::interval) AS calendar
155
+ FROM measurements
156
+ ), classes AS (
157
+ SELECT calendar.calendar,
158
+ m_1.location_id,
159
+ m_1.direction_id
160
+ FROM calendar
161
+ JOIN ( SELECT DISTINCT measurements.locations_id::character varying(50) AS location_id,
162
+ measurements.directions_id::character varying(50) AS direction_id
163
+ FROM measurements) m_1 ON true
164
+ )
165
+ SELECT c.calendar,
166
+ date_trunc('hour'::text, c.calendar) AS calendar_hour,
167
+ c.calendar::date AS calendar_date,
168
+ ll.measurement_start,
169
+ COALESCE(ll.measurement_end, now()::date::timestamp with time zone) AS measurement_end,
170
+ c.location_id,
171
+ c.direction_id,
172
+ concat(c.location_id, '-', c.direction_id) AS compound_id,
173
+ COALESCE(m.value, 0::bigint) AS value,
174
+ COALESCE(m.count_n, 0::bigint) AS count_n
175
+ FROM classes c
176
+ LEFT JOIN measurements m ON c.calendar = m.measured_from AND c.location_id::text = m.locations_id::text AND c.direction_id::text = m.directions_id::text
177
+ LEFT JOIN analytic.pedestrians_locations_list ll ON c.location_id::text = ll.cube_id::text
178
+ WHERE c.calendar >= ll.measurement_start AND c.calendar <= COALESCE(ll.measurement_end, now()::date::timestamp with time zone);
179
+
180
+
181
+ -- analytic.v_pedestrians_detections_api source
182
+
183
+ CREATE OR REPLACE VIEW analytic.v_pedestrians_detections_api
184
+ AS WITH wifi AS (
185
+ SELECT pedestrians_wifi.location_id,
186
+ pedestrians_wifi.direction_id,
187
+ date_trunc('hour'::text, pedestrians_wifi.measured_from) + (date_part('minute'::text, pedestrians_wifi.measured_from)::integer / 15)::double precision * '00:15:00'::interval AS measured_from,
188
+ date_trunc('hour'::text, pedestrians_wifi.measured_from) + (date_part('minute'::text, pedestrians_wifi.measured_from)::integer / 15)::double precision * '00:15:00'::interval + '00:15:00'::interval AS measured_to,
189
+ sum(pedestrians_wifi.value) AS value,
190
+ count(pedestrians_wifi.value) AS count_n,
191
+ 3 AS quantity
192
+ FROM flow.pedestrians_wifi
193
+ GROUP BY pedestrians_wifi.location_id, pedestrians_wifi.direction_id, (date_trunc('hour'::text, pedestrians_wifi.measured_from) + (date_part('minute'::text, pedestrians_wifi.measured_from)::integer / 15)::double precision * '00:15:00'::interval), (date_trunc('hour'::text, pedestrians_wifi.measured_from) + (date_part('minute'::text, pedestrians_wifi.measured_from)::integer / 15)::double precision * '00:15:00'::interval + '00:15:00'::interval)
194
+ ), pyro AS (
195
+ SELECT cd.locations_id AS location_id,
196
+ cd.directions_id AS direction_id,
197
+ to_timestamp((cd.measured_from / 1000)::double precision) AS measured_from,
198
+ to_timestamp((cd.measured_from / 1000)::double precision) + '00:15:00'::interval AS measured_to,
199
+ sum(cd.value) AS value,
200
+ count(cd.value) AS count_n,
201
+ 1 AS quantity
202
+ FROM flow.counters_detections cd
203
+ WHERE cd.category::text = 'pedestrian'::text AND (cd.directions_id::text IN ( SELECT DISTINCT pedestrians_directions_api.direction_id
204
+ FROM flow.pedestrians_directions_api))
205
+ GROUP BY cd.locations_id, cd.directions_id, (to_timestamp((cd.measured_from / 1000)::double precision)), (to_timestamp((cd.measured_from / 1000)::double precision) + '00:15:00'::interval)
206
+ ), flow AS (
207
+ SELECT flow_measurements.cube_id::character varying(50) AS location_id,
208
+ flow_measurements.sink_id::character varying(50) AS direction_id,
209
+ date_trunc('hour'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision)) + (date_part('minute'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision))::integer / 15)::double precision * '00:15:00'::interval AS measured_from,
210
+ date_trunc('hour'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision)) + (date_part('minute'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision))::integer / 15)::double precision * '00:15:00'::interval + '00:15:00'::interval AS measured_to,
211
+ sum(flow_measurements.value) AS value,
212
+ count(flow_measurements.value) AS count_n,
213
+ 3 AS quantity
214
+ FROM flow.flow_measurements
215
+ WHERE ((flow_measurements.cube_id::character varying(50)::text, flow_measurements.sink_id::character varying(50)::text) IN ( SELECT DISTINCT pedestrians_directions_api.cube_id AS location_id,
216
+ pedestrians_directions_api.direction_id
217
+ FROM flow.pedestrians_directions_api)) AND flow_measurements.category::text = 'pedestrian'::text
218
+ GROUP BY (flow_measurements.cube_id::character varying(50)), (flow_measurements.sink_id::character varying(50)), (date_trunc('hour'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision)) + (date_part('minute'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision))::integer / 15)::double precision * '00:15:00'::interval), (date_trunc('hour'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision)) + (date_part('minute'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision))::integer / 15)::double precision * '00:15:00'::interval + '00:15:00'::interval)
219
+ ORDER BY (date_trunc('hour'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision)) + (date_part('minute'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision))::integer / 15)::double precision * '00:15:00'::interval), (flow_measurements.cube_id::character varying(50)), (flow_measurements.sink_id::character varying(50))
220
+ ), measurements AS (
221
+ SELECT wifi.location_id,
222
+ wifi.direction_id,
223
+ wifi.measured_from,
224
+ wifi.measured_to,
225
+ wifi.value,
226
+ wifi.count_n,
227
+ wifi.quantity
228
+ FROM wifi
229
+ UNION ALL
230
+ SELECT pyro.location_id,
231
+ pyro.direction_id,
232
+ pyro.measured_from,
233
+ pyro.measured_to,
234
+ pyro.value,
235
+ pyro.count_n,
236
+ pyro.quantity
237
+ FROM pyro
238
+ UNION ALL
239
+ SELECT flow.location_id,
240
+ flow.direction_id,
241
+ flow.measured_from,
242
+ flow.measured_to,
243
+ flow.value,
244
+ flow.count_n,
245
+ flow.quantity
246
+ FROM flow
247
+ )
248
+ SELECT measurements.measured_from,
249
+ measurements.measured_to,
250
+ pda.location_id::character varying(50) AS location_id,
251
+ measurements.direction_id,
252
+ measurements.value,
253
+ CASE
254
+ WHEN (measurements.count_n::numeric / measurements.quantity::numeric) > 1::numeric THEN 1::numeric
255
+ ELSE measurements.count_n::numeric / measurements.quantity::numeric
256
+ END AS quality
257
+ FROM measurements
258
+ LEFT JOIN flow.pedestrians_directions_api pda ON measurements.direction_id::text = pda.direction_id::text;
259
+
260
+
261
+ -- analytic.v_pedestrians_detections_daily source
262
+
263
+ CREATE OR REPLACE VIEW analytic.v_pedestrians_detections_daily
264
+ AS WITH wifi AS (
265
+ SELECT pedestrians_wifi.location_id AS locations_id,
266
+ pedestrians_wifi.direction_id AS directions_id,
267
+ pedestrians_wifi.measured_from::date AS measured_from,
268
+ sum(pedestrians_wifi.value) AS value,
269
+ count(pedestrians_wifi.value) AS count_n,
270
+ count(pedestrians_wifi.value)::numeric / 288::numeric AS quality_ratio
271
+ FROM flow.pedestrians_wifi
272
+ GROUP BY pedestrians_wifi.location_id, pedestrians_wifi.direction_id, (pedestrians_wifi.measured_from::date)
273
+ ), pyro AS (
274
+ SELECT cd.locations_id,
275
+ lg.first_dir AS directions_id,
276
+ to_timestamp((cd.measured_from / 1000)::double precision)::date AS measured_from,
277
+ sum(cd.value) AS value,
278
+ count(cd.value) / count(DISTINCT cd.directions_id) AS count_n,
279
+ count(cd.value)::numeric / 96::numeric / count(DISTINCT cd.directions_id)::numeric AS quality_ratio
280
+ FROM flow.counters_detections cd
281
+ LEFT JOIN ( SELECT pedestrians_locations_gates.direction_id,
282
+ pedestrians_locations_gates.direction_type,
283
+ min(pedestrians_locations_gates.direction_id::text) OVER (PARTITION BY pedestrians_locations_gates.cube_id, pedestrians_locations_gates.direction_type) AS first_dir
284
+ FROM analytic.pedestrians_locations_gates) lg ON cd.directions_id::text = lg.direction_id::text
285
+ WHERE cd.category::text = 'pedestrian'::text AND (cd.directions_id::text IN ( SELECT DISTINCT pedestrians_locations_gates.direction_id
286
+ FROM analytic.pedestrians_locations_gates))
287
+ GROUP BY cd.locations_id, lg.first_dir, (to_timestamp((cd.measured_from / 1000)::double precision)::date)
288
+ ), flow AS (
289
+ SELECT flow_measurements.cube_id::character varying(50) AS location_id,
290
+ flow_measurements.sink_id::character varying(50) AS direction_id,
291
+ to_timestamp((flow_measurements.start_timestamp / 1000)::double precision)::date AS measured_from,
292
+ sum(flow_measurements.value) AS value,
293
+ count(flow_measurements.value) AS count_n,
294
+ count(flow_measurements.value)::numeric / 288::numeric AS quality_ratio
295
+ FROM flow.flow_measurements
296
+ WHERE ((flow_measurements.cube_id::character varying(50)::text, flow_measurements.sink_id::character varying(50)::text) IN ( SELECT DISTINCT pedestrians_locations_gates.cube_id AS location_id,
297
+ pedestrians_locations_gates.direction_id
298
+ FROM analytic.pedestrians_locations_gates)) AND flow_measurements.category::text = 'pedestrian'::text
299
+ GROUP BY (flow_measurements.cube_id::character varying(50)), (flow_measurements.sink_id::character varying(50)), (to_timestamp((flow_measurements.start_timestamp / 1000)::double precision)::date)
300
+ ORDER BY (to_timestamp((flow_measurements.start_timestamp / 1000)::double precision)::date), (flow_measurements.cube_id::character varying(50)) DESC, (flow_measurements.sink_id::character varying(50))
301
+ ), measurements AS (
302
+ SELECT pyro.locations_id,
303
+ pyro.directions_id,
304
+ pyro.measured_from,
305
+ pyro.value,
306
+ pyro.count_n,
307
+ pyro.quality_ratio
308
+ FROM pyro
309
+ UNION ALL
310
+ SELECT flow.location_id,
311
+ flow.direction_id,
312
+ flow.measured_from,
313
+ flow.value,
314
+ flow.count_n,
315
+ flow.quality_ratio
316
+ FROM flow
317
+ UNION ALL
318
+ SELECT wifi.locations_id,
319
+ wifi.directions_id,
320
+ wifi.measured_from,
321
+ wifi.value,
322
+ wifi.count_n,
323
+ wifi.quality_ratio
324
+ FROM wifi
325
+ ), calendar AS (
326
+ SELECT generate_series(min(measurements.measured_from)::timestamp with time zone, max(measurements.measured_from)::timestamp with time zone, '1 day'::interval) AS calendar
327
+ FROM measurements
328
+ ), classes AS (
329
+ SELECT calendar.calendar,
330
+ m_1.location_id,
331
+ m_1.direction_id
332
+ FROM calendar
333
+ JOIN ( SELECT DISTINCT measurements.locations_id::character varying(50) AS location_id,
334
+ measurements.directions_id::character varying(50) AS direction_id
335
+ FROM measurements) m_1 ON true
336
+ )
337
+ SELECT c.calendar,
338
+ c.location_id,
339
+ c.direction_id,
340
+ concat(c.location_id, '-', c.direction_id) AS compound_id,
341
+ COALESCE(m.value, 0::bigint) AS value,
342
+ COALESCE(m.count_n, 0::bigint) AS count_n,
343
+ COALESCE(m.quality_ratio, 0::numeric) AS quality_ratio,
344
+ CASE
345
+ WHEN c.calendar < ll.measurement_start OR c.calendar > ll.measurement_end THEN 4
346
+ WHEN COALESCE(m.quality_ratio, 0::numeric) = 0::numeric THEN 3
347
+ WHEN COALESCE(m.quality_ratio, 0::numeric) < 0.9 THEN 2
348
+ WHEN COALESCE(m.quality_ratio, 0::numeric) > 0.9 AND COALESCE(m.quality_ratio, 0::numeric) < 1::numeric THEN 1
349
+ WHEN COALESCE(m.quality_ratio, 0::numeric) >= 1::numeric THEN 0
350
+ ELSE NULL::integer
351
+ END AS quality_code,
352
+ CASE
353
+ WHEN c.calendar < ll.measurement_start OR c.calendar > ll.measurement_end THEN 'Nenainstalovaná technologie'::text
354
+ WHEN COALESCE(m.quality_ratio, 0::numeric) = 0::numeric THEN 'Bez dat (0%)'::text
355
+ WHEN COALESCE(m.quality_ratio, 0::numeric) < 0.9 THEN 'Částečná data (<90%)'::text
356
+ WHEN COALESCE(m.quality_ratio, 0::numeric) > 0.9 AND COALESCE(m.quality_ratio, 0::numeric) < 1::numeric THEN 'Nekompletní data (>90%)'::text
357
+ WHEN COALESCE(m.quality_ratio, 0::numeric) >= 1::numeric THEN 'Kompletní data (100%)'::text
358
+ ELSE NULL::text
359
+ END AS quality_status
360
+ FROM classes c
361
+ LEFT JOIN measurements m ON c.calendar = m.measured_from AND c.location_id::text = m.locations_id::text AND c.direction_id::text = m.directions_id
362
+ LEFT JOIN analytic.pedestrians_locations_list ll ON c.location_id::text = ll.cube_id::text;
363
+
364
+
365
+ -- analytic.v_pedestrians_flow_quality source
366
+
367
+ CREATE OR REPLACE VIEW analytic.v_pedestrians_flow_quality
368
+ AS WITH timeline_category AS (
369
+ SELECT DISTINCT fs.cube_id,
370
+ fs.id AS sink_id,
371
+ timeline."timestamp"
372
+ FROM flow.flow_sinks fs
373
+ LEFT JOIN ( SELECT generate_series(date_trunc('month'::text, CURRENT_DATE - '180 days'::interval)::timestamp with time zone, date_trunc('hour'::text, CURRENT_DATE::timestamp with time zone), '01:00:00'::interval) AS "timestamp") timeline ON true
374
+ ), base_table AS (
375
+ SELECT date_trunc('hour'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision)) AS start_timestamp,
376
+ flow_measurements.cube_id,
377
+ flow_measurements.sink_id,
378
+ flow_measurements.category,
379
+ count(flow_measurements.cube_id) AS count
380
+ FROM flow.flow_measurements
381
+ WHERE flow_measurements.start_timestamp::double precision >= (1000::double precision * date_part('epoch'::text, CURRENT_DATE - '210 days'::interval))
382
+ GROUP BY (date_trunc('hour'::text, to_timestamp((flow_measurements.start_timestamp / 1000)::double precision))), flow_measurements.cube_id, flow_measurements.sink_id, flow_measurements.category
383
+ ), real_nrow AS (
384
+ SELECT base_table.start_timestamp,
385
+ base_table.cube_id,
386
+ base_table.sink_id,
387
+ sum(base_table.count) AS n_row,
388
+ sum(base_table.count) FILTER (WHERE base_table.category::text = 'pedestrian'::text) AS n_row_pedestrian
389
+ FROM base_table
390
+ GROUP BY base_table.start_timestamp, base_table.cube_id, base_table.sink_id
391
+ ), expected_nrow AS (
392
+ SELECT base_table.cube_id,
393
+ base_table.sink_id,
394
+ count(DISTINCT base_table.category) * 12 AS expected_nrow,
395
+ 12 AS expected_nrow_pedestrian
396
+ FROM base_table
397
+ WHERE base_table.start_timestamp >= (CURRENT_DATE - '30 days'::interval)
398
+ GROUP BY base_table.cube_id, base_table.sink_id
399
+ )
400
+ SELECT t."timestamp",
401
+ date_trunc('month'::text, t."timestamp")::date AS month,
402
+ t.cube_id,
403
+ t.sink_id,
404
+ concat(t.cube_id, ' - ', t.sink_id) AS cube_sink,
405
+ COALESCE(r.n_row, 0::bigint::numeric) AS n_row,
406
+ COALESCE(r.n_row_pedestrian, 0::bigint::numeric) AS n_row_pedestrian,
407
+ er.expected_nrow,
408
+ er.expected_nrow_pedestrian
409
+ FROM timeline_category t
410
+ LEFT JOIN real_nrow r ON t."timestamp" = r.start_timestamp AND t.cube_id = r.cube_id AND t.sink_id = r.sink_id
411
+ LEFT JOIN expected_nrow er ON t.cube_id = er.cube_id AND t.sink_id = er.sink_id;
412
+
413
+ -- analytic.v_flow_quality source
414
+
415
+ DROP VIEW IF EXISTS analytic.v_flow_quality
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,14 @@
1
+ import { BaseWorker } from "@golemio/core/dist/integration-engine/workers";
2
+ export declare class CountersWorker extends BaseWorker {
3
+ private dataSourceEcoCounter;
4
+ private dataSourceEcoCounterMeasurements;
5
+ private ecoCounterTransformation;
6
+ private ecoCounterMeasurementsTransformation;
7
+ private queuePrefix;
8
+ private countersLocationsModel;
9
+ private countersDirectionsModel;
10
+ private countersDetectionsModel;
11
+ constructor();
12
+ refreshEcoCounterDataInDB: (msg: any) => Promise<void>;
13
+ updateEcoCounter: (msg: any) => Promise<void>;
14
+ }
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.CountersWorker = void 0;
16
+ const index_1 = require("../schema-definitions/index");
17
+ const config_1 = require("@golemio/core/dist/integration-engine/config");
18
+ const datasources_1 = require("@golemio/core/dist/integration-engine/datasources");
19
+ const models_1 = require("@golemio/core/dist/integration-engine/models");
20
+ const workers_1 = require("@golemio/core/dist/integration-engine/workers");
21
+ const golemio_validator_1 = require("@golemio/core/dist/shared/golemio-validator");
22
+ const moment_timezone_1 = __importDefault(require("@golemio/core/dist/shared/moment-timezone"));
23
+ const EcoCounterMeasurementsTransformation_1 = require("./transformations/EcoCounterMeasurementsTransformation");
24
+ const EcoCounterTransformation_1 = require("./transformations/EcoCounterTransformation");
25
+ class CountersWorker extends workers_1.BaseWorker {
26
+ constructor() {
27
+ super();
28
+ this.refreshEcoCounterDataInDB = (msg) => __awaiter(this, void 0, void 0, function* () {
29
+ const data = yield this.dataSourceEcoCounter.getAll();
30
+ const transformedData = yield this.ecoCounterTransformation.transform(data);
31
+ yield this.countersLocationsModel.save(transformedData.locationsPedestrians);
32
+ yield this.countersDirectionsModel.save(transformedData.directionsPedestrians);
33
+ const promisesPeds = transformedData.directionsPedestrians.map((p) => {
34
+ this.sendMessageToExchange("workers." + this.queuePrefix + ".updateEcoCounter", JSON.stringify({
35
+ category: "pedestrian",
36
+ directions_id: p.id,
37
+ id: p.vendor_id,
38
+ locations_id: p.locations_id,
39
+ }));
40
+ });
41
+ yield Promise.all(promisesPeds);
42
+ });
43
+ this.updateEcoCounter = (msg) => __awaiter(this, void 0, void 0, function* () {
44
+ const inputData = JSON.parse(msg.content.toString());
45
+ const locationsId = inputData.locations_id;
46
+ const directionsId = inputData.directions_id;
47
+ const category = inputData.category;
48
+ const id = inputData.id;
49
+ // EcoCounter API is actually working with local Europe/Prague time, not ISO!!!
50
+ // so we have to send local time to request.
51
+ // Furthermore, the returned dates are START of the measurement interval, so if we want measurements
52
+ // from interval between 06:00 and 07:00 UTC (which is local 07:00 - 08:00), we have to send parameters
53
+ // from=07:00 and to=07:45, because it returns all the measurements where from and to parameters are INCLUDED.
54
+ const now = moment_timezone_1.default.utc().tz("Europe/Prague");
55
+ const step = 15;
56
+ const remainder = now.minute() % step;
57
+ // rounded to nearest next 15 minutes
58
+ const nowRounded = now.clone().subtract(remainder, "minutes").seconds(0).milliseconds(0);
59
+ const strTo = nowRounded.clone().subtract(step, "minutes").format("YYYY-MM-DDTHH:mm:ss");
60
+ const strFrom = nowRounded.clone().subtract(72, "hours").format("YYYY-MM-DDTHH:mm:ss");
61
+ let url = config_1.config.datasources.BicycleCountersEcoCounterMeasurements;
62
+ url = url.replace(":id", id);
63
+ url = url.replace(":from", strFrom);
64
+ url = url.replace(":to", strTo);
65
+ url = url.replace(":step", `${step}m`);
66
+ url = url.replace(":complete", "true");
67
+ this.dataSourceEcoCounterMeasurements.setProtocolStrategy(new datasources_1.HTTPProtocolStrategy({
68
+ headers: {
69
+ Authorization: `Bearer ${config_1.config.datasources.CountersEcoCounterTokens.OICT}`,
70
+ },
71
+ json: true,
72
+ method: "GET",
73
+ url,
74
+ }));
75
+ const data = yield this.dataSourceEcoCounterMeasurements.getAll();
76
+ // pedestrians
77
+ if (category === "pedestrian") {
78
+ yield this.countersDetectionsModel.saveBySqlFunction((yield this.ecoCounterMeasurementsTransformation.transform(data)).map((x) => {
79
+ x.directions_id = directionsId;
80
+ x.locations_id = locationsId;
81
+ x.category = "pedestrian";
82
+ return x;
83
+ }), ["locations_id", "directions_id", "measured_from", "category"]);
84
+ }
85
+ });
86
+ const parser = new datasources_1.JSONDataTypeStrategy({ resultsPath: "" });
87
+ parser.setFilter((item) => item.counter !== null);
88
+ this.dataSourceEcoCounter = new datasources_1.DataSource(index_1.Counters.ecoCounter.name + "DataSource", new datasources_1.HTTPProtocolStrategy({
89
+ headers: {
90
+ Authorization: `Bearer ${config_1.config.datasources.CountersEcoCounterTokens.OICT}`,
91
+ },
92
+ method: "GET",
93
+ url: config_1.config.datasources.BicycleCountersEcoCounter,
94
+ }), parser, new golemio_validator_1.JSONSchemaValidator(index_1.Counters.ecoCounter.name + "Validator", index_1.Counters.ecoCounter.datasourceJsonSchema));
95
+ this.dataSourceEcoCounterMeasurements = new datasources_1.DataSource(index_1.Counters.ecoCounter.name + "MeasurementsDataSource", undefined, new datasources_1.JSONDataTypeStrategy({ resultsPath: "" }), new golemio_validator_1.JSONSchemaValidator(index_1.Counters.ecoCounter.name + "MeasurementsDataSource", index_1.Counters.ecoCounter.measurementsDatasourceJsonSchema));
96
+ this.ecoCounterTransformation = new EcoCounterTransformation_1.EcoCounterTransformation();
97
+ this.ecoCounterMeasurementsTransformation = new EcoCounterMeasurementsTransformation_1.EcoCounterMeasurementsTransformation();
98
+ this.countersLocationsModel = new models_1.PostgresModel(index_1.Counters.locations.name + "Model", {
99
+ outputSequelizeAttributes: index_1.Counters.locations.outputSequelizeAttributes,
100
+ pgTableName: index_1.Counters.locations.pgTableName,
101
+ pgSchema: index_1.Counters.pgSchema,
102
+ savingType: "insertOrUpdate",
103
+ }, new golemio_validator_1.JSONSchemaValidator(index_1.Counters.locations.name + "ModelValidator", index_1.Counters.locations.outputJsonSchemaObject));
104
+ this.countersDirectionsModel = new models_1.PostgresModel(index_1.Counters.directions.name + "Model", {
105
+ outputSequelizeAttributes: index_1.Counters.directions.outputSequelizeAttributes,
106
+ pgTableName: index_1.Counters.directions.pgTableName,
107
+ pgSchema: index_1.Counters.pgSchema,
108
+ savingType: "insertOrUpdate",
109
+ }, new golemio_validator_1.JSONSchemaValidator(index_1.Counters.directions.name + "ModelValidator", index_1.Counters.directions.outputJsonSchemaObject));
110
+ this.countersDetectionsModel = new models_1.PostgresModel(index_1.Counters.detections.name + "Model", {
111
+ outputSequelizeAttributes: index_1.Counters.detections.outputSequelizeAttributes,
112
+ pgTableName: index_1.Counters.detections.pgTableName,
113
+ pgSchema: index_1.Counters.pgSchema,
114
+ savingType: "insertOrUpdate",
115
+ }, new golemio_validator_1.JSONSchemaValidator(index_1.Counters.detections.name + "ModelValidator", index_1.Counters.detections.outputJsonSchemaObject));
116
+ this.queuePrefix = config_1.config.RABBIT_EXCHANGE_NAME + "." + "counters";
117
+ }
118
+ }
119
+ exports.CountersWorker = CountersWorker;
120
+ //# sourceMappingURL=CountersWorker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CountersWorker.js","sourceRoot":"","sources":["../../src/integration-engine/CountersWorker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uDAAsC;AACtC,yEAAsE;AACtE,mFAA2H;AAC3H,yEAA6E;AAC7E,2EAA2E;AAC3E,mFAAkF;AAClF,gGAA+D;AAC/D,iHAA8G;AAC9G,yFAAsF;AAEtF,MAAa,cAAe,SAAQ,oBAAU;IAa1C;QACI,KAAK,EAAE,CAAC;QA8DL,8BAAyB,GAAG,CAAO,GAAQ,EAAiB,EAAE;YACjE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,MAAM,EAAE,CAAC;YAEtD,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAE5E,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,eAAe,CAAC,oBAAoB,CAAC,CAAC;YAC7E,MAAM,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC;YAE/E,MAAM,YAAY,GAAG,eAAe,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;gBACjE,IAAI,CAAC,qBAAqB,CACtB,UAAU,GAAG,IAAI,CAAC,WAAW,GAAG,mBAAmB,EACnD,IAAI,CAAC,SAAS,CAAC;oBACX,QAAQ,EAAE,YAAY;oBACtB,aAAa,EAAE,CAAC,CAAC,EAAE;oBACnB,EAAE,EAAE,CAAC,CAAC,SAAS;oBACf,YAAY,EAAE,CAAC,CAAC,YAAY;iBAC/B,CAAC,CACL,CAAC;YACN,CAAC,CAAC,CAAC;YACH,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC,CAAA,CAAC;QAEK,qBAAgB,GAAG,CAAO,GAAQ,EAAiB,EAAE;YACxD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;YACrD,MAAM,WAAW,GAAG,SAAS,CAAC,YAAY,CAAC;YAC3C,MAAM,YAAY,GAAG,SAAS,CAAC,aAAa,CAAC;YAC7C,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;YACpC,MAAM,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;YAExB,+EAA+E;YAC/E,4CAA4C;YAC5C,oGAAoG;YACpG,uGAAuG;YACvG,8GAA8G;YAC9G,MAAM,GAAG,GAAG,yBAAM,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;YAC7C,MAAM,IAAI,GAAG,EAAE,CAAC;YAChB,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;YACtC,qCAAqC;YACrC,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;YACzF,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;YACzF,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;YAEvF,IAAI,GAAG,GAAG,eAAM,CAAC,WAAW,CAAC,qCAAqC,CAAC;YACnE,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC7B,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACpC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAChC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,CAAC,CAAC;YACvC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;YAEvC,IAAI,CAAC,gCAAgC,CAAC,mBAAmB,CACrD,IAAI,kCAAoB,CAAC;gBACrB,OAAO,EAAE;oBACL,aAAa,EAAE,UAAU,eAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,IAAI,EAAE;iBAC9E;gBACD,IAAI,EAAE,IAAI;gBACV,MAAM,EAAE,KAAK;gBACb,GAAG;aACN,CAAC,CACL,CAAC;YAEF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,gCAAgC,CAAC,MAAM,EAAE,CAAC;YAElE,cAAc;YACd,IAAI,QAAQ,KAAK,YAAY,EAAE;gBAC3B,MAAM,IAAI,CAAC,uBAAuB,CAAC,iBAAiB,CAChD,CACI,MAAM,IAAI,CAAC,oCAAoC,CAAC,SAAS,CAAC,IAAI,CAAC,CAClE,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE;oBACb,CAAC,CAAC,aAAa,GAAG,YAAY,CAAC;oBAC/B,CAAC,CAAC,YAAY,GAAG,WAAW,CAAC;oBAC7B,CAAC,CAAC,QAAQ,GAAG,YAAY,CAAC;oBAC1B,OAAO,CAAC,CAAC;gBACb,CAAC,CAAC,EACF,CAAC,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,UAAU,CAAC,CACjE,CAAC;aACL;QACL,CAAC,CAAA,CAAC;QAxIE,MAAM,MAAM,GAAG,IAAI,kCAAoB,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAC;QAC7D,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,oBAAoB,GAAG,IAAI,wBAAU,CACtC,gBAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,YAAY,EACvC,IAAI,kCAAoB,CAAC;YACrB,OAAO,EAAE;gBACL,aAAa,EAAE,UAAU,eAAM,CAAC,WAAW,CAAC,wBAAwB,CAAC,IAAI,EAAE;aAC9E;YACD,MAAM,EAAE,KAAK;YACb,GAAG,EAAE,eAAM,CAAC,WAAW,CAAC,yBAAyB;SACpD,CAAC,EACF,MAAM,EACN,IAAI,uCAAmB,CAAC,gBAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,WAAW,EAAE,gBAAQ,CAAC,UAAU,CAAC,oBAAoB,CAAC,CAC5G,CAAC;QACF,IAAI,CAAC,gCAAgC,GAAG,IAAI,wBAAU,CAClD,gBAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,wBAAwB,EACnD,SAAgB,EAChB,IAAI,kCAAoB,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,EAC7C,IAAI,uCAAmB,CACnB,gBAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,wBAAwB,EACnD,gBAAQ,CAAC,UAAU,CAAC,gCAAgC,CACvD,CACJ,CAAC;QACF,IAAI,CAAC,wBAAwB,GAAG,IAAI,mDAAwB,EAAE,CAAC;QAC/D,IAAI,CAAC,oCAAoC,GAAG,IAAI,2EAAoC,EAAE,CAAC;QAEvF,IAAI,CAAC,sBAAsB,GAAG,IAAI,sBAAa,CAC3C,gBAAQ,CAAC,SAAS,CAAC,IAAI,GAAG,OAAO,EACjC;YACI,yBAAyB,EAAE,gBAAQ,CAAC,SAAS,CAAC,yBAAyB;YACvE,WAAW,EAAE,gBAAQ,CAAC,SAAS,CAAC,WAAW;YAC3C,QAAQ,EAAE,gBAAQ,CAAC,QAAQ;YAC3B,UAAU,EAAE,gBAAgB;SAC/B,EACD,IAAI,uCAAmB,CAAC,gBAAQ,CAAC,SAAS,CAAC,IAAI,GAAG,gBAAgB,EAAE,gBAAQ,CAAC,SAAS,CAAC,sBAAsB,CAAC,CACjH,CAAC;QACF,IAAI,CAAC,uBAAuB,GAAG,IAAI,sBAAa,CAC5C,gBAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,OAAO,EAClC;YACI,yBAAyB,EAAE,gBAAQ,CAAC,UAAU,CAAC,yBAAyB;YACxE,WAAW,EAAE,gBAAQ,CAAC,UAAU,CAAC,WAAW;YAC5C,QAAQ,EAAE,gBAAQ,CAAC,QAAQ;YAC3B,UAAU,EAAE,gBAAgB;SAC/B,EACD,IAAI,uCAAmB,CAAC,gBAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,gBAAgB,EAAE,gBAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC,CACnH,CAAC;QACF,IAAI,CAAC,uBAAuB,GAAG,IAAI,sBAAa,CAC5C,gBAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,OAAO,EAClC;YACI,yBAAyB,EAAE,gBAAQ,CAAC,UAAU,CAAC,yBAAyB;YACxE,WAAW,EAAE,gBAAQ,CAAC,UAAU,CAAC,WAAW;YAC5C,QAAQ,EAAE,gBAAQ,CAAC,QAAQ;YAC3B,UAAU,EAAE,gBAAgB;SAC/B,EACD,IAAI,uCAAmB,CAAC,gBAAQ,CAAC,UAAU,CAAC,IAAI,GAAG,gBAAgB,EAAE,gBAAQ,CAAC,UAAU,CAAC,sBAAsB,CAAC,CACnH,CAAC;QAEF,IAAI,CAAC,WAAW,GAAG,eAAM,CAAC,oBAAoB,GAAG,GAAG,GAAG,UAAU,CAAC;IACtE,CAAC;CA+EJ;AAzJD,wCAyJC"}
@@ -33,12 +33,12 @@ class FlowWorker extends workers_1.BaseWorker {
33
33
  this.refreshMatViewPedestriansDetectApi = () => __awaiter(this, void 0, void 0, function* () {
34
34
  try {
35
35
  const connection = connectors_1.PostgresConnector.getConnection();
36
- yield connection.query(`REFRESH MATERIALIZED VIEW "public"."mv_pedestrians_detections_api"`, {
36
+ yield connection.query(`CALL "${index_1.Flow.pgSchema}".update_detections_data()`, {
37
37
  type: sequelize_1.default.QueryTypes.SELECT,
38
38
  });
39
39
  }
40
40
  catch (err) {
41
- throw new golemio_errors_1.CustomError("Error while REFRESH MATERIALIZED VIEW.", true, this.constructor.name, 5050, err);
41
+ throw new golemio_errors_1.CustomError("Error while aggregating flow data.", true, this.constructor.name, 5050, err);
42
42
  }
43
43
  });
44
44
  this.getHistoryIntervalFromMsg = (msg) => {
@@ -399,21 +399,25 @@ class FlowWorker extends workers_1.BaseWorker {
399
399
  };
400
400
  this.flowMeasurementModel = new models_1.PostgresModel(index_1.Flow.detections.name + "Model", {
401
401
  outputSequelizeAttributes: index_1.Flow.detections.outputSequelizeAttributes,
402
+ pgSchema: index_1.Flow.pgSchema,
402
403
  pgTableName: index_1.Flow.detections.pgTableName,
403
404
  savingType: "insertOrUpdate",
404
405
  }, null);
405
406
  this.flowODMeasurementModel = new models_1.PostgresModel(index_1.Flow.detectionsOD.name + "Model", {
406
407
  outputSequelizeAttributes: index_1.Flow.detectionsOD.outputSequelizeAttributes,
408
+ pgSchema: index_1.Flow.pgSchema,
407
409
  pgTableName: index_1.Flow.detectionsOD.pgTableName,
408
410
  savingType: "insertOrUpdate",
409
411
  }, null);
410
412
  this.flowCubesModel = new models_1.PostgresModel(index_1.Flow.cubes.name + "Model", {
411
413
  outputSequelizeAttributes: index_1.Flow.cubes.outputSequelizeAttributes,
414
+ pgSchema: index_1.Flow.pgSchema,
412
415
  pgTableName: index_1.Flow.cubes.pgTableName,
413
416
  savingType: "insertOrUpdate",
414
417
  }, null);
415
418
  this.flowSinksModel = new models_1.PostgresModel(index_1.Flow.sinks.name + "Model", {
416
419
  outputSequelizeAttributes: index_1.Flow.sinks.outputSequelizeAttributes,
420
+ pgSchema: index_1.Flow.pgSchema,
417
421
  pgTableName: index_1.Flow.sinks.pgTableName,
418
422
  savingType: "insertOrUpdate",
419
423
  }, null);