diff --git a/CHANGELOG.md b/CHANGELOG.md index a3dcf01..cff91d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.2.1] + +### Fixed +- Fixed inconsistent IP scroll-speed calculation between timing and rendering + +### Added +- Repository URL to script metadata + ## [0.2.0] ### Added - `MY IP` intro diff --git a/InternetMonitor.ax b/InternetMonitor.ax index 8cadb1a..abd786a 100644 --- a/InternetMonitor.ax +++ b/InternetMonitor.ax @@ -1,7 +1,8 @@ # @name InternetMonitor # @desc Public IPv4 and Internet status monitor # @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 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 @@ -17,105 +18,182 @@ class InternetMonitor var refreshms, retryms, threshold var introms, viewms var speed, onlinec, offlinec, infoc + var state, flight, attempt, fails var nextcheck + var ip, ipw var xintro, xon, xoff, xcheck + var phase, phaseat var scrollat, scrollms def init() self.url1="https://api.ipify.org" self.url2="https://checkip.global.api.aws/" + self.refreshms=store.get("refresh")*1000 self.retryms=store.get("retry_seconds")*1000 self.threshold=store.get("fail_threshold") + self.introms=store.get("intro_seconds")*1000 self.viewms=store.get("view_seconds")*1000 self.speed=store.get("scroll_speed") + self.onlinec=store.get("online_color") self.offlinec=store.get("offline_color") self.infoc=store.get("info_color") + + # state: + # 0 = noch kein sicherer Zustand + # 1 = online + # -1 = offline self.state=0 + self.flight=false self.attempt=0 self.fails=0 + + # Sofort nach dem Start prüfen self.nextcheck=0 + + # Letzte bekannte öffentliche IPv4 übernehmen self.ip=store.get("ip") + if self.ip==nil self.ip="---.---.---.---" end + self.ipw=text_width(self.ip) + + # Textpositionen vorberechnen self.xintro=(width()-text_ink_width("MY IP"))/2 self.xon=7+(width()-7-text_ink_width("ONLINE"))/2 self.xoff=7+(width()-7-text_ink_width("OFFLINE"))/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.phaseat=0 + self.scrollat=0 self.scrollms=0 end def on_body(b,st) var m=nil + + # Diese Version verarbeitet bewusst nur IPv4. 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 + + # Primärer Dienst fehlgeschlagen: + # AWS einmal als Fallback versuchen if m==nil if self.attempt==0 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 end + + # Beide Dienste in diesem Prüfzyklus fehlgeschlagen self.flight=false self.fails+=1 + + # Nach Fehler schneller erneut prüfen self.nextcheck=now_ms()+self.retryms + + # Erst nach mehreren aufeinanderfolgenden + # Fehlerzyklen wirklich OFFLINE melden if self.fails>=self.threshold self.state=-1 store.set("online",false) end + return end + + # Erfolgreiche Antwort self.flight=false self.fails=0 self.state=1 + self.ip=m[1] self.ipw=text_width(self.ip) + + # Wieder normales Prüfintervall verwenden self.nextcheck=now_ms()+self.refreshms + store.set("ip",self.ip) store.set("online",true) end def loop() var n=now_ms() + + # Internet/Public-IPv4 prüfen if !self.flight && n>=self.nextcheck self.flight=true self.attempt=0 + + # Mehrfachen Request-Start verhindern 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 + + # MY IP Intro if self.phase==1 if n-self.phaseat>=self.introms self.phase=2 self.phaseat=n end + + # ONLINE / OFFLINE / CHECK elif self.phase==2 if n-self.phaseat>=self.viewms + if self.state==1 self.phase=3 self.scrollat=n + + # 100 % entsprechen ungefähr 21 Pixel/s var pxps=21*self.speed/100 + if pxps<1 pxps=1 end + + # Strecke eines vollständigen Durchlaufs var run=width()+self.ipw + + # Zwei vollständige IP-Durchläufe self.scrollms=int(run*1000/pxps)*2 + else self.phase=0 rotation.resume() rotation.next() end end + + # Rainbow-IP nach zwei Durchläufen beenden elif self.phase==3 if n-self.scrollat>=self.scrollms self.phase=0 @@ -128,48 +206,110 @@ class InternetMonitor def on_show() self.phase=1 self.phaseat=now_ms() + + # Eigene Sequenz vollständig anzeigen rotation.pause() end def draw() clear() + + # Intro if self.phase==1 - text(self.xintro,6,"MY IP",self.infoc) + text( + self.xintro, + 6, + "MY IP", + self.infoc + ) return end + + # Noch kein sicherer Zustand if self.state==0 - text(self.xcheck,6,"CHECK",self.infoc) + text( + self.xcheck, + 6, + "CHECK", + self.infoc + ) return end + + # Offline erst nach bestätigten Fehlerzyklen if self.state<0 line(1,2,5,6,self.offlinec) line(1,6,5,2,self.offlinec) - text(self.xoff,6,"OFFLINE",self.offlinec) + + text( + self.xoff, + 6, + "OFFLINE", + self.offlinec + ) + return end + + # Online if self.phase==2 line(1,4,2,5,self.onlinec) line(2,5,5,2,self.onlinec) - text(self.xon,6,"ONLINE",self.onlinec) + + text( + self.xon, + 6, + "ONLINE", + self.onlinec + ) + return end + + # Animierte Rainbow-IP if self.phase==3 var n=now_ms() + + # Wichtig: gleiche Berechnung wie in loop() var pxps=21*self.speed/100 + if pxps<1 pxps=1 end + + # Länge eines vollständigen Durchlaufs var run=width()+self.ipw + + # Dauer eines Durchlaufs var runms=int(run*1000/pxps) + + # Zeit innerhalb des aktuellen Durchlaufs. + # Beim zweiten Durchlauf wieder bei 0 beginnen. var elapsed=(n-self.scrollat)%runms + + # Scrollposition var px=int(elapsed*pxps/1000) + var x=width()-px + + # Animierter HSV-Regenbogen. + # Beide Durchläufe starten mit derselben Farbphase. var ph=int(elapsed/20)%360 + 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 -return InternetMonitor() +return InternetMonitor() \ No newline at end of file diff --git a/README.md b/README.md index b86f760..81426a7 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Version 0.2.0 supports public IPv4 only. 6. Configure it under **Apps → InternetMonitor → Settings** if required. ## Version -**0.2.0** +**0.2.1** ## Author Spectral