Release v0.2.1

This commit is contained in:
2026-08-22 15:14:11 +02:00
parent d6a4b4c27e
commit 8685f462c3
3 changed files with 159 additions and 11 deletions
+8
View File
@@ -1,5 +1,13 @@
# Changelog # Changelog
## [0.2.1]
### Fixed
- Fixed inconsistent IP scroll-speed calculation between timing and rendering
### Added
- Repository URL to script metadata
## [0.2.0] ## [0.2.0]
### Added ### Added
- `MY IP` intro - `MY IP` intro
+150 -10
View File
@@ -1,7 +1,8 @@
# @name InternetMonitor # @name InternetMonitor
# @desc Public IPv4 and Internet status monitor # @desc Public IPv4 and Internet status monitor
# @author Spectral # @author Spectral
# @version 0.2.0 # @version 0.2.1
# @url https://git.mike-lindner.net/mike/awtrix-ng-internet-monitor
# @config refresh number "Prüfintervall" default=60 min=30 max=1800 unit=s # @config refresh number "Prüfintervall" default=60 min=30 max=1800 unit=s
# @config retry_seconds number "Fehler-Retry" default=15 min=5 max=60 unit=s # @config retry_seconds number "Fehler-Retry" default=15 min=5 max=60 unit=s
# @config fail_threshold number "Offline nach Fehlern" default=3 min=1 max=10 # @config fail_threshold number "Offline nach Fehlern" default=3 min=1 max=10
@@ -17,105 +18,182 @@ class InternetMonitor
var refreshms, retryms, threshold var refreshms, retryms, threshold
var introms, viewms var introms, viewms
var speed, onlinec, offlinec, infoc var speed, onlinec, offlinec, infoc
var state, flight, attempt, fails var state, flight, attempt, fails
var nextcheck var nextcheck
var ip, ipw var ip, ipw
var xintro, xon, xoff, xcheck var xintro, xon, xoff, xcheck
var phase, phaseat var phase, phaseat
var scrollat, scrollms var scrollat, scrollms
def init() def init()
self.url1="https://api.ipify.org" self.url1="https://api.ipify.org"
self.url2="https://checkip.global.api.aws/" self.url2="https://checkip.global.api.aws/"
self.refreshms=store.get("refresh")*1000 self.refreshms=store.get("refresh")*1000
self.retryms=store.get("retry_seconds")*1000 self.retryms=store.get("retry_seconds")*1000
self.threshold=store.get("fail_threshold") self.threshold=store.get("fail_threshold")
self.introms=store.get("intro_seconds")*1000 self.introms=store.get("intro_seconds")*1000
self.viewms=store.get("view_seconds")*1000 self.viewms=store.get("view_seconds")*1000
self.speed=store.get("scroll_speed") self.speed=store.get("scroll_speed")
self.onlinec=store.get("online_color") self.onlinec=store.get("online_color")
self.offlinec=store.get("offline_color") self.offlinec=store.get("offline_color")
self.infoc=store.get("info_color") self.infoc=store.get("info_color")
# state:
# 0 = noch kein sicherer Zustand
# 1 = online
# -1 = offline
self.state=0 self.state=0
self.flight=false self.flight=false
self.attempt=0 self.attempt=0
self.fails=0 self.fails=0
# Sofort nach dem Start prüfen
self.nextcheck=0 self.nextcheck=0
# Letzte bekannte öffentliche IPv4 übernehmen
self.ip=store.get("ip") self.ip=store.get("ip")
if self.ip==nil if self.ip==nil
self.ip="---.---.---.---" self.ip="---.---.---.---"
end end
self.ipw=text_width(self.ip) self.ipw=text_width(self.ip)
# Textpositionen vorberechnen
self.xintro=(width()-text_ink_width("MY IP"))/2 self.xintro=(width()-text_ink_width("MY IP"))/2
self.xon=7+(width()-7-text_ink_width("ONLINE"))/2 self.xon=7+(width()-7-text_ink_width("ONLINE"))/2
self.xoff=7+(width()-7-text_ink_width("OFFLINE"))/2 self.xoff=7+(width()-7-text_ink_width("OFFLINE"))/2
self.xcheck=(width()-text_ink_width("CHECK"))/2 self.xcheck=(width()-text_ink_width("CHECK"))/2
# Phasen:
# 0 = normale Rotation
# 1 = MY IP
# 2 = ONLINE / OFFLINE / CHECK
# 3 = Rainbow-IP
self.phase=0 self.phase=0
self.phaseat=0 self.phaseat=0
self.scrollat=0 self.scrollat=0
self.scrollms=0 self.scrollms=0
end end
def on_body(b,st) def on_body(b,st)
var m=nil var m=nil
# Diese Version verarbeitet bewusst nur IPv4.
if b!=nil && st>=200 && st<300 if b!=nil && st>=200 && st<300
m=re.search("([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)",b) m=re.search(
"([0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+)",
b
)
end end
# Primärer Dienst fehlgeschlagen:
# AWS einmal als Fallback versuchen
if m==nil if m==nil
if self.attempt==0 if self.attempt==0
self.attempt=1 self.attempt=1
http.get(self.url2,/ b,s -> self.on_body(b,s))
http.get(
self.url2,
/ b,s -> self.on_body(b,s)
)
return return
end end
# Beide Dienste in diesem Prüfzyklus fehlgeschlagen
self.flight=false self.flight=false
self.fails+=1 self.fails+=1
# Nach Fehler schneller erneut prüfen
self.nextcheck=now_ms()+self.retryms self.nextcheck=now_ms()+self.retryms
# Erst nach mehreren aufeinanderfolgenden
# Fehlerzyklen wirklich OFFLINE melden
if self.fails>=self.threshold if self.fails>=self.threshold
self.state=-1 self.state=-1
store.set("online",false) store.set("online",false)
end end
return return
end end
# Erfolgreiche Antwort
self.flight=false self.flight=false
self.fails=0 self.fails=0
self.state=1 self.state=1
self.ip=m[1] self.ip=m[1]
self.ipw=text_width(self.ip) self.ipw=text_width(self.ip)
# Wieder normales Prüfintervall verwenden
self.nextcheck=now_ms()+self.refreshms self.nextcheck=now_ms()+self.refreshms
store.set("ip",self.ip) store.set("ip",self.ip)
store.set("online",true) store.set("online",true)
end end
def loop() def loop()
var n=now_ms() var n=now_ms()
# Internet/Public-IPv4 prüfen
if !self.flight && n>=self.nextcheck if !self.flight && n>=self.nextcheck
self.flight=true self.flight=true
self.attempt=0 self.attempt=0
# Mehrfachen Request-Start verhindern
self.nextcheck=n+self.refreshms self.nextcheck=n+self.refreshms
http.get(self.url1,/ b,s -> self.on_body(b,s))
http.get(
self.url1,
/ b,s -> self.on_body(b,s)
)
end end
# MY IP Intro
if self.phase==1 if self.phase==1
if n-self.phaseat>=self.introms if n-self.phaseat>=self.introms
self.phase=2 self.phase=2
self.phaseat=n self.phaseat=n
end end
# ONLINE / OFFLINE / CHECK
elif self.phase==2 elif self.phase==2
if n-self.phaseat>=self.viewms if n-self.phaseat>=self.viewms
if self.state==1 if self.state==1
self.phase=3 self.phase=3
self.scrollat=n self.scrollat=n
# 100 % entsprechen ungefähr 21 Pixel/s
var pxps=21*self.speed/100 var pxps=21*self.speed/100
if pxps<1 if pxps<1
pxps=1 pxps=1
end end
# Strecke eines vollständigen Durchlaufs
var run=width()+self.ipw var run=width()+self.ipw
# Zwei vollständige IP-Durchläufe
self.scrollms=int(run*1000/pxps)*2 self.scrollms=int(run*1000/pxps)*2
else else
self.phase=0 self.phase=0
rotation.resume() rotation.resume()
rotation.next() rotation.next()
end end
end end
# Rainbow-IP nach zwei Durchläufen beenden
elif self.phase==3 elif self.phase==3
if n-self.scrollat>=self.scrollms if n-self.scrollat>=self.scrollms
self.phase=0 self.phase=0
@@ -128,48 +206,110 @@ class InternetMonitor
def on_show() def on_show()
self.phase=1 self.phase=1
self.phaseat=now_ms() self.phaseat=now_ms()
# Eigene Sequenz vollständig anzeigen
rotation.pause() rotation.pause()
end end
def draw() def draw()
clear() clear()
# Intro
if self.phase==1 if self.phase==1
text(self.xintro,6,"MY IP",self.infoc) text(
self.xintro,
6,
"MY IP",
self.infoc
)
return return
end end
# Noch kein sicherer Zustand
if self.state==0 if self.state==0
text(self.xcheck,6,"CHECK",self.infoc) text(
self.xcheck,
6,
"CHECK",
self.infoc
)
return return
end end
# Offline erst nach bestätigten Fehlerzyklen
if self.state<0 if self.state<0
line(1,2,5,6,self.offlinec) line(1,2,5,6,self.offlinec)
line(1,6,5,2,self.offlinec) line(1,6,5,2,self.offlinec)
text(self.xoff,6,"OFFLINE",self.offlinec)
text(
self.xoff,
6,
"OFFLINE",
self.offlinec
)
return return
end end
# Online
if self.phase==2 if self.phase==2
line(1,4,2,5,self.onlinec) line(1,4,2,5,self.onlinec)
line(2,5,5,2,self.onlinec) line(2,5,5,2,self.onlinec)
text(self.xon,6,"ONLINE",self.onlinec)
text(
self.xon,
6,
"ONLINE",
self.onlinec
)
return return
end end
# Animierte Rainbow-IP
if self.phase==3 if self.phase==3
var n=now_ms() var n=now_ms()
# Wichtig: gleiche Berechnung wie in loop()
var pxps=21*self.speed/100 var pxps=21*self.speed/100
if pxps<1 if pxps<1
pxps=1 pxps=1
end end
# Länge eines vollständigen Durchlaufs
var run=width()+self.ipw var run=width()+self.ipw
# Dauer eines Durchlaufs
var runms=int(run*1000/pxps) var runms=int(run*1000/pxps)
# Zeit innerhalb des aktuellen Durchlaufs.
# Beim zweiten Durchlauf wieder bei 0 beginnen.
var elapsed=(n-self.scrollat)%runms var elapsed=(n-self.scrollat)%runms
# Scrollposition
var px=int(elapsed*pxps/1000) var px=int(elapsed*pxps/1000)
var x=width()-px var x=width()-px
# Animierter HSV-Regenbogen.
# Beide Durchläufe starten mit derselben Farbphase.
var ph=int(elapsed/20)%360 var ph=int(elapsed/20)%360
for i : 0 .. size(self.ip)-1 for i : 0 .. size(self.ip)-1
x+=text(x,6,self.ip[i],hsv((ph+i*30)%360,100,100)) x+=text(
x,
6,
self.ip[i],
hsv(
(ph+i*30)%360,
100,
100
)
)
end end
end end
end end
end end
return InternetMonitor() return InternetMonitor()
+1 -1
View File
@@ -78,7 +78,7 @@ Version 0.2.0 supports public IPv4 only.
6. Configure it under **Apps → InternetMonitor → Settings** if required. 6. Configure it under **Apps → InternetMonitor → Settings** if required.
## Version ## Version
**0.2.0** **0.2.1**
## Author ## Author
Spectral Spectral