<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://wiki.freifunk-dresden.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mikaff0</id>
	<title>Freifunk Dresden - Anwender-Wiki - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.freifunk-dresden.de/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mikaff0"/>
	<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php/Spezial:Beitr%C3%A4ge/Mikaff0"/>
	<updated>2026-05-31T16:03:28Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Elbhangfest&amp;diff=8249</id>
		<title>Elbhangfest</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Elbhangfest&amp;diff=8249"/>
		<updated>2026-05-06T09:21:32Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: /* Wer ist da 2026? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projekte]]&lt;br /&gt;
= Netzwerk =&lt;br /&gt;
[[Datei:Elbhangfest-Netzwerk-ab8.0.1.png|mini|Elbhangfest Netzwerk (ab 8.0.1)]]&lt;br /&gt;
&lt;br /&gt;
Es gibt derzeit nur einen Internetzugang vor Ort. Über diesen soll das Elbhangfest mit Freifunk versorgt werden.&amp;lt;br/&amp;gt;&lt;br /&gt;
# Normale Freifunk Knoten verbunden via Mesh-On-VLAN/WAN (am besten Knoten über WLAN ignorieren)&lt;br /&gt;
# Roaming auf den Freifunk Routern Aktiv&lt;br /&gt;
# Offloader für VPN Traffic&lt;br /&gt;
&lt;br /&gt;
== Normale Freifunk Knoten ==&lt;br /&gt;
Die Freifunk Knoten sind via WAN/LAN alle mit einander verbunden. Das Routing-Protokoll tauscht parallel zu den WLAN-Verbindungen auch Routing-Pakete via LAN mit anderen Knoten am LAN aus.&amp;lt;br/&amp;gt;&lt;br /&gt;
Jeder Knoten bietet via &#039;&#039;&#039;SSID&#039;&#039;&#039; &amp;quot;&#039;&#039;Freifunk Dresden&#039;&#039;&amp;quot; ein WLAN-Netz an. Dabei wird die IP Adresse jeweils von jedem Knoten (in seinem Bereich) an das Endgerät verteilt.&amp;lt;br/&amp;gt;&lt;br /&gt;
Ein Roaming ist damit möglich.&lt;br /&gt;
&lt;br /&gt;
= 2026 =&lt;br /&gt;
&lt;br /&gt;
=== Wer ist da 2026? ===&lt;br /&gt;
[[Datei:Wifi FFDD.png|mini]]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Samstag 27.06.26 !! Sonntag 28.06.26&lt;br /&gt;
|-&lt;br /&gt;
| Weesenstein || X || X&lt;br /&gt;
|-&lt;br /&gt;
| Niklas || X || X&lt;br /&gt;
|-&lt;br /&gt;
| Mika ||   || (X)&lt;br /&gt;
|-&lt;br /&gt;
| Name || X || X&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Materialliste: ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Was? !! Name !! Verfügbarkeit geklärt?&lt;br /&gt;
|-&lt;br /&gt;
| Banner 2x || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Pavillon 1x (3x3) || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Pavillon 1x (3x6) || Caleb || ?&lt;br /&gt;
|-&lt;br /&gt;
| Biertischgarnitur 3x &amp;lt;br&amp;gt; (3xTisch + 6xBank) || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Anhänger || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Strom (AKKU`s) || Lodrich || ?&lt;br /&gt;
|-&lt;br /&gt;
| Uplink-Router || Caleb || ?&lt;br /&gt;
|-&lt;br /&gt;
| ? || ? || ?&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= 2025 =&lt;br /&gt;
&lt;br /&gt;
=== Wer war da 2025? ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Samstag 28.06.25 !! Sonntag 29.06.25&lt;br /&gt;
|-&lt;br /&gt;
| Weesenstein || X (8:30 - 17) || X (13 - 18)&lt;br /&gt;
|-&lt;br /&gt;
| Niklas || X (8:30 - 18) || X (9 - 18)&lt;br /&gt;
|-&lt;br /&gt;
| Lodrich || - || X (9 - 18)&lt;br /&gt;
|-&lt;br /&gt;
| Caleb || X Mit 3D Druck und Freifunk || X Mit 3D Druck und Freifunk&lt;br /&gt;
|-&lt;br /&gt;
| Emploi || - || X (9 - 18)&lt;br /&gt;
|-&lt;br /&gt;
| Sten || X (15 - 18) || -&lt;br /&gt;
|-&lt;br /&gt;
| LordAlex || X (8:30 - 12)  || -&lt;br /&gt;
|-&lt;br /&gt;
| Torsten || X (10:00 - 18)  || -&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
[[Datei:Elbhangfest 2025.png|500px|rahmenlos]]&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Materialliste: ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Was? !! Name !! Verfügbarkeit geklärt?&lt;br /&gt;
|-&lt;br /&gt;
| Banner 2x || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Pavillon 1x (3x3) || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Pavillon 1x (3x6) || Caleb || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Biertischgarnitur 4x &amp;lt;br&amp;gt; (4xTisch + 8xBank) || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Anhänger || Lodrich || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Strom (AKKU`s) || Lodrich || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Uplink-Router || Caleb || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Router für Richtfunk || Flint || Ja (nicht nötig)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= 2022 =&lt;br /&gt;
&lt;br /&gt;
=== Wer war da ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Donnerstag !! Freitag !! Samstag !! Sonntag&lt;br /&gt;
|-&lt;br /&gt;
| Sten || X || || || X (zum Abbau)&lt;br /&gt;
|-&lt;br /&gt;
| Emploi || X || || X ||&lt;br /&gt;
|-&lt;br /&gt;
| Flint || X || X || ||&lt;br /&gt;
|-&lt;br /&gt;
| Max || || X (wahrscheinlich erst Nachmittags) || X (wahrscheinlich erst Abends) || X&lt;br /&gt;
|-&lt;br /&gt;
| Stephan || || X (nach Arbeit) || X (Nachmittags) || X&lt;br /&gt;
|-&lt;br /&gt;
| Caleb || || X || X || X&lt;br /&gt;
|-&lt;br /&gt;
| Niklas || || X (bis ~ 17 Uhr) || X ||&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= 2020 =&lt;br /&gt;
- Aufbau Sten&lt;br /&gt;
[[Datei:Speedtest-Elbhangfest.png|mini|Speedtest 18.09.2020]]&lt;br /&gt;
&lt;br /&gt;
=== Zusätzliche config ===&lt;br /&gt;
&lt;br /&gt;
DHCP Futro zeigt clients auf mesh viewer an&lt;br /&gt;
dafür muss im futro folgende Datei bearbeitet werden: usr/lib/ddmes.sysinfo&lt;br /&gt;
ca zeile 161  if(match(&amp;quot;&#039;$wifi2_ifname&#039;&amp;quot;,$6) &amp;amp;&amp;amp; match(&amp;quot;0x2&amp;quot;,$3))  durch ca zeile 161  if(match(&amp;quot;&#039;$lan_ifname&#039;&amp;quot;,$6) &amp;amp;&amp;amp; match(&amp;quot;0x2&amp;quot;,$3)) ersetzen.&lt;br /&gt;
Also wifi2 zu lan.&lt;br /&gt;
&lt;br /&gt;
== Einfaches Roaming (wird nicht mehr benötigt)==&lt;br /&gt;
Jeder Knoten besitzt die Möglichkeit ein privates Wifi Netzwerk aufzubauen. Dieses lässt sich so konfigurieren, dass es unverschlüsselt ist.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dieses dritte Wifi-Netzwerk (es gibt bereits ein Wifi-Adhoc-Netz zum Meshen zwischen Knoten, und eines für die Endgeräte) ist direkt mit den LAN-Ports (gelb) verbunden. Alle Geräte, welche dann sich mit diesem Wifi-Netzwerk verbinden, erhalten ihre IP Adresse von DHCP-Servern in diesem LAN-Netzwerk.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dabei kann der DHCP-Server in dem Router (für LAN Port) oder ein anderer Router im LAN die IP Adresse liefern.&lt;br /&gt;
&lt;br /&gt;
Der Knoten ist so konfiguiert, dass er selber keine IP-Adresse liefert, sondern diese vom &#039;&#039;&#039;Futro 1&#039;&#039;&#039; vergeben wird.&amp;lt;br/&amp;gt;&lt;br /&gt;
Jeder Knoten, der in diesem Netzwerk teilnimmt, nutzt die &#039;&#039;&#039;SSID:&#039;&#039;&#039; &amp;quot;&#039;&#039;Freifunk-Elbhangfest&#039;&#039;&amp;quot;. Da es nun mehrere Knoten mit der gleichen SSID gibt, wechselt ein Endgerät auf einen anderen Router, wenn die Signalstärke zu schwach geworden ist.&amp;lt;br/&amp;gt;&lt;br /&gt;
Das ist kein echtes Roaming und es gibt eine kurze Unterbrechung in der Verbindung.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Da zum Elbhangfest mehrere hundert Leute mit diesem Netz via &amp;quot;&#039;&#039;Freifunk Dresden: Elbhangfest&#039;&#039;&amp;quot; verbunden sein kann, muss &#039;&#039;&#039;Futro 1&#039;&#039;&#039; entsprechend viele IP Adressen vergeben. Entsprechend wurde das LAN wie folgt konfiguriert:&lt;br /&gt;
 Futro 1&lt;br /&gt;
   WAN IP   : DHCP&lt;br /&gt;
   LAN IP   : 192.168.0.1&lt;br /&gt;
   Netzmaske: 255.255.0.0&lt;br /&gt;
   LAN DHCP : 192.168.0.100 - (5000 Nutzer)&lt;br /&gt;
&lt;br /&gt;
 Futro 2&lt;br /&gt;
   WAN IP   : DHCP&lt;br /&gt;
   LAN IP   : 192.168.0.2 / Mesh-On-Lan&lt;br /&gt;
   Netzmaske: 255.255.0.0&lt;br /&gt;
   LAN DHCP : abgeschaltet&lt;br /&gt;
&lt;br /&gt;
 Router IP: 192.168.0.10 (bis 192.168.0.15)&lt;br /&gt;
 Netzmaske: 255.255.0.0&lt;br /&gt;
 Gateway:   0.0.0.0&lt;br /&gt;
 DHCP:      abgeschaltet&lt;br /&gt;
&lt;br /&gt;
[[Datei:Elbhangfest-Network.png|mini|Elbhangfest Netzwerk (pre 8.0.1)]]&lt;br /&gt;
&lt;br /&gt;
= 2018 =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Planung&#039;&#039;&#039;: Max, Stephan, Daniel &amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Aufbau&#039;&#039;&#039;:  Max, Daniel, Janek &amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Betreuung&#039;&#039;&#039;: Max, Stephan, Daniel, Mirko, Micha, Janek, Torsten &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Installation erfolgte bereits am Donnerstag 21.6.2018. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein erster Speedtest ergibt nur &#039;&#039;20Mbit/s im Download und 8Mbit/s im Upload&#039;&#039;, was aber für den zu versorgenden Bereich hoffentlich ausreicht.&lt;br /&gt;
&lt;br /&gt;
Zum Elbhangfest haben uns die Strassenkreuzer kontaktiert. Sie wollen dort zur Veranstaltung ein eigenes Netz via Freifunk aufbauen. Dazu haben wir uns mit ihnen bereits schon einmal zum Wissensaustausch getroffen. Ein weiteres Treffen findet heute statt. Am Donnerstag vor dem Elbhangfest findet der Aufbau des Festgeländes statt, wo wir den Aufbau des Freifunk Netzes begleiten.&lt;br /&gt;
&lt;br /&gt;
Der Internetzugang für die Anbindung an das Freifunknetzwerk wird durch durch die Alte Feuerwache bereitgestellt. Die Technik für diese Veranstaltung wird privat gestellt.&amp;lt;br/&amp;gt;&lt;br /&gt;
Der Zugang zum Internet erfolgt durch verschiedene private Personen, die mit ihren Routern oder Servern zusammen das Netzwerk bilden.&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Sprechstunden-Themen&amp;diff=8248</id>
		<title>Sprechstunden-Themen</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Sprechstunden-Themen&amp;diff=8248"/>
		<updated>2026-05-06T09:16:42Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Verein]][[Category:Sprechstunde]]&lt;br /&gt;
Ein Treffen für Freifunker:innen und Interessent:innen. Themenwünsche können auch gern über die vielfältigen [[Hauptseite|Kontaktmöglichkeiten]] angebracht werden.&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen zur Sprechstunde findet ihr &#039;&#039;&#039;[[Freifunk-Sprechstunde|hier]]&#039;&#039;&#039;. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&#039;&#039;&#039;Bitte beachtet hier Hinweise zur [[Freifunk-Sprechstunde|Anmeldung]] zur Sprechstunde im Rosenwerk.&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Nächster Termin==&lt;br /&gt;
===06.05.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Rosenwerk &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt; ANMELDUNG BEACHTEN &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer ist beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* LA 1521 bricht alle 10 min Verbindungen zu selbstgehosteter BBB Instanz und Hetzner SFTP ab... Troubleshooting&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/LED-Config LEDs] an den Routern&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
* Andreas plant eine Webcam an der Kirche *******. Eventueller Anschluss über FF. Gleichzeitige Befestigung eines Meshcore Repeaters oben auf der Kirche. Kein Uplink möglich --&amp;gt; Brainstorming welchen Knoten man anzapfen kann. &lt;br /&gt;
* Kontakt zum Wums&lt;br /&gt;
* Nutzer mit altem EOL Gerät bezüglich Zyxel Multi Router angeschrieben MT &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt; &lt;br /&gt;
* Erklärung und Optimierung /etc/config/uhttpd MT&lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ Router tausch Aktion die ersten 10 mit einem EOL (im netz länger als 1.1.2026) Gerät bekommen ein aktuelles Tauschgerät. &lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
&lt;br /&gt;
* [[#Ziele 2026 | Ziele 2026]]&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Ziele 2026&#039;&#039;&#039; == &lt;br /&gt;
* 1. Knoten Nummer für neue Gateways wieder im dafür reservierten Bereich. &amp;lt;br&amp;gt;-&amp;gt; Eintragung erfolgt manuell (Anfrage an Stephan@) &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
* 2. Installationsseite (Communitys)&lt;br /&gt;
* 3. Communities (Routing auf Servern)&lt;br /&gt;
* 4. Wireguard für Privates (layer 3) - aktuell ist fastd layer2 vorhanden. Alternativ mit fastd3 (l2tp) (Umbau aufwendig)&lt;br /&gt;
* 5. Wireguard zum direkt Ausleiten. (openvpn raus)&lt;br /&gt;
* 6. Hardware für Verein (Veranstaltung)&lt;br /&gt;
* 7. Weiterentwicklung Firmware&lt;br /&gt;
* 8. Unterstützung weiterer Router&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Vergangene Treffen==&lt;br /&gt;
===29.04.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Shahin&lt;br /&gt;
* Broiler&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* Sten&lt;br /&gt;
* Gast aus Leipzig&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* LA 1521 bricht alle 10 min Verbindungen zu selbstgehosteter BBB Instanz und Hetzner SFTP ab... Troubleshooting&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/LED-Config LEDs] an den Routern&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
* Andreas plant eine Webcam an der Kirche *******. Eventueller Anschluss über FF. Gleichzeitige Befestigung eines Meshcore Repeaters oben auf der Kirche. Kein Uplink möglich --&amp;gt; Brainstorming welchen Knoten man anzapfen kann. &lt;br /&gt;
* Kontakt zum Wums&lt;br /&gt;
* Nutzer mit altem EOL Gerät bezüglich Zyxel Multi Router angeschrieben MT &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt; &lt;br /&gt;
* Erklärung und Optimierung /etc/config/uhttpd MT&lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ Router tausch Aktion die ersten 10 mit einem EOL (im netz länger als 1.1.2026) Gerät bekommen ein aktuelles Tauschgerät. &lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===22.04.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* Mika&lt;br /&gt;
* Stan&lt;br /&gt;
* Hibbo&lt;br /&gt;
* LordAlex&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* LA 1521 bricht alle 10 min Verbindungen zu selbstgehosteter BBB Instanz und Hetzner SFTP ab... Troubleshooting&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/LED-Config LEDs] an den Routern&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
* Andreas plant eine Webcam an der Kirche *******. Eventueller Anschluss über FF. Gleichzeitige Befestigung eines Meshcore Repeaters oben auf der Kirche. Kein Uplink möglich --&amp;gt; Brainstorming welchen Knoten man anzapfen kann. &lt;br /&gt;
* Kontakt zum Wums&lt;br /&gt;
* Gespräch über Zyxel Multi Router&lt;br /&gt;
* Erklärung und Optimierung /etc/config/uhttpd MT&lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ Router tausch Aktion die ersten 10 mit einem EOL (im netz länger als 1.1.2026) Gerät bekommen ein aktuelles Tauschgerät. &lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
===15.04.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Max&lt;br /&gt;
* Hibbo&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* LA 1521 bricht alle 10 min Verbindungen zu selbstgehosteter BBB Instanz und Hetzner SFTP ab... Troubleshooting&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/LED-Config LEDs] an den Routern&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
* Andreas plant eine Webcam an der Kirche *******. Eventueller Anschluss über FF. Gleichzeitige Befestigung eines Meshcore Repeaters oben auf der Kirche. Kein Uplink möglich --&amp;gt; Brainstorming welchen Knoten man anzapfen kann. &lt;br /&gt;
* Kontakt zum Wums&lt;br /&gt;
* Gespräch über Zyxel Multi Router&lt;br /&gt;
* Erklärung und Optimierung /etc/config/uhttpd MT&lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ Router tausch Aktion die ersten 10 mit einem EOL (im netz länger als 1.1.2026) Gerät bekommen ein aktuelles Tauschgerät. &lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===09.04.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Rosenwerk &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Torsten|Torsten]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* Roybaer&lt;br /&gt;
* Stephan&lt;br /&gt;
* Diego&lt;br /&gt;
* Gast1&lt;br /&gt;
* Ole&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/LED-Config LEDs] an den Routern&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
* Andreas plant eine Webcam an der Kirche *******. Eventueller Anschluss über FF. Gleichzeitige Befestigung eines Meshcore Repeaters oben auf der Kirche. Kein Uplink möglich --&amp;gt; Brainstorming welchen Knoten man anzapfen kann. &lt;br /&gt;
* Kontakt zum Wums&lt;br /&gt;
* Gespräch über Zyxel Multi Router&lt;br /&gt;
* Erklärung und Optimierung /etc/config/uhttpd MT&lt;br /&gt;
* Einführung Meshtastic Gast1&lt;br /&gt;
* Spende Aruba&lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ Router tausch Aktion die ersten 10 mit einem EOL (im netz länger als 1.1.2026) Gerät bekommen ein aktuelles Tauschgerät. &lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
===01.04.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* Niklas&lt;br /&gt;
* Stan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/LED-Config LEDs] an den Routern&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
* Andreas plant eine Webcam an der Kirche *******. Eventueller Anschluss über FF. Gleichzeitige Befestigung eines Meshcore Repeaters oben auf der Kirche. Kein Uplink möglich --&amp;gt; Brainstorming welchen Knoten man anzapfen kann. &lt;br /&gt;
* Kontakt zum Wums&lt;br /&gt;
* Gespräch über Zyxel Multi Router&lt;br /&gt;
* Erklärung und Optimierung /etc/config/uhttpd MT&lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ Router tausch Aktion die ersten 10 mit einem EOL (im netz länger als 1.1.2026) Gerät bekommen ein aktuelles Tauschgerät. &lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===25.03.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* Ole&lt;br /&gt;
* Sten&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* Niklas&lt;br /&gt;
* DrBroiler (LE)&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/LED-Config LEDs] an den Routern&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
* Andreas plant eine Webcam an der Kirche *******. Eventueller Anschluss über FF. Gleichzeitige Befestigung eines Meshcore Repeaters oben auf der Kirche. Kein Uplink möglich --&amp;gt; Brainstorming welchen Knoten man anzapfen kann. &lt;br /&gt;
* Kontakt zum Wums&lt;br /&gt;
* Gespräch über Zyxel Multi Router&lt;br /&gt;
* Erklärung und Optimierung /etc/config/uhttpd MT&lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ Router tausch Aktion die ersten 10 mit einem EOL (im netz länger als 1.1.2026) Gerät bekommen ein aktuelles Tauschgerät. &lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===18.03.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* Niklas&lt;br /&gt;
* Christian (Gast)&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
* Andreas plant eine Webcam an der Kirche *******. Eventueller Anschluss über FF. Gleichzeitige Befestigung eines Meshcore Repeaters oben auf der Kirche. Kein Uplink möglich --&amp;gt; Brainstorming welchen Knoten man anzapfen kann. &lt;br /&gt;
* Kontakt zum Wums&lt;br /&gt;
* Gespräch über Zyxel Multi Router&lt;br /&gt;
* Erklärung und Optimierung /etc/config/uhttpd MT&lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
===11.03.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Rosenwerk &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Diego&lt;br /&gt;
* Gast (Löbtau Friedenskirche)&lt;br /&gt;
* Gast (Dresden Altstadt)&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]] (Online)&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
* Andreas plant eine Webcam an der Kirche *******. Eventueller Anschluss über FF. Gleichzeitige Befestigung eines Meshcore Repeaters oben auf der Kirche. Kein Uplink möglich --&amp;gt; Brainstorming welchen Knoten man anzapfen kann. &lt;br /&gt;
* Gespräch über Zyxel Multi Router&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===04.03.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* Niklas&lt;br /&gt;
* Sten&lt;br /&gt;
* Diego&lt;br /&gt;
* Gast Andreas&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
* Andreas plant eine Webcam an der Kirche *******. Eventueller Anschluss über FF. Gleichzeitige Befestigung eines Meshcore Repeaters oben auf der Kirche. Kein Uplink möglich --&amp;gt; Brainstorming welchen Knoten man anzapfen kann. &lt;br /&gt;
* Gespräch über Zyxel Multi Router&lt;br /&gt;
* Freifunk Video für Social Media&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===25.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* Diego&lt;br /&gt;
* Ole&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* Pre-alpha-Firmware (Fehleranalyse bei ZTE MF289F und Ubiquiti UniFi 6 LR v3)&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
===18.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* Ole&lt;br /&gt;
* Stan&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Blaudio&lt;br /&gt;
* LordAlex&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* Beschlüsse vom 12.02.2026:&lt;br /&gt;
** Terminfindung (August/September)? &amp;quot;20 Jahre Freifunk Dresden&amp;quot; &amp;gt; 22.08.2026 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
** Festlegung: Umgang mit Router-Genexis EX400-Spende &amp;gt; 841 ersetzten! &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** ☑ Wer stellt den Kontakt her? [[Benutzer:Hibo98|Niklas]] &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===12.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Rosenwerk &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
* Torsten&lt;br /&gt;
* Sebastian (Gast)&lt;br /&gt;
* Diego&lt;br /&gt;
* Ole&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* Beschlüsse:&lt;br /&gt;
** ☑ Terminfindung (August/September)? &amp;quot;20 Jahre Freifunk Dresden&amp;quot; &amp;gt; 22.08.2026&lt;br /&gt;
** ☑ Festlegung: Umgang mit Router-Genexis EX400-Spende &amp;gt; 841 ersetzten!&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt; (Festlegung am 12.02.2026!) &amp;lt;/font&amp;gt;&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
&lt;br /&gt;
===04.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Sten&lt;br /&gt;
* LordAlex&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
===28.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]] Definitiv zu spät und dann nur aus dem Auto. &lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* Martin LE&lt;br /&gt;
* Sten&lt;br /&gt;
* LordAlex&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===21.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* Ole&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Stan&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☑ Unterstützung des BMFSFJ-Vorhabens „NETZ-Werk-LER“ vom CODIP an der TU Dresden ([[Benutzer:Diego|DJ]])&lt;br /&gt;
* ☑ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
===14.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Rosenwerk &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Sven (Online)&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☑ &amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;envs Matrix Server wird abgeschaltet!&amp;lt;/font&amp;gt; Was wollen wir machen? (evtl. eigenen Server ohne offene Anmeldung nur für Mitglieder des Vereins) (Lode)&lt;br /&gt;
** Vereins-Server: Abstimmung: Nein&lt;br /&gt;
** Jeder sucht sich einen neuen Server!&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
===07.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Emploi&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
==Archiv==&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2025]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2024]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2023]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2022]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2021]]&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2020]]&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2019]]&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2018]]&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=LED-Config&amp;diff=8230</id>
		<title>LED-Config</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=LED-Config&amp;diff=8230"/>
		<updated>2026-04-28T16:20:03Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: /* Router */  Add Cudy RE3000&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Router ==&lt;br /&gt;
&lt;br /&gt;
Ausgabe von:&lt;br /&gt;
&lt;br /&gt;
 for i in /sys/class/leds/*; do echo $i; done&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable zebra toptextcells sortable&amp;quot;  style=&amp;quot;background:white;&lt;br /&gt;
|-&lt;br /&gt;
! Geräte-Name&lt;br /&gt;
! colspan=&amp;quot;12&amp;quot; | LEDs&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 3370&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dsl&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7312&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dect&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7320&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dect&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:info&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7412&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dect&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7530&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:info&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Aruba AP-105&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wlan5g&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | ASUS RT-AX53U&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy AP3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wlan-5ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wlan-2ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;11&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy AP3000 Outdoor v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;11&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy M3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wan-online&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wan-online&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy RE3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wifi5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wifi2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy TR3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:status&lt;br /&gt;
|colspan=&amp;quot;12&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy WR3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:internet&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;8&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy WR3000S v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:internet&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wan-online&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wlan-2ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wlan-5ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;9&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | D-Link COVR-X1860 A1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; |mt76-phy0&lt;br /&gt;
|  olspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:status&lt;br /&gt;
|colspan=&amp;quot;11&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | D-Link DAP-X1860 A1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:rssihigh&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:rssilow&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:rssimedium&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:rssilow&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Genexis Pulse EX400&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan-2ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan-5ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | GL.iNet GL-MT1300&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:run&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:system&lt;br /&gt;
| colspan=&amp;quot;9&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | GL.iNet GL-MT6000&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:run&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:system&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Joy-IT JT-OR750i (8.2.4)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath10k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:status&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Netgear R6120&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wlan2g&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Netgear R6220&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Netgear WAC104&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link Archer C5 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:qss&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link Archer C6 v3 (8.2.7)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wan&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link Archer C60 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath10k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link RE650 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:eth_act&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:eth_link&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wps&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link TL-WDR4300 v1 (8.2.7)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:qss&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link TL-WR1043ND v2 (8.2.7)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link TL-WR1043N v5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan3&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan4&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Xiaomi Mi Router 4A Gigabit Edition&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:yellow&amp;quot; | yellow:status&lt;br /&gt;
|colspan=&amp;quot;6&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Xiaomi Redmi Router AC2100&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Xiaomi Redmi Router AX6S&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:net&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:net&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:power&lt;br /&gt;
|  colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
|colspan=&amp;quot;5&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | YouHua WR1200JS&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:internet&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Zyxel WSM20&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:led1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:led3&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:led4&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:led2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:led5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:system&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Befehle ==&lt;br /&gt;
&lt;br /&gt;
Beispiel LED ein:&lt;br /&gt;
 echo 1 &amp;gt; /sys/class/leds/orange:wan/brightness&lt;br /&gt;
Beispiel LED aus:&lt;br /&gt;
 echo 0 &amp;gt; /sys/class/leds/orange:wan/brightness&lt;br /&gt;
&lt;br /&gt;
Alle aus&lt;br /&gt;
 for i in /sys/class/leds/*; do echo 0 &amp;gt; &amp;quot;$i&amp;quot;/brightness; done&lt;br /&gt;
&lt;br /&gt;
Alle ein&lt;br /&gt;
 for i in /sys/class/leds/*; do echo 1 &amp;gt; &amp;quot;$i&amp;quot;/for i in /sys/class/leds/*; do echo $i; done; done&lt;br /&gt;
&lt;br /&gt;
Herzschlag&lt;br /&gt;
 for i in /sys/class/leds/*; do echo heartbeat &amp;gt; &amp;quot;$i&amp;quot;/trigger; done&lt;br /&gt;
&lt;br /&gt;
Trigger timmer man&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; done&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo 200 &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 200 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; done&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo 1 &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 1 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; done&lt;br /&gt;
&lt;br /&gt;
Psyco&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo 10 &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 100 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; done&lt;br /&gt;
&lt;br /&gt;
Psyco extended&lt;br /&gt;
 n=1; for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo $(($n * 10)) &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo $(($n * 1000)) &amp;gt; &amp;quot;$i&amp;quot;/delay_off; n=$(($n+1));  done&lt;br /&gt;
&lt;br /&gt;
Lauflicht&lt;br /&gt;
 n=1; for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo $((n * 100)) &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 100 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; n=$(($n + 1));done&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=LED-Config&amp;diff=8227</id>
		<title>LED-Config</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=LED-Config&amp;diff=8227"/>
		<updated>2026-04-27T11:21:33Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Router ==&lt;br /&gt;
&lt;br /&gt;
Ausgabe von:&lt;br /&gt;
&lt;br /&gt;
 for i in /sys/class/leds/*; do echo $i; done&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable zebra toptextcells sortable&amp;quot;  style=&amp;quot;background:white;&lt;br /&gt;
|-&lt;br /&gt;
! Geräte-Name&lt;br /&gt;
! colspan=&amp;quot;12&amp;quot; | LEDs&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 3370&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dsl&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7312&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dect&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7320&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dect&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:info&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7412&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dect&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7530&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:info&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Aruba AP-105&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wlan5g&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | ASUS RT-AX53U&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy AP3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wlan-5ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wlan-2ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;11&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy AP3000 Outdoor v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;11&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy M3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wan-online&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wan-online&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy TR3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:status&lt;br /&gt;
|colspan=&amp;quot;12&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy WR3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:internet&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;8&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy WR3000S v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:internet&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wan-online&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wlan-2ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wlan-5ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;9&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | D-Link COVR-X1860 A1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; |mt76-phy0&lt;br /&gt;
|  olspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:status&lt;br /&gt;
|colspan=&amp;quot;11&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | D-Link DAP-X1860 A1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:rssihigh&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:rssilow&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:rssimedium&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:rssilow&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Genexis Pulse EX400&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan-2ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan-5ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | GL.iNet GL-MT1300&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:run&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:system&lt;br /&gt;
| colspan=&amp;quot;9&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | GL.iNet GL-MT6000&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:run&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:system&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Joy-IT JT-OR750i (8.2.4)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath10k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:status&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Netgear R6120&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wlan2g&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Netgear R6220&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Netgear WAC104&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link Archer C5 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:qss&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link Archer C6 v3 (8.2.7)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wan&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link Archer C60 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath10k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link RE650 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:eth_act&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:eth_link&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wps&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link TL-WDR4300 v1 (8.2.7)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:qss&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link TL-WR1043ND v2 (8.2.7)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link TL-WR1043N v5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan3&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan4&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Xiaomi Mi Router 4A Gigabit Edition&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:yellow&amp;quot; | yellow:status&lt;br /&gt;
|colspan=&amp;quot;6&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Xiaomi Redmi Router AC2100&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Xiaomi Redmi Router AX6S&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:net&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:net&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:power&lt;br /&gt;
|  colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
|colspan=&amp;quot;5&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | YouHua WR1200JS&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:internet&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Zyxel WSM20&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:led1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:led3&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:led4&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:led2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:led5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:system&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Befehle ==&lt;br /&gt;
&lt;br /&gt;
Beispiel LED ein:&lt;br /&gt;
 echo 1 &amp;gt; /sys/class/leds/orange:wan/brightness&lt;br /&gt;
Beispiel LED aus:&lt;br /&gt;
 echo 0 &amp;gt; /sys/class/leds/orange:wan/brightness&lt;br /&gt;
&lt;br /&gt;
Alle aus&lt;br /&gt;
 for i in /sys/class/leds/*; do echo 0 &amp;gt; &amp;quot;$i&amp;quot;/brightness; done&lt;br /&gt;
&lt;br /&gt;
Alle ein&lt;br /&gt;
 for i in /sys/class/leds/*; do echo 1 &amp;gt; &amp;quot;$i&amp;quot;/for i in /sys/class/leds/*; do echo $i; done; done&lt;br /&gt;
&lt;br /&gt;
Herzschlag&lt;br /&gt;
 for i in /sys/class/leds/*; do echo heartbeat &amp;gt; &amp;quot;$i&amp;quot;/trigger; done&lt;br /&gt;
&lt;br /&gt;
Trigger timmer man&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; done&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo 200 &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 200 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; done&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo 1 &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 1 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; done&lt;br /&gt;
&lt;br /&gt;
Psyco&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo 10 &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 100 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; done&lt;br /&gt;
&lt;br /&gt;
Psyco extended&lt;br /&gt;
 n=1; for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo $(($n * 10)) &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo $(($n * 1000)) &amp;gt; &amp;quot;$i&amp;quot;/delay_off; n=$(($n+1));  done&lt;br /&gt;
&lt;br /&gt;
Lauflicht&lt;br /&gt;
 n=1; for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo $((n * 100)) &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 100 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; n=$(($n + 1));done&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=LED-Config&amp;diff=8226</id>
		<title>LED-Config</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=LED-Config&amp;diff=8226"/>
		<updated>2026-04-27T11:20:33Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: Added more Cudy Devices&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Router ==&lt;br /&gt;
&lt;br /&gt;
Ausgabe von:&lt;br /&gt;
&lt;br /&gt;
 for i in /sys/class/leds/*; do echo $i; done&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable zebra toptextcells sortable&amp;quot;  style=&amp;quot;background:white;&lt;br /&gt;
|-&lt;br /&gt;
! Geräte-Name&lt;br /&gt;
! colspan=&amp;quot;12&amp;quot; | LEDs&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 3370&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dsl&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7312&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dect&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7320&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dect&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:info&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7412&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dect&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7530&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:info&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Aruba AP-105&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wlan5g&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | ASUS RT-AX53U&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy AP3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | amber:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wlan-5ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wlan-2ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;11&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy AP3000 Outdoor v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;11&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy M3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wan-online&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wan-online&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy TR3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:status&lt;br /&gt;
|colspan=&amp;quot;12&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy WR3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:internet&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;8&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy WR3000S v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:internet&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wan-online&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wlan-2ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wlan-5ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;9&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | D-Link COVR-X1860 A1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; |mt76-phy0&lt;br /&gt;
|  olspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:status&lt;br /&gt;
|colspan=&amp;quot;11&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | D-Link DAP-X1860 A1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:rssihigh&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:rssilow&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:rssimedium&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:rssilow&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Genexis Pulse EX400&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan-2ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan-5ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | GL.iNet GL-MT1300&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:run&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:system&lt;br /&gt;
| colspan=&amp;quot;9&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | GL.iNet GL-MT6000&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:run&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:system&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Joy-IT JT-OR750i (8.2.4)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath10k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:status&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Netgear R6120&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wlan2g&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Netgear R6220&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Netgear WAC104&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link Archer C5 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:qss&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link Archer C6 v3 (8.2.7)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wan&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link Archer C60 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath10k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link RE650 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:eth_act&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:eth_link&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wps&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link TL-WDR4300 v1 (8.2.7)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:qss&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link TL-WR1043ND v2 (8.2.7)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link TL-WR1043N v5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan3&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan4&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Xiaomi Mi Router 4A Gigabit Edition&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:yellow&amp;quot; | yellow:status&lt;br /&gt;
|colspan=&amp;quot;6&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Xiaomi Redmi Router AC2100&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Xiaomi Redmi Router AX6S&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:net&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:net&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:power&lt;br /&gt;
|  colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
|colspan=&amp;quot;5&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | YouHua WR1200JS&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:internet&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Zyxel WSM20&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:led1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:led3&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:led4&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:led2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:led5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:system&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Befehle ==&lt;br /&gt;
&lt;br /&gt;
Beispiel LED ein:&lt;br /&gt;
 echo 1 &amp;gt; /sys/class/leds/orange:wan/brightness&lt;br /&gt;
Beispiel LED aus:&lt;br /&gt;
 echo 0 &amp;gt; /sys/class/leds/orange:wan/brightness&lt;br /&gt;
&lt;br /&gt;
Alle aus&lt;br /&gt;
 for i in /sys/class/leds/*; do echo 0 &amp;gt; &amp;quot;$i&amp;quot;/brightness; done&lt;br /&gt;
&lt;br /&gt;
Alle ein&lt;br /&gt;
 for i in /sys/class/leds/*; do echo 1 &amp;gt; &amp;quot;$i&amp;quot;/for i in /sys/class/leds/*; do echo $i; done; done&lt;br /&gt;
&lt;br /&gt;
Herzschlag&lt;br /&gt;
 for i in /sys/class/leds/*; do echo heartbeat &amp;gt; &amp;quot;$i&amp;quot;/trigger; done&lt;br /&gt;
&lt;br /&gt;
Trigger timmer man&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; done&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo 200 &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 200 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; done&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo 1 &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 1 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; done&lt;br /&gt;
&lt;br /&gt;
Psyco&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo 10 &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 100 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; done&lt;br /&gt;
&lt;br /&gt;
Psyco extended&lt;br /&gt;
 n=1; for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo $(($n * 10)) &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo $(($n * 1000)) &amp;gt; &amp;quot;$i&amp;quot;/delay_off; n=$(($n+1));  done&lt;br /&gt;
&lt;br /&gt;
Lauflicht&lt;br /&gt;
 n=1; for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo $((n * 100)) &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 100 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; n=$(($n + 1));done&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=LED-Config&amp;diff=8225</id>
		<title>LED-Config</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=LED-Config&amp;diff=8225"/>
		<updated>2026-04-27T11:08:24Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: Tabelle Alphabetisch Sortiert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Router ==&lt;br /&gt;
&lt;br /&gt;
Ausgabe von:&lt;br /&gt;
&lt;br /&gt;
 for i in /sys/class/leds/*; do echo $i; done&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable zebra toptextcells sortable&amp;quot;  style=&amp;quot;background:white;&lt;br /&gt;
|-&lt;br /&gt;
! Geräte-Name&lt;br /&gt;
! colspan=&amp;quot;12&amp;quot; | LEDs&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 3370&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dsl&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7312&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dect&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7320&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dect&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:info&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7412&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:dect&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | AVM FRITZ!Box 7530&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:fon&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:info&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:info&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Aruba AP-105&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wlan5g&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | ASUS RT-AX53U&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy M3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wan-online&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wan-online&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Cudy WR3000 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:internet&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | D-Link COVR-X1860 A1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; |mt76-phy0&lt;br /&gt;
|  olspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:status&lt;br /&gt;
|colspan=&amp;quot;5&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | D-Link DAP-X1860 A1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:rssihigh&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:rssilow&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:rssimedium&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:rssilow&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:power&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Genexis Pulse EX400&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan-2ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan-5ghz&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:status&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | GL.iNet GL-MT1300&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:run&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:system&lt;br /&gt;
| colspan=&amp;quot;9&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | GL.iNet GL-MT6000&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:run&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:system&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Joy-IT JT-OR750i (8.2.4)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath10k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:status&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Netgear R6120&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wlan2g&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Netgear R6220&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Netgear WAC104&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link Archer C5 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:qss&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link Archer C6 v3 (8.2.7)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wifi5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wan&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link Archer C60 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath10k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link RE650 v1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wifi5g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:eth_act&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:eth_link&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:wps&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link TL-WDR4300 v1 (8.2.7)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:qss&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan2g&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan5g&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link TL-WR1043ND v2 (8.2.7)&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | TP-Link TL-WR1043N v5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | ath9k-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan3&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:lan4&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wlan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:orange&amp;quot; | orange:wan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Xiaomi Mi Router 4A Gigabit Edition&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:yellow&amp;quot; | yellow:status&lt;br /&gt;
|colspan=&amp;quot;6&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Xiaomi Redmi Router AC2100&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:wan&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:status&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:wan&lt;br /&gt;
|colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Xiaomi Redmi Router AX6S&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:net&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:gold&amp;quot; | amber:power&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:net&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:power&lt;br /&gt;
|  colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
|colspan=&amp;quot;5&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | YouHua WR1200JS&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:internet&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:usb&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:blue&amp;quot; | blue:wps&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;10&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;color:grey&amp;quot; | Zyxel WSM20&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:led1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:green&amp;quot; | green:led3&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy0&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:#424242&amp;quot; | mt76-phy1&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:led4&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:red&amp;quot; | red:system&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:led2&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:led5&lt;br /&gt;
| colspan=&amp;quot;1&amp;quot; style=&amp;quot;background:white&amp;quot; | white:system&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot; style=&amp;quot;background:black&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Befehle ==&lt;br /&gt;
&lt;br /&gt;
Beispiel LED ein:&lt;br /&gt;
 echo 1 &amp;gt; /sys/class/leds/orange:wan/brightness&lt;br /&gt;
Beispiel LED aus:&lt;br /&gt;
 echo 0 &amp;gt; /sys/class/leds/orange:wan/brightness&lt;br /&gt;
&lt;br /&gt;
Alle aus&lt;br /&gt;
 for i in /sys/class/leds/*; do echo 0 &amp;gt; &amp;quot;$i&amp;quot;/brightness; done&lt;br /&gt;
&lt;br /&gt;
Alle ein&lt;br /&gt;
 for i in /sys/class/leds/*; do echo 1 &amp;gt; &amp;quot;$i&amp;quot;/for i in /sys/class/leds/*; do echo $i; done; done&lt;br /&gt;
&lt;br /&gt;
Herzschlag&lt;br /&gt;
 for i in /sys/class/leds/*; do echo heartbeat &amp;gt; &amp;quot;$i&amp;quot;/trigger; done&lt;br /&gt;
&lt;br /&gt;
Trigger timmer man&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; done&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo 200 &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 200 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; done&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo 1 &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 1 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; done&lt;br /&gt;
&lt;br /&gt;
Psyco&lt;br /&gt;
 for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo 10 &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 100 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; done&lt;br /&gt;
&lt;br /&gt;
Psyco extended&lt;br /&gt;
 n=1; for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo $(($n * 10)) &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo $(($n * 1000)) &amp;gt; &amp;quot;$i&amp;quot;/delay_off; n=$(($n+1));  done&lt;br /&gt;
&lt;br /&gt;
Lauflicht&lt;br /&gt;
 n=1; for i in /sys/class/leds/*; do echo timer &amp;gt; &amp;quot;$i&amp;quot;/trigger; echo $((n * 100)) &amp;gt; &amp;quot;$i&amp;quot;/delay_on; echo 100 &amp;gt; &amp;quot;$i&amp;quot;/delay_off; n=$(($n + 1));done&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Sprechstunden-Themen&amp;diff=8112</id>
		<title>Sprechstunden-Themen</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Sprechstunden-Themen&amp;diff=8112"/>
		<updated>2026-03-11T16:39:38Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: /* 11.03.2026  Rosenwerk  ANMELDUNG BEACHTEN!    */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Verein]][[Category:Sprechstunde]]&lt;br /&gt;
Ein Treffen für Freifunker:innen und Interessent:innen. Themenwünsche können auch gern über die vielfältigen [[Hauptseite|Kontaktmöglichkeiten]] angebracht werden.&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen zur Sprechstunde findet ihr &#039;&#039;&#039;[[Freifunk-Sprechstunde|hier]]&#039;&#039;&#039;. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&#039;&#039;&#039;Bitte beachtet hier Hinweise zur [[Freifunk-Sprechstunde|Anmeldung]] zur Sprechstunde im Rosenwerk.&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Nächster Termin==&lt;br /&gt;
===11.03.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Rosenwerk &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt; ANMELDUNG BEACHTEN! &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer ist beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Diego&lt;br /&gt;
* Gast (Löbtau Friedenskirche)&lt;br /&gt;
* Gast (Dresden Altstadt)&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
* Andreas plant eine Webcam an der Kirche *******. Eventueller Anschluss über FF. Gleichzeitige Befestigung eines Meshcore Repeaters oben auf der Kirche. Kein Uplink möglich --&amp;gt; Brainstorming welchen Knoten man anzapfen kann. &lt;br /&gt;
* Gespräch über Zyxel Multi Router&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
&lt;br /&gt;
* [[#Ziele 2025 | Ziele 2025]]&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Ziele 2026&#039;&#039;&#039; == &lt;br /&gt;
* 1. Knoten Nummer für neue Gateways wieder im dafür reservierten Bereich. &amp;lt;br&amp;gt;-&amp;gt; Eintragung erfolgt manuell (Anfrage an Stephan@) &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
* 2. Installationsseite (Communitys)&lt;br /&gt;
* 3. Communities (Routing auf Servern)&lt;br /&gt;
* 4. Wireguard für Privates (layer 3) - aktuell ist fastd layer2 vorhanden. Alternativ mit fastd3 (l2tp) (Umbau aufwendig)&lt;br /&gt;
* 5. Wireguard zum direkt Ausleiten. (openvpn raus)&lt;br /&gt;
* 6. Hardware für Verein (Veranstaltung)&lt;br /&gt;
* 7. Weiterentwicklung Firmware&lt;br /&gt;
* 8. Unterstützung weiterer Router&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Vergangene Treffen==&lt;br /&gt;
===04.03.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* Niklas&lt;br /&gt;
* Sten&lt;br /&gt;
* Diego&lt;br /&gt;
* Gast Andreas&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
* Andreas plant eine Webcam an der Kirche *******. Eventueller Anschluss über FF. Gleichzeitige Befestigung eines Meshcore Repeaters oben auf der Kirche. Kein Uplink möglich --&amp;gt; Brainstorming welchen Knoten man anzapfen kann. &lt;br /&gt;
* Gespräch über Zyxel Multi Router&lt;br /&gt;
* Freifunk Video für Social Media&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===25.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* Diego&lt;br /&gt;
* Ole&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* Pre-alpha-Firmware (Fehleranalyse bei ZTE MF289F und Ubiquiti UniFi 6 LR v3)&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* LTE Config ZTEmoped (LTE läuft unter OpenWRT, aber nicht mit FF Firmware. Modem verbindet sich mit Mobilfunkmast, aber es kommt nicht in FF an. &lt;br /&gt;
** Spaß mit UCI&lt;br /&gt;
** Spaß mit Firewalls&lt;br /&gt;
** Reboot-fest gestalten&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
===18.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* Ole&lt;br /&gt;
* Stan&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Blaudio&lt;br /&gt;
* LordAlex&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* Beschlüsse vom 12.02.2026:&lt;br /&gt;
** Terminfindung (August/September)? &amp;quot;20 Jahre Freifunk Dresden&amp;quot; &amp;gt; 22.08.2026 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
** Festlegung: Umgang mit Router-Genexis EX400-Spende &amp;gt; 841 ersetzten! &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** ☑ Wer stellt den Kontakt her? [[Benutzer:Hibo98|Niklas]] &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===12.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Rosenwerk &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
* Torsten&lt;br /&gt;
* Sebastian (Gast)&lt;br /&gt;
* Diego&lt;br /&gt;
* Ole&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* Beschlüsse:&lt;br /&gt;
** ☑ Terminfindung (August/September)? &amp;quot;20 Jahre Freifunk Dresden&amp;quot; &amp;gt; 22.08.2026&lt;br /&gt;
** ☑ Festlegung: Umgang mit Router-Genexis EX400-Spende &amp;gt; 841 ersetzten!&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt; (Festlegung am 12.02.2026!) &amp;lt;/font&amp;gt;&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
&lt;br /&gt;
===04.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Sten&lt;br /&gt;
* LordAlex&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
===28.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]] Definitiv zu spät und dann nur aus dem Auto. &lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* Martin LE&lt;br /&gt;
* Sten&lt;br /&gt;
* LordAlex&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===21.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* Ole&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Stan&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☑ Unterstützung des BMFSFJ-Vorhabens „NETZ-Werk-LER“ vom CODIP an der TU Dresden ([[Benutzer:Diego|DJ]])&lt;br /&gt;
* ☑ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
===14.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Rosenwerk &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Sven (Online)&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☑ &amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;envs Matrix Server wird abgeschaltet!&amp;lt;/font&amp;gt; Was wollen wir machen? (evtl. eigenen Server ohne offene Anmeldung nur für Mitglieder des Vereins) (Lode)&lt;br /&gt;
** Vereins-Server: Abstimmung: Nein&lt;br /&gt;
** Jeder sucht sich einen neuen Server!&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
===07.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Emploi&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
==Archiv==&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2025]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2024]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2023]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2022]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2021]]&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2020]]&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2019]]&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2018]]&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Sprechstunden-Themen&amp;diff=8032</id>
		<title>Sprechstunden-Themen</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Sprechstunden-Themen&amp;diff=8032"/>
		<updated>2026-02-23T16:48:31Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: /* 25.02.2026  Online      */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Verein]][[Category:Sprechstunde]]&lt;br /&gt;
Ein Treffen für Freifunker:innen und Interessent:innen. Themenwünsche können auch gern über die vielfältigen [[Hauptseite|Kontaktmöglichkeiten]] angebracht werden.&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen zur Sprechstunde findet ihr &#039;&#039;&#039;[[Freifunk-Sprechstunde|hier]]&#039;&#039;&#039;. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&#039;&#039;&#039;Bitte beachtet hier Hinweise zur [[Freifunk-Sprechstunde|Anmeldung]] zur Sprechstunde im Rosenwerk.&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Nächster Termin==&lt;br /&gt;
===25.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer ist beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
** Überarbeitung der WebSeite &amp;quot;Empfehlungen&amp;quot;, da &amp;gt;50% der Geräte EOL^.&lt;br /&gt;
* ☐ Router Config um alle steuerbaren LED auszuschalten ([[Benutzer:Mikaff0|Mika]])&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
&lt;br /&gt;
* [[#Ziele 2025 | Ziele 2025]]&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Ziele 2026&#039;&#039;&#039; == &lt;br /&gt;
* 1. Knoten Nummer für neue Gateways wieder im dafür reservierten Bereich. &amp;lt;br&amp;gt;-&amp;gt; Eintragung erfolgt manuell (Anfrage an Stephan@) &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
* 2. Installationsseite (Communitys)&lt;br /&gt;
* 3. Communities (Routing auf Servern)&lt;br /&gt;
* 4. Wireguard für Privates (layer 3) - aktuell ist fastd layer2 vorhanden. Alternativ mit fastd3 (l2tp) (Umbau aufwendig)&lt;br /&gt;
* 5. Wireguard zum direkt Ausleiten. (openvpn raus)&lt;br /&gt;
* 6. Hardware für Verein (Veranstaltung)&lt;br /&gt;
* 7. Weiterentwicklung Firmware&lt;br /&gt;
* 8. Unterstützung weiterer Router&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Vergangene Treffen==&lt;br /&gt;
===18.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* Ole&lt;br /&gt;
* Stan&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Blaudio&lt;br /&gt;
* LordAlex&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* Beschlüsse vom 12.02.2026:&lt;br /&gt;
** Terminfindung (August/September)? &amp;quot;20 Jahre Freifunk Dresden&amp;quot; &amp;gt; 22.08.2026 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
** Festlegung: Umgang mit Router-Genexis EX400-Spende &amp;gt; 841 ersetzten! &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** ☑ Wer stellt den Kontakt her? [[Benutzer:Hibo98|Niklas]] &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===12.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Rosenwerk &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
* Torsten&lt;br /&gt;
* Sebastian (Gast)&lt;br /&gt;
* Diego&lt;br /&gt;
* Ole&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* Beschlüsse:&lt;br /&gt;
** ☑ Terminfindung (August/September)? &amp;quot;20 Jahre Freifunk Dresden&amp;quot; &amp;gt; 22.08.2026&lt;br /&gt;
** ☑ Festlegung: Umgang mit Router-Genexis EX400-Spende &amp;gt; 841 ersetzten!&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt; (Festlegung am 12.02.2026!) &amp;lt;/font&amp;gt;&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
&lt;br /&gt;
===04.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Sten&lt;br /&gt;
* LordAlex&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
===28.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]] Definitiv zu spät und dann nur aus dem Auto. &lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* Martin LE&lt;br /&gt;
* Sten&lt;br /&gt;
* LordAlex&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===21.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* Ole&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Stan&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☑ Unterstützung des BMFSFJ-Vorhabens „NETZ-Werk-LER“ vom CODIP an der TU Dresden ([[Benutzer:Diego|DJ]])&lt;br /&gt;
* ☑ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
===14.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Rosenwerk &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Sven (Online)&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☑ &amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;envs Matrix Server wird abgeschaltet!&amp;lt;/font&amp;gt; Was wollen wir machen? (evtl. eigenen Server ohne offene Anmeldung nur für Mitglieder des Vereins) (Lode)&lt;br /&gt;
** Vereins-Server: Abstimmung: Nein&lt;br /&gt;
** Jeder sucht sich einen neuen Server!&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
===07.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Emploi&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
==Archiv==&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2025]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2024]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2023]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2022]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2021]]&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2020]]&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2019]]&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2018]]&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Elbhangfest&amp;diff=8029</id>
		<title>Elbhangfest</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Elbhangfest&amp;diff=8029"/>
		<updated>2026-02-23T09:32:57Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: /* Wer war da 2026? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Projekte]]&lt;br /&gt;
= Netzwerk =&lt;br /&gt;
[[Datei:Elbhangfest-Netzwerk-ab8.0.1.png|mini|Elbhangfest Netzwerk (ab 8.0.1)]]&lt;br /&gt;
&lt;br /&gt;
Es gibt derzeit nur einen Internetzugang vor Ort. Über diesen soll das Elbhangfest mit Freifunk versorgt werden.&amp;lt;br/&amp;gt;&lt;br /&gt;
# Normale Freifunk Knoten verbunden via Mesh-On-VLAN/WAN (am besten Knoten über WLAN ignorieren)&lt;br /&gt;
# Roaming auf den Freifunk Routern Aktiv&lt;br /&gt;
# Offloader für VPN Traffic&lt;br /&gt;
&lt;br /&gt;
== Normale Freifunk Knoten ==&lt;br /&gt;
Die Freifunk Knoten sind via WAN/LAN alle mit einander verbunden. Das Routing-Protokoll tauscht parallel zu den WLAN-Verbindungen auch Routing-Pakete via LAN mit anderen Knoten am LAN aus.&amp;lt;br/&amp;gt;&lt;br /&gt;
Jeder Knoten bietet via &#039;&#039;&#039;SSID&#039;&#039;&#039; &amp;quot;&#039;&#039;Freifunk Dresden&#039;&#039;&amp;quot; ein WLAN-Netz an. Dabei wird die IP Adresse jeweils von jedem Knoten (in seinem Bereich) an das Endgerät verteilt.&amp;lt;br/&amp;gt;&lt;br /&gt;
Ein Roaming ist damit möglich.&lt;br /&gt;
&lt;br /&gt;
= 2026 =&lt;br /&gt;
&lt;br /&gt;
=== Wer ist da 2026? ===&lt;br /&gt;
[[Datei:Wifi FFDD.png|mini]]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Samstag 27.06.26 !! Sonntag 28.06.26&lt;br /&gt;
|-&lt;br /&gt;
| Weesenstein || X || X&lt;br /&gt;
|-&lt;br /&gt;
| Niklas || X || X&lt;br /&gt;
|-&lt;br /&gt;
| Mika || X || &lt;br /&gt;
|-&lt;br /&gt;
| Name || X || X&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Materialliste: ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Was? !! Name !! Verfügbarkeit geklärt?&lt;br /&gt;
|-&lt;br /&gt;
| Banner 2x || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Pavillon 1x (3x3) || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Pavillon 1x (3x6) || Caleb || ?&lt;br /&gt;
|-&lt;br /&gt;
| Biertischgarnitur 4x &amp;lt;br&amp;gt; (4xTisch + 8xBank) || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Anhänger || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Strom (AKKU`s) || Lodrich || ?&lt;br /&gt;
|-&lt;br /&gt;
| Uplink-Router || Caleb || ?&lt;br /&gt;
|-&lt;br /&gt;
| ? || ? || ?&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= 2025 =&lt;br /&gt;
&lt;br /&gt;
=== Wer war da 2025? ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Samstag 28.06.25 !! Sonntag 29.06.25&lt;br /&gt;
|-&lt;br /&gt;
| Weesenstein || X (8:30 - 17) || X (13 - 18)&lt;br /&gt;
|-&lt;br /&gt;
| Niklas || X (8:30 - 18) || X (9 - 18)&lt;br /&gt;
|-&lt;br /&gt;
| Lodrich || - || X (9 - 18)&lt;br /&gt;
|-&lt;br /&gt;
| Caleb || X Mit 3D Druck und Freifunk || X Mit 3D Druck und Freifunk&lt;br /&gt;
|-&lt;br /&gt;
| Emploi || - || X (9 - 18)&lt;br /&gt;
|-&lt;br /&gt;
| Sten || X (15 - 18) || -&lt;br /&gt;
|-&lt;br /&gt;
| LordAlex || X (8:30 - 12)  || -&lt;br /&gt;
|-&lt;br /&gt;
| Torsten || X (10:00 - 18)  || -&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
[[Datei:Elbhangfest 2025.png|500px|rahmenlos]]&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Materialliste: ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Was? !! Name !! Verfügbarkeit geklärt?&lt;br /&gt;
|-&lt;br /&gt;
| Banner 2x || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Pavillon 1x (3x3) || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Pavillon 1x (3x6) || Caleb || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Biertischgarnitur 4x &amp;lt;br&amp;gt; (4xTisch + 8xBank) || Weesenstein || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Anhänger || Lodrich || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Strom (AKKU`s) || Lodrich || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Uplink-Router || Caleb || &amp;lt;font color=&amp;quot;green&amp;quot;&amp;gt;Ja&amp;lt;/font&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Router für Richtfunk || Flint || Ja (nicht nötig)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= 2022 =&lt;br /&gt;
&lt;br /&gt;
=== Wer war da ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! Donnerstag !! Freitag !! Samstag !! Sonntag&lt;br /&gt;
|-&lt;br /&gt;
| Sten || X || || || X (zum Abbau)&lt;br /&gt;
|-&lt;br /&gt;
| Emploi || X || || X ||&lt;br /&gt;
|-&lt;br /&gt;
| Flint || X || X || ||&lt;br /&gt;
|-&lt;br /&gt;
| Max || || X (wahrscheinlich erst Nachmittags) || X (wahrscheinlich erst Abends) || X&lt;br /&gt;
|-&lt;br /&gt;
| Stephan || || X (nach Arbeit) || X (Nachmittags) || X&lt;br /&gt;
|-&lt;br /&gt;
| Caleb || || X || X || X&lt;br /&gt;
|-&lt;br /&gt;
| Niklas || || X (bis ~ 17 Uhr) || X ||&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= 2020 =&lt;br /&gt;
- Aufbau Sten&lt;br /&gt;
[[Datei:Speedtest-Elbhangfest.png|mini|Speedtest 18.09.2020]]&lt;br /&gt;
&lt;br /&gt;
=== Zusätzliche config ===&lt;br /&gt;
&lt;br /&gt;
DHCP Futro zeigt clients auf mesh viewer an&lt;br /&gt;
dafür muss im futro folgende Datei bearbeitet werden: usr/lib/ddmes.sysinfo&lt;br /&gt;
ca zeile 161  if(match(&amp;quot;&#039;$wifi2_ifname&#039;&amp;quot;,$6) &amp;amp;&amp;amp; match(&amp;quot;0x2&amp;quot;,$3))  durch ca zeile 161  if(match(&amp;quot;&#039;$lan_ifname&#039;&amp;quot;,$6) &amp;amp;&amp;amp; match(&amp;quot;0x2&amp;quot;,$3)) ersetzen.&lt;br /&gt;
Also wifi2 zu lan.&lt;br /&gt;
&lt;br /&gt;
== Einfaches Roaming (wird nicht mehr benötigt)==&lt;br /&gt;
Jeder Knoten besitzt die Möglichkeit ein privates Wifi Netzwerk aufzubauen. Dieses lässt sich so konfigurieren, dass es unverschlüsselt ist.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dieses dritte Wifi-Netzwerk (es gibt bereits ein Wifi-Adhoc-Netz zum Meshen zwischen Knoten, und eines für die Endgeräte) ist direkt mit den LAN-Ports (gelb) verbunden. Alle Geräte, welche dann sich mit diesem Wifi-Netzwerk verbinden, erhalten ihre IP Adresse von DHCP-Servern in diesem LAN-Netzwerk.&amp;lt;br/&amp;gt;&lt;br /&gt;
Dabei kann der DHCP-Server in dem Router (für LAN Port) oder ein anderer Router im LAN die IP Adresse liefern.&lt;br /&gt;
&lt;br /&gt;
Der Knoten ist so konfiguiert, dass er selber keine IP-Adresse liefert, sondern diese vom &#039;&#039;&#039;Futro 1&#039;&#039;&#039; vergeben wird.&amp;lt;br/&amp;gt;&lt;br /&gt;
Jeder Knoten, der in diesem Netzwerk teilnimmt, nutzt die &#039;&#039;&#039;SSID:&#039;&#039;&#039; &amp;quot;&#039;&#039;Freifunk-Elbhangfest&#039;&#039;&amp;quot;. Da es nun mehrere Knoten mit der gleichen SSID gibt, wechselt ein Endgerät auf einen anderen Router, wenn die Signalstärke zu schwach geworden ist.&amp;lt;br/&amp;gt;&lt;br /&gt;
Das ist kein echtes Roaming und es gibt eine kurze Unterbrechung in der Verbindung.&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Da zum Elbhangfest mehrere hundert Leute mit diesem Netz via &amp;quot;&#039;&#039;Freifunk Dresden: Elbhangfest&#039;&#039;&amp;quot; verbunden sein kann, muss &#039;&#039;&#039;Futro 1&#039;&#039;&#039; entsprechend viele IP Adressen vergeben. Entsprechend wurde das LAN wie folgt konfiguriert:&lt;br /&gt;
 Futro 1&lt;br /&gt;
   WAN IP   : DHCP&lt;br /&gt;
   LAN IP   : 192.168.0.1&lt;br /&gt;
   Netzmaske: 255.255.0.0&lt;br /&gt;
   LAN DHCP : 192.168.0.100 - (5000 Nutzer)&lt;br /&gt;
&lt;br /&gt;
 Futro 2&lt;br /&gt;
   WAN IP   : DHCP&lt;br /&gt;
   LAN IP   : 192.168.0.2 / Mesh-On-Lan&lt;br /&gt;
   Netzmaske: 255.255.0.0&lt;br /&gt;
   LAN DHCP : abgeschaltet&lt;br /&gt;
&lt;br /&gt;
 Router IP: 192.168.0.10 (bis 192.168.0.15)&lt;br /&gt;
 Netzmaske: 255.255.0.0&lt;br /&gt;
 Gateway:   0.0.0.0&lt;br /&gt;
 DHCP:      abgeschaltet&lt;br /&gt;
&lt;br /&gt;
[[Datei:Elbhangfest-Network.png|mini|Elbhangfest Netzwerk (pre 8.0.1)]]&lt;br /&gt;
&lt;br /&gt;
= 2018 =&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Planung&#039;&#039;&#039;: Max, Stephan, Daniel &amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Aufbau&#039;&#039;&#039;:  Max, Daniel, Janek &amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Betreuung&#039;&#039;&#039;: Max, Stephan, Daniel, Mirko, Micha, Janek, Torsten &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Installation erfolgte bereits am Donnerstag 21.6.2018. &amp;lt;br&amp;gt;&lt;br /&gt;
Ein erster Speedtest ergibt nur &#039;&#039;20Mbit/s im Download und 8Mbit/s im Upload&#039;&#039;, was aber für den zu versorgenden Bereich hoffentlich ausreicht.&lt;br /&gt;
&lt;br /&gt;
Zum Elbhangfest haben uns die Strassenkreuzer kontaktiert. Sie wollen dort zur Veranstaltung ein eigenes Netz via Freifunk aufbauen. Dazu haben wir uns mit ihnen bereits schon einmal zum Wissensaustausch getroffen. Ein weiteres Treffen findet heute statt. Am Donnerstag vor dem Elbhangfest findet der Aufbau des Festgeländes statt, wo wir den Aufbau des Freifunk Netzes begleiten.&lt;br /&gt;
&lt;br /&gt;
Der Internetzugang für die Anbindung an das Freifunknetzwerk wird durch durch die Alte Feuerwache bereitgestellt. Die Technik für diese Veranstaltung wird privat gestellt.&amp;lt;br/&amp;gt;&lt;br /&gt;
Der Zugang zum Internet erfolgt durch verschiedene private Personen, die mit ihren Routern oder Servern zusammen das Netzwerk bilden.&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Sprechstunden-Themen&amp;diff=8028</id>
		<title>Sprechstunden-Themen</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Sprechstunden-Themen&amp;diff=8028"/>
		<updated>2026-02-23T09:30:29Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Verein]][[Category:Sprechstunde]]&lt;br /&gt;
Ein Treffen für Freifunker:innen und Interessent:innen. Themenwünsche können auch gern über die vielfältigen [[Hauptseite|Kontaktmöglichkeiten]] angebracht werden.&lt;br /&gt;
&lt;br /&gt;
Weitere Informationen zur Sprechstunde findet ihr &#039;&#039;&#039;[[Freifunk-Sprechstunde|hier]]&#039;&#039;&#039;. &amp;lt;font color=&amp;quot;red&amp;quot;&amp;gt;&#039;&#039;&#039;Bitte beachtet hier Hinweise zur [[Freifunk-Sprechstunde|Anmeldung]] zur Sprechstunde im Rosenwerk.&#039;&#039;&#039;&amp;lt;/font&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Nächster Termin==&lt;br /&gt;
===25.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer ist beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
** Überarbeitung der WebSeite &amp;quot;Empfehlungen&amp;quot;, da &amp;gt;50% der Geräte EOL^.&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
&lt;br /&gt;
* [[#Ziele 2025 | Ziele 2025]]&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Ziele 2026&#039;&#039;&#039; == &lt;br /&gt;
* 1. Knoten Nummer für neue Gateways wieder im dafür reservierten Bereich. &amp;lt;br&amp;gt;-&amp;gt; Eintragung erfolgt manuell (Anfrage an Stephan@) &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
* 2. Installationsseite (Communitys)&lt;br /&gt;
* 3. Communities (Routing auf Servern)&lt;br /&gt;
* 4. Wireguard für Privates (layer 3) - aktuell ist fastd layer2 vorhanden. Alternativ mit fastd3 (l2tp) (Umbau aufwendig)&lt;br /&gt;
* 5. Wireguard zum direkt Ausleiten. (openvpn raus)&lt;br /&gt;
* 6. Hardware für Verein (Veranstaltung)&lt;br /&gt;
* 7. Weiterentwicklung Firmware&lt;br /&gt;
* 8. Unterstützung weiterer Router&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
==Vergangene Treffen==&lt;br /&gt;
===18.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* Ole&lt;br /&gt;
* Stan&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Blaudio&lt;br /&gt;
* LordAlex&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* Beschlüsse vom 12.02.2026:&lt;br /&gt;
** Terminfindung (August/September)? &amp;quot;20 Jahre Freifunk Dresden&amp;quot; &amp;gt; 22.08.2026 &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
** Festlegung: Umgang mit Router-Genexis EX400-Spende &amp;gt; 841 ersetzten! &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
* [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] 2026 (26.-28.06.2026)&lt;br /&gt;
** ☑ Wer stellt den Kontakt her? [[Benutzer:Hibo98|Niklas]] &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
** Bitte Teilnahme eintragen [https://wiki.freifunk-dresden.de/index.php/Elbhangfest Elbhangfest] (soweit schon bekannt)&lt;br /&gt;
* Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** ☐ Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** &amp;lt;font style=&amp;quot;color: green;&amp;quot;&amp;gt; Termin: 22.08.2026 &amp;lt;/font&amp;gt; &amp;lt;span style=&amp;quot;color:green;&amp;quot;&amp;gt;✔&amp;lt;/span&amp;gt;&lt;br /&gt;
*** ☐ Pressemitteilung zum Jubiläum&lt;br /&gt;
*** ☐ auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** ☐ Sonderflyer auflegen?&lt;br /&gt;
**** ☐ Sonderbanner anfertigen lassen?&lt;br /&gt;
**** ☐ Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===12.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Rosenwerk &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Mikaff0|Mika]]&lt;br /&gt;
* Torsten&lt;br /&gt;
* Sebastian (Gast)&lt;br /&gt;
* Diego&lt;br /&gt;
* Ole&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* Beschlüsse:&lt;br /&gt;
** ☑ Terminfindung (August/September)? &amp;quot;20 Jahre Freifunk Dresden&amp;quot; &amp;gt; 22.08.2026&lt;br /&gt;
** ☑ Festlegung: Umgang mit Router-Genexis EX400-Spende &amp;gt; 841 ersetzten!&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt; (Festlegung am 12.02.2026!) &amp;lt;/font&amp;gt;&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
&lt;br /&gt;
===04.02.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Sten&lt;br /&gt;
* LordAlex&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
===28.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]] Definitiv zu spät und dann nur aus dem Auto. &lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* Martin LE&lt;br /&gt;
* Sten&lt;br /&gt;
* LordAlex&lt;br /&gt;
*&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]] &lt;br /&gt;
===21.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* Ole&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Stan&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☑ Unterstützung des BMFSFJ-Vorhabens „NETZ-Werk-LER“ vom CODIP an der TU Dresden ([[Benutzer:Diego|DJ]])&lt;br /&gt;
* ☑ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
===14.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Rosenwerk &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Emploi|Emploi]]&lt;br /&gt;
* Sven (Online)&lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☑ &amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;envs Matrix Server wird abgeschaltet!&amp;lt;/font&amp;gt; Was wollen wir machen? (evtl. eigenen Server ohne offene Anmeldung nur für Mitglieder des Vereins) (Lode)&lt;br /&gt;
** Vereins-Server: Abstimmung: Nein&lt;br /&gt;
** Jeder sucht sich einen neuen Server!&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
===07.01.2026&amp;lt;span style=&amp;quot;color: green&amp;quot;&amp;gt;  &#039;&#039;&#039;Online &amp;lt;font style=&amp;quot;color: red;&amp;quot;&amp;gt;  &amp;lt;/font&amp;gt;  &#039;&#039;&#039;&amp;lt;/span&amp;gt;===&lt;br /&gt;
;Wer war beim Stammtisch am Start?&lt;br /&gt;
* [[Benutzer:Hibo98|Niklas]]&lt;br /&gt;
* [[Benutzer:Weesenstein|Weesenstein]]&lt;br /&gt;
* [[Benutzer:Diego|Diego]]&lt;br /&gt;
* Mika&lt;br /&gt;
* [[Benutzer:Lodrich|Max]]&lt;br /&gt;
* LordAlex&lt;br /&gt;
* Emploi&lt;br /&gt;
* &lt;br /&gt;
&lt;br /&gt;
; Thementagesordnung&lt;br /&gt;
* ☐ Vorbereitung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; (Wie wollen wir das öffentlichkeitswirksam feiern/präsentieren?) ([[Benutzer:Weesenstein|Weesenstein]])&lt;br /&gt;
** Ideensammlung&lt;br /&gt;
*** Erweiterte Sprechstunde mit Grillen&lt;br /&gt;
*** Terminfindung (August/September)? (Festlegung im Januar!)&lt;br /&gt;
*** Pressemitteilung zum Jubiläum&lt;br /&gt;
*** auf jeder Veranstaltung &amp;quot;20 Jahre Freifunk Dresden&amp;quot; repräsentieren (Elbhangfest , Ehrenamtsbörse, ...)&lt;br /&gt;
**** Sonderflyer auflegen?&lt;br /&gt;
**** Sonderbanner anfertigen lassen?&lt;br /&gt;
**** Sonderaufkleber auflegen?&lt;br /&gt;
* ☐ Easy-Install-config (LA)&lt;br /&gt;
* ☐ Veränderung der Seite &amp;quot;Router auswählen&amp;quot;&lt;br /&gt;
* ☐ Zukünftige Entwicklung eigene Internetanbindung&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
; Themenwünsche (&amp;lt;font color=&amp;quot;orangered&amp;quot;&amp;gt;bitte Namen angeben&amp;lt;/font&amp;gt;)&lt;br /&gt;
* ☐ Einstiegshürde nehmen: &amp;quot;Mein erster Freifunkrouter&amp;quot;??? (LA)&lt;br /&gt;
** Anfänger-Anleitung IN EINFACHER SPRACHE.&lt;br /&gt;
** Die 5 wichtigesten Schritte der Einrichtung &lt;br /&gt;
*** Beorzugtes Gateway&lt;br /&gt;
*** VPN Server&lt;br /&gt;
*** Kontaktinfos&lt;br /&gt;
*** Wesensteins Grafik als Erklärung&lt;br /&gt;
*** 5 G Indoor&lt;br /&gt;
*** Outlook: Privates Netz, Privates Wlan etc. pp.&lt;br /&gt;
** Aufräumen der [[Freifunk_Netzwerk|Vpnserver Seite]]&lt;br /&gt;
&lt;br /&gt;
==Archiv==&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2025]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2024]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2023]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2022]]&#039;&#039;&#039; &lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2021]]&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2020]]&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2019]]&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;[[Sprechstunden-Themen 2018]]&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7985</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7985"/>
		<updated>2026-02-16T18:54:53Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
&lt;br /&gt;
====Knoten====&lt;br /&gt;
{{#Widget:Hotspots-Filter|filter=KG-Klotzsche}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7984</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7984"/>
		<updated>2026-02-16T18:54:33Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
&lt;br /&gt;
====Knoten====&lt;br /&gt;
{{#Widget:Hotspots-Filter|filter=KG-Klotzsche}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
===Knoten===&lt;br /&gt;
{{#Widget:Hotspots-Filter|filter=Mika}}&lt;br /&gt;
&lt;br /&gt;
===Hardware===&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7983</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7983"/>
		<updated>2026-02-16T18:53:14Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
====Knoten====&lt;br /&gt;
&lt;br /&gt;
{{#Widget:Hotspots-Filter|filter=Weesenstein}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7982</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7982"/>
		<updated>2026-02-16T18:52:59Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
====Knoten====&lt;br /&gt;
&lt;br /&gt;
{{#Widget:Hotspots-Filter|filter=KG-Klotzsche}}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7981</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7981"/>
		<updated>2026-02-16T18:50:15Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
====Knoten====&lt;br /&gt;
&lt;br /&gt;
{{#Widget:Hotspots-Filter|filter=KG-Klotzsche}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Modell !! Knotennummer !! Standort !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP DG || Cudy WR3000S v1 || 1284 || Dachgeschoss IT-Schrank || Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP EG || Cudy AP3000 v1 || 1354 || Erdgeschoss Foyer || Backup Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG1 || Cudy AP3000 v1 || 1074 || Untergeschoss Raum für Kinder ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG2 || Cudy AP3000 v1 || 1342 || Untergeschoss Küche ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP Hof || Cudy AP3000 Outdoor v1 || 1290 || Außen an Garage im Hof || noch nicht installiert&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7980</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7980"/>
		<updated>2026-02-16T18:50:02Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  function setFilterValueAndHide() {&lt;br /&gt;
    const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
    if (inputField) {&lt;br /&gt;
      inputField.value = &amp;quot;&amp;lt;!--{$filter|escape:&#039;javascript&#039;}--&amp;gt;&amp;quot;;&lt;br /&gt;
      document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      // &#039;search&#039;-Event auslösen&lt;br /&gt;
      const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
      inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
      // Falls DataTables global verfügbar ist, suche nach der Tabelle&lt;br /&gt;
      if (typeof $.fn.dataTable !== &#039;undefined&#039;) {&lt;br /&gt;
        const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
        dataTable.search(&amp;quot;KG-Klotzsche&amp;quot;).draw();&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      observer.disconnect(); // Observer stoppen&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // MutationObserver erstellen&lt;br /&gt;
  const observer = new MutationObserver(function(mutations) {&lt;br /&gt;
    setFilterValueAndHide();&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  // Beobachte Änderungen im body oder einem spezifischen Container&lt;br /&gt;
  observer.observe(document.body, {&lt;br /&gt;
    childList: true,&lt;br /&gt;
    subtree: true&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  // Sofortige Prüfung&lt;br /&gt;
  setFilterValueAndHide();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7979</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7979"/>
		<updated>2026-02-16T18:49:03Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
====Knoten====&lt;br /&gt;
&lt;br /&gt;
{{#Widget:Hotspots-Filter|filter=KG-Klotzsch}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Modell !! Knotennummer !! Standort !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP DG || Cudy WR3000S v1 || 1284 || Dachgeschoss IT-Schrank || Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP EG || Cudy AP3000 v1 || 1354 || Erdgeschoss Foyer || Backup Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG1 || Cudy AP3000 v1 || 1074 || Untergeschoss Raum für Kinder ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG2 || Cudy AP3000 v1 || 1342 || Untergeschoss Küche ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP Hof || Cudy AP3000 Outdoor v1 || 1290 || Außen an Garage im Hof || noch nicht installiert&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7978</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7978"/>
		<updated>2026-02-16T18:47:31Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  function setFilterValueAndHide() {&lt;br /&gt;
    const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
    console.log(inputField);&lt;br /&gt;
    if (inputField) {&lt;br /&gt;
      inputField.value = &amp;quot;{&amp;lt;!--{$filter|escape:&#039;javascript&#039;}--&amp;gt;}&amp;quot;;&lt;br /&gt;
      document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      // &#039;search&#039;-Event auslösen&lt;br /&gt;
      const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
      inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
      // Falls DataTables global verfügbar ist, suche nach der Tabelle&lt;br /&gt;
      if (typeof $.fn.dataTable !== &#039;undefined&#039;) {&lt;br /&gt;
        const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
        dataTable.search(&amp;quot;KG-Klotzsche&amp;quot;).draw();&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      observer.disconnect(); // Observer stoppen&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // MutationObserver erstellen&lt;br /&gt;
  const observer = new MutationObserver(function(mutations) {&lt;br /&gt;
    setFilterValueAndHide();&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  // Beobachte Änderungen im body oder einem spezifischen Container&lt;br /&gt;
  observer.observe(document.body, {&lt;br /&gt;
    childList: true,&lt;br /&gt;
    subtree: true&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  // Sofortige Prüfung&lt;br /&gt;
  setFilterValueAndHide();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7977</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7977"/>
		<updated>2026-02-16T18:46:45Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
====Knoten====&lt;br /&gt;
&lt;br /&gt;
{{#Widget:Hotspots-Filter|filter=KG-Klotzsche}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Modell !! Knotennummer !! Standort !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP DG || Cudy WR3000S v1 || 1284 || Dachgeschoss IT-Schrank || Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP EG || Cudy AP3000 v1 || 1354 || Erdgeschoss Foyer || Backup Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG1 || Cudy AP3000 v1 || 1074 || Untergeschoss Raum für Kinder ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG2 || Cudy AP3000 v1 || 1342 || Untergeschoss Küche ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP Hof || Cudy AP3000 Outdoor v1 || 1290 || Außen an Garage im Hof || noch nicht installiert&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7976</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7976"/>
		<updated>2026-02-16T18:46:35Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
====Knoten====&lt;br /&gt;
&lt;br /&gt;
{{#Widget:Hotspots-Filter|filter=&amp;quot;KG-Klotzsche&amp;quot;}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Modell !! Knotennummer !! Standort !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP DG || Cudy WR3000S v1 || 1284 || Dachgeschoss IT-Schrank || Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP EG || Cudy AP3000 v1 || 1354 || Erdgeschoss Foyer || Backup Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG1 || Cudy AP3000 v1 || 1074 || Untergeschoss Raum für Kinder ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG2 || Cudy AP3000 v1 || 1342 || Untergeschoss Küche ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP Hof || Cudy AP3000 Outdoor v1 || 1290 || Außen an Garage im Hof || noch nicht installiert&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7975</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7975"/>
		<updated>2026-02-16T18:46:12Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
====Knoten====&lt;br /&gt;
&lt;br /&gt;
{{#Widget:Hotspots-Filter|filter=KG-Klotzsche}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Modell !! Knotennummer !! Standort !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP DG || Cudy WR3000S v1 || 1284 || Dachgeschoss IT-Schrank || Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP EG || Cudy AP3000 v1 || 1354 || Erdgeschoss Foyer || Backup Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG1 || Cudy AP3000 v1 || 1074 || Untergeschoss Raum für Kinder ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG2 || Cudy AP3000 v1 || 1342 || Untergeschoss Küche ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP Hof || Cudy AP3000 Outdoor v1 || 1290 || Außen an Garage im Hof || noch nicht installiert&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7974</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7974"/>
		<updated>2026-02-16T18:46:04Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  function setFilterValueAndHide() {&lt;br /&gt;
    const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
    if (inputField) {&lt;br /&gt;
      inputField.value = &amp;quot;{&amp;lt;!--{$filter|escape:&#039;javascript&#039;}--&amp;gt;}&amp;quot;;&lt;br /&gt;
      document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      // &#039;search&#039;-Event auslösen&lt;br /&gt;
      const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
      inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
      // Falls DataTables global verfügbar ist, suche nach der Tabelle&lt;br /&gt;
      if (typeof $.fn.dataTable !== &#039;undefined&#039;) {&lt;br /&gt;
        const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
        dataTable.search(&amp;quot;KG-Klotzsche&amp;quot;).draw();&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      observer.disconnect(); // Observer stoppen&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // MutationObserver erstellen&lt;br /&gt;
  const observer = new MutationObserver(function(mutations) {&lt;br /&gt;
    setFilterValueAndHide();&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  // Beobachte Änderungen im body oder einem spezifischen Container&lt;br /&gt;
  observer.observe(document.body, {&lt;br /&gt;
    childList: true,&lt;br /&gt;
    subtree: true&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  // Sofortige Prüfung&lt;br /&gt;
  setFilterValueAndHide();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7973</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7973"/>
		<updated>2026-02-16T18:42:52Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  function setFilterValueAndHide() {&lt;br /&gt;
    const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
    if (inputField) {&lt;br /&gt;
      inputField.value = &amp;lt;!--{$param2|escape:&#039;html&#039;}--&amp;gt;;&lt;br /&gt;
      document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      // &#039;search&#039;-Event auslösen&lt;br /&gt;
      const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
      inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
      // Falls DataTables global verfügbar ist, suche nach der Tabelle&lt;br /&gt;
      if (typeof $.fn.dataTable !== &#039;undefined&#039;) {&lt;br /&gt;
        const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
        dataTable.search(&amp;quot;KG-Klotzsche&amp;quot;).draw();&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      observer.disconnect(); // Observer stoppen&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // MutationObserver erstellen&lt;br /&gt;
  const observer = new MutationObserver(function(mutations) {&lt;br /&gt;
    setFilterValueAndHide();&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  // Beobachte Änderungen im body oder einem spezifischen Container&lt;br /&gt;
  observer.observe(document.body, {&lt;br /&gt;
    childList: true,&lt;br /&gt;
    subtree: true&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  // Sofortige Prüfung&lt;br /&gt;
  setFilterValueAndHide();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7972</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7972"/>
		<updated>2026-02-16T18:42:25Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
====Knoten====&lt;br /&gt;
&lt;br /&gt;
{{#Widget:Hotspots-Filter|filter=KG-Klotzsch}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Modell !! Knotennummer !! Standort !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP DG || Cudy WR3000S v1 || 1284 || Dachgeschoss IT-Schrank || Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP EG || Cudy AP3000 v1 || 1354 || Erdgeschoss Foyer || Backup Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG1 || Cudy AP3000 v1 || 1074 || Untergeschoss Raum für Kinder ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG2 || Cudy AP3000 v1 || 1342 || Untergeschoss Küche ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP Hof || Cudy AP3000 Outdoor v1 || 1290 || Außen an Garage im Hof || noch nicht installiert&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7971</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7971"/>
		<updated>2026-02-16T18:42:16Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  function setFilterValueAndHide() {&lt;br /&gt;
    const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
    if (inputField) {&lt;br /&gt;
      inputField.value = &amp;quot;&amp;lt;!--{$param2|escape:&#039;html&#039;}--&amp;gt;&amp;quot;;&lt;br /&gt;
      document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      // &#039;search&#039;-Event auslösen&lt;br /&gt;
      const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
      inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
      // Falls DataTables global verfügbar ist, suche nach der Tabelle&lt;br /&gt;
      if (typeof $.fn.dataTable !== &#039;undefined&#039;) {&lt;br /&gt;
        const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
        dataTable.search(&amp;quot;KG-Klotzsche&amp;quot;).draw();&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      observer.disconnect(); // Observer stoppen&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // MutationObserver erstellen&lt;br /&gt;
  const observer = new MutationObserver(function(mutations) {&lt;br /&gt;
    setFilterValueAndHide();&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  // Beobachte Änderungen im body oder einem spezifischen Container&lt;br /&gt;
  observer.observe(document.body, {&lt;br /&gt;
    childList: true,&lt;br /&gt;
    subtree: true&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  // Sofortige Prüfung&lt;br /&gt;
  setFilterValueAndHide();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7970</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7970"/>
		<updated>2026-02-16T18:40:31Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
====Knoten====&lt;br /&gt;
&lt;br /&gt;
{{#Widget:Hotspots-Filter|filter=KG-Klotzsche}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Modell !! Knotennummer !! Standort !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP DG || Cudy WR3000S v1 || 1284 || Dachgeschoss IT-Schrank || Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP EG || Cudy AP3000 v1 || 1354 || Erdgeschoss Foyer || Backup Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG1 || Cudy AP3000 v1 || 1074 || Untergeschoss Raum für Kinder ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG2 || Cudy AP3000 v1 || 1342 || Untergeschoss Küche ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP Hof || Cudy AP3000 Outdoor v1 || 1290 || Außen an Garage im Hof || noch nicht installiert&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7969</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7969"/>
		<updated>2026-02-16T18:39:55Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  function setFilterValueAndHide() {&lt;br /&gt;
    const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
    if (inputField) {&lt;br /&gt;
      inputField.value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
      document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      // &#039;search&#039;-Event auslösen&lt;br /&gt;
      const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
      inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
      // Falls DataTables global verfügbar ist, suche nach der Tabelle&lt;br /&gt;
      if (typeof $.fn.dataTable !== &#039;undefined&#039;) {&lt;br /&gt;
        const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
        dataTable.search(&amp;quot;KG-Klotzsche&amp;quot;).draw();&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
      observer.disconnect(); // Observer stoppen&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // MutationObserver erstellen&lt;br /&gt;
  const observer = new MutationObserver(function(mutations) {&lt;br /&gt;
    setFilterValueAndHide();&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  // Beobachte Änderungen im body oder einem spezifischen Container&lt;br /&gt;
  observer.observe(document.body, {&lt;br /&gt;
    childList: true,&lt;br /&gt;
    subtree: true&lt;br /&gt;
  });&lt;br /&gt;
&lt;br /&gt;
  // Sofortige Prüfung&lt;br /&gt;
  setFilterValueAndHide();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7968</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7968"/>
		<updated>2026-02-16T18:36:58Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
====Knoten====&lt;br /&gt;
&lt;br /&gt;
{{#Widget:Hotspots-Filter}}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Modell !! Knotennummer !! Standort !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP DG || Cudy WR3000S v1 || 1284 || Dachgeschoss IT-Schrank || Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP EG || Cudy AP3000 v1 || 1354 || Erdgeschoss Foyer || Backup Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG1 || Cudy AP3000 v1 || 1074 || Untergeschoss Raum für Kinder ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG2 || Cudy AP3000 v1 || 1342 || Untergeschoss Küche ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP Hof || Cudy AP3000 Outdoor v1 || 1290 || Außen an Garage im Hof || noch nicht installiert&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7967</id>
		<title>Benutzer:Mikaff0</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Benutzer:Mikaff0&amp;diff=7967"/>
		<updated>2026-02-16T18:36:10Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Betreute Installation==&lt;br /&gt;
===Gemeindehaus Kirchgemeinde Klotzsche===&lt;br /&gt;
Im Gemeindehaus der Kirchgemeinde Klotzsche gibt es seit November 2025 Freifunk.&lt;br /&gt;
Die Knoten meshen per VLAN miteinander.&lt;br /&gt;
====Knoten====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable sortable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Modell !! Knotennummer !! Standort !! Comment&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP DG || Cudy WR3000S v1 || 1284 || Dachgeschoss IT-Schrank || Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP EG || Cudy AP3000 v1 || 1354 || Erdgeschoss Foyer || Backup Uplink&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG1 || Cudy AP3000 v1 || 1074 || Untergeschoss Raum für Kinder ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP UG2 || Cudy AP3000 v1 || 1342 || Untergeschoss Küche ||&lt;br /&gt;
|-&lt;br /&gt;
| KG-Klotzsche GAP Hof || Cudy AP3000 Outdoor v1 || 1290 || Außen an Garage im Hof || noch nicht installiert&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Eigene Router==&lt;br /&gt;
* Asus RT-AX53U&lt;br /&gt;
* Cudy AP3000 Outdoor&lt;br /&gt;
* Cudy TR3000&lt;br /&gt;
===Router Empfehlung===&lt;br /&gt;
Ich kann die Router der Cudy AX3000 Serie empfehlen. Diese machen einen sehr guten VPN Durchsatz und es gibt für verschiedene Bedürfnisse passende Geräte.&lt;br /&gt;
[https://geizhals.de/wishlists/4918307 Liste meiner Router Empfehlung auf Geizhals.de]&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7966</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7966"/>
		<updated>2026-02-16T18:34:51Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  // Warte auf die Initialisierung von DataTables&lt;br /&gt;
  $(document).on(&#039;init.dt&#039;, function(e, settings) {&lt;br /&gt;
    // Prüfe, ob es sich um die richtige Tabelle handelt (falls mehrere Tabellen existieren)&lt;br /&gt;
    if (settings.nTable.id === &#039;hotspots&#039;) {&lt;br /&gt;
      const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
      if (inputField) {&lt;br /&gt;
        inputField.value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
        document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        // &#039;search&#039;-Event auslösen&lt;br /&gt;
        const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
        inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
        // DataTables-Suche explizit auslösen&lt;br /&gt;
        const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
        dataTable.search(&amp;quot;KG-Klotzsche&amp;quot;).draw();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7965</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7965"/>
		<updated>2026-02-16T18:29:56Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
setTimeout(function() {&lt;br /&gt;
    document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
    document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
    // Das &#039;search&#039;-Event manuell auslösen (für DataTables)&lt;br /&gt;
    const searchEvent = new Event(&amp;quot;search&amp;quot;, {&lt;br /&gt;
        bubbles: true,&lt;br /&gt;
        cancelable: true,&lt;br /&gt;
    });&lt;br /&gt;
    document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).dispatchEvent(searchEvent);&lt;br /&gt;
}, 1000); // 1000 Millisekunden = 1 Sekunde&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7964</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7964"/>
		<updated>2026-02-16T18:29:12Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
setTimeout(function() {&lt;br /&gt;
    document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
    document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
    // Das &#039;search&#039;-Event manuell auslösen (für DataTables)&lt;br /&gt;
    const searchEvent = new Event(&amp;quot;search&amp;quot;, {&lt;br /&gt;
        bubbles: true,&lt;br /&gt;
        cancelable: true,&lt;br /&gt;
    });&lt;br /&gt;
    document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).dispatchEvent(searchEvent);&lt;br /&gt;
}, 1000); // 1000 Millisekunden = 1 Sekunde&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7963</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7963"/>
		<updated>2026-02-16T18:27:56Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
setTimeout(() =&amp;gt; {&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
// Das &#039;search&#039;-Event manuell auslösen (für DataTables)&lt;br /&gt;
const searchEvent = new Event(&amp;quot;search&amp;quot;, {&lt;br /&gt;
  bubbles: true,&lt;br /&gt;
  cancelable: true,&lt;br /&gt;
});&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).dispatchEvent(searchEvent);&lt;br /&gt;
},5000);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7962</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7962"/>
		<updated>2026-02-16T18:26:48Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
setTimeout(() =&amp;gt; {&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
// Das &#039;search&#039;-Event manuell auslösen (für DataTables)&lt;br /&gt;
const searchEvent = new Event(&amp;quot;search&amp;quot;, {&lt;br /&gt;
  bubbles: true,&lt;br /&gt;
  cancelable: true,&lt;br /&gt;
});&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).dispatchEvent(searchEvent);&lt;br /&gt;
},2000);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7961</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7961"/>
		<updated>2026-02-16T18:25:22Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
setTimeout(&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
// Das &#039;search&#039;-Event manuell auslösen (für DataTables)&lt;br /&gt;
const searchEvent = new Event(&amp;quot;search&amp;quot;, {&lt;br /&gt;
  bubbles: true,&lt;br /&gt;
  cancelable: true,&lt;br /&gt;
});&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).dispatchEvent(searchEvent);&lt;br /&gt;
,2000);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7960</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7960"/>
		<updated>2026-02-16T18:24:58Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
setTimeout(&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
// Das &#039;search&#039;-Event manuell auslösen (für DataTables)&lt;br /&gt;
const searchEvent = new Event(&amp;quot;search&amp;quot;, {&lt;br /&gt;
  bubbles: true,&lt;br /&gt;
  cancelable: true,&lt;br /&gt;
});&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).dispatchEvent(searchEvent);&lt;br /&gt;
,1000);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7959</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7959"/>
		<updated>2026-02-16T18:22:55Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  setTimeout(&lt;br /&gt;
    const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
    if (inputField) {&lt;br /&gt;
      inputField.value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
      document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
      inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
      // DataTables-Suche auslösen&lt;br /&gt;
      if (typeof $.fn.dataTable !== &#039;undefined&#039;) {&lt;br /&gt;
        const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
        dataTable.search(&amp;quot;KG-Klotzsche&amp;quot;).draw();&lt;br /&gt;
      }&lt;br /&gt;
    } else {&lt;br /&gt;
      console.error(&amp;quot;Input-Feld immer noch nicht gefunden!&amp;quot;);&lt;br /&gt;
    }, 1000); // Warte 1 Sekunde (anpassen, falls nötig)&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7958</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7958"/>
		<updated>2026-02-16T18:21:14Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  setTimeout(function() {&lt;br /&gt;
    const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
    if (inputField) {&lt;br /&gt;
      inputField.value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
      document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
      const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
      inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
      // DataTables-Suche auslösen&lt;br /&gt;
      if (typeof $.fn.dataTable !== &#039;undefined&#039;) {&lt;br /&gt;
        const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
        dataTable.search(&amp;quot;KG-Klotzsche&amp;quot;).draw();&lt;br /&gt;
      }&lt;br /&gt;
    } else {&lt;br /&gt;
      console.error(&amp;quot;Input-Feld immer noch nicht gefunden!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }, 1000); // Warte 1 Sekunde (anpassen, falls nötig)&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7957</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7957"/>
		<updated>2026-02-16T18:20:05Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  // Warte auf die Initialisierung von DataTables&lt;br /&gt;
  $(document).on(&#039;init.dt&#039;, function(e, settings) {&lt;br /&gt;
    // Prüfe, ob es sich um die richtige Tabelle handelt (falls mehrere Tabellen existieren)&lt;br /&gt;
    if (settings.nTable.id === &#039;hotspots&#039;) {&lt;br /&gt;
      const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
      if (inputField) {&lt;br /&gt;
        inputField.value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
        document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
        // &#039;search&#039;-Event auslösen&lt;br /&gt;
        const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
        inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
        // DataTables-Suche explizit auslösen&lt;br /&gt;
        const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
        dataTable.search(&amp;quot;KG-Klotzsche&amp;quot;).draw();&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7956</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7956"/>
		<updated>2026-02-16T18:16:53Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
// Funktion, die ausgeführt wird, wenn das Element gefunden wird&lt;br /&gt;
function setFilterValueAndHide() {&lt;br /&gt;
  const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
  if (inputField) {&lt;br /&gt;
    inputField.value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
    document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // &#039;search&#039;-Event auslösen&lt;br /&gt;
    const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
    inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
    // Optional: DataTables-Suche explizit auslösen (falls nötig)&lt;br /&gt;
    if (typeof $.fn.dataTable !== &#039;undefined&#039;) {&lt;br /&gt;
      const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
      dataTable.search(&amp;quot;KG-Klotzsche&amp;quot;).draw();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Observer stoppen, da das Element gefunden wurde&lt;br /&gt;
    observer.disconnect();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// MutationObserver erstellen&lt;br /&gt;
const observer = new MutationObserver(function(mutations, obs) {&lt;br /&gt;
  setFilterValueAndHide();&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Beobachte Änderungen im gesamten Dokument&lt;br /&gt;
observer.observe(document.body, {&lt;br /&gt;
  childList: true,    // Beobachte direkte Kinder&lt;br /&gt;
  subtree: true       // Beobachte alle Nachkommen&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Falls das Element bereits existiert, sofort ausführen&lt;br /&gt;
setFilterValueAndHide();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7955</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7955"/>
		<updated>2026-02-16T18:16:33Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  // Warte auf die Initialisierung von DataTables&lt;br /&gt;
  $(document).on(&#039;init.dt&#039;, function() {&lt;br /&gt;
    const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
    if (inputField) {&lt;br /&gt;
      inputField.value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
      document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
      const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
      inputField.dispatchEvent(searchEvent);&lt;br /&gt;
    }&lt;br /&gt;
  });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7954</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7954"/>
		<updated>2026-02-16T18:14:21Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  const inputField = document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;);&lt;br /&gt;
  if (inputField) {&lt;br /&gt;
    inputField.value = &amp;quot;KG-Klotzsche&amp;quot;;&lt;br /&gt;
    document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    // &#039;search&#039;-Event auslösen&lt;br /&gt;
    const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
    inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
    // Optional: DataTables-Suche explizit auslösen (falls nötig)&lt;br /&gt;
    if (typeof $.fn.dataTable !== &#039;undefined&#039;) {&lt;br /&gt;
      const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
      dataTable.search(&amp;quot;KG-Klotzsche&amp;quot;).draw();&lt;br /&gt;
    }&lt;br /&gt;
  } else {&lt;br /&gt;
    console.error(&amp;quot;Input-Feld nicht gefunden!&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7953</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7953"/>
		<updated>2026-02-16T18:11:11Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).value = &amp;quot;KG-Klotzsche&amp;quot;&lt;br /&gt;
document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
// Das &#039;search&#039;-Event manuell auslösen (für DataTables)&lt;br /&gt;
const searchEvent = new Event(&#039;search&#039;, {&lt;br /&gt;
  bubbles: true,&lt;br /&gt;
  cancelable: true&lt;br /&gt;
});&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7952</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7952"/>
		<updated>2026-02-16T18:10:33Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).value = &amp;quot;KG-Klotzsche&amp;quot;&lt;br /&gt;
document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
// Das &#039;search&#039;-Event manuell auslösen (für DataTables)&lt;br /&gt;
const searchEvent = new Event(&#039;search&#039;, {&lt;br /&gt;
  bubbles: true,&lt;br /&gt;
  cancelable: true&lt;br /&gt;
});&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7951</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7951"/>
		<updated>2026-02-16T18:09:15Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).value = &amp;quot;KG-Klotzsche&amp;quot;&lt;br /&gt;
document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
// Das &#039;search&#039;-Event manuell auslösen (für DataTables)&lt;br /&gt;
const searchEvent = new Event(&#039;search&#039;, {&lt;br /&gt;
  bubbles: true,&lt;br /&gt;
  cancelable: true&lt;br /&gt;
});&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7950</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7950"/>
		<updated>2026-02-16T18:08:47Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).value = &amp;lt;!--{$filter|escape:&#039;html&#039;}--&amp;gt;&lt;br /&gt;
document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
// Das &#039;search&#039;-Event manuell auslösen (für DataTables)&lt;br /&gt;
const searchEvent = new Event(&#039;search&#039;, {&lt;br /&gt;
  bubbles: true,&lt;br /&gt;
  cancelable: true&lt;br /&gt;
});&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7949</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7949"/>
		<updated>2026-02-16T18:08:16Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).value = &amp;quot;&amp;lt;!--{$filter|escape:&#039;html&#039;}--&amp;gt;&amp;quot;&lt;br /&gt;
document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
// Das &#039;search&#039;-Event manuell auslösen (für DataTables)&lt;br /&gt;
const searchEvent = new Event(&#039;search&#039;, {&lt;br /&gt;
  bubbles: true,&lt;br /&gt;
  cancelable: true&lt;br /&gt;
});&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7948</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7948"/>
		<updated>2026-02-16T17:52:09Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.querySelector(&amp;quot;#hotspots_filter input&amp;quot;).value = &amp;lt;!--{$filter|escape:&#039;html&#039;}--&amp;gt;&amp;lt;;&lt;br /&gt;
document.getElementById(&amp;quot;hotspots_filter&amp;quot;).style.display = &amp;quot;none&amp;quot;;&lt;br /&gt;
// Das &#039;search&#039;-Event manuell auslösen (für DataTables)&lt;br /&gt;
const searchEvent = new Event(&#039;search&#039;, {&lt;br /&gt;
  bubbles: true,&lt;br /&gt;
  cancelable: true&lt;br /&gt;
});&lt;br /&gt;
querySelector(&amp;quot;#hotspots_filter input&amp;quot;).inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
// Falls DataTables nicht automatisch reagiert, die Suche explizit auslösen&lt;br /&gt;
const dataTable = $(&#039;#hotspots&#039;).DataTable(); // Annahme: Die Tabelle hat die ID &#039;hotspots&#039;&lt;br /&gt;
dataTable.search(neuerWert).draw(); // Sucht nach dem neuen Wert und aktualisiert die Tabelle&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7947</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7947"/>
		<updated>2026-02-16T17:48:35Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
document.addEventListener(&#039;DOMContentLoaded&#039;, function() {&lt;br /&gt;
  const inputField = document.querySelector(&#039;#hotspots_filter input&#039;);&lt;br /&gt;
&lt;br /&gt;
  if (inputField) {&lt;br /&gt;
    const neuerWert = &amp;quot;Dein neuer Wert&amp;quot;;&lt;br /&gt;
    inputField.value = neuerWert;&lt;br /&gt;
&lt;br /&gt;
    // Event auslösen&lt;br /&gt;
    const searchEvent = new Event(&#039;search&#039;, { bubbles: true, cancelable: true });&lt;br /&gt;
    inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
    // DataTables-Suche auslösen (falls nötig)&lt;br /&gt;
    if (typeof $.fn.dataTable !== &#039;undefined&#039;) {&lt;br /&gt;
      const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
      dataTable.search(neuerWert).draw();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Element unsichtbar machen&lt;br /&gt;
    document.getElementById(&#039;hotspots_filter&#039;).style.display = &#039;none&#039;;&lt;br /&gt;
  } else {&lt;br /&gt;
    console.error(&#039;Input-Feld nicht gefunden! Überprüfe den Selektor.&#039;);&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
	<entry>
		<id>https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7946</id>
		<title>Widget:Hotspots-Filter</title>
		<link rel="alternate" type="text/html" href="https://wiki.freifunk-dresden.de/index.php?title=Widget:Hotspots-Filter&amp;diff=7946"/>
		<updated>2026-02-16T17:45:58Z</updated>

		<summary type="html">&lt;p&gt;Mikaff0: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
 IMPORTANT: it is important to load javascript data before loading jQuery.&lt;br /&gt;
 Because when jQuery is loaded it starts running and as soon as DOM is read, &amp;quot;handler&amp;quot; is&lt;br /&gt;
 called. When loading data file after jQuery, then jQuery may be faster to call handler, but&lt;br /&gt;
 without any data.&lt;br /&gt;
 https://datatables.net/manual/styling/classes&lt;br /&gt;
&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://api.freifunk-dresden.de/freifunk-dresden-hotspots.json.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- now load jQuery (before datatables. datatable initialisation depend on jQuery --&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/jquery/jquery-ui.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/jquery/jquery-ui.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; type=&amp;quot;text/css&amp;quot; href=&amp;quot;/hotspots/datatables/datatables.min.css&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/hotspots/datatables/datatables.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;style&amp;gt;&lt;br /&gt;
.stats {}&lt;br /&gt;
.statsx {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOCSURBVEiJ5ZfLbxtVGMV/c2fcelon9diOG1dGNN4QYiJYsGGBQGp4qkiwQbBBleiGP6AS/AM8VB5LNoAilmzKhrJBQgoIdYVAbVVqSBrn4feMX01dxzO+LBzfempHrcGhC87mes74+879zpwZzcADggbw3idfnTaE/mXH7cQPSigQMIpex337/XNnvwMwAHQhll99+dloLGJxdW2LdCrpK5oEV7arx7/9/sdlYAZAALiuG41FrEkOOISZqIXrurH+sTG4s1G/D4pTwn2L7mVht1FHTB/7R/avrNzhxdBW7oHdzPVxS0ZifOHVvx6McGftz4kIjxcuKQlnrqvz/1m4us0mhVaLR+NhrpVqvv955RJ/NHcPJlxe1fatg7j926/jtNpf2CuXRghXfesg2lcuT0a4demXIa5rV3yrgpTsXvkdTcr7Ft43XFM//0Q2/aSPC66tYwKF1XV4eF7ViEaNYzs7cLPx78K1kIiS37jBQiKKZpoqILUfOrRn4kRkh+2Bmva1OjagV8o88nh6SPS+w+XmcyBlbx2AV3UIzKXoVh0/Xyz0mjn+S9Dd2UFrtUZJ7CO83bPGzW37GzkOh+ZSeI4/1W6xiAiFEHel3d3Mopfy4wmLUEht4I6wTeBkCs/xT9wtFTi8+AT6XaHrbGTRC37X+hgZLieTQc4v0s5k2Og/pTI3sG42WTWOEm42wHVVzXQ2S/upZzh8acXX58jlqxja6HCpidOppAqBWbNJLC1h1mzFzVtH0YJBFhbn0YJBRLOuagL1GnPPLyEcW3HpVJKpegVRzPt6D02s4Hl4VYdDjy3iOTbS83q0Y6NbEQD0sIWo1wCQt26hGQb61DRSCGSrhWaaICWdrU30rgQpQdNGT9yH7lQwjs+iGQGM+KxKrOfYiD1hYUUQzQYAbrGAMZsAoBuL4xZ7YfLKJURoCmkewauU97daEaUCRvKhnh3JJO7W5p6wgx4O93jLQtSre8J59MSJnnB0Rm20s5ElcHIO70SSTnZ9SFhZnXvjNQBCgPPcaXJrW5jmNK1PP8ICGsDtp0/1eC2AefECuYsXAGi98Arba1sEIzGcz86r5q1TL6FNRXA+/qBHvPimOqcBvHv+C/nOmdeBybzK7sd9vvwNH547q8Ge1bqhV4tl/705aRRLNoZhqCeM+pLQhfa163oH9nJt6LrT9by3+l8S/z/8Dfo07AAuLNF8AAAAAElFTkSuQmCC&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
.grafanax {&lt;br /&gt;
   background-image:url(&#039;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAABYhJREFUSImdln1sldUdxz/nPC/33t5Su7RYirSsKJDBVlKsmQkoCoti4prokgkxZG9ZhvtjJm5LDC/6h875p2+Jc6KQadSsccoGIYrGzaHorLBWZVBaBhRKu9rS1/v2POf89sctvX287a3wS07uy/md7+d8f+d5zjlKRIQrDHPhvygvjq6uvaxxIoK+UmjQ8QHjD21ifMcPCDoOXdZYpRTqShybvjNM7PwhkhrNCyUrSD7SilNT/7U1LtuxiJB989kpKIBMjJJtfQrTdwYRmWr2y15Mz0lm8jajYxFBKRX5JMgSfLif3If7MMfbwIQzTkxVzsdtXIvpasf2ngKtKf/9XpxF10Xy3Ok/7NhFcgdfxXR+iuk7CwhObQO6bhnh0b/nheaqyPAAwftvTBO1hJ1HSoNNVzvZ15+OJIQD52Gmh0cpVHkluqYedVUVyothh/qx57uRiZFobhgUDY+AVSI5pyMcF2/N9/HXtuBc24iKl0W6JT1B2N1O8P5ego/2gzFk9+3CW30runphgTV9je3wAGO/Wj/r+ukFiym7/0mc+uVzTxAwPSdJ/3Eb5tTnOEubSG7fjfJiea2I44oqnOVNoKSo6WsaSO586WtDAZy6pSS378Ft/h6m6yi5d14pmIiAtSa2cQv4gCdTTZV5JH7+KLpyfpG4WIMd6iM82UbYfRR7sR+ZVjEVT1J23+O4K1eTe2cPkk0DX1ljALdpA05dA/ZCFyhAwLtxI851TVGgCPbsF2T+/DvM6Q4IcyCA6+EsWo5382a8G+9CuR4qniTxs8cYf+xuwhOH8RrXF28gMnERGe0Bf9JxDPwNW1BKRfLCtr+SeuIezJlPQGXzub6AzmF6PyPz2jZST27GDvbkS3v1YmK3/wTTdbi41AD27L9BpVC+RfkWffUCdP13Ijnm3BdkWh8ElcZtvImyrX8gufMtyh54jdjGraiKJMq32PNHSD17L3akDwBv7SZkvL+41JJLER47kJ/9ZDiLV0bcigjBP58DlcFb9yNid+5AOQUZd0kzbnMLmZd+gf3yNDLWQ/bNHcS3PIeeV4276raoYzt0mvSL9xB2tE65Vb5FV1ZFSxJkMOc+RlfNJ3bbAxHo1GQXLCN+7zOouEb5FtP9LvZ8R971qjsLYDvSS+blTdiB9vw6TW8qF1U1WTDDON9sRCUqiqCXQteuwP3WuslnxRAe3x/tF2vJHdyGpM6hPFvU7EhXVNFLoCqrQdKzQiF/5uq6xikdGTr2FfDgcey594qdTjYZbEfSQwVBN4bbeDe2/yNM7ycl4UimoCWpKFhVLcP77n0oX83oGJ0m/Gw3TDs9vRt+idOwhtyBnxIeewU73osd7cH2HSkwRZCBtoLj8S7s4H8KBiQf2FN/I/jX48joDEefP49Yy1501YqCsMliOl/HnNqHZAbRlUtxV21FV38bAHvxBNnW9SCmAKtaSeyuAyjHjx4SYgPs2YPY/o8xnS8jwVhh0Lx6/Ntb0RUNpcsLSJgi9/ZmbN/hYg93/AWndu0sdy4RwhO7CNu2k98HJ+GJGtzVD6PrW1BObGZoup/g8P3Y3nejHTqGXrgBt/lRdHnd7Jc9EUv46W8x3XuiHUqhypfgNGxG16xDJRaAcpDx09j+f2C6diOZ/xXS/W/grfkTat4SiNdMbUYlb5l24BDBoZbZui9Jg3bBFt8ycBK4zbtwFt5R1FW87UwLGf8cfDsHGMAU/aO8atym59Hzb51xREkwKkB5sxakZDgNW2aFzglW5dfmX35AoaBsOU79byC+CBk7gqQ6IRhCUsfz3y+NQ6Gqbi45sZJrLOEw9sIL4CRQ5dejyptQ2i/Oy/VhTvwYGfsARFBX3YKz4g2U9q4MfDkhEiLDB5GRt9G1v0bFFpXM/z/LE5JTSgZnuwAAAABJRU5ErkJggg==&#039;);&lt;br /&gt;
&lt;br /&gt;
    background-size: 30px;&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    display: block;&lt;br /&gt;
    width: 30px;&lt;br /&gt;
    height: 30px;&lt;br /&gt;
    text-decoration: none;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    text-indent: 100%;&lt;br /&gt;
    white-space:nowrap;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/style&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Spalten anzeigen:&amp;lt;/b&amp;gt; &lt;br /&gt;
&amp;lt;!-- &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;2&amp;quot;&amp;gt;Stats&amp;lt;/a&amp;gt;, --&amp;gt;&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;3&amp;quot;&amp;gt;IP-Adresse&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;5&amp;quot;&amp;gt;Uptime&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;6&amp;quot;&amp;gt;Erstmalig registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;7&amp;quot;&amp;gt;Registriert&amp;lt;/a&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;12&amp;quot;&amp;gt;SSID&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;13&amp;quot;&amp;gt;Gateway&amp;lt;/a&amp;gt;,&lt;br /&gt;
 &amp;lt;a class=&amp;quot;toggle-vis&amp;quot; data-column=&amp;quot;14&amp;quot;&amp;gt;Model&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table id=&amp;quot;hotspots&amp;quot; class=&amp;quot;display cell-border compact&amp;quot; style=&amp;quot;width:100%;&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;thead&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Node&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Stat&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Meshing&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;IP&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th title=&amp;quot;Online / Gateway / [Online oder Offline Tage]&amp;quot;&amp;gt;Ok&amp;lt;br&amp;gt;GW&amp;lt;br&amp;gt;Tage&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Uptime&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Erstmalig&amp;lt;br&amp;gt;registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Registriert&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Map&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Firmware&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;AU&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;SSID&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Gateway&amp;lt;br&amp;gt;aktuell/bevorzugt.&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Model&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Ort&amp;lt;/th&amp;gt;&lt;br /&gt;
                &amp;lt;th&amp;gt;Kommentar&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/thead&amp;gt;&lt;br /&gt;
        &amp;lt;tfoot&amp;gt;&lt;br /&gt;
            &amp;lt;tr style=&amp;quot;background-color:#434244;color:#cccccc;&amp;quot;&amp;gt;&lt;br /&gt;
	  &amp;lt;th colspan=&amp;quot;17&amp;quot; &amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
            &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;/tfoot&amp;gt;&lt;br /&gt;
 &amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function getIp(node)&lt;br /&gt;
{&lt;br /&gt;
 var _middle = Math.floor((node / 255)) % 256;&lt;br /&gt;
 var _minor  = (node % 255) + 1;&lt;br /&gt;
 return &#039;10.200.&#039; + _middle.toString() + &#039;.&#039; + _minor.toString();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
https://api.jquery.com/jquery.noconflict/&lt;br /&gt;
&lt;br /&gt;
If for some reason two versions of jQuery are loaded (which is not recommended), &lt;br /&gt;
calling $.noConflict(true) from the second version will return the globally &lt;br /&gt;
scoped jQuery variables to those of the first version.&lt;br /&gt;
Some times it could be issue with older version (or not stable) of JQuery files.&lt;br /&gt;
&lt;br /&gt;
Solution: move new jQuery completely in new object and use this.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
var my = {};&lt;br /&gt;
my.query = jQuery.noConflict( true );&lt;br /&gt;
&lt;br /&gt;
// use new way to call function when DOM is ready. old way was $(document).ready(handler)&lt;br /&gt;
my.query(function() {&lt;br /&gt;
  // remember Table, to later access it via event function when a link is clicked with&lt;br /&gt;
  // specific class name to make columns visible&lt;br /&gt;
  var myTable = my.query(&#039;#hotspots&#039;).DataTable( {&lt;br /&gt;
	&amp;quot;processing&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;pageLength&amp;quot; : 25,&lt;br /&gt;
	//&amp;quot;lengthMenu&amp;quot;: [[ 25, 50, 100, 200, -1 ], [25,50,100,200,&amp;quot;All&amp;quot;]],&lt;br /&gt;
	paging: false,&lt;br /&gt;
	&amp;quot;order&amp;quot; : [[0,&#039;asc&#039;]],&lt;br /&gt;
&lt;br /&gt;
	// extensions&lt;br /&gt;
	&amp;quot;fixedHeader&amp;quot;: true,&lt;br /&gt;
	//&amp;quot;responsive&amp;quot;: true,&lt;br /&gt;
	&amp;quot;language&amp;quot;:{&lt;br /&gt;
		&amp;quot;search&amp;quot;:&amp;quot;Filter&amp;quot;&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
	// define nowrap for specific columns&lt;br /&gt;
	&amp;quot;columnDefs&amp;quot;: [&lt;br /&gt;
		{ className: &amp;quot;dt-nowrap&amp;quot;, &amp;quot;targets&amp;quot;: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] },&lt;br /&gt;
		// default: visible&lt;br /&gt;
		{ visible: false, &amp;quot;targets&amp;quot;: [3,5,6,7,12,13,14] }&lt;br /&gt;
&lt;br /&gt;
	],&lt;br /&gt;
        &amp;quot;data&amp;quot;: dataSet,&lt;br /&gt;
&lt;br /&gt;
        // https://datatables.net/reference/option/rowCallback&lt;br /&gt;
	&amp;quot;rowCallback&amp;quot;: function( row, data ) {&lt;br /&gt;
		&lt;br /&gt;
		if ( data.id &amp;lt; 1000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#bbddbb&amp;quot; : &amp;quot;#cceecc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.id &amp;gt; 1000 &amp;amp;&amp;amp; data.id &amp;lt; 51000 )&lt;br /&gt;
		{&lt;br /&gt;
			row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#ddddee&amp;quot; : &amp;quot;#eeeeff&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		if ( data.status.offline_since &amp;gt; 2 )&lt;br /&gt;
		{	&lt;br /&gt;
			//row.style.backgroundColor= (row.className==&amp;quot;odd&amp;quot;) ? &amp;quot;#cccccc&amp;quot; : &amp;quot;#dddddd&amp;quot;;&lt;br /&gt;
			row.style.backgroundColor= &amp;quot;#cccccc&amp;quot;;&lt;br /&gt;
			//row.firstChild.style.backgroundColor = row.style.backgroundColor;&lt;br /&gt;
		}&lt;br /&gt;
	},&lt;br /&gt;
&lt;br /&gt;
        // see: https://datatables.net/manual/data/orthogonal-data&lt;br /&gt;
        &amp;quot;columns&amp;quot;: [&lt;br /&gt;
                // node&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + data + &#039;.freifunk-dresden.de/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + data + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                // statistic icon&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var stat = &#039;&amp;lt;a class=&amp;quot;stats&amp;quot; data=&amp;quot;&#039; + data + &#039;&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/stat.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        var grafana = &#039;&amp;lt;a href=&amp;quot;https://grafana.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;/hotspots/images/grafana.png&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
                                        return stat + grafana;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //connections&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.connection_types&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var wifi = data.wifi ? &#039;&amp;lt;img title=&amp;quot;meshing via wifi&amp;quot; src=&amp;quot;/hotspots/images/wifi-on-24.png&amp;quot;&amp;gt;&#039; &lt;br /&gt;
							     : &#039;&amp;lt;img title=&amp;quot;Kein wifi meshing&amp;quot; src=&amp;quot;/hotspots/images/wifi-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var backbone = data.backbone ? &#039;&amp;lt;img title=&amp;quot;meshing via backbone&amp;quot; src=&amp;quot;/hotspots/images/backbone-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
								     : &#039;&amp;lt;img title=&amp;quot;Kein backbone meshing&amp;quot; src=&amp;quot;/hotspots/images/backbone-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					var lan = data.lan ? &#039;&amp;lt;img title=&amp;quot;meshing via lan&amp;quot; src=&amp;quot;/hotspots/images/lan-on-24.png&amp;quot;&amp;gt;&#039;&lt;br /&gt;
							   : &#039;&amp;lt;img title=&amp;quot;Kein lan meshing&amp;quot; src=&amp;quot;/hotspots/images/lan-off-24.png&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
					return wifi + &#039;&amp;amp;nbsp;&#039; + backbone + &#039;&amp;amp;nbsp;&#039; + lan;&lt;br /&gt;
				}&lt;br /&gt;
                                // sort&lt;br /&gt;
                                var sort_value = data.lan ? 1 : 0;&lt;br /&gt;
                                if(data.backbone) sort_value += 10;&lt;br /&gt;
                                if(data.wifi) sort_value += 100;&lt;br /&gt;
				return sort_value;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //ip&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,   //use &amp;quot;id&amp;quot; as input data for renderer&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var ip = getIp(data);&lt;br /&gt;
					return &#039;&amp;lt;a href=&amp;quot;http://&#039; + ip + &#039;/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&#039; + ip + &#039;&amp;lt;/a&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //online/gw/tage&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        var t = new Date(data.lastseen*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					var stat_time = day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
&lt;br /&gt;
					var img_o = data.online ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
					var img_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;yes.png&#039; : &#039;no-grey.png&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // tage sind offline oder online tage, abhaengig vom aktuellen zustand.&lt;br /&gt;
                                        var days = data.online ? Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
                                        var title_o = data.online ? &#039;Online seit &#039; + Math.floor(data.uptime / 86400) + &#039; Tagen&#039;: &#039;Offline seit &#039; + data.offline_since + &#039; Tagen&#039;; &lt;br /&gt;
                                        var title_g = data.gateway &amp;amp;&amp;amp; data.online ? &#039;Gateway&#039; : &#039;Kein Gateway&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_g= data.gateway &amp;amp;&amp;amp; data.online ? &#039;+gw&#039; : &#039;-gw&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_g+&#039;&amp;quot; title=&amp;quot;&#039;+title_o+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_o + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
						+ &#039;&amp;lt;img title=&amp;quot;&#039;+title_g+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_g + &#039;&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                                                + &#039;[&#039; + days + &#039;]&#039; ;&lt;br /&gt;
				}&lt;br /&gt;
				return data.online ? - Math.floor(data.uptime / 86400) : data.offline_since;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //uptime&lt;br /&gt;
                { &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
                  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
                                var rest = 0;&lt;br /&gt;
                                if(data.online){ rest = data.uptime };&lt;br /&gt;
				// If display or filter data is requested, format the date&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
                                        &lt;br /&gt;
                                        var days = Math.floor(rest / 86400);&lt;br /&gt;
                                        rest = rest % 86400;&lt;br /&gt;
                                        var hours = Math.floor(rest / 3600);&lt;br /&gt;
                                        rest = rest % 3600;&lt;br /&gt;
                                        var minutes = Math.floor(rest/60);&lt;br /&gt;
&lt;br /&gt;
					return days+&#039;d &#039;+hours+&#039;h &#039;+minutes+&#039;m&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				//else return id that is used when sorting this column&lt;br /&gt;
				return rest;&lt;br /&gt;
			}&lt;br /&gt;
                },&lt;br /&gt;
                //firstseen&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.firstseen&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //registerred&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.registered&amp;quot;, &lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var t = new Date(data*1000);&lt;br /&gt;
					var day = ( &#039;0&#039; + t.getDate() ).slice(-2);&lt;br /&gt;
					var month = ( &#039;0&#039; + (t.getMonth() + 1) ).slice(-2);&lt;br /&gt;
					var h = ( &#039;0&#039; + t.getHours() ).slice(-2);&lt;br /&gt;
					var m = ( &#039;0&#039; + t.getMinutes() ).slice(-2);&lt;br /&gt;
					return day + &#039;.&#039; + month + &#039;.&#039; + t.getFullYear()&lt;br /&gt;
					       + &#039; &#039; + h + &#039;:&#039; + m;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //nick&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;name&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,15); }&lt;br /&gt;
		},&lt;br /&gt;
                //map&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;id&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return &#039;&amp;lt;a href=&amp;quot;https://meshviewer.freifunk-dresden.de/&#039; + data + &#039;&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Map&amp;lt;/a&amp;gt;&#039;; &lt;br /&gt;
				}&lt;br /&gt;
				return 0;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //firmware version&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;firmware&amp;quot; },&lt;br /&gt;
                //autoupdate&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.autoupdate&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
					var img_au = data ? &#039;yes.png&#039; : &#039;no.png&#039;;&lt;br /&gt;
                                        var title_au = data ? &#039;Auto-Update&#039; : &#039;Kein Auto-Update&#039;;&lt;br /&gt;
&lt;br /&gt;
                                        // definiere einfach ein attribut, was ebenfalls von data-table beim filtern verwendet wird.&lt;br /&gt;
                                        var search_au= data ? &#039;+au&#039; : &#039;-au&#039;;&lt;br /&gt;
&lt;br /&gt;
					return &#039;&amp;lt;img search=&amp;quot;&#039;+search_au+&#039;&amp;quot; title=&amp;quot;&#039;+title_au+&#039;&amp;quot; src=&amp;quot;/hotspots/images/&#039; + img_au + &#039;&amp;quot;&amp;gt;&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //wifi ssid&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status.ssid&amp;quot;},&lt;br /&gt;
                //preverred gateway&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;status&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) {&lt;br /&gt;
				if ( type === &#039;display&#039; || type === &#039;filter&#039; ) {&lt;br /&gt;
				  return data.selected_gateway + &#039;(&#039; + data.preferred_gateway + &#039;)&#039;;&lt;br /&gt;
				}&lt;br /&gt;
				return data.selected_gateway;&lt;br /&gt;
			}&lt;br /&gt;
		},&lt;br /&gt;
                //device model&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;model&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //location&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;location&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,25); }&lt;br /&gt;
		},&lt;br /&gt;
                //comment&lt;br /&gt;
		{ &amp;quot;data&amp;quot;: &amp;quot;note&amp;quot;,&lt;br /&gt;
		  &amp;quot;render&amp;quot; : function (data, type, row) { return data.substring(0,60); }&lt;br /&gt;
		},&lt;br /&gt;
        ]&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
    //function that is called each time a link with class &amp;quot;toggle-vis&amp;quot; is clicked.&lt;br /&gt;
    //Then corresponding column visibility toggles&lt;br /&gt;
    my.query(&#039;a.toggle-vis&#039;).on( &#039;click&#039;, function (e) {&lt;br /&gt;
        e.preventDefault();&lt;br /&gt;
 &lt;br /&gt;
        // Get the column API object&lt;br /&gt;
        var column = myTable.column( $(this).attr(&#039;data-column&#039;) );&lt;br /&gt;
 &lt;br /&gt;
        // Toggle the visibility&lt;br /&gt;
        column.visible( ! column.visible() );&lt;br /&gt;
    } );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    //register event handler&lt;br /&gt;
    my.query(&#039;#hotspots tbody&#039;).on(&#039;click&#039;, &#039;a.stats&#039;, function () {&lt;br /&gt;
        var id = this.attributes[&#039;data&#039;].nodeValue;&lt;br /&gt;
&lt;br /&gt;
        //create  &amp;lt;div&amp;gt;&lt;br /&gt;
        var popup = &#039;&amp;lt;div id=&amp;quot;statdialog&#039; + id + &#039;&amp;quot; title=&amp;quot;Statistik&amp;quot;&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;b&amp;gt;Knoten:&amp;lt;/b&amp;gt; &#039; + id + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_h_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;6hour&amp;quot;)\&#039;&amp;gt;6 Stunden&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_d_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1day&amp;quot;)\&#039;&amp;gt;Tag&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_w_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1week&amp;quot;)\&#039;&amp;gt;Woche&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_m_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1month&amp;quot;)\&#039;&amp;gt;Monat&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;button id=&amp;quot;btn_y_&#039;+id+&#039;&amp;quot; onclick=\&#039;switchTime(&#039; + id + &#039;, &amp;quot;1year&amp;quot;)\&#039;&amp;gt;Jahr&amp;lt;/button&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_timing_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_clients_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_backbone_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_ap_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;br&amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;img id=&amp;quot;img_vpn_&#039;+id+&#039;&amp;quot; height=&amp;quot;150&amp;quot; width=&amp;quot;350&amp;quot; &amp;gt;&#039;&lt;br /&gt;
                  + &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
        my.query(&#039;body&#039;).append(popup);&lt;br /&gt;
&lt;br /&gt;
       // elements must exist as DOM objects before accessing&lt;br /&gt;
       switchTime(id, &#039;1day&#039;);&lt;br /&gt;
&lt;br /&gt;
        //show popup&lt;br /&gt;
        my.query( &#039;#statdialog&#039; + id ).dialog({&lt;br /&gt;
           resizable: false,&lt;br /&gt;
           height: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           //width: 792, //16+380+380+16 (margin is 16)&lt;br /&gt;
           //width: 792, //16+350+16 (margin is 16)&lt;br /&gt;
           width: &amp;quot;auto&amp;quot;,&lt;br /&gt;
           modal: false,&lt;br /&gt;
           // position: { my: &amp;quot;left top&amp;quot;, at: &amp;quot;left top&amp;quot;},&lt;br /&gt;
           close: function( event, ui ) {&lt;br /&gt;
                    my.query( &#039;#statdialog&#039; ).remove();  //remove div&lt;br /&gt;
                  }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
    }); //event handler statistic&lt;br /&gt;
&lt;br /&gt;
 } );&lt;br /&gt;
&lt;br /&gt;
 //function must be global, so it can be found by onclick handlers.&lt;br /&gt;
        function switchTime(id,period){&lt;br /&gt;
            //var period=&#039;1day&#039;; //6hour,1day,1week,1month,1year&lt;br /&gt;
            var srcTiming=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/timing/&#039; + period;&lt;br /&gt;
            var srcClients=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/clients/&#039; + period;&lt;br /&gt;
            var srcBackbone=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/backbone/&#039; + period;&lt;br /&gt;
            var srcAp=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/ap/&#039; + period;&lt;br /&gt;
            var srcVpn=&#039;https://stats.freifunk-dresden.de/&#039; + id + &#039;/vpn/&#039; + period;&lt;br /&gt;
            my.query(&#039;#img_timing_&#039;+id).attr(&amp;quot;src&amp;quot;,srcTiming);&lt;br /&gt;
            my.query(&#039;#img_clients_&#039;+id).attr(&amp;quot;src&amp;quot;,srcClients);&lt;br /&gt;
            my.query(&#039;#img_backbone_&#039;+id).attr(&amp;quot;src&amp;quot;,srcBackbone);&lt;br /&gt;
            my.query(&#039;#img_ap_&#039;+id).attr(&amp;quot;src&amp;quot;,srcAp);&lt;br /&gt;
            my.query(&#039;#img_vpn_&#039;+id).attr(&amp;quot;src&amp;quot;,srcVpn);&lt;br /&gt;
            //mark button (boarder)&lt;br /&gt;
            my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:none;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;6hour&amp;quot;) my.query(&#039;#btn_h_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1day&amp;quot;) my.query(&#039;#btn_d_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1week&amp;quot;) my.query(&#039;#btn_w_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1month&amp;quot;) my.query(&#039;#btn_m_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
            if(period==&amp;quot;1year&amp;quot;) my.query(&#039;#btn_y_&#039;+id).attr(&amp;quot;style&amp;quot;,&amp;quot;background-color:powderblue;&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
//set filter by widget param and make the filter field unvisible&lt;br /&gt;
const neuerWert = &amp;quot;KG-Klotzsche&amp;quot;  //&amp;lt;!--{$input|escape:&#039;html&#039;}--&amp;gt;; &lt;br /&gt;
const inputField = document.querySelector(&#039;#hotspots_filter input&#039;);&lt;br /&gt;
inputField.value = neuerWert;&lt;br /&gt;
&lt;br /&gt;
const searchEvent = new Event(&#039;search&#039;, {&lt;br /&gt;
  bubbles: true,&lt;br /&gt;
  cancelable: true&lt;br /&gt;
});&lt;br /&gt;
inputField.dispatchEvent(searchEvent);&lt;br /&gt;
&lt;br /&gt;
const dataTable = $(&#039;#hotspots&#039;).DataTable();&lt;br /&gt;
dataTable.search(neuerWert).draw();&lt;br /&gt;
&lt;br /&gt;
document.getElementById(&#039;hotspots_filter&#039;).style.display = &#039;none&#039;;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mikaff0</name></author>
	</entry>
</feed>