scene and function
This commit is contained in:
143
askirepository.lua
Normal file
143
askirepository.lua
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
-----------------------------------------------------------------------------------------
|
||||||
|
--
|
||||||
|
-- askirepository.lua
|
||||||
|
-- ASKI Portal API Repository
|
||||||
|
--
|
||||||
|
-----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local json = require("json")
|
||||||
|
|
||||||
|
local AskiRepository = {}
|
||||||
|
|
||||||
|
-- Cookie-Authentifizierungsfunktion
|
||||||
|
function AskiRepository.getPostCookieAuth(url, email, password, code, callback)
|
||||||
|
-- Erstelle den Request Body
|
||||||
|
local requestBody = json.encode({
|
||||||
|
email = email,
|
||||||
|
password = password,
|
||||||
|
code = code
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Callback-Funktion für die Antwort
|
||||||
|
local function networkListener(event)
|
||||||
|
if event.isError then
|
||||||
|
print("Netzwerkfehler: " .. tostring(event.response))
|
||||||
|
if callback then
|
||||||
|
callback(false, nil, "Netzwerkfehler: " .. tostring(event.response))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("Status Code: " .. event.status)
|
||||||
|
--print("Response: " .. event.response)
|
||||||
|
|
||||||
|
-- Extrahiere Cookie aus den Headers
|
||||||
|
if event.responseHeaders then
|
||||||
|
local cookie = event.responseHeaders["Set-Cookie"] or
|
||||||
|
event.responseHeaders["set-cookie"]
|
||||||
|
|
||||||
|
if cookie then
|
||||||
|
--print("Cookie: " .. cookie)
|
||||||
|
if callback then
|
||||||
|
callback(true, cookie, event.response)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("Kein Cookie in der Antwort gefunden")
|
||||||
|
if callback then
|
||||||
|
callback(false, nil, "Kein Cookie gefunden")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if callback then
|
||||||
|
callback(false, nil, "Keine Headers in der Antwort")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- POST Request Parameter
|
||||||
|
local params = {
|
||||||
|
headers = {
|
||||||
|
["Content-Type"] = "application/json",
|
||||||
|
["Content-Length"] = tostring(#requestBody)
|
||||||
|
},
|
||||||
|
body = requestBody
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Führe den POST Request aus
|
||||||
|
network.request(url, "POST", networkListener, params)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Post Pv Data
|
||||||
|
function AskiRepository.getPostHistoricData(url, deviceId, fromDate, toDate, cookie, callback)
|
||||||
|
-- Erstelle den Request Body
|
||||||
|
local requestBody = json.encode({
|
||||||
|
meters = {
|
||||||
|
{
|
||||||
|
deviceId = deviceId,
|
||||||
|
meterId = 40,
|
||||||
|
meterSubId = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sumTariffs = true,
|
||||||
|
type = 1,
|
||||||
|
tariff = 0,
|
||||||
|
from = fromDate,
|
||||||
|
to = toDate
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Callback-Funktion für die Antwort
|
||||||
|
local function networkListener(event)
|
||||||
|
if event.isError then
|
||||||
|
print("Netzwerkfehler: " .. tostring(event.response))
|
||||||
|
if callback then
|
||||||
|
callback(false, nil, "Netzwerkfehler: " .. tostring(event.response))
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("Status Code: " .. event.status)
|
||||||
|
print("Response: " .. event.response)
|
||||||
|
|
||||||
|
-- Prüfe ob Status Code erfolgreich ist (200-299)
|
||||||
|
if event.status >= 200 and event.status < 300 then
|
||||||
|
-- Parse die JSON Response
|
||||||
|
if event.response and event.response ~= "" then
|
||||||
|
local dataSet = json.decode(event.response)
|
||||||
|
if dataSet then
|
||||||
|
print("DataSet erfolgreich empfangen")
|
||||||
|
if callback then
|
||||||
|
callback(true, dataSet, event.response)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("Fehler beim Parsen der Response")
|
||||||
|
if callback then
|
||||||
|
callback(false, nil, "JSON Parse Fehler")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("Leere Response erhalten")
|
||||||
|
if callback then
|
||||||
|
callback(false, nil, "Leere Response")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("HTTP Fehler: " .. event.status)
|
||||||
|
if callback then
|
||||||
|
callback(false, nil, "HTTP Fehler " .. event.status .. ": " .. tostring(event.response))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- POST Request Parameter
|
||||||
|
local params = {
|
||||||
|
headers = {
|
||||||
|
["Content-Type"] = "application/json",
|
||||||
|
["Content-Length"] = tostring(#requestBody),
|
||||||
|
["Cookie"] = cookie
|
||||||
|
},
|
||||||
|
body = requestBody
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Führe den POST Request aus
|
||||||
|
network.request(url, "POST", networkListener, params)
|
||||||
|
end
|
||||||
|
|
||||||
|
return AskiRepository
|
||||||
119
main.lua
119
main.lua
@@ -4,5 +4,122 @@
|
|||||||
--
|
--
|
||||||
-----------------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
-- Your code here
|
-- Importiere das ASKI Repository
|
||||||
|
local AskiRepository = require("askirepository")
|
||||||
local json = require("json")
|
local json = require("json")
|
||||||
|
local composer = require("composer")
|
||||||
|
|
||||||
|
-- Konfiguration Authentifizierungsfunktion
|
||||||
|
local postAuthUrl = "https://api.portal.aski.at/auth/login"
|
||||||
|
local email = "David.aschl@ifn-holding.com"
|
||||||
|
local password = "20IFN25"
|
||||||
|
local code = ""
|
||||||
|
local cookie = nil
|
||||||
|
|
||||||
|
-- Konfiguration für den Abruf von Daten mit Cookie-Authentifizierungsfunktion
|
||||||
|
local fromDate = "2026-05-07T00:00:00.000Z"
|
||||||
|
local toDate = "2026-05-07T23:59:59.999Z"
|
||||||
|
local postDataUrl = "https://api.portal.aski.at/historical_values/power"
|
||||||
|
local devices = {
|
||||||
|
{
|
||||||
|
deviceId = "08dd1489-1129-4774-81ed-9bf1ce3f580d",
|
||||||
|
name = "Traun"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deviceId = "08dd20cd-9d7f-4a2e-897a-3be55c3bfec3",
|
||||||
|
name = "Lannach"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deviceId = "08dd0ac5-7510-4990-8124-39cf64ec7e71",
|
||||||
|
name = "Sarleinsbach"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
local deviceDataSets = {}
|
||||||
|
local completedRequests = 0
|
||||||
|
local totalRequests = 0
|
||||||
|
|
||||||
|
-- Einfache Lade-Anzeige
|
||||||
|
local background = display.newRect(display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight)
|
||||||
|
background:setFillColor(0.95, 0.95, 0.95)
|
||||||
|
|
||||||
|
local loadingText = display.newText({
|
||||||
|
text = "Verbinde mit Server...",
|
||||||
|
x = display.contentCenterX,
|
||||||
|
y = display.contentCenterY,
|
||||||
|
fontSize = 24,
|
||||||
|
font = native.systemFont
|
||||||
|
})
|
||||||
|
loadingText:setFillColor(0.3, 0.3, 0.8)
|
||||||
|
|
||||||
|
-- Callback-Funktion für den Datenabruf (wird für jedes Device aufgerufen)
|
||||||
|
local function onDataComplete(deviceName, success, dataSet, response)
|
||||||
|
completedRequests = completedRequests + 1
|
||||||
|
|
||||||
|
if success then
|
||||||
|
print("✓ Datenabruf für " .. deviceName .. " erfolgreich!")
|
||||||
|
deviceDataSets[deviceName] = dataSet
|
||||||
|
else
|
||||||
|
print("✗ Datenabruf für " .. deviceName .. " fehlgeschlagen: " .. tostring(response))
|
||||||
|
deviceDataSets[deviceName] = { error = tostring(response) }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Aktualisiere Status
|
||||||
|
loadingText.text = string.format("Lade Daten... (%d/%d)", completedRequests, totalRequests)
|
||||||
|
|
||||||
|
-- Wenn alle Requests abgeschlossen sind, wechsle zur Scene
|
||||||
|
if completedRequests >= totalRequests then
|
||||||
|
print("✓ Alle DataSets geladen - Wechsle zur Scene01")
|
||||||
|
|
||||||
|
-- Entferne Lade-Anzeige
|
||||||
|
loadingText:removeSelf()
|
||||||
|
background:removeSelf()
|
||||||
|
|
||||||
|
-- Wechsle zur Datenansicht-Scene und übergebe die Daten
|
||||||
|
composer.gotoScene("scenen.scene01", {
|
||||||
|
effect = "fade",
|
||||||
|
time = 500,
|
||||||
|
params = {
|
||||||
|
deviceDataSets = deviceDataSets,
|
||||||
|
devices = devices
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Callback-Funktion für die Authentifizierung
|
||||||
|
local function onAuthComplete(success, receivedCookie, response)
|
||||||
|
if success then
|
||||||
|
print("✓ Authentifizierung erfolgreich!")
|
||||||
|
print("✓ Cookie erhalten und kann verwendet werden")
|
||||||
|
|
||||||
|
loadingText.text = "Authentifiziert - Lade Daten..."
|
||||||
|
|
||||||
|
-- Hier kannst du mit dem Cookie weiterarbeiten
|
||||||
|
cookie = receivedCookie
|
||||||
|
print("✓ Cookie: " .. cookie)
|
||||||
|
|
||||||
|
-- Setze die Anzahl der erwarteten Requests
|
||||||
|
totalRequests = #devices
|
||||||
|
completedRequests = 0
|
||||||
|
|
||||||
|
-- Rufe die Datenabruf-Funktion für alle Devices auf
|
||||||
|
for i, device in ipairs(devices) do
|
||||||
|
print("Lade Daten für " .. device.name .. " (" .. device.deviceId .. ")")
|
||||||
|
|
||||||
|
-- Erstelle einen spezifischen Callback für dieses Device
|
||||||
|
local function deviceCallback(success, dataSet, response)
|
||||||
|
onDataComplete(device.name, success, dataSet, response)
|
||||||
|
end
|
||||||
|
|
||||||
|
AskiRepository.getPostHistoricData(postDataUrl, device.deviceId, fromDate, toDate, cookie, deviceCallback)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print("✗ Authentifizierung fehlgeschlagen: " .. tostring(response))
|
||||||
|
loadingText.text = "✗ Authentifizierung fehlgeschlagen"
|
||||||
|
loadingText:setFillColor(0.8, 0.2, 0.2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Rufe die Authentifizierungsfunktion auf
|
||||||
|
AskiRepository.getPostCookieAuth(postAuthUrl, email, password, code, onAuthComplete)
|
||||||
157
scenen/scene01.lua
Normal file
157
scenen/scene01.lua
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
-----------------------------------------------------------------------------------------
|
||||||
|
--
|
||||||
|
-- scene01.lua
|
||||||
|
-- Datenansicht Scene
|
||||||
|
--
|
||||||
|
-----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
local composer = require("composer")
|
||||||
|
local json = require("json")
|
||||||
|
|
||||||
|
local scene = composer.newScene()
|
||||||
|
|
||||||
|
-- -----------------------------------------------------------------------------------
|
||||||
|
-- Scene event functions
|
||||||
|
-- -----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
-- create()
|
||||||
|
function scene:create(event)
|
||||||
|
local sceneGroup = self.view
|
||||||
|
-- Kein Hintergrund, keine UI-Elemente
|
||||||
|
end
|
||||||
|
|
||||||
|
-- show()
|
||||||
|
function scene:show(event)
|
||||||
|
local sceneGroup = self.view
|
||||||
|
local phase = event.phase
|
||||||
|
|
||||||
|
if phase == "will" then
|
||||||
|
-- Code hier wird ausgeführt, wenn die Scene noch off-screen ist (aber im Begriff ist, on-screen zu kommen)
|
||||||
|
|
||||||
|
elseif phase == "did" then
|
||||||
|
-- Code hier wird ausgeführt, wenn die Scene komplett on-screen ist
|
||||||
|
|
||||||
|
-- Hole die übergebenen Daten
|
||||||
|
local deviceDataSets = event.params.deviceDataSets
|
||||||
|
local devices = event.params.devices
|
||||||
|
|
||||||
|
if deviceDataSets and devices then
|
||||||
|
-- Berechne Layout
|
||||||
|
local itemHeight = 90
|
||||||
|
local cardWidth = display.contentWidth - 60
|
||||||
|
local totalHeight = #devices * itemHeight
|
||||||
|
local startY = (display.contentHeight - totalHeight) / 2 + (itemHeight / 2)
|
||||||
|
|
||||||
|
for i, device in ipairs(devices) do
|
||||||
|
local yPos = startY + ((i - 1) * itemHeight)
|
||||||
|
|
||||||
|
-- Container für jedes Device (zentral)
|
||||||
|
local itemBg = display.newRoundedRect(sceneGroup, display.contentCenterX, yPos, cardWidth, itemHeight - 10, 8)
|
||||||
|
itemBg:setFillColor(1, 1, 1)
|
||||||
|
itemBg.strokeWidth = 2
|
||||||
|
itemBg:setStrokeColor(0.85, 0.85, 0.85)
|
||||||
|
|
||||||
|
-- Device Name (Titel)
|
||||||
|
local nameText = display.newText({
|
||||||
|
parent = sceneGroup,
|
||||||
|
text = device.name,
|
||||||
|
x = display.contentCenterX,
|
||||||
|
y = yPos - 25,
|
||||||
|
fontSize = 18,
|
||||||
|
font = native.systemFontBold,
|
||||||
|
align = "center"
|
||||||
|
})
|
||||||
|
nameText:setFillColor(0.2, 0.2, 0.2)
|
||||||
|
|
||||||
|
-- Daten extrahieren
|
||||||
|
local dataSet = deviceDataSets[device.name]
|
||||||
|
local valueText = "Keine Daten"
|
||||||
|
local dateText = ""
|
||||||
|
|
||||||
|
if dataSet and not dataSet.error then
|
||||||
|
if type(dataSet) == "table" and #dataSet > 0 then
|
||||||
|
local meterData = nil
|
||||||
|
for _, meter in ipairs(dataSet) do
|
||||||
|
if meter.deviceId == device.deviceId then
|
||||||
|
meterData = meter
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if meterData and meterData.values and #meterData.values > 0 then
|
||||||
|
local firstValue = meterData.values[1]
|
||||||
|
if firstValue.value then
|
||||||
|
valueText = string.format("%.2f kW", firstValue.value)
|
||||||
|
end
|
||||||
|
if firstValue.datetime then
|
||||||
|
dateText = firstValue.datetime
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif dataSet and dataSet.error then
|
||||||
|
valueText = "Fehler: " .. dataSet.error
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Wert anzeigen
|
||||||
|
local valueLabel = display.newText({
|
||||||
|
parent = sceneGroup,
|
||||||
|
text = valueText,
|
||||||
|
x = display.contentCenterX,
|
||||||
|
y = yPos,
|
||||||
|
fontSize = 16,
|
||||||
|
align = "center"
|
||||||
|
})
|
||||||
|
valueLabel:setFillColor(0.3, 0.6, 0.3)
|
||||||
|
|
||||||
|
-- Datum anzeigen (falls vorhanden)
|
||||||
|
if dateText ~= "" then
|
||||||
|
local formattedDate = dateText:match("(%d%d%d%d%-%d%d%-%d%d)")
|
||||||
|
if formattedDate then
|
||||||
|
local dateLabel = display.newText({
|
||||||
|
parent = sceneGroup,
|
||||||
|
text = "📅 " .. formattedDate,
|
||||||
|
x = display.contentCenterX,
|
||||||
|
y = yPos + 25,
|
||||||
|
fontSize = 12,
|
||||||
|
align = "center"
|
||||||
|
})
|
||||||
|
dateLabel:setFillColor(0.5, 0.5, 0.5)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
print("✓ Scene01 geladen mit zentral angeordneten Datenboxen")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- hide()
|
||||||
|
function scene:hide(event)
|
||||||
|
local sceneGroup = self.view
|
||||||
|
local phase = event.phase
|
||||||
|
|
||||||
|
if phase == "will" then
|
||||||
|
-- Code hier wird ausgeführt, wenn die Scene on-screen ist (aber im Begriff ist, off-screen zu gehen)
|
||||||
|
|
||||||
|
elseif phase == "did" then
|
||||||
|
-- Code hier wird ausgeführt, unmittelbar nachdem die Scene off-screen gegangen ist
|
||||||
|
-- ScrollView-Inhalt wird automatisch mit der Scene entfernt
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- destroy()
|
||||||
|
function scene:destroy(event)
|
||||||
|
local sceneGroup = self.view
|
||||||
|
print("Scene01 zerstört")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- -----------------------------------------------------------------------------------
|
||||||
|
-- Scene event function listeners
|
||||||
|
-- -----------------------------------------------------------------------------------
|
||||||
|
scene:addEventListener("create", scene)
|
||||||
|
scene:addEventListener("show", scene)
|
||||||
|
scene:addEventListener("hide", scene)
|
||||||
|
scene:addEventListener("destroy", scene)
|
||||||
|
-- -----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return scene
|
||||||
Reference in New Issue
Block a user