Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Off Topic
  4. IP-Scanner für das Hausnetz.

NEWS

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    22
    1
    1.1k

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    9.2k

  • Monatsrückblick – September 2025
    BluefoxB
    Bluefox
    14
    1
    2.4k

IP-Scanner für das Hausnetz.

Geplant Angeheftet Gesperrt Verschoben Off Topic
7 Beiträge 5 Kommentatoren 614 Aufrufe 5 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • B Offline
    B Offline
    Beowolf
    schrieb am zuletzt editiert von
    #1

    Das ist ein kleiner Webserver-Scanner für das eigene Netzwerk. Das Programm listet dann die gefundenen Adressen auf und durch einen Mausklick kann die entsprechende Adresse direkt aufgerufen werden.

    Der IP-Bereich kann eingestellt werden.

    Ich habe mal versucht eine Anleitung für das Programm zu schreiben.

    1. Entpacke die ZIP-Datei.

    2. Installiere PyInstaller (falls noch nicht geschehen):

      pip install pyinstaller

    3. Starte das Build-Skript build_webscanner.bat per Doppelklick oder über die Eingabeaufforderung:

      build_webscanner.bat

    4. Die fertige EXE-Datei findest du danach im Ordner dist.

    webscanner.zip

    Hier der Inhalt der einzelnen Dateien. Nichts böses drin. :blush:

    webscanner.py

    import tkinter as tk
    from tkinter import ttk
    import webbrowser
    import socket
    import threading
    import queue
    from concurrent.futures import ThreadPoolExecutor
    
    START_IP = "192.168.49.1"
    END_IP = "192.168.49.254"
    PORTS = [80]
    
    def ip_to_int(ip):
        parts = list(map(int, ip.split(".")))
        return (parts[0]<<24) + (parts[1]<<16) + (parts[2]<<8) + parts[3]
    
    def int_to_ip(i):
        return f"{(i>>24)&0xFF}.{(i>>16)&0xFF}.{(i>>8)&0xFF}.{i&0xFF}"
    
    def generate_ips(start_ip, end_ip):
        start = ip_to_int(start_ip)
        end = ip_to_int(end_ip)
        for i in range(start, end+1):
            yield int_to_ip(i)
    
    class WebserverScanner:
        def __init__(self, progress_callback=None):
            self.progress_callback = progress_callback
    
        def scan_ip_port(self, ip, port):
            try:
                with socket.create_connection((ip, port), timeout=0.5):
                    return True
            except:
                return False
    
        def get_hostname(self, ip):
            try:
                return socket.gethostbyaddr(ip)[0]
            except:
                return "Kein Hostname"
    
        def scan_threaded(self, ips, ports):
            results = []
            total = len(ips)*len(ports)
            count_lock = threading.Lock()
            count = [0]
    
            def scan_one(ip_port):
                ip, port = ip_port
                if self.scan_ip_port(ip, port):
                    hostname = self.get_hostname(ip)
                    res = {"ip": ip, "hostname": hostname, "port": port}
                else:
                    res = None
                with count_lock:
                    count[0] += 1
                    if self.progress_callback:
                        self.progress_callback(count[0], total)
                return res
    
            ip_ports = [(ip, port) for ip in ips for port in ports]
    
            with ThreadPoolExecutor(max_workers=100) as executor:
                for r in executor.map(scan_one, ip_ports):
                    if r:
                        results.append(r)
    
            return results
    
    class WebserverViewerApp:
        def __init__(self, root):
            self.root = root
            self.root.title("Webserver Scanner 192.168.49.x")
            self.root.geometry("900x700")
    
            self.entries = []
            self.queue = queue.Queue()
            self.resize_after_id = None
            self.current_columns = None  # Merke letzte Spaltenanzahl
            self.entries_displayed = None
    
            self.header = tk.Label(root, text="Webserver Scanner 192.168.49.1 - 254", font=("Arial", 18))
            self.header.pack(pady=10)
    
            self.progress = ttk.Progressbar(root, orient="horizontal", length=600, mode="determinate")
            self.progress.pack(pady=10)
    
            self.status_label = tk.Label(root, text="Bereit", font=("Arial", 12))
            self.status_label.pack()
    
            self.update_btn = tk.Button(root, text="Jetzt scannen", command=self.start_scan)
            self.update_btn.pack(pady=10)
    
            self.canvas = tk.Canvas(root)
            self.scroll_frame = tk.Frame(self.canvas)
            self.scrollbar = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
            self.canvas.configure(yscrollcommand=self.scrollbar.set)
    
            self.scrollbar.pack(side="right", fill="y")
            self.canvas.pack(fill="both", expand=True)
    
            # Erstelle Fenster-Item für scroll_frame im Canvas
            self.canvas_frame = self.canvas.create_window((0,0), window=self.scroll_frame, anchor="nw")
    
            # Scrollregion aktualisieren bei Größe des scroll_frame
            self.scroll_frame.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
    
            # Breite des scroll_frame immer an Canvas-Breite anpassen
            self.canvas.bind('<Configure>', self.resize_scroll_frame)
    
            # Debounced Resize-Handler für Fenstergröße
            self.root.bind("<Configure>", self.on_resize)
    
            self.root.after(100, self.check_queue)
    
        def resize_scroll_frame(self, event):
            self.canvas.itemconfig(self.canvas_frame, width=event.width)
    
        def on_resize(self, event):
            # Debounce mit 300ms Delay
            if self.resize_after_id:
                self.root.after_cancel(self.resize_after_id)
            self.resize_after_id = self.root.after(300, lambda: self.update_display(self.entries))
    
        def start_scan(self):
            self.update_btn.config(state="disabled")
            self.progress['value'] = 0
            self.status_label.config(text="Scan läuft...")
            threading.Thread(target=self.run_scan, daemon=True).start()
    
        def progress_callback(self, count, total):
            percent = int((count / total) * 100)
            self.queue.put(("progress", percent))
    
        def run_scan(self):
            scanner = WebserverScanner(progress_callback=self.progress_callback)
            ips = list(generate_ips(START_IP, END_IP))
            results = scanner.scan_threaded(ips, PORTS)
            self.queue.put(("done", results))
    
        def check_queue(self):
            try:
                while True:
                    msg, data = self.queue.get_nowait()
                    if msg == "progress":
                        self.progress['value'] = data
                        self.status_label.config(text=f"Scan läuft... {data}%")
                    elif msg == "done":
                        self.entries = data
                        self.update_display(data)
                        self.status_label.config(text=f"Scan abgeschlossen. {len(data)} Server gefunden.")
                        self.update_btn.config(state="normal")
            except queue.Empty:
                pass
            self.root.after(100, self.check_queue)
    
        def update_display(self, entries):
            # Berechne aktuelle Spaltenanzahl
            frame_width = self.canvas.winfo_width() or 900
            box_min_width = 170
            columns = max(1, frame_width // box_min_width)
    
            # Prüfe, ob Spaltenanzahl oder Einträge sich geändert haben
            if self.current_columns == columns and self.entries_displayed == entries:
                return
    
            self.current_columns = columns
            self.entries_displayed = entries
    
            # Alte Widgets löschen
            for widget in self.scroll_frame.winfo_children():
                widget.destroy()
    
            if not entries:
                tk.Label(self.scroll_frame, text="Keine Webserver gefunden", font=("Arial", 14), fg="red").pack(pady=20)
                return
    
            box_height = 110
            for index, entry in enumerate(entries):
                row = index // columns
                col = index % columns
    
                container = tk.Frame(self.scroll_frame, bd=1, relief="solid", padx=5, pady=5)
                container.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
    
                ip_label = tk.Label(container, text=entry['ip'], font=("Arial", 12, "bold"))
                ip_label.pack()
    
                if entry['hostname']:
                    host_label = tk.Label(container, text=entry['hostname'], font=("Arial", 10), fg="gray")
                    host_label.pack()
    
                btn_color = "#4CAF50" if entry['port'] == 80 else "#2196F3"
                open_button = tk.Button(container, text=f"Öffnen (Port {entry['port']})",
                                        bg=btn_color, fg="white",
                                        command=lambda ip=entry['ip'], port=entry['port']: self.open_url(ip, port))
                open_button.pack(pady=5, fill="x")
    
            # Spalten gleichmäßig verteilen
            for c in range(columns):
                self.scroll_frame.grid_columnconfigure(c, weight=1)
    
        def open_url(self, ip, port):
            url = f"https://{ip}" if port == 443 else f"http://{ip}"
            webbrowser.open(url)
    
    if __name__ == "__main__":
        root = tk.Tk()
        app = WebserverViewerApp(root)
        root.mainloop()
    
    

    build_webscanner.bat

    @echo off
    echo.
    echo ===============================
    echo   Building webscanner.exe ...
    echo ===============================
    echo.
    
    
    
    pyinstaller webscanner.spec
    
    echo.
    echo Fertig! EXE liegt in /dist/webscanner.exe
    pause
    

    webscanner.spec

    # webscanner.spec
    block_cipher = None
    
    a = Analysis(
        ['webscanner.py'],
        pathex=[],
        binaries=[],
        datas=[],
        hiddenimports=[],
        hookspath=[],
        hooksconfig={},
        runtime_hooks=[],
        excludes=[],
        win_no_prefer_redirects=False,
        win_private_assemblies=False,
        cipher=block_cipher,
        noarchive=False,
    )
    
    pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
    
    exe = EXE(
        pyz,
        a.scripts,
        [],
        exclude_binaries=True,
        name='webscanner',
        debug=False,
        bootloader_ignore_signals=False,
        strip=False,
        upx=True,
        console=False,  # GUI-Anwendung (kein Terminalfenster)
        )
    
    coll = COLLECT(
        exe,
        a.binaries,
        a.zipfiles,
        a.datas,
        strip=False,
        upx=True,
        name='webscanner',
    )
    

    Das Programm kann natürlich auch direkt im cmd-Fenster (Windows) durch python webscanner.py im entsprechenden Verzeichnis gestartet werden.

    Vor dem Start oder der Erstellung der EXE-Datei muß natürlich der IP-Bereich in webscanner.py angepasst werden.

    START_IP = "192.168.49.1"
    END_IP = "192.168.49.254"
    PORTS = [80]
    

    Wenn es läuft, sollte es etwa so aussehen:

    webscanner.jpg

    Viel Spaß damit

    Die Natur braucht nicht unseren Schutz, sie braucht unsere Abwesenheit.

    OliverIOO 1 Antwort Letzte Antwort
    0
    • arteckA Offline
      arteckA Offline
      arteck
      Developer Most Active
      schrieb am zuletzt editiert von
      #2

      macht der das nicht auch ..

      dd5bd92a-a2e6-4416-93d1-fe4d348a101e-grafik.png

      zigbee hab ich, zwave auch, nuc's genauso und HA auch

      B 1 Antwort Letzte Antwort
      0
      • arteckA arteck

        macht der das nicht auch ..

        dd5bd92a-a2e6-4416-93d1-fe4d348a101e-grafik.png

        B Offline
        B Offline
        Beowolf
        schrieb am zuletzt editiert von
        #3

        @arteck
        Mag sein. Mein kleines PRogramm läuft "auserhalb" von ioBroker.

        Und das tolle an meinem Programm ist, es ist vollkommen kostenlos. Es kostet keine 5,95 €.

        :flushed: :flushed: :flushed:

        Die Natur braucht nicht unseren Schutz, sie braucht unsere Abwesenheit.

        HomoranH 1 Antwort Letzte Antwort
        1
        • B Beowolf

          @arteck
          Mag sein. Mein kleines PRogramm läuft "auserhalb" von ioBroker.

          Und das tolle an meinem Programm ist, es ist vollkommen kostenlos. Es kostet keine 5,95 €.

          :flushed: :flushed: :flushed:

          HomoranH Nicht stören
          HomoranH Nicht stören
          Homoran
          Global Moderator Administrators
          schrieb am zuletzt editiert von
          #4

          @beowolf sagte in IP-Scanner für das Hausnetz.:

          Mein kleines PRogramm läuft "auserhalb" von ioBroker.

          Deswegen hab ich es auch nach offTopic verschoben!

          kein Support per PN! - Fragen im Forum stellen - es gibt fast nichts, was nicht auch für andere interessant ist.

          Benutzt das Voting rechts unten im Beitrag wenn er euch geholfen hat.

          der Installationsfixer: curl -fsL https://iobroker.net/fix.sh | bash -

          1 Antwort Letzte Antwort
          0
          • B Offline
            B Offline
            Beowolf
            schrieb am zuletzt editiert von
            #5

            Ok. Danke.

            Die Natur braucht nicht unseren Schutz, sie braucht unsere Abwesenheit.

            1 Antwort Letzte Antwort
            0
            • B Beowolf

              Das ist ein kleiner Webserver-Scanner für das eigene Netzwerk. Das Programm listet dann die gefundenen Adressen auf und durch einen Mausklick kann die entsprechende Adresse direkt aufgerufen werden.

              Der IP-Bereich kann eingestellt werden.

              Ich habe mal versucht eine Anleitung für das Programm zu schreiben.

              1. Entpacke die ZIP-Datei.

              2. Installiere PyInstaller (falls noch nicht geschehen):

                pip install pyinstaller

              3. Starte das Build-Skript build_webscanner.bat per Doppelklick oder über die Eingabeaufforderung:

                build_webscanner.bat

              4. Die fertige EXE-Datei findest du danach im Ordner dist.

              webscanner.zip

              Hier der Inhalt der einzelnen Dateien. Nichts böses drin. :blush:

              webscanner.py

              import tkinter as tk
              from tkinter import ttk
              import webbrowser
              import socket
              import threading
              import queue
              from concurrent.futures import ThreadPoolExecutor
              
              START_IP = "192.168.49.1"
              END_IP = "192.168.49.254"
              PORTS = [80]
              
              def ip_to_int(ip):
                  parts = list(map(int, ip.split(".")))
                  return (parts[0]<<24) + (parts[1]<<16) + (parts[2]<<8) + parts[3]
              
              def int_to_ip(i):
                  return f"{(i>>24)&0xFF}.{(i>>16)&0xFF}.{(i>>8)&0xFF}.{i&0xFF}"
              
              def generate_ips(start_ip, end_ip):
                  start = ip_to_int(start_ip)
                  end = ip_to_int(end_ip)
                  for i in range(start, end+1):
                      yield int_to_ip(i)
              
              class WebserverScanner:
                  def __init__(self, progress_callback=None):
                      self.progress_callback = progress_callback
              
                  def scan_ip_port(self, ip, port):
                      try:
                          with socket.create_connection((ip, port), timeout=0.5):
                              return True
                      except:
                          return False
              
                  def get_hostname(self, ip):
                      try:
                          return socket.gethostbyaddr(ip)[0]
                      except:
                          return "Kein Hostname"
              
                  def scan_threaded(self, ips, ports):
                      results = []
                      total = len(ips)*len(ports)
                      count_lock = threading.Lock()
                      count = [0]
              
                      def scan_one(ip_port):
                          ip, port = ip_port
                          if self.scan_ip_port(ip, port):
                              hostname = self.get_hostname(ip)
                              res = {"ip": ip, "hostname": hostname, "port": port}
                          else:
                              res = None
                          with count_lock:
                              count[0] += 1
                              if self.progress_callback:
                                  self.progress_callback(count[0], total)
                          return res
              
                      ip_ports = [(ip, port) for ip in ips for port in ports]
              
                      with ThreadPoolExecutor(max_workers=100) as executor:
                          for r in executor.map(scan_one, ip_ports):
                              if r:
                                  results.append(r)
              
                      return results
              
              class WebserverViewerApp:
                  def __init__(self, root):
                      self.root = root
                      self.root.title("Webserver Scanner 192.168.49.x")
                      self.root.geometry("900x700")
              
                      self.entries = []
                      self.queue = queue.Queue()
                      self.resize_after_id = None
                      self.current_columns = None  # Merke letzte Spaltenanzahl
                      self.entries_displayed = None
              
                      self.header = tk.Label(root, text="Webserver Scanner 192.168.49.1 - 254", font=("Arial", 18))
                      self.header.pack(pady=10)
              
                      self.progress = ttk.Progressbar(root, orient="horizontal", length=600, mode="determinate")
                      self.progress.pack(pady=10)
              
                      self.status_label = tk.Label(root, text="Bereit", font=("Arial", 12))
                      self.status_label.pack()
              
                      self.update_btn = tk.Button(root, text="Jetzt scannen", command=self.start_scan)
                      self.update_btn.pack(pady=10)
              
                      self.canvas = tk.Canvas(root)
                      self.scroll_frame = tk.Frame(self.canvas)
                      self.scrollbar = tk.Scrollbar(root, orient="vertical", command=self.canvas.yview)
                      self.canvas.configure(yscrollcommand=self.scrollbar.set)
              
                      self.scrollbar.pack(side="right", fill="y")
                      self.canvas.pack(fill="both", expand=True)
              
                      # Erstelle Fenster-Item für scroll_frame im Canvas
                      self.canvas_frame = self.canvas.create_window((0,0), window=self.scroll_frame, anchor="nw")
              
                      # Scrollregion aktualisieren bei Größe des scroll_frame
                      self.scroll_frame.bind("<Configure>", lambda e: self.canvas.configure(scrollregion=self.canvas.bbox("all")))
              
                      # Breite des scroll_frame immer an Canvas-Breite anpassen
                      self.canvas.bind('<Configure>', self.resize_scroll_frame)
              
                      # Debounced Resize-Handler für Fenstergröße
                      self.root.bind("<Configure>", self.on_resize)
              
                      self.root.after(100, self.check_queue)
              
                  def resize_scroll_frame(self, event):
                      self.canvas.itemconfig(self.canvas_frame, width=event.width)
              
                  def on_resize(self, event):
                      # Debounce mit 300ms Delay
                      if self.resize_after_id:
                          self.root.after_cancel(self.resize_after_id)
                      self.resize_after_id = self.root.after(300, lambda: self.update_display(self.entries))
              
                  def start_scan(self):
                      self.update_btn.config(state="disabled")
                      self.progress['value'] = 0
                      self.status_label.config(text="Scan läuft...")
                      threading.Thread(target=self.run_scan, daemon=True).start()
              
                  def progress_callback(self, count, total):
                      percent = int((count / total) * 100)
                      self.queue.put(("progress", percent))
              
                  def run_scan(self):
                      scanner = WebserverScanner(progress_callback=self.progress_callback)
                      ips = list(generate_ips(START_IP, END_IP))
                      results = scanner.scan_threaded(ips, PORTS)
                      self.queue.put(("done", results))
              
                  def check_queue(self):
                      try:
                          while True:
                              msg, data = self.queue.get_nowait()
                              if msg == "progress":
                                  self.progress['value'] = data
                                  self.status_label.config(text=f"Scan läuft... {data}%")
                              elif msg == "done":
                                  self.entries = data
                                  self.update_display(data)
                                  self.status_label.config(text=f"Scan abgeschlossen. {len(data)} Server gefunden.")
                                  self.update_btn.config(state="normal")
                      except queue.Empty:
                          pass
                      self.root.after(100, self.check_queue)
              
                  def update_display(self, entries):
                      # Berechne aktuelle Spaltenanzahl
                      frame_width = self.canvas.winfo_width() or 900
                      box_min_width = 170
                      columns = max(1, frame_width // box_min_width)
              
                      # Prüfe, ob Spaltenanzahl oder Einträge sich geändert haben
                      if self.current_columns == columns and self.entries_displayed == entries:
                          return
              
                      self.current_columns = columns
                      self.entries_displayed = entries
              
                      # Alte Widgets löschen
                      for widget in self.scroll_frame.winfo_children():
                          widget.destroy()
              
                      if not entries:
                          tk.Label(self.scroll_frame, text="Keine Webserver gefunden", font=("Arial", 14), fg="red").pack(pady=20)
                          return
              
                      box_height = 110
                      for index, entry in enumerate(entries):
                          row = index // columns
                          col = index % columns
              
                          container = tk.Frame(self.scroll_frame, bd=1, relief="solid", padx=5, pady=5)
                          container.grid(row=row, column=col, padx=5, pady=5, sticky="nsew")
              
                          ip_label = tk.Label(container, text=entry['ip'], font=("Arial", 12, "bold"))
                          ip_label.pack()
              
                          if entry['hostname']:
                              host_label = tk.Label(container, text=entry['hostname'], font=("Arial", 10), fg="gray")
                              host_label.pack()
              
                          btn_color = "#4CAF50" if entry['port'] == 80 else "#2196F3"
                          open_button = tk.Button(container, text=f"Öffnen (Port {entry['port']})",
                                                  bg=btn_color, fg="white",
                                                  command=lambda ip=entry['ip'], port=entry['port']: self.open_url(ip, port))
                          open_button.pack(pady=5, fill="x")
              
                      # Spalten gleichmäßig verteilen
                      for c in range(columns):
                          self.scroll_frame.grid_columnconfigure(c, weight=1)
              
                  def open_url(self, ip, port):
                      url = f"https://{ip}" if port == 443 else f"http://{ip}"
                      webbrowser.open(url)
              
              if __name__ == "__main__":
                  root = tk.Tk()
                  app = WebserverViewerApp(root)
                  root.mainloop()
              
              

              build_webscanner.bat

              @echo off
              echo.
              echo ===============================
              echo   Building webscanner.exe ...
              echo ===============================
              echo.
              
              
              
              pyinstaller webscanner.spec
              
              echo.
              echo Fertig! EXE liegt in /dist/webscanner.exe
              pause
              

              webscanner.spec

              # webscanner.spec
              block_cipher = None
              
              a = Analysis(
                  ['webscanner.py'],
                  pathex=[],
                  binaries=[],
                  datas=[],
                  hiddenimports=[],
                  hookspath=[],
                  hooksconfig={},
                  runtime_hooks=[],
                  excludes=[],
                  win_no_prefer_redirects=False,
                  win_private_assemblies=False,
                  cipher=block_cipher,
                  noarchive=False,
              )
              
              pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
              
              exe = EXE(
                  pyz,
                  a.scripts,
                  [],
                  exclude_binaries=True,
                  name='webscanner',
                  debug=False,
                  bootloader_ignore_signals=False,
                  strip=False,
                  upx=True,
                  console=False,  # GUI-Anwendung (kein Terminalfenster)
                  )
              
              coll = COLLECT(
                  exe,
                  a.binaries,
                  a.zipfiles,
                  a.datas,
                  strip=False,
                  upx=True,
                  name='webscanner',
              )
              

              Das Programm kann natürlich auch direkt im cmd-Fenster (Windows) durch python webscanner.py im entsprechenden Verzeichnis gestartet werden.

              Vor dem Start oder der Erstellung der EXE-Datei muß natürlich der IP-Bereich in webscanner.py angepasst werden.

              START_IP = "192.168.49.1"
              END_IP = "192.168.49.254"
              PORTS = [80]
              

              Wenn es läuft, sollte es etwa so aussehen:

              webscanner.jpg

              Viel Spaß damit

              OliverIOO Offline
              OliverIOO Offline
              OliverIO
              schrieb am zuletzt editiert von OliverIO
              #6

              @beowolf

              Danke für das Skript.
              Ich verwende dafür den static site generator pelican in Verbindung mit einem nginx Webserver.
              Für jedes Gerät was ich ansteuerbar haben möchte lege ich eine kleine Datei an mit tite, subtext und Kategorie an. Vorteil ist, da nicht jedes Gerät auf Port 80 eine Admin Oberfläche anbietet (Cups,portainer, iobroker ) das individuell zu bearbeiten
              Auf Basis eines templates wird dann meine link Webseite Life aktualisiert (pelican läuft als docker Container und überwacht ob sich in einem Verzeichnis was ändert und startet dann die Erzeugung neu.

              Den Webserver habe ich intern auf die Domain links gemapt. Meist reicht auch nur l oder li im Browser aus um die Seite aufzurufen

              IMG_0345.jpeg

              Meine Adapter und Widgets
              TVProgram, SqueezeboxRPC, OpenLiga, RSSFeed, MyTime,, pi-hole2, vis-json-template, skiinfo, vis-mapwidgets, vis-2-widgets-rssfeed
              Links im Profil

              1 Antwort Letzte Antwort
              0
              • Jey CeeJ Online
                Jey CeeJ Online
                Jey Cee
                Developer
                schrieb am zuletzt editiert von
                #7

                Ich verwende in der Regel Angry IP Scanner wenn ich ein eigenständiges Programm brauche.

                Persönlicher Support
                Spenden -> paypal.me/J3YC33

                1 Antwort Letzte Antwort
                0
                Antworten
                • In einem neuen Thema antworten
                Anmelden zum Antworten
                • Älteste zuerst
                • Neuste zuerst
                • Meiste Stimmen


                Support us

                ioBroker
                Community Adapters
                Donate

                706

                Online

                32.5k

                Benutzer

                81.6k

                Themen

                1.3m

                Beiträge
                Community
                Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
                ioBroker Community 2014-2025
                logo
                • Anmelden

                • Du hast noch kein Konto? Registrieren

                • Anmelden oder registrieren, um zu suchen
                • Erster Beitrag
                  Letzter Beitrag
                0
                • Home
                • Aktuell
                • Tags
                • Ungelesen 0
                • Kategorien
                • Unreplied
                • Beliebt
                • GitHub
                • Docu
                • Hilfe