From 6a0457076d836431ea8cea39a94020412e373027 Mon Sep 17 00:00:00 2001 From: dfcarvajal Date: Sat, 20 Dec 2025 22:31:11 +0100 Subject: [PATCH] Primeros modelados --- flows.json | 524 +++++++++++++++++++++++++++++++++++++++++++++++- flows_cred.json | 4 +- 2 files changed, 524 insertions(+), 4 deletions(-) diff --git a/flows.json b/flows.json index b79c1f8..10c9720 100644 --- a/flows.json +++ b/flows.json @@ -10,7 +10,23 @@ { "id": "f511dd2230a153e7", "type": "tab", - "label": "Flujo 1", + "label": "Grafíco", + "disabled": false, + "info": "", + "env": [] + }, + { + "id": "230815bb0628a63e", + "type": "tab", + "label": "Modelo", + "disabled": false, + "info": "", + "env": [] + }, + { + "id": "56fb69eb622c3f3b", + "type": "tab", + "label": "Mapa", "disabled": false, "info": "", "env": [] @@ -40,6 +56,95 @@ "password": "tfmuocdfcarvajal", "passwordFieldType": "str" }, + { + "id": "3afa9de4406d30d8", + "type": "ui-base", + "name": "My Dashboard", + "path": "/dashboard", + "appIcon": "", + "includeClientData": true, + "acceptsClientConfig": [ + "ui-notification", + "ui-control" + ], + "showPathInSidebar": false, + "headerContent": "page", + "navigationStyle": "default", + "titleBarStyle": "default", + "showReconnectNotification": true, + "notificationDisplayTime": 1, + "showDisconnectNotification": true, + "allowInstall": false + }, + { + "id": "c81bf3ad6297e603", + "type": "ui-theme", + "name": "Default Theme", + "colors": { + "surface": "#ffffff", + "primary": "#0094CE", + "bgPage": "#eeeeee", + "groupBg": "#ffffff", + "groupOutline": "#cccccc" + }, + "sizes": { + "density": "default", + "pagePadding": "12px", + "groupGap": "12px", + "groupBorderRadius": "4px", + "widgetGap": "12px" + } + }, + { + "id": "b332967d63ddbdfe", + "type": "ui-page", + "name": "Page 1", + "ui": "3afa9de4406d30d8", + "path": "/page1", + "icon": "home", + "layout": "flex", + "theme": "c81bf3ad6297e603", + "breakpoints": [ + { + "name": "Default", + "px": "0", + "cols": "3" + }, + { + "name": "Tablet", + "px": "576", + "cols": "6" + }, + { + "name": "Small Desktop", + "px": "768", + "cols": "9" + }, + { + "name": "Desktop", + "px": "1024", + "cols": "12" + } + ], + "order": 1, + "className": "", + "visible": "true", + "disabled": "false" + }, + { + "id": "f8afeee042444067", + "type": "ui-group", + "name": "Visualizador", + "page": "b332967d63ddbdfe", + "width": "8", + "height": "8", + "order": 1, + "showTitle": true, + "className": "", + "visible": "true", + "disabled": "false", + "groupType": "default" + }, { "id": "3005f842c2ae482e", "type": "inject", @@ -480,7 +585,7 @@ "type": "postgresql", "z": "f511dd2230a153e7", "name": "Consulta h3 con geojson", - "query": "SELECT \n h3_lat_lng_to_cell(point(ST_Y(geom), ST_X(geom)), 9) AS h3,\n COUNT(*) AS total\nFROM servicios_geo\nGROUP BY h3;", + "query": "SELECT \n h3_lat_lng_to_cell(point(ST_Y(geom), ST_X(geom)), 8) AS h3,\n COUNT(*) AS total\nFROM servicios_geo\nGROUP BY h3;", "postgreSQLConfig": "748b5921246ec468", "split": false, "rowsPerMsg": 1, @@ -625,7 +730,7 @@ "type": "postgresql", "z": "f511dd2230a153e7", "name": "Consultar solo 500", - "query": "SELECT *\nFROM servicios_geo\nORDER BY id_servicio\nLIMIT 5", + "query": "SELECT *\nFROM servicios_geo\nWHERE tipo_servicio != 'Base'\nLIMIT 500;", "postgreSQLConfig": "748b5921246ec468", "split": false, "rowsPerMsg": 1, @@ -683,5 +788,418 @@ "x": 960, "y": 340, "wires": [] + }, + { + "id": "c7c7d9aedc600352", + "type": "postgresql", + "z": "230815bb0628a63e", + "name": "Generamos la vista básica de H3 con 8", + "query": "-- 1.1 Vista básica con h3 (nivel 8)\nCREATE OR REPLACE VIEW vw_servicios_h3 AS\nSELECT\n id,\n id_servicio,\n fecha_entrada,\n fecha_servicio,\n codigo_grua,\n tipo_servicio,\n geom,\n h3_lat_lng_to_cell(point(ST_Y(geom), ST_X(geom)), 8) AS h3,\n EXTRACT(HOUR FROM fecha_servicio AT TIME ZONE 'UTC')::int AS hour,\n EXTRACT(DOW FROM fecha_servicio AT TIME ZONE 'UTC')::int AS dow, -- 0 = Sunday\n CASE WHEN tipo_servicio = 'Requerimiento nulo' THEN 1 ELSE 0 END AS is_nulo\nFROM servicios_geo;", + "postgreSQLConfig": "748b5921246ec468", + "split": false, + "rowsPerMsg": 1, + "outputs": 1, + "x": 360, + "y": 60, + "wires": [ + [ + "eab6c7a9df1e6c8c" + ] + ] + }, + { + "id": "e65ea3eb95cf6c9f", + "type": "inject", + "z": "230815bb0628a63e", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 110, + "y": 60, + "wires": [ + [ + "c7c7d9aedc600352" + ] + ] + }, + { + "id": "eab6c7a9df1e6c8c", + "type": "debug", + "z": "230815bb0628a63e", + "name": "debug 4", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 940, + "y": 60, + "wires": [] + }, + { + "id": "a1c78ddc8ef1f1fd", + "type": "postgresql", + "z": "230815bb0628a63e", + "name": "Generamos el nivel de demanda por hora y día de la semana", + "query": "-- Conteo por (dia de la semana y hora)\nCREATE OR REPLACE VIEW vw_total_by_hour_dow AS\nSELECT\n dow,\n hour,\n COUNT(*) AS total_hour_dow\nFROM vw_servicios_h3\nGROUP BY dow, hour\nORDER BY dow, hour;\n\n--- Calcular valores para día de la semana y hora, asignamos un demand_level\nCREATE OR REPLACE VIEW vw_hour_levels_dow AS\nWITH counts AS (\n SELECT dow, hour, total_hour_dow\n FROM vw_total_by_hour_dow\n),\npercentiles_per_dow AS (\n SELECT\n dow,\n percentile_cont(0.3333) WITHIN GROUP (ORDER BY total_hour_dow) AS q1,\n percentile_cont(0.6666) WITHIN GROUP (ORDER BY total_hour_dow) AS q2\n FROM counts\n GROUP BY dow\n)\nSELECT\n c.dow,\n c.hour,\n c.total_hour_dow,\n CASE\n WHEN c.total_hour_dow <= p.q1 THEN 'baja'\n WHEN c.total_hour_dow <= p.q2 THEN 'media'\n ELSE 'alta'\n END AS demand_level\nFROM counts c\nJOIN percentiles_per_dow p ON p.dow = c.dow\nORDER BY c.dow, c.hour;", + "postgreSQLConfig": "748b5921246ec468", + "split": false, + "rowsPerMsg": 1, + "outputs": 1, + "x": 420, + "y": 120, + "wires": [ + [ + "e9272483eeab8c19" + ] + ] + }, + { + "id": "e9272483eeab8c19", + "type": "debug", + "z": "230815bb0628a63e", + "name": "debug 5", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 940, + "y": 120, + "wires": [] + }, + { + "id": "0bec605824bbb7ea", + "type": "inject", + "z": "230815bb0628a63e", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 110, + "y": 120, + "wires": [ + [ + "a1c78ddc8ef1f1fd" + ] + ] + }, + { + "id": "6b5cc73d3ff597e3", + "type": "postgresql", + "z": "230815bb0628a63e", + "name": "Generamos la vista de servicios etiquetados por demanda según el horario", + "query": "CREATE OR REPLACE VIEW vw_servicios_labeled AS\nSELECT s.*,\n hl.demand_level\nFROM vw_servicios_h3 s\nLEFT JOIN vw_hour_levels_dow hl\n ON s.dow = hl.dow AND s.hour = hl.hour;", + "postgreSQLConfig": "748b5921246ec468", + "split": false, + "rowsPerMsg": 1, + "outputs": 1, + "x": 470, + "y": 180, + "wires": [ + [ + "ae7888f46928631e" + ] + ] + }, + { + "id": "b2f0b35e19e565c8", + "type": "postgresql", + "z": "230815bb0628a63e", + "name": "Generamos la vista de demanda_h3_hour", + "query": "--- Generamos la vista de la demanda h3 por hora\nCREATE OR REPLACE VIEW demanda_h3_hour AS\nSELECT\n s.h3,\n s.hour,\n s.dow,\n hl.demand_level,\n COUNT(*)::int AS total_events,\n SUM(s.is_nulo)::int AS total_nulos,\n CASE WHEN COUNT(*)=0 THEN 0.0 ELSE SUM(s.is_nulo)::double precision / COUNT(*) END AS nulo_rate\nFROM vw_servicios_labeled s\nLEFT JOIN vw_hour_levels_dow hl\n ON hl.dow = s.dow\n AND hl.hour = s.hour\nGROUP BY s.h3, s.hour, s.dow, hl.demand_level;", + "postgreSQLConfig": "748b5921246ec468", + "split": false, + "rowsPerMsg": 1, + "outputs": 1, + "x": 360, + "y": 240, + "wires": [ + [ + "b7999a625ea2a4f7" + ] + ] + }, + { + "id": "94425a5d1997a6de", + "type": "postgresql", + "z": "230815bb0628a63e", + "name": "Verificaciones", + "query": "--- revision de valores\nSELECT * FROM vw_hour_levels_dow ORDER BY dow, hour;\n--- por servicio tiene que tener un nivel de demanda\nSELECT * FROM vw_servicios_labeled LIMIT 20;\n--- la agregación de los valores es correcta\nSELECT * FROM demanda_h3_hour ORDER BY total_events DESC LIMIT 20;", + "postgreSQLConfig": "748b5921246ec468", + "split": false, + "rowsPerMsg": 1, + "outputs": 1, + "x": 280, + "y": 300, + "wires": [ + [ + "f11aaa2122049f7e" + ] + ] + }, + { + "id": "6181e6dc62c93438", + "type": "inject", + "z": "230815bb0628a63e", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 110, + "y": 180, + "wires": [ + [ + "6b5cc73d3ff597e3" + ] + ] + }, + { + "id": "01d5f95df74d1a4b", + "type": "inject", + "z": "230815bb0628a63e", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 110, + "y": 240, + "wires": [ + [ + "b2f0b35e19e565c8" + ] + ] + }, + { + "id": "1c5af8b39a382a49", + "type": "inject", + "z": "230815bb0628a63e", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 110, + "y": 300, + "wires": [ + [ + "94425a5d1997a6de" + ] + ] + }, + { + "id": "ae7888f46928631e", + "type": "debug", + "z": "230815bb0628a63e", + "name": "debug 6", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 940, + "y": 180, + "wires": [] + }, + { + "id": "b7999a625ea2a4f7", + "type": "debug", + "z": "230815bb0628a63e", + "name": "debug 7", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 940, + "y": 240, + "wires": [] + }, + { + "id": "f11aaa2122049f7e", + "type": "debug", + "z": "230815bb0628a63e", + "name": "debug 8", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 940, + "y": 300, + "wires": [] + }, + { + "id": "1a960e62640178c4", + "type": "inject", + "z": "230815bb0628a63e", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 200, + "y": 380, + "wires": [ + [ + "239bb9ceb6c8f1a2" + ] + ] + }, + { + "id": "239bb9ceb6c8f1a2", + "type": "http request", + "z": "230815bb0628a63e", + "name": "", + "method": "GET", + "ret": "txt", + "paytoqs": "ignore", + "url": "http://10.10.14.70:5000/predict?hour=11&dow=1&total_events=3", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 360, + "y": 380, + "wires": [ + [ + "3bbe9a72ae47d0d3" + ] + ] + }, + { + "id": "3bbe9a72ae47d0d3", + "type": "debug", + "z": "230815bb0628a63e", + "name": "debug 9", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 520, + "y": 380, + "wires": [] + }, + { + "id": "cee897cd4088d738", + "type": "ui-template", + "z": "56fb69eb622c3f3b", + "group": "f8afeee042444067", + "page": "", + "ui": "", + "name": "Mapa Embebido", + "order": 1, + "width": 0, + "height": 0, + "head": "", + "format": "", + "storeOutMessages": true, + "passthru": true, + "resendOnRefresh": true, + "templateScope": "local", + "className": "", + "x": 120, + "y": 260, + "wires": [ + [] + ] } ] \ No newline at end of file diff --git a/flows_cred.json b/flows_cred.json index 9e26dfe..2a5fc8b 100644 --- a/flows_cred.json +++ b/flows_cred.json @@ -1 +1,3 @@ -{} \ No newline at end of file +{ + "239bb9ceb6c8f1a2": {} +} \ No newline at end of file