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
- Using the Shelly Plug to monitor Starlink’s power consumption - Jeff Geerling
- Shelly Plug S API reference
Foto
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 |
---|---|
power | aktuá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 |
total | celková 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"
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í.