-- Heizölpreise v1.0.1 RC3 for NI-Neutrino -- Based on satbaby's Heizölpreise v0.6, GPL-2.0-or-later local n=neutrino() local CA='/etc/ssl/certs/ca-certificates.crt' local TMP='/tmp/ni_heizoel24.html' local countries={de={url='https://www.heizoel24.de/heizoelpreise',name='Deutschland'},at={url='https://www.heizoel24.at/heizoelpreise',name='Österreich'}} local function get_page(url) local cmd='curl -4 -sS -L --fail --connect-timeout 12 --max-time 30 --cacert '..CA..' -o '..TMP..' '..url os.remove(TMP) local result=os.execute(cmd) local f=io.open(TMP,'rb') local html=f and f:read('*a') or nil if f then f:close() end os.remove(TMP) if result~=0 and result~=true then return nil,'Download fehlgeschlagen (curl).' end if not html or #html<1000 then return nil,'Keine vollständige Antwort erhalten.' end return html end local function parse(html,country) local h1=html:find('

]*>([%d%.]+,%d%d)') local change=chunk:match('class="font%-weight%-bold"[^>]*>([+%-]?%d+[,.]%d+%%)%s+zum Vortag') if not price then return nil,'Tagespreis nicht gefunden (HTML geändert?).' end return {date=date or 'unbekannt',price=price,change=change or 'nicht verfügbar'} end -- OSD-Aufloesung: fb0/virtual_size ist auf manchen Boxen die -- virtuelle (z.B. doppelt hohe) Speicherflaeche, NICHT die sichtbare OSD-Hoehe. -- Daher NICHT als Fensterkoordinate verwenden! -- Fuer die beiden getesteten OSD-Modi sichere Voreinstellung anhand der Breite. -- Bei abweichender OSD-Aufloesung hier beide Werte manuell eintragen. local OSD_WIDTH_OVERRIDE=0 local OSD_HEIGHT_OVERRIDE=0 local function osd_size() if OSD_WIDTH_OVERRIDE>0 and OSD_HEIGHT_OVERRIDE>0 then return OSD_WIDTH_OVERRIDE,OSD_HEIGHT_OVERRIDE end local f=io.open('/sys/class/graphics/fb0/virtual_size','r') if f then local line=f:read('*l') or '' f:close() local w=tonumber(line:match('^(%d+),')) -- Nur die Breite als Hinweis verwenden; die virtuelle Hoehe ignorieren. if w and w>=640 and w<1700 then return 1280,720 end end return 1920,1080 end local OSD_W,OSD_H=osd_size() local compact=(OSD_W<1700 or OSD_H<900) local function centered_window(w,h) return math.max(0,math.floor((OSD_W-w)/2)),math.max(0,math.floor((OSD_H-h)/2)) end local function show(country) local html,err=get_page(countries[country].url) local data if html then data,err=parse(html,countries[country].name) end local ww,wh=compact and 1100 or 1380,compact and 480 or 500 local wx,wy=centered_window(ww,wh) local win=cwindow.new{x=wx,y=wy,dx=ww,dy=wh, title='Heizölpreise 1.0.1 RC3 - '..countries[country].name, btnBlue='Bundesländer', btnRed='Land wechseln',btnGreen='Schliessen'} local function label(x,y,width,height,value,font,color) ctext.new{parent=win,x=x,y=y,dx=width,dy=height, text=value,font_text=font or FONT.MENU,color_text=color or COL.WHITE} end local content_width=ww-100 if data then local trend=COL.WHITE local arrow='=' if data.change:sub(1,1)=='-' then trend=COL.GREEN arrow='v' elseif data.change:sub(1,1)=='+' then trend=COL.RED arrow='^' end label(48,34,content_width,45,'HEIZOEL | '..countries[country].name,FONT.MENU_TITLE) label(48,105,content_width,85,data.price..' EUR',FONT.MENU_TITLE) label(48,180,content_width,40,'Durchschnittspreis je 100 Liter',FONT.MENU) label(48,240,content_width,55,arrow..' '..data.change..' zum Vortag',FONT.MENU_TITLE,trend) label(48,315,content_width,36,'Stand: '..data.date..' | Quelle: HeizOel24',FONT.MENU) label(48,348,content_width,34,'Durchschnittswert - kein individuelles Angebot',FONT.MENU) else label(48,60,content_width,50,'Preisdaten konnten nicht geladen werden.',FONT.MENU_TITLE,COL.RED) label(48,135,content_width,95,tostring(err),FONT.MENU) label(48,240,content_width,70,countries[country].url,FONT.MENU) end win:paint() local switch=false local states=false while true do local msg=n:GetInput(500) if msg==RC.red then switch=true;break end if msg==RC.blue then states=true;break end if msg==RC.home or msg==RC.setup or msg==RC.exit or msg==RC.green or msg==RC.ok then break end end win:hide() return switch,states end -- Alle 16 Bundesländer alphabetisch sortiert. local regions_de={ {name='Baden-Württemberg',slug='baden-wuerttemberg'}, {name='Bayern',slug='bayern'}, {name='Berlin',slug='berlin'}, {name='Brandenburg',slug='brandenburg'}, {name='Bremen',slug='bremen'}, {name='Hamburg',slug='hamburg'}, {name='Hessen',slug='hessen'}, {name='Mecklenburg-Vorpommern',slug='mecklenburg-vorpommern'}, {name='Niedersachsen',slug='niedersachsen'}, {name='Nordrhein-Westfalen',slug='nordrhein-westfalen'}, {name='Rheinland-Pfalz',slug='rheinland-pfalz'}, {name='Saarland',slug='saarland'}, {name='Sachsen',slug='sachsen'}, {name='Sachsen-Anhalt',slug='sachsen-anhalt'}, {name='Schleswig-Holstein',slug='schleswig-holstein'}, {name='Thüringen',slug='thueringen'}, } -- Österreichische Bundesländer alphabetisch sortiert. local regions_at={ {name='Burgenland',slug='burgenland'}, {name='Kärnten',slug='kaernten'}, {name='Niederösterreich',slug='niederoesterreich'}, {name='Oberösterreich',slug='oberoesterreich'}, {name='Salzburg',slug='salzburg'}, {name='Steiermark',slug='steiermark'}, {name='Tirol',slug='tirol'}, {name='Vorarlberg',slug='vorarlberg'}, {name='Wien',slug='wien'}, } local function parse_region(html,name) local heading='Heizölpreise für '..name local h1=html:find(']*>([%d%.]+,%d%d)') local change=chunk:match('class="font%-weight%-bold"[^>]*>([+%-]?%d+[,.]%d+%%)%s+zum Vortag') if not price then return nil,'Preis nicht gefunden' end return {price=price,date=date or '?',change=change or '?'} end local function show_regions(country) local regions=(country=='at') and regions_at or regions_de local rows={} for i,r in ipairs(regions) do local html,err=get_page(countries[country].url..'/'..r.slug) local data if html then data,err=parse_region(html,r.name) end rows[i]={name=r.name,data=data,err=err} end local ww,wh=compact and 1140 or 1480,compact and 610 or 860 local wx,wy=centered_window(ww,wh) local page=1 local per_page=compact and 8 or #rows local pages=math.ceil(#rows/per_page) local win local function label(x,y,w,h,s,color) ctext.new{parent=win,x=x,y=y,dx=w,dy=h,text=s, font_text=FONT.MENU,color_text=color or COL.WHITE} end local function draw_page() if win then win:hide() end local title='Heizölpreise 1.0.1 RC3 - '..countries[country].name..' - Bundesländer' if compact then title='Heizölpreise - '..countries[country].name..' - Bundesländer' end win=cwindow.new{x=wx,y=wy,dx=ww,dy=wh,title=title,btnBlue='Zurück'} if compact then label(35,25,590,40,'Bundesland') label(640,25,190,40,'EUR/100l') label(860,25,205,40,'Vortag') for slot=1,per_page do local row=rows[(page-1)*per_page+slot] if row then local y=80+(slot-1)*51 local data=row.data local color=COL.WHITE if data and data.change:sub(1,1)=='-' then color=COL.GREEN elseif data and data.change:sub(1,1)=='+' then color=COL.RED end label(35,y,580,45,row.name) label(640,y,190,45,data and data.price or '---') label(860,y,205,45,data and data.change or '---',color) end end label(35,500,620,36,'HeizOel24 | EUR/100l | Seite '..page..'/'..pages) if pages>1 then label(715,500,380,36,'< Seite wechseln >') end else local per_column=(country=='at') and 5 or 8 for col=0,1 do local x=35+col*725 label(x,30,350,40,'Bundesland') label(x+365,30,150,40,'EUR/100l') label(x+530,30,160,40,'Vortag') end for i,row in ipairs(rows) do local col=math.floor((i-1)/per_column) local rownum=(i-1)%per_column local x=35+col*725 local y=95+rownum*70 local data=row.data local color=COL.WHITE if data and data.change:sub(1,1)=='-' then color=COL.GREEN elseif data and data.change:sub(1,1)=='+' then color=COL.RED end if row.name=='Mecklenburg-Vorpommern' then label(x,y-5,355,34,'Mecklenburg-') label(x,y+25,355,34,'Vorpommern') else label(x,y,355,48,row.name) end label(x+365,y,150,48,data and data.price or '---') label(x+530,y,160,48,data and data.change or '---',color) end label(35,690,1370,34,'Durchschnittspreis je 100 Liter | Quelle: HeizOel24') end win:paint() end draw_page() while true do local msg=n:GetInput(500) if msg==RC.blue or msg==RC.home or msg==RC.setup or msg==RC.exit or msg==RC.ok then break end if compact and pages>1 then if msg==RC.right or msg==RC.down then page=(page%pages)+1 draw_page() elseif msg==RC.left or msg==RC.up then page=((page+pages-2)%pages)+1 draw_page() end end end if win then win:hide() end end local country='de' while true do local switch,states=show(country) if states then show_regions(country) elseif switch then country=(country=='de') and 'at' or 'de' else break end end