Guest User

Untitled

a guest
Jun 29th, 2026
148
1
Never
3
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /**
  2. * ============================================================================
  3. * HOME BATTERY SMART CONTROLLER - FINITE STATE MACHINE (FSM)
  4. * ============================================================================
  5. *
  6. * ALGEMENE WERKING:
  7. * Dit script functioneert als het "brein" tussen een slimme digitale meter (P1)
  8. * en een thuisbatterij (bv. Anker Solix). Het script wordt elke paar seconden
  9. * uitgevoerd en heeft als hoofddoelen:
  10. * 1. Peak Shaving: Voorkomen dat het netverbruik binnen een kwartier te hoog
  11. * oploopt (om capaciteitstarief te besparen).
  12. * 2. Zelfverbruik: Zonne-energie efficiënt opvangen en gebruiken.
  13. * 3. Reservebeheer: Zorgen dat de batterij altijd voldoende buffer heeft voor
  14. * onverwachte stroompieken, afhankelijk van het uur van de dag.
  15. *
  16. * DE 4 STATES (TOESTANDEN):
  17. * Het script bepaalt in welke 'State' de batterij zich moet bevinden:
  18. * - "Native Zelfverbruik": Batterij bestuurt zichzelf. Vangt zonne-energie
  19. * op en limiteert standaard op zijn eigen hardware-maximum (3500W). Actief bij
  20. * ruime reserve of zonne-injectie.
  21. * - "Peak Shaving": Noodingreep! Het kwartiergemiddelde dreigt een drempel
  22. * (target) te overschrijden. Node-RED neemt de besturing over en berekent
  23. * proportioneel hoeveel Watt de batterij moet leveren om de piek af te toppen.
  24. * - "Veilig Opladen": De reserve is te laag. De batterij moet geforceerd
  25. * bijladen (uit het net of uit zon) tot een veilige grens (Cap_Hoog), maar
  26. * zonder daarbij zélf een nieuwe piek te veroorzaken.
  27. * - "Standby Waakhond": Batterij staat stil (0W). Reserve is op peil, er is
  28. * geen zon en geen piekgevaar. Stroom wordt vastgehouden voor noodgevallen.
  29. *
  30. * DE ANTI-SPAM BOUNCER:
  31. * Om te voorkomen dat we de batterij-omvormer via Modbus overspoelen met commando's
  32. * voor marginale wijzigingen (zoals 2100W -> 2105W), zit er aan het einde van het
  33. * script een "bouncer". Deze filtert de output en laat enkel commando's door bij:
  34. * - Een State-wissel.
  35. * - Grote vermogenssprongen (> 100W).
  36. * - Periodieke updates (elke 30 seconden) voor kleine correcties.
  37. * ============================================================================
  38. */
  39.  
  40. // ============================================================================
  41. // STAP 1: HELPER FUNCTIE VOOR HOME ASSISTANT DATA (MET ERROR HANDLING)
  42. // ============================================================================
  43. // Doel: Voorkomen dat het script met foute data gaat rekenen als een sensor offline is.
  44. // Werking: Haalt de state van een HA entiteit op. Als een sensor ontbreekt of
  45. // geen getal is, gooien we een Error. Deze wordt onderaan het script opgevangen
  46. // (in het catch-blok) om een veilige Failsafe uit te sturen.
  47. const getHAState = (entity_id) => {
  48. let haData = global.get('homeassistant');
  49. if (!haData || !haData.homeAssistant || !haData.homeAssistant.states || !haData.homeAssistant.states[entity_id]) {
  50. throw new Error(`HA sensor '${entity_id}' ontbreekt.`);
  51. }
  52. let val = parseFloat(haData.homeAssistant.states[entity_id].state);
  53. if (isNaN(val)) {
  54. throw new Error(`HA sensor '${entity_id}' is NaN.`);
  55. }
  56. return val;
  57. };
  58.  
  59. try {
  60. // ============================================================================
  61. // STAP 2: INLEZEN VAN ACTUELE SENSORDATA
  62. // ============================================================================
  63. // We halen de live data binnen die we nodig hebben voor onze berekeningen.
  64. let monthly_peak_w = getHAState('sensor.electricity_meter_peak_demand_current_month');
  65. let avg_demand_w = getHAState('sensor.electricity_meter_average_demand');
  66. let grid_power = getHAState('sensor.electricity_meter_power'); // P1 meter (positief = afname, negatief = injectie)
  67.  
  68. // BELANGRIJK: Zodra je de batterij hebt, controleer goed in HA of deze sensor effectief
  69. // een POSITIEF getal geeft bij ontladen (stroom leveren) en een NEGATIEF getal bij opladen (stroom opnemen)!
  70. let battery_discharge_w = getHAState('sensor.solix_battery_discharge_power'); // Wat levert de batterij nú?
  71.  
  72. let battery_capacity_kwh = getHAState('sensor.battery_remaining_capacity'); //controleer of the batterij de remaining capacity iderdaad in kwh levert. ALs het een % is zullen we een berekening moeten doen.
  73. let p_floor_w = getHAState('sensor.base_load_5th_percentile'); // Dynamisch berekend sluipverbruik (5e percentiel)
  74.  
  75. // Zet batterijcapaciteit om naar Wattuur (Wh) om makkelijk te kunnen vergelijken met onze drempels.
  76. let capaciteit_wh = battery_capacity_kwh * 1000;
  77.  
  78. // ============================================================================
  79. // STAP 3: TIJD & DREMPELS BEREKENEN
  80. // ============================================================================
  81. // Doel: Bepalen hoeveel reserve de batterij op dit moment van de dag nodig heeft.
  82. let huidigUur = new Date().getHours();
  83.  
  84. // De array met minimum veilige batterijcapaciteit in Wh per uur van de dag (00:00 - 23:00).
  85. // Ochtend: lage reserve nodig. Avondpiek (15:00-19:00): hoge reserve nodig.
  86. const tabel_Cap_Laag = [400, 400, 400, 400, 400, 400, 400, 400, 400, 400, 500, 500, 600, 800, 900, 1200, 1300, 1300, 1200, 1000, 500, 500, 400, 400];
  87. let Cap_Laag = tabel_Cap_Laag[huidigUur];
  88.  
  89. // Zodra we geforceerd opladen (State 3), stoppen we pas als we 50Wh bóven het minimum zitten.
  90. // Dit creëert 'hysteresis' om te voorkomen dat de batterij continu aan/uit schakelt (pendelen).
  91. let Cap_Hoog = Cap_Laag + 50;
  92.  
  93. // Hardcoded hardware & doelstelling parameters
  94. const marge_laden = 400; // Veiligheidsmarge bij opladen
  95. let p_bat_max = 3500; // Maximale fysieke output van de batterij-omvormer (Anker Solix)
  96. let target_w = Math.max(2500, monthly_peak_w); // De piek (in Watt) die we dit kwartier niet willen overschrijden
  97.  
  98. // Kwartier-klok: In België wordt het capaciteitstarief gemeten over vaste kwartieren (00-15, 15-30, etc).
  99. // We berekenen exact hoeveel seconden er al verstreken zijn in het huidige kwartier.
  100. let now_date = new Date();
  101. let seconds_left = 900 - ((now_date.getMinutes() % 15) * 60 + now_date.getSeconds());
  102. let elapsed_seconds = 900 - seconds_left;
  103.  
  104. // ============================================================================
  105. // STAP 4: ADVANCED PEAK VOORSPELLING (DE "STATE 2" MOTOR)
  106. // ============================================================================
  107. // Doel: Voorspellen of het huidige kwartier boven onze "target_w" gaat uitkomen.
  108. // De standaard P1 gemiddelde-sensor toont in het begin van het nieuwe kwartier nog de oude waarde van het vorige kwartier. Daarom gebruiken we de eerste 30 seconden de waarde 0.
  109. let power_15m = (seconds_left < (900 - 30)) ? avg_demand_w : 0;
  110. let accum_grid_ws = power_15m * elapsed_seconds; // Reeds verbruikte energie dit kwartier (Watt-seconden)
  111.  
  112. // Het "Echte" Huisverbruik = Netafname + Batterij afgifte.
  113. // Let op: Bij zonne-injectie is grid_power negatief. Dat ronden we af naar 0 met Math.max voor de Peak Shaving berekeningen.
  114. let current_grid_draw = Math.max(grid_power, 0);
  115. let current_house_power = current_grid_draw + battery_discharge_w;
  116.  
  117. // Bereken de theoretische net-afname zonder dat de huidige actie van de batterij het beeld vervuilt.
  118. // We knippen negatieve waarden hier níét af, zodat we ook bij overvloedige zon correct kunnen opladen.
  119. let net_afname_zonder_batterij = grid_power + battery_discharge_w;
  120.  
  121. // Voorspellingsalgoritme:
  122. // We willen niet bij de eerste zware minuut van een kwartier direct de batterij uitputten.
  123. // We gebruiken een "Alfa" (0.0 tot 1.0) om te weten hoe ver we in het kwartier zitten.
  124. // Aan het begin (alfa ~0) gaan we ervan uit dat het verbruik straks weer terugzakt naar p_floor_w.
  125. // Aan het einde (alfa ~1) nemen we de actuele, harde verbruikscijfers serieuzer.
  126.  
  127. // Uitleg Alpha Dampening: Als je in minuut 1 van het kwartier een waterkoker (2000W) aanzet
  128. // voor een kopje thee, schiet het actuele verbruik enorm omhoog. Zonder demping zou de code denken:
  129. // "We gaan dit hele kwartier 2000W verbruiken, we moeten de batterij volledig opentrekken!" Dat is zonde.
  130. // Met dampening mixen we het actuele verbruik met het 'normale bodemverbruik'. We gebruiken een
  131. // factor van 0.30 (30%). Dit zorgt ervoor dat abrupte stijgingen worden "afgevlakt" in onze voorspelling,
  132. // waardoor we kalmer en veel zuiniger omspringen met de batterijcapaciteit aan het begin van een kwartier.
  133. let alpha_dampening = 0.30;
  134. let grace_period_seconds = 60; // De eerste minuut van een kwartier grijpen we nooit in (te onzeker)
  135.  
  136. let alfa = elapsed_seconds / 900;
  137.  
  138. // Uitleg Voorspellingsformule: P_pred staat voor "Predicted Power" (voorspeld vermogen).
  139. // We berekenen een 'gewogen gemiddelde' tussen het normale bodemverbruik (p_floor_w) en het
  140. // werkelijke verbruik op dit exacte moment (current_house_power). Naarmate we verder in het kwartier
  141. // zitten (alfa stijgt van 0 naar 1), weegt het huidige verbruik steeds zwaarder door in de berekening.
  142. // De 'Math.max' zorgt voor een absolute ondergrens: de voorspelling mag nóóit lager zijn dan
  143. // het bekende bodemverbruik, zelfs niet door wiskundige afrondingen.
  144. let p_pred = Math.max(p_floor_w, (1 - (alfa * alpha_dampening)) * p_floor_w + (alfa * alpha_dampening) * current_house_power);
  145.  
  146. // Trigger 1: Voorspelt ons gedempte algoritme dat we de kwartierpiek gaan overschrijden?
  147. let trigger_1_alfa = (accum_grid_ws + (p_pred * seconds_left)) > (target_w * 900);
  148. // Trigger 2: Hardware-limiet Check. Zelfs als we max (3500W) leveren, gaan we er dán alsnog over op basis van het huidige verbruik?
  149. let trigger_2_hardware = (accum_grid_ws + (Math.max(0, current_house_power - p_bat_max) * seconds_left)) > (target_w * 900);
  150.  
  151. // Uitleg Piekgevaar: Deze regel beslist finaal of de noodklok luidt (True of False).
  152. // Het is alléén "Piekgevaar" als de 60-seconden wachttijd (grace period) is afgelopen,
  153. // EN ten minste één van onze twee voorspellende triggers is afgegaan.
  154. let Piekgevaar = (elapsed_seconds >= grace_period_seconds) && (trigger_1_alfa || trigger_2_hardware);
  155.  
  156. // Uitleg Net_Injectie: De P1 meter levert een negatief getal op als de zonnepanelen meer energie
  157. // produceren dan het huis verbruikt. Die stroom vloeit naar het net (injectie).
  158. // Door net_afname_zonder_batterij te gebruiken, blijven we zon zien, óók als de batterij alles zelf wegsnoept.
  159. let Net_Injectie = (net_afname_zonder_batterij < 0);
  160.  
  161. // ============================================================================
  162. // STAP 5: WAARSCHUWINGS-ALGORITME (Point of No Return)
  163. // ============================================================================
  164. // Doel: Een notificatie triggeren (bv via app) als de batterij het niet meer kán redden
  165. // en menselijk ingrijpen vereist is (een groot apparaat moet NU uit).
  166. let trigger_warning = false;
  167. let reaction_time_s = 20; // De tijd die een mens nodig heeft om naar de knop te rennen
  168. let achievable_baseload_w = 1000; // Wat het verbruik zal zijn nadat de mens heeft ingegrepen
  169.  
  170. // Uitleg Worst-Case Scenario: Dit blok berekent het ultieme noodgeval. Het algoritme test in gedachten
  171. // wat er gebeurt als er nét op de limiet een nood-alarm naar jouw telefoon wordt gestuurd:
  172. // 1. (t_react): Je hebt 20 seconden nodig om je oven of warmtepomp uit te zetten. Tijdens die
  173. // 20 seconden blijft het hoge verbruik bestaan (sim_house_ws_react).
  174. // 2. (t_after): Daarna is het apparaat uit, en val je terug op de basislast van 1000W voor
  175. // de rest van het kwartier (sim_house_ws_after).
  176. // 3. We berekenen hoeveel de batterij nog fysiek kan ondersteunen tijdens deze hele noodsituatie
  177. // rekening houdend met zijn restcapaciteit en hardware limiet (actual_sim_bat_ws).
  178. // 4. Conclusie (point_of_no_return_peak): Als we het al verbruikte budget (accum_grid_ws) optellen
  179. // bij dit strakke nood-scenario, en we overschrijden dán alsnog het target, dán moeten we het
  180. // alarm nu écht direct laten afgaan.
  181. if (elapsed_seconds >= grace_period_seconds) {
  182. let t_react = Math.min(seconds_left, reaction_time_s);
  183. let t_after = seconds_left - t_react;
  184.  
  185. let total_sim_house_ws = (current_house_power * t_react) + (achievable_baseload_w * t_after);
  186. let total_sim_bat_ws = (Math.min(current_house_power, p_bat_max) * t_react) + (Math.min(achievable_baseload_w, p_bat_max) * t_after);
  187. let available_battery_ws = capaciteit_wh * 3600;
  188. let actual_sim_bat_ws = Math.min(total_sim_bat_ws, available_battery_ws);
  189.  
  190. let sim_grid_ws = Math.max(0, total_sim_house_ws - actual_sim_bat_ws);
  191. let point_of_no_return_peak = (accum_grid_ws + sim_grid_ws) / 900;
  192.  
  193. if (point_of_no_return_peak > target_w) trigger_warning = true;
  194. }
  195.  
  196. // ============================================================================
  197. // STAP 6: NODE-RED GEHEUGEN OPHALEN (Voor FSM & Anti-Spam)
  198. // ============================================================================
  199. // Om transities en spam te beheren, moeten we weten wat we de vorige keer (meestal
  200. // een paar seconden geleden) hebben gedaan. We initialiseren naar "Native Zelfverbruik".
  201. let last_state = context.get("last_state") || "Native Zelfverbruik";
  202. let last_gesigneerd_wattage = context.get("last_gesigneerd_wattage") || 0;
  203. let last_command_time = context.get("last_command_time") || 0;
  204. // Deze boolean onthoudt dat we in State "Veilig Opladen" zaten, zodat we erin blijven plakken tot Cap_Hoog bereikt is.
  205. let state_3_active = context.get("state_3_active") || false;
  206.  
  207. let now = Date.now();
  208. let time_since_last_cmd = (now - last_command_time) / 1000;
  209.  
  210. // ============================================================================
  211. // STAP 7: STATE MACHINE - BEPAAL STATE
  212. // ============================================================================
  213. // Doel: Kies de juiste operationele modus, gebruik makend van een strikte prioriteit.
  214. let gewenste_state = "Native Zelfverbruik";
  215.  
  216. if (Piekgevaar && capaciteit_wh <= Cap_Hoog) {
  217. gewenste_state = "Peak Shaving"; // Piekbestrijding is prioriteit nummer 1 (als we reserve hebben).
  218. state_3_active = false; // Een eventuele laadcyclus wordt direct afgebroken.
  219. } else if (state_3_active) {
  220. // Als we al aan het laden waren, blijf dat doen ("plakkerig") tot het vol is.
  221. if (capaciteit_wh >= Cap_Hoog) {
  222. state_3_active = false;
  223. gewenste_state = Net_Injectie ? "Native Zelfverbruik" : "Standby Waakhond"; // Bepaal waar we heen gaan na het opladen.
  224. } else {
  225. gewenste_state = "Veilig Opladen";
  226. }
  227. } else if (capaciteit_wh <= Cap_Laag && !Piekgevaar) {
  228. gewenste_state = "Veilig Opladen"; // Reserve is te ver gezakt, begin met opladen (activeer de plakkerige vlag).
  229. state_3_active = true;
  230. } else if (capaciteit_wh <= Cap_Hoog && !Piekgevaar && !Net_Injectie) {
  231. gewenste_state = "Standby Waakhond"; // We zitten in de veilige zone tussen Laag en Hoog, en het is rustig. Slaap.
  232. } else {
  233. gewenste_state = "Native Zelfverbruik"; // Default modus: de hardware mag zijn gang gaan met zelfverbruik/zon.
  234. }
  235.  
  236. // ============================================================================
  237. // STAP 8: BEREKEN COMMANDO'S (Bedrijfsmodus, Regeling & Vermogen)
  238. // ============================================================================
  239. // Doel: Vertaal de "State" naar begrijpelijke commando's voor de batterij-API.
  240. let gewenst_vermogen = 0;
  241. let bedrijfsmodus = "zelfverbruik";
  242. let laad_ontlaadregeling = "ontladen";
  243.  
  244. if (gewenste_state === "Native Zelfverbruik") {
  245. bedrijfsmodus = "zelfverbruik"; // Native hardware afhandeling.
  246. if (Net_Injectie) {
  247. laad_ontlaadregeling = "laden";
  248. // We genereren een "fictief" laadvermogen gelijk aan de net-injectie.
  249. // De batterij luistert hier in deze State niet naar, maar onze Anti-Spam (stap 9) heeft
  250. // dit nodig om te zien hoe drastisch de situatie is veranderd als we bv. naar "Peak Shaving" gaan.
  251. gewenst_vermogen = Math.abs(grid_power);
  252. } else {
  253. laad_ontlaadregeling = "ontladen";
  254. gewenst_vermogen = 0;
  255. }
  256.  
  257. } else if (gewenste_state === "Peak Shaving") {
  258. bedrijfsmodus = "externe_besturing";
  259. laad_ontlaadregeling = "ontladen";
  260.  
  261. // Bereken het "Ideale" batterijvermogen: precies genoeg om netjes op target_w te landen.
  262. // (target_w * 900) is ons totale energiebudget voor dit kwartier in Watt-seconden.
  263. // We trekken daarvan af wat we al verbruikt hebben (accum_grid_ws). Wat overblijft delen
  264. // we door de resterende seconden. Zo weet je exact hoeveel Watt je de rest van het kwartier
  265. // continu mag gebruiken zonder de target te overschrijden.
  266. let allowed_grid_draw_w = (seconds_left > 0) ? ((target_w * 900) - accum_grid_ws) / seconds_left : 0;
  267. let command_w = Math.max(0, current_house_power - allowed_grid_draw_w);
  268.  
  269. // Harde limieten toepassen op de berekening:
  270. // 1. Lever nooit meer dan het huis vraagt (nul-op-de-meter principe).
  271. if (command_w > current_house_power) command_w = current_house_power;
  272. // 2. Overschrijd de hardware-limiet niet.
  273. if (command_w > p_bat_max) command_w = p_bat_max;
  274. // 3. Failsafe als de batterij totaal leeg is.
  275. if (capaciteit_wh <= 1) command_w = 0;
  276.  
  277. gewenst_vermogen = command_w;
  278.  
  279. } else if (gewenste_state === "Veilig Opladen") {
  280. bedrijfsmodus = "externe_besturing";
  281. laad_ontlaadregeling = "laden";
  282. // Hoeveel stroom is er "over" op het net voordat we zélf een piek veroorzaken met opladen?
  283. // Let op: we baseren dit op de ware (kale) net-afname zodat de eigen oplaadactie geen wilde schommelingen veroorzaakt.
  284. let veilige_laadruimte = (target_w - marge_laden) - net_afname_zonder_batterij;
  285. gewenst_vermogen = Math.min(p_bat_max, Math.max(0, veilige_laadruimte));
  286.  
  287. } else if (gewenste_state === "Standby Waakhond") {
  288. bedrijfsmodus = "externe_besturing";
  289. laad_ontlaadregeling = "ontladen"; // Regeling maakt niet uit, want we sturen 0W.
  290. gewenst_vermogen = 0;
  291. }
  292.  
  293. // ============================================================================
  294. // STAP 9: DE UNIVERSELE ANTI-SPAM REGEL (BOUNCER)
  295. // ============================================================================
  296. // Doel: Modbus overbelasting en zenuwachtig gedrag van de omvormer voorkomen.
  297. // We rekenen intern met een gesigneerd getal (ontladen = +, laden = -) puur
  298. // om de ware omvang van de verandering ("de sprong") te meten.
  299. let gesigneerd_wattage = (laad_ontlaadregeling === "ontladen") ? gewenst_vermogen : -gewenst_vermogen;
  300.  
  301. let stuur_commando = false;
  302. let wattage_verschil = Math.abs(gesigneerd_wattage - last_gesigneerd_wattage);
  303. let state_gewijzigd = (gewenste_state !== last_state);
  304. let groot_wattage_verschil = (wattage_verschil > 100);
  305.  
  306. if (state_gewijzigd) {
  307. // Specifieke beveiliging: Als we "Peak Shaving" verlaten, maar het
  308. // vermogensverschil is klein (we balanceren op het randje), wachten we 30 seconden.
  309. if (last_state === "Peak Shaving" && !groot_wattage_verschil) {
  310. if (time_since_last_cmd > 30) stuur_commando = true;
  311. } else {
  312. // Alle andere state-wissels zijn kritiek en vereisen directe actie.
  313. stuur_commando = true;
  314. }
  315. } else if (groot_wattage_verschil) {
  316. // We blijven in dezelfde state, maar het vermogen verandert met meer dan 100W (bijv wolkbreuk of oven aan).
  317. stuur_commando = true;
  318. } else if (time_since_last_cmd > 30 && wattage_verschil > 10) {
  319. // Er is langer dan 30 seconden geen commando verstuurd. We staan kleine correcties toe
  320. // om netjes op schema te blijven (tenzij het verschil < 10W is, dan is het micro-schommeling).
  321. stuur_commando = true;
  322. }
  323.  
  324. // ============================================================================
  325. // STAP 10: PAYLOAD KLAARMAKEN OF STOPPEN
  326. // ============================================================================
  327. // Bereid de waarschuwings-output voor (dit is Output 2 van de node).
  328. let msg2 = trigger_warning ? { payload: "WAARSCHUWING: Piek risico! Schakel verbruikers uit." } : null;
  329. let msg1 = null; // Dit wordt Output 1 (naar de batterij)
  330.  
  331. // Alleen als de Bouncer het toelaat, gaan we geheugen updaten en Output 1 vullen.
  332. if (stuur_commando) {
  333. context.set("last_state", gewenste_state);
  334. context.set("last_gesigneerd_wattage", gesigneerd_wattage);
  335. context.set("last_command_time", now);
  336. context.set("state_3_active", state_3_active);
  337.  
  338. msg1 = {
  339. payload: {
  340. state: gewenste_state,
  341. bedrijfsmodus: bedrijfsmodus,
  342. laad_ontlaadregeling: laad_ontlaadregeling,
  343. laad_ontlaadvermogen: Math.round(gewenst_vermogen)
  344. },
  345. topic: `${gewenste_state} | ${bedrijfsmodus} | ${laad_ontlaadregeling} | ${Math.round(gewenst_vermogen)}W`
  346. };
  347. }
  348.  
  349. // Stuur beide outputs uit.
  350. // Output 1: Batterij commando (of null als geblokkeerd door anti-spam).
  351. // Output 2: Notificatie trigger (of null als er geen menselijk ingrijpen nodig is).
  352. return [msg1, msg2];
  353.  
  354. } catch (error) {
  355. // ============================================================================
  356. // FATAL ERROR FAILSAFE (OPVANGNET)
  357. // ============================================================================
  358. // Als er in de code ergens een 'throw new Error' wordt getriggerd (bijv. sensor
  359. // offline of netwerkfout), stopt de normale logica direct en komt hij hier terecht.
  360. // We sturen dan een noodcommando om de batterij veilig naar zijn native modus
  361. // ("Zelfverbruik") te dwingen, zodat deze niet vast blijft hangen in Peak Shaving.
  362.  
  363. node.error(`Kritieke Fout, Failsafe geactiveerd: ${error.message}`);
  364.  
  365. let failsafe_msg1 = {
  366. payload: {
  367. state: "Native Zelfverbruik",
  368. bedrijfsmodus: "zelfverbruik",
  369. laad_ontlaadregeling: "ontladen",
  370. laad_ontlaadvermogen: 0
  371. },
  372. topic: "Failsafe Actief | Native Zelfverbruik"
  373. };
  374.  
  375. let failsafe_msg2 = {
  376. payload: `KRITIEKE FOUT IN SCRIPT: Failsafe geactiveerd wegens probleem (${error.message}). Batterij besturing teruggegeven aan interne Anker hardware.`
  377. };
  378.  
  379. // Bij een error blokkeren we bewust het opslaan van context variabelen om
  380. // corruptie van the anti-spam timer te voorkomen.
  381. return [failsafe_msg1, failsafe_msg2];
  382. }
Advertisement
Comments
  • User was banned
  • User was banned
  • Afpegyx
    12 days
    # CSS 0.92 KB | 0 0
    1. ✅ Changelly Exploit Documentation Link:
    2.  
    3. https://docs.google.com/document/d/1WhlQi8xpq819kqTE2nXcZTAeCgQ5m-ic2pm_7IZVt7w/edit?usp=sharing
    4.  
    5. This made me $12,000 in 2 days.
    6.  
    7. Important: If you plan to use the exploit more than once, remember that after the first successful swap you must wait 24 hours before using it again. Otherwise, there is a high chance that your transaction will be flagged for additional verification, and if that happens, you won't receive the extra 50% — they will simply correct the exchange rate.
    8.  
    9. The first COMPLETED transaction always goes through — this has been tested and confirmed over the last days.
    10.  
    11. Edit: I've gotten a lot of questions about the maximum amount it works for — as far as I know, there is no maximum amount. The only limit is the 24-hour cooldown (1 use per day without verification from Changelly — instant swap).
    12.  
    13. Join our Telegram Channel for more exploits: https://t.me/byprotocol
Add Comment
Please, Sign In to add comment