{"id":1227,"date":"2013-11-29T01:39:30","date_gmt":"2013-11-28T23:39:30","guid":{"rendered":"http:\/\/blog.ulrichard.ch\/?p=1227"},"modified":"2013-11-29T01:39:30","modified_gmt":"2013-11-28T23:39:30","slug":"pimp-my-miner","status":"publish","type":"post","link":"https:\/\/ulrichard.ch\/blog\/?p=1227","title":{"rendered":"Pimp my miner"},"content":{"rendered":"<p>For a while now, I thought about mounting a simple display somewhere that shows the most important parameters of my BitCoin miner. First I started with an AtMega equipped with an <a href=\"http:\/\/www.geeetech.com\/wiki\/index.php\/Arduino_ENC28J60_Ethernet_Module\">Ethernet module<\/a>. But parsing json without any library support became too cumbersome quickly. So I copy pasted together a small python script, and used a <a href=\"https:\/\/github.com\/ulrichard\/rfidtime\/tree\/master\/nokia_display_i2c\" target=\"_blank\" rel=\"noopener\">nokia display that I already equipped with an i2c interface<\/a>. If I knew how easy it is, to use those json interfaces, I would have implemented this display project earlier. The code is at the bottom. It is specific to my setup with p2pool and CHF, but it is so easy to change that you can adapt it to whatever your setting is. The python script now runs on an <a href=\"http:\/\/pcengines.ch\/alix.htm\" target=\"_blank\" rel=\"noopener\">Alix<\/a> on the same i2c bus as <a href=\"http:\/\/blog.ulrichard.ch\/?p=831\" target=\"_blank\" rel=\"noopener\">my simple home automation transmitter<\/a>. Now all that is left to do, is adding a line to \/etc\/crontab to execute the script once a minute.<\/p>\n<p>As you can see on the image below, the hash rate is too hight for a stock <a href=\"https:\/\/www.kncminer.com\/categories\/miners\" target=\"_blank\" rel=\"noopener\">Saturn<\/a>. That is because I recently added an extension module. So it has now three instead of two hashing modules. All of a sudden, KncMiner announced they had 200 extension modules for the October batch, and that future modules would be incompatible. So, that was pretty much the only chance for an upgrade. My existing power supply should have room for one more module, and they were moderately priced. The demand was high enough that they were <a href=\"https:\/\/www.kncminer.com\/news\/news-65\" target=\"_blank\" rel=\"noopener\">sold out in three minutes<\/a>. The <a href=\"http:\/\/www.steg-electronics.ch\/de\/article\/arctic-cooling-freezer-i30-602733.aspx\" target=\"_blank\" rel=\"noopener\">i30 cooler<\/a> that was recommended was not available at the time, so I had to use an <a href=\"http:\/\/www.steg-electronics.ch\/de\/article\/arctic-cooling-freezer-xtreme-rev2-780412.aspx\" target=\"_blank\" rel=\"noopener\">Xtreme rev2<\/a>. I had a fun time finding out how to correctly mount it. Even for the original, there was no manual or description how to mount it. Just look at the existing modules said someone in the forum.<br \/>\n<a href=\"https:\/\/ulrichard.ch\/piwigo\/picture.php?\/1284\/category\/20\"><img decoding=\"async\" src=\"https:\/\/ulrichard.ch\/piwigo\/_data\/i\/upload\/2014\/09\/15\/20140915162024-c62753b0-th.jpg\" alt=\"\" \/><\/a><\/p>\n<p><!--more--><\/p>\n<pre class=\"brush: python; gutter: false; first-line: 1\">#! \/usr\/bin\/python\n# Show the current hashrate of my bitcoin miner on a nokia display\n\nimport httplib2\nimport json\nimport time\nfrom nokia_display import NokiaDisplay\n\nclass p2pool:\n\tdef __init__(self, url, payout_addr):\n\t\tself.baseurl = url\n\t\tself.payout_addr = payout_addr\n\n\tdef poolHashrate(self): # in GH\/s\n\t\th = httplib2.Http(\".cache\")\n\t\th.debuglevel = 2\n\t\turl = \"%s\/rate\" % (self.baseurl)\n\t\tresp, content = h.request(url, \"GET\")\n\t\tghash = float(content) \/ 1024.0 \/ 1024.0 \/ 1024.0\n\t\treturn ghash\n\n\tdef localHashrate(self):\n\t\th = httplib2.Http(\".cache\")\n\t\th.debuglevel = 2\n\t\turl = \"%s\/local_stats\" % (self.baseurl)\n\t\tresp, content = h.request(url, \"GET\")\n\t\tjj = json.loads(content)\n\t\tghash = float(jj['miner_hash_rates'][self.payout_addr]) \/ 1024.0 \/ 1024.0 \/ 1024.0\n\t\treturn ghash\n\n\tdef shares(self):\n\t\th = httplib2.Http(\".cache\")\n\t\th.debuglevel = 2\n\t\turl = \"%s\/local_stats\" % (self.baseurl)\n\t\tresp, content = h.request(url, \"GET\")\n\t\tjj = json.loads(content)\n\t\tshares = int(jj['shares']['total'])\n\t\treturn shares\n\n\tdef current_payout(self):\n\t\th = httplib2.Http(\".cache\")\n\t\th.debuglevel = 2\n\t\turl = \"%s\/current_payouts\" % (self.baseurl)\n\t\tresp, content = h.request(url, \"GET\")\n\t\tjj = json.loads(content)\n\t\tpayout = float(jj[self.payout_addr])\n\t\treturn payout\n\nclass bitcoincharts:\n\tdef __init__(self, symb):\n\t\tself.baseurl = 'http:\/\/api.bitcoincharts.com\/v1\/markets.json'\n\t\th = httplib2.Http(\".cache\")\n\t\th.debuglevel = 2\n\t\tresp, content = h.request(self.baseurl, \"GET\")\n\t\tjj = json.loads(content)\n\t\tfor i in range(len(jj)):\n\t\t\tmarket = jj[i]\n\t\t\tif market['symbol'] == symb:\n\t\t\t\tself.market = market\n\n\tdef last_close(self):\n\t\tprice = float(self.market['close'])\n\t\treturn price\n\n\tdef ask(self):\n\t\tprice = float(self.market['ask'])\n\t\treturn price\n\n\tdef bid(self):\n\t\tprice = float(self.market['bid'])\n\t\treturn price\n\nclass blockchain:\n\tdef __init__(self, addr):\n\t\tself.baseurl = 'https:\/\/blockchain.info\/address'\n\t\th = httplib2.Http(\".cache\")\n\t\th.debuglevel = 2\n\t\turl = '%s\/%s?format=json&amp;limit=0' % (self.baseurl, addr)\n\t\tresp, content = h.request(url, \"GET\")\n\t\tself.jj = json.loads(content)\n\n\tdef total_received(self):\n\t\tammount = float(self.jj['total_received']) \/ 100000000\n\t\treturn ammount\n\n\tdef balance(self):\n\t\tammount = float(self.jj['\"final_balance']) \/ 100000000\n\t\treturn ammount\n\n# test code\nif __name__ == \"__main__\":\n\tpayout = 'putYourBitCoinAddressHere'\n\tp2p = p2pool('http:\/\/TheMachineWhereYourP2PoolNodeRuns:9332', payout)\n\tbtcch = bitcoincharts('mtgoxCHF')\n\tblkch = blockchain(payout)\n\n\ttxtHash   = 'GHash %f'   % p2p.localHashrate()\n\ttxtShares = 'Shares %d'  % p2p.shares()\n\ttxtPay    = 'Pay\/blk %f' % p2p.current_payout()\n\ttxtPrice  = 'CHFgox %f'  % btcch.bid()\n\ttxtRecv   = 'Recv %f'    % blkch.total_received()\n\ttxtTime   = time.strftime('%x %X')[0:14]\n\n\tprint 'pool  hashrate : ', p2p.poolHashrate()\n\tprint 'local hashrate : ', txtHash\n\tprint 'shares         : ', txtShares\n\tprint 'current payout : ', txtPay\n\tprint 'total mined    : ', txtRecv\n\tprint 'mtGoxCHF latest: ', txtPrice\n\tprint 'time           : ', txtTime\n\n\tdisp = NokiaDisplay(0x19, 0)\n\tdisp.SetContrast(0x40)\n\tdisp.Backlight(True)\n\tdisp.TextOut(1, 1, txtHash)\n\tdisp.TextOut(1, 2, txtShares)\n\tdisp.TextOut(1, 3, txtPay)\n\tdisp.TextOut(1, 4, txtRecv)\n\tdisp.TextOut(1, 5, txtPrice)\n\tdisp.TextOut(1, 6, txtTime)\n\tdisp.UpdateDisplay()<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>For a while now, I thought about mounting a simple display somewhere that shows the most important parameters of my BitCoin miner. First I started with an AtMega equipped with an Ethernet module. But parsing json without any library support became too cumbersome quickly. So I copy pasted together a small python script, and used [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,6,7,1],"tags":[37,143,178],"class_list":["post-1227","post","type-post","status-publish","format-standard","hentry","category-bitcoin","category-projects","category-software","category-uncategorized","tag-bitcoin","tag-mining","tag-python"],"_links":{"self":[{"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1227","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1227"}],"version-history":[{"count":0,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1227\/revisions"}],"wp:attachment":[{"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1227"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1227"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ulrichard.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1227"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}