Primeros modelados

This commit is contained in:
2025-12-20 22:31:11 +01:00
parent 2da1c9b591
commit 6a0457076d
2 changed files with 524 additions and 4 deletions

View File

@@ -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": "<iframe src=\"/worldmap\" style=\"width:100%; height:100%; border:none;\">\n</iframe>",
"storeOutMessages": true,
"passthru": true,
"resendOnRefresh": true,
"templateScope": "local",
"className": "",
"x": 120,
"y": 260,
"wires": [
[]
]
}
]

View File

@@ -1 +1,3 @@
{}
{
"239bb9ceb6c8f1a2": {}
}