Hallo zusammen,
ich möchte hier ein Smart-Home-Projekt mit euch teilen, das ich entwickelt habe, um mein GPU-Mining umweltfreundlicher und kosteneffizienter zu betreiben.
Ziel war es, den PV-Überschuss meiner Solaranlage sinnvoll zu nutzen: Wenn mein Haus Strom ins Netz einspeist, wird automatisch geprüft, ob genug Leistung vorhanden ist – und nur dann werden meine GPUs aktiviert. Die Steuerung erfolgt über Home Assistant in Kombination mit HASS.Agent auf dem Mining-Rig.
GitHub-Projekt:
https://github.com/Sedowan/power-aware-miner-homeassistant
Projektkomponenten
HASS.Agent
-
commands.json
→ Startet oder stoppt per MQTT Kommandos ein Mining-Skript auf dem Windows-Rig. -
sensors.json
→ Meldet Systemparameter wie GPU-Auslastung oder Temperaturen zurück.
GMiner
- Beispiel-Batch-Skript
mine_ravencoin_0.batzum Starten von Ravencoin-Mining.
Home Assistant
-
automations.yaml
→ Reagiert auf Messwerte (z. B. Netzeinspeisung) und schaltet GPUs abhängig vom Überschuss. -
mining_template.yaml
Technische Voraussetzungen
-
PV-Anlage mit Leistungsmessung (z. B. Shelly 3EM, SMA, openWB, etc.)
-
Home Assistant + MQTT-Broker (z. B. Mosquitto)
-
Windows-Mining-PC mit HASS.Agent
-
GMiner (oder ein anderer Miner)
Funktionsweise (PV-gesteuert)
-
Home Assistant erkennt Überschuss (z. B. > 500W Netzeinspeisung).
-
Home Assistant wertet dies aus – bei ausreichendem Überschuss (kaskadiert) wird ein MQTT-Befehl an das Mining-Rig gesendet.
-
HASS.Agent führt daraufhin ein Batch-Skript aus, das den Miner startet.
-
Sobald der Überschuss sinkt oder ins Minus geht, wird der Miner automatisch kaskadiert gestoppt.
Vorteile dieser Lösung
-
Nutzung von überschüssigem Solarstrom -
Kein unnötiger Netzbezug für GPU-Mining -
Volle Automatisierung & Überwachung -
Modular & erweiterbar auf weitere Verbraucher oder Geräte.
Technische Umsetzung im Detail
1.
Dynamische GPU-Steuerung per Template (mining_template.yaml)
- sensor:
- name: "possible_gpus"
state: >
{% set grid_p = states('sensor.[YOUR_GRID_SENSOR]') | float(0) %}
{% set pv_p = states('sensor.[YOUR_SOLAR_POWER]') | float(0) %}
{% set soc_v = states('sensor.[YOUR_STATE_OF_CHARGE]') | float(0) %}
{% set active_g = states('sensor.active_gpus') | int(0) %}
{% set est_p_gpu = [YOUR_ESTIMATED_POWER_DRAW_PERGPU] %}
{% set lower_soc = [YOUR_LOWER_SOC_LIMIT] %}
...
{% if grid_p_wo_gpu > [YOUR_SURPLUS_THRESHOLD] and soc_v > lower_soc %}
{% set gpus = (grid_p_wo_gpu / est_p_gpu) | round(0) %}
{% else %}
{% set gpus = 0 %}
{% endif %}
{{ gpus }}
Ein zweiter Sensor zählt die aktiv laufenden GPUs:
- sensor:
- name: "active_gpus"
state: >
{% set gpus = [
states('binary_sensor.mining_rig_1_gminer_gpu0_active'),
states('binary_sensor.mining_rig_1_gminer_gpu1_active'),
...
] %}
{{ gpus | select('eq', 'on') | list | count }}
2.
Automatisierung (automations.yaml)
Startet eine GPU, wenn possible_gpus > active_gpus:
- conditions:
- condition: state
entity_id: binary_sensor.mining_rig_1_gminer_gpu0_active
state: "off"
- condition: numeric_state
entity_id: sensor.active_gpus
below: sensor.possible_gpus
sequence:
- action: button.press
metadata: {}
data: {}
target:
entity_id: button.mining_rig_1_mining_rig_1_start_gpu0
- delay:
hours: 0
minutes: 0
seconds: 15
milliseconds: 0
- conditions:
- condition: state
entity_id: binary_sensor.mining_rig_1_gminer_gpu1_active
state: "off"
- condition: numeric_state
entity_id: sensor.active_gpus
below: sensor.possible_gpus
sequence:
- action: button.press
metadata: {}
data: {}
target:
entity_id: button.mining_rig_1_mining_rig_1_start_gpu1
- delay:
hours: 0
minutes: 0
seconds: 15
milliseconds: 0
Stopp-Aktionen erfolgen analog, sobald weniger GPUs erlaubt sind.
- conditions:
- condition: state
entity_id: binary_sensor.mining_rig_1_gminer_gpu5_active
state: "on"
- condition: numeric_state
entity_id: sensor.possible_gpus
below: 6
sequence:
- action: button.press
metadata: {}
data: {}
target:
entity_id: button.mining_rig_1_mining_rig_1_stopgpu5
- conditions:
- condition: state
entity_id: binary_sensor.mining_rig_1_gminer_gpu4_active
state: "on"
- condition: numeric_state
entity_id: sensor.possible_gpus
below: 5
sequence:
- action: button.press
metadata: {}
data: {}
target:
entity_id: button.mining_rig_1_mining_rig_1_stopgpu4
3.
GPU-Startskript (mine_ravencoin_0.bat)
title GMiner_GPU0
cd C:\Mining\GMiner
miner.exe --algo kawpow --server rvn.2miners.com:6060 --user [YOUR_WALLET].[WORKER] --devices 0
pause
Weitere GPUs haben identische Skripte mit --devices 1, 2, 3, …
4.
HASS.Agent Befehle (commands.json)
Starten:
{
"Name": "Mining-Rig-1-Start-GPU0",
"Command": "C:\\Mining\\GMiner\\mine_ravencoin_0.bat"
}
Stoppen:
{
"Name": "Mining-Rig-1-StopGPU5",
"Command": "taskkill /f /fi \"WindowTitle eq GMiner_GPU5\" /t"
}
5.
Sensorstatus über HASS.Agent (sensors.json)
{
"Type": "NamedWindowSensor",
"WindowName": "GMiner_GPU0",
"EntityName": "GMiner_GPU0_active"
}
Diese Information geht an Home Assistant zurück und wird im Template genutzt.
GitHub
Projekt: https://github.com/Sedowan/power-aware-miner-homeassistant
Ich hoffe, dass es jemanden hilft um auf ähnliche Weise seinen Computer per Home Assistant zu steuern.
Grüße!