PowerShell script to get readings of Heat Cost Allocators (doprimo-3 heating meters) operated by ista Nederland B.V.
on a per day, per billing period and per meter basis.
This is an unofficial script. The official API is not documented and the script is based on reverse-engineering the API calls made by the official portal. Use it as your own risk and responsibility. No liability is assumed for any damages or losses caused by the use of this script.
git clone https://github.com/daniel0x00/HeatCostAllocator.git
- PowerShell 7 or higher, available for Windows, MacOS and Linux.
- Add your credentials to the ista Nederland B.V. login portal on the
usage.ps1
file, vars$Username
and$Password
. (Don't have an account?). - By default, the script will get the heating readings broken down by day and by the full billing period. It will export 2
.CSV
files:DailyBasis_ExportedAt_yyyy-MM-dd_HCAReadings.csv
andFullPeriodBasis_ExportedAt_yyyy-MM-dd_HCAReadings.csv
. - It is recommended to export once a week: every Tuesday night. If you schedule the execution of
usage.ps1
in a cron job to every Tuesday, you will export both the readings as a daily basis (DailyBasis
file) as well as the full billing period (FullPeriodBasis
CSV file). - The
FullPeriodBasis
CSV file will match what is shown in the portal. - The idea is that you export every week at least once, so you'll accumulate
FullPeriodBasis
CSV files and hence you'll be able to calculate the consumption per radiator, per week. On the official portal you can't do this calculation as you only see the consumption per the full billing period (or until last Sunday since today's day). - Run the script by dot-sourcing it:
PS /> . .\usage.ps1
PS /> $fullData | select -Last 1 | fl
RequestedAtTimestamp : 1736001228
CurEndTimestamp : 1656540000
CurEndDatetime : 6/30/2022 12:00:00 AM
RequestedBillingPeriodYear : 2022
Period : Full
MeterId : <redacted>
MeterNr : <redacted>
BillingPeriodId : 2021
RadNr : 1
Position : Kitchen
TransferLoss : 0
Multiply : 1
Reduction : 35
CalcFactor : 1.05
BsDate : 01-07-2021
EsDate : 30-06-2022
BeginValue : 0
EndValue : 1154
CValue : 1154
CCValue : 1212
CCDValue : 788
DecPos : 0
SValR : 0
EvalR : 0
serviceId : 1
Order : 1
ArtNr : <redacted>
DisplayName : <redacted>
Address : <redacted>
Zip : <redacted>
Cuid : <redacted>
CurStart : 01-07-2021
CurEnd : 30-06-2022
TotalNow : 4293
Show consumption per day between two dates (inclusive) and only for radiators that has consumed more than 0 units, with column selection as displayed in the official invoice.
PS /> $dailyData | Where-Object {$_.CurEndDatetime -ge '2024-12-01' -and $_.CurEndDatetime -le '2025-01-01' -and $_.CCDValue -gt 0} | Select-Object CurEndDatetime, BillingPeriodId, RadNr, Position, MeterNr, BsDate, EsDate, BeginValue, EndValue, CValue, CalcFactor, CCValue, Reduction, CCDValue | Sort-Object CurEndDatetime, RadNr | Format-Table *
CurEndDatetime BillingPeriodId RadNr Position MeterNr BsDate EsDate BeginValue EndValue CValue CalcFactor CCValue Reduction CCDValue
-------------- -------------------------- ----- -------- ------- ------ ------ ---------- -------- ------ ---------- ------- --------- --------
12/1/2024 12:00:00 AM 2025 1 Kitchen <redacted> 30-11-2024 01-12-2024 258.000 276.000 18.000 1.050 19.000 35.000 12
12/1/2024 12:00:00 AM 2025 3 Bedroom <redacted> 30-11-2024 01-12-2024 33.000 42.000 9.000 1.150 10.000 55.000 5
12/1/2024 12:00:00 AM 2025 4 Bathroom <redacted> 30-11-2024 01-12-2024 211.000 213.000 2.000 0.600 1.000 35.000 1
12/1/2024 12:00:00 AM 2025 5 Bedroom <redacted> 30-11-2024 01-12-2024 422.000 432.000 10.000 1.050 11.000 55.000 5
12/1/2024 12:00:00 AM 2025 6 Living room <redacted> 30-11-2024 01-12-2024 354.000 377.000 23.000 0.550 13.000 35.000 8
12/2/2024 12:00:00 AM 2025 1 Kitchen <redacted> 01-12-2024 02-12-2024 270.000 287.000 17.000 1.050 18.000 35.000 12
12/2/2024 12:00:00 AM 2025 3 Bedroom <redacted> 01-12-2024 02-12-2024 39.000 47.000 8.000 1.150 9.000 55.000 4
12/2/2024 12:00:00 AM 2025 4 Bathroom <redacted> 01-12-2024 02-12-2024 212.000 214.000 2.000 0.600 1.000 35.000 1
12/2/2024 12:00:00 AM 2025 5 Bedroom <redacted> 01-12-2024 02-12-2024 429.000 436.000 7.000 1.050 7.000 55.000 3
12/2/2024 12:00:00 AM 2025 6 Living room <redacted> 01-12-2024 02-12-2024 369.000 390.000 21.000 0.550 12.000 35.000 8
Daily values as presented by $dailyData
are not the same as the values shown on the official invoice. Use $fullData
for that. But for $fullData
you cannot display per-day consumption.
The reason why? Note how CCDValue
is calculated on a per-day basis, taken radiator #3 as example:
CurEndDatetime RadNr Position MeterNr BsDate EsDate BeginValue EndValue CValue CalcFactor CCValue Reduction CCDValue
-------------- ----- -------- ------- ------ ------ ---------- -------- ------ ---------- ------- --------- --------
12/1/2024 12:00:00 AM 3 Bedroom <redacted> 30-11-2024 01-12-2024 33.000 42.000 9.000 1.150 10.000 55.000 5
12/2/2024 12:00:00 AM 3 Bedroom <redacted> 01-12-2024 02-12-2024 39.000 47.000 8.000 1.150 9.000 55.000 4
On day 01-12-2024
the consumption was 5
units. The EndValue
of that day was 42
. However, the next day 02-12-2024
, the BeginValue
is not 42
, rather is 39
, which is 33
as BeginValue
of previous day plus 5
as consumed after applying the reduction formula of the previous day. But why 39
instead of 38
-the difference is 6
- ? It must be because of CCDValue
is casted to an integer instead of rounded to 0 decimals when displaying the data in CCDValue
, however rounding will be used for calculation in the backend.
Calculation for 01-12-2024
: (42 - 33) * 1.150
= 10.35
, rounded to 0 decimals to 10
. Then, 10 * 55%
= 5.5
, casted to 0 decimals to 5
, but kept in the backed rounded to 0 decimals, which then will 5.5
= 6
.
Calculation for 02-12-2024
: BeginValue
of previous day + rounded value of previous day = 33 + 6
= 39
.
This difference is carried-over in the backend for the whole billing period. Thus, the only way of calculating real consumption is by using the value of BeginValue
since the start of billing period and the EndValue
of the last day of the billing period. Then applying the formula CCDValue = (EndValue - BeginValue) * CalcFactor * ((100 - Reduction) / 100)
.
Unofficial (best-guess effort) explanation of the columns generated by the script.
Column | Description | Belongs to official API? |
---|---|---|
CurEndTimestamp | Represents the time in Unix format of the CurEnd date. Output as first column, so a Big Data tool (like Splunk) picks it up as event time. |
No. Introduced as a helper column. |
CurEndDatetime | Represents the time DateTime object. Useful to sort and filter while in PowerShell. | No. Introduced as a helper function. |
RequestedAtTimestamp | Represents the time at which the request was made to the API. | No. Introduced as a helper column. |
RequestedBillingPeriodYear | Represents the billing period parameter passed to the API requests. | No. Introduced as a helper column. The API will output BillingPeriodId on the response. |
Period | Represents the period of export. Can be Daily -indicating daily readings- or Full -indicating full billing period readings-. |
No. Introduced as a helper column. |
BeginValue | Meter reading as it was seen on BsDate date. |
Yes |
EndValue | Meter reading as it was seen on EsDate date. |
Yes |
CValue | Difference EndValue -BeginValue |
Yes |
CCDValue | This is the amount of units you're going to be billed for, after the application of Reduction , CalcFactor and Multiply . IMPORTANT: this value CANNOT be used on the DailyBasis export as the calculation will be different than on the FullPeriod export. |
Yes |
TransferLoss | Refers to heat transfer losses associated with the measurement process. It accounts for the heat that is lost during the transfer of energy from the radiator to the environment, which might not directly contribute to the actual heating of the room. It can be a set value or a formula. Since my radiators all have a TransferLoss of 0 , I cannot determine it's usage. However, I don't think is being used as this column doesn't show up in the official bill. |
Yes |
DecPos | Decimal position, determines the number of decimal places shown in the displayed value. Example: DecPos = 2 means 123.45; DecPos = 0 means 123. | Yes |
SValR | Scaling value for radiators, adjusts for specific radiator heat output. Typically determined based on radiator type, size, and heat output. Example: Larger radiators → Higher SValR. Unknown usage. Since my radiators all have a SValR of 0 , I cannot determine it's usage. |
Yes |
EvalR | Evaluation factor. All my radiadors do have a value of 92 . Unknown usage. |
Yes |
Unofficial (best-guess effort) explanation on how the billing is calculated:
- Billing is based on the readings of the full billing period.
- To get a list of available billing periods for your account —which also represents how far back can you go in time in your account—, you can use:
(New-HCASession -LoginUrl $LoginUrl -Username $Username -Password $Password | Get-HCAUser -UserUrl $UserUrl).User.Cus | ForEach-Object { $_.curConsumption | ForEach-Object { $_.BillingPeriods | Format-Table * } }
y s e ta
- - - --
2025 7/1/2024 12:00:00 AM 6/30/2025 12:00:00 AM 12.600
2024 7/1/2023 12:00:00 AM 6/30/2024 12:00:00 AM 11.600
2023 7/1/2022 12:00:00 AM 6/30/2023 12:00:00 AM 10.300
2022 7/1/2021 12:00:00 AM 6/30/2022 12:00:00 AM 10.800
- You're billed for the Units shown on the
CCDValue
column. This value is calculated as follows:(EndValue - BeginValue) * CalcFactor * ((100 - Reduction) / 100)
, then rounded to the nearest integer, as valueDecPos
enforces.
- You cannot use daily exports to calculate the billing. The
CCDValue
will be different on the daily export than on the full billing period export. The daily export is only useful to see the daily consumption of the radiators —for example to see if meters are measuring0
onCCDValue
if you have the heating turned off—, but not to calculate the billing. - The
EUR
price of the unit determined byista Nedarland B.V.
is not shown on the API response on portal mijn.ista.nl. Instead, debicasso portal is used to see the billing details of your billing period, available by the end of October, sectionMijn dossier
, subjectAfrekening periode : 1-7-xxxx t/m 30-6-xxxx
. My understanding is that theEUR
price per unit is calculated upon the consumption of your whole building (section #2,Berekening eenheidsprijzen
, thenVariabele energiekosten 55,00%
), then broken down by radiator (section #3Overzicht meterstanden en bepaling van uw verbruik
) and then price per unit is calculated on section #4Uw kostenspecificatie
, sub-sectionVariabele energiekosten
. Have in mind you also pay a price for theVloeroppervlakte
(floor area) of your building: this varies per building.
Sharing here the price per unit of variable costs and fixed costs for each billing period, for my building.
Represents 55% of the bill.
Billing year | Billing period | Price per unit | % variation vs previous year |
---|---|---|---|
2022 | 1-7-2021 / 30-6-2022 | 0.422241 EUR | unknown |
2023 | 1-7-2022 / 30-6-2023 | 0.953447 EUR | 125% |
2024 | 1-7-2023 / 30-6-2024 | 1.110027 EUR | 16% |
Represents 45% of the bill.
Billing year | Billing period | Price per unit | % variation vs previous year |
---|---|---|---|
2022 | 1-7-2021 / 30-6-2022 | 0.076722 EUR | unknown |
2023 | 1-7-2022 / 30-6-2023 | 0.130516 EUR | 70.12% |
2024 | 1-7-2023 / 30-6-2024 | 0.116517 EUR | -10.73% |