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: 21)
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: 3)
Reply
#4
(Yesterday, 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


Forum Jump: