Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Arduino
  • ESP32 & Co.
  • Raspberry Pi & Pico
  • Solo Mining
  • Über mich
  • Deutsch
  • English
Menu

Shelly 1PM + ESP32: Daten speichern & zeitgesteuert senden

Posted on 11. März 202513. März 2025 by Stefan Draeger

Der Shelly 1PM kann nicht nur Verbraucher schalten, sondern auch Verbrauchsdaten in der Cloud speichern und visualisieren. Allerdings ist dafür eine aktive WLAN-Verbindung erforderlich. Ein großer Vorteil des Shelly ist, dass lokale Szenen auch ohne Internetverbindung ausgeführt werden und das Gerät weiterhin über das lokale Netzwerk erreichbar bleibt. Doch sobald die Internetverbindung unterbrochen ist, entstehen Lücken in der Datenaufzeichnung – ein Problem, wenn man eine lückenlose Historie benötigt. In diesem Beitrag zeige ich eine einfache und kostengünstige Lösung, um Messdaten mit einem ESP32 zu puffern und sie zeitgesteuert an ThingSpeak zu senden.

Shelly 1PM + ESP32: Daten speichern & zeitgesteuert senden
Dieses Video auf YouTube ansehen.

Hinweis: Dieser Beitrag entstand aus einer Idee aus meiner YouTube-Community. Ich freue mich immer über Anregungen und Fragen von euch – so kann ich gezielt Lösungen für echte Probleme entwickeln. Wenn auch du ein technisches Problem hast oder eine Idee für einen Beitrag, dann schreib mir gerne eine Mail oder hinterlasse einen Kommentar!

Die hier präsentierte Schaltung und Umsetzung funktioniert mit allen Shelly-Geräten, die eine Leistungsmessung unterstützen. Allerdings kann der JSON-Response je nach Modell variieren, daher solltest du diesen überprüfen und gegebenenfalls an den entsprechenden Stellen anpassen.

Shelly 2PM Gen2 - Vorderseite
Shelly 2PM Gen2 – Vorderseite
Shelly 1PM Gen3
Shelly 1PM Gen3
Shelly 1PM Mini Gen3
Shelly 1PM Mini Gen3
Shelly Plug S
Shelly Plug S

Inhaltsverzeichnis

  • REST-Schnittstelle am Shelly
  • Ablegen der Daten auf dem Mikrocontroller
  • Aufbau der Schaltung mit einem Shelly 1PM Mini Gen3 und ESP32-C3 Mini
  • Speichern der Daten von einem Shelly 1PM auf dem ESP32-C3 Mini
    • Flashen des ESP32-C3 Mini für die Programmierung in MicroPython
    • Speichern von Daten in einer JSON-Datei auf dem Mikrocontroller ESP32-C3
      • JSON vs. Dictionary in Python
      • Speichern von Daten in der Datei data.json
    • Auslesen des JSON-Response vom Shelly 1PM oder Shelly Plug S
      • Aufbau einer WiFi-Verbindung am ESP32
      • Synchronisieren der RTC vom ESP32
      • Abrufen der Daten vom Shelly via Modul urequest
      • Sammeln der Daten im Intervall von 5 Minuten
      • Programm – Abrufen der Verbrauchsdaten eines Verbrauchers am Shelly und Speichern der Daten auf dem ESP32-C3
  • Visualisieren / Verarbeiten der gespeicherten Daten vom ESP32-C3 in ThingSpeak

REST-Schnittstelle am Shelly

Ein großer Vorteil der Shelly-Geräte ist die einfache REST-Schnittstelle, über die sie nicht nur geschaltet, sondern auch ausgelesen werden können.
Mit dem Aufruf http://<IP-Adresse>/rpc/Shelly.GetStatus lässt sich der aktuelle Status des Shelly als JSON abrufen. Das JSON-Format ist dabei sowohl für Menschen gut lesbar als auch leicht von einem Mikrocontroller zu verarbeiten. Zudem gibt es keine Begrenzung bei der Abrufhäufigkeit, sodass die Daten theoretisch sogar im Sekundentakt abgefragt werden können.

JSON-Response von einem Shelly Plug S Gen3
JSON-Response von einem Shelly Plug S Gen3

Aus dem JSON-Response wird der Block "switch:0" ausgewertet, da er die Leistungsdaten des angeschlossenen Verbrauchers enthält. Zusätzlich können wir den aktuellen Zeitstempel "unixtime" aus dem Block "sys" entnehmen und ebenfalls speichern.

Ablegen der Daten auf dem Mikrocontroller

Die gesammelten Daten werden auf dem Mikrocontroller in einer JSON-Datei gespeichert und bei bestehen einer Internetverbindung an ThingSpeak gesendet. Der ESP32-C3 verfügt über 4 MB Flash-Speicher, was ausreichend ist, um die Daten eines Tages zu speichern.

Da dieses Projekt auch in Umgebungen mit instabiler Internetverbindung eingesetzt werden kann, wird vor dem Senden zunächst geprüft, ob eine Verbindung besteht. Ist das der Fall, werden die Daten übertragen. Falls keine Verbindung verfügbar ist, wird das Senden zu einem späteren Zeitpunkt erneut versucht.

Aufbau der Schaltung mit einem Shelly 1PM Mini Gen3 und ESP32-C3 Mini

Für den Aufbau der kleinen Schaltung benötigst du:

  • einen Shelly 1PM Mini Gen3* oder Shelly Plug S*
  • einen ESP32-C3 Mini*
    • ein USB-C Datenkabel

Hinweis von mir: Die mit einem Sternchen (*) markierten Links sind Affiliate-Links. Wenn du über diese Links einkaufst, erhalte ich eine kleine Provision, die dazu beiträgt, diesen Blog zu unterstützen. Der Preis für dich bleibt dabei unverändert. Vielen Dank für deine Unterstützung!

Schaltung - Shelly 1PM Mini Gen3 mit ESP32
Schaltung – Shelly 1PM Mini Gen3 mit ESP32

Der Shelly Plug S bietet den großen Vorteil, dass keine spezielle Verkabelung erforderlich ist. Du kannst einfach einen Verbraucher direkt über die integrierte Schuko-Steckdose anschließen – ideal für Einsteiger, die schnell und unkompliziert loslegen möchten.

Speichern der Daten von einem Shelly 1PM auf dem ESP32-C3 Mini

Um die Daten des Shelly 1PM auf dem ESP32-C3 speichern zu können, muss zunächst eine Verbindung zum Gerät hergestellt und der JSON-Response über die bereits erwähnte REST-Schnittstelle abgerufen und ausgewertet werden. Die Umsetzung ist sowohl mit der Arduino IDE als auch mit MicroPython möglich. Da das Dateihandling in MicroPython deutlich einfacher und übersichtlicher ist, habe ich mich in diesem Projekt für diese Variante entschieden.

Flashen des ESP32-C3 Mini für die Programmierung in MicroPython

Bevor der kleine Mikrocontroller mit MicroPython programmiert werden kann, muss er zunächst mit der passenden Firmware geflasht werden. Das funktioniert entweder ganz bequem über Thonny, eine leicht bedienbare Entwicklungsumgebung, oder mithilfe des esptool von Espressif Systems über die Kommandozeile. Im folgenden Video zeige ich dir beide Varianten Schritt für Schritt.

Flashen des ESP32-C3 Super Mini für MicroPython
Dieses Video auf YouTube ansehen.

Speichern von Daten in einer JSON-Datei auf dem Mikrocontroller ESP32-C3

Der ESP32-C3 verfügt über 4 MB internen Flash-Speicher, der sich vielseitig nutzen lässt – etwa für das Speichern von Bildern, Textdateien oder kleinen Datensätzen. In diesem Projekt verwenden wir den Speicher, um eine JSON-Datei anzulegen und dort die erfassten Messdaten strukturiert abzulegen.

Im ersten Schritt erstellen wir die JSON-Datei auf dem Mikrocontroller und definieren eine Grundstruktur, die später fortlaufend mit neuen Werten ergänzt wird.

{
  "10.03.2025": {
    "1741590664": {
      "voltage": 230,
      "ampere": 12,
      "apower": 23,
      "current": 1
    },
    "1741590685": {
      "voltage": 225,
      "ampere": 11,
      "apower": 24,
      "current": 2
    }
  }
}

JSON vs. Dictionary in Python

MicroPython ist eine speziell für Mikrocontroller optimierte Variante der Programmiersprache Python. Viele bekannte Sprachmuster und Konzepte aus Python lassen sich daher direkt wiederverwenden – das macht die Programmierung besonders einfach und effizient.

Da JSON-Datenstrukturen in Python direkt als Dictionary dargestellt werden können, ist der Umgang mit empfangenen oder zu speichernden Daten besonders komfortabel. So lassen sich JSON-Dateien ganz leicht einlesen, bearbeiten und wieder abspeichern – ideal für den Einsatz auf dem ESP32-C3.

import json

# Datei einlesen und in ein Dictionary umwandeln
def read_json_file(filename):
    try:
        with open(filename, 'r') as file:
            data = json.load(file)
            return data
    except FileNotFoundError:
        print(f"Datei '{filename}' wurde nicht gefunden.")
    except json.JSONDecodeError:
        print(f"Fehler beim Einlesen der Datei '{filename}': Ungültiges JSON-Format.")
    return {}

# Dictionary schön ausgeben
def print_json_dict(data):
    for key, value in data.items():
        print(f"{key}: {value}")

# Hauptprogramm
filename = "data.json"
json_data = read_json_file(filename)
if json_data:
    print("Inhalt der Datei:")
    print_json_dict(json_data)

Dieser Code liest die Datei data.json, die sich auf dem Mikrocontroller befindet, ein und gibt deren Inhalt in der Shell von Thonny aus.

Speichern von Daten in der Datei data.json

Das Speichern der Daten ist ebenso unkompliziert wie das Einlesen: Wir befüllen einfach unser Dictionary mit den gewünschten Schlüssel-Wert-Paaren und schreiben es anschließend zurück in die Datei. So lassen sich Messwerte strukturiert und dauerhaft auf dem Mikrocontroller ablegen.

import ujson

# Beispiel-Daten (könnten z. B. von einem Sensor stammen)
data = {
    "10.03.2025": {
        "1741590664": {
            "voltage": 230,
            "ampere": 12,
            "apower": 23,
            "current": 1
        }
    }
}

# Datei öffnen und Dictionary als JSON speichern
def save_json_file(filename, content):
    try:
        with open(filename, 'w') as file:
            ujson.dump(content, file)
            print("Daten erfolgreich gespeichert.")
    except OSError:
        print("Fehler beim Schreiben der Datei.")

# Aufruf der Funktion
save_json_file("data.json", data)

Um einen neuen Datensatz dem Dictionary hinzuzufügen, prüfen wir zunächst, ob bereits ein Eintrag für das entsprechende Datum existiert. Falls ja, fügen wir lediglich den neuen Zeitstempel samt Messwerten zum bestehenden Datum hinzu. Existiert das Datum noch nicht, wird ein neuer Schlüssel mit dem Datum angelegt und der Datensatz dort eingefügt.

# Globales Dictionary (muss vorher definiert sein)
data = {}

def add_entry(date_str, timestamp_str, values_dict):
    """
    Fügt einen neuen Datensatz zum globalen Dictionary 'data' hinzu.

    :param date_str: Datum als String, z. B. "10.03.2025"
    :param timestamp_str: Zeitstempel als String, z. B. "1741590664"
    :param values_dict: Dictionary mit Messwerten
    """
    global data

    if date_str not in data:
        data[date_str] = {}

    data[date_str][timestamp_str] = values_dict

Nachdem die Daten ergänzt wurden, müssen sie nur noch in das Dictionary zurückgeschrieben werden. Damit ist der erste Schritt geschafft: das Speichern und Lesen von JSON-Daten auf dem ESP32-C3 Super Mini mit MicroPython.

fertiger Quellcode zum lesen & speichern von JSON Daten auf dem ESP32-C3
# -----------------------------------------------------------------------------
# Autor: Stefan Draeger
# Webseite: https://draeger-it.blog
# Beitrag: https://draeger-it.blog/shelly-1pm-esp32-daten-speichern-zeitgesteuert-senden/
# Beschreibung:
# Dieses Skript liest eine JSON-Datei vom ESP32-C3 ein, fügt neue Messdaten
# hinzu und speichert die aktualisierten Daten zurück in die Datei.
# -----------------------------------------------------------------------------

import ujson

# Globales Dictionary zur Speicherung der Messdaten
data = {}

# Liest die JSON-Datei ein und wandelt den Inhalt in ein Dictionary um
def read_json_file(filename):
    global data
    try:
        with open(filename, 'r') as file:
            data = ujson.load(file)
    except OSError:
        print(f"Datei '{filename}' wurde nicht gefunden.")
    except ValueError:
        print(f"Fehler beim Einlesen der Datei '{filename}': Ungültiges JSON-Format.")

# Fügt dem Dictionary einen neuen Eintrag mit Zeitstempel und Messwerten hinzu
def add_entry(date_str, timestamp_str, values_dict):
    """
    Fügt einen neuen Datensatz zum globalen Dictionary 'data' hinzu.

    :param date_str: Datum als String, z. B. "10.03.2025"
    :param timestamp_str: Zeitstempel als String, z. B. "1741590664"
    :param values_dict: Dictionary mit Messwerten
    """
    global data

    # Wenn das Datum noch nicht existiert, wird es angelegt
    if date_str not in data:
        data[date_str] = {}

    # Zeitstempel samt Werten hinzufügen oder überschreiben
    data[date_str][timestamp_str] = values_dict

# Speichert das Dictionary als JSON-Datei auf dem ESP32
def save_data_to_file():
    """
    Speichert das globale Dictionary 'data' in die Datei 'data.json'.
    """
    global data
    try:
        with open("data.json", "w") as file:
            ujson.dump(data, file)
            print("Daten erfolgreich gespeichert.")
    except OSError:
        print("Fehler beim Schreiben der Datei.")

# Gibt das Dictionary zeilenweise in der Shell aus
def print_json_dict():
    global data
    for key, value in data.items():
        print(f"{key}: {value}")

# ----------------------------------------------------------------------
# Hauptprogramm
# ----------------------------------------------------------------------

filename = "data.json"

# Vorhandene Datei einlesen
read_json_file(filename)

# Inhalt der Datei anzeigen
print("Inhalt der Datei:")
print_json_dict()

# Neuen Messwert hinzufügen
add_entry("10.03.2025", "1741590722", {
    "voltage": 228,
    "ampere": 9,
    "apower": 21,
    "current": 3
})

# Datei mit neuem Eintrag speichern
save_data_to_file()

# Datei erneut laden und aktualisierte Daten anzeigen
read_json_file(filename)
print("Aktualisierter Inhalt der Datei:")
print_json_dict()

Auslesen des JSON-Response vom Shelly 1PM oder Shelly Plug S

Aufbau einer WiFi-Verbindung am ESP32

Bevor wir die REST-Schnittstelle des Shellys ansprechen können, müssen wir eine Verbindung zum lokalen WLAN aufbauen. Dieses ist mit wenigen Zeilen Code gelöst.

Quellcode zum aufbauen einer WiFi-Verbindung am ESP32
# -----------------------------------------------------------------------------
# Autor: Stefan Draeger
# Webseite: https://draeger-it.blog
# Beitrag: https://draeger-it.blog/shelly-1pm-esp32-daten-speichern-zeitgesteuert-senden/
#
# Beschreibung:
# Dieses Skript stellt mit dem ESP32-C3 Super Mini eine Verbindung zum lokalen
# WLAN her und nutzt eine Status-LED an GPIO 2 als einfache Rückmeldung.
#
# - Während der Verbindungssuche blinkt die LED.
# - Nach erfolgreicher Verbindung leuchtet die LED dauerhaft.
# - Bei fehlgeschlagener Verbindung bleibt die LED aus.
# -----------------------------------------------------------------------------

import network
import time
from machine import Pin

# WLAN-Zugangsdaten
SSID = "abc"
PASSWORD = "123"

# Status-LED an GPIO 2 (z. B. für den ESP32-C3 Super Mini)
led = Pin(2, Pin.OUT)

# Funktion zum Aufbau der WLAN-Verbindung
def connect_wifi(ssid, password):
    # WLAN-Modul im Station Mode aktivieren
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)

    # Verbindung starten, falls noch nicht verbunden
    if not wlan.isconnected():
        print("Verbinde mit WLAN...")
        wlan.connect(ssid, password)

        # LED blinkt während der Verbindungssuche
        timeout = 10  # Sekunden
        while not wlan.isconnected() and timeout > 0:
            led.value(1 - led.value())  # LED-Zustand wechseln (manuelles Blinken)
            time.sleep(0.5)
            timeout -= 0.5
            print(".", end="")

    # Verbindung erfolgreich
    if wlan.isconnected():
        print("\nWLAN verbunden.")
        print("IP-Adresse:", wlan.ifconfig()[0])
        led.value(1)  # LED dauerhaft an
        return True
    else:
        # Verbindung fehlgeschlagen
        print("\nVerbindung fehlgeschlagen.")
        led.value(0)  # LED bleibt aus
        return False

# WLAN-Verbindung aufbauen
connect_wifi(SSID, PASSWORD)

Wenn die WiFi-Verbindung aufgebaut wurde, dann wird auf der Shell die zugewiesene IP-Adresse ausgegeben sowie wird eine LED zum leuchten gebracht.

Ausgabe der IP-Adresse des ESP32-C3 auf der Shelly von Thonny
Ausgabe der IP-Adresse des ESP32-C3 auf der Shelly von Thonny

Synchronisieren der RTC vom ESP32

Damit wir später einen gültigen Zeitstempel als Schlüssel für unsere Datenspeicherung verwenden können, müssen wir zunächst die RTC (Echtzeituhr) des ESP32 synchronisieren. Sobald die WLAN-Verbindung steht, lässt sich das über einen NTP-Server ganz einfach erledigen.

Quellcode zum synchronisieren der RTC am ESP32-C3
# -----------------------------------------------------------------------------
# Autor: Stefan Draeger
# Webseite: https://draeger-it.blog
# Beitrag: https://draeger-it.blog/shelly-1pm-esp32-daten-speichern-zeitgesteuert-senden/
#
# Beschreibung:
# Dieses Skript verbindet den ESP32-C3 mit einem WLAN, synchronisiert die
# interne Echtzeituhr (RTC) über einen NTP-Server und gibt das aktuelle Datum 
# formatiert aus. 
#
# - Während der Verbindungssuche blinkt die LED.
# - Nach erfolgreicher Verbindung leuchtet die LED dauerhaft.
# - Das Datum wird im Format TT.MM.JJJJ ausgegeben.
# -----------------------------------------------------------------------------

import time
import network
import ntptime
from machine import Pin

# WLAN-Zugangsdaten
SSID = "abc"
PASSWORD = "123"

# Status-LED an GPIO 2 (z. B. für den ESP32-C3 Super Mini)
led = Pin(2, Pin.OUT)

# Funktion zum Aufbau der WLAN-Verbindung
def connect_wifi(ssid, password):
    """
    Baut eine Verbindung zum WLAN auf und gibt den Status zurück.
    Während der Verbindungssuche blinkt die LED, nach erfolgreicher Verbindung
    leuchtet sie dauerhaft.
    
    :param ssid: Name des WLAN-Netzwerks
    :param password: WLAN-Passwort
    :return: True, wenn erfolgreich verbunden, sonst False
    """
    wlan = network.WLAN(network.STA_IF)  # WLAN-Modul im Station Mode
    wlan.active(True)  # WLAN aktivieren

    if not wlan.isconnected():
        print("Verbinde mit WLAN...")
        wlan.connect(ssid, password)

        # LED blinkt während der Verbindungssuche
        timeout = 10  # Maximale Wartezeit in Sekunden
        while not wlan.isconnected() and timeout > 0:
            led.value(1 - led.value())  # LED-Zustand wechseln (manuelles Blinken)
            time.sleep(0.5)
            timeout -= 0.5
            print(".", end="")

    if wlan.isconnected():
        print("\nWLAN verbunden.")
        print("IP-Adresse:", wlan.ifconfig()[0])
        led.value(1)  # LED dauerhaft an = erfolgreich verbunden
        return True
    else:
        print("\nVerbindung fehlgeschlagen.")
        led.value(0)  # LED bleibt aus
        return False

# Funktion zur Umwandlung des Unix-Timestamps in ein formatiertes Datum
def formatDate():
    """
    Wandelt den aktuellen Unix-Zeitstempel in ein lesbares Datum um.

    :return: String im Format "TT.MM.JJJJ"
    """
    timestamp = time.localtime()  # Aktuelle Zeit abrufen
    return "{tag:02d}.{monat:02d}.{jahr:4d}".format(tag=timestamp[2], monat=timestamp[1], jahr=timestamp[0])

# WLAN-Verbindung herstellen
isWiFiConnected = connect_wifi(SSID, PASSWORD)

# Falls WLAN verbunden, Zeit vom NTP-Server holen
if isWiFiConnected:
    try:
        ntptime.settime()  # Zeit vom NTP-Server synchronisieren
        print("Zeit erfolgreich synchronisiert.")
        print("Aktuelles Datum:", formatDate())
    except:
        print("Fehler bei der Zeitsynchronisation.")
else:
    print("Keine WLAN-Verbindung – NTP-Sync nicht möglich.")

Der Code stellt zunächst eine WLAN-Verbindung her und synchronisiert anschließend die interne RTC des ESP32 über einen NTP-Server. Sobald die Synchronisation abgeschlossen ist, wird der aktuelle Zeitstempel im Format eines Tupels (time.localtime()) ausgelesen. Daraus wird das Datum im deutschen Format „Tag.Monat.Jahr“ generiert. Dieses Datum verwenden wir später als Schlüssel (Key) zur strukturierten Ablage der Messwerte in der JSON-Datei.

Abrufen der Daten vom Shelly via Modul urequest

Die Daten vom Shelly wird via GET Request abgerufen. Dazu benötigen wir die IP-Adresse des Shellys welchge wir aus den Geräteinformationen ablesen können.

Dieser IP-Adresse wird der Pfad „/rpc/Shelly.GetStatus“ angehangen und mit der Adresse können nun alle Daten abgerufen werden.

Quellcode zum Abrufen der Daten vom Shelly
# -----------------------------------------------------------------------------
# Autor: Stefan Draeger
# Webseite: https://draeger-it.blog
# Beitrag: https://draeger-it.blog/shelly-1pm-esp32-daten-speichern-zeitgesteuert-senden/
#
# Beschreibung:
# Dieses Skript verbindet den ESP32-C3 mit einem WLAN-Netzwerk, ruft aktuelle
# Leistungsdaten eines Shelly-Geräts über die REST-API (rpc/Shelly.GetStatus)
# ab und extrahiert daraus die benötigten Messwerte.
#
# - WLAN-Verbindung mit Statusanzeige über LED (GPIO 2)
# - Abruf des Shelly-Status über HTTP (lokale IP)
# - Extraktion von Spannung, Leistung, Strom und Unix-Zeitstempel
# -----------------------------------------------------------------------------

import network
import time
from machine import Pin
import urequests

# WLAN-Zugangsdaten (bitte anpassen!)
SSID = "abc"
PASSWORD = "123"

# Shelly-REST-Endpunkt für Statusdaten
SHELLY_URL = "http://192.168.178.91/rpc/Shelly.GetStatus"

# Status-LED an GPIO 2 (zeigt WLAN-Status an)
led = Pin(2, Pin.OUT)

# Verbindet den ESP32 mit dem WLAN und zeigt den Status über die LED an
def connect_wifi(ssid, password):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)

    if not wlan.isconnected():
        print("Verbinde mit WLAN...")
        wlan.connect(ssid, password)

        # LED blinkt während der Verbindungssuche
        timeout = 10  # Sekunden
        while not wlan.isconnected() and timeout > 0:
            led.value(1 - led.value())  # LED-Zustand wechseln
            time.sleep(0.5)
            timeout -= 0.5
            print(".", end="")

    if wlan.isconnected():
        print("\nWLAN verbunden.")
        print("IP-Adresse:", wlan.ifconfig()[0])
        led.value(1)  # LED dauerhaft an
        return True
    else:
        print("\nVerbindung fehlgeschlagen.")
        led.value(0)  # LED aus
        return False

# Ruft die JSON-Daten vom Shelly-Device ab
def fetch_shelly_data():
    try:
        response = urequests.get(SHELLY_URL)
        if response.status_code == 200:
            json_data = response.json()  # JSON zu Python-Dictionary umwandeln
            response.close()
            return json_data
        else:
            print("Fehler beim Abrufen der Daten:", response.status_code)
            response.close()
            return None
    except Exception as e:
        print("Verbindungsfehler:", e)
        return None

# Extrahiert relevante Werte aus der Shelly-Antwort
def extract_shelly_values(data):
    try:
        voltage = data["switch:0"]["voltage"]
        apower = data["switch:0"]["apower"]
        current = data["switch:0"]["current"]
        unixtime = data["sys"]["unixtime"]

        # Rückgabe als kompaktes Dictionary
        return {
            "voltage": voltage,
            "apower": apower,
            "current": current,
            "unixtime": unixtime
        }
    except KeyError as e:
        print("Fehlender Wert im JSON:", e)
        return None

# Gibt das aktuelle Datum im Format TT.MM.JJJJ zurück
def formatDate():
    timestamp = time.localtime()
    return "{:02d}.{:02d}.{:04d}".format(timestamp[2], timestamp[1], timestamp[0])

# Hauptablauf
isWiFiConnected = connect_wifi(SSID, PASSWORD)
if isWiFiConnected:
    shelly_data = fetch_shelly_data()
    if shelly_data:
        print("Empfangene Daten:")
        print(shelly_data)

        values = extract_shelly_values(shelly_data)
        if values:
            print("Extrahierte Werte:")
            print(values)

In der Shell von Thonny kann man die Daten vom Shelly ablesen und ebenso die extrahierten Daten welche wir später auf dem Mikrocontroller speichern möchten.

extrahierte Verbrauchsdaten des Shellys auf der Shell von Thonny
extrahierte Verbrauchsdaten des Shellys auf der Shell von Thonny

Sammeln der Daten im Intervall von 5 Minuten

Die Daten sollen nun alle 5 Minuten automatisch abgerufen und gespeichert werden. Dazu starten wir den Hauptteil des Programms in einer Endlosschleife und legen anschließend eine Pause von 300 Sekunden (entspricht 5 Minuten) ein. Theoretisch lassen sich auf diese Weise bis zu 288 Datensätze pro Tag erfassen und auf dem ESP32-C3 speichern.

# 5 Minuten in Sekunden
INTERVAL = 300

# Hauptablauf
isWiFiConnected = connect_wifi(SSID, PASSWORD)

while True:
    if isWiFiConnected:
        if sync_rtc():
            shelly_data = fetch_shelly_data()
            if shelly_data:
                print("Empfangene Daten:")
                print(shelly_data)
                values = extract_shelly_values(shelly_data)
                if values:
                    print("Extrahierte Werte:")
                    print(values)
                    datum = formatDate()
                    print("Verwendbares Datum als Key:", datum)
                    filename = "data.json"
                    read_json_file(filename)
                    print("Inhalt der Datei:")
                    print_json_dict()
                    add_entry(datum, values['unixtime'], values)
                    save_data_to_file()
                    read_json_file(filename)
                    print_json_dict()

    print("Warte 5 Minuten bis zum nächsten Abruf...")
    time.sleep(INTERVAL)

Programm – Abrufen der Verbrauchsdaten eines Verbrauchers am Shelly und Speichern der Daten auf dem ESP32-C3

Dieses Programm verbindet den ESP32-C3 mit dem WLAN, ruft aktuelle Leistungsdaten vom Shelly über die REST-API ab und extrahiert die wichtigsten Werte wie Spannung, Leistung und Stromstärke. Du musst lediglich die WLAN-Zugangsdaten sowie die IP-Adresse deines Shelly-Geräts im Code anpassen – danach ist das Skript sofort einsatzbereit.

fertiges Programm zum abrufen der Leistungsdaten eines Verbrauchers am Shelly und speichern dieser auf dem ESP32-C3 als JSON
import network
import time
from machine import Pin
import urequests
import ntptime
import ujson

# Globales Dictionary für alle gesammelten Messdaten
data = {}

# WLAN-Zugangsdaten (bitte anpassen)
SSID = "abc"
PASSWORD = "123"

# Shelly-Endpunkt für den Abruf der aktuellen Leistungsdaten
SHELLY_URL = "http://192.168.178.91/rpc/Shelly.GetStatus"

# Abfrageintervall in Sekunden (5 Minuten)
INTERVAL = 300

# LED an GPIO 2 zur Anzeige der WLAN-Verbindung
led = Pin(2, Pin.OUT)

# Verbindet den ESP32 mit dem WLAN und zeigt den Status über die LED an
def connect_wifi(ssid, password):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)

    if not wlan.isconnected():
        print("Verbinde mit WLAN...")
        wlan.connect(ssid, password)

        # LED blinkt während der Verbindungssuche
        timeout = 10
        while not wlan.isconnected() and timeout > 0:
            led.value(1 - led.value())
            time.sleep(0.5)
            timeout -= 0.5
            print(".", end="")

    if wlan.isconnected():
        print("\nWLAN verbunden.")
        print("IP-Adresse:", wlan.ifconfig()[0])
        led.value(1)  # LED dauerhaft an bei Verbindung
        return True
    else:
        print("\nVerbindung fehlgeschlagen.")
        led.value(0)
        return False

# Synchronisiert die interne Uhr über einen NTP-Zeitserver
def sync_rtc():
    try:
        ntptime.settime()
        print("RTC erfolgreich synchronisiert.")
        return True
    except:
        print("Fehler bei der RTC-Synchronisation.")
        return False

# Wandelt Unix-Zeitstempel in ein Datumsformat TT.MM.JJJJ
def timestamp_to_date(timestamp):
    try:
        t = time.localtime(timestamp)
        return "{:02d}.{:02d}.{:04d}".format(t[2], t[1], t[0])
    except:
        return "00.00.0000"

# Ruft die aktuellen Daten vom Shelly-Gerät ab
def fetch_shelly_data():
    try:
        response = urequests.get(SHELLY_URL)
        if response.status_code == 200:
            json_data = response.json()
            response.close()
            return json_data
        else:
            print("Fehler beim Abrufen der Daten:", response.status_code)
            response.close()
            return None
    except Exception as e:
        print("Verbindungsfehler:", e)
        return None

# Extrahiert relevante Messwerte aus dem Shelly-JSON
def extract_shelly_values(data):
    try:
        voltage = data["switch:0"]["voltage"]
        apower = data["switch:0"]["apower"]
        current = data["switch:0"]["current"]
        unixtime = data["sys"]["unixtime"]

        return {
            "voltage": voltage,
            "apower": apower,
            "current": current,
            "unixtime": unixtime
        }
    except KeyError as e:
        print("Fehlender Wert im JSON:", e)
        return None

# Gibt das aktuelle Datum aus der RTC im Format TT.MM.JJJJ zurück
def formatDate():
    timestamp = time.localtime()
    return "{:02d}.{:02d}.{:04d}".format(timestamp[2], timestamp[1], timestamp[0])

# Liest die bestehende Datei 'data.json' in das globale Dictionary
def read_json_file(filename):
    global data
    try:
        with open(filename, 'r') as file:
            data = ujson.load(file)
    except OSError:
        print(f"Datei '{filename}' wurde nicht gefunden.")
    except ValueError:
        print(f"Fehler beim Einlesen der Datei '{filename}': Ungültiges JSON-Format.")

# Fügt einen neuen Eintrag zum globalen Dictionary hinzu
def add_entry(date_str, timestamp_str, values_dict):
    """
    Fügt die Messwerte unter dem jeweiligen Datum und Zeitstempel ins Dictionary ein.
    Der Timestamp wird dabei als Key verwendet, die Messwerte als Value.
    """
    global data

    if date_str not in data:
        data[date_str] = {}

    # Entferne 'unixtime' aus den Werten, da er bereits als Key verwendet wird
    values_dict.pop('unixtime')

    data[date_str][timestamp_str] = values_dict

# Speichert das globale Dictionary in die Datei 'data.json'
def save_data_to_file():
    global data
    try:
        with open("data.json", "w") as file:
            ujson.dump(data, file)
            print("Daten erfolgreich gespeichert.")
    except OSError:
        print("Fehler beim Schreiben der Datei.")

# Gibt das komplette Dictionary formatiert in der Konsole aus
def print_json_dict():
    global data
    for key, value in data.items():
        print(f"{key}: {value}")

# -----------------------------------------
# Hauptprogramm
# -----------------------------------------

# WLAN einmalig beim Start verbinden
isWiFiConnected = connect_wifi(SSID, PASSWORD)

# Hauptschleife: Alle 5 Minuten Daten abfragen und speichern
while True:
    if isWiFiConnected:
        if sync_rtc():
            shelly_data = fetch_shelly_data()
            if shelly_data:
                print("Empfangene Daten:")
                print(shelly_data)

                values = extract_shelly_values(shelly_data)
                if values:
                    print("Extrahierte Werte:")
                    print(values)

                    # Aktuelles Datum als Schlüssel
                    datum = formatDate()
                    print("Verwendbares Datum als Key:", datum)

                    filename = "data.json"
                    read_json_file(filename)
                    print("Inhalt der Datei:")
                    print_json_dict()

                    # Daten hinzufügen und speichern
                    add_entry(datum, str(values['unixtime']), values)
                    save_data_to_file()

                    # Inhalt erneut ausgeben
                    read_json_file(filename)
                    print("Aktualisierter Inhalt:")
                    print_json_dict()

    print("Warte 5 Minuten bis zum nächsten Abruf...")
    time.sleep(INTERVAL)

Visualisieren / Verarbeiten der gespeicherten Daten vom ESP32-C3 in ThingSpeak

Die Daten wurden nun erfolgreich auf dem ESP32-C3 gespeichert – doch lokal auf dem Mikrocontroller sind sie weder besonders lesbar noch einfach auswertbar. Daher möchte ich die erfassten Werte nun in ThingSpeak visualisieren.

Wie man Daten an ThingSpeak sendet, habe ich bereits in mehreren Beiträgen auf diesem Blog gezeigt, zum Beispiel:

  • IoT-Service ThingSpeak einrichten und betreiben
  • ThingSpeak & ESP Easy
  • MAKER Pi Pico #1 – Senden von Sensordaten an ThingSpeak
  • Calliope Mini & ThingSpeak

In diesem Abschnitt zeige ich dir, wie du die Messdaten deines Shelly-Geräts auslesen und anschließend – sofern eine Internetverbindung besteht – an ThingSpeak senden kannst. Sollte keine Verbindung verfügbar sein, werden die Daten zunächst lokal auf dem Mikrocontroller gespeichert und beim nächsten erfolgreichen Durchlauf automatisch übertragen.

Dank des internen Flash-Speichers von 4 MB beim ESP32-C3 Super Mini lassen sich auf diese Weise problemlos mehrere Tage an Daten puffern – ideal für Projekte mit unzuverlässiger Internetverbindung.

Damit die Daten bei der Übertragung zu ThingSpeak auch dem korrekten Zeitpunkt zugeordnet werden können, fügen wir der URL den zusätzlichen Parameter created_at hinzu. So können wir auch nachträglich Daten mit dem tatsächlichen Zeitstempel hochladen – perfekt für eine lückenlose Historie.

Die URL zum Übertragen eines Datensatzes in meinem Fall sieht folgendermaßen aus:

https://api.thingspeak.com/update.json?
api_key=<WRITE_KEY>&
field1=<VOLTAGE>&
field2=<AMPERE>&
field3=<CURRENT>&
created_at=<TIMESTAMP>

Den Parameter created_at können wir entweder im ISO 8601 Format (z. B. 2025-03-10T10:30:00Z) oder als Unix-Timestamp übergeben. Beide Varianten sind von ThingSpeak akzeptiert und ermöglichen eine rückwirkende Zuordnung der Messdaten.

Quellcode
# -----------------------------------------------------------------------------
# Autor: Stefan Draeger
# Webseite: https://draeger-it.blog
# Beitrag: https://draeger-it.blog/shelly-1pm-esp32-daten-speichern-zeitgesteuert-senden/
#
# Beschreibung:
# Dieses MicroPython-Skript für den ESP32-C3 liest alle 5 Minuten Leistungsdaten 
# eines Shelly-Geräts per REST-Schnittstelle aus und speichert diese lokal in 
# einer JSON-Datei. Falls eine Internetverbindung besteht, werden die Daten an 
# ThingSpeak gesendet und anschließend vom Mikrocontroller gelöscht. 
# Zusätzlich wird ein Logfile "debug.log" mit Zeitstempeln geführt.
# -----------------------------------------------------------------------------

import network
import time
from machine import Pin
import urequests
import ntptime
import ujson

# Globales Dictionary zur Datenspeicherung
data = {}

# WLAN-Zugangsdaten (bitte anpassen)
SSID = "abc"
PASSWORD = "123"

# REST-Endpunkt des Shelly-Geräts
SHELLY_URL = "http://192.168.178.91/rpc/Shelly.GetStatus"

# Messintervall in Sekunden (5 Minuten)
INTERVAL = 300

# LED an GPIO 2 dient als Statusanzeige (verbunden/nicht verbunden)
led = Pin(2, Pin.OUT)

# -----------------------------------------------------------------------------
# Funktion: debugLog
# Schreibt Zeitstempel + Meldung + Schweregrad in die Datei "debug.log"
# -----------------------------------------------------------------------------
def debugLog(text, level="INFO"):
    try:
        now = time.localtime()
        datum = "{:02d}.{:02d}.{:04d}".format(now[2], now[1], now[0])
        uhrzeit = "{:02d}:{:02d}:{:02d}".format(now[3], now[4], now[5])
        log_line = f"[{datum} {uhrzeit}] [{level.upper()}] {text}\n"
        with open("debug.log", "a") as log_file:
            log_file.write(log_line)
    except Exception as e:
        print("⚠️ Fehler beim Schreiben ins Log:", e)

# -----------------------------------------------------------------------------
# Funktion: connect_wifi
# Baut eine WLAN-Verbindung auf und blinkt dabei die LED als Statusanzeige.
# -----------------------------------------------------------------------------
def connect_wifi(ssid, password):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)

    if not wlan.isconnected():
        print("Verbinde mit WLAN...")
        wlan.connect(ssid, password)

        timeout = 10  # Sekunden
        while not wlan.isconnected() and timeout > 0:
            led.value(1 - led.value())  # LED blinkt
            time.sleep(0.5)
            timeout -= 0.5
            print(".", end="")

    if wlan.isconnected():
        led.value(1)
        debugLog("WLAN verbunden")
        debugLog("IP-Adresse: " + wlan.ifconfig()[0])
        return True
    else:
        debugLog("Verbindung fehlgeschlagen.", "ERROR")
        led.value(0)
        return False

# -----------------------------------------------------------------------------
# Funktion: sync_rtc
# Synchronisiert die interne Uhr des ESP32 mit einem NTP-Server.
# -----------------------------------------------------------------------------
def sync_rtc():
    try:
        ntptime.settime()
        debugLog("RTC erfolgreich synchronisiert.")
        return True
    except:
        debugLog("Fehler bei der RTC-Synchronisation.", "ERROR")
        return False

# -----------------------------------------------------------------------------
# Hilfsfunktion: Wandelt Unix-Timestamp in Datum (z. B. für JSON-Key)
# -----------------------------------------------------------------------------
def timestamp_to_date(timestamp):
    try:
        t = time.localtime(timestamp)
        return "{:02d}.{:02d}.{:04d}".format(t[2], t[1], t[0])
    except:
        return "00.00.0000"

# -----------------------------------------------------------------------------
# Funktion: fetch_shelly_data
# Holt aktuellen JSON-Status vom Shelly über die REST-Schnittstelle.
# -----------------------------------------------------------------------------
def fetch_shelly_data():
    try:
        response = urequests.get(SHELLY_URL)
        if response.status_code == 200:
            json_data = response.json()
            response.close()
            return json_data
        else:
            debugLog("Fehler beim Abrufen der Daten: " + str(response.status_code), "ERROR")
            response.close()
            return None
    except Exception as e:
        debugLog(f"Verbindungsfehler: {e}", "ERROR")
        return None

# -----------------------------------------------------------------------------
# Funktion: extract_shelly_values
# Extrahiert relevante Felder aus dem JSON-Response.
# -----------------------------------------------------------------------------
def extract_shelly_values(data):
    try:
        return {
            "voltage": data["switch:0"]["voltage"],
            "apower": data["switch:0"]["apower"],
            "current": data["switch:0"]["current"],
            "unixtime": data["sys"]["unixtime"]
        }
    except KeyError as e:
        debugLog(f"Fehlender Wert im JSON: {e}", "ERROR")
        return None

# Gibt das aktuelle Datum im Format TT.MM.JJJJ zurück (für JSON-Struktur)
def formatDate():
    timestamp = time.localtime()
    return "{:02d}.{:02d}.{:04d}".format(timestamp[2], timestamp[1], timestamp[0])

# -----------------------------------------------------------------------------
# Funktion: read_json_file
# Liest bestehende JSON-Datei auf dem Flash-Speicher in das globale Dictionary.
# -----------------------------------------------------------------------------
def read_json_file(filename):
    global data
    try:
        with open(filename, 'r') as file:
            data = ujson.load(file)
    except OSError:
        debugLog(f"Datei '{filename}' wurde nicht gefunden.", "ERROR")
    except ValueError:
        debugLog(f"Fehler beim Einlesen der Datei '{filename}': Ungültiges JSON-Format.", "ERROR")

# -----------------------------------------------------------------------------
# Funktion: add_entry
# Fügt einen Datensatz mit Timestamp in das Dictionary ein (Key = Datum)
# -----------------------------------------------------------------------------
def add_entry(date_str, timestamp_str, values_dict):
    global data
    if date_str not in data:
        data[date_str] = {}
    values_dict.pop('unixtime')
    data[date_str][timestamp_str] = values_dict

# -----------------------------------------------------------------------------
# Funktion: save_data_to_file
# Speichert das aktualisierte Dictionary in die Datei 'data.json'
# -----------------------------------------------------------------------------
def save_data_to_file():
    global data
    try:
        with open("data.json", "w") as file:
            ujson.dump(data, file)
            debugLog("Daten erfolgreich gespeichert.")
    except OSError:
        debugLog("Fehler beim Schreiben der Datei.", "ERROR")

# -----------------------------------------------------------------------------
# Funktion: internet_available
# Prüft, ob der ESP32 eine Verbindung zum Internet (nicht nur WLAN) hat.
# -----------------------------------------------------------------------------
def internet_available():
    try:
        response = urequests.get("http://www.google.com")
        if response.status_code == 200:
            response.close()
            debugLog("Internetverbindung verfügbar.")
            return True
        else:
            debugLog("Internetverbindung fehlgeschlagen. Status: " + str(response.status_code), "ERROR")
            response.close()
            return False
    except Exception as e:
        debugLog(f"Kein Internetzugriff: {e}", "ERROR")
        return False

# -----------------------------------------------------------------------------
# Funktion: send_data_to_thingspeak
# Überträgt die Daten an ThingSpeak und entfernt erfolgreich gesendete Einträge.
# -----------------------------------------------------------------------------
def send_data_to_thingspeak():
    global data

    THINGSPEAK_API_KEY = "9ZMMDML77HTWPMRR"
    THINGSPEAK_URL = "https://api.thingspeak.com/update.json"

    daten_zu_entfernen = []

    for datum in list(data.keys()):
        eintraege = data[datum]
        gesendete_timestamps = []

        for timestamp, werte in eintraege.items():
            try:
                payload = {
                    "api_key": THINGSPEAK_API_KEY,
                    "field1": werte.get("voltage"),
                    "field2": werte.get("apower"),
                    "field3": werte.get("current"),
                    "created_at": int(timestamp)
                }
                response = urequests.post(THINGSPEAK_URL, json=payload)
                if response.status_code == 200:
                    debugLog(f"Datensatz {timestamp} gesendet.")
                    gesendete_timestamps.append(timestamp)
                else:
                    debugLog(f"Fehler beim Senden von {timestamp}: Status {response.status_code}", "ERROR")
                response.close()
            except Exception as e:
                debugLog(f"Fehler beim Senden von {timestamp}: {e}", "ERROR")

        for ts in gesendete_timestamps:
            del data[datum][ts]

        if not data[datum]:
            daten_zu_entfernen.append(datum)

    for d in daten_zu_entfernen:
        del data[d]

    save_data_to_file()
    print("Alle gesendeten Daten wurden aus der Datei entfernt.")

# -----------------------------------------------------------------------------
# Hauptprogramm: 5-Minuten-Loop zum Messen, Speichern & ggf. Senden
# -----------------------------------------------------------------------------
isWiFiConnected = connect_wifi(SSID, PASSWORD)

while True:
    if isWiFiConnected:
        if sync_rtc():
            shelly_data = fetch_shelly_data()
            if shelly_data:
                values = extract_shelly_values(shelly_data)
                if values:
                    datum = formatDate()
                    read_json_file("data.json")
                    add_entry(datum, str(values['unixtime']), values)
                    save_data_to_file()

                # Wenn Internet vorhanden → versuche Upload
                if internet_available():
                    send_data_to_thingspeak()

    print("Warte 5 Minuten bis zum nächsten Abruf...")
    time.sleep(INTERVAL)

Zusätzlich leite ich alle Ausgaben welche auf der Shell ausgegeben werden in eine Datei schreiben, somit kann man zu einem späteren Zeitpunkt nachvollziehen warum ggf. keine Daten gesendet oder gespeichert werden konnten.

[10.03.2025 16:04:38] [INFO] WLAN verbunden
[10.03.2025 16:04:38] [INFO] IP-Adresse: 192.168.178.32
[10.03.2025 15:04:38] [INFO] RTC erfolgreich synchronisiert.
[10.03.2025 15:04:38] [INFO] Daten erfolgreich gespeichert.
[10.03.2025 15:04:39] [INFO] Internetverbindung verfügbar.
[10.03.2025 15:04:40] [INFO] Datensatz 1741619079 gesendet.
[10.03.2025 15:04:40] [INFO] Daten erfolgreich gespeichert.

3 thoughts on “Shelly 1PM + ESP32: Daten speichern & zeitgesteuert senden”

  1. Matthias sagt:
    15. März 2025 um 14:43 Uhr

    Hallo Stefan,
    tolle Sache, den Vorteil darin sehe ich zu „Shelly Cloud“, das die Werte „lokal“ zwischengespeichert werden, und gehen somit nicht verloren, wenn keine Internetverbindung besteht. (Sh plus1PM,Gen2, usw.. haben keinen Zwischenspeicher ?).
    Wäre es als alternative auch machbar, anstelle Daten senden an ThingSpeak, die Daten als CSV.Datei am Desktop zu hinterlegen. ( Es gibt von dir einBlog, Daten in Excel importieren)
    Na, ja, mal schaun, ich wag mich mal dran.
    – ich verwende den „tasmotizer-1.2.exe“ zum flashen von ESP8266. Könnte dieser anstelle Tonny verwendet werden?
    Gruß Matthias

    Antworten
    1. Stefan Draeger sagt:
      16. März 2025 um 10:08 Uhr

      Hi,
      die Idee der Erweitung zum export der Daten als CSV Datei klingt gut. Und ist recht einfach machbar als kleine Schnittstelle auf dem ESP32.

      Gruß, Stefan

      Antworten
  2. Pingback: ESP32 Daten als CSV exportieren: Einfacher Zugriff über den Webbrowser - Technik Blog

Schreibe einen Kommentar Antworten abbrechen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen

Tel.: 01778501273
E-Mail: info@draeger-it.blog

Folge mir auf

  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2025 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Verwalten von {vendor_count}-Lieferanten Lese mehr über diese Zwecke
Einstellungen anzeigen
{title} {title} {title}