Skip to content

Commit 202b9fc

Browse files
committed
Add support for ZMaster
1 parent fd23905 commit 202b9fc

File tree

3 files changed

+76
-9
lines changed

3 files changed

+76
-9
lines changed

fullcyclepy/FullCyclePython.pyproj

+3
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,9 @@
259259
<Compile Include="tests\test_service.py">
260260
<SubType>Code</SubType>
261261
</Compile>
262+
<Compile Include="tests\test_innosilicon.py">
263+
<SubType>Code</SubType>
264+
</Compile>
262265
<Compile Include="tests\test_taskscheduler.py">
263266
<SubType>Code</SubType>
264267
</Compile>

fullcyclepy/helpers/antminerhelper.py

+45-9
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,58 @@ def stats(miner: Miner):
4949
if not miner.is_disabled():
5050
raise MinerMonitorException(jstatus[0]['description'])
5151
else:
52-
status = jstats['STATS'][0]
53-
jsonstats = jstats['STATS'][1]
54-
#details = jstats['STATS'][1]
52+
miner_software = parse_miner_software(jstats)
53+
if miner_software.startswith('sgminer'):
54+
jstats = stats_and_pools['STATS']
55+
jsonstats = jstats
56+
status = jstats[0]
57+
jstatus = stats_and_pools['STATUS']
58+
minerinfo = helpers.antminerhelper.parse_statistics_inno(entity, jsonstats, status)
5559

56-
minerinfo = parse_minerinfo(status)
60+
else:
61+
status = jstats['STATS'][0]
62+
jsonstats = jstats['STATS'][1]
63+
64+
minerinfo = parse_minerinfo(status)
5765

58-
#build MinerStatistics from stats
59-
parse_statistics(entity, jsonstats, status)
60-
minerpool = parse_minerpool(miner, stats_and_pools['pools'][0])
66+
#build MinerStatistics from stats
67+
parse_statistics(entity, jsonstats, status)
68+
minerpool = parse_minerpool(miner, stats_and_pools['pools'][0])
6169

6270
return entity, minerinfo, thecall, minerpool
6371
except BaseException as ex:
6472
print('Failed to call miner stats api: ' + str(ex))
6573
raise MinerMonitorException(ex)
6674
return None, None, None, None
6775

76+
def parse_miner_software(jsonstats):
77+
if 'STATUS' in jsonstats:
78+
status = jsonstats['STATUS']
79+
if len(status) > 0 and 'Description' in status[0]:
80+
return status[0]['Description']
81+
return 'unknown'
82+
83+
def parse_statistics_inno(entity, jsonstats, status):
84+
miner_stats = [x for x in jsonstats if 'ID' in x and x['ID'].startswith('HLT')]
85+
86+
entity.minercount = len(miner_stats)
87+
elapsed =[x['Elapsed'] for x in miner_stats]
88+
entity.elapsed = max(elapsed)
89+
entity.currenthash = sum([int(float(x['MHS av'])) for x in miner_stats])
90+
entity.hash_avg = sum([int(float(x['MHS av'])) for x in miner_stats])
91+
entity.hardware_errors = sum([sum({v for (k, v) in y.items() if k.endswith('HW errors')}) for y in miner_stats])
92+
93+
#entity.frequency = jsonstats['frequency']
94+
#entity.frequency = str(int(sum(frequencies.values()) / len(frequencies)))
95+
96+
controllertemps = [int(float(x['Temp'])) for x in miner_stats]
97+
entity.controllertemp = max(controllertemps)
98+
dict_temps = {'Temp_'+x['ID']: x['Temp'] for x in miner_stats}
99+
parse_board_temps(entity, dict_temps, 'Temp')
100+
#some stats are not ready to parse yet
101+
#parse_fans(entity, jsonstats)
102+
#parse_board_status(entity, jsonstats)
103+
68104
def parse_statistics(entity, jsonstats, status):
69105
entity.minercount = int(jsonstats['miner_count'])
70106
entity.elapsed = int(jsonstats['Elapsed'])
@@ -103,9 +139,9 @@ def parse_fans(entity, jsonstats):
103139
if len(fans) > 2:
104140
entity.fan3 = fans[fankeys[2]]
105141

106-
def parse_board_temps(entity, jsonstats):
142+
def parse_board_temps(entity, jsonstats, key = 'temp2_'):
107143
#should be 3
108-
boardtemps = {k:v for (k, v) in jsonstats.items() if k.startswith('temp2_') and v != 0}
144+
boardtemps = {k:v for (k, v) in jsonstats.items() if k.startswith(key) and v != 0}
109145
boardtempkeys = list(boardtemps.keys())
110146
if len(boardtemps) > 0:
111147
entity.tempboard1 = boardtemps[boardtempkeys[0]]

fullcyclepy/tests/test_innosilicon.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
import datetime
3+
import json
4+
import domain.minerstatistics
5+
from domain.mining import Miner, MinerInfo, MinerCurrentPool, MinerAccessLevel, MinerApiCall
6+
import helpers.antminerhelper
7+
8+
miner = Miner('test')
9+
entity = domain.minerstatistics.MinerStatistics(miner, when=datetime.datetime.utcnow())
10+
11+
stats_and_pools = json.loads('{"STATUS":[{"STATUS":"S","When":1542065836,"Code":70,"Msg":"CGMiner stats","Description":"sgminer 4.4.2"}],"STATS":[{"STATS":0,"ID":"HLT0","Elapsed":3350,"Calls":0,"Wait":0.000000,"Max":0.000000,"Min":99999999.000000,"Chain ID":0,"Num chips":12,"Num cores":380,"Num active chips":12,"Chain skew":0,"Temp max":79.000000,"Temp min":55.000000,"Temp":65.000000,"Fan duty":25,"iVid":170,"PLL":354,"Voltage Max":903,"Voltage Min":873,"Voltage Avg":886,"VidOptimal":true,"pllOptimal":true,"VoltageBalanced":false,"Chain num":0,"MHS av":950000.000000,"Disabled":false,"Enabled chips":"fff","00 HW errors":2,"00 Stales":0,"00 Nonces found":7,"00 Nonce ranges":0,"00 Cooldown":0,"00 Fail count":0,"00 Fail reset":32,"00 Temp":0,"00 nVol":884,"00 PLL":0,"00 pllOptimal":false,"01 HW errors":0,"01 Stales":0,"01 Nonces found":9,"01 Nonce ranges":0,"01 Cooldown":0,"01 Fail count":0,"01 Fail reset":32,"01 Temp":0,"01 nVol":881,"01 PLL":0,"01 pllOptimal":false,"02 HW errors":2,"02 Stales":0,"02 Nonces found":14,"02 Nonce ranges":0,"02 Cooldown":0,"02 Fail count":0,"02 Fail reset":32,"02 Temp":0,"02 nVol":881,"02 PLL":0,"02 pllOptimal":false,"03 HW errors":0,"03 Stales":0,"03 Nonces found":4,"03 Nonce ranges":0,"03 Cooldown":0,"03 Fail count":0,"03 Fail reset":32,"03 Temp":0,"03 nVol":878,"03 PLL":0,"03 pllOptimal":false,"04 HW errors":2,"04 Stales":0,"04 Nonces found":10,"04 Nonce ranges":0,"04 Cooldown":0,"04 Fail count":0,"04 Fail reset":32,"04 Temp":0,"04 nVol":900,"04 PLL":0,"04 pllOptimal":false,"05 HW errors":4,"05 Stales":0,"05 Nonces found":12,"05 Nonce ranges":0,"05 Cooldown":0,"05 Fail count":0,"05 Fail reset":32,"05 Temp":0,"05 nVol":903,"05 PLL":0,"05 pllOptimal":false,"06 HW errors":4,"06 Stales":0,"06 Nonces found":11,"06 Nonce ranges":0,"06 Cooldown":0,"06 Fail count":0,"06 Fail reset":32,"06 Temp":0,"06 nVol":879,"06 PLL":0,"06 pllOptimal":false,"07 HW errors":3,"07 Stales":0,"07 Nonces found":8,"07 Nonce ranges":0,"07 Cooldown":0,"07 Fail count":0,"07 Fail reset":30,"07 Temp":0,"07 nVol":899,"07 PLL":0,"07 pllOptimal":false,"08 HW errors":0,"08 Stales":0,"08 Nonces found":10,"08 Nonce ranges":0,"08 Cooldown":0,"08 Fail count":0,"08 Fail reset":31,"08 Temp":0,"08 nVol":894,"08 PLL":0,"08 pllOptimal":false,"09 HW errors":2,"09 Stales":0,"09 Nonces found":8,"09 Nonce ranges":0,"09 Cooldown":0,"09 Fail count":0,"09 Fail reset":32,"09 Temp":0,"09 nVol":882,"09 PLL":0,"09 pllOptimal":false,"10 HW errors":1,"10 Stales":0,"10 Nonces found":10,"10 Nonce ranges":0,"10 Cooldown":0,"10 Fail count":1,"10 Fail reset":31,"10 Temp":0,"10 nVol":888,"10 PLL":0,"10 pllOptimal":false,"11 HW errors":1,"11 Stales":0,"11 Nonces found":9,"11 Nonce ranges":0,"11 Cooldown":0,"11 Fail count":0,"11 Fail reset":32,"11 Temp":0,"11 nVol":873,"11 PLL":0,"11 pllOptimal":false},{"STATS":1,"ID":"HLT1","Elapsed":3350,"Calls":0,"Wait":0.000000,"Max":0.000000,"Min":99999999.000000,"Chain ID":1,"Num chips":12,"Num cores":380,"Num active chips":12,"Chain skew":0,"Temp max":72.000000,"Temp min":54.000000,"Temp":63.000000,"Fan duty":25,"iVid":170,"PLL":354,"Voltage Max":904,"Voltage Min":867,"Voltage Avg":886,"VidOptimal":true,"pllOptimal":true,"VoltageBalanced":false,"Chain num":1,"MHS av":950000.000000,"Disabled":false,"Enabled chips":"fff","00 HW errors":1,"00 Stales":0,"00 Nonces found":8,"00 Nonce ranges":0,"00 Cooldown":0,"00 Fail count":0,"00 Fail reset":32,"00 Temp":0,"00 nVol":890,"00 PLL":0,"00 pllOptimal":false,"01 HW errors":0,"01 Stales":0,"01 Nonces found":12,"01 Nonce ranges":0,"01 Cooldown":0,"01 Fail count":0,"01 Fail reset":32,"01 Temp":0,"01 nVol":884,"01 PLL":0,"01 pllOptimal":false,"02 HW errors":0,"02 Stales":0,"02 Nonces found":10,"02 Nonce ranges":0,"02 Cooldown":0,"02 Fail count":0,"02 Fail reset":32,"02 Temp":0,"02 nVol":867,"02 PLL":0,"02 pllOptimal":false,"03 HW errors":1,"03 Stales":0,"03 Nonces found":6,"03 Nonce ranges":0,"03 Cooldown":0,"03 Fail count":0,"03 Fail reset":32,"03 Temp":0,"03 nVol":895,"03 PLL":0,"03 pllOptimal":false,"04 HW errors":0,"04 Stales":0,"04 Nonces found":5,"04 Nonce ranges":0,"04 Cooldown":0,"04 Fail count":0,"04 Fail reset":32,"04 Temp":0,"04 nVol":894,"04 PLL":0,"04 pllOptimal":false,"05 HW errors":3,"05 Stales":0,"05 Nonces found":6,"05 Nonce ranges":0,"05 Cooldown":0,"05 Fail count":0,"05 Fail reset":32,"05 Temp":0,"05 nVol":887,"05 PLL":0,"05 pllOptimal":false,"06 HW errors":1,"06 Stales":0,"06 Nonces found":9,"06 Nonce ranges":0,"06 Cooldown":0,"06 Fail count":0,"06 Fail reset":31,"06 Temp":0,"06 nVol":882,"06 PLL":0,"06 pllOptimal":false,"07 HW errors":0,"07 Stales":0,"07 Nonces found":10,"07 Nonce ranges":0,"07 Cooldown":0,"07 Fail count":0,"07 Fail reset":32,"07 Temp":0,"07 nVol":904,"07 PLL":0,"07 pllOptimal":false,"08 HW errors":1,"08 Stales":0,"08 Nonces found":12,"08 Nonce ranges":0,"08 Cooldown":0,"08 Fail count":0,"08 Fail reset":32,"08 Temp":0,"08 nVol":879,"08 PLL":0,"08 pllOptimal":false,"09 HW errors":0,"09 Stales":0,"09 Nonces found":10,"09 Nonce ranges":0,"09 Cooldown":0,"09 Fail count":0,"09 Fail reset":32,"09 Temp":0,"09 nVol":889,"09 PLL":0,"09 pllOptimal":false,"10 HW errors":0,"10 Stales":0,"10 Nonces found":6,"10 Nonce ranges":0,"10 Cooldown":0,"10 Fail count":0,"10 Fail reset":31,"10 Temp":0,"10 nVol":889,"10 PLL":0,"10 pllOptimal":false,"11 HW errors":0,"11 Stales":0,"11 Nonces found":5,"11 Nonce ranges":0,"11 Cooldown":0,"11 Fail count":0,"11 Fail reset":30,"11 Temp":0,"11 nVol":879,"11 PLL":0,"11 pllOptimal":false},{"STATS":2,"ID":"HLT2","Elapsed":3350,"Calls":0,"Wait":0.000000,"Max":0.000000,"Min":99999999.000000,"Chain ID":2,"Num chips":12,"Num cores":383,"Num active chips":12,"Chain skew":0,"Temp max":74.000000,"Temp min":51.000000,"Temp":63.000000,"Fan duty":25,"iVid":170,"PLL":354,"Voltage Max":893,"Voltage Min":862,"Voltage Avg":880,"VidOptimal":true,"pllOptimal":true,"VoltageBalanced":false,"Chain num":2,"MHS av":957500.000000,"Disabled":false,"Enabled chips":"fff","00 HW errors":2,"00 Stales":0,"00 Nonces found":7,"00 Nonce ranges":0,"00 Cooldown":0,"00 Fail count":0,"00 Fail reset":31,"00 Temp":0,"00 nVol":877,"00 PLL":0,"00 pllOptimal":false,"01 HW errors":0,"01 Stales":0,"01 Nonces found":6,"01 Nonce ranges":0,"01 Cooldown":0,"01 Fail count":1,"01 Fail reset":32,"01 Temp":0,"01 nVol":862,"01 PLL":0,"01 pllOptimal":false,"02 HW errors":1,"02 Stales":0,"02 Nonces found":7,"02 Nonce ranges":0,"02 Cooldown":0,"02 Fail count":0,"02 Fail reset":32,"02 Temp":0,"02 nVol":877,"02 PLL":0,"02 pllOptimal":false,"03 HW errors":0,"03 Stales":0,"03 Nonces found":3,"03 Nonce ranges":0,"03 Cooldown":0,"03 Fail count":0,"03 Fail reset":32,"03 Temp":0,"03 nVol":883,"03 PLL":0,"03 pllOptimal":false,"04 HW errors":2,"04 Stales":0,"04 Nonces found":3,"04 Nonce ranges":0,"04 Cooldown":0,"04 Fail count":0,"04 Fail reset":32,"04 Temp":0,"04 nVol":889,"04 PLL":0,"04 pllOptimal":false,"05 HW errors":1,"05 Stales":0,"05 Nonces found":12,"05 Nonce ranges":0,"05 Cooldown":0,"05 Fail count":0,"05 Fail reset":32,"05 Temp":0,"05 nVol":879,"05 PLL":0,"05 pllOptimal":false,"06 HW errors":1,"06 Stales":0,"06 Nonces found":3,"06 Nonce ranges":0,"06 Cooldown":0,"06 Fail count":0,"06 Fail reset":32,"06 Temp":0,"06 nVol":893,"06 PLL":0,"06 pllOptimal":false,"07 HW errors":1,"07 Stales":0,"07 Nonces found":10,"07 Nonce ranges":0,"07 Cooldown":0,"07 Fail count":0,"07 Fail reset":32,"07 Temp":0,"07 nVol":887,"07 PLL":0,"07 pllOptimal":false,"08 HW errors":0,"08 Stales":0,"08 Nonces found":19,"08 Nonce ranges":0,"08 Cooldown":0,"08 Fail count":0,"08 Fail reset":32,"08 Temp":0,"08 nVol":888,"08 PLL":0,"08 pllOptimal":false,"09 HW errors":1,"09 Stales":0,"09 Nonces found":5,"09 Nonce ranges":0,"09 Cooldown":0,"09 Fail count":0,"09 Fail reset":32,"09 Temp":0,"09 nVol":879,"09 PLL":0,"09 pllOptimal":false,"10 HW errors":2,"10 Stales":0,"10 Nonces found":6,"10 Nonce ranges":0,"10 Cooldown":0,"10 Fail count":0,"10 Fail reset":32,"10 Temp":0,"10 nVol":872,"10 PLL":0,"10 pllOptimal":false,"11 HW errors":2,"11 Stales":0,"11 Nonces found":12,"11 Nonce ranges":0,"11 Cooldown":0,"11 Fail count":0,"11 Fail reset":32,"11 Temp":0,"11 nVol":879,"11 PLL":0,"11 pllOptimal":false},{"STATS":3,"ID":"POOL0","Elapsed":3350,"Calls":0,"Wait":0.000000,"Max":0.000000,"Min":99999999.000000,"Pool Calls":0,"Pool Attempts":0,"Pool Wait":0.000000,"Pool Max":0.000000,"Pool Min":99999999.000000,"Pool Av":0.000000,"Work Had Roll Time":false,"Work Can Roll":false,"Work Had Expire":false,"Work Roll Time":0,"Work Diff":524344.00000000,"Min Diff":524344.00000000,"Max Diff":524344.00000000,"Min Diff Count":15968,"Max Diff Count":15968,"Times Sent":307,"Bytes Sent":871390,"Times Recv":381,"Bytes Recv":36185,"Net Bytes Sent":871390,"Net Bytes Recv":36185},{"STATS":4,"ID":"POOL1","Elapsed":3350,"Calls":0,"Wait":0.000000,"Max":0.000000,"Min":99999999.000000,"Pool Calls":0,"Pool Attempts":0,"Pool Wait":0.000000,"Pool Max":0.000000,"Pool Min":99999999.000000,"Pool Av":0.000000,"Work Had Roll Time":false,"Work Can Roll":false,"Work Had Expire":false,"Work Roll Time":0,"Work Diff":0.00000000,"Min Diff":0.00000000,"Max Diff":0.00000000,"Min Diff Count":0,"Max Diff Count":0,"Times Sent":3,"Bytes Sent":218,"Times Recv":6,"Bytes Recv":947,"Net Bytes Sent":218,"Net Bytes Recv":947},{"STATS":5,"ID":"POOL2","Elapsed":3350,"Calls":0,"Wait":0.000000,"Max":0.000000,"Min":99999999.000000,"Pool Calls":0,"Pool Attempts":0,"Pool Wait":0.000000,"Pool Max":0.000000,"Pool Min":99999999.000000,"Pool Av":0.000000,"Work Had Roll Time":false,"Work Can Roll":false,"Work Had Expire":false,"Work Roll Time":0,"Work Diff":524344.00000000,"Min Diff":524344.00000000,"Max Diff":524344.00000000,"Min Diff Count":1,"Max Diff Count":1,"Times Sent":3,"Bytes Sent":218,"Times Recv":7,"Bytes Recv":1264,"Net Bytes Sent":218,"Net Bytes Recv":1264}],"id":1}')
12+
13+
#stats => STATS
14+
jstats = stats_and_pools['STATS'] #[0]
15+
16+
#should be 0,1,2?
17+
jsonstats = jstats
18+
status = jstats[0]
19+
20+
entity.rawstats = jstats
21+
#jstats => stats_and_pools
22+
jstatus = stats_and_pools['STATUS']
23+
24+
miner_software = helpers.antminerhelper.parse_miner_software(stats_and_pools)
25+
26+
#build MinerStatistics from stats
27+
minerinfo = helpers.antminerhelper.parse_statistics_inno(entity, jsonstats, status)
28+

0 commit comments

Comments
 (0)