Logic Machine Forum
External eletric pricing on API - Printable Version

+- Logic Machine 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: External eletric pricing on API (/showthread.php?tid=3865)



External eletric pricing on API - Tue - 09.02.2022

Hello there

I'm newbee to scripting to a API, I need you help to get me startet. I can from bellow link get the eletric pricing for the next 24 hours (is updated everyday at 14:00 for the next day)

https://api.energidataservice.dk/datastore_search?resource_id=elspotprices&filters=%7B%22HourDK%22:%222022-02-09T10:00:00%22,%22PriceArea%22:%22DK1%22%7D

I do have some docomentation for it:

https://www.energidataservice.dk/guides/api-guides

And I do know that I need to make some ssl.https.request(url) there I change from current time (date = os.date('*t')) and make a new string with date.time and so on. But anybody that can help me in the right directions?

I want to make a routine that charges my eletrich car in the correct time, I ca get acces to my car date here: https://www.platform.tronity.io/ (still working progess on how for me :-)) https://app.platform.tronity.io/docs

In advance thx


RE: External eletric pricing on API - Tue - 09.02.2022

(09.02.2022, 09:20)Tue Wrote: Hello there

I'm newbee to scripting to a API, I need you help to get me startet. I can from bellow link get the eletric pricing for the next 24 hours (is updated everyday at 14:00 for the next day)

https://api.energidataservice.dk/datastore_search?resource_id=elspotprices&filters=%7B%22HourDK%22:%222022-02-09T10:00:00%22,%22PriceArea%22:%22DK1%22%7D

I do have some docomentation for it:

https://www.energidataservice.dk/guides/api-guides

And I do know that I need to make some ssl.https.request(url) there I change from current time (date = os.date('*t')) and make a new string with date.time and so on. But anybody that can help me in the right directions?

I want to make a routine that charges my eletrich car in the correct time, I ca get acces to my car date here: https://www.platform.tronity.io/ (still working progess on how for me :-)) https://app.platform.tronity.io/docs

In advance thx


This is what I got so far, how do I decode json in Lua?

Code:
--[[************************************************************************************************
Created: 2022-02-09
Get eletric pricing from Norpol and set car charge when good :-)
************************************************************************************************]]--
require('json')
https = require 'ssl.https'
local date = os.date('*t')
local data = ' '
local url = ' '

for i=1, 24 do
  date.hour = date.hour + 1
  if date.hour > 23 then
    date.day = date.day + 1
    date.hour = 0
  end  -- Missing if month changes or year (to come later)
 
    data = date.year .. '-' .. date.month .. '-' .. date.day .. 'T' .. date.hour .. ':00:00' -- Make the date/clock string to request
    url = 'https://api.energidataservice.dk/datastore_search?resource_id=elspotprices&filters=%7B%22HourDK%22:%22' .. data .. '%22,%22PriceArea%22:%22DK1%22%7D' -- Here is the requst string :-)
    status = ssl.https.request(url) -- Here comes reply from server

  log(status) -- How do I decode it and get it into a time table
end

--[[
This is returned format..:
{
  "help": "https://api.energidataservice.dk/help_show?name=datastore_search",
  "success": true,
  "result": {
    "include_total": true,
    "resource_id": "c86859d2-942e-4029-aec1-32d56f1a2e5d",
    "fields": [
      {
        "type": "int",
        "id": "_id"
      },
      {
        "type": "timestamptz",
        "id": "HourUTC"
      },
      {
        "type": "timestamp",
        "id": "HourDK"
      },
      {
        "type": "text",
        "id": "PriceArea"
      },
      {
        "type": "float8",
        "id": "SpotPriceDKK"
      },
      {
        "type": "float8",
        "id": "SpotPriceEUR"
      }
    ],
    "records_format": "objects",
    "records": [
      {
        "_id": 2023070,
        "HourUTC": "2022-02-09T09:00:00+00:00",
        "HourDK": "2022-02-09T10:00:00",
        "PriceArea": "DK1",
        "SpotPriceDKK": 885.32, <-***************************** This is the value what I need ***********************
        "SpotPriceEUR": 118.94
      }
    ],
    "_links": {
      "start": "/datastore_search?filters=%7B%22HourDK%22%3A%222022-02-09T10%3A00%3A00%22%2C%22PriceArea%22%3A%22DK1%22%7D&resource_id=elspotprices",
      "next": "/datastore_search?offset=100&filters=%7B%22HourDK%22%3A%222022-02-09T10%3A00%3A00%22%2C%22PriceArea%22%3A%22DK1%22%7D&resource_id=elspotprices"
    },
    "filters": {
      "HourDK": "2022-02-09T10:00:00",
      "PriceArea": "DK1"
    },
    "total": 1
  }
} ]]--



RE: External eletric pricing on API - admin - 09.02.2022

Get the date/time for the next hour in proper format:
Code:
os.date('%Y-%m-%dT%H:00:00', os.time() + 3600)

Then decode the status data:
Code:
data = json.decode(status)
price = data.result.records[1].SpotPriceDKK
log(price)



RE: External eletric pricing on API - Tue - 10.02.2022

Hello there

Thax alot, now that works :-)
Code:
--[[************************************************************************************************
Created: 2022-02-09
Get eletric pricing from Norpol the next 24 hours and set car charge when good :-)
It works now, needs to sort out lowest rates and so on
************************************************************************************************]]--

require('json')
https = require 'ssl.https'
local data = ' '
local url = ' '
local priser = {klokken, pris}
local end_i = 11

-- if hour is <= 13 it must stop at 23 hours (no new prices yet)
-- if hour is > 13 there are prices until followering midnight (more than 24 hours
if tonumber(os.date('%H', os.time())) <= 12 then
  end_i = 23 - tonumber(os.date('%H', os.time()))
else
  end_i = (23 - tonumber(os.date('%H', os.time()))) + 24
end

-- Get prices for the next hours, defined in "end_i"
-- Prices are from Norpol energy trader
-- They are from west region Denmark
for i=0, end_i do
  data = os.date('%Y-%m-%dT%H:00:00', (os.time() + (3600*i)))
    url = 'https://api.energidataservice.dk/datastore_search?resource_id=elspotprices&filters=%7B%22HourDK%22:%22' .. data .. '%22,%22PriceArea%22:%22DK1%22%7D' -- Here is the requst string :-)
    status = ssl.https.request(url) -- Here comes reply from server
  data = json.decode(status) -- Decode the Json file
    price = data.result.records[1].SpotPriceDKK / 1000 -- Find price in DKK ører for bellow time
  time = data.result.records[1].HourDK -- Time of above price expected
 
  -- Extra cost from 17 to 20 hour at Konstant net (as we uses)
  if (os.date('%H' , (os.time() + (3600*i)))) == '17' or (os.date('%H' , (os.time() + (3600*i)))) == '18' or (os.date('%H' , (os.time() + (3600*i)))) == '19' then
    price = price + konstant_ekstra_tariff_17_20
  end

    priser[i] = {klokken = tonumber(os.date('%H' , os.time() + (3600*i))),pris = price}-- store price and time for price
end
log(priser) -- Here are recorded data

-- find when prices are lowest in the forcast
local pos = 0
local tester = 20
for i=0, end_i do
  if tester > priser[i].pris then
    pos = i
    tester = priser[i].pris
  end 
end
log (priser[pos]) -- This is the most cheap hour

now there comes a new challanges, I want to find state of EV car, It is now posible for me to get the POST that makes me get the Bearer Authorization, but cannot get it out of the string?, and from there how do I make ep GET command with it?

Code:
--[[************************************************************************************************
Created: 2022-02-10
Get state of charge from car
************************************************************************************************]]--
require('socket.http')
function encodepost(t)
  local res = {}
  local esc = require('socket.url').escape

  for k, v in pairs(t) do
    res[ #res + 1 ] = esc(k) .. '=' .. esc(v)
  end

  return table.concat(res, '&')
end

url = 'https://api-eu.TRONITY.io/oauth/authentication'

payload = encodepost({
  client_id = "WRITE IT HERE",
  client_secret = "WRITE IT HERE",
  grant_type = "app"
})

res, err, headers, status = socket.http.request(url, payload)
--log(res, err, headers, status)

if err == 201 then -- Get Bearer Authorization
    log(res) -- Here is the Bearer Authorization in how do I get the access_token out? And how do I do a json GET with that token?
end

THIS IS MY res string, where I need to get access_token value/string out from:

string: {"id":"cfed0e4d6351407dae165944745d48f","access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJjZmVkMGU0ZC02MzUxLTQwN2QtYWUxNi0yNTk0NDc0NWQ0OGYiLCJhcHBJZCI6Ijg3NzhjMTM4LTQ0ODgtNGU2Ni1iMmZhLTY3NGUyYmQ2NGYyMiIsInZlaGljbGVJZCI6bnVsbCwic2NvcGVzIjpbInJlYWRfYmF0dGVyeSIsInJlYWRfY2FyZHMiLCJyZWFkX2NoYXJnZXBvaW50cyIsInJlYWRfaWRsZXMiLCJyZWFkX2xvY2F0aW9uIiwicmVhZF9vZG9tZXRlciIsInJlYWeHAiOjE2NDQ1OTU0ODQsImF1ZCI6Imh0dHBzOi8vcGxhdGZvcm0udHJvbml0eS5pbyIsImlzcyI6InBsYXRmb3JtLnRyb25pdHkuaW8ifQ.AWboomF9whW6udiSzWsWyWvlhu9ZpmdEN9IKrbFOHIM","expires_in":3600,"token_type":"bearer"}

And this is my URL I need to GET with above bearer Authorization

url = 'https://api-eu.TRONITY.io/v1/vehicles/{CAR ID HERE}/bulk'


RE: External eletric pricing on API - Erwin van der Zwart - 10.02.2022

Code:
require('json')
if err == 201 then -- Get Bearer Authorization 
  --log(res) -- Here is the Bearer Authorization in how do I get the access_token out? And how do I do a json GET with that token?
 
  data = json.pdecode(res)
  tokentype = data.token_type
  accesstoken = data.access_token
  expiresin = data.expires_in
  id = data.id

  log(tokentype)
  log(accesstoken)
  log(expiresin)
  log(id)
end
Here is an sample of integration i wrote with authentication token renewal that uses the expire stamp of the token, with this sample you should be able to create what you want to do
Code:
-- Load required packages
require('ltn12')
require('socket.http')
require("json")

-- START OF SETTINGS ************************************************************

-- Set credentials
username = "xxxxx"
password = "xxxxx"

-- END OF SETTINGS **************************************************************

-- START OF FUNCTIONS ***********************************************************
function GetAuthData()
  local request_url = 'https://xxxx.com/api/v3/xxx/auth'
  local response_body = {}
  local request_body = json.encode(
    {
      email = username,
      password = password
    }
  )
  local body, code, hdrs, stat = socket.http.request{
    url = request_url;
    method = "POST";
    headers =
    {
      ["Content-Type"] = "application/json";
      ["Content-Length"] = #request_body;
    };
    source = ltn12.source.string(request_body);
    sink = ltn12.sink.table(response_body);
  }
  if code == 200 then
    ret = table.concat(response_body)
    ret = json.pdecode(ret)
    ret.expires_at = os.time() + ret.expires_in
    return ret
  end
end

function APIRequest(method, api_key, request, requestdata)
  local request_url = 'https://xxxx.xxxx.com/api/v3' .. request
  local response_body = {}
  local request_body = requestdata
  local body, code, hdrs, stat = socket.http.request{
    url = request_url;
    method = method;
    headers =
    {
      ["Content-Type"] = "application/json";
      ['Content-Length'] = #request_body,
      ["Api_key"] = api_key;
    };
    source = ltn12.source.string(request_body);
    sink = ltn12.sink.table(response_body);
  }
  if code == 200 then
    ret = table.concat(response_body)
    ret = json.pdecode(ret)
    return ret
  end
end
-- END OF FUNCTIONS ***********************************************************

-- START OF AUTHENTICATION ****************************************************
if not authdata then
  authdata = GetAuthData()
else
  if authdata.expires_at - 60 < os.time() then
    -- renew authdata
    authdata = GetAuthData()
  end
end
-- END OF AUTENTHICATION ******************************************************

-- START OF DATA REQUESTS *****************************************************

request_data = json.encode({})
resp = APIRequest("GET", authdata.api_key, "/location", request_data)
log(resp)

-- END OF DATA REQUESTS *******************************************************

-- START OF UPDATE REQUESTS ***************************************************
request_data = json.encode({
  id = 12,
  customproperties = {
    {
      label = "mylabel",
      value = "myvalue"
    }
  }
}
)

resp = APIRequest("PUT", authdata.api_key, "/probe", request_data)
log(resp)

request_data = json.encode({
  id = 12,
  name = "new name"
}
)

resp = APIRequest("PUT", authdata.api_key, "/location", request_data)
log(resp)

-- END OF UPDATE REQUESTS *****************************************************



RE: External eletric pricing on API - Tue - 11.02.2022

Got up running THX :-) when done I will post the source code here if anybody else need it :-)

Now I want to edit a Schedule, lets call them, Charge_ev_in_min

How do I edit a schedule from script? I need to do the following:
Set time and date for start
Set value (0-600)
Disable scheduler
Enable scheduler