Ether schürfen mit FHEM
Vorweg
Wer nichts von Cryptowährungen hält oder nicht weiß was das ist oder was das hier soll, der kann direkt aufhören weiter zu lesen. Ich möchte auf jeden Fall hier keine Grundsatzdebatte über Cryptowährungen oder das Crypto-Mining hier haben, dafür gibt es gewiss andere geeignetere Plattformen. Weiterhin solltet ihr euch schon mit FHEM auskennen, da ich nicht auf Basissachen wie „was ist ein Dummy“ oder „wie kann ich ein Reading erzeugen“ etc. eingehen kann. Auch sollten die wichtigsten Begriffe rund um das Ethereum Mining bekannt sein. Ich mine im Pool von ethermine.org, es sollte aber genauso für die Pools von ethpool.org, etc.ethermine.org, zcash.flypool.org gehen, da sie die selbe API verwenden.
Hier beschreibe ich wie ich mein bescheidenen Mining Rig mit dem ich Ethereum schürfe überwache was den Strombedarf angeht und wie ich anhand des aktuellen Ether Marktpreises errechnen ob ein rechnerischer Gewinn dabei rausspringt oder es besser ist eine andere Währung zu schürfen oder das Ganze ganz einzustellen. Die Umsetzung erfolgte in FHEM.
Die Namen der einzelnen Devices in FHEM die ich verwendet habe können natürlich verändert werden, jedoch ist zu beachten, dass diese hier auch in Perl Skripten weiterverwendet werden und ihr dann eure Skripte entsprechend anpassen müsst falls ihr andere Namen nehmt.
Stromverbrauch messen
Da ein Mining Rig ordentlich Strom zieht ist und das die Kosten des Minens sind muss man relativ genau wissen wie viel Strom das Teil so frisst. Da ich hier eine Homematic Infrastruktur habe, habe ich ein Homematic Zwischenstecker (HM-ES-PMSw1-Pl) genommen der sämtliche Stromparameter misst und in regelmäßigen Abständen an den FHEM Server sendet. Vom in FHEM eingebundenen HM-ES-PMSw1-Pl habe ich channel_02 verwendet der in FHEM ein eigenes Device darstellt und Strom.GPU_Miner genannt. Dessen Reading power zeigt den aktuellen Stromverbrauch in Watt. Wenn ihr andere devices verwendet um euren Strombedarf in FHEM zu überwachen dann müsst ihr den Namen des Readings im EtherCalculator (weiter unten) anpassen und darauf achten dass wiklich Watt gemessen werden bzw. zu Watt umrechnen.
Wir brauchen jetzt ein dummy namens MyKwhPreis in dem ihr den Kilowattstunden-Preis eures Stromversorgers mit set MyKwhPreis Preis in Euro eintragt, also 0.29 für 29 Cent. Hier das define:
defmod MyKwhPreis dummy attr MyKwhPreis icon icoBlitz attr MyKwhPreis room Mining attr MyKwhPreis stateFormat state EUR
Pooldaten unseres Miners
Um die Daten wie z.B. die Hashrate unseres Miners im Pool abzurufen könnt ihr das ganz einfach die entsprechende API des Pools verwenden. Das geht in FHEM ganz einfach mit dem HTTPMOD. Ich zeige das hier für den Ethermine Pool:
defmod MyEtherpoolStats HTTPMOD https://api.ethermine.org/miner/:3Exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/currentStats 300 attr MyEtherpoolStats enableCookies 0 attr MyEtherpoolStats event-on-change-reading .* attr MyEtherpoolStats extractAllJSON 1 attr MyEtherpoolStats icon it_internet@SkyBlue attr MyEtherpoolStats room Mining attr MyEtherpoolStats stateFormat Aktuell: cur_MHs MH/s <br> Durchschnitt: avg_MHs MH/s attr MyEtherpoolStats userReadings avg_MHs:data_averageHashrate.* { nearest('0.01' , ReadingsVal("MyEtherpoolStats","data_averageHashrate",0) / 1000000) }, cur_MHs:data_currentHashrate.* { nearest('0.01' , ReadingsVal("MyEtherpoolStats","data_currentHashrate",0) / 1000000) },
Für 3Exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx müsst ihr eure Ether Wallet Adresse eintragen. Das ist die Adresse, die ihr in eurer Mining Software angegeben habt, an die euer Mining Gewinn gesendet wird und praktisch die Id eures Miners ist. Es reicht alle 5 Minuten (300 Sekunden) neue Werte anzufordern, da erstens sich da nicht so schnell große Veränderungen ergeben und zweitens die Anzahl der Anfragen pro Zeit über die Ethermine API limitiert ist und ihr bei zu vielen Anfragen gesperrt werden könnt.
Wenn alles funktioniert hat, dann seht ihr bald folgende Readings natürlich mit euren Werten:
Ether Preis
Um die Profitabilität unseres Miners zu errechnen müssen wir wissen wie der Ether gehandelt wird. Diese Daten entnehme ich der bekannten Seite Coinmarketcap über deren API. Dazu verwende ich ebenfalls den HTTPMOD in FHEM. Das define sieht so aus:
defmod EtherPreis HTTPMOD https://api.coinmarketcap.com/v1/ticker/ethereum/?convert=EUR 300 attr EtherPreis enableCookies 0 attr EtherPreis event-on-change-reading .* attr EtherPreis extractAllJSON 1 attr EtherPreis icon it_internet@SkyBlue attr EtherPreis room Mining attr EtherPreis stateFormat preis_EUR EUR <br> preis_USD USD attr EtherPreis userReadings preis_EUR:01_price_eur.* { nearest('0.01' , ReadingsVal("EtherPreis","01_price_eur",0)) }, preis_USD:01_price_usd.* { nearest('0.01' , ReadingsVal("EtherPreis","01_price_usd",0)) },
Auch hier reicht es nur alle 5 Minuten neue Werte abzurufen.
Die Readings sollten so ähnlich aussehen:
Profitabilität berechnen
Zunächst brauchen wir einen dummy namens EtherMiningGewinn in dem wir später den Gewinn/Verlust visualisieren können:
defmod EtherMiningGewinn dummy attr EtherMiningGewinn icon euro@SkyBlue attr EtherMiningGewinn room Mining
Jetzt erstellen wir den Rechner der uns berechnet wie profitabel unsere Mining Rig arbeitet. Das machen wir mit einem notify der bei Veränderungen des Stromverbrauchs, der Hashrate oder des Ether Preises uns den aktuellen Gewinn oder Verlust mit einem Perl Skript errechnet und die Ergebnisse als Reading im notify anzeigt bzw. im dummy EtherMiningGewinn.
Hier das entsprechende define:
defmod EtherCalculator notify Strom.GPU_Miner:power.*|EtherPreis:01_price_eur.*|MyEtherpoolStats:data_coinsPerMin.*|MyKwhPreis:state.* { ### Ether Preis EUR ### my $etherpreis = ReadingsVal("EtherPreis","01_price_eur",0); my $etherpreis_x = nearest('0.01' , $etherpreis); fhem("setreading EtherCalculator 01_EtherPreis_EUR $etherpreis_x");; ### Bitcoin Preis EUR ### my $bitcoinpreis = ReadingsVal("BitcoinPreis","01_price_eur",0); my $bitcoinpreis_x = nearest('0.01' , $bitcoinpreis); fhem("setreading EtherCalculator 07_BitcoinPreis_EUR $bitcoinpreis_x");; ### Stromkosten Berechnung ### my $strompreis = ReadingsVal("MyKwhPreis","state",0); fhem("setreading EtherCalculator 02_Strom_Kwh_Preis_EUR $strompreis");; my $stromverbrauch_x = ReadingsVal("Strom.GPU_Miner","power",0); my $stromverbrauch = $stromverbrauch_x / 1000; fhem("setreading EtherCalculator 03_Stromverbrauch_aktuell_W $stromverbrauch_x");; fhem("setreading EtherCalculator 04_Stromverbrauch_aktuell_Kwh $stromverbrauch");; my $kosten_h = $stromverbrauch * $strompreis; my $kosten_d = $kosten_h * 24; my $kosten_w = $kosten_d * 7; my $kosten_m = $kosten_d * 30; my $kosten_y = $kosten_d * 365; fhem("setreading EtherCalculator 11_StromKosten_Stunde_EUR $kosten_h");; fhem("setreading EtherCalculator 12_StromKosten_Tag_EUR $kosten_d");; fhem("setreading EtherCalculator 13_StromKosten_Woche_EUR $kosten_w");; fhem("setreading EtherCalculator 14_StromKosten_Monat_EUR $kosten_m");; fhem("setreading EtherCalculator 15_StromKosten_Jahr_EUR $kosten_y");; ### Mining Berechnung ### my $coins_h = ReadingsVal("MyEtherpoolStats","data_coinsPerMin",0) * 60; my $coins_d = $coins_h * 24; my $coins_w = $coins_d * 7; my $coins_m = $coins_d * 30; my $coins_y = $coins_d * 365; fhem("setreading EtherCalculator 21_Coins_Stunde $coins_h");; fhem("setreading EtherCalculator 22_Coins_Tag $coins_d");; fhem("setreading EtherCalculator 23_Coins_Woche $coins_w");; fhem("setreading EtherCalculator 24_Coins_Monat $coins_m");; fhem("setreading EtherCalculator 25_Coins_Jahr $coins_y");; ### Umsatz Berechnung ### my $umsatz_h = $coins_h * $etherpreis; my $umsatz_d = $umsatz_h * 24; my $umsatz_w = $umsatz_d * 7; my $umsatz_m = $umsatz_d * 30; my $umsatz_y = $umsatz_d * 365; fhem("setreading EtherCalculator 31_Umsatz_Stunde_EUR $umsatz_h");; fhem("setreading EtherCalculator 32_Umsatz_Tag_EUR $umsatz_d");; fhem("setreading EtherCalculator 33_Umsatz_Woche_EUR $umsatz_w");; fhem("setreading EtherCalculator 34_Umsatz_Monat_EUR $umsatz_m");; fhem("setreading EtherCalculator 35_Umsatz_Jahr_EUR $umsatz_y");; ### Gewinn Berechnung ### my $gewinn_h = $umsatz_h - $kosten_h; my $gewinn_d = nearest('0.01' , $gewinn_h * 24); my $gewinn_w = nearest('0.01' , $gewinn_d * 7); my $gewinn_m = nearest('0.01' , $gewinn_d * 30); my $gewinn_y = nearest('0.01' , $gewinn_d * 365); fhem("setreading EtherCalculator 41_Gewinn_Stunde_EUR $gewinn_h");; fhem("setreading EtherCalculator 42_Gewinn_Tag_EUR $gewinn_d");; fhem("setreading EtherCalculator 43_Gewinn_Woche_EUR $gewinn_w");; fhem("setreading EtherCalculator 44_Gewinn_Monat_EUR $gewinn_m");; fhem("setreading EtherCalculator 45_Gewinn_Jahr_EUR $gewinn_y");; ### Gewinne in ein Dummy zur schnelleren Übersicht ### my $gewinn_x = "Gewinn Tag: $gewinn_d € <br> Gewinn Woche: $gewinn_w € <br> Gewinn Monat: $gewinn_m € <br> Gewinn Jahr: $gewinn_y €"; fhem("set EtherMiningGewinn $gewinn_x");; } attr EtherCalculator icon access_keypad_2@SkyBlue attr EtherCalculator room Mining
Die entsprechenden Readings sehen so aus:
Das dummy EtherMiningGewinn sieht dann so aus:
WICHTIG: Wenn ihr hier negative Werte angezeigt bekommt dann solltet ihr euren Miner upgraden oder das Mining sofort einstellen denn dann gebt ihr mehr für Strom aus als mit dem Mining wieder reinkommt!
Das wäre es im Prinzip, aber jetzt kommt noch ein wenig mehr um eure Werte in einem Filelog zu speichern und in Grafen zu visualisieren. Weiterhin habe ich noch über die entsprechenden APIs die Ether mining dificulty sowie den Bitcoin Preis abgefragt und als Grafen dargestellt.
Zusätzliche Daten
Das define zur Abfrage der network dificulty sieht so aus:
defmod EtherNetworkStats HTTPMOD https://api.ethermine.org/networkStats 1800 attr EtherNetworkStats enableCookies 0 attr EtherNetworkStats event-on-change-reading .* attr EtherNetworkStats extractAllJSON 1 attr EtherNetworkStats icon it_internet@SkyBlue attr EtherNetworkStats room Mining attr EtherNetworkStats stateFormat difficulty attr EtherNetworkStats userReadings difficulty:data_difficulty.* { nearest('0.1' , ReadingsVal("EtherNetworkStats","data_difficulty",0) / 1000000000000) },
und die entsprechenden Readings so:
Den Bitcoin Preis bekommen wir mit folgendem HTTPMOD:
defmod BitcoinPreis HTTPMOD https://api.coinmarketcap.com/v1/ticker/bitcoin/?convert=EUR 300 attr BitcoinPreis enableCookies 0 attr BitcoinPreis event-on-change-reading .* attr BitcoinPreis extractAllJSON 1 attr BitcoinPreis icon it_internet@SkyBlue attr BitcoinPreis room Mining attr BitcoinPreis stateFormat preis_EUR EUR <br> preis_USD USD attr BitcoinPreis userReadings preis_EUR:01_price_eur.* { nearest('0.01' , ReadingsVal("BitcoinPreis","01_price_eur",0)) }, preis_USD:01_price_usd.* { nearest('0.01' , ReadingsVal("BitcoinPreis","01_price_usd",0)) },
und erhalten folgende Readings:
Werte speichern und visualisieren
Um die angerufenen und errechneten Werte aus den verschiedenen FHEM devices in einem Filelog zu speichern und die Datenmenge möglichst gering zu halten habe ich das Ganze mit einem Perl Skript gemacht welches in einem at einmal pro Stunde ausgeführt wird. Zunächst aber müssen wir ein dummy namens EtherFilelogHelper erstellen in dem die zusammengetragenen Werte abgelegt werden:
defmod EtherFilelogHelper dummy attr EtherFilelogHelper event-on-update-reading .* attr EtherFilelogHelper room Mining attr EtherFilelogHelper stateFormat avg_MHs / EtherPreis_EUR / Stromverbrauch_aktuell_W / Gewinn_Jahr_EUR
Und nun das entsprechende at EtherFilelogPrepare :
defmod EtherFilelogPrepare at +*01:00 { ### Stromkosten Berechnung ### my $r = ReadingsVal("EtherCalculator","01_EtherPreis_EUR",0); fhem("setreading EtherFilelogHelper EtherPreis_EUR $r");; $r = ReadingsVal("EtherCalculator","07_BitcoinPreis_EUR",0); fhem("setreading EtherFilelogHelper BitcoinPreis_EUR $r");; $r = ReadingsVal("EtherCalculator","45_Gewinn_Jahr_EUR",0); fhem("setreading EtherFilelogHelper Gewinn_Jahr_EUR $r");; $r = ReadingsVal("EtherCalculator","03_Stromverbrauch_aktuell_W",0); fhem("setreading EtherFilelogHelper Stromverbrauch_aktuell_W $r");; $r = ReadingsVal("MyEtherpoolStats","avg_MHs",0); fhem("setreading EtherFilelogHelper avg_MHs $r");; $r = ReadingsVal("EtherNetworkStats","difficulty",0); fhem("setreading EtherFilelogHelper difficulty $r");; } attr EtherFilelogPrepare alignTime 00:30 attr EtherFilelogPrepare icon clock@SkyBlue attr EtherFilelogPrepare room Mining
Nach der ersten Ausführung von EtherFilelogPrepare sollten im EtherFilelogHelper folgende Readings zu finden sein:
Jetzt kann man einfach ein Filelog erstellen, welches ansprigt, wenn im dummy EtherFilelogHelper neue Werte vom at EtherFilelogPrepare geschrieden werden. Hier das entsprechende define:
defmod EtherFilelog FileLog ./log/ethermining-%Y.log EtherFilelogHelper:.* attr EtherFilelog room Mining
Jetzt könnt ihr euch mit Create SVG plot in EtherFilelog die entsprechenden Grafen erstellen. Meine Grafen sehen so aus:
Zum Schluss
Wie ich feststellen konnte ist der Mining Gewinn pro Jahr am abhängigsten vom Ether Preis. Wenn eure Mining Hardware stabil durchläuft, dann gibt es nur geringe Schwankungen im Stromverbrauch oder der Hashrate. Auch die Änderungen in der Network dificulty scheinen keinen großen Einfluss zu haben.
Spenden
Wenn Dir der Beitrag hier gefallen oder geholfen hat und Du mir etwas zukommen lassen willst, dann erfährst du hier wie: http://tips-und-mehr.de/spenden/
Ein sehr informativer und umfangreicher Artikel. Hier muss man sich schon mit dem Thema auskennen, um durchzublicken. In jedem Fall gut geschrieben.
Ja, deswegen hatte ich im Vorwort geschrieben, dass Vorwissen notwendig ist. Aber falls Fragen rund ums Mining oder Cryptos bestehen, kann ich gerne versuchen darauf einzugehen.