Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
90c8986900 | ||
|
|
5457ae6cd5 | ||
|
|
aa3d105fcb | ||
|
|
77f59f6db6 | ||
|
|
3fa0d96fbb | ||
|
|
e55477a8b8 | ||
|
|
7d5744ae28 | ||
|
|
d4500be10c | ||
|
|
7ef2540133 | ||
|
|
1ea4f4e124 | ||
|
|
a8a0e4a5fe | ||
|
|
5f2f6e01da | ||
|
|
41b4c23d45 |
@@ -157,6 +157,19 @@
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19j Pro+ (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19jProPlus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19j XP (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
@@ -170,6 +183,19 @@
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19j+ (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [x] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19jPlus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19j No PIC (Stock)
|
||||
|
||||
- [x] Shutdowns
|
||||
@@ -287,6 +313,19 @@
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19 XP Hydro (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19XPHydro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19+ (BOS+)
|
||||
|
||||
- [x] Shutdowns
|
||||
@@ -443,6 +482,19 @@
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19 Hydro (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19Hydro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19 Pro (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
@@ -456,6 +508,19 @@
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19 Pro A (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19ProA
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19 Pro Hydro (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
@@ -469,6 +534,32 @@
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19 XP (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19XP
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19 XP Hydro (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19XPHydro
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## S19a (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X3.L3.VnishL3Plus
|
||||
::: pyasic.miners.antminer.vnish.X3.L3.VNishL3Plus
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X7.L7.VnishL7
|
||||
::: pyasic.miners.antminer.vnish.X7.L7.VNishL7
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
|
||||
@@ -105,6 +105,19 @@
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## L9 (VNish)
|
||||
|
||||
- [x] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [x] Setpoints
|
||||
- [x] Presets
|
||||
|
||||
::: pyasic.miners.antminer.vnish.X9.L9.VNishL9
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## T9 (Hive)
|
||||
|
||||
- [ ] Shutdowns
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
# pyasic
|
||||
## DGX Models
|
||||
|
||||
## DG1 (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.elphapex.daoge.DGX.DG1.ElphapexDG1
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## DG1+ (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
@@ -14,3 +27,16 @@
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
## DG1Home (Stock)
|
||||
|
||||
- [ ] Shutdowns
|
||||
- [ ] Power Modes
|
||||
- [ ] Setpoints
|
||||
- [ ] Presets
|
||||
|
||||
::: pyasic.miners.elphapex.daoge.DGX.DG1.ElphapexDG1Home
|
||||
handler: python
|
||||
options:
|
||||
show_root_heading: false
|
||||
heading_level: 0
|
||||
|
||||
|
||||
@@ -86,6 +86,8 @@ details {
|
||||
<li><a href="../antminer/X19#s19j-no-pic-stock">S19j No PIC (Stock)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro_1-stock">S19 Pro+ (Stock)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-stock">S19j Pro (Stock)</a></li>
|
||||
<li><a href="../antminer/X19#s19j_1-stock">S19j+ (Stock)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro_1-stock">S19j Pro+ (Stock)</a></li>
|
||||
<li><a href="../antminer/X19#s19-xp-stock">S19 XP (Stock)</a></li>
|
||||
<li><a href="../antminer/X19#s19a-stock">S19a (Stock)</a></li>
|
||||
<li><a href="../antminer/X19#s19a-pro-stock">S19a Pro (Stock)</a></li>
|
||||
@@ -563,6 +565,12 @@ details {
|
||||
<li><a href="../avalonminer/A15X#avalon-1566-stock">Avalon 1566 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Q Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../avalonminer/Q#avalon-q-home-stock">Avalon Q Home (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -656,6 +664,7 @@ details {
|
||||
<li><a href="../antminer/X19#s19-xp-bos_1">S19 XP (BOS+)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro_1-hydro-bos_1">S19 Pro+ Hydro (BOS+)</a></li>
|
||||
<li><a href="../antminer/X19#t19-bos_1">T19 (BOS+)</a></li>
|
||||
<li><a href="../antminer/X19#s19-xp-hydro-bos_1">S19 XP Hydro (BOS+)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -694,6 +703,12 @@ details {
|
||||
<li><a href="../antminer/X7#l7-vnish">L7 (VNish)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X9 Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../antminer/X9#l9-vnish">L9 (VNish)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>X17 Series:</summary>
|
||||
<ul>
|
||||
@@ -709,11 +724,15 @@ details {
|
||||
<li><a href="../antminer/X19#s19-pro-vnish">S19 Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-vnish">S19j (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19i-vnish">S19i (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19-xp-vnish">S19 XP (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19-xp-hydro-vnish">S19 XP Hydro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19a-vnish">S19a (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19-hydro-vnish">S19 Hydro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19a-pro-vnish">S19a Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro-a-vnish">S19 Pro A (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19-pro-hydro-vnish">S19 Pro Hydro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#s19k-pro-vnish">S19k Pro (VNish)</a></li>
|
||||
<li><a href="../antminer/X19#t19-vnish">T19 (VNish)</a></li>
|
||||
@@ -922,6 +941,12 @@ details {
|
||||
<li><a href="../iceriver/KSX#ks5m-stock">KS5M (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>ALX Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../iceriver/ALX#al3-stock">AL3 (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
@@ -953,6 +978,8 @@ details {
|
||||
<summary>DGX Series:</summary>
|
||||
<ul>
|
||||
<li><a href="../elphapex/DGX#dg1_1-stock">DG1+ (Stock)</a></li>
|
||||
<li><a href="../elphapex/DGX#dg1-stock">DG1 (Stock)</a></li>
|
||||
<li><a href="../elphapex/DGX#dg1home-stock">DG1Home (Stock)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
</ul>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from .base import MinerAlgoType
|
||||
from .blake256 import Blake256Algo
|
||||
from .blockflow import BlockFlowAlgo
|
||||
from .eaglesong import EaglesongAlgo
|
||||
from .equihash import EquihashAlgo
|
||||
from .ethash import EtHashAlgo
|
||||
@@ -24,3 +25,4 @@ class MinerAlgo:
|
||||
EAGLESONG = EaglesongAlgo
|
||||
ETHASH = EtHashAlgo
|
||||
EQUIHASH = EquihashAlgo
|
||||
BLOCKFLOW = BlockFlowAlgo
|
||||
|
||||
12
pyasic/device/algorithm/blockflow.py
Normal file
12
pyasic/device/algorithm/blockflow.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .base import MinerAlgoType
|
||||
from .hashrate import BlockFlowHashRate
|
||||
from .hashrate.unit import BlockFlowUnit
|
||||
|
||||
|
||||
class BlockFlowAlgo(MinerAlgoType):
|
||||
hashrate: type[BlockFlowHashRate] = BlockFlowHashRate
|
||||
unit: type[BlockFlowUnit] = BlockFlowUnit
|
||||
|
||||
name = "BlockFlow"
|
||||
@@ -1,5 +1,6 @@
|
||||
from .base import AlgoHashRateType
|
||||
from .blake256 import Blake256HashRate
|
||||
from .blockflow import BlockFlowHashRate
|
||||
from .eaglesong import EaglesongHashRate
|
||||
from .equihash import EquihashHashRate
|
||||
from .ethash import EtHashHashRate
|
||||
@@ -22,3 +23,4 @@ class AlgoHashRate:
|
||||
EAGLESONG = EaglesongHashRate
|
||||
ETHASH = EtHashHashRate
|
||||
EQUIHASH = EquihashHashRate
|
||||
BLOCKFLOW = BlockFlowHashRate
|
||||
|
||||
18
pyasic/device/algorithm/hashrate/blockflow.py
Normal file
18
pyasic/device/algorithm/hashrate/blockflow.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing_extensions import Self
|
||||
|
||||
from pyasic.device.algorithm.hashrate.base import AlgoHashRateType
|
||||
from pyasic.device.algorithm.hashrate.unit.blockflow import BlockFlowUnit
|
||||
|
||||
from .unit import HashUnit
|
||||
|
||||
|
||||
class BlockFlowHashRate(AlgoHashRateType):
|
||||
rate: float
|
||||
unit: BlockFlowUnit = HashUnit.BLOCKFLOW.default
|
||||
|
||||
def into(self, other: BlockFlowUnit) -> Self:
|
||||
return self.__class__(
|
||||
rate=self.rate / (other.value / self.unit.value), unit=other
|
||||
)
|
||||
@@ -1,4 +1,5 @@
|
||||
from .blake256 import Blake256Unit
|
||||
from .blockflow import BlockFlowUnit
|
||||
from .eaglesong import EaglesongUnit
|
||||
from .equihash import EquihashUnit
|
||||
from .ethash import EtHashUnit
|
||||
@@ -21,3 +22,4 @@ class HashUnit:
|
||||
EAGLESONG = EaglesongUnit
|
||||
ETHASH = EtHashUnit
|
||||
EQUIHASH = EquihashUnit
|
||||
BLOCKFLOW = BlockFlowUnit
|
||||
|
||||
16
pyasic/device/algorithm/hashrate/unit/blockflow.py
Normal file
16
pyasic/device/algorithm/hashrate/unit/blockflow.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from .base import AlgoHashRateUnitType
|
||||
|
||||
|
||||
class BlockFlowUnit(AlgoHashRateUnitType):
|
||||
H = 1
|
||||
KH = int(H) * 1000
|
||||
MH = int(KH) * 1000
|
||||
GH = int(MH) * 1000
|
||||
TH = int(GH) * 1000
|
||||
PH = int(TH) * 1000
|
||||
EH = int(PH) * 1000
|
||||
ZH = int(EH) * 1000
|
||||
|
||||
default = MH
|
||||
@@ -43,6 +43,7 @@ class AntminerModels(MinerModelType):
|
||||
S19jNoPIC = "S19j No PIC"
|
||||
S19ProPlus = "S19 Pro+"
|
||||
S19jPro = "S19j Pro"
|
||||
S19jPlus = "S19j+"
|
||||
S19jProNoPIC = "S19j Pro No PIC"
|
||||
S19jProPlus = "S19j Pro+"
|
||||
S19jProPlusNoPIC = "S19j Pro+ No PIC"
|
||||
@@ -54,6 +55,7 @@ class AntminerModels(MinerModelType):
|
||||
S19ProPlusHydro = "S19 Pro+ Hydro"
|
||||
S19KPro = "S19K Pro"
|
||||
S19kPro = "S19k Pro"
|
||||
S19ProA = "S19 Pro A"
|
||||
S19kProNoPIC = "S19k Pro No PIC"
|
||||
S19jXP = "S19j XP"
|
||||
T19 = "T19"
|
||||
@@ -63,6 +65,7 @@ class AntminerModels(MinerModelType):
|
||||
S21Pro = "S21 Pro"
|
||||
S21Hydro = "S21 Hydro"
|
||||
T21 = "T21"
|
||||
S19XPHydro = "S19 XP Hydro"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
@@ -453,6 +456,7 @@ class AvalonminerModels(MinerModelType):
|
||||
Avalon1566 = "Avalon 1566"
|
||||
AvalonNano3 = "Avalon Nano 3"
|
||||
AvalonNano3s = "Avalon Nano 3s"
|
||||
AvalonQHome = "Avalon Q Home"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
@@ -532,6 +536,7 @@ class IceRiverModels(MinerModelType):
|
||||
KS5 = "KS5"
|
||||
KS5L = "KS5L"
|
||||
KS5M = "KS5M"
|
||||
AL3 = "AL3"
|
||||
|
||||
def __str__(self):
|
||||
return self.value
|
||||
@@ -557,7 +562,9 @@ class BraiinsModels(MinerModelType):
|
||||
|
||||
|
||||
class ElphapexModels(MinerModelType):
|
||||
DG1 = "DG1"
|
||||
DG1Plus = "DG1+"
|
||||
DG1Home = "DG1Home"
|
||||
|
||||
|
||||
class MinerModel:
|
||||
|
||||
@@ -25,7 +25,9 @@ from pyasic.miners.device.models import (
|
||||
S19i,
|
||||
S19j,
|
||||
S19jNoPIC,
|
||||
S19jPlus,
|
||||
S19jPro,
|
||||
S19jProPlus,
|
||||
S19jXP,
|
||||
S19KPro,
|
||||
S19Plus,
|
||||
@@ -80,6 +82,10 @@ class BMMinerS19jPro(AntminerModern, S19jPro):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19jPlus(AntminerModern, S19jPlus):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19L(AntminerModern, S19L):
|
||||
pass
|
||||
|
||||
@@ -102,3 +108,7 @@ class BMMinerS19KPro(AntminerModern, S19KPro):
|
||||
|
||||
class BMMinerS19jXP(AntminerModern, S19jXP):
|
||||
pass
|
||||
|
||||
|
||||
class BMMinerS19jProPlus(AntminerModern, S19jProPlus):
|
||||
pass
|
||||
|
||||
@@ -22,7 +22,9 @@ from .S19 import (
|
||||
BMMinerS19i,
|
||||
BMMinerS19j,
|
||||
BMMinerS19jNoPIC,
|
||||
BMMinerS19jPlus,
|
||||
BMMinerS19jPro,
|
||||
BMMinerS19jProPlus,
|
||||
BMMinerS19jXP,
|
||||
BMMinerS19KPro,
|
||||
BMMinerS19L,
|
||||
|
||||
@@ -30,6 +30,7 @@ from pyasic.miners.device.models import (
|
||||
S19Plus,
|
||||
S19Pro,
|
||||
S19ProPlusHydro,
|
||||
S19XPHydro,
|
||||
)
|
||||
|
||||
|
||||
@@ -87,3 +88,7 @@ class BOSMinerS19XP(BOSer, S19XP):
|
||||
|
||||
class BOSMinerS19ProPlusHydro(BOSer, S19ProPlusHydro):
|
||||
pass
|
||||
|
||||
|
||||
class BOSMinerS19XPHydro(BOSer, S19XPHydro):
|
||||
pass
|
||||
|
||||
@@ -29,5 +29,6 @@ from .S19 import (
|
||||
BOSMinerS19Pro,
|
||||
BOSMinerS19ProPlusHydro,
|
||||
BOSMinerS19XP,
|
||||
BOSMinerS19XPHydro,
|
||||
)
|
||||
from .T19 import BOSMinerT19
|
||||
|
||||
@@ -20,13 +20,16 @@ from pyasic.miners.device.models import (
|
||||
S19XP,
|
||||
S19a,
|
||||
S19aPro,
|
||||
S19Hydro,
|
||||
S19i,
|
||||
S19j,
|
||||
S19jPro,
|
||||
S19kPro,
|
||||
S19NoPIC,
|
||||
S19Pro,
|
||||
S19ProA,
|
||||
S19ProHydro,
|
||||
S19XPHydro,
|
||||
)
|
||||
|
||||
|
||||
@@ -42,10 +45,18 @@ class VNishS19Pro(VNish, S19Pro):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19Hydro(VNish, S19Hydro):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19XP(VNish, S19XP):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19XPHydro(VNish, S19XPHydro):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19a(VNish, S19a):
|
||||
pass
|
||||
|
||||
@@ -54,6 +65,10 @@ class VNishS19aPro(VNish, S19aPro):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19ProA(VNish, S19ProA):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19i(VNish, S19i):
|
||||
pass
|
||||
|
||||
@@ -72,3 +87,7 @@ class VNishS19ProHydro(VNish, S19ProHydro):
|
||||
|
||||
class VNishS19kPro(VNish, S19kPro):
|
||||
pass
|
||||
|
||||
|
||||
class VNishS19ProA(VNish, S19ProA):
|
||||
pass
|
||||
|
||||
@@ -18,13 +18,16 @@ from .S19 import (
|
||||
VNishS19,
|
||||
VNishS19a,
|
||||
VNishS19aPro,
|
||||
VNishS19Hydro,
|
||||
VNishS19i,
|
||||
VNishS19j,
|
||||
VNishS19jPro,
|
||||
VNishS19kPro,
|
||||
VNishS19NoPIC,
|
||||
VNishS19Pro,
|
||||
VNishS19ProA,
|
||||
VNishS19ProHydro,
|
||||
VNishS19XP,
|
||||
VNishS19XPHydro,
|
||||
)
|
||||
from .T19 import VNishT19
|
||||
|
||||
@@ -18,5 +18,5 @@ from pyasic.miners.backends import VNish
|
||||
from pyasic.miners.device.models import L3Plus
|
||||
|
||||
|
||||
class VnishL3Plus(VNish, L3Plus):
|
||||
class VNishL3Plus(VNish, L3Plus):
|
||||
pass
|
||||
|
||||
@@ -14,4 +14,4 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .L3 import VnishL3Plus
|
||||
from .L3 import VNishL3Plus
|
||||
|
||||
@@ -18,5 +18,5 @@ from pyasic.miners.backends import VNish
|
||||
from pyasic.miners.device.models import L7
|
||||
|
||||
|
||||
class VnishL7(VNish, L7):
|
||||
class VNishL7(VNish, L7):
|
||||
pass
|
||||
|
||||
@@ -14,4 +14,4 @@
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .L7 import VnishL7
|
||||
from .L7 import VNishL7
|
||||
|
||||
22
pyasic/miners/antminer/vnish/X9/L9.py
Normal file
22
pyasic/miners/antminer/vnish/X9/L9.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import VNish
|
||||
from pyasic.miners.device.models import L9
|
||||
|
||||
|
||||
class VNishL9(VNish, L9):
|
||||
pass
|
||||
17
pyasic/miners/antminer/vnish/X9/__init__.py
Normal file
17
pyasic/miners/antminer/vnish/X9/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .L9 import VNishL9
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
from .X3 import *
|
||||
from .X7 import *
|
||||
from .X9 import *
|
||||
from .X17 import *
|
||||
from .X19 import *
|
||||
from .X21 import *
|
||||
|
||||
22
pyasic/miners/avalonminer/cgminer/Q/Q.py
Normal file
22
pyasic/miners/avalonminer/cgminer/Q/Q.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2025 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.miners.backends import AvalonMiner
|
||||
from pyasic.miners.device.models import AvalonQHome
|
||||
|
||||
|
||||
class CGMinerAvalonQHome(AvalonMiner, AvalonQHome):
|
||||
pass
|
||||
1
pyasic/miners/avalonminer/cgminer/Q/__init__.py
Normal file
1
pyasic/miners/avalonminer/cgminer/Q/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .Q import CGMinerAvalonQHome
|
||||
@@ -22,3 +22,4 @@ from .A11X import *
|
||||
from .A12X import *
|
||||
from .A15X import *
|
||||
from .nano import *
|
||||
from .Q import *
|
||||
|
||||
@@ -49,31 +49,31 @@ AVALON_NANO_DATA_LOC = DataLocations(
|
||||
),
|
||||
str(DataOptions.EXPECTED_HASHRATE): DataFunction(
|
||||
"_get_expected_hashrate",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.HASHBOARDS): DataFunction(
|
||||
"_get_hashboards",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.ENVIRONMENT_TEMP): DataFunction(
|
||||
"_get_env_temp",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.WATTAGE_LIMIT): DataFunction(
|
||||
"_get_wattage_limit",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.WATTAGE): DataFunction(
|
||||
"_get_wattage",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.FANS): DataFunction(
|
||||
"_get_fans",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.FAULT_LIGHT): DataFunction(
|
||||
"_get_fault_light",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.UPTIME): DataFunction(
|
||||
"_get_uptime",
|
||||
@@ -102,35 +102,35 @@ AVALON_NANO3S_DATA_LOC = DataLocations(
|
||||
),
|
||||
str(DataOptions.HASHRATE): DataFunction(
|
||||
"_get_hashrate",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.EXPECTED_HASHRATE): DataFunction(
|
||||
"_get_expected_hashrate",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.HASHBOARDS): DataFunction(
|
||||
"_get_hashboards",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.ENVIRONMENT_TEMP): DataFunction(
|
||||
"_get_env_temp",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.WATTAGE_LIMIT): DataFunction(
|
||||
"_get_wattage_limit",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.WATTAGE): DataFunction(
|
||||
"_get_wattage",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.FANS): DataFunction(
|
||||
"_get_fans",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.FAULT_LIGHT): DataFunction(
|
||||
"_get_fault_light",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.UPTIME): DataFunction(
|
||||
"_get_uptime",
|
||||
@@ -170,58 +170,58 @@ class CGMinerAvalonNano3s(AvalonMiner, AvalonNano3s):
|
||||
|
||||
data_locations = AVALON_NANO3S_DATA_LOC
|
||||
|
||||
async def _get_wattage(self, rpc_stats: dict = None) -> Optional[int]:
|
||||
if rpc_stats is None:
|
||||
async def _get_wattage(self, rpc_estats: dict = None) -> Optional[int]:
|
||||
if rpc_estats is None:
|
||||
try:
|
||||
rpc_stats = await self.rpc.stats()
|
||||
rpc_estats = await self.rpc.estats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if rpc_stats is not None:
|
||||
if rpc_estats is not None:
|
||||
try:
|
||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||
parsed_stats = self.parse_stats(unparsed_stats)
|
||||
return int(parsed_stats["PS"][6])
|
||||
unparsed_estats = rpc_estats["STATS"][0]["MM ID0"]
|
||||
parsed_estats = self.parse_estats(unparsed_estats)
|
||||
return int(parsed_estats["PS"][6])
|
||||
except (IndexError, KeyError, ValueError, TypeError):
|
||||
pass
|
||||
|
||||
async def _get_hashrate(self, rpc_stats: dict = None) -> Optional[AlgoHashRate]:
|
||||
if rpc_stats is None:
|
||||
async def _get_hashrate(self, rpc_estats: dict = None) -> Optional[AlgoHashRate]:
|
||||
if rpc_estats is None:
|
||||
try:
|
||||
rpc_stats = await self.rpc.stats()
|
||||
rpc_estats = await self.rpc.estats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if rpc_stats is not None:
|
||||
if rpc_estats is not None:
|
||||
try:
|
||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||
parsed_stats = self.parse_stats(unparsed_stats)
|
||||
unparsed_estats = rpc_estats["STATS"][0]["MM ID0"]
|
||||
parsed_estats = self.parse_estats(unparsed_estats)
|
||||
return self.algo.hashrate(
|
||||
rate=float(parsed_stats["GHSspd"][0]), unit=self.algo.unit.GH
|
||||
rate=float(parsed_estats["GHSspd"]), unit=self.algo.unit.GH
|
||||
).into(self.algo.unit.default)
|
||||
except (IndexError, KeyError, ValueError, TypeError):
|
||||
pass
|
||||
|
||||
async def _get_hashboards(self, rpc_stats: dict = None) -> List[HashBoard]:
|
||||
hashboards = await AvalonMiner._get_hashboards(self, rpc_stats)
|
||||
async def _get_hashboards(self, rpc_estats: dict = None) -> List[HashBoard]:
|
||||
hashboards = await AvalonMiner._get_hashboards(self, rpc_estats)
|
||||
|
||||
if rpc_stats is None:
|
||||
if rpc_estats is None:
|
||||
try:
|
||||
rpc_stats = await self.rpc.stats()
|
||||
rpc_estats = await self.rpc.estats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if rpc_stats is not None:
|
||||
if rpc_estats is not None:
|
||||
|
||||
try:
|
||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||
parsed_stats = self.parse_stats(unparsed_stats)
|
||||
unparsed_estats = rpc_estats["STATS"][0]["MM ID0"]
|
||||
parsed_estats = self.parse_estats(unparsed_estats)
|
||||
except (IndexError, KeyError, ValueError, TypeError):
|
||||
return hashboards
|
||||
|
||||
for board in range(len(hashboards)):
|
||||
try:
|
||||
board_hr = parsed_stats["GHSspd"][board]
|
||||
board_hr = parsed_estats["GHSspd"][board]
|
||||
hashboards[board].hashrate = self.algo.hashrate(
|
||||
rate=float(board_hr), unit=self.algo.unit.GH
|
||||
).into(self.algo.unit.default)
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
import copy
|
||||
import re
|
||||
import time
|
||||
from typing import List, Optional
|
||||
|
||||
from pyasic.data import Fan, HashBoard
|
||||
@@ -22,6 +23,7 @@ from pyasic.device.algorithm import AlgoHashRate
|
||||
from pyasic.errors import APIError
|
||||
from pyasic.miners.backends.cgminer import CGMiner
|
||||
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
|
||||
from pyasic.rpc.avalonminer import AvalonMinerRPCAPI
|
||||
|
||||
AVALON_DATA_LOC = DataLocations(
|
||||
**{
|
||||
@@ -43,31 +45,31 @@ AVALON_DATA_LOC = DataLocations(
|
||||
),
|
||||
str(DataOptions.EXPECTED_HASHRATE): DataFunction(
|
||||
"_get_expected_hashrate",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.HASHBOARDS): DataFunction(
|
||||
"_get_hashboards",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.ENVIRONMENT_TEMP): DataFunction(
|
||||
"_get_env_temp",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.WATTAGE_LIMIT): DataFunction(
|
||||
"_get_wattage_limit",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.WATTAGE): DataFunction(
|
||||
"_get_wattage",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.FANS): DataFunction(
|
||||
"_get_fans",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.FAULT_LIGHT): DataFunction(
|
||||
"_get_fault_light",
|
||||
[RPCAPICommand("rpc_stats", "stats")],
|
||||
[RPCAPICommand("rpc_estats", "estats")],
|
||||
),
|
||||
str(DataOptions.UPTIME): DataFunction(
|
||||
"_get_uptime",
|
||||
@@ -84,6 +86,9 @@ AVALON_DATA_LOC = DataLocations(
|
||||
class AvalonMiner(CGMiner):
|
||||
"""Handler for Avalon Miners"""
|
||||
|
||||
_rpc_cls = AvalonMinerRPCAPI
|
||||
rpc: AvalonMinerRPCAPI
|
||||
|
||||
data_locations = AVALON_DATA_LOC
|
||||
|
||||
async def fault_light_on(self) -> bool:
|
||||
@@ -134,45 +139,94 @@ class AvalonMiner(CGMiner):
|
||||
return False
|
||||
return False
|
||||
|
||||
async def stop_mining(self) -> bool:
|
||||
try:
|
||||
# Shut off 5 seconds from now
|
||||
timestamp = int(time.time()) + 5
|
||||
data = await self.rpc.ascset(0, f"softoff", f"1:{timestamp}")
|
||||
except APIError:
|
||||
return False
|
||||
if "success" in data["STATUS"][0]["Msg"]:
|
||||
return True
|
||||
return False
|
||||
|
||||
async def resume_mining(self) -> bool:
|
||||
try:
|
||||
# Shut off 5 seconds from now
|
||||
timestamp = int(time.time()) + 5
|
||||
data = await self.rpc.ascset(0, f"softon", f"1:{timestamp}")
|
||||
except APIError:
|
||||
return False
|
||||
if "success" in data["STATUS"][0]["Msg"]:
|
||||
return True
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def parse_stats(stats):
|
||||
_stats_items = re.findall(".+?\\[*?]", stats)
|
||||
stats_items = []
|
||||
stats_dict = {}
|
||||
for item in _stats_items:
|
||||
if ": " in item:
|
||||
data = item.replace("]", "").split("[")
|
||||
data_list = [i.split(": ") for i in data[1].strip().split(", ")]
|
||||
data_dict = {}
|
||||
try:
|
||||
for key, val in [tuple(item) for item in data_list]:
|
||||
data_dict[key] = val
|
||||
except ValueError:
|
||||
# --avalon args
|
||||
for arg_item in data_list:
|
||||
item_data = arg_item[0].split(" ")
|
||||
for idx, val in enumerate(item_data):
|
||||
if idx % 2 == 0 or idx == 0:
|
||||
data_dict[val] = item_data[idx + 1]
|
||||
def parse_estats(data):
|
||||
# Deep copy to preserve original structure
|
||||
new_data = copy.deepcopy(data)
|
||||
|
||||
raw_data = [data[0].strip(), data_dict]
|
||||
def convert_value(val, key):
|
||||
val = val.strip()
|
||||
|
||||
if key == "SYSTEMSTATU":
|
||||
return val
|
||||
|
||||
if " " in val:
|
||||
parts = val.split()
|
||||
result = []
|
||||
for part in parts:
|
||||
if part.isdigit():
|
||||
result.append(int(part))
|
||||
else:
|
||||
try:
|
||||
result.append(float(part))
|
||||
except ValueError:
|
||||
result.append(part)
|
||||
return result
|
||||
else:
|
||||
raw_data = [
|
||||
value
|
||||
for value in item.replace("[", " ")
|
||||
.replace("]", " ")
|
||||
.split(" ")[:-1]
|
||||
if value != ""
|
||||
]
|
||||
if len(raw_data) == 1:
|
||||
raw_data.append("")
|
||||
if raw_data[0] == "":
|
||||
raw_data = raw_data[1:]
|
||||
if val.isdigit():
|
||||
return int(val)
|
||||
try:
|
||||
return float(val)
|
||||
except ValueError:
|
||||
return val
|
||||
|
||||
stats_dict[raw_data[0]] = raw_data[1:]
|
||||
stats_items.append(raw_data)
|
||||
def parse_info_block(info_str):
|
||||
pattern = re.compile(r"(\w+)\[([^\]]*)\]")
|
||||
return {
|
||||
key: convert_value(val, key) for key, val in pattern.findall(info_str)
|
||||
}
|
||||
|
||||
return stats_dict
|
||||
for stat in new_data.get("STATS", []):
|
||||
keys_to_replace = {}
|
||||
|
||||
for key, value in stat.items():
|
||||
if "MM" in key:
|
||||
# Normalize key by removing suffix after colon
|
||||
norm_key = key.split(":")[0]
|
||||
|
||||
mm_data = value
|
||||
if not isinstance(mm_data, str):
|
||||
continue
|
||||
if mm_data.startswith("'STATS':"):
|
||||
mm_data = mm_data[len("'STATS':") :]
|
||||
keys_to_replace[norm_key] = parse_info_block(mm_data)
|
||||
|
||||
elif key == "HBinfo":
|
||||
match = re.search(r"'(\w+)':\{(.+)\}", value)
|
||||
if match:
|
||||
hb_key = match.group(1)
|
||||
hb_data = match.group(2)
|
||||
keys_to_replace[key] = {hb_key: parse_info_block(hb_data)}
|
||||
|
||||
# Remove old keys and insert parsed versions
|
||||
for k in list(stat.keys()):
|
||||
if "MM" in k or k == "HBinfo":
|
||||
del stat[k]
|
||||
stat.update(keys_to_replace)
|
||||
|
||||
return new_data
|
||||
|
||||
##################################################
|
||||
### DATA GATHERING FUNCTIONS (get_{some_data}) ###
|
||||
@@ -211,7 +265,7 @@ class AvalonMiner(CGMiner):
|
||||
except (KeyError, IndexError, ValueError, TypeError):
|
||||
pass
|
||||
|
||||
async def _get_hashboards(self, rpc_stats: dict = None) -> List[HashBoard]:
|
||||
async def _get_hashboards(self, rpc_estats: dict = None) -> List[HashBoard]:
|
||||
if self.expected_hashboards is None:
|
||||
return []
|
||||
|
||||
@@ -220,164 +274,202 @@ class AvalonMiner(CGMiner):
|
||||
for i in range(self.expected_hashboards)
|
||||
]
|
||||
|
||||
if rpc_stats is None:
|
||||
if rpc_estats is None:
|
||||
try:
|
||||
rpc_stats = await self.rpc.stats()
|
||||
rpc_estats = await self.rpc.estats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if rpc_stats is not None:
|
||||
if rpc_estats is not None:
|
||||
try:
|
||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||
parsed_stats = self.parse_stats(unparsed_stats)
|
||||
parsed_estats = self.parse_estats(rpc_estats)
|
||||
except (IndexError, KeyError, ValueError, TypeError):
|
||||
return hashboards
|
||||
|
||||
for board in range(self.expected_hashboards):
|
||||
|
||||
try:
|
||||
hashboards[board].chip_temp = int(parsed_stats["MTmax"][board])
|
||||
board_hr = parsed_estats["STATS"][0]["MM ID0"]["MGHS"]
|
||||
if isinstance(board_hr, list):
|
||||
hashboards[board].hashrate = self.algo.hashrate(
|
||||
rate=float(board_hr[board]), unit=self.algo.unit.GH
|
||||
).into(self.algo.unit.default)
|
||||
else:
|
||||
hashboards[board].hashrate = self.algo.hashrate(
|
||||
rate=float(board_hr), unit=self.algo.unit.GH
|
||||
).into(self.algo.unit.default)
|
||||
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
try:
|
||||
board_hr = parsed_stats["MGHS"][board]
|
||||
hashboards[board].hashrate = self.algo.hashrate(
|
||||
rate=float(board_hr), unit=self.algo.unit.GH
|
||||
).into(self.algo.unit.default)
|
||||
hashboards[board].chip_temp = int(
|
||||
parsed_estats["STATS"][0]["MM ID0"]["MTmax"][board]
|
||||
)
|
||||
except LookupError:
|
||||
pass
|
||||
try:
|
||||
hashboards[board].chip_temp = int(
|
||||
parsed_estats["STATS"][0]["MM ID0"]["Tmax"]
|
||||
)
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
try:
|
||||
hashboards[board].temp = int(parsed_stats["MTavg"][board])
|
||||
hashboards[board].temp = int(
|
||||
parsed_estats["STATS"][0]["MM ID0"]["MTmax"][board]
|
||||
)
|
||||
except LookupError:
|
||||
pass
|
||||
try:
|
||||
hashboards[board].temp = int(
|
||||
parsed_estats["STATS"][0]["MM ID0"]["Tavg"]
|
||||
)
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
try:
|
||||
chip_data = parsed_stats[f"PVT_T{board}"]
|
||||
hashboards[board].inlet_temp = int(
|
||||
parsed_estats["STATS"][0]["MM ID0"]["MTavg"][board]
|
||||
)
|
||||
except LookupError:
|
||||
try:
|
||||
hashboards[board].inlet_temp = int(
|
||||
parsed_estats["STATS"][0]["MM ID0"]["HBITemp"]
|
||||
)
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
try:
|
||||
hashboards[board].outlet_temp = int(
|
||||
parsed_estats["STATS"][0]["MM ID0"]["MTmax"][board]
|
||||
)
|
||||
except LookupError:
|
||||
try:
|
||||
hashboards[board].outlet_temp = int(
|
||||
parsed_estats["STATS"][0]["MM ID0"]["HBOTemp"]
|
||||
)
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
try:
|
||||
chip_data = parsed_estats["STATS"][0]["MM ID0"][f"PVT_T{board}"]
|
||||
hashboards[board].missing = False
|
||||
if chip_data:
|
||||
hashboards[board].chips = len(
|
||||
[item for item in chip_data if not item == "0"]
|
||||
)
|
||||
except LookupError:
|
||||
pass
|
||||
try:
|
||||
chip_data = parsed_estats["STATS"][0]["HBinfo"][f"HB{board}"][
|
||||
f"PVT_T{board}"
|
||||
]
|
||||
hashboards[board].missing = False
|
||||
if chip_data:
|
||||
hashboards[board].chips = len(
|
||||
[item for item in chip_data if not item == "0"]
|
||||
)
|
||||
except LookupError:
|
||||
pass
|
||||
|
||||
return hashboards
|
||||
|
||||
async def _get_expected_hashrate(
|
||||
self, rpc_stats: dict = None
|
||||
self, rpc_estats: dict = None
|
||||
) -> Optional[AlgoHashRate]:
|
||||
if rpc_stats is None:
|
||||
if rpc_estats is None:
|
||||
try:
|
||||
rpc_stats = await self.rpc.stats()
|
||||
rpc_estats = await self.rpc.estats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if rpc_stats is not None:
|
||||
if rpc_estats is not None:
|
||||
try:
|
||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||
parsed_stats = self.parse_stats(unparsed_stats)
|
||||
parsed_estats = self.parse_estats(rpc_estats)["STATS"][0]["MM ID0"]
|
||||
return self.algo.hashrate(
|
||||
rate=float(parsed_stats["GHSmm"][0]), unit=self.algo.unit.GH
|
||||
rate=float(parsed_estats["GHSmm"]), unit=self.algo.unit.GH
|
||||
).into(self.algo.unit.default)
|
||||
except (IndexError, KeyError, ValueError, TypeError):
|
||||
pass
|
||||
|
||||
async def _get_env_temp(self, rpc_stats: dict = None) -> Optional[float]:
|
||||
if rpc_stats is None:
|
||||
async def _get_env_temp(self, rpc_estats: dict = None) -> Optional[float]:
|
||||
if rpc_estats is None:
|
||||
try:
|
||||
rpc_stats = await self.rpc.stats()
|
||||
rpc_estats = await self.rpc.estats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if rpc_stats is not None:
|
||||
if rpc_estats is not None:
|
||||
try:
|
||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||
parsed_stats = self.parse_stats(unparsed_stats)
|
||||
return float(parsed_stats["Temp"][0])
|
||||
parsed_estats = self.parse_estats(rpc_estats)["STATS"][0]["MM ID0"]
|
||||
return float(parsed_estats["Temp"])
|
||||
except (IndexError, KeyError, ValueError, TypeError):
|
||||
pass
|
||||
|
||||
async def _get_wattage_limit(self, rpc_stats: dict = None) -> Optional[int]:
|
||||
if rpc_stats is None:
|
||||
async def _get_wattage_limit(self, rpc_estats: dict = None) -> Optional[int]:
|
||||
if rpc_estats is None:
|
||||
try:
|
||||
rpc_stats = await self.rpc.stats()
|
||||
rpc_estats = await self.rpc.estats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if rpc_stats is not None:
|
||||
if rpc_estats is not None:
|
||||
try:
|
||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||
parsed_stats = self.parse_stats(unparsed_stats)
|
||||
return int(parsed_stats["MPO"][0])
|
||||
parsed_estats = self.parse_estats(rpc_estats)["STATS"][0]["MM ID0"]
|
||||
return int(parsed_estats["MPO"])
|
||||
except (IndexError, KeyError, ValueError, TypeError):
|
||||
pass
|
||||
|
||||
async def _get_wattage(self, rpc_stats: dict = None) -> Optional[int]:
|
||||
if rpc_stats is None:
|
||||
async def _get_wattage(self, rpc_estats: dict = None) -> Optional[int]:
|
||||
if rpc_estats is None:
|
||||
try:
|
||||
rpc_stats = await self.rpc.stats()
|
||||
rpc_estats = await self.rpc.estats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if rpc_stats is not None:
|
||||
if rpc_estats is not None:
|
||||
try:
|
||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||
parsed_stats = self.parse_stats(unparsed_stats)
|
||||
return int(parsed_stats["WALLPOWER"][0])
|
||||
parsed_estats = self.parse_estats(rpc_estats)["STATS"][0]["MM ID0"]
|
||||
return int(parsed_estats["WALLPOWER"])
|
||||
except (IndexError, KeyError, ValueError, TypeError):
|
||||
pass
|
||||
|
||||
async def _get_fans(self, rpc_stats: dict = None) -> List[Fan]:
|
||||
async def _get_fans(self, rpc_estats: dict = None) -> List[Fan]:
|
||||
if self.expected_fans is None:
|
||||
return []
|
||||
|
||||
if rpc_stats is None:
|
||||
if rpc_estats is None:
|
||||
try:
|
||||
rpc_stats = await self.rpc.stats()
|
||||
rpc_estats = await self.rpc.estats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
fans_data = [Fan() for _ in range(self.expected_fans)]
|
||||
if rpc_stats is not None:
|
||||
if rpc_estats is not None:
|
||||
try:
|
||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||
parsed_stats = self.parse_stats(unparsed_stats)
|
||||
parsed_estats = self.parse_estats(rpc_estats)["STATS"][0]["MM ID0"]
|
||||
except LookupError:
|
||||
return fans_data
|
||||
|
||||
for fan in range(self.expected_fans):
|
||||
try:
|
||||
fans_data[fan].speed = int(parsed_stats[f"Fan{fan + 1}"][0])
|
||||
fans_data[fan].speed = int(parsed_estats[f"Fan{fan + 1}"])
|
||||
except (IndexError, KeyError, ValueError, TypeError):
|
||||
pass
|
||||
return fans_data
|
||||
|
||||
async def _get_fault_light(self, rpc_stats: dict = None) -> Optional[bool]:
|
||||
async def _get_fault_light(self, rpc_estats: dict = None) -> Optional[bool]:
|
||||
if self.light:
|
||||
return self.light
|
||||
if rpc_stats is None:
|
||||
if rpc_estats is None:
|
||||
try:
|
||||
rpc_stats = await self.rpc.stats()
|
||||
rpc_estats = await self.rpc.estats()
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
if rpc_stats is not None:
|
||||
if rpc_estats is not None:
|
||||
try:
|
||||
unparsed_stats = rpc_stats["STATS"][0]["MM ID0"]
|
||||
parsed_stats = self.parse_stats(unparsed_stats)
|
||||
led = int(parsed_stats["Led"][0])
|
||||
parsed_estats = self.parse_estats(rpc_estats)["STATS"][0]["MM ID0"]
|
||||
led = int(parsed_estats["Led"])
|
||||
return True if led == 1 else False
|
||||
except (IndexError, KeyError, ValueError, TypeError):
|
||||
pass
|
||||
|
||||
try:
|
||||
data = await self.rpc.ascset(0, "led", "1-255")
|
||||
except APIError:
|
||||
return False
|
||||
try:
|
||||
if data["STATUS"][0]["Msg"] == "ASC 0 set info: LED[1]":
|
||||
return True
|
||||
except LookupError:
|
||||
pass
|
||||
return False
|
||||
|
||||
@@ -115,11 +115,18 @@ class ESPMiner(BaseMiner):
|
||||
|
||||
if web_system_info is not None:
|
||||
try:
|
||||
expected_hashrate = (
|
||||
web_system_info.get("smallCoreCount")
|
||||
* web_system_info.get("asicCount")
|
||||
* web_system_info.get("frequency")
|
||||
)
|
||||
small_core_count = web_system_info.get("smallCoreCount")
|
||||
asic_count = web_system_info.get("asicCount")
|
||||
frequency = web_system_info.get("frequency")
|
||||
|
||||
if asic_count is None:
|
||||
try:
|
||||
asic_info = await self.web.asic_info()
|
||||
asic_count = asic_info.get("asicCount")
|
||||
except APIError:
|
||||
pass
|
||||
|
||||
expected_hashrate = small_core_count * asic_count * frequency
|
||||
|
||||
return self.algo.hashrate(
|
||||
rate=float(expected_hashrate), unit=self.algo.unit.MH
|
||||
|
||||
@@ -126,6 +126,15 @@ class S19jPro(AntMinerMake):
|
||||
algo = MinerAlgo.SHA256
|
||||
|
||||
|
||||
class S19jPlus(AntMinerMake):
|
||||
raw_model = MinerModel.ANTMINER.S19jPlus
|
||||
|
||||
expected_chips = 108
|
||||
expected_fans = 4
|
||||
expected_hashboards = 3
|
||||
algo = MinerAlgo.SHA256
|
||||
|
||||
|
||||
class S19jProNoPIC(AntMinerMake):
|
||||
raw_model = MinerModel.ANTMINER.S19jProNoPIC
|
||||
|
||||
@@ -216,6 +225,15 @@ class S19KPro(AntMinerMake):
|
||||
algo = MinerAlgo.SHA256
|
||||
|
||||
|
||||
class S19ProA(AntMinerMake):
|
||||
raw_model = MinerModel.ANTMINER.S19ProA
|
||||
|
||||
expected_chips = 114
|
||||
expected_fans = 4
|
||||
expected_hashboards = 3
|
||||
algo = MinerAlgo.SHA256
|
||||
|
||||
|
||||
class S19jXP(AntMinerMake):
|
||||
raw_model = MinerModel.ANTMINER.S19jXP
|
||||
|
||||
@@ -223,3 +241,12 @@ class S19jXP(AntMinerMake):
|
||||
expected_fans = 4
|
||||
expected_hashboards = 3
|
||||
algo = MinerAlgo.SHA256
|
||||
|
||||
|
||||
class S19XPHydro(AntMinerMake):
|
||||
raw_model = MinerModel.ANTMINER.S19XPHydro
|
||||
|
||||
expected_chips = 204
|
||||
expected_fans = 0
|
||||
expected_hashboards = 3
|
||||
algo = MinerAlgo.SHA256
|
||||
|
||||
@@ -24,6 +24,7 @@ from .S19 import (
|
||||
S19i,
|
||||
S19j,
|
||||
S19jNoPIC,
|
||||
S19jPlus,
|
||||
S19jPro,
|
||||
S19jProNoPIC,
|
||||
S19jProPlus,
|
||||
@@ -35,8 +36,10 @@ from .S19 import (
|
||||
S19NoPIC,
|
||||
S19Plus,
|
||||
S19Pro,
|
||||
S19ProA,
|
||||
S19ProHydro,
|
||||
S19ProPlus,
|
||||
S19ProPlusHydro,
|
||||
S19XPHydro,
|
||||
)
|
||||
from .T19 import T19
|
||||
|
||||
27
pyasic/miners/device/models/avalonminer/Q/Q.py
Normal file
27
pyasic/miners/device/models/avalonminer/Q/Q.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.device.algorithm import MinerAlgo
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import AvalonMinerMake
|
||||
|
||||
|
||||
class AvalonQHome(AvalonMinerMake):
|
||||
raw_model = MinerModel.AVALONMINER.AvalonQHome
|
||||
|
||||
expected_chips = 160
|
||||
expected_fans = 2
|
||||
expected_hashboards = 1
|
||||
algo = MinerAlgo.SHA256
|
||||
17
pyasic/miners/device/models/avalonminer/Q/__init__.py
Normal file
17
pyasic/miners/device/models/avalonminer/Q/__init__.py
Normal file
@@ -0,0 +1,17 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2022 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from .Q import AvalonQHome
|
||||
@@ -22,3 +22,4 @@ from .A11X import *
|
||||
from .A12X import *
|
||||
from .A15X import *
|
||||
from .nano import *
|
||||
from .Q import *
|
||||
|
||||
@@ -18,6 +18,15 @@ from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import ElphapexMake
|
||||
|
||||
|
||||
class DG1(ElphapexMake):
|
||||
raw_model = MinerModel.ELPHAPEX.DG1
|
||||
|
||||
expected_chips = 144
|
||||
expected_hashboards = 4
|
||||
expected_fans = 4
|
||||
algo = MinerAlgo.SCRYPT
|
||||
|
||||
|
||||
class DG1Plus(ElphapexMake):
|
||||
raw_model = MinerModel.ELPHAPEX.DG1Plus
|
||||
|
||||
@@ -25,3 +34,12 @@ class DG1Plus(ElphapexMake):
|
||||
expected_hashboards = 4
|
||||
expected_fans = 4
|
||||
algo = MinerAlgo.SCRYPT
|
||||
|
||||
|
||||
class DG1Home(ElphapexMake):
|
||||
raw_model = MinerModel.ELPHAPEX.DG1Home
|
||||
|
||||
expected_chips = 120
|
||||
expected_hashboards = 4
|
||||
expected_fans = 4
|
||||
algo = MinerAlgo.SCRYPT
|
||||
|
||||
@@ -1 +1 @@
|
||||
from .DG1 import DG1Plus
|
||||
from .DG1 import DG1, DG1Home, DG1Plus
|
||||
|
||||
27
pyasic/miners/device/models/iceriver/ALX/AL3.py
Normal file
27
pyasic/miners/device/models/iceriver/ALX/AL3.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2024 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
from pyasic.device.algorithm import MinerAlgo
|
||||
from pyasic.device.models import MinerModel
|
||||
from pyasic.miners.device.makes import IceRiverMake
|
||||
|
||||
|
||||
class AL3(IceRiverMake):
|
||||
raw_model = MinerModel.ICERIVER.AL3
|
||||
|
||||
expected_chips = 156
|
||||
expected_fans = 4
|
||||
expected_hashboards = 3
|
||||
algo = MinerAlgo.BLOCKFLOW
|
||||
1
pyasic/miners/device/models/iceriver/ALX/__init__.py
Normal file
1
pyasic/miners/device/models/iceriver/ALX/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .AL3 import AL3
|
||||
@@ -1 +1,2 @@
|
||||
from .ALX import *
|
||||
from .KSX import *
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
from pyasic.miners.backends.elphapex import ElphapexMiner
|
||||
from pyasic.miners.device.models import DG1Plus
|
||||
from pyasic.miners.device.models import DG1, DG1Home, DG1Plus
|
||||
|
||||
|
||||
class ElphapexDG1Plus(ElphapexMiner, DG1Plus):
|
||||
pass
|
||||
|
||||
|
||||
class ElphapexDG1(ElphapexMiner, DG1):
|
||||
pass
|
||||
|
||||
|
||||
class ElphapexDG1Home(ElphapexMiner, DG1Home):
|
||||
pass
|
||||
|
||||
@@ -1 +1 @@
|
||||
from .DG1 import ElphapexDG1Plus
|
||||
from .DG1 import ElphapexDG1, ElphapexDG1Home, ElphapexDG1Plus
|
||||
|
||||
@@ -41,6 +41,7 @@ from pyasic.miners.elphapex import *
|
||||
from pyasic.miners.goldshell import *
|
||||
from pyasic.miners.hammer import *
|
||||
from pyasic.miners.iceriver import *
|
||||
from pyasic.miners.iceriver.iceminer.ALX import IceRiverAL3
|
||||
from pyasic.miners.innosilicon import *
|
||||
from pyasic.miners.luckyminer import *
|
||||
from pyasic.miners.volcminer import *
|
||||
@@ -108,6 +109,8 @@ MINER_CLASSES = {
|
||||
"ANTMINER S19J88NOPIC": BMMinerS19jNoPIC,
|
||||
"ANTMINER S19PRO+": BMMinerS19ProPlus,
|
||||
"ANTMINER S19J PRO": BMMinerS19jPro,
|
||||
"ANTMINER S19J+": BMMinerS19jPlus,
|
||||
"ANTMINER S19J PRO+": BMMinerS19jProPlus,
|
||||
"ANTMINER S19 XP": BMMinerS19XP,
|
||||
"ANTMINER S19A": BMMinerS19a,
|
||||
"ANTMINER S19A PRO": BMMinerS19aPro,
|
||||
@@ -509,6 +512,7 @@ MINER_CLASSES = {
|
||||
"AVALONMINER NANO3": CGMinerAvalonNano3,
|
||||
"AVALON NANO3S": CGMinerAvalonNano3s,
|
||||
"AVALONMINER 15-194": CGMinerAvalon1566,
|
||||
"AVALON Q": CGMinerAvalonQHome,
|
||||
},
|
||||
MinerTypes.INNOSILICON: {
|
||||
None: type("InnosiliconUnknown", (Innosilicon, InnosiliconMake), {}),
|
||||
@@ -561,12 +565,14 @@ MINER_CLASSES = {
|
||||
"ANTMINER T21": BOSMinerT21,
|
||||
"BRAIINS MINI MINER BMM 100": BraiinsBMM100,
|
||||
"BRAIINS MINI MINER BMM 101": BraiinsBMM101,
|
||||
"ANTMINER S19 XP HYD.": BOSMinerS19XPHydro,
|
||||
},
|
||||
MinerTypes.VNISH: {
|
||||
None: VNish,
|
||||
"L3+": VnishL3Plus,
|
||||
"ANTMINER L3+": VnishL3Plus,
|
||||
"ANTMINER L7": VnishL7,
|
||||
"L3+": VNishL3Plus,
|
||||
"ANTMINER L3+": VNishL3Plus,
|
||||
"ANTMINER L7": VNishL7,
|
||||
"ANTMINER L9": VNishL9,
|
||||
"ANTMINER S17+": VNishS17Plus,
|
||||
"ANTMINER S17 PRO": VNishS17Pro,
|
||||
"ANTMINER S19": VNishS19,
|
||||
@@ -574,11 +580,15 @@ MINER_CLASSES = {
|
||||
"ANTMINER S19 PRO": VNishS19Pro,
|
||||
"ANTMINER S19J": VNishS19j,
|
||||
"ANTMINER S19I": VNishS19i,
|
||||
"ANTMINER S19 XP": VNishS19XP,
|
||||
"ANTMINER S19 XP HYD.": VNishS19XPHydro,
|
||||
"ANTMINER S19J PRO": VNishS19jPro,
|
||||
"ANTMINER S19J PRO A": VNishS19jPro,
|
||||
"ANTMINER S19J PRO BB": VNishS19jPro,
|
||||
"ANTMINER S19A": VNishS19a,
|
||||
"ANTMINER S19 HYD.": VNishS19Hydro,
|
||||
"ANTMINER S19A PRO": VNishS19aPro,
|
||||
"ANTMINER S19 PRO A": VNishS19ProA,
|
||||
"ANTMINER S19 PRO HYD.": VNishS19ProHydro,
|
||||
"ANTMINER S19K PRO": VNishS19kPro,
|
||||
"ANTMINER T19": VNishT19,
|
||||
@@ -677,6 +687,7 @@ MINER_CLASSES = {
|
||||
"KS5": IceRiverKS5,
|
||||
"KS5L": IceRiverKS5L,
|
||||
"KS5M": IceRiverKS5M,
|
||||
"10306": IceRiverAL3,
|
||||
},
|
||||
MinerTypes.HAMMER: {
|
||||
None: type("HammerUnknown", (BlackMiner, HammerMake), {}),
|
||||
@@ -689,6 +700,8 @@ MINER_CLASSES = {
|
||||
MinerTypes.ELPHAPEX: {
|
||||
None: type("ElphapexUnknown", (ElphapexMiner, ElphapexMake), {}),
|
||||
"DG1+": ElphapexDG1Plus,
|
||||
"DG1": ElphapexDG1,
|
||||
"DG1-Home": ElphapexDG1Home,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
6
pyasic/miners/iceriver/iceminer/ALX/AL3.py
Normal file
6
pyasic/miners/iceriver/iceminer/ALX/AL3.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from pyasic.miners.backends.iceriver import IceRiver
|
||||
from pyasic.miners.device.models.iceriver import AL3
|
||||
|
||||
|
||||
class IceRiverAL3(IceRiver, AL3):
|
||||
pass
|
||||
1
pyasic/miners/iceriver/iceminer/ALX/__init__.py
Normal file
1
pyasic/miners/iceriver/iceminer/ALX/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from .AL3 import IceRiverAL3
|
||||
27
pyasic/rpc/avalonminer.py
Normal file
27
pyasic/rpc/avalonminer.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# ------------------------------------------------------------------------------
|
||||
# Copyright 2025 Upstream Data Inc -
|
||||
# -
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); -
|
||||
# you may not use this file except in compliance with the License. -
|
||||
# You may obtain a copy of the License at -
|
||||
# -
|
||||
# http://www.apache.org/licenses/LICENSE-2.0 -
|
||||
# -
|
||||
# Unless required by applicable law or agreed to in writing, software -
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, -
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
|
||||
# See the License for the specific language governing permissions and -
|
||||
# limitations under the License. -
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
from pyasic.rpc.cgminer import CGMinerRPCAPI
|
||||
|
||||
|
||||
class AvalonMinerRPCAPI(CGMinerRPCAPI):
|
||||
"""An abstraction of the AvalonMiner API.
|
||||
|
||||
Each method corresponds to an API command in AvalonMiner.
|
||||
"""
|
||||
|
||||
async def litestats(self):
|
||||
return await self.send_command("litestats")
|
||||
@@ -96,3 +96,6 @@ class ESPMinerWebAPI(BaseWebAPI):
|
||||
|
||||
async def update_settings(self, **config):
|
||||
return await self.send_command("system", patch=True, **config)
|
||||
|
||||
async def asic_info(self):
|
||||
return await self.send_command("system/asic")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "pyasic"
|
||||
version = "0.72.9"
|
||||
version = "0.74.0"
|
||||
|
||||
description = "A simplified and standardized interface for Bitcoin ASICs."
|
||||
authors = [{name = "UpstreamData", email = "brett@upstreamdata.ca"}]
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user