This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

NordPool prices in LogicMachine
#1
Hi!

Has anyone had any experience with getting (integrating) NordPool prices into LogicMachine?

Tried different versions but nothing worked. 

What about this one? 

https://dashboard.elering.ee/en/nps/pric...59:59.999Z
https://dashboard.elering.ee/api/nps/pri...%3A00.999Z

Anyone had any luck or experience? Can you please share scripts for getting NordPool prices into logic machine?
Reply
#2
Hi!

Here is a script, that gives six objects 1.current_time; 2.current_price; 3.cheapest_hour; 4.cheapest_price; 5.costly_hour; 6.costly_price

Code:
https = require('ssl.https') json = require('json') ltn12 = require('ltn12') country = 'lv' -- Latvia --country = 'fi' -- Finland --country = 'lt' -- Lithuania --country = 'ee' -- Estonia obj_current_time = grp.create({ datatype = dt.time, address = '35/5/11', name = 'current_time'}) obj_current_price = grp.create({ datatype = dt.float32, address = '35/5/12', name = 'current_price'}) obj_cheapest_hour = grp.create({ datatype = dt.time, address = '35/5/13', name = 'cheapest_hour'}) obj_cheapest_hour_price = grp.create({ datatype = dt.float32, address = '35/5/14', name = 'cheapest_price'}) obj_costly_hour = grp.create({ datatype = dt.time, address = '35/5/15', name = 'costly_hour'}) obj_costly_hour_price = grp.create({ datatype = dt.float32, address = '35/5/16', name = 'costly_price'}) --[[]] current_date = os.date('*t') previous_date = os.date('*t', os.time()-24*60*60) --log(previous_date) if previous_date.month < 10 then   previous_date.month = '0' .. previous_date.month end if previous_date.day < 10 then   previous_date.day = '0' .. previous_date.day end previous_date_str = previous_date.year .. '-' .. previous_date.month .. '-' .. previous_date.day --log(previous_date_str) next_date = os.date('*t', os.time() + 24*60*60) --log(next_date) if next_date.month < 10 then   next_date.month = '0' .. next_date.month end if next_date.day < 10 then   next_date.day = '0' .. next_date.day end next_date_str = next_date.year .. '-' .. next_date.month .. '-' .. next_date.day --log(next_date_str) url = 'https://dashboard.elering.ee/api/nps/price?start='.. previous_date_str ..'T00%3A00%3A00.999Z&end=' .. next_date_str ..'T00%3A00%3A00.999Z' --log(url) mac = 0 io.readfile('/sys/class/net/eth0/address'):gsub('%x%x', function(v)   mac = mac * 256 + tonumber(v, 16) end) response = {} res, code = https.request({   url = url,   protocol = 'tlsv12',   headers = {     ['user-agent'] = 'LM ' .. mac   },   sink = ltn12.sink.table(response) }) if res and code == 200 then   data = json.pdecode(table.concat(response)) else   log('request error', res, code) end --log(data) --log(data['data'][country]) min_price = 99999 max_price = -1 min_price_hour = -1 max_price_hour = -1 for i = 23, 47, 1 do -- 23 is 00:00 for GMT+0200 (Eastern European Standard Time)   if data['data'][country][i] then      price = data['data'][country][i]['price']         if price < min_price then       min_price = price -- EUR/MegaWatt*hour       min_price_hour = i - 23 -- get hour for GMT+0200 (Eastern European Standard Time)     end         if price > max_price then       max_price = price -- EUR/MegaWatt*hour       max_price_hour = i - 23 -- get hour for GMT+0200 (Eastern European Standard Time)     end       end end --log(min_price_hour) --log(min_price) --log(max_price_hour) --log(max_price) curr_day_time = {} if current_date['wday'] > 1 then   current_date['wday'] = current_date['wday'] - 1 -- 1 is Monday, 2 is Tuesday else   current_date['wday'] = 7 -- 7 is Sunday end   curr_day_time['day'] = current_date['wday'] curr_day_time['hour'] = current_date['hour'] curr_day_time['minute'] = current_date['min'] grp.write(obj_current_time, curr_day_time) -- 3 byte time day current_price = data['data'][country][ current_date['hour'] + 23 ]['price'] -- EUR/MegaWatt*hour --[[ timestamp = data['data'][country][ current_date['hour'] + 23 ]['timestamp'] log(timestamp) temp = os.date("*t", timestamp) log(temp) --]] grp.write(obj_current_price, current_price) -- float cheapest_day_time = {} cheapest_day_time['day'] = current_date['wday'] cheapest_day_time['hour'] = min_price_hour grp.write(obj_cheapest_hour, cheapest_day_time) -- 3 byte time day grp.write(obj_cheapest_hour_price, min_price) -- float costly_day_time = {} costly_day_time['day'] = current_date['wday'] costly_day_time['hour'] = max_price_hour grp.write(obj_costly_hour, costly_day_time) -- 3 byte time day grp.write(obj_costly_hour_price, max_price) -- float --]]

Attached Files
.lua   elering_v03.lua (Size: 4.02 KB / Downloads: 22)
Reply
#3
Hi!

We have rewritten script (old script will not work properly), because of a change
in time intervals (previously electricity price was per hour, now per 15 minutes).

Here is a new script:

Code:
https = require('ssl.https') json = require('json') ltn12 = require('ltn12') country = 'lv' -- Latvia --country = 'fi' -- Finland --country = 'lt' -- Lithuania --country = 'ee' -- Estonia current_price_addr = '40/1/18' cheapest_hour_addr = '40/1/16' cheapest_hour_price_addr = '40/1/17' costliest_hour_addr = '40/1/19' cosltiest_hour_price_addr = '40/1/20' cheapest_time_addr = '40/1/14' cheapest_price_addr = '40/1/15' costliest_time_addr = '40/1/21' costliest_price_addr = '40/1/22' 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 = os.time({year = current_date.year, month = current_date.month, day = current_date.day, hour = 23, min = 59, sec = 59}) local current_ts = os.time() previous_date = os.date('%F', os.time() - 24*60*60) next_date = os.date('%F', os.time() + 24*60*60) url = 'https://dashboard.elering.ee/api/nps/price?start='.. previous_date ..'T00%3A00%3A00.999Z&end=' .. next_date ..'T00%3A00%3A00.999Z' mac = 0 io.readfile('/sys/class/net/eth0/address'):gsub('%x%x', function(v)   mac = mac * 256 + tonumber(v, 16) end) response = {} res, code = https.request({   url = url,   protocol = 'tlsv12',   headers = {     ['user-agent'] = 'LM ' .. mac   },   sink = ltn12.sink.table(response) }) if res and code == 200 then   data = json.pdecode(table.concat(response)) else   log('request error', res, code)   return end min_price = 99999 max_price = -1 min_price_timestamp = 0 max_price_timestamp = 0 current_price = nil hourly_prices = {} for h = 0, 23 do   hourly_prices[h] = { sum = 0, count = 0 } end if not data or not data.data or not data.data[country] then   log('No data for country: ' .. country)   return end for _, record in ipairs(data.data[country]) do   local timestamp = record.timestamp   local price = record.price   if timestamp >= day_start_ts and timestamp <= day_end_ts then         if price < min_price then       min_price = price       min_price_timestamp = timestamp     end         if price > max_price then       max_price = price       max_price_timestamp = timestamp     end     local record_time = os.date('*t', timestamp)     local hour = record_time.hour     if hourly_prices[hour] then       hourly_prices[hour].sum = hourly_prices[hour].sum + price       hourly_prices[hour].count = hourly_prices[hour].count + 1     end   end     if current_ts >= timestamp and current_ts < (timestamp + 15 * 60) then     current_price = price   end end --log('--- Current Status ---') if current_price then   --log('Current 15-min price: ' .. current_price .. ' EUR/MWh')   grp.write(current_price_addr, current_price) -- float else   log('Could not determine current price') end min_avg_price = 99999 max_avg_price = -1 cheapest_hour = -1 costliest_hour = -1 for hour, data in pairs(hourly_prices) do   if data.count > 0 then     local avg_price = data.sum / data.count     --log(string.format("Hour %02d:00 - Avg Price: %.2f", hour, avg_price))         if avg_price < min_avg_price then       min_avg_price = avg_price       cheapest_hour = hour     end     if avg_price > max_avg_price then       max_avg_price = avg_price       costliest_hour = hour     end   end end cheapest_hour_time = {} cheapest_hour_time['wday'] = current_date['wday'] --log('--- Cheapest Hour Today ---') if cheapest_hour ~= -1 then   --log(string.format('Hour: %02d:00 - %02d:59', cheapest_hour, cheapest_hour))   --log(string.format('Average Price: %.2f EUR/MWh', min_avg_price))   cheapest_hour_time['hour'] = cheapest_hour   grp.write(cheapest_hour_addr, cheapest_hour_time)   grp.write(cheapest_hour_price_addr, min_avg_price) else   log('Could not calculate the cheapest hour.') end costliest_hour_time = {} costliest_hour_time['wday'] = current_date['wday'] --log('--- Costliest Hour Today ---') if costliest_hour ~= -1 then   --log(string.format('Hour: %02d:00 - %02d:59', costliest_hour, costliest_hour))   --log(string.format('Average Price: %.2f EUR/MWh', max_avg_price))   costliest_hour_time['hour'] = costliest_hour   grp.write(costliest_hour_addr, costliest_hour_time)   grp.write(cosltiest_hour_price_addr, max_avg_price) else   log('Could not calculate the costliest hour.') end cheapest_time = {} cheapest_time['wday'] = current_date['wday'] --log('--- Cheapest 15-min Interval Today ---') if min_price_timestamp > 0 then   local min_price_time = os.date('*t', min_price_timestamp)   --log('Price: ' .. min_price .. ' EUR/MWh')   --log('Time: ' .. string.format('%02d:%02d', min_price_time.hour, min_price_time.min))   cheapest_time['hour'] = min_price_time.hour   cheapest_time['minute'] = min_price_time.min   grp.write(cheapest_time_addr, cheapest_time)   grp.write(cheapest_price_addr, min_price) else   log('Could not find minimum price for today') end costliest_time = {} costliest_time['wday'] = current_date['wday'] --log('--- Costliest 15-min Interval Today ---') if max_price_timestamp > 0 then   local max_price_time = os.date('*t', max_price_timestamp)   --log('Price: ' .. max_price .. ' EUR/MWh')   --log('Time: ' .. string.format('%02d:%02d', max_price_time.hour, max_price_time.min))   costliest_time['hour'] = max_price_time.hour   costliest_time['minute'] = max_price_time.min   grp.write(costliest_time_addr, costliest_time)   grp.write(costliest_price_addr, max_price) else   log('Could not find maximum price for today') end

Attached Files
.lua   electricity_price_20251006_04.lua (Size: 5.5 KB / Downloads: 5)
Reply
#4
(06.10.2025, 12:51)RomansP Wrote: Hi!

We have rewritten script (old script will not work properly), because of a change
in time intervals (previously electricity price was per hour, now per 15 minutes).

Here is a new script:

Code:
https = require('ssl.https') json = require('json') ltn12 = require('ltn12') country = 'lv' -- Latvia --country = 'fi' -- Finland --country = 'lt' -- Lithuania --country = 'ee' -- Estonia current_price_addr = '40/1/18' cheapest_hour_addr = '40/1/16' cheapest_hour_price_addr = '40/1/17' costliest_hour_addr = '40/1/19' cosltiest_hour_price_addr = '40/1/20' cheapest_time_addr = '40/1/14' cheapest_price_addr = '40/1/15' costliest_time_addr = '40/1/21' costliest_price_addr = '40/1/22' 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 = os.time({year = current_date.year, month = current_date.month, day = current_date.day, hour = 23, min = 59, sec = 59}) local current_ts = os.time() previous_date = os.date('%F', os.time() - 24*60*60) next_date = os.date('%F', os.time() + 24*60*60) url = 'https://dashboard.elering.ee/api/nps/price?start='.. previous_date ..'T00%3A00%3A00.999Z&end=' .. next_date ..'T00%3A00%3A00.999Z' mac = 0 io.readfile('/sys/class/net/eth0/address'):gsub('%x%x', function(v)   mac = mac * 256 + tonumber(v, 16) end) response = {} res, code = https.request({   url = url,   protocol = 'tlsv12',   headers = {     ['user-agent'] = 'LM ' .. mac   },   sink = ltn12.sink.table(response) }) if res and code == 200 then   data = json.pdecode(table.concat(response)) else   log('request error', res, code)   return end min_price = 99999 max_price = -1 min_price_timestamp = 0 max_price_timestamp = 0 current_price = nil hourly_prices = {} for h = 0, 23 do   hourly_prices[h] = { sum = 0, count = 0 } end if not data or not data.data or not data.data[country] then   log('No data for country: ' .. country)   return end for _, record in ipairs(data.data[country]) do   local timestamp = record.timestamp   local price = record.price   if timestamp >= day_start_ts and timestamp <= day_end_ts then         if price < min_price then       min_price = price       min_price_timestamp = timestamp     end         if price > max_price then       max_price = price       max_price_timestamp = timestamp     end     local record_time = os.date('*t', timestamp)     local hour = record_time.hour     if hourly_prices[hour] then       hourly_prices[hour].sum = hourly_prices[hour].sum + price       hourly_prices[hour].count = hourly_prices[hour].count + 1     end   end     if current_ts >= timestamp and current_ts < (timestamp + 15 * 60) then     current_price = price   end end --log('--- Current Status ---') if current_price then   --log('Current 15-min price: ' .. current_price .. ' EUR/MWh')   grp.write(current_price_addr, current_price) -- float else   log('Could not determine current price') end min_avg_price = 99999 max_avg_price = -1 cheapest_hour = -1 costliest_hour = -1 for hour, data in pairs(hourly_prices) do   if data.count > 0 then     local avg_price = data.sum / data.count     --log(string.format("Hour %02d:00 - Avg Price: %.2f", hour, avg_price))         if avg_price < min_avg_price then       min_avg_price = avg_price       cheapest_hour = hour     end     if avg_price > max_avg_price then       max_avg_price = avg_price       costliest_hour = hour     end   end end cheapest_hour_time = {} cheapest_hour_time['wday'] = current_date['wday'] --log('--- Cheapest Hour Today ---') if cheapest_hour ~= -1 then   --log(string.format('Hour: %02d:00 - %02d:59', cheapest_hour, cheapest_hour))   --log(string.format('Average Price: %.2f EUR/MWh', min_avg_price))   cheapest_hour_time['hour'] = cheapest_hour   grp.write(cheapest_hour_addr, cheapest_hour_time)   grp.write(cheapest_hour_price_addr, min_avg_price) else   log('Could not calculate the cheapest hour.') end costliest_hour_time = {} costliest_hour_time['wday'] = current_date['wday'] --log('--- Costliest Hour Today ---') if costliest_hour ~= -1 then   --log(string.format('Hour: %02d:00 - %02d:59', costliest_hour, costliest_hour))   --log(string.format('Average Price: %.2f EUR/MWh', max_avg_price))   costliest_hour_time['hour'] = costliest_hour   grp.write(costliest_hour_addr, costliest_hour_time)   grp.write(cosltiest_hour_price_addr, max_avg_price) else   log('Could not calculate the costliest hour.') end cheapest_time = {} cheapest_time['wday'] = current_date['wday'] --log('--- Cheapest 15-min Interval Today ---') if min_price_timestamp > 0 then   local min_price_time = os.date('*t', min_price_timestamp)   --log('Price: ' .. min_price .. ' EUR/MWh')   --log('Time: ' .. string.format('%02d:%02d', min_price_time.hour, min_price_time.min))   cheapest_time['hour'] = min_price_time.hour   cheapest_time['minute'] = min_price_time.min   grp.write(cheapest_time_addr, cheapest_time)   grp.write(cheapest_price_addr, min_price) else   log('Could not find minimum price for today') end costliest_time = {} costliest_time['wday'] = current_date['wday'] --log('--- Costliest 15-min Interval Today ---') if max_price_timestamp > 0 then   local max_price_time = os.date('*t', max_price_timestamp)   --log('Price: ' .. max_price .. ' EUR/MWh')   --log('Time: ' .. string.format('%02d:%02d', max_price_time.hour, max_price_time.min))   costliest_time['hour'] = max_price_time.hour   costliest_time['minute'] = max_price_time.min   grp.write(costliest_time_addr, costliest_time)   grp.write(costliest_price_addr, max_price) else   log('Could not find maximum price for today') end

What about Denmark Smile
Reply
#5
Hi,

We will prepare script for Denmark, Sweden, Norway and Germany
Reply
#6
Hello,

We have prepared script for electricity prices for Denmark, Norway, Sweden and Germany

Code:
price_area = 'DK1' -- west Denmark DK1 grid region --price_area = 'DK2' -- east Denmark DK2 grid region --price_area = 'DE' -- Germany --price_area = 'NO2' -- southern and southwestern Norway --price_area = 'SE3' -- north Sweden --price_area = 'SE4' -- south Sweden current_price_addr = '40/1/18' -- 14. 4 byte floating point cheapest_hour_addr = '40/1/16' -- 10. 3 byte time / day cheapest_hour_price_addr = '40/1/17' -- 14. 4 byte floating point costliest_hour_addr = '40/1/19' -- 10. 3 byte time / day costliest_hour_price_addr = '40/1/20' -- 14. 4 byte floating point start_date = os.date('%Y-%m-%d') end_date = os.date('%Y-%m-%d', os.time() + 48 * 60 * 60) url = 'https://api.energidataservice.dk/dataset/DayAheadPrices?start=' ..       start_date .. '&end=' .. end_date ..       '&filter={"PriceArea":["' .. price_area .. '"]}' resp, code = require('socket.http').request(url) if resp and code == 200 then   data = require('json').pdecode(resp) else   log('request error', resp, code)   return end if not data or not data.records then   log('No data for price area: ' .. price_area)   return end curr_day = tonumber(os.date('%u')) next_day = curr_day == 7 and 1 or (curr_day + 1) curr_date = os.date('%Y%m%d') curr_hour_str = curr_date .. os.date('%H') curr_hour = tonumber(curr_hour_str) curr_min = math.floor(tonumber(os.date('%M')) / 15) * 15 curr_ts = curr_hour_str .. string.format('%02d', curr_min) prices = {} for _, record in ipairs(data.records) do   ts = record.TimeDK:gsub('%-', ''):gsub('T', ''):gsub(':', '')   hour = tonumber(ts:sub(1, 10))   price = record.DayAheadPriceEUR   if hour >= curr_hour then     store = prices[ hour ] or { sum = 0, count = 0 }     store.sum = store.sum + price     store.count = store.count + 1     prices[ hour ] = store   end   if ts:sub(1, 12) == curr_ts then     curr_price = price   end end hourly = {} for hour, store in pairs(prices) do   price = store.sum / store.count   hourly[ #hourly + 1 ] = {     hour = hour,     price = price   } end table.sort(hourly, function(a, b)   return a.price > b.price end) function update(store, hour_addr, price_addr)   local hour = tostring(store.hour)   local date = hour:sub(1, 8)   local day = date == curr_date and curr_day or next_day   grp.checkupdate(hour_addr, { day = day, hour = hour:sub(9, 10) })   grp.checkupdate(price_addr, store.price) end grp.checkupdate(current_price_addr, curr_price) update(hourly[1], costliest_hour_addr, costliest_hour_price_addr) update(hourly[#hourly], cheapest_hour_addr, cheapest_hour_price_addr)

Attached Files
.lua   electricity_price_dk_20251013.lua (Size: 2.49 KB / Downloads: 3)
Reply
#7
(19.12.2022, 18:08)martins.neibergs@gmail.com Wrote: Hi!

Has anyone had any experience with getting (integrating) NordPool prices into LogicMachine?

Tried different versions but nothing worked. 

What about this one? 

https://dashboard.elering.ee/en/nps/pric...59:59.999Z
https://dashboard.elering.ee/api/nps/pri...%3A00.999Z

Anyone had any luck or experience? Can you please share scripts for getting NordPool prices into logic machine?

Hi!
I do two scripts
Both "Scheduled"
Script 1 -
Collecting electric price from API. running 4 times/day hour 17,18,21,23 amd minute 5.
Code:
CODE -- API-skript (spara per datum) local json = require("json") local ltn12 = require("ltn12") local http = require("socket.http") local DECIMALS = 5 local PRISKLASS = "SE2" local function fetch_prices(date_timestamp)     local year = os.date("%Y", date_timestamp)     local month_day = os.date("%m-%d", date_timestamp)     local url = string.format("https://www.elprisetjustnu.se/api/v1/prices/%s/%s_%s.json", year, month_day, PRISKLASS)     local resp = {}     local res, code = http.request({url = url, method = "GET", sink = ltn12.sink.table(resp)})     if code == 200 then         local decoded = json.pdecode(table.concat(resp))         if decoded then             local prices = {}             for i,v in ipairs(decoded) do                 local time_start = v.time_start -- "2025-09-10T21:15:00+02:00"                 local hh = string.sub(time_start, 12, 13)                 local mm = string.sub(time_start, 15, 16)                 local val = tonumber(string.format("%." .. DECIMALS .. "f", v.SEK_per_kWh))                 if mm == "00" then                     -- timpris: duplicera till kvart                     for _, q in ipairs({"00","15","30","45"}) do                         prices[hh .. ":" .. q] = val                     end                 else                     prices[hh .. ":" .. mm] = val                 end             end             return prices         end     end     return nil end local function save_prices()     local now = os.time()     -- idag och imorgon som timestamps (midnatt)     local t = os.date("*t", now)     t.hour, t.min, t.sec = 0,0,0     local idag_ts = os.time(t)     local imorgon_ts = idag_ts + 86400     -- Spara dagens priser i storage med datumnyckel     local ds_idag = os.date("%Y-%m-%d", idag_ts)     local p_idag = fetch_prices(idag_ts)     if p_idag then         storage.set("elpris_" .. ds_idag, json.encode(p_idag))         log("Sparade elpriser för " .. ds_idag)     else         log("️ Kunde inte hämta priser för " .. ds_idag)     end     -- Spara morgondagens priser (förutsatt kl 18+ eller när du vill hämta)     if tonumber(os.date("%H", now)) >= 18 then         local ds_im = os.date("%Y-%m-%d", imorgon_ts)         local p_im = fetch_prices(imorgon_ts)         if p_im then             storage.set("elpris_" .. ds_im, json.encode(p_im))             log("Sparade elpriser för " .. ds_im)         else             log("️ Kunde inte hämta priser för " .. ds_im)         end     end     -- Rensa gamla nycklar (behåll t.ex. -3..+2 dagar)     for i = 4, 30 do         local old = os.date("%Y-%m-%d", idag_ts - i*86400)         storage.set("elpris_" .. old, nil)     end end save_prices()


Script 2
Writing current electrical price to KNX address
Running as scheduled minute 0,15,30,45
Code:
local json = require("json") local GA_ELPRIS = "34/4/99" local function round_to_quarter()     local now = os.time()     local hh = tonumber(os.date("%H", now))     local min = tonumber(os.date("%M", now))     min = math.floor(min / 15) * 15     return string.format("%02d:%02d", hh, min) end -- försök hitta pris i dataset för en specifik datumnyckel local function find_in_date(date_str, hhmm)     local key = "elpris_" .. date_str     local j = storage.get(key)     if not j then return nil end     local prices = json.decode(j)     if not prices then return nil end     local p = prices[hhmm]     if p then return p, key end     -- fallback: sök närmaste tidigare kvart inom detta dataset     local hh = tonumber(string.sub(hhmm,1,2))     local mm = tonumber(string.sub(hhmm,4,5))     local kvart_list = {0,15,30,45}     for h = hh, 0, -1 do         for i = #kvart_list, 1, -1 do             local q = kvart_list[i]             if (h < hh) or (q <= mm) then                 local try = string.format("%02d:%02d", h, q)                 if prices[try] then                     return prices[try], key, try                 end             end         end     end     return nil end -- Huvudfunktion som provar datum i prioriterad ordning local function get_price_for_quarter()     local now = os.time()     local hhmm = round_to_quarter()     local date_today = os.date("%Y-%m-%d", now)     local date_tomorrow = os.date("%Y-%m-%d", now + 86400)     local date_yesterday = os.date("%Y-%m-%d", now - 86400)     local candidates = {date_today, date_tomorrow, date_yesterday}     for _, d in ipairs(candidates) do         local p, used_key, used_q = find_in_date(d, hhmm)         if p then             -- used_q kan vara nil om exakt hhmm träffade; annars är used_q den kvarten vi använde             local used = used_q or hhmm             return p, used, used_key         end     end     return nil, hhmm, nil end -- Anropa och skriv till KNX local pris, used_hhmm, used_key = get_price_for_quarter() if pris then     local pris_5dec = string.format("%.5f", pris)     log(string.format("Skriver elpris kl %s (från %s): %s kr/kWh", used_hhmm, used_key or "ingen", pris_5dec))     grp.write(GA_ELPRIS, tonumber(pris_5dec)) else     log("️ Ingen elprisinformation hittades för " .. used_hhmm) end
Reply
#8
Hello,

Here is a new script for a hourly pricing for Latvia, Finland, Lithuania, Estonia

Code:
country = 'lv' -- Latvia --country = 'fi' -- Finland --country = 'lt' -- Lithuania --country = 'ee' -- Estonia current_hour_price_addr = '43/1/2' cheapest_hour_addr = '43/1/3' cheapest_hour_price_addr = '43/1/4' costliest_hour_addr = '43/1/5' costliest_hour_price_addr = '43/1/6' 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 = os.time({year = current_date.year, month = current_date.month, day = current_date.day, hour = 23, min = 59, sec = 59}) local previous_date = os.date('%F', os.time() - 24 * 60 * 60) local next_date = os.date('%F', os.time() + 24 * 60 * 60) local url = 'https://dashboard.elering.ee/api/nps/price?start=' .. previous_date .. 'T00%3A00%3A00.999Z&end=' .. next_date .. 'T00%3A00%3A00.999Z' --log(url) local res, code = require('socket.http').request(url) if not (res and code == 200) then   log('request error: ', res, code)   return end local data = require('json').pdecode(res) if not data or not data.data or not data.data[country] then   log('No data for country: ' .. country)   return end local hourly_prices = {} for h = 0, 23 do   hourly_prices[h] = { sum = 0, count = 0 } end for _, record in ipairs(data.data[country]) do   local timestamp = record.timestamp   local price = record.price   if timestamp >= day_start_ts and timestamp <= day_end_ts then     local record_time = os.date('*t', timestamp)     local hour = record_time.hour     if hourly_prices[hour] then       hourly_prices[hour].sum = hourly_prices[hour].sum + price       hourly_prices[hour].count = hourly_prices[hour].count + 1     end   end end local min_avg_price = 99999 local max_avg_price = -1 local cheapest_hour = -1 local costliest_hour = -1 local current_hour_avg_price = nil for hour, price_data in pairs(hourly_prices) do   if price_data.count > 0 then     local avg_price = price_data.sum / price_data.count     log(string.format("Average price per hour %02d:00 - %.2f EUR/MWh", hour, avg_price))     if avg_price < min_avg_price then       min_avg_price = avg_price       cheapest_hour = hour     end     if avg_price > max_avg_price then       max_avg_price = avg_price       costliest_hour = hour     end         if hour == current_date.hour then       current_hour_avg_price = avg_price     end   end end if current_hour_avg_price then   log(string.format('Price for current hour (%02d:00): %.2f EUR/MWh', current_date.hour, current_hour_avg_price))   grp.write(current_hour_price_addr, current_hour_avg_price) end if cheapest_hour ~= -1 then   log(string.format('Cheapest hour: %02d:00, Price: %.2f EUR/MWh', cheapest_hour, min_avg_price))   local cheapest_hour_time = { wday = current_date.wday, hour = cheapest_hour }   grp.write(cheapest_hour_addr, cheapest_hour_time)   grp.write(cheapest_hour_price_addr, min_avg_price) else   log('Could not calculate the cheapest hour.') end if costliest_hour ~= -1 then   log(string.format('Costliest hour: %02d:00, Price: %.2f EUR/MWh', costliest_hour, max_avg_price))   local costliest_hour_time = { wday = current_date.wday, hour = costliest_hour }   grp.write(costliest_hour_addr, costliest_hour_time)   grp.write(costliest_hour_price_addr, max_avg_price) else   log('Could not calculate the costliest hour.') end

Attached Files
.lua   electricity_price_lv_20260202.lua (Size: 3.37 KB / Downloads: 2)
Reply


Forum Jump: