LogicMachine Forum
Nordpool electricity - Printable Version

+- LogicMachine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: Nordpool electricity (/showthread.php?tid=6139)



Nordpool electricity - almoisey - 06.10.2025

existing script for nordpool prices ( from https://dashboard.elering.ee/et) doesn't work propertly since 1.october/ Do you have new variant of this script for electricity price?


RE: Nordpool electricity - RomansP - 06.10.2025

Hello,

I have tested nordpool script
https://forum.logicmachine.net/showthread.php?tid=4456&highlight=nordpool
It is working for me (price values for every hour). Please specify what errors you have in the logs.


RE: Nordpool electricity - almoisey - 06.10.2025

This script had worked property until the 1.october. But now all data script read ( current price, cheapest price of the day ) are uncorrect

(06.10.2025, 07:35)RomansP. Wrote: Hello,

I have tested nordpool script
https://forum.logicmachine.net/showthread.php?tid=4456&highlight=nordpool
It is working for me (price values for every hour). Please specify what errors you have in the logs.



RE: Nordpool electricity - RomansP - 06.10.2025

I will write a new version of this script


RE: Nordpool electricity - RomansP - 06.10.2025

Here is a new version of the script:

https://forum.logicmachine.net/showthread.php?tid=4456&pid=40105#pid40105


RE: Nordpool electricity - almoisey - 14.01.2026

Hello. Now Nordpool offers two options - 15-minute pricing and hourly pricing. Could you please add also a script for the second options( hourly pricing)?


RE: Nordpool electricity - admin - 14.01.2026

The API that our script uses only supports 15 minute intervals at the moment.


RE: Nordpool electricity - almoisey - 15.01.2026

But perhaps can you add the second variant to give the option to choise hourly or 15min pricing ?


RE: Nordpool electricity - RomansP - 15.01.2026

Hello,

We are planning to make script for hourly pricing, but we are going to do it later


RE: Nordpool electricity - icuzz - 19.01.2026

(15.01.2026, 11:54)almoisey Wrote: But  perhaps can you add the second variant to give the option to choise hourly or 15min pricing ?
This should work. Don't now about the DST (summer time/winter time) because haven't tested it yet.
Code:
-------------------------------------------------
-- PRICE CALCULATION -Change these
-------------------------------------------------
vat        = 1.255
marginal  = 0.42
electricity_tax = 2.82752
night_tariff = 0.89
day_tariff = 1.87

function add_costs(base_price, hour)
  local tariff

  -- Night tariff 22:00–07:00
  if hour >= 22 or hour < 7 then
    tariff = night_tariff
  else
    tariff = day_tariff
  end

  return base_price * vat + marginal + tariff + electricity_tax
end

https = require('ssl.https')
json = require('json')
ltn12 = require('ltn12')

country = 'fi'

current_price_addr        = '35/5/12'
cheapest_hour_addr        = '35/5/13'
cheapest_hour_price_addr  = '35/5/14'
costliest_hour_addr       = '35/5/15'
cosltiest_hour_price_addr = '35/5/16'

-------------------------------------------------
-- Helper: format numbers to "xx.xx snt"
-------------------------------------------------
-- Format for KNX (string with unit)
local function fmt2s(x)
  if type(x) ~= "number" then return x end
  return string.format("%.3f snt", x)
end

-- Format for storage (pure number)
local function fmt2num(x)
  if type(x) ~= "number" then return x end
  return tonumber(string.format("%.5f", x))
end

-------------------------------------------------
-- DATE SETUP
-------------------------------------------------
local current_date = os.date('*t')

local day_start_ts = os.time({
  year  = current_date.year,
  month = current_date.month,
  day   = current_date.day,
  hour  = 0, min = 0, sec = 0
})
local day_end_ts = day_start_ts + 24 * 3600

local tomorrow_start_ts = day_start_ts + 24 * 3600
local tomorrow_end_ts   = tomorrow_start_ts + 24 * 3600

local current_ts = os.time()

-------------------------------------------------
-- FETCH DATA
-------------------------------------------------
local previous_date = os.date('%F', os.time() - 24 * 3600)
local next_date     = os.date('%F', os.time() + 24 * 3600)

local url =
  'https://dashboard.elering.ee/api/nps/price?start=' ..
  previous_date .. 'T21%3A00%3A00Z&end=' ..
  next_date .. 'T23%3A59%3A59Z'

local mac = 0
io.readfile('/sys/class/net/eth0/address'):gsub('%x%x', function(v)
  mac = mac * 256 + tonumber(v, 16)
end)

local response = {}
local res, code = https.request({
  url = url,
  protocol = 'tlsv12',
  headers = { ['user-agent'] = 'LM ' .. mac },
  sink = ltn12.sink.table(response)
})

if not (res and code == 200) then
  log('request error', res, code)
  return
end

local data = json.pdecode(table.concat(response))
if not data or not data.data or not data.data[country] then
  log('No data for country: ' .. country)
  return
end

-------------------------------------------------
-- PROCESS TODAY + TOMORROW
-------------------------------------------------
local hourly_prices_today = {}
local today_hours = {}
local tomorrow_entries = {}

for h = 0, 23 do
  hourly_prices_today[h] = { sum = 0, count = 0 }
end

for _, record in ipairs(data.data[country]) do
  local timestamp = record.timestamp
  local lt = os.date('*t', timestamp)
  local hour = lt.hour
  local price = add_costs(record.price * 0.1, hour)

  -- TODAY
  if timestamp >= day_start_ts and timestamp < day_end_ts then
    local d = hourly_prices_today[hour]
    d.sum = d.sum + price
    d.count = d.count + 1
  end

  -- TOMORROW (15-min entries)
  if timestamp >= tomorrow_start_ts and timestamp < tomorrow_end_ts then
    tomorrow_entries[#tomorrow_entries + 1] = {
      timestamp = timestamp,
      price = price
    }
  end
end

-------------------------------------------------
-- CURRENT PRICE
-------------------------------------------------
do
  local ch = tonumber(os.date('%H', current_ts))
  local d = hourly_prices_today[ch]
  if d and d.count > 0 then
    grp.write(current_price_addr, d.sum / d.count)
  end
end

-------------------------------------------------
-- TODAY HOURLY AVERAGES
-------------------------------------------------
for h = 0, 23 do
  local d = hourly_prices_today[h]
  if d.count > 0 then
    today_hours[h+1] = d.sum / d.count
  else
    today_hours[h+1] = "Ei hintaa"
  end
end

-- WRITE TODAY → 35/6/0..23 (numeric)
for h = 0, 23 do
  grp.checkwrite('35/6/' .. h, today_hours[h+1])
end

-------------------------------------------------
-- TOMORROW: 15-min → hourly
-------------------------------------------------
local tomorrow_segments = {}

do
  local total_quarters = #tomorrow_entries
  local full_segments = math.floor(total_quarters / 4)

  for seg = 0, full_segments do
    local base = seg * 4 + 1
    if tomorrow_entries[base + 3] then
      local ts = tomorrow_entries[base].timestamp
      local h = os.date('*t', ts).hour

      local s = 0
      for j = base, base + 3 do
        s = s + tomorrow_entries[j].price
      end

      tomorrow_segments[#tomorrow_segments + 1] = {
        hour = h,
        price = s / 4
      }
    end
  end
end

local seg_count = #tomorrow_segments
local tomorrow_hours_stored = {}

-------------------------------------------------
-- WRITE TOMORROW → 35/7/0..23 (STRING "xx.xx snt")
-------------------------------------------------
for h = 0, 23 do
  local seg_idx = nil

  if seg_count == 24 then
    seg_idx = h + 1
  elseif seg_count == 23 then
    if h <= 2 then seg_idx = h + 1
    elseif h == 3 then seg_idx = nil
    else seg_idx = h end
  elseif seg_count == 25 then
    if h <= 2 then seg_idx = h + 1
    elseif h == 3 then seg_idx = 4
    else seg_idx = h + 2 end
  else
    if h + 1 <= seg_count then seg_idx = h + 1 end
  end

  local value = "Ei hintaa"
  if seg_idx and tomorrow_segments[seg_idx] then
    value = fmt2s(tomorrow_segments[seg_idx].price)
  end

  grp.checkwrite('35/7/' .. h, value)
  tomorrow_hours_stored[h+1] = value
end

-------------------------------------------------
-- DST EXTRA HOUR → 35/7/25
-------------------------------------------------
if seg_count == 25 and tomorrow_segments[5] then
  grp.checkwrite('35/7/25', fmt2s(tomorrow_segments[5].price))
else
  grp.checkwrite('35/7/25', "Ei hintaa")
end

-------------------------------------------------
-- DAY AFTER TOMORROW FIRST HOUR → 35/7/24
-------------------------------------------------
local day_after_tomorrow_price = "Ei hintaa"

do
  local start_ts = tomorrow_end_ts
  local end_ts = tomorrow_end_ts + 3600

  local sum = 0
  local count = 0

  for _, record in ipairs(data.data[country]) do
    local ts = record.timestamp
    if ts >= start_ts and ts < end_ts then
      local lt = os.date('*t', ts)
      local p = add_costs(record.price * 0.1, lt.hour)
      sum = sum + p
      count = count + 1
    end
  end

  if count > 0 then
    day_after_tomorrow_price = fmt2s(sum / count)
  end
end

grp.checkwrite('35/7/24', day_after_tomorrow_price)



RE: Nordpool electricity - RomansP - 02.02.2026

Hello,

Here is an updated script, for hourly pricing

https://forum.logicmachine.net/showthread.php?tid=4456&pid=41114#pid41114