Home assistant Ecoforest warmtepomp en eplucon thermostaat

Pagina: 1 ... 5 6 Laatste
Acties:

Onderwerpen


  • jeroenvi
  • Registratie: Juli 2022
  • Laatst online: 13-01 09:14
Ik heb nog een andere repo op github gevonden, met nog erg veel ongedocumenteerde registers erin: https://github.com/jrmno/Ecoforest_Heatpump_Modbus. De vraag is natuurlijk of die allemaal correct zijn, of misschien afhankelijk van model en/of softwareversie.

Mijn eerste stap om dat verder te checken was om de repo te forken en een simpel Python script toe te voegen, dat alle registers in de CSV opvraagt (hardcoded op IP van mijn pCOWEB kaart in de WP). Output met formatting.

Even in een aparte branch ook de huidige output van dat script toegevoegd: https://github.com/Jeroen...ree/example-script-output

Mijn geplande vervolgstappen:
- Output beter checken / annoteren
- CSV file aanvullen mbt waar de informatie vandaan komt: in welke versie van de EcoForest Modbus Guide het staat, cq of het undocumented is
- Ook registers uitlezen die niet in de CSV staan, en nonzero waardes signaleren in de output

  • K_VL
  • Registratie: Januari 2009
  • Laatst online: 21:52
jeroenvi schreef op donderdag 13 november 2025 @ 21:52:
Ik heb nog een andere repo op github gevonden, met nog erg veel ongedocumenteerde registers erin: https://github.com/jrmno/Ecoforest_Heatpump_Modbus. De vraag is natuurlijk of die allemaal correct zijn, of misschien afhankelijk van model en/of softwareversie.
De officiële handleiding helpt ook al een eind ;) : https://drive.proton.me/urls/DJD0TY0XEG#tVHGCsNGxwEG

  • jeroenvi
  • Registratie: Juli 2022
  • Laatst online: 13-01 09:14
Held! Dat is nog eens een mooi document :) En mooi actueel: "API BUS Client manual 03E (Rev1)/2025"

Ik durf het bijna niet te vragen, maar: hoe kom je aan deze PDF? En heb je toevallig ook toegang tot service software en/of updates?

  • K_VL
  • Registratie: Januari 2009
  • Laatst online: 21:52
jeroenvi schreef op vrijdag 14 november 2025 @ 11:22:
[...]


Held! Dat is nog eens een mooi document :) En mooi actueel: "API BUS Client manual 03E (Rev1)/2025"

Ik durf het bijna niet te vragen, maar: hoe kom je aan deze PDF? En heb je toevallig ook toegang tot service software en/of updates?
Gewoon eens gevraagd aan de leverancier 8)
Mijn WP wordt op dit moment geplaatst, ik vraag het eens aan de installateur i.v.m. updates.
Ik zou ze willen aansturen via Qbus (Luqas module), we zien nog wel hoe ver ik ermee kom.

[ Voor 8% gewijzigd door K_VL op 14-11-2025 11:34 ]


  • jeroenvi
  • Registratie: Juli 2022
  • Laatst online: 13-01 09:14
K_VL schreef op vrijdag 14 november 2025 @ 11:29:
[...]
Gewoon eens gevraagd aan de leverancier 8)
Mijn WP wordt op dit moment geplaatst, ik vraag het eens aan de installateur i.v.m. updates.
Ik zou ze willen aansturen via Qbus (Luqas module), we zien nog wel hoe ver ik ermee kom.
Nice. Mijn leverancier (LTA Energy) heeft echt wel meegedacht, maar ze zijn niet gewend om af te wijken van "het Eplucon concept" - en Eplucon zelf wilde me niet helpen. Ecoforest heeft best wat info publiek toegankelijk (en je kan je zelfs aanmelden voor hun Ecoforest Academy training sessies), maar als eindklant heb ik geen toegang gekregen tot de downloads. De Modbus registerlijst die ik had gekregen was verouderd en matcht dus op meerdere punten niet met de API doc die jij hebt gehad.

Uiteindelijk wil ik graag minstens het zelfde toegangs- en kennisniveau over de warmtepomp hebben als de installateur, en wil ik de th-Touch afkoppelen van Internet.

  • xavier_82
  • Registratie: Juli 2017
  • Laatst online: 23:44
jeroenvi schreef op woensdag 5 november 2025 @ 12:47:
[...]


Sorry dat ik reageer op een 2 jaar oud bericht, maar ik ben erg benieuwd: je schrijft "een soort van pCOWEB". Heb je een "echte" pCOWEB kaart in de controller zitten, of een Easynet module van EcoForest, of iets anders?

Ik heb net een "echte" pCOWEB kaart via Marktplaats gekocht en in mijn warmtepomp geplaatst; hij heeft inmiddels verbinding met mijn netwerk, maar lijkt intern nog niet te communiceren met de Carel pCO serie controller. Ik denk dat ik nog een instelling in de pCO mis. Als ik dit werkend krijg, dan is het misschien een iets duurdere oplossing dan een RS485 BMS card in de pCO controller (en iets als een WaveShare RS485 voor de Ethernet connectie), maar het heeft dan ook wel wat dat ik een minicomputer met Linux extra in mijn warmtepomp heb zitten - op de pCOWEB heb je nl root access en kan je evt ook zelf plugins maken, zag ik.
Easynet module van Ecoforest, opzich is hetzelfde alleen zonder root access en niet door Carel gemaakt, heeft wel een extra BMS, mini usb, fieldbus en volgens mij een diagnostiek poort (er zijn wel verschillende modellen blijkbaar en ik heb er 2 niet meer in gebruik).
jeroenvi schreef op donderdag 13 november 2025 @ 21:52:
Ik heb nog een andere repo op github gevonden, met nog erg veel ongedocumenteerde registers erin: https://github.com/jrmno/Ecoforest_Heatpump_Modbus. De vraag is natuurlijk of die allemaal correct zijn, of misschien afhankelijk van model en/of softwareversie.
Lijst komt van mijn hand. In principe gedaan wat jij nu aan het doen bent gecombineerd met het aflezen van de al geconfigureerde Easynet module, WP tot versie BC15_HP_V04B49_E uit 2021 werken de registers nog prima, ik weet dat met deze update nieuwe registers bij zijn gekomen maar heb de tijd en zin niet om deze te gaan uitzoeken. :X

  • PMuizen
  • Registratie: Juli 2010
  • Laatst online: 21:38
Heeft iemand ooit een firmware update gedaan? En hoe kom je dan aan die bestanden?

  • Vaez
  • Registratie: Juni 2009
  • Laatst online: 21:11
PMuizen schreef op vrijdag 14 november 2025 @ 20:26:
Heeft iemand ooit een firmware update gedaan? En hoe kom je dan aan die bestanden?
Onze th touch heeft een keer een firmware update gehad. Maar dit heeft de installateur gedaan via usb. Heb niet het idee dat deze bestanden publiekelijk beschikbaar zijn ergens.

  • jeroenvi
  • Registratie: Juli 2022
  • Laatst online: 13-01 09:14
Gwaihir schreef op zondag 9 november 2025 @ 12:54:
Daarnaast kan ik me niet aan de indruk onttrekken dat 't ding ook ergens de production flow beschikbaar moet hebben. Hoe stelt hij anders de warmteopbrengst vast?
Daar heb ik nog een tijdje over nagedacht. Als je die opbrengsten een beetje nauwkeurig wil vaststellen, dan zou je inderdaad de combinatie van flow en delta T moeten weten. Voor zover ik kan nagaan zitten er echter geen flow meters in de warmtepomp. Ik denk dat er dus geen flow meting wordt gedaan, maar gebruik wordt gemaakt van een benadering op basis van het PWM signaal van de pomp-aansturing.

  • jeroenvi
  • Registratie: Juli 2022
  • Laatst online: 13-01 09:14
K_VL schreef op vrijdag 14 november 2025 @ 11:29:
[...]


Gewoon eens gevraagd aan de leverancier 8)
Mijn WP wordt op dit moment geplaatst, ik vraag het eens aan de installateur i.v.m. updates.
Ik zou ze willen aansturen via Qbus (Luqas module), we zien nog wel hoe ver ik ermee kom.
Kleine tegenvaller: op de Modbus-adressen uit die API doc krijg ik geen waardes, eigenlijk alleen 0. En vooralsnog lijkt het niet iets met een offset te zijn.

Ik ben benieuwd hoe het bij jou verder gaat na plaatsing.

  • K_VL
  • Registratie: Januari 2009
  • Laatst online: 21:52
jeroenvi schreef op zondag 16 november 2025 @ 21:23:
[...]


Kleine tegenvaller: op de Modbus-adressen uit die API doc krijg ik geen waardes, eigenlijk alleen 0. En vooralsnog lijkt het niet iets met een offset te zijn.

Ik ben benieuwd hoe het bij jou verder gaat na plaatsing.
Da's minder, mogelijks iets ivm firmware & API versie? Het chapeprogramma draait nu, ik blijf er nog een 2 weken wijselijk af ;)

  • PMuizen
  • Registratie: Juli 2010
  • Laatst online: 21:38
Ik ben benieuwd of meerdere mensen dit soort spikes patronen zien bij het verwarmen.
Heb er geen echte verklaring voor, het is niet het ontdooien, ik heb een luchtgevoerd buitendeel.

Enig verklaring die ik heb is misschien dat ie drukken of iets met oliecirculatie.

Afbeeldingslocatie: https://tweakers.net/i/0UMREFpIuWHLwfRheza8-YfunzU=/800x/filters:strip_exif()/f/image/YTcEOkLZke85N2wJ8IEABJ3a.png?f=fotoalbum_large

  • bjp
  • Registratie: Januari 2010
  • Laatst online: 23:30

bjp

mijn WP (W/W) doet dit idd ook bij lange belasting (in de zone min tot 33% ongeveer) -> zover ik uit het verleden op T.net vernomen heb is het een nood aan oliecirculatie. Als je het minimum verhoogd, heb je er geen last meer van, maar mogelijks meer pendelen. Bij mij is de peak-to-next-peak tijd ongeveer 1h10, heel gelijkaardig.

Ik maak er mij geen zorgen over.

[ Voor 5% gewijzigd door bjp op 21-11-2025 12:38 ]

8.3kW Oost-West PV en 7.7kWh thuisbatterij | WP EcoForest 1-6 PRO en dWTW | Stromer ST1 & ST3


  • wdool
  • Registratie: Januari 2008
  • Laatst online: 20:33
Ik ben een Homey app aan het bouwen en via de Eplucon API haal ik diverse data punten op, een daarvan is Consumed energy. Echter dat is slechts per maand: https://homey.app/en-nl/a...y/Eplucon-Heat-Pump/test/

{{url}}/api/v2/econtrol/modules/{{moduleId}}/heatpump_energy_statistics?year=2025&month=2

De reponse in mijn geval is dan (test data)
{
"auth": true,
"data": [
{
"datefield": "2025-02-01",
"consumed_energy": 39,
"delivered_heat": 136,
"delivered_cooling": 0
}
],
"error_code": 200
}

Nu zie ik in https://drive.proton.me/urls/DJD0TY0XEG#tVHGCsNGxwEG dat er veel meer data zou moeten zijn. Enig idee hoe ik die kan uitlezen?

4.1.7. Power meter
The API HP Client allows both showing the powers produced by the heat pump for each service, differentiating active and passive cooling, and the total power consumed, and the power consumed in surplus conditions. All these measures are sent in the same units, which can be consulted at a specific address available on the communications BUS.

4.1.8. Energy meters
In the API HP client is available information regarding the energy consumed and produced in the installation:
• It is shown the accumulated energy for the current day and month, for each of the last 12 months (excluding the current month) and the accumulated energy for the last 12 complete months.
• For each period are shown separately the energy produced by the heat pump and the electrical auxiliary equipment for each of the services.
• For each period are shown the energy consumed and the energy consumed in surplus conditions by the heat pump.
• Different units are defined for heat pump and auxiliary units, and for each of the periods considered.
NOTE
▪ Current day energy meters update every 60 seconds and reset at the end of the day.
▪ Current month energy meters update at the end of the day and reset at the end of the month.
▪ Monthly historical energy meters are updated each time a month ends, replacing with the month just
ended the same month of the previous year.

API HP Client manual
▪ Yearly energy meter is updated each time a month ends, including the month just ended in calculus
of yearly energy instead of the same month of the previous year.

  • Keukenboer
  • Registratie: December 2015
  • Laatst online: 25-12-2025
Hoe kan ik in de TH-Thouch of in het menu van de EcoGEO controleren wat de ingestelde hysterese is?

  • JuutieZ
  • Registratie: Januari 2017
  • Laatst online: 21:47
Welke hysterese bedoel je?

  • Gwaihir
  • Registratie: December 2002
  • Niet online
PMuizen schreef op vrijdag 21 november 2025 @ 12:27:
Enig verklaring die ik heb is misschien dat ie drukken of iets met oliecirculatie.
Klopt, heeft te maken met de oliecirculatie, zoals @bjp aangeeft. Hoe verder je van 50% af draait, hoe vaker hij dat gaat doen.

Ik heb geen idee hoe je buitendeel precies presteert bij verschillend gebruik. Maar puur op basis van die grafieken zou ik overwegen het minimum toerental te verhogen. Hij zal daardoor vaker af slaan, maar een betere (S)COP draaien, mogelijk een fors betere.

  • Gwaihir
  • Registratie: December 2002
  • Niet online
xavier_82 schreef op vrijdag 14 november 2025 @ 17:20:
Lijst komt van mijn hand. In principe gedaan wat jij nu aan het doen bent gecombineerd met het aflezen van de al geconfigureerde Easynet module, WP tot versie BC15_HP_V04B49_E uit 2021 werken de registers nog prima, ik weet dat met deze update nieuwe registers bij zijn gekomen maar heb de tijd en zin niet om deze te gaan uitzoeken. :X
Registers 42 en 43 staan elk 2x in de lijst. (?)

  • xavier_82
  • Registratie: Juli 2017
  • Laatst online: 23:44
Gwaihir schreef op zondag 4 januari 2026 @ 16:06:
[...]

Registers 42 en 43 staan elk 2x in de lijst. (?)
Dat klopt, ik dacht standaard zijn ze voor de fase 5 & 6 van de vloer droog programma, maar ze kunnen ook gebruikt worden voor de recirculatie temperatuur afhankelijk hoe de recirculatie pomp is aangesloten en welke als eerst is gebruikt.

  • Gwaihir
  • Registratie: December 2002
  • Niet online
@xavier_82 Ok.

[Ik ben nog altijd op jacht naar die max-output waarde die ik zo goed kan gebruiken (en moet 't nog altijd register voor register proberen met een grote omweg). Vandaag weer enkele 'gaten' in de lijst uitgesloten.]

  • jeroenvi
  • Registratie: Juli 2022
  • Laatst online: 13-01 09:14
wdool schreef op maandag 22 december 2025 @ 21:07:
Ik ben een Homey app aan het bouwen en via de Eplucon API haal ik diverse data punten op, een daarvan is Consumed energy. Echter dat is slechts per maand: https://homey.app/en-nl/a...y/Eplucon-Heat-Pump/test/

Nu zie ik in https://drive.proton.me/urls/DJD0TY0XEG#tVHGCsNGxwEG dat er veel meer data zou moeten zijn. Enig idee hoe ik die kan uitlezen?

4.1.7. Power meter
The API HP Client allows both showing the powers produced by the heat pump for each service, differentiating active and passive cooling, and the total power consumed, and the power consumed in surplus conditions. All these measures are sent in the same units, which can be consulted at a specific address available on the communications BUS.

4.1.8. Energy meters
In the API HP client is available information regarding the energy consumed and produced in the installation:
• It is shown the accumulated energy for the current day and month, for each of the last 12 months (excluding the current month) and the accumulated energy for the last 12 complete months.
• For each period are shown separately the energy produced by the heat pump and the electrical auxiliary equipment for each of the services.
• For each period are shown the energy consumed and the energy consumed in surplus conditions by the heat pump.
• Different units are defined for heat pump and auxiliary units, and for each of the periods considered.
NOTE
▪ Current day energy meters update every 60 seconds and reset at the end of the day.
▪ Current month energy meters update at the end of the day and reset at the end of the month.
▪ Monthly historical energy meters are updated each time a month ends, replacing with the month just
ended the same month of the previous year.

API HP Client manual
▪ Yearly energy meter is updated each time a month ends, including the month just ended in calculus
of yearly energy instead of the same month of the previous year.
Klopt. De warmtepomp heeft die informatie wel, maar of je het via MODBUS kan uitlezen is afhankelijk van welke API versie in de warmtepomp is geconfigureerd.

Dit is allemaal niet heel duidelijk vindbaar, maar wat ik bij elkaar heb gepuzzeld:
  • Vanaf een bepaalde firmware kan je op de warmtepomp kiezen tussen API versie 23 of 24
  • Deze versies zijn absoluut niet compatible met elkaar, bij API versie 24 wordt een compleet andere MODBUS adresstructuur gebruikt
  • Voor "BUS" aansturing (dus aansturing via MOBDUS registers, zoals de th-Touch doet) moet de aansturing dus de juiste API versie implementeren
  • De meest recente firmware die ik voor de th-Touch heb gekregen, gebruikt nog steeds API versie 23. Mijn installateur kon me niet vertellen wanneer er evt nieuwe firmware voor komt cq hoe een migratiepad eruit ziet.
Dus de warmtepomp heeft intern wel de informatie; het energieverbruik van de actuele dag en van de lopende maand kan je via het display ook opvragen. Maar zo lang de API versie op 23 staat, kan je het niet via de bus uitlezen. Met API versie 24 moet het wel kunnen, maar daar kan de th-Touch nog niet mee werken. Dus eigenlijk loopt Eplucon hier gewoon een stuk achter...

Ik wil als testje binnenkort tijdelijk de thermostaat afkoppelen en dan even de API versie naar 24 zetten om een registerdump te maken - maar ik wacht nog even tot het buiten minder koud is. Toen ik medio december een firmware update op de warmtepomp deed was hij ook alle config kwijt, en heeft het me behoorlijk wat uurtjes gekost om alle settings weer goed te krijgen.

  • jeroenvi
  • Registratie: Juli 2022
  • Laatst online: 13-01 09:14
Gwaihir schreef op zondag 4 januari 2026 @ 18:16:
@xavier_82 Ok.

[Ik ben nog altijd op jacht naar die max-output waarde die ik zo goed kan gebruiken (en moet 't nog altijd register voor register proberen met een grote omweg). Vandaag weer enkele 'gaten' in de lijst uitgesloten.]
Welke max-output zoek je? De EcoGeo heeft aparte max output per bedrijfsmodus toch? Gaat het om hoeveel procent van het vermogen de WP max mag gebruiken voor verwarming bij vraag van DG1? Of max voor tapwater, of voor zwembad? Die zijn afaik allemaal apart in te stellen.

[ Voor 17% gewijzigd door jeroenvi op 08-01-2026 09:23 . Reden: Uitbreiden van de vraag ]


  • Gwaihir
  • Registratie: December 2002
  • Niet online
jeroenvi schreef op donderdag 8 januari 2026 @ 09:21:
Welke max-output zoek je? De EcoGeo heeft aparte max output per bedrijfsmodus toch? Gaat het om hoeveel procent van het vermogen de WP max mag gebruiken voor verwarming bij vraag van DG1? Of max voor tapwater, of voor zwembad? Die zijn afaik allemaal apart in te stellen.
Ik wil de maximale output voor CV-verwarming graag in kunnen stellen. Op de WP zit die in een beveiligingsmenu en staat hij (af fabriek, bij de 1-9) op 11kW. Het register waar dat in staat, heb ik nog niet gevonden.

Er is inderdaad een losse voor tapwater en ik denk ook voor zwembad. Wel 1x voor 'verwarming', dacht ik, niet voor DG1 los van DG2, etc. (Mocht dat wel zo zijn, dan zoek ik DG1.)

Ik wil nl. een hoeveelheid warmte van de WP. Momenteel stel ik dat in via het maximale toerental (dat percentage wat je noemt) maar dat is onhandig omdat de relatie tussen toerental en opbrengst erg ingewikkeld is. (COP is afhankelijk van de temperaturen.)

  • bjp
  • Registratie: Januari 2010
  • Laatst online: 23:30

bjp

via modbus haal ik hier zowel “condensatie vermogen” als toerental. Je zou gerust dynamisch het maximum %RPM kunnen instellen op basis van huidige “condensatie vermogen” (= warmte productie).

8.3kW Oost-West PV en 7.7kWh thuisbatterij | WP EcoForest 1-6 PRO en dWTW | Stromer ST1 & ST3


  • wdool
  • Registratie: Januari 2008
  • Laatst online: 20:33
@jeroenvi ik ben heel benieuwd, hoop dat het koude weer snel over is :-)

  • ChrisK
  • Registratie: Januari 2023
  • Laatst online: 23:20
Omdat ik de app te traag vind werken heb ik gisteren met scriptable een widget gemaakt waarmee ik via de API de parameters direct kan uitlezen die ik van belang vind. Nu ging dat gisteren perfect, maar vandaag krijg ik waarden van 4 uur geleden met de timestamp (created_at) van nu.

De app en webportaal zijn wel actueel. Aan de hand van de WW temp kan ik terugvinden dat alle waarden matchen op ca 4 uur geleden (edit 13/1: vandaag 2-3 uur oud). Het lijkt mij dat de app dezelfde API aanspreekt.

Iemand enig idee hoe dit zou kunnen?

[ Voor 3% gewijzigd door ChrisK op 13-01-2026 17:00 ]


  • wdool
  • Registratie: Januari 2008
  • Laatst online: 20:33
@ChrisK would you mind sharing the script?

  • ChrisK
  • Registratie: Januari 2023
  • Laatst online: 23:20
No problem! Opgesteld met wat hulp van OpenAI ;-)
code:
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
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
 /**
 * Ecoforest / EPLucon – Scriptable widget (configurable)
 *
 * Data model:
 * - statistics endpoint geeft een "rows table": veel meetregels met created_at + veel velden.
 * - Wij nemen de LAATSTE row als "actueel".
 *
 * Aanpasbaar:
 * - Zet velden aan/uit in TOGGLES (true/false).
 * - Voeg eventueel eigen velden toe in FIELDS (label + mogelijke key-namen + unit + decimals).
 *
 */

// =======================
// ✅ INSTELLINGEN
// =======================

const BASE = "https://portaal.eplucon.nl/api/v2";
const API_TOKEN = ""; 
const MODULE_ID = 1000640; 

// Wanneer je in de Scriptable app runt, wil je een preview:
const PREVIEW_FAMILY = "medium"; // "small" | "medium" | "large"

// Velden aan/uit (standaard: DG1 temp + toerental aan)
const TOGGLES = {
  dg1_temp: false,
  compressor_rpm: true,

  outside_temp: false,
  indoor_temp: true,
  ww_temp: true,
  ww_mode: false,
  cv_pressure: false,
  power_now: false,
  total_import_energy: false,
  total_produced_energy: false,

  brine_in: false,
  brine_out: false,
  brine_pressure: false,

  heating_in: true,
  heating_out: true,
  condensation_temp: false,
  evaporation_temp: false,

  suction_gas_temp: false,
  discharge_gas_temp: false,
  superheat: false,

  compressor_suction_pressure: false,
  compressor_discharge_pressure: false,

  valve_pos_sg2: false,
  valve_pos_sg3: false,
  valve_pos_sg4: false,
  expansion_valve_pos: false,
  fan_rpm: false,

  setpoint_heating_dg1: false,
  setpoint_cooling_dg1: false,
  setpoint_heating_sg2: false,
  setpoint_cooling_sg2: false,
  setpoint_heating_sg3: false,
  setpoint_cooling_sg3: false,
  setpoint_heating_sg4: false,
  setpoint_cooling_sg4: false,

  overheat: false,
  inverter_temp: false,
};

// =======================
// 📌 VELDDEFINITIES
// =======================
/**
 * FIELDS definieert alle velden die je kunt tonen.
 *
 * id:        moet overeenkomen met TOGGLES key
 * label:     wat je in de widget ziet
 * keys:      mogelijke veldnamen zoals ze in jouw row-object voorkomen
 * unit:      suffix (°C, bar, W, rpm, etc.)
 * decimals:  afronding
 *
 * Je kunt hier makkelijk velden bijmaken/aanpassen.
 */
const FIELDS = [
  { id: "dg1_temp", label: "Actuele temp DG1", keys: ["Actuele temp. DG1"], unit: "°C", decimals: 1 },
  { id: "compressor_rpm", label: "Compressor", keys: ["Compressor toerental"], unit: "rpm", decimals: 0 },

  { id: "outside_temp", label: "Buiten", keys: ["Buitentemp."], unit: "°C", decimals: 1 },
  { id: "indoor_temp", label: "Binnen", keys: ["Binnentemperatuur"], unit: "°C", decimals: 1 },
  { id: "ww_temp", label: "WW", keys: ["WW temperatuur"], unit: "°C", decimals: 1 },
  { id: "cv_pressure", label: "CV druk", keys: ["Cv druk", "CV druk"], unit: "bar", decimals: 1 },

  { id: "power_now", label: "Actueel verbruik", keys: ["Actueel verbruik"], unit: "W", decimals: 0 },
  { id: "total_import_energy", label: "Import energie", keys: ["Totaal import energie"], unit: "kWh", decimals: 1 },
  { id: "total_produced_energy", label: "Geproduceerd", keys: ["Totaal geproduceerde energie"], unit: "kWh", decimals: 1 },

  { id: "brine_in", label: "Brine in", keys: ["Brine in temperatuur"], unit: "°C", decimals: 1 },
  { id: "brine_out", label: "Brine uit", keys: ["Brine out temperatuur"], unit: "°C", decimals: 1 },
  { id: "brine_pressure", label: "Brine druk", keys: ["Brine druk"], unit: "bar", decimals: 1 },

  { id: "heating_in", label: "Heating in", keys: ["Heating in temperatuur"], unit: "°C", decimals: 1 },
  { id: "heating_out", label: "Heating out", keys: ["Heating out temperatuur"], unit: "°C", decimals: 1 },
  { id: "condensation_temp", label: "Condensatie", keys: ["Condensatie temp."], unit: "°C", decimals: 1 },
  { id: "evaporation_temp", label: "Verdamping", keys: ["Verdamping temp."], unit: "°C", decimals: 1 },

  { id: "suction_gas_temp", label: "Zuig gas", keys: ["Zuig gas temperatuur"], unit: "°C", decimals: 1 },
  { id: "discharge_gas_temp", label: "Pers gas", keys: ["Pers gas temperatuur"], unit: "°C", decimals: 1 },
  { id: "superheat", label: "Oververhitting", keys: ["Oververhitting"], unit: "K", decimals: 1 },

  { id: "compressor_suction_pressure", label: "Zuigdruk", keys: ["Compressorzuigdruk"], unit: "bar", decimals: 1 },
  { id: "compressor_discharge_pressure", label: "Afvoerdruk", keys: ["Compressorafvoerdruk"], unit: "bar", decimals: 1 },

  { id: "valve_pos_sg2", label: "Ventiel SG2", keys: ["Positie ventiel SG2"], unit: "%", decimals: 0 },
  { id: "valve_pos_sg3", label: "Ventiel SG3", keys: ["Positie ventiel SG3"], unit: "%", decimals: 0 },
  { id: "valve_pos_sg4", label: "Ventiel SG4", keys: ["Positie ventiel SG4"], unit: "%", decimals: 0 },
  { id: "expansion_valve_pos", label: "Exp. ventiel", keys: ["Positie expansie ventiel"], unit: "%", decimals: 0 },
  { id: "fan_rpm", label: "Ventilator", keys: ["Act. vent. toerental"], unit: "rpm", decimals: 0 },

  { id: "setpoint_heating_dg1", label: "SP verw DG1", keys: ["Setpoint verwarming DG1"], unit: "°C", decimals: 1 },
  { id: "setpoint_cooling_dg1", label: "SP koel DG1", keys: ["Setpoint koeling DG1"], unit: "°C", decimals: 1 },

  { id: "setpoint_heating_sg2", label: "SP verw SG2", keys: ["Setpoint verwarming SG2"], unit: "°C", decimals: 1 },
  { id: "setpoint_cooling_sg2", label: "SP koel SG2", keys: ["Setpoint koeling SG2"], unit: "°C", decimals: 1 },

  { id: "setpoint_heating_sg3", label: "SP verw SG3", keys: ["Setpoint verwarming SG3"], unit: "°C", decimals: 1 },
  { id: "setpoint_cooling_sg3", label: "SP koel SG3", keys: ["Setpoint koeling SG3"], unit: "°C", decimals: 1 },

  { id: "setpoint_heating_sg4", label: "SP verw SG4", keys: ["Setpoint verwarming SG4"], unit: "°C", decimals: 1 },
  { id: "setpoint_cooling_sg4", label: "SP koel SG4", keys: ["Setpoint koeling SG4"], unit: "°C", decimals: 1 },

  { id: "overheat", label: "Oververhitting", keys: ["Oververhitting"], unit: "K", decimals: 1 },
  { id: "inverter_temp", label: "Inverter temp", keys: ["Inverter temperatuur"], unit: "°C", decimals: 1 },
  { id: "ww_mode", label: "WW", keys: ["WW"], unit: "", decimals: 0 },
];

// =======================
// 🔧 HELPERS
// =======================

async function showInAppOrWidget(widget, family = "medium") {
  if (config.runsInWidget) {
    Script.setWidget(widget);
  } else {
    if (family === "small") await widget.presentSmall();
    else if (family === "large") await widget.presentLarge();
    else await widget.presentMedium();
  }
  Script.complete();
}



// EPLucon lijkt invalid values te gebruiken zoals -9999.
function cleanValue(v) {
  if (v === null || v === undefined) return null;
  const num = Number(v);
  if (!Number.isNaN(num) && (num === -9999 || num === 9999)) return null;
  return v;
}

function fmtValue(v, unit, decimals) {
  v = cleanValue(v);
  if (v === null || v === undefined) return "—";
  const num = Number(v);
  if (Number.isNaN(num)) return String(v) + (unit ? ` ${unit}` : "");
  return num.toFixed(decimals) + (unit ? ` ${unit}` : "");
}

async function apiGetJSON(path) {
  const req = new Request(`${BASE}${path}`);
  req.method = "GET";
  req.headers = { "Authorization": `Bearer ${API_TOKEN}`, "Accept": "application/json" };
  req.timeoutInterval = 6;
  return await req.loadJSON();
}


/**
 * - stats.data is niet de rows-array maar bevat zelf weer .data
 * Daarom unwrapen totdat we een array vinden.
 */
function extractRows(stats) {
  if (Array.isArray(stats)) return stats;

  const candidates = [
    stats?.data,
    stats?.data?.data,
    stats?.result?.data,
    stats?.items,
    stats?.items?.data,
  ];
  for (const c of candidates) if (Array.isArray(c)) return c;

  // follow .data chain (max 5)
  let cur = stats;
  for (let i = 0; i < 5; i++) {
    if (Array.isArray(cur)) return cur;
    if (cur && typeof cur === "object" && cur.data !== undefined) cur = cur.data;
    else break;
  }
  return null;
}

async function fetchRowsToday(moduleId) {
  const now = new Date();
  const year = now.getFullYear();
  const month = now.getMonth() + 1;

  const path = `/econtrol/modules/${moduleId}/statistics`
  const stats = await apiGetJSON(path);
  

  const rows = extractRows(stats);
  console.log(rows[rows.length-1])
  if (!Array.isArray(rows)) {
    const topKeys = stats && typeof stats === "object" ? Object.keys(stats).join(",") : String(typeof stats);
    throw new Error("Kan rows-array niet vinden. Top-level keys: " + topKeys);
  }
  if (rows.length === 0) throw new Error("Geen rows vandaag (array leeg).");
  return rows;
}

function getLatestRow(rows) {
  return rows[rows.length - 1];
}



function getField(row, keys) {
  for (const k of keys) {
    if (row[k] !== undefined) return row[k];
  }
  return null;
}

// =======================
// 🖼️ WIDGET UI
// =======================

function buildWidgetFromRow(row) {
  const w = new ListWidget();
  w.setPadding(20, 20, 20, 20);

  
  const title = w.addText("Ecoforest live");
  title.font = Font.boldSystemFont(16);
  w.addSpacer(8);

  // 1) Bepaal welke FIELDS aan staan
  const active = FIELDS.filter(f => TOGGLES[f.id]);

  // 2) Render ze
  for (const f of active) {
    const raw = getField(row, f.keys);
    const text = fmtValue(raw, f.unit, f.decimals);
    const t = w.addText(`${f.label}: ${text}`);
    t.font = Font.systemFont(18);
    t.minimumScaleFactor = 0.7;
  }
  
  
  w.addSpacer(8);
  const ts = row["created_at"] ? new Date(row["created_at"]) : new Date();
  const footer = w.addText(
    `Laatste meting: ${ts.toLocaleTimeString("nl-NL", { hour: "2-digit", minute: "2-digit" })}`
  );
  footer.font = Font.systemFont(10);
  footer.textOpacity = 0.6;
  

  return w;
}

// =======================
// ▶️ MAIN
// =======================

try {
  const moduleId = MODULE_ID;
  const rows = await fetchRowsToday(moduleId);
  const latest = getLatestRow(rows);
  const widget = buildWidgetFromRow(latest);
  await showInAppOrWidget(widget, PREVIEW_FAMILY);

} catch (e) {
  const w = new ListWidget();
  w.setPadding(12, 12, 12, 12);
  w.addText("Ecoforest live").font = Font.boldSystemFont(16);
  w.addSpacer(8);
  w.addText("Fout bij ophalen").font = Font.boldSystemFont(14);
  w.addSpacer(4);
  w.addText(String(e)).font = Font.systemFont(11);
  await showInAppOrWidget(w, PREVIEW_FAMILY);
}
Pagina: 1 ... 5 6 Laatste