Post

CZE | Shelly Plug S | Monitorování spotřeby

CZE | Shelly Plug S | Monitorování spotřeby

Úvod

Shelly plug S je “chytrá zásuvka”, která umožňuje spotřebič zapínat a vypínat přes WiFi, měřit spotřebu a nebo přes webové rozhraní nastavit, kdy se má spotřebič zapnout a vypnout na základě časového rozvrhu. Článek je návodem jak nastavit a měření spotřeby v Linuxu, ale není důvod, aby to nefungovalo na Windows.

Zásuvka existuje v různých verzích (bez S je větší a zvládne vyšší proud, Plus je novější model s BlueTooth)

Zástrčka je univerzální, zásuvka je německá bez kolíku. Většinou to nevadí a někdy je nutné spotřebič připojit přes prodlužovačku s univerzální zástrčkou (v mém případě kotel).

Užitečné odkazy

Foto

Photo 1 Photo 2 Photo 3 Photo 4

Nastavení zásuvky

Při prvním zapnutí vytvoří zásuvka Access point. Stačí se připojit a ponastavovat pár věcí.

Chceme zásuvku zapnout po výpadku napájení, připojit do domácí wifi a nemusí nějak komunikovat s cloudem:

  • Settings -> Power on default mode -> [X] ON
  • Internet&Security -> Connect the Shelly to an existing wifi: SSID+password
  • Internet&Security -> Cloud: disable

Pokud zásuvce nedovolíme přístup na internet, nejspíš jí musíme poskytnout čas.

  • Settings -> Timezone and geolocation
  • Internet&Security -> SNTP

Nalezení zásuvky

Když zásuvku připojíme do domácí sítě, je nutné najít její IP adresu.

Můžeme se podívat na router a najít něco jako “Connected devices” a tam shellyplug

Na openSUSE se dá použít netdiscover:

1
2
3
4
5
6
7
8
9
10
11
# zypper in netdiscover
# netdiscover

 Currently scanning: 192.168.25.0/16   |   Screen View: Unique Hosts

 2 Captured ARP Req/Rep packets, from 2 hosts.   Total size: 120
 _____________________________________________________________________________
   IP            At MAC Address     Count     Len  MAC Vendor / Hostname
 -----------------------------------------------------------------------------
 192.168.0.1     38:43:7d:ee:63:f8      1      60  Compal Broadband Networks, Inc.
 192.168.0.73    08:3a:8d:c1:66:1d      1      60  Espressif Inc. 

Na Fedoře netdiscover není, nmap poslouží také, ale člověk musí tušit, co ve výstupu nesedí:

1
2
3
4
5
6
7
$ sudo dnf in nmap
$ nmap -sn 192.168.0.0/24
Starting Nmap 7.93 ( https://nmap.org ) at 2023-06-03 21:28 CEST
Nmap scan report for _gateway (192.168.0.1)
Host is up (0.0067s latency).
Nmap scan report for 192.168.0.73
Host is up (0.028s latency).

Další možnost je si netdiscover stáhnout a zkompilovat, vyžaduje to jen sudo dnf in libpcap-devel a hodit třeba do adresáře /root/bin.

Čtení spotřeby

1
curl 192.168.0.73/meter/0
1
{"power":9.54,"overpower":0.00,"is_valid":true,"timestamp":1681455421,"counters":[9.858, 9.865, 9.885],"total":586}`
klíčhodnota
poweraktuální spotřeba ve wattech
owerpower 
is_valid 
timestampčas v sekundách od 1.1.1970
countersčítače, spotřeba poslední tři minuty
totalcelková spotřeba ve watt-minutách (60 J, 1/60 Wh, 1/60000 kWh)

Logování spotřeby

K logování spotřeby poslouží jednoduché skripty, zde je kód v shellu a Pythonu. Pozor na cestu k logu.

1
2
3
4
5
6
7
8
9
10
#!/bin/sh

logfile="/home/pavel/shelly.log"
url="http://192.168.0.73/meter/0"

while true; do
  curl -s "$url" >> "$logfile"
  echo "" >> "$logfile" # Add a newline after each entry
  sleep 10
done
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python3

import requests
import time

logfile = "/home/pavel/shelly.log"
url = "http://192.168.0.73/meter/0"

while True:
    response = requests.get(url)
    with open(logfile, 'a') as f:
        f.write(response.text)
        f.write('\n')  # Add a newline after each entry
    time.sleep(10)

V Linuxu je nejlepší skript spustit na pozadí tak, aby běžel i po odhlášení uživatele příkazem:

1
nohup ~/bin/shelly_log.sh >/dev/null 2>&1 &

Přesměrování výstupu je volitelné, bez něj se vytvoří souboru nohup.out s výstupem skriptu.

Konverze logu na CSV

Jednoduše a rychle (tuším, že se to nevyrovná s prázdnými řádky, když vypadne komunikace)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python3
import json
import csv
from datetime import datetime

log_filename = "shelly.log"
csv_filename = "shelly_output.csv"

with open(log_filename, "r") as log_file, open(csv_filename, "w") as csv_file:
    csv_writer = csv.writer(csv_file)
    csv_writer.writerow(["timestamp", "power"])

    for line in log_file:
        data = json.loads(line)
        power = data["power"]
        timestamp = data["timestamp"]
        timestamp_iso8601 = datetime.utcfromtimestamp(timestamp).isoformat()
        csv_writer.writerow([timestamp_iso8601, power])

Složitěji a pomalu (a s konkrétní verzí Pythonu)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/python3.11
import re
import pandas as pd
from datetime import datetime

log_filename = "shelly.log"
csv_filename = "shelly_output_pandas.csv"

pattern = r'\{"power":([0-9.]+),"overpower":[0-9.]+,"is_valid":(?:true|false),"timestamp":(\d+),.*\}'
regex = re.compile(pattern)

timestamps = []
power_values = []

with open(log_filename, "r") as log_file:
    for line in log_file:
        match = regex.match(line)
        if match:
            power = float(match.group(1))
            timestamp = int(match.group(2))
            timestamp_iso8601 = datetime.utcfromtimestamp(timestamp).isoformat()
            timestamps.append(timestamp_iso8601)
            power_values.append(power)

df = pd.DataFrame({"timestamp": timestamps, "power": power_values})
df.to_csv(csv_filename, index=False)

Výsledkem konverze z JSONu:

1
2
3
{"power":9.74,"overpower":0.00,"is_valid":true,"timestamp":1681455620,"counters":[9.846, 9.819, 9.823],"total":615}
{"power":199.94,"overpower":0.00,"is_valid":true,"timestamp":1681455631,"counters":[9.846, 9.819, 9.823],"total":615}
{"power":187.00,"overpower":0.00,"is_valid":true,"timestamp":1681455641,"counters":[9.846, 9.819, 9.823],"total":615}

na CSV je

1
2
3
2023-04-14T07:00:20,9.74
2023-04-14T07:00:31,199.94
2023-04-14T07:00:41,187.0

Graf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/gnuplot

set datafile separator ","
set xdata time
set timefmt "%Y-%m-%dT%H:%M:%S"
set format x "%Y-%m-%d\n%H:%M:%S"

set title "Power Consumption"
set xlabel "Time"
set ylabel "Power (W)"
set yrange [0:40]
set xrange ["2023-06-01T18:00:00":"2023-06-03T18:00:00"]

set grid
set terminal pngcairo size 800,450 enhanced font "JetBrains Mono,10" transparent
set output "shelly_power_plot.png"

plot "shelly_output.csv" using 1:2 with lines title "Power"

Power consumption graph Power consumption graph

Závěr, recenze

Se zásuvkou jsem spokojen, byť na měření spotřeby stačí jednodušší přístroje s jednodušším použitím. Jen z nich nelze vyčíst spotřebu v průběhu dne nebo snadno měřit spotřebu počítače při různém typu zatížení.

This post is licensed under CC BY 4.0 by the author.