----------------------------------------------------------------------------------------- -- -- scene01.lua -- Datenansicht Scene -- ----------------------------------------------------------------------------------------- local composer = require("composer") local widget = require("widget") local AskiRepository = require("askirepository") local scene = composer.newScene() -- Globale Variablen für Datenabruf local selectedDate = nil local devices = nil local currentCookie = nil -- ----------------------------------------------------------------------------------- -- Scene event functions -- ----------------------------------------------------------------------------------- -- Hilfsfunktion: Hole Gestern als Datum local function getYesterdayDate() local currentTime = os.time() print("Aktuelle Zeit (Timestamp): " .. currentTime) local yesterdayTime = currentTime - (24 * 60 * 60) -- 1 Tag zurück print("Gestern Zeit (Timestamp): " .. yesterdayTime) return os.date("*t", yesterdayTime) end -- Hilfsfunktion: Formatiere Datum für API local function formatDateForAPI(dateTable, isEndOfDay) if isEndOfDay then return string.format("%04d-%02d-%02dT23:59:59.999Z", dateTable.year, dateTable.month, dateTable.day) else return string.format("%04d-%02d-%02dT00:00:00.000Z", dateTable.year, dateTable.month, dateTable.day) end end -- Go to Week scene02 local function gotoWeek() composer.gotoScene("scenen.scene02", { effect = "fade", time = 500, params = { devices = devices, cookie = currentCookie } }) end -- create() function scene:create(event) local sceneGroup = self.view -- Hintergrund local bg = display.newRect(sceneGroup, display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight) bg:setFillColor(0.95, 0.95, 0.95) -- Setze Standard-Datum auf gestern selectedDate = getYesterdayDate() 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 (falls neu übermittelt) local deviceDataSets = event.params and event.params.deviceDataSets or nil if event.params then if event.params.devices then devices = event.params.devices end if event.params.cookie then currentCookie = event.params.cookie end end -- Funktion zum Anzeigen der Daten local function displayData(dataSets) -- Entferne alte Daten-Anzeigen (aber nicht Datepicker und Button) for i = sceneGroup.numChildren, 1, -1 do local child = sceneGroup[i] if child._isDataDisplay then child:removeSelf() end end if dataSets and devices then -- Kompaktes Layout local itemHeight = 60 local cardWidth = display.contentWidth - 40 local startY = 190 -- Start nach Datepicker und Button for i, device in ipairs(devices) do local yPos = startY + ((i - 1) * itemHeight) -- Container für jedes Device local itemBg = display.newRoundedRect(sceneGroup, display.contentCenterX, yPos, cardWidth, itemHeight - 8, 6) itemBg:setFillColor(1, 1, 1) itemBg.strokeWidth = 1 itemBg:setStrokeColor(0.85, 0.85, 0.85) itemBg._isDataDisplay = true -- Device Name local nameText = display.newText({ parent = sceneGroup, text = device.name, x = display.contentCenterX - cardWidth/2 + 80, y = yPos - 5, fontSize = 14, font = native.systemFontBold, align = "left" }) nameText:setFillColor(0.2, 0.2, 0.2) nameText._isDataDisplay = true -- Daten extrahieren local dataSet = dataSets[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:match("(%d%d%d%d%-%d%d%-%d%d)") or "" end end end elseif dataSet and dataSet.error then valueText = "Fehler" end -- Wert anzeigen local valueLabel = display.newText({ parent = sceneGroup, text = valueText, x = display.contentCenterX - cardWidth/2 + 80, y = yPos + 12, fontSize = 13, align = "left" }) valueLabel:setFillColor(0.3, 0.6, 0.3) valueLabel._isDataDisplay = true -- Datum (rechts) if dateText ~= "" then local dateLabel = display.newText({ parent = sceneGroup, text = dateText, x = display.contentCenterX + cardWidth/2 - 60, y = yPos, fontSize = 11, align = "right" }) dateLabel:setFillColor(0.5, 0.5, 0.5) dateLabel._isDataDisplay = true end end end end -- Funktion zum Neuladen der Daten local function reloadData() if not currentCookie or not devices or not selectedDate then print("Fehler: Cookie, Devices oder Datum fehlt") return end print("Lade Daten für " .. string.format("%04d-%02d-%02d", selectedDate.year, selectedDate.month, selectedDate.day)) local fromDate = formatDateForAPI(selectedDate, false) local toDate = formatDateForAPI(selectedDate, true) local newDeviceDataSets = {} local completedRequests = 0 local totalRequests = #devices -- Lade-Anzeige local loadingOverlay = display.newRect(sceneGroup, display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight) loadingOverlay:setFillColor(0, 0, 0, 0.5) loadingOverlay._isDataDisplay = true local loadingText = display.newText({ parent = sceneGroup, text = "Lade Daten...", x = display.contentCenterX, y = display.contentCenterY, fontSize = 20, font = native.systemFontBold }) loadingText:setFillColor(1, 1, 1) loadingText._isDataDisplay = true -- Callback für jeden Device local function onDataComplete(deviceName, success, dataSet, response) completedRequests = completedRequests + 1 if success then newDeviceDataSets[deviceName] = dataSet print("✓ Daten empfangen für: " .. deviceName) print(" Typ: " .. type(dataSet)) if type(dataSet) == "table" then print(" Anzahl Einträge: " .. #dataSet) end else newDeviceDataSets[deviceName] = { error = tostring(response) } print("✗ Fehler für " .. deviceName .. ": " .. tostring(response)) end if completedRequests >= totalRequests then -- Entferne Lade-Anzeige loadingOverlay:removeSelf() loadingText:removeSelf() -- Zeige neue Daten displayData(newDeviceDataSets) print("✓ Daten erfolgreich geladen") end end -- Lade Daten für alle Devices for i, device in ipairs(devices) do local function deviceCallback(success, dataSet, response) onDataComplete(device.name, success, dataSet, response) end AskiRepository.getPostHistoricData( "https://api.portal.aski.at/historical_values/power", device.deviceId, fromDate, toDate, currentCookie, deviceCallback ) end end -- Datepicker-Bereich (oben) local datePickerBg = display.newRoundedRect(sceneGroup, display.contentCenterX, 50, display.contentWidth - 40, 60, 8) datePickerBg:setFillColor(1, 1, 1) datePickerBg.strokeWidth = 2 datePickerBg:setStrokeColor(0.3, 0.5, 0.8) local dateLabel = display.newText({ parent = sceneGroup, text = "Datum Auswahl:", x = display.contentCenterX - 80, y = 40, fontSize = 14, font = native.systemFontBold }) dateLabel:setFillColor(0.2, 0.2, 0.2) -- Datum-Anzeige (klickbar) local dateDisplay = display.newText({ parent = sceneGroup, text = string.format("%04d-%02d-%02d", selectedDate.year, selectedDate.month, selectedDate.day), x = display.contentCenterX - 80, y = 60, fontSize = 16, font = native.systemFont }) dateDisplay:setFillColor(0.3, 0.5, 0.8) -- Pfeile zum Datum ändern local prevDayBtn = display.newText({ parent = sceneGroup, text = "◀", x = display.contentCenterX + 30, y = 50, fontSize = 24 }) prevDayBtn:setFillColor(0.3, 0.5, 0.8) local nextDayBtn = display.newText({ parent = sceneGroup, text = "▶", x = display.contentCenterX + 90, y = 50, fontSize = 24 }) nextDayBtn:setFillColor(0.5, 0.5, 0.5) -- Ausgegraut, falls am Maximum -- Funktion zum Aktualisieren der Datumsanzeige local function updateDateDisplay() dateDisplay.text = string.format("%04d-%02d-%02d", selectedDate.year, selectedDate.month, selectedDate.day) -- Prüfe ob "nächster Tag" erlaubt ist local yesterday = getYesterdayDate() local yesterdayTimestamp = os.time(yesterday) local selectedTimestamp = os.time(selectedDate) if selectedTimestamp >= yesterdayTimestamp then nextDayBtn:setFillColor(0.5, 0.5, 0.5) -- Ausgegraut else nextDayBtn:setFillColor(0.3, 0.5, 0.8) -- Aktiv end end -- Event-Handler für Datum-Änderung prevDayBtn:addEventListener("tap", function() local currentTimestamp = os.time(selectedDate) local newTimestamp = currentTimestamp - (24 * 60 * 60) selectedDate = os.date("*t", newTimestamp) updateDateDisplay() end) nextDayBtn:addEventListener("tap", function() local yesterday = getYesterdayDate() local yesterdayTimestamp = os.time(yesterday) local currentTimestamp = os.time(selectedDate) if currentTimestamp < yesterdayTimestamp then local newTimestamp = currentTimestamp + (24 * 60 * 60) selectedDate = os.date("*t", newTimestamp) updateDateDisplay() end end) -- Reload-Button local reloadBtn = widget.newButton({ label = "Daten laden", onRelease = reloadData, emboss = false, shape = "roundedRect", width = 200, height = 40, cornerRadius = 8, fillColor = { default={0.3, 0.6, 0.3, 1}, over={0.2, 0.5, 0.2, 1} }, strokeColor = { default={0.2, 0.4, 0.2, 1}, over={0.1, 0.3, 0.1, 1} }, strokeWidth = 2, labelColor = { default={1, 1, 1}, over={1, 1, 1} }, fontSize = 16, x = display.contentCenterX, y = 120 }) sceneGroup:insert(reloadBtn) -- Zeige initiale Daten oder lade sie neu if deviceDataSets and devices then displayData(deviceDataSets) print("✓ Scene01 geladen mit Datepicker und kompakter Ansicht") elseif devices and currentCookie then -- Wenn wir von einer anderen Scene zurückkommen (z.B. Scene02), -- aber keine neuen Daten mitgebracht haben, lade die Daten neu print("✓ Zurück zu Scene01 - Lade Daten neu...") reloadData() end -- Design für Wochenübersicht Button local weekBtn = widget.newButton({ label = "Zu den letzten 7 Tagen", emboss = false, shape = "roundedRect", width = 200, height = 40, cornerRadius = 8, fillColor = { default = { 0.3, 0.5, 0.8, 1 }, over = { 0.2, 0.4, 0.7, 1 } }, strokeColor = { default = { 0.2, 0.4, 0.2, 1 }, over = { 0.1, 0.3, 0.1, 1 } }, strokeWidth = 2, labelColor = { default = { 1, 1, 1 }, over = { 1, 1, 1 } }, fontSize = 16, x = display.contentCenterX, y = 380 }) -- Event-Listener für Wochenübersicht Button sceneGroup:insert(weekBtn) weekBtn:addEventListener("tap", gotoWeek) 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