script.js
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 |
"use strict"; print("PCdeMano CPU BLINKING Dashboard START"); let config = sd_read_file("/webscreen.json"); let broker = "192.168.1.144"; let port = 1883; let topic = "nestdisk/cpu/stats"; let clientId = "pcdemano-webscreen"; let mqttUser = ""; let mqttPass = ""; if (config !== "") { let b = parse_json_value(config, "mqtt_broker"); let p = parse_json_value(config, "mqtt_port"); let t = parse_json_value(config, "mqtt_topic"); let c = parse_json_value(config, "mqtt_client_id"); let u = parse_json_value(config, "mqtt_user"); let pw = parse_json_value(config, "mqtt_pass"); if (b !== "") broker = b; if (p !== "") port = toNumber(p); if (t !== "") topic = t; if (c !== "") clientId = c; if (u !== "") mqttUser = u; if (pw !== "") mqttPass = pw; } let COLOR_RED = 0xE53935; let COLOR_ORANGE = 0xFB8C00; let COLOR_YELLOW = 0xFDD835; let COLOR_WHITE = 0xFFFFFF; let COLOR_MUTED = 0xAAAAAA; let COLOR_GREEN = 0x3FB950; let COLOR_FAIL = 0xFF4444; let headerStyle = create_style(); style_set_text_font(headerStyle, 20); style_set_text_color(headerStyle, COLOR_WHITE); let statusStyle = create_style(); style_set_text_font(statusStyle, 14); style_set_text_color(statusStyle, COLOR_MUTED); let nameStyle = create_style(); style_set_text_font(nameStyle, 14); style_set_text_color(nameStyle, COLOR_MUTED); // Estilos dinámicos let tempStyle = create_style(); let loadStyle = create_style(); let freqStyle = create_style(); style_set_text_font(tempStyle, 34); style_set_text_font(loadStyle, 34); style_set_text_font(freqStyle, 34); style_set_text_color(tempStyle, COLOR_WHITE); style_set_text_color(loadStyle, COLOR_WHITE); style_set_text_color(freqStyle, COLOR_WHITE); let headerLabel = create_label(185, 14); obj_add_style(headerLabel, headerStyle, 0); label_set_text(headerLabel, "CPU MONITOR"); let statusLabel = create_label(380, 16); obj_add_style(statusLabel, statusStyle, 0); label_set_text(statusLabel, "Conectando..."); // ------------------------------------------------------------- // ORDEN: LOAD → TEMP → FREQ // ------------------------------------------------------------- let nameLoad = create_label(20, 80); obj_add_style(nameLoad, nameStyle, 0); label_set_text(nameLoad, "LOAD (%)"); let valLoad = create_label(30, 100); obj_add_style(valLoad, loadStyle, 0); label_set_text(valLoad, "---"); let nameTemp = create_label(215, 80); obj_add_style(nameTemp, nameStyle, 0); label_set_text(nameTemp, "TEMP (C)"); let valTemp = create_label(210, 100); obj_add_style(valTemp, tempStyle, 0); label_set_text(valTemp, "---"); let nameFreq = create_label(375, 80); obj_add_style(nameFreq, nameStyle, 0); label_set_text(nameFreq, "FREQ (MHz)"); let valFreq = create_label(385, 100); obj_add_style(valFreq, freqStyle, 0); label_set_text(valFreq, "---"); let topicLabel = create_label(8, 18); obj_add_style(topicLabel, statusStyle, 0); label_set_text(topicLabel, topic); // ------------------------------------------------------------- // PARPADEO // ------------------------------------------------------------- let blinkState = 0; let blinkLoad = 0; let blinkTemp = 0; let blinkFreq = 0; let blink_loop = function() { blinkState = 1 - blinkState; if (blinkLoad) { style_set_text_color(loadStyle, blinkState ? COLOR_WHITE : blinkLoad); obj_add_style(valLoad, loadStyle, 0); } if (blinkTemp) { style_set_text_color(tempStyle, blinkState ? COLOR_WHITE : blinkTemp); obj_add_style(valTemp, tempStyle, 0); } if (blinkFreq) { style_set_text_color(freqStyle, blinkState ? COLOR_WHITE : blinkFreq); obj_add_style(valFreq, freqStyle, 0); } }; create_timer("blink_loop", 500); // ------------------------------------------------------------- let wifiReady = 0; let mqttConnected = 0; let check_wifi = function() { if (wifiReady) return; if (!wifi_status()) return; wifiReady = 1; label_set_text(statusLabel, "WiFi OK"); mqtt_init(broker, port); let ok = (mqttUser !== "" && mqttPass !== "") ? mqtt_connect(clientId, mqttUser, mqttPass) : mqtt_connect(clientId); if (ok) { mqttConnected = 1; mqtt_subscribe(topic); mqtt_on_message("on_mqtt_msg"); label_set_text(statusLabel, "Conectado"); style_set_text_color(statusStyle, COLOR_GREEN); } else { label_set_text(statusLabel, "MQTT error"); style_set_text_color(statusStyle, COLOR_FAIL); } }; let testgif = create_image("/logobig.png", 150, 180); // ------------------------------------------------------------- let main_loop = function() { if (!wifiReady) { check_wifi(); return; } if (!mqttConnected) return; mqtt_loop(); if (!mqtt_has_message()) return; let payload = mqtt_get_payload(); mqtt_msg_clear(); if (payload === "") return; let freq = parse_json_value(payload, "freq"); let load = parse_json_value(payload, "load"); let temp = parse_json_value(payload, "cpu_temp"); // Reset flags blinkLoad = 0; blinkTemp = 0; blinkFreq = 0; // ------------------------- // CARGA CPU (load) // ------------------------- if (load !== "") { let v = toNumber(load); label_set_text(valLoad, load); if (v > 50) { style_set_text_color(loadStyle, COLOR_RED); style_set_text_font(loadStyle, 48); blinkLoad = COLOR_RED; } else if (v > 20) { style_set_text_color(loadStyle, COLOR_ORANGE); style_set_text_font(loadStyle, 44); blinkLoad = COLOR_ORANGE; } else if (v > 10) { style_set_text_color(loadStyle, COLOR_YELLOW); style_set_text_font(loadStyle, 40); } else { style_set_text_color(loadStyle, COLOR_WHITE); style_set_text_font(loadStyle, 34); } obj_add_style(valLoad, loadStyle, 0); } // ------------------------- // TEMPERATURA CPU // ------------------------- if (temp !== "") { let v = toNumber(temp); label_set_text(valTemp, temp); if (v > 85) { style_set_text_color(tempStyle, COLOR_RED); style_set_text_font(tempStyle, 48); blinkTemp = COLOR_RED; } else if (v > 75) { style_set_text_color(tempStyle, COLOR_ORANGE); style_set_text_font(tempStyle, 44); blinkTemp = COLOR_ORANGE; } else if (v > 65) { style_set_text_color(tempStyle, COLOR_YELLOW); style_set_text_font(tempStyle, 40); } else { style_set_text_color(tempStyle, COLOR_WHITE); style_set_text_font(tempStyle, 34); } obj_add_style(valTemp, tempStyle, 0); } // ------------------------- // FRECUENCIA CPU // ------------------------- if (freq !== "") { let v = toNumber(freq); label_set_text(valFreq, freq); if (v > 3000) { style_set_text_color(freqStyle, COLOR_RED); style_set_text_font(freqStyle, 48); blinkFreq = COLOR_RED; } else if (v > 2000) { style_set_text_color(freqStyle, COLOR_ORANGE); style_set_text_font(freqStyle, 44); blinkFreq = COLOR_ORANGE; } else if (v > 1300) { style_set_text_color(freqStyle, COLOR_YELLOW); style_set_text_font(freqStyle, 40); } else { style_set_text_color(freqStyle, COLOR_WHITE); style_set_text_font(freqStyle, 34); } obj_add_style(valFreq, freqStyle, 0); } }; create_timer("main_loop", 1000); print("CPU Dashboard ready, waiting for WiFi..."); |
A pesar de su longitud, el programa es realmente sencillo. Tras establecer la conexión a la red, queda a la escucha del topic nestdisk/cpu/stats y, cada vez que recibe un mensaje, extrae únicamente los valores load, cpu_temp y freq, que son los que utiliza el WebScreen.

A partir de ahí, el sistema verifica si cada uno de ellos se mantiene dentro de sus límites normales de operación o si entra en zona de alarma. En función de ese estado, ajusta dinámicamente el tamaño del valor mostrado, modifica su color según la severidad e incluso activa un efecto de blinking en los casos críticos para llamar la atención del usuario.
Sobre el rendimiento
A pesar de la carga computacional prácticamente nula de este ejemplo tan sencillo, seguimos sin conseguir que el dispositivo se resetee con la frecuencia que debería. Nuestros amigos de HW Lab nos han comentado que en los próximos días lanzarán una nueva versión del firmware que ampliará la memoria disponible, muy probablemente la causa de estos errores.
141