diff --git a/docs/index.md b/docs/index.md
index 3e375d0f..f07d9e9a 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -42,8 +42,8 @@ if __name__ == "__main__":
## Creating miners based on IP
-If you already know the IP address of your miner or miners, you can use the [`MinerFactory`][pyasic.miners.miner_factory.MinerFactory] to communicate and identify the miners, or an abstraction of its functionality, [`get_miner()`][pyasic.miners.miner_factory.MinerFactory.get_miner].
-The function [`get_miner()`][pyasic.miners.miner_factory.MinerFactory.get_miner] will return any miner it found at the IP address specified, or an `UnknownMiner` if it cannot identify the miner.
+If you already know the IP address of your miner or miners, you can use the [`MinerFactory`][pyasic.miners.miner_factory.MinerFactory] to communicate and identify the miners, or an abstraction of its functionality, [`get_miner()`][pyasic.miners.get_miner].
+The function [`get_miner()`][pyasic.miners.get_miner] will return any miner it found at the IP address specified, or an `UnknownMiner` if it cannot identify the miner.
```python
import asyncio # asyncio for handling the async part
from pyasic import get_miner # handles miner creation
diff --git a/docs/miners/antminer/X15.md b/docs/miners/antminer/X15.md
index a6df8805..8fbb1c26 100644
--- a/docs/miners/antminer/X15.md
+++ b/docs/miners/antminer/X15.md
@@ -1,11 +1,10 @@
# pyasic
## X15 Models
-
## Z15
-
-::: pyasic.miners.zec.antminer.cgminer.X15.Z15.CGMinerZ15
+::: pyasic.miners.antminer.cgminer.X15.Z15.CGMinerZ15
handler: python
options:
show_root_heading: false
heading_level: 4
+
diff --git a/docs/miners/antminer/X17.md b/docs/miners/antminer/X17.md
index c9bd1a7e..6560a408 100644
--- a/docs/miners/antminer/X17.md
+++ b/docs/miners/antminer/X17.md
@@ -2,116 +2,114 @@
## X17 Models
## S17
-
-::: pyasic.miners.btc.antminer.bmminer.X17.S17.BMMinerS17
+::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17
handler: python
options:
show_root_heading: false
heading_level: 4
## S17+
-
-::: pyasic.miners.btc.antminer.bmminer.X17.S17_Plus.BMMinerS17Plus
+::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17Plus
handler: python
options:
show_root_heading: false
heading_level: 4
## S17 Pro
-
-::: pyasic.miners.btc.antminer.bmminer.X17.S17_Pro.BMMinerS17Pro
+::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S17e
-
-::: pyasic.miners.btc.antminer.bmminer.X17.S17e.BMMinerS17e
+::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17e
handler: python
options:
show_root_heading: false
heading_level: 4
## T17
-
-::: pyasic.miners.btc.antminer.bmminer.X17.T17.BMMinerT17
+::: pyasic.miners.antminer.bmminer.X17.T17.BMMinerT17
handler: python
options:
show_root_heading: false
heading_level: 4
## T17+
-
-::: pyasic.miners.btc.antminer.bmminer.X17.T17_Plus.BMMinerT17Plus
+::: pyasic.miners.antminer.bmminer.X17.T17.BMMinerT17Plus
handler: python
options:
show_root_heading: false
heading_level: 4
-
## T17e
-
-::: pyasic.miners.btc.antminer.bmminer.X17.T17e.BMMinerT17e
+::: pyasic.miners.antminer.bmminer.X17.T17.BMMinerT17e
handler: python
options:
show_root_heading: false
heading_level: 4
-
## S17 (BOS)
-
-::: pyasic.miners.btc.antminer.bosminer.X17.S17.BOSMinerS17
+::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17
handler: python
options:
show_root_heading: false
heading_level: 4
## S17+ (BOS)
-
-::: pyasic.miners.btc.antminer.bosminer.X17.S17_Plus.BOSMinerS17Plus
+::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Plus
handler: python
options:
show_root_heading: false
heading_level: 4
## S17 Pro (BOS)
-
-::: pyasic.miners.btc.antminer.bosminer.X17.S17_Pro.BOSMinerS17Pro
+::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S17e (BOS)
-
-::: pyasic.miners.btc.antminer.bosminer.X17.S17e.BOSMinerS17e
+::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17e
handler: python
options:
show_root_heading: false
heading_level: 4
## T17 (BOS)
-
-::: pyasic.miners.btc.antminer.bosminer.X17.T17.BOSMinerT17
+::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17
handler: python
options:
show_root_heading: false
heading_level: 4
## T17+ (BOS)
-
-::: pyasic.miners.btc.antminer.bosminer.X17.T17_Plus.BOSMinerT17Plus
+::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17Plus
handler: python
options:
show_root_heading: false
heading_level: 4
-
## T17e (BOS)
-
-::: pyasic.miners.btc.antminer.bosminer.X17.T17e.BOSMinerT17e
+::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17e
handler: python
options:
show_root_heading: false
heading_level: 4
+
+## S17+ (VNish)
+::: pyasic.miners.antminer.vnish.X17.S17.VNishS17Plus
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## S17 Pro (VNish)
+::: pyasic.miners.antminer.vnish.X17.S17.VNishS17Pro
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
diff --git a/docs/miners/antminer/X19.md b/docs/miners/antminer/X19.md
index 3b898db3..f0d0e58d 100644
--- a/docs/miners/antminer/X19.md
+++ b/docs/miners/antminer/X19.md
@@ -2,109 +2,170 @@
## X19 Models
## S19
-
-::: pyasic.miners.btc.antminer.bmminer.X19.S19.BMMinerS19
+::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19L
-
-::: pyasic.miners.btc.antminer.bmminer.X19.S19L.BMMinerS19L
+::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19L
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro
-
-::: pyasic.miners.btc.antminer.bmminer.X19.S19_Pro.BMMinerS19Pro
+::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19Pro
handler: python
options:
show_root_heading: false
heading_level: 4
-
-## S19a
-
-::: pyasic.miners.btc.antminer.bmminer.X19.S19a.BMMinerS19a
- handler: python
- options:
- show_root_heading: false
- heading_level: 4
-
-
## S19j
+::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19j
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
-::: pyasic.miners.btc.antminer.bmminer.X19.S19j.BMMinerS19j
+## S19j No PIC
+::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19jNoPIC
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## S19 Pro+
+::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19ProPlus
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro
-
-::: pyasic.miners.btc.antminer.bmminer.X19.S19j_Pro.BMMinerS19jPro
+::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19jPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 XP
+::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19XP
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
-::: pyasic.miners.btc.antminer.bmminer.X19.S19_XP.BMMinerS19XP
+## S19a
+::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19a
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## S19a Pro
+::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19aPro
handler: python
options:
show_root_heading: false
heading_level: 4
## T19
-
-::: pyasic.miners.btc.antminer.bmminer.X19.T19.BMMinerT19
+::: pyasic.miners.antminer.bmminer.X19.T19.BMMinerT19
handler: python
options:
show_root_heading: false
heading_level: 4
-
## S19 (BOS)
-
-::: pyasic.miners.btc.antminer.bosminer.X19.S19.BOSMinerS19
+::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro (BOS)
-
-::: pyasic.miners.btc.antminer.bosminer.X19.S19_Pro.BOSMinerS19Pro
+::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19Pro
handler: python
options:
show_root_heading: false
heading_level: 4
-
## S19j (BOS)
+::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19j
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
-::: pyasic.miners.btc.antminer.bosminer.X19.S19j.BOSMinerS19j
+## S19j No PIC (BOS)
+::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jNoPIC
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro (BOS)
-
-::: pyasic.miners.btc.antminer.bosminer.X19.S19j_Pro.BOSMinerS19jPro
+::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro
handler: python
options:
show_root_heading: false
heading_level: 4
## T19 (BOS)
-
-::: pyasic.miners.btc.antminer.bosminer.X19.T19.BOSMinerT19
+::: pyasic.miners.antminer.bosminer.X19.T19.BOSMinerT19
handler: python
options:
show_root_heading: false
heading_level: 4
+
+## S19 (VNish)
+::: pyasic.miners.antminer.vnish.X19.S19.VNishS19
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## S19 Pro (VNish)
+::: pyasic.miners.antminer.vnish.X19.S19.VNishS19Pro
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## S19j (VNish)
+::: pyasic.miners.antminer.vnish.X19.S19.VNishS19j
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## S19j Pro (VNish)
+::: pyasic.miners.antminer.vnish.X19.S19.VNishS19jPro
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## S19a (VNish)
+::: pyasic.miners.antminer.vnish.X19.S19.VNishS19a
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## S19a Pro (VNish)
+::: pyasic.miners.antminer.vnish.X19.S19.VNishS19aPro
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## T19 (VNish)
+::: pyasic.miners.antminer.vnish.X19.T19.VNishT19
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
diff --git a/docs/miners/antminer/X3.md b/docs/miners/antminer/X3.md
index 1b687d8a..fcdcc9e7 100644
--- a/docs/miners/antminer/X3.md
+++ b/docs/miners/antminer/X3.md
@@ -1,11 +1,31 @@
# pyasic
## X3 Models
-
-## HS3
-
-::: pyasic.miners.hns.antminer.cgminer.X3.HS3.CGMinerHS3
+## D3
+::: pyasic.miners.antminer.cgminer.X3.D3.CGMinerD3
handler: python
options:
show_root_heading: false
heading_level: 4
+
+## HS3
+::: pyasic.miners.antminer.bmminer.X3.HS3.BMMinerHS3
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## L3+
+::: pyasic.miners.antminer.bmminer.X3.L3.BMMinerL3Plus
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## L3+ (VNish)
+::: pyasic.miners.antminer.vnish.X3.L3.VnishL3Plus
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
diff --git a/docs/miners/antminer/X5.md b/docs/miners/antminer/X5.md
index f72bf9fd..deb33a89 100644
--- a/docs/miners/antminer/X5.md
+++ b/docs/miners/antminer/X5.md
@@ -1,11 +1,10 @@
# pyasic
## X5 Models
-
## DR5
-
-::: pyasic.miners.dcr.antminer.cgminer.X5.DR5.CGMinerDR5
+::: pyasic.miners.antminer.cgminer.X5.DR5.CGMinerDR5
handler: python
options:
show_root_heading: false
heading_level: 4
+
diff --git a/docs/miners/antminer/X7.md b/docs/miners/antminer/X7.md
index 19fe7643..2d198a10 100644
--- a/docs/miners/antminer/X7.md
+++ b/docs/miners/antminer/X7.md
@@ -1,11 +1,10 @@
# pyasic
## X7 Models
-
## L7
-
-::: pyasic.miners.ltc.antminer.bmminer.X7.L7.BMMinerL7
+::: pyasic.miners.antminer.bmminer.X7.L7.BMMinerL7
handler: python
options:
show_root_heading: false
heading_level: 4
+
diff --git a/docs/miners/antminer/X9.md b/docs/miners/antminer/X9.md
index e6549306..cc0a3186 100644
--- a/docs/miners/antminer/X9.md
+++ b/docs/miners/antminer/X9.md
@@ -1,44 +1,52 @@
# pyasic
## X9 Models
-
-## X9 (BOS)
-
-::: pyasic.miners.btc.antminer.bosminer.X9.S9.BOSMinerS9
+## E9Pro
+::: pyasic.miners.antminer.bmminer.X9.E9.BMMinerE9Pro
handler: python
options:
show_root_heading: false
heading_level: 4
-
## S9
-
-::: pyasic.miners.btc.antminer.bmminer.X9.S9.BMMinerS9
+::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9
handler: python
options:
show_root_heading: false
heading_level: 4
## S9i
+::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9i
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
-::: pyasic.miners.btc.antminer.bmminer.X9.S9i.BMMinerS9i
+## S9j
+::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9j
handler: python
options:
show_root_heading: false
heading_level: 4
## T9
-
-::: pyasic.miners.btc.antminer.bmminer.X9.T9.BMMinerT9
+::: pyasic.miners.antminer.bmminer.X9.T9.BMMinerT9
handler: python
options:
show_root_heading: false
heading_level: 4
-## E9 Pro
-
-::: pyasic.miners.etc.antminer.cgminer.X9.E9_Pro.CGMinerE9Pro
+## S9 (BOS)
+::: pyasic.miners.antminer.bosminer.X9.S9.BOSMinerS9
handler: python
options:
show_root_heading: false
heading_level: 4
+
+## T9 (Hiveon)
+::: pyasic.miners.antminer.hiveon.X9.T9.HiveonT9
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
diff --git a/docs/miners/avalonminer/A10X.md b/docs/miners/avalonminer/A10X.md
index 37cd018b..60f9bb81 100644
--- a/docs/miners/avalonminer/A10X.md
+++ b/docs/miners/avalonminer/A10X.md
@@ -1,26 +1,24 @@
# pyasic
## A10X Models
-## A1026
-
-::: pyasic.miners.btc.avalonminer.cgminer.A10X.A1026.CGMinerAvalon1026
+## Avalon 1026
+::: pyasic.miners.avalonminer.cgminer.A10X.A1026.CGMinerAvalon1026
handler: python
options:
show_root_heading: false
heading_level: 4
-## A1047
-
-::: pyasic.miners.btc.avalonminer.cgminer.A10X.A1047.CGMinerAvalon1047
+## Avalon 1047
+::: pyasic.miners.avalonminer.cgminer.A10X.A1047.CGMinerAvalon1047
handler: python
options:
show_root_heading: false
heading_level: 4
-## A1066
-
-::: pyasic.miners.btc.avalonminer.cgminer.A10X.A1066.CGMinerAvalon1066
+## Avalon 1066
+::: pyasic.miners.avalonminer.cgminer.A10X.A1066.CGMinerAvalon1066
handler: python
options:
show_root_heading: false
heading_level: 4
+
diff --git a/docs/miners/avalonminer/A11X.md b/docs/miners/avalonminer/A11X.md
new file mode 100644
index 00000000..4624b2f4
--- /dev/null
+++ b/docs/miners/avalonminer/A11X.md
@@ -0,0 +1,10 @@
+# pyasic
+## A11X Models
+
+## Avalon 1166 Pro
+::: pyasic.miners.avalonminer.cgminer.A11X.A1166.CGMinerAvalon1166Pro
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
diff --git a/docs/miners/goldshell/HSX.md b/docs/miners/avalonminer/A12X.md
similarity index 51%
rename from docs/miners/goldshell/HSX.md
rename to docs/miners/avalonminer/A12X.md
index 7e9815a7..0a8429a0 100644
--- a/docs/miners/goldshell/HSX.md
+++ b/docs/miners/avalonminer/A12X.md
@@ -1,10 +1,10 @@
# pyasic
-## HSX Models
+## A12X Models
-## HS5
-
-::: pyasic.miners.hns.goldshell.bfgminer.HSX.HS5.BFGMinerHS5
+## Avalon 1246
+::: pyasic.miners.avalonminer.cgminer.A12X.A1246.CGMinerAvalon1246
handler: python
options:
show_root_heading: false
heading_level: 4
+
diff --git a/docs/miners/avalonminer/A7X.md b/docs/miners/avalonminer/A7X.md
index 2e14ae3e..b2c8371c 100644
--- a/docs/miners/avalonminer/A7X.md
+++ b/docs/miners/avalonminer/A7X.md
@@ -1,26 +1,24 @@
# pyasic
## A7X Models
-## A721
-
-::: pyasic.miners.btc.avalonminer.cgminer.A7X.A721.CGMinerAvalon721
+## Avalon 721
+::: pyasic.miners.avalonminer.cgminer.A7X.A721.CGMinerAvalon721
handler: python
options:
show_root_heading: false
heading_level: 4
-## A741
-
-::: pyasic.miners.btc.avalonminer.cgminer.A7X.A741.CGMinerAvalon741
+## Avalon 741
+::: pyasic.miners.avalonminer.cgminer.A7X.A741.CGMinerAvalon741
handler: python
options:
show_root_heading: false
heading_level: 4
-## A761
-
-::: pyasic.miners.btc.avalonminer.cgminer.A7X.A761.CGMinerAvalon761
+## Avalon 761
+::: pyasic.miners.avalonminer.cgminer.A7X.A761.CGMinerAvalon761
handler: python
options:
show_root_heading: false
heading_level: 4
+
diff --git a/docs/miners/avalonminer/A8X.md b/docs/miners/avalonminer/A8X.md
index e3f6c78c..7e99dcba 100644
--- a/docs/miners/avalonminer/A8X.md
+++ b/docs/miners/avalonminer/A8X.md
@@ -1,26 +1,24 @@
# pyasic
## A8X Models
-## A821
-
-::: pyasic.miners.btc.avalonminer.cgminer.A8X.A821.CGMinerAvalon821
+## Avalon 821
+::: pyasic.miners.avalonminer.cgminer.A8X.A821.CGMinerAvalon821
handler: python
options:
show_root_heading: false
heading_level: 4
-## A841
-
-::: pyasic.miners.btc.avalonminer.cgminer.A8X.A841.CGMinerAvalon841
+## Avalon 841
+::: pyasic.miners.avalonminer.cgminer.A8X.A841.CGMinerAvalon841
handler: python
options:
show_root_heading: false
heading_level: 4
-## A851
-
-::: pyasic.miners.btc.avalonminer.cgminer.A8X.A851.CGMinerAvalon851
+## Avalon 851
+::: pyasic.miners.avalonminer.cgminer.A8X.A851.CGMinerAvalon851
handler: python
options:
show_root_heading: false
heading_level: 4
+
diff --git a/docs/miners/avalonminer/A9X.md b/docs/miners/avalonminer/A9X.md
index 456aa1b0..1af53274 100644
--- a/docs/miners/avalonminer/A9X.md
+++ b/docs/miners/avalonminer/A9X.md
@@ -1,10 +1,10 @@
# pyasic
## A9X Models
-## A921
-
-::: pyasic.miners.btc.avalonminer.cgminer.A9X.A921.CGMinerAvalon921
+## Avalon 921
+::: pyasic.miners.avalonminer.cgminer.A9X.A921.CGMinerAvalon921
handler: python
options:
show_root_heading: false
heading_level: 4
+
diff --git a/docs/miners/goldshell/KDX.md b/docs/miners/goldshell/KDX.md
deleted file mode 100644
index c9175f04..00000000
--- a/docs/miners/goldshell/KDX.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# pyasic
-## KDX Models
-
-## KD5
-
-::: pyasic.miners.kda.goldshell.bfgminer.KDX.KD5.BFGMinerKD5
- handler: python
- options:
- show_root_heading: false
- heading_level: 4
-
-
-## KD Max
-
-::: pyasic.miners.kda.goldshell.bfgminer.KDX.KDMax.BFGMinerKDMax
- handler: python
- options:
- show_root_heading: false
- heading_level: 4
diff --git a/docs/miners/goldshell/X5.md b/docs/miners/goldshell/X5.md
new file mode 100644
index 00000000..466beeb7
--- /dev/null
+++ b/docs/miners/goldshell/X5.md
@@ -0,0 +1,24 @@
+# pyasic
+## X5 Models
+
+## CK5
+::: pyasic.miners.goldshell.bfgminer.X5.CK5.BFGMinerCK5
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## HS5
+::: pyasic.miners.goldshell.bfgminer.X5.HS5.BFGMinerHS5
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## KD5
+::: pyasic.miners.goldshell.bfgminer.X5.KD5.BFGMinerKD5
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
diff --git a/docs/miners/goldshell/CKX.md b/docs/miners/goldshell/XMax.md
similarity index 53%
rename from docs/miners/goldshell/CKX.md
rename to docs/miners/goldshell/XMax.md
index eeec69f8..7b458431 100644
--- a/docs/miners/goldshell/CKX.md
+++ b/docs/miners/goldshell/XMax.md
@@ -1,10 +1,10 @@
# pyasic
-## CKX Models
+## XMax Models
-## CK5
-
-::: pyasic.miners.ckb.goldshell.bfgminer.CKX.CK5.BFGMinerCK5
+## KD Max
+::: pyasic.miners.goldshell.bfgminer.XMax.KDMax.BFGMinerKDMax
handler: python
options:
show_root_heading: false
heading_level: 4
+
diff --git a/docs/miners/innosilicon/A10X.md b/docs/miners/innosilicon/A10X.md
index f108eb4e..b3e5bf03 100644
--- a/docs/miners/innosilicon/A10X.md
+++ b/docs/miners/innosilicon/A10X.md
@@ -2,9 +2,9 @@
## A10X Models
## A10X
-
-::: pyasic.miners.etc.innosilicon.cgminer.A10X.A10X.CGMinerA10X
+::: pyasic.miners.innosilicon.cgminer.A10X.A10X.CGMinerA10X
handler: python
options:
show_root_heading: false
heading_level: 4
+
diff --git a/docs/miners/innosilicon/T3X.md b/docs/miners/innosilicon/T3X.md
index 5eb858b0..47fd870e 100644
--- a/docs/miners/innosilicon/T3X.md
+++ b/docs/miners/innosilicon/T3X.md
@@ -2,9 +2,9 @@
## T3X Models
## T3H+
-
-::: pyasic.miners.btc.innosilicon.cgminer.T3X.T3H_Plus.CGMinerInnosiliconT3HPlus
+::: pyasic.miners.innosilicon.cgminer.T3X.T3H.CGMinerT3HPlus
handler: python
options:
show_root_heading: false
heading_level: 4
+
diff --git a/docs/miners/miner_factory.md b/docs/miners/miner_factory.md
index c9c5fb28..b47a4266 100644
--- a/docs/miners/miner_factory.md
+++ b/docs/miners/miner_factory.md
@@ -8,6 +8,14 @@
heading_level: 4
+## Get Miner
+::: pyasic.miners.get_miner
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+
## AnyMiner
::: pyasic.miners.miner_factory.AnyMiner
handler: python
diff --git a/docs/miners/supported_types.md b/docs/miners/supported_types.md
index 0ba08bef..1ff82a20 100644
--- a/docs/miners/supported_types.md
+++ b/docs/miners/supported_types.md
@@ -11,37 +11,72 @@ details {
padding-bottom:0px;
}
-
-Braiins OS+ Devices:
+
+
+Stock Firmware Antminers:
- X19 Series:
+ X3 Series:
- X17 Series:
+ X5 Series:
+
+
+ X7 Series:
+
X9 Series:
+
+
+ X15 Series:
+
+
+
+ X17 Series:
+
+
+
+ X19 Series:
+
@@ -51,440 +86,199 @@ details {
M2X Series:
-
+
M3X Series:
-
+
M5X Series:
-
-
-
-
-
-
-Stock Firmware Antminers:
-
-
- X19 Series:
-
-
-
- X17 Series:
-
-
-
- X15 Series:
-
-
-
- X9 Series:
-
-
-
- X7 Series:
-
-
-
- X5 Series:
-
-
-
- X3 Series:
-
+
@@ -492,75 +286,157 @@ details {
Stock Firmware Avalonminers:
- A7X Series:
-
+ A7X Series:
+
- A8X Series:
-
+ A8X Series:
+
- A9X Series:
-
+ A9X Series:
+
- A10X Series:
-
+ A10X Series:
+
+
+
+ A11X Series:
+
+
+
+ A12X Series:
+
-Stock Firmware Innosilicon Miners:
+Stock Firmware Innosilicons:
- T3X Series:
-
+ T3X Series:
+
- A10X Series:
-
+ A10X Series:
+
-Stock Firmware BFGMinerGoldshell Miners:
+Stock Firmware Goldshells:
- CKX Series:
-
+ X5 Series:
+
- HSX Series:
-
-
-
- KDX Series:
-
+ XMax Series:
+
+
+BOS+ Firmware Miners:
+
+
+ X9 Series:
+
+
+
+ X17 Series:
+
+
+
+ X19 Series:
+
+
+
+
+
+Vnish Firmware Miners:
+
+
+ X3 Series:
+
+
+
+ X17 Series:
+
+
+
+ X19 Series:
+
+
+
+
+
+HiveOS Firmware Miners:
+
+
\ No newline at end of file
diff --git a/docs/miners/whatsminer/M2X.md b/docs/miners/whatsminer/M2X.md
index 70e4121f..e5c1efa7 100644
--- a/docs/miners/whatsminer/M2X.md
+++ b/docs/miners/whatsminer/M2X.md
@@ -1,90 +1,80 @@
# pyasic
## M2X Models
-## M20V10
-
-::: pyasic.miners.btc.whatsminer.btminer.M2X.M20.BTMinerM20V10
+## M20 V10
+::: pyasic.miners.whatsminer.btminer.M2X.M20.BTMinerM20V10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M20SV10
-
-::: pyasic.miners.btc.whatsminer.btminer.M2X.M20S.BTMinerM20SV10
+## M20S V10
+::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M20SV20
-
-::: pyasic.miners.btc.whatsminer.btminer.M2X.M20S.BTMinerM20SV20
+## M20S V20
+::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M20SV30
-
-::: pyasic.miners.btc.whatsminer.btminer.M2X.M20S.BTMinerM20SV30
+## M20S V30
+::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M20S+V30
-
-::: pyasic.miners.btc.whatsminer.btminer.M2X.M20S_Plus.BTMinerM20SPlusV30
+## M20S+ V30
+::: pyasic.miners.whatsminer.btminer.M2X.M20S_Plus.BTMinerM20SPlusV30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M21V10
-
-::: pyasic.miners.btc.whatsminer.btminer.M2X.M21.BTMinerM21V10
+## M21 V10
+::: pyasic.miners.whatsminer.btminer.M2X.M21.BTMinerM21V10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M21SV20
-
-::: pyasic.miners.btc.whatsminer.btminer.M2X.M21S.BTMinerM21SV20
+## M21S V20
+::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M21SV60
-
-::: pyasic.miners.btc.whatsminer.btminer.M2X.M21S.BTMinerM21SV60
+## M21S V60
+::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M21SV70
-
-::: pyasic.miners.btc.whatsminer.btminer.M2X.M21S.BTMinerM21SV70
+## M21S V70
+::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV70
handler: python
options:
show_root_heading: false
heading_level: 4
-## M21S+V20
-
-::: pyasic.miners.btc.whatsminer.btminer.M2X.M21S_Plus.BTMinerM21SPlusV20
+## M21S+ V20
+::: pyasic.miners.whatsminer.btminer.M2X.M21S_Plus.BTMinerM21SPlusV20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M29V10
-
-::: pyasic.miners.btc.whatsminer.btminer.M2X.M29.BTMinerM29V10
+## M29 V10
+::: pyasic.miners.whatsminer.btminer.M2X.M29.BTMinerM29V10
handler: python
options:
show_root_heading: false
heading_level: 4
+
diff --git a/docs/miners/whatsminer/M3X.md b/docs/miners/whatsminer/M3X.md
index 8be43bc9..6b2415d4 100644
--- a/docs/miners/whatsminer/M3X.md
+++ b/docs/miners/whatsminer/M3X.md
@@ -1,1098 +1,955 @@
# pyasic
## M3X Models
-## M30V10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30.BTMinerM30V10
+## M30 V10
+::: pyasic.miners.whatsminer.btminer.M3X.M30.BTMinerM30V10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30V20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30.BTMinerM30V20
+## M30 V20
+::: pyasic.miners.whatsminer.btminer.M3X.M30.BTMinerM30V20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SV10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SV10
+## M30S V10
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SV10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SV20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SV20
+## M30S V20
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SV20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SV30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SV30
+## M30S V30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SV30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SV40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SV40
+## M30S V40
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SV40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SV50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SV50
+## M30S V50
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SV50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SV60
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SV60
+## M30S V60
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SV60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SV70
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SV70
+## M30S V70
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SV70
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SV80
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SV80
+## M30S V80
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SV80
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVE10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVE10
+## M30S VE10
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVE10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVE20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVE20
+## M30S VE20
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVE20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVE30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVE30
+## M30S VE30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVE30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVE40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVE40
+## M30S VE40
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVE40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVE50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVE50
+## M30S VE50
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVE50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVE60
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVE60
+## M30S VE60
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVE60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVE70
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVE70
+## M30S VE70
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVE70
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVF10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVF10
+## M30S VF10
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVF10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVF20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVF20
+## M30S VF20
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVF20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVF30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVF30
+## M30S VF30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVF30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVG10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVG10
+## M30S VG10
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVG10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVG20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVG20
+## M30S VG20
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVG20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVG30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVG30
+## M30S VG30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVG30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVG40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVG40
+## M30S VG40
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVG40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVH10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVH10
+## M30S VH10
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVH10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVH20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVH20
+## M30S VH20
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVH20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVH30
+## M30S VH30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVH30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVH40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVH40
+## M30S VH40
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVH40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVH50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVH50
+## M30S VH50
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVH50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVH60
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVH60
+## M30S VH60
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVH60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30SVI20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S.BTMinerM30SVI20
+## M30S VI20
+::: pyasic.miners.whatsminer.btminer.M3X.M30S.BTMinerM30SVI20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+V10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV10
+## M30S+ V10
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+V20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV20
+## M30S+ V20
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+V30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV30
+## M30S+ V30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+V40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV40
+## M30S+ V40
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+V50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV50
+## M30S+ V50
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+V60
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV60
+## M30S+ V60
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+V70
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV70
+## M30S+ V70
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV70
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+V80
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV80
+## M30S+ V80
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV80
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+V90
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV90
+## M30S+ V90
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV90
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+V100
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV100
+## M30S+ V100
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusV100
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VE30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE30
+## M30S+ VE30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VE40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE40
+## M30S+ VE40
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VE50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE50
+## M30S+ VE50
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VE60
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE60
+## M30S+ VE60
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VE70
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE70
+## M30S+ VE70
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE70
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VE80
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE80
+## M30S+ VE80
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE80
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VE90
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE90
+## M30S+ VE90
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE90
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VE100
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE100
+## M30S+ VE100
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVE100
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VF20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVF20
+## M30S+ VF20
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVF20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VF30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVF30
+## M30S+ VF30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVF30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M36S+VG30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM36SPlusVG30
+## M30S+ VG30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVG30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VG30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVG30
+## M30S+ VG40
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVG40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VG40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVG40
+## M30S+ VG50
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVG50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VG50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVG50
+## M30S+ VG60
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVG60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VG60
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVG60
+## M30S+ VH10
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVH10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VH10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVH10
+## M30S+ VH20
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVH20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VH20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVH20
+## M30S+ VH30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVH30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVH30
+## M30S+ VH40
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVH40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VH40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVH40
+## M30S+ VH50
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVH50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VH50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVH50
+## M30S+ VH60
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVH60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S+VH60
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus.BTMinerM30SPlusVH60
+## M30S++ V10
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusV10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++V10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusV10
+## M30S++ V20
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusV20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++V20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusV20
+## M30S++ VE30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVE30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VE30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVE30
+## M30S++ VE40
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVE40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VE40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVE40
+## M30S++ VE50
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVE50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VE50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVE50
+## M30S++ VF40
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVF40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VF40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVF40
+## M30S++ VG30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVG30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VG30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVG30
+## M30S++ VG40
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVG40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VG40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVG40
+## M30S++ VG50
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVG50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VG50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVG50
+## M30S++ VH10
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VH10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH10
+## M30S++ VH20
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VH20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH20
+## M30S++ VH30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH30
+## M30S++ VH40
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VH40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH40
+## M30S++ VH50
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VH50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH50
+## M30S++ VH60
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VH60
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH60
+## M30S++ VH70
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH70
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VH70
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH70
+## M30S++ VH80
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH80
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VH80
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH80
+## M30S++ VH90
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH90
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VH90
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH90
+## M30S++ VH100
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH100
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VH100
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVH100
+## M30S++ VJ20
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVJ20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VJ20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVJ20
+## M30S++ VJ30
+::: pyasic.miners.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVJ30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M30S++VJ30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M30S_Plus_Plus.BTMinerM30SPlusPlusVJ30
+## M31 V10
+::: pyasic.miners.whatsminer.btminer.M3X.M31.BTMinerM31V10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31V10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31.BTMinerM31V10
+## M31 V20
+::: pyasic.miners.whatsminer.btminer.M3X.M31.BTMinerM31V20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31V20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31.BTMinerM31V20
+## M31S V10
+::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SV10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S.BTMinerM31SV10
+## M31S V20
+::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SV20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S.BTMinerM31SV20
+## M31S V30
+::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SV30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S.BTMinerM31SV30
+## M31S V40
+::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SV40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S.BTMinerM31SV40
+## M31S V50
+::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SV50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S.BTMinerM31SV50
+## M31S V60
+::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SV60
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S.BTMinerM31SV60
+## M31S V70
+::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV70
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SV70
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S.BTMinerM31SV70
+## M31S V80
+::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV80
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SV80
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S.BTMinerM31SV80
+## M31S V90
+::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SV90
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SV90
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S.BTMinerM31SV90
+## M31S VE10
+::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SVE10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SVE10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S.BTMinerM31SVE10
+## M31S VE20
+::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SVE20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SVE20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S.BTMinerM31SVE20
+## M31S VE30
+::: pyasic.miners.whatsminer.btminer.M3X.M31S.BTMinerM31SVE30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SVE30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S.BTMinerM31SVE30
+## M31SE V10
+::: pyasic.miners.whatsminer.btminer.M3X.M31SE.BTMinerM31SEV10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SEV10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31SE.BTMinerM31SEV10
+## M31SE V20
+::: pyasic.miners.whatsminer.btminer.M3X.M31SE.BTMinerM31SEV20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SEV20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31SE.BTMinerM31SEV20
+## M31SE V30
+::: pyasic.miners.whatsminer.btminer.M3X.M31SE.BTMinerM31SEV30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31SEV30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31SE.BTMinerM31SEV30
+## M31H V40
+::: pyasic.miners.whatsminer.btminer.M3X.M31H.BTMinerM31HV40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31HV40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31H.BTMinerM31HV40
+## M31S+ V10
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+V10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV10
+## M31S+ V20
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+V20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV20
+## M31S+ V30
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+V30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV30
+## M31S+ V40
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+V40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV40
+## M31S+ V50
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+V50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV50
+## M31S+ V60
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+V60
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV60
+## M31S+ V80
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV80
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+V80
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV80
+## M31S+ V90
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV90
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+V90
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV90
+## M31S+ V100
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV100
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+V100
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusV100
+## M31S+ VE10
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+VE10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE10
+## M31S+ VE20
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+VE20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE20
+## M31S+ VE30
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+VE30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE30
+## M31S+ VE40
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+VE40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE40
+## M31S+ VE50
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+VE50
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE50
+## M31S+ VE60
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+VE60
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE60
+## M31S+ VE80
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE80
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+VE80
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVE80
+## M31S+ VF20
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVF20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+VF20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVF20
+## M31S+ VF30
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVF30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+VF30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVF30
+## M31S+ VG20
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVG20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+VG20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVG20
+## M31S+ VG30
+::: pyasic.miners.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVG30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M31S+VG30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M31S_Plus.BTMinerM31SPlusVG30
+## M32 V10
+::: pyasic.miners.whatsminer.btminer.M3X.M32.BTMinerM32V10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M32V10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M32.BTMinerM32V10
+## M32 V20
+::: pyasic.miners.whatsminer.btminer.M3X.M32.BTMinerM32V20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M32V20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M32.BTMinerM32V20
+## M33 V10
+::: pyasic.miners.whatsminer.btminer.M3X.M33.BTMinerM33V10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M33V10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M33.BTMinerM33V10
+## M33 V20
+::: pyasic.miners.whatsminer.btminer.M3X.M33.BTMinerM33V20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M33V20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M33.BTMinerM33V20
+## M33 V30
+::: pyasic.miners.whatsminer.btminer.M3X.M33.BTMinerM33V30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M33V30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M33.BTMinerM33V30
+## M33S VG30
+::: pyasic.miners.whatsminer.btminer.M3X.M33S.BTMinerM33SVG30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M33SVG30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M33S.BTMinerM33SVG30
+## M33S+ VH20
+::: pyasic.miners.whatsminer.btminer.M3X.M33S_Plus.BTMinerM33SPlusVH20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M33S+VH20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M33S_Plus.BTMinerM33SPlusVH20
+## M33S+ VH30
+::: pyasic.miners.whatsminer.btminer.M3X.M33S_Plus.BTMinerM33SPlusVH30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M33S+VH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M33S_Plus.BTMinerM33SPlusVH30
+## M33S++ VH20
+::: pyasic.miners.whatsminer.btminer.M3X.M33S_Plus_Plus.BTMinerM33SPlusPlusVH20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M33S++VH20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M33S_Plus_Plus.BTMinerM33SPlusPlusVH20
+## M33S++ VH30
+::: pyasic.miners.whatsminer.btminer.M3X.M33S_Plus_Plus.BTMinerM33SPlusPlusVH30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M33S++VH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M33S_Plus_Plus.BTMinerM33SPlusPlusVH30
+## M33S++ VG40
+::: pyasic.miners.whatsminer.btminer.M3X.M33S_Plus_Plus.BTMinerM33SPlusPlusVG40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M33S++VG40
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M33S_Plus_Plus.BTMinerM33SPlusPlusVG40
+## M34S+ VE10
+::: pyasic.miners.whatsminer.btminer.M3X.M34S_Plus.BTMinerM34SPlusVE10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M34S+VE10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M34S_Plus.BTMinerM34SPlusVE10
+## M36S VE10
+::: pyasic.miners.whatsminer.btminer.M3X.M36S.BTMinerM36SVE10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M36SVE10
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M36S.BTMinerM36SVE10
+## M36S+ VG30
+::: pyasic.miners.whatsminer.btminer.M3X.M36S_Plus.BTMinerM36SPlusVG30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M36S+VG30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M36S_Plus.BTMinerM36SPlusVG30
+## M36S++ VH30
+::: pyasic.miners.whatsminer.btminer.M3X.M36S_Plus_Plus.BTMinerM36SPlusPlusVH30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M36S++VH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M36S_Plus_Plus.BTMinerM36SPlusPlusVH30
+## M39 V20
+::: pyasic.miners.whatsminer.btminer.M3X.M39.BTMinerM39V20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M39V20
-
-::: pyasic.miners.btc.whatsminer.btminer.M3X.M39.BTMinerM39V20
- handler: python
- options:
- show_root_heading: false
- heading_level: 4
diff --git a/docs/miners/whatsminer/M5X.md b/docs/miners/whatsminer/M5X.md
index f61f346c..238bdefc 100644
--- a/docs/miners/whatsminer/M5X.md
+++ b/docs/miners/whatsminer/M5X.md
@@ -1,242 +1,241 @@
# pyasic
## M5X Models
-## M50VG30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VG30
+## M50 VG30
+::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VG30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50VH10
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH10
+## M50 VH10
+::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50VH20
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH20
+## M50 VH20
+::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50VH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH30
+## M50 VH30
+::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50VH40
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH40
+## M50 VH40
+::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50VH50
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH50
+## M50 VH50
+::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50VH60
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH60
+## M50 VH60
+::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH60
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50VH70
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH70
+## M50 VH70
+::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH70
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50VH80
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VH80
+## M50 VH80
+::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH80
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50VJ10
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VJ10
+## M50 VJ10
+::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VJ10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50VJ20
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VJ20
+## M50 VJ20
+::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VJ20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50VJ30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50.BTMinerM50VJ30
+## M50 VJ30
+::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VJ30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50SVJ10
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ10
+## M50S VJ10
+::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50SVJ20
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ20
+## M50S VJ20
+::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50SVJ30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ30
+## M50S VJ30
+::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50SVH10
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVH10
+## M50S VH10
+::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50SVH20
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVH20
+## M50S VH20
+::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50SVH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVH30
+## M50S VH30
+::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50SVH40
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVH40
+## M50S VH40
+::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50SVH50
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S.BTMinerM50SVH50
+## M50S VH50
+::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH50
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50S+VH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVH30
+## M50S+ VH30
+::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVH30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50S+VH40
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVH40
+## M50S+ VH40
+::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVH40
handler: python
options:
show_root_heading: false
heading_level: 4
-## M50S+VJ30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVJ30
+## M50S+ VJ30
+::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVJ30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M53VH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M53.BTMinerM53VH30
+## M50S+ VK20
+::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVK20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M53SVH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M53S.BTMinerM53SVH30
+## M50S++ VK10
+::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus_Plus.BTMinerM50SPlusPlusVK10
handler: python
options:
show_root_heading: false
heading_level: 4
-## M53S+VJ30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M53S_Plus.BTMinerM53SPlusVJ30
+## M50S++ VK20
+::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus_Plus.BTMinerM50SPlusPlusVK20
handler: python
options:
show_root_heading: false
heading_level: 4
-## M56VH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M56.BTMinerM56VH30
+## M50S++ VK30
+::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus_Plus.BTMinerM50SPlusPlusVK30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M56SVH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M56S.BTMinerM56SVH30
+## M53 VH30
+::: pyasic.miners.whatsminer.btminer.M5X.M53.BTMinerM53VH30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M56S+VJ30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M56S_Plus.BTMinerM56SPlusVJ30
+## M53S VH30
+::: pyasic.miners.whatsminer.btminer.M5X.M53S.BTMinerM53SVH30
handler: python
options:
show_root_heading: false
heading_level: 4
-## M59VH30
-
-::: pyasic.miners.btc.whatsminer.btminer.M5X.M59.BTMinerM59VH30
+## M53S+ VJ30
+::: pyasic.miners.whatsminer.btminer.M5X.M53S_Plus.BTMinerM53SPlusVJ30
handler: python
options:
show_root_heading: false
heading_level: 4
+
+## M56 VH30
+::: pyasic.miners.whatsminer.btminer.M5X.M56.BTMinerM56VH30
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## M56S VH30
+::: pyasic.miners.whatsminer.btminer.M5X.M56S.BTMinerM56SVH30
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## M56S+ VJ30
+::: pyasic.miners.whatsminer.btminer.M5X.M56S_Plus.BTMinerM56SPlusVJ30
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
+## M59 VH30
+::: pyasic.miners.whatsminer.btminer.M5X.M59.BTMinerM59VH30
+ handler: python
+ options:
+ show_root_heading: false
+ heading_level: 4
+
diff --git a/pyasic/data/__init__.py b/pyasic/data/__init__.py
index 70fcaab0..12f8eec0 100644
--- a/pyasic/data/__init__.py
+++ b/pyasic/data/__init__.py
@@ -66,34 +66,22 @@ class MinerData:
Attributes:
ip: The IP of the miner as a str.
datetime: The time and date this data was generated.
+ mac: The MAC address of the miner as a str.
model: The model of the miner as a str.
make: The make of the miner as a str.
api_ver: The current api version on the miner as a str.
fw_ver: The current firmware version on the miner as a str.
hostname: The network hostname of the miner as a str.
- hashrate: The hashrate of the miner in TH/s as a float.
+ hashrate: The hashrate of the miner in TH/s as a float. Calculated automatically.
+ _hashrate: Backup for hashrate found via API instead of hashboards.
nominal_hashrate: The factory nominal hashrate of the miner in TH/s as a float.
- left_board_hashrate: The hashrate of the left board of the miner in TH/s as a float.
- center_board_hashrate: The hashrate of the center board of the miner in TH/s as a float.
- right_board_hashrate: The hashrate of the right board of the miner in TH/s as a float.
+ hashboards: A list of hashboards on the miner with their statistics.
temperature_avg: The average temperature across the boards. Calculated automatically.
env_temp: The environment temps as a float.
- left_board_temp: The temp of the left PCB as an int.
- left_board_chip_temp: The temp of the left board chips as an int.
- center_board_temp: The temp of the center PCB as an int.
- center_board_chip_temp: The temp of the center board chips as an int.
- right_board_temp: The temp of the right PCB as an int.
- right_board_chip_temp: The temp of the right board chips as an int.
wattage: Current power draw of the miner as an int.
wattage_limit: Power limit of the miner as an int.
- fan_1: The speed of the first fan as an int.
- fan_2: The speed of the second fan as an int.
- fan_3: The speed of the third fan as an int.
- fan_4: The speed of the fourth fan as an int.
+ fans: A list of fans on the miner with their speeds.
fan_psu: The speed of the PSU on the fan if the miner collects it.
- left_chips: The number of chips online in the left board as an int.
- center_chips: The number of chips online in the left board as an int.
- right_chips: The number of chips online in the left board as an int.
total_chips: The total number of chips on all boards. Calculated automatically.
ideal_chips: The ideal number of chips in the miner as an int.
percent_ideal_chips: The percent of total chips out of the ideal count. Calculated automatically.
@@ -106,7 +94,7 @@ class MinerData:
pool_2_url: The second pool url on the miner as a str.
pool_2_user: The second pool user on the miner as a str.
errors: A list of errors on the miner.
- fault_light: Whether or not the fault light is on as a boolean.
+ fault_light: Whether the fault light is on as a boolean.
efficiency: Efficiency of the miner in J/TH (Watts per TH/s). Calculated automatically.
"""
@@ -123,34 +111,18 @@ class MinerData:
nominal_hashrate: float = 0
hashboards: List[HashBoard] = field(default_factory=list)
ideal_hashboards: int = 1
- left_board_hashrate: float = field(init=False)
- center_board_hashrate: float = field(init=False)
- right_board_hashrate: float = field(init=False)
temperature_avg: int = field(init=False)
env_temp: float = -1.0
- left_board_temp: int = field(init=False)
- left_board_chip_temp: int = field(init=False)
- center_board_temp: int = field(init=False)
- center_board_chip_temp: int = field(init=False)
- right_board_temp: int = field(init=False)
- right_board_chip_temp: int = field(init=False)
wattage: int = -1
wattage_limit: int = -1
fans: List[Fan] = field(default_factory=list)
- fan_1: int = field(init=False)
- fan_2: int = field(init=False)
- fan_3: int = field(init=False)
- fan_4: int = field(init=False)
fan_psu: int = -1
- left_chips: int = field(init=False)
- center_chips: int = field(init=False)
- right_chips: int = field(init=False)
total_chips: int = field(init=False)
ideal_chips: int = 1
percent_ideal_chips: float = field(init=False)
percent_ideal_hashrate: float = field(init=False)
percent_ideal_wattage: float = field(init=False)
- nominal: int = field(init=False)
+ nominal: bool = field(init=False)
pool_split: str = "0"
pool_1_url: str = "Unknown"
pool_1_user: str = "Unknown"
@@ -228,42 +200,6 @@ class MinerData:
def hashrate(self, val):
self._hashrate = val
- @property
- def fan_1(self): # noqa - Skip PyCharm inspection
- if len(self.fans) > 0:
- return self.fans[0].speed
-
- @fan_1.setter
- def fan_1(self, val):
- pass
-
- @property
- def fan_2(self): # noqa - Skip PyCharm inspection
- if len(self.fans) > 1:
- return self.fans[1].speed
-
- @fan_2.setter
- def fan_2(self, val):
- pass
-
- @property
- def fan_3(self): # noqa - Skip PyCharm inspection
- if len(self.fans) > 2:
- return self.fans[2].speed
-
- @fan_3.setter
- def fan_3(self, val):
- pass
-
- @property
- def fan_4(self): # noqa - Skip PyCharm inspection
- if len(self.fans) > 3:
- return self.fans[3].speed
-
- @fan_4.setter
- def fan_4(self, val):
- pass
-
@property
def total_chips(self): # noqa - Skip PyCharm inspection
return sum([hb.chips for hb in self.hashboards])
@@ -272,151 +208,6 @@ class MinerData:
def total_chips(self, val):
pass
- @property
- def left_chips(self): # noqa - Skip PyCharm inspection
- if len(self.hashboards) in [2, 3, 4]:
- return self.hashboards[0].chips
-
- return 0
-
- @left_chips.setter
- def left_chips(self, val):
- pass
-
- @property
- def center_chips(self): # noqa - Skip PyCharm inspection
- if len(self.hashboards) == 1:
- return self.hashboards[0].chips
- if len(self.hashboards) in [2, 3, 4]:
- return self.hashboards[1].chips
- return 0
-
- @center_chips.setter
- def center_chips(self, val):
- pass
-
- @property
- def right_chips(self): # noqa - Skip PyCharm inspection
- if len(self.hashboards) == 2:
- return self.hashboards[1].chips
- if len(self.hashboards) == 3:
- return self.hashboards[2].chips
- if len(self.hashboards) > 3:
- return self.hashboards[-1:][0].chips
- return 0
-
- @right_chips.setter
- def right_chips(self, val):
- pass
-
- @property
- def left_board_hashrate(self): # noqa - Skip PyCharm inspection
- if len(self.hashboards) in [2, 3, 4]:
- return self.hashboards[0].hashrate
- return 0
-
- @left_board_hashrate.setter
- def left_board_hashrate(self, val):
- pass
-
- @property
- def center_board_hashrate(self): # noqa - Skip PyCharm inspection
- if len(self.hashboards) == 1:
- return self.hashboards[0].hashrate
- if len(self.hashboards) in [2, 3, 4]:
- return self.hashboards[1].hashrate
- return 0
-
- @center_board_hashrate.setter
- def center_board_hashrate(self, val):
- pass
-
- @property
- def right_board_hashrate(self): # noqa - Skip PyCharm inspection
- if len(self.hashboards) == 2:
- return self.hashboards[1].hashrate
- if len(self.hashboards) == 3:
- return self.hashboards[2].hashrate
- if len(self.hashboards) > 3:
- return self.hashboards[-1:][0].hashrate
- return 0
-
- @right_board_hashrate.setter
- def right_board_hashrate(self, val):
- pass
-
- @property
- def left_board_temp(self): # noqa - Skip PyCharm inspection
- if len(self.hashboards) in [2, 3, 4]:
- return self.hashboards[0].temp
- return 0
-
- @left_board_temp.setter
- def left_board_temp(self, val):
- pass
-
- @property
- def center_board_temp(self): # noqa - Skip PyCharm inspection
- if len(self.hashboards) == 1:
- return self.hashboards[0].temp
- if len(self.hashboards) in [2, 3, 4]:
- return self.hashboards[1].temp
- return 0
-
- @center_board_temp.setter
- def center_board_temp(self, val):
- pass
-
- @property
- def right_board_temp(self): # noqa - Skip PyCharm inspection
- if len(self.hashboards) == 2:
- return self.hashboards[1].temp
- if len(self.hashboards) == 3:
- return self.hashboards[2].temp
- if len(self.hashboards) > 3:
- return self.hashboards[-1:][0].temp
- return 0
-
- @right_board_temp.setter
- def right_board_temp(self, val):
- pass
-
- @property
- def left_board_chip_temp(self): # noqa - Skip PyCharm inspection
- if len(self.hashboards) in [2, 3, 4]:
- return self.hashboards[0].chip_temp
- return 0
-
- @left_board_chip_temp.setter
- def left_board_chip_temp(self, val):
- pass
-
- @property
- def center_board_chip_temp(self): # noqa - Skip PyCharm inspection
- if len(self.hashboards) == 1:
- return self.hashboards[0].chip_temp
- if len(self.hashboards) in [2, 3, 4]:
- return self.hashboards[1].chip_temp
- return 0
-
- @center_board_chip_temp.setter
- def center_board_chip_temp(self, val):
- pass
-
- @property
- def right_board_chip_temp(self): # noqa - Skip PyCharm inspection
- if len(self.hashboards) == 2:
- return self.hashboards[1].chip_temp
- if len(self.hashboards) == 3:
- return self.hashboards[2].chip_temp
- if len(self.hashboards) > 3:
- return self.hashboards[-1:][0].chip_temp
- return 0
-
- @right_board_chip_temp.setter
- def right_board_chip_temp(self, val):
- pass
-
@property
def nominal(self): # noqa - Skip PyCharm inspection
return self.ideal_chips == self.total_chips
@@ -536,24 +327,40 @@ class MinerData:
escaped_data = self[attribute].replace(" ", "\\ ")
tag_data.append(f"{attribute}={escaped_data}")
continue
- if isinstance(self[attribute], str):
+ elif str(attribute).startswith("_"):
+ continue
+ elif isinstance(self[attribute], str):
field_data.append(f'{attribute}="{self[attribute]}"')
continue
- if isinstance(self[attribute], bool):
+ elif isinstance(self[attribute], bool):
field_data.append(f"{attribute}={str(self[attribute]).lower()}")
continue
- if isinstance(self[attribute], int):
+ elif isinstance(self[attribute], int):
field_data.append(f"{attribute}={self[attribute]}")
continue
- if isinstance(self[attribute], float):
+ elif isinstance(self[attribute], float):
field_data.append(f"{attribute}={self[attribute]}")
continue
- if attribute == "fault_light" and not self[attribute]:
+ elif attribute == "fault_light" and not self[attribute]:
field_data.append(f"{attribute}=false")
continue
- if attribute == "errors":
+ elif attribute == "errors":
for idx, item in enumerate(self[attribute]):
field_data.append(f'error_{idx+1}="{item.error_message}"')
+ elif attribute == "hashboards":
+ for idx, item in enumerate(self[attribute]):
+ field_data.append(f"hashboard_{idx+1}_hashrate={item.hashrate}")
+ field_data.append(f"hashboard_{idx+1}_temperature={item.temp}")
+ field_data.append(
+ f"hashboard_{idx+1}_chip_temperature={item.chip_temp}"
+ )
+ field_data.append(f"hashboard_{idx+1}_chips={item.chips}")
+ field_data.append(
+ f"hashboard_{idx+1}_expected_chips={item.expected_chips}"
+ )
+ elif attribute == "fans":
+ for idx, item in enumerate(self[attribute]):
+ field_data.append(f"fan_{idx+1}={item.speed}")
tags_str = ",".join(tag_data)
field_str = ",".join(field_data)
diff --git a/pyasic/miners/antminer/vnish/X17/S17.py b/pyasic/miners/antminer/vnish/X17/S17.py
new file mode 100644
index 00000000..36529f6a
--- /dev/null
+++ b/pyasic/miners/antminer/vnish/X17/S17.py
@@ -0,0 +1,25 @@
+# ------------------------------------------------------------------------------
+# 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.types import S17Plus, S17Pro
+
+
+class VNishS17Plus(VNish, S17Plus):
+ pass
+
+
+class VNishS17Pro(VNish, S17Pro):
+ pass
diff --git a/pyasic/miners/antminer/vnish/X17/__init__.py b/pyasic/miners/antminer/vnish/X17/__init__.py
new file mode 100644
index 00000000..68430b81
--- /dev/null
+++ b/pyasic/miners/antminer/vnish/X17/__init__.py
@@ -0,0 +1,16 @@
+# ------------------------------------------------------------------------------
+# 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 .S17 import VNishS17Plus, VNishS17Pro
diff --git a/pyasic/miners/antminer/vnish/__init__.py b/pyasic/miners/antminer/vnish/__init__.py
index 1a3d7d49..0b4464e9 100644
--- a/pyasic/miners/antminer/vnish/__init__.py
+++ b/pyasic/miners/antminer/vnish/__init__.py
@@ -15,4 +15,5 @@
# ------------------------------------------------------------------------------
from .X3 import *
+from .X17 import *
from .X19 import *
diff --git a/pyasic/miners/backends/antminer.py b/pyasic/miners/backends/antminer.py
index 059b5f0b..ae5a2865 100644
--- a/pyasic/miners/backends/antminer.py
+++ b/pyasic/miners/backends/antminer.py
@@ -353,7 +353,7 @@ class AntminerOld(CGMiner):
except APIError:
pass
- fans_data = [Fan(), Fan(), Fan(), Fan()]
+ fans_data = [Fan() for _ in range(self.fan_count)]
if api_stats:
try:
fan_offset = -1
@@ -367,8 +367,8 @@ class AntminerOld(CGMiner):
fan_offset = 3
for fan in range(self.fan_count):
- fans_data[fan] = Fan(
- api_stats["STATS"][1].get(f"fan{fan_offset+fan}")
+ fans_data[fan].speed = api_stats["STATS"][1].get(
+ f"fan{fan_offset+fan}", 0
)
except (KeyError, IndexError):
pass
diff --git a/pyasic/miners/backends/bfgminer.py b/pyasic/miners/backends/bfgminer.py
index 92468f26..cd605f7c 100644
--- a/pyasic/miners/backends/bfgminer.py
+++ b/pyasic/miners/backends/bfgminer.py
@@ -247,14 +247,16 @@ class BFGMiner(BaseMiner):
for fan_num in range(0, 8, 4):
for _f_num in range(4):
- f = api_stats["STATS"][1].get(f"fan{fan_num + _f_num}")
- if f and not f == 0 and fan_offset == -1:
+ f = api_stats["STATS"][1].get(f"fan{fan_num + _f_num}", 0)
+ if not f == 0 and fan_offset == -1:
fan_offset = fan_num
if fan_offset == -1:
fan_offset = 1
for fan in range(self.fan_count):
- fans_data[fan] = api_stats["STATS"][1].get(f"fan{fan_offset+fan}")
+ fans_data[fan] = api_stats["STATS"][1].get(
+ f"fan{fan_offset+fan}", 0
+ )
except (KeyError, IndexError):
pass
fans = [Fan(speed=d) if d else Fan() for d in fans_data]
diff --git a/pyasic/miners/backends/bmminer.py b/pyasic/miners/backends/bmminer.py
index 2ab1c25b..ce47e544 100644
--- a/pyasic/miners/backends/bmminer.py
+++ b/pyasic/miners/backends/bmminer.py
@@ -275,24 +275,25 @@ class BMMiner(BaseMiner):
except APIError:
pass
- fans_data = [None, None, None, None]
+ fans = [Fan() for _ in range(self.fan_count)]
if api_stats:
try:
fan_offset = -1
for fan_num in range(1, 8, 4):
for _f_num in range(4):
- f = api_stats["STATS"][1].get(f"fan{fan_num + _f_num}")
+ f = api_stats["STATS"][1].get(f"fan{fan_num + _f_num}", 0)
if f and not f == 0 and fan_offset == -1:
fan_offset = fan_num
if fan_offset == -1:
fan_offset = 1
for fan in range(self.fan_count):
- fans_data[fan] = api_stats["STATS"][1].get(f"fan{fan_offset+fan}")
+ fans[fan].speed = api_stats["STATS"][1].get(
+ f"fan{fan_offset+fan}", 0
+ )
except (KeyError, IndexError):
pass
- fans = [Fan(speed=d) if d else Fan() for d in fans_data]
return fans
diff --git a/pyasic/miners/backends/bosminer.py b/pyasic/miners/backends/bosminer.py
index e502a195..50dce80c 100644
--- a/pyasic/miners/backends/bosminer.py
+++ b/pyasic/miners/backends/bosminer.py
@@ -155,7 +155,7 @@ BOSMINER_DATA_LOC = {
"config": {
"... on BosminerConfig": {
"groups": {
- "pools": {"urluser": None},
+ "pools": {"url": None, "user": None},
"strategy": {
"... on QuotaStrategy": {"quota": None}
},
@@ -414,7 +414,7 @@ class BOSMiner(BaseMiner):
if graphql_version:
try:
- fw_ver = graphql_version["bos"]["info"]["version"]["full"]
+ fw_ver = graphql_version["data"]["bos"]["info"]["version"]["full"]
except KeyError:
pass
@@ -442,7 +442,7 @@ class BOSMiner(BaseMiner):
if graphql_hostname:
try:
- hostname = graphql_hostname["bos"]["hostname"]
+ hostname = graphql_hostname["data"]["bos"]["hostname"]
return hostname
except KeyError:
pass
@@ -477,7 +477,7 @@ class BOSMiner(BaseMiner):
try:
return round(
float(
- graphql_hashrate["bosminer"]["info"]["workSolver"][
+ graphql_hashrate["data"]["bosminer"]["info"]["workSolver"][
"realHashrate"
]["mhs1M"]
/ 1000000
@@ -535,14 +535,19 @@ class BOSMiner(BaseMiner):
if graphql_boards:
try:
- boards = graphql_boards["bosminer"]["info"]["workSolver"][
+ boards = graphql_boards["data"]["bosminer"]["info"]["workSolver"][
"childSolvers"
]
except (KeyError, IndexError):
boards = None
if boards:
- offset = 6 if int(boards[0]["name"]) in [6, 7, 8] else 0
+ b_names = [int(b["name"]) for b in boards]
+ offset = 0
+ if 3 in b_names:
+ offset = 1
+ elif 6 in b_names:
+ offset = 6
for hb in boards:
_id = int(hb["name"]) - offset
board = hashboards[_id]
@@ -643,13 +648,12 @@ class BOSMiner(BaseMiner):
)
except APIError:
pass
-
- if graphql_wattage:
+ if graphql_wattage is not None:
try:
- return graphql_wattage["bosminer"]["info"]["workSolver"]["power"][
- "approxConsumptionW"
- ]
- except KeyError:
+ return graphql_wattage["data"]["bosminer"]["info"]["workSolver"][
+ "power"
+ ]["approxConsumptionW"]
+ except (KeyError, TypeError):
pass
if not api_tunerstatus:
@@ -679,10 +683,10 @@ class BOSMiner(BaseMiner):
if graphql_wattage_limit:
try:
- return graphql_wattage_limit["bosminer"]["info"]["workSolver"]["power"][
- "limitW"
- ]
- except KeyError:
+ return graphql_wattage_limit["data"]["bosminer"]["info"]["workSolver"][
+ "power"
+ ]["limitW"]
+ except (KeyError, TypeError):
pass
if not api_tunerstatus:
@@ -707,17 +711,20 @@ class BOSMiner(BaseMiner):
)
except APIError:
pass
-
if graphql_fans:
- fans = {"fan_1": Fan(), "fan_2": Fan(), "fan_3": Fan(), "fan_4": Fan()}
+ fans = []
for n in range(self.fan_count):
try:
- fans[f"fan_{n + 1}"].speed = graphql_fans["bosminer"]["info"][
- "fans"
- ][n]["rpm"]
+ fans.append(
+ Fan(
+ speed=graphql_fans["data"]["bosminer"]["info"]["fans"][n][
+ "rpm"
+ ]
+ )
+ )
except KeyError:
pass
- return [fans["fan_1"], fans["fan_2"], fans["fan_3"], fans["fan_4"]]
+ return fans
if not api_fans:
try:
@@ -726,14 +733,14 @@ class BOSMiner(BaseMiner):
pass
if api_fans:
- fans = {"fan_1": Fan(), "fan_2": Fan(), "fan_3": Fan(), "fan_4": Fan()}
+ fans = []
for n in range(self.fan_count):
try:
- fans[f"fan_{n + 1}"].speed = api_fans["FANS"][n]["RPM"]
+ fans.append(Fan(api_fans["FANS"][n]["RPM"]))
except (IndexError, KeyError):
pass
- return [fans["fan_1"], fans["fan_2"], fans["fan_3"], fans["fan_4"]]
- return [Fan(), Fan(), Fan(), Fan()]
+ return fans
+ return [Fan() for _ in range(self.fan_count)]
async def get_fan_psu(self) -> Optional[int]:
return None
@@ -763,7 +770,7 @@ class BOSMiner(BaseMiner):
if graphql_pools:
groups = []
try:
- g = graphql_pools["bosminer"]["config"]["groups"]
+ g = graphql_pools["data"]["bosminer"]["config"]["groups"]
for group in g:
pools = {"quota": group["strategy"]["quota"]}
for i, pool in enumerate(group["pools"]):
@@ -775,7 +782,7 @@ class BOSMiner(BaseMiner):
pools[f"pool_{i + 1}_user"] = pool["user"]
groups.append(pools)
return groups
- except KeyError:
+ except (KeyError, TypeError):
pass
if not api_pools:
@@ -852,7 +859,7 @@ class BOSMiner(BaseMiner):
if graphql_errors:
errors = []
try:
- boards = graphql_errors["bosminer"]["info"]["workSolver"][
+ boards = graphql_errors["data"]["bosminer"]["info"]["workSolver"][
"childSolvers"
]
except (KeyError, IndexError):
@@ -946,7 +953,7 @@ class BOSMiner(BaseMiner):
# get light through GraphQL
if graphql_fault_light:
try:
- self.light = graphql_fault_light["bos"]["faultLight"]
+ self.light = graphql_fault_light["data"]["bos"]["faultLight"]
return self.light
except (TypeError, KeyError, ValueError, IndexError):
pass
diff --git a/pyasic/miners/backends/btminer.py b/pyasic/miners/backends/btminer.py
index cc005f7e..73ba9c49 100644
--- a/pyasic/miners/backends/btminer.py
+++ b/pyasic/miners/backends/btminer.py
@@ -463,15 +463,13 @@ class BTMiner(BaseMiner):
except APIError:
pass
- fans = [Fan(), Fan(), Fan(), Fan()]
+ fans = [Fan() for _ in range(self.fan_count)]
if api_summary:
try:
if self.fan_count > 0:
fans = [
- Fan(api_summary["SUMMARY"][0]["Fan Speed In"]),
- Fan(api_summary["SUMMARY"][0]["Fan Speed Out"]),
- Fan(),
- Fan(),
+ Fan(api_summary["SUMMARY"][0].get("Fan Speed In", 0)),
+ Fan(api_summary["SUMMARY"][0].get("Fan Speed Out", 0)),
]
except (KeyError, IndexError):
pass
diff --git a/pyasic/miners/backends/cgminer.py b/pyasic/miners/backends/cgminer.py
index 3787f630..96b7f2b8 100644
--- a/pyasic/miners/backends/cgminer.py
+++ b/pyasic/miners/backends/cgminer.py
@@ -296,7 +296,7 @@ class CGMiner(BaseMiner):
except APIError:
pass
- fans_data = [Fan(), Fan(), Fan(), Fan()]
+ fans = [Fan() for _ in range(self.fan_count)]
if api_stats:
try:
fan_offset = -1
@@ -310,12 +310,12 @@ class CGMiner(BaseMiner):
fan_offset = 1
for fan in range(self.fan_count):
- fans_data[fan] = Fan(
- api_stats["STATS"][1].get(f"fan{fan_offset+fan}")
+ fans[fan].speed = api_stats["STATS"][1].get(
+ f"fan{fan_offset+fan}", 0
)
except (KeyError, IndexError):
pass
- return fans_data
+ return fans
async def get_fan_psu(self) -> Optional[int]:
return None
diff --git a/pyasic/miners/backends/cgminer_avalon.py b/pyasic/miners/backends/cgminer_avalon.py
index 3bb966d6..c1234fd9 100644
--- a/pyasic/miners/backends/cgminer_avalon.py
+++ b/pyasic/miners/backends/cgminer_avalon.py
@@ -29,20 +29,26 @@ AVALON_DATA_LOC = {
"model": {"cmd": "get_model", "kwargs": {}},
"api_ver": {"cmd": "get_api_ver", "kwargs": {"api_version": {"api": "version"}}},
"fw_ver": {"cmd": "get_fw_ver", "kwargs": {"api_version": {"api": "version"}}},
- "hostname": {"cmd": "get_hostname", "kwargs": {"mac": {"web": "mac"}}},
- "hashrate": {"cmd": "get_hashrate", "kwargs": {"api_summary": {"api": "summary"}}},
+ "hostname": {"cmd": "get_hostname", "kwargs": {"mac": {"api": "version"}}},
+ "hashrate": {"cmd": "get_hashrate", "kwargs": {"api_devs": {"api": "devs"}}},
"nominal_hashrate": {
"cmd": "get_nominal_hashrate",
"kwargs": {"api_stats": {"api": "stats"}},
},
"hashboards": {"cmd": "get_hashboards", "kwargs": {"api_stats": {"api": "stats"}}},
- "env_temp": {"cmd": "get_env_temp", "kwargs": {}},
+ "env_temp": {"cmd": "get_env_temp", "kwargs": {"api_stats": {"api": "stats"}}},
"wattage": {"cmd": "get_wattage", "kwargs": {}},
- "wattage_limit": {"cmd": "get_wattage_limit", "kwargs": {}},
+ "wattage_limit": {
+ "cmd": "get_wattage_limit",
+ "kwargs": {"api_stats": {"api": "stats"}},
+ },
"fans": {"cmd": "get_fans", "kwargs": {"api_stats": {"api": "stats"}}},
"fan_psu": {"cmd": "get_fan_psu", "kwargs": {}},
"errors": {"cmd": "get_errors", "kwargs": {}},
- "fault_light": {"cmd": "get_fault_light", "kwargs": {}},
+ "fault_light": {
+ "cmd": "get_fault_light",
+ "kwargs": {"api_stats": {"api": "stats"}},
+ },
"pools": {"cmd": "get_pools", "kwargs": {"api_pools": {"api": "pools"}}},
}
@@ -115,8 +121,17 @@ class CGMinerAvalon(CGMiner):
data = item.replace("]", "").split("[")
data_list = [i.split(": ") for i in data[1].strip().split(", ")]
data_dict = {}
- for key, val in [tuple(item) for item in data_list]:
- data_dict[key] = val
+ 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 in range(len(item_data)):
+ if idx % 2 == 0 or idx == 0:
+ data_dict[item_data[idx]] = item_data[idx + 1]
+
raw_data = [data[0].strip(), data_dict]
else:
raw_data = [
@@ -168,16 +183,16 @@ class CGMinerAvalon(CGMiner):
if mac:
return f"Avalon{mac.replace(':', '')[-6:]}"
- async def get_hashrate(self, api_summary: dict = None) -> Optional[float]:
- if not api_summary:
+ async def get_hashrate(self, api_devs: dict = None) -> Optional[float]:
+ if not api_devs:
try:
- api_summary = await self.api.summary()
+ api_devs = await self.api.devs()
except APIError:
pass
- if api_summary:
+ if api_devs:
try:
- return round(float(api_summary["SUMMARY"][0]["MHS 1m"] / 1000000), 2)
+ return round(float(api_devs["DEVS"][0]["MHS 1m"] / 1000000), 2)
except (KeyError, IndexError, ValueError, TypeError):
pass
@@ -195,38 +210,87 @@ class CGMinerAvalon(CGMiner):
if api_stats:
try:
- stats_data = api_stats[0].get("STATS")
- if stats_data:
- for key in stats_data[0].keys():
- if key.startswith("MM ID"):
- raw_data = self.parse_stats(stats_data[0][key])
- for board in range(self.ideal_hashboards):
- chip_temp = raw_data.get("MTmax")
- if chip_temp:
- hashboards[board].chip_temp = chip_temp[board]
-
- temp = raw_data.get("MTavg")
- if temp:
- hashboards[board].temp = temp[board]
-
- chips = raw_data.get(f"PVT_T{board}")
- if chips:
- hashboards[board].chips = len(
- [item for item in chips if not item == "0"]
- )
+ unparsed_stats = api_stats["STATS"][0]["MM ID0"]
+ parsed_stats = self.parse_stats(unparsed_stats)
except (IndexError, KeyError, ValueError, TypeError):
- pass
+ return hashboards
+
+ for board in range(self.ideal_hashboards):
+ try:
+ hashboards[board].chip_temp = int(parsed_stats["MTmax"][board])
+ except LookupError:
+ pass
+
+ try:
+ board_hr = parsed_stats["MGHS"][board]
+ hashboards[board].hashrate = round(float(board_hr) / 1000, 2)
+ except LookupError:
+ pass
+
+ try:
+ hashboards[board].temp = int(parsed_stats["MTavg"][board])
+ except LookupError:
+ pass
+
+ try:
+ chip_data = parsed_stats[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_env_temp(self) -> Optional[float]:
- return None
+ async def get_nominal_hashrate(self, api_stats: dict = None) -> Optional[float]:
+ if not api_stats:
+ try:
+ api_stats = await self.api.stats()
+ except APIError:
+ pass
+
+ if api_stats:
+ try:
+ unparsed_stats = api_stats["STATS"][0]["MM ID0"]
+ parsed_stats = self.parse_stats(unparsed_stats)
+ return round(float(parsed_stats["GHSmm"]) / 1000, 2)
+ except (IndexError, KeyError, ValueError, TypeError):
+ pass
+
+ async def get_env_temp(self, api_stats: dict = None) -> Optional[float]:
+ if not api_stats:
+ try:
+ api_stats = await self.api.stats()
+ except APIError:
+ pass
+
+ if api_stats:
+ try:
+ unparsed_stats = api_stats["STATS"][0]["MM ID0"]
+ parsed_stats = self.parse_stats(unparsed_stats)
+ return float(parsed_stats["Temp"])
+ except (IndexError, KeyError, ValueError, TypeError):
+ pass
async def get_wattage(self) -> Optional[int]:
return None
- async def get_wattage_limit(self) -> Optional[int]:
- return None
+ async def get_wattage_limit(self, api_stats: dict = None) -> Optional[int]:
+ if not api_stats:
+ try:
+ api_stats = await self.api.stats()
+ except APIError:
+ pass
+
+ if api_stats:
+ try:
+ unparsed_stats = api_stats["STATS"][0]["MM ID0"]
+ parsed_stats = self.parse_stats(unparsed_stats)
+ return int(parsed_stats["MPO"])
+ except (IndexError, KeyError, ValueError, TypeError):
+ pass
async def get_fans(self, api_stats: dict = None) -> List[Fan]:
if not api_stats:
@@ -235,19 +299,19 @@ class CGMinerAvalon(CGMiner):
except APIError:
pass
- fans_data = [Fan(), Fan(), Fan(), Fan()]
+ fans_data = [Fan() for _ in range(self.fan_count)]
if api_stats:
try:
- stats_data = api_stats[0].get("STATS")
- if stats_data:
- for key in stats_data[0].keys():
- if key.startswith("MM ID"):
- raw_data = self.parse_stats(stats_data[0][key])
- for fan in range(self.fan_count):
- fans_data[fan] = Fan(int(raw_data[f"Fan{fan + 1}"]))
- except (KeyError, IndexError, ValueError, TypeError):
- pass
+ unparsed_stats = api_stats["STATS"][0]["MM ID0"]
+ parsed_stats = self.parse_stats(unparsed_stats)
+ except LookupError:
+ return fans_data
+ for fan in range(self.fan_count):
+ try:
+ fans_data[fan].speed = int(parsed_stats[f"Fan{fan + 1}"])
+ except (IndexError, KeyError, ValueError, TypeError):
+ pass
return fans_data
async def get_pools(self, api_pools: dict = None) -> List[dict]:
@@ -279,13 +343,31 @@ class CGMinerAvalon(CGMiner):
async def get_errors(self) -> List[MinerErrorData]:
return []
- async def get_fault_light(self) -> bool:
+ async def get_fault_light(self, api_stats: dict = None) -> bool: # noqa
if self.light:
return self.light
+ if not api_stats:
+ try:
+ api_stats = await self.api.stats()
+ except APIError:
+ pass
+
+ if api_stats:
+ try:
+ unparsed_stats = api_stats["STATS"][0]["MM ID0"]
+ parsed_stats = self.parse_stats(unparsed_stats)
+ led = int(parsed_stats["Led"])
+ return True if led == 1 else False
+ except (IndexError, KeyError, ValueError, TypeError):
+ pass
+
try:
data = await self.api.ascset(0, "led", "1-255")
except APIError:
return False
- if data["STATUS"][0]["Msg"] == "ASC 0 set info: LED[1]":
- return True
+ try:
+ if data["STATUS"][0]["Msg"] == "ASC 0 set info: LED[1]":
+ return True
+ except LookupError:
+ pass
return False
diff --git a/pyasic/miners/innosilicon/cgminer/A10X/A10X.py b/pyasic/miners/innosilicon/cgminer/A10X/A10X.py
index c4d378a0..837f4028 100644
--- a/pyasic/miners/innosilicon/cgminer/A10X/A10X.py
+++ b/pyasic/miners/innosilicon/cgminer/A10X/A10X.py
@@ -254,7 +254,7 @@ class CGMinerA10X(CGMiner, A10X):
else:
web_get_all = web_get_all["all"]
- fan_data = [Fan(), Fan(), Fan(), Fan()]
+ fans = [Fan() for _ in range(self.fan_count)]
if web_get_all:
try:
spd = web_get_all["fansSpeed"]
@@ -263,9 +263,9 @@ class CGMinerA10X(CGMiner, A10X):
else:
round((int(spd) * 6000) / 100)
for i in range(self.fan_count):
- fan_data[i] = Fan(spd)
+ fans[i].speed = spd
- return fan_data
+ return fans
async def get_pools(self, api_pools: dict = None) -> List[dict]:
groups = []
diff --git a/pyasic/miners/innosilicon/cgminer/T3X/T3H.py b/pyasic/miners/innosilicon/cgminer/T3X/T3H.py
index 0363b2dd..5387b2b3 100644
--- a/pyasic/miners/innosilicon/cgminer/T3X/T3H.py
+++ b/pyasic/miners/innosilicon/cgminer/T3X/T3H.py
@@ -236,7 +236,7 @@ class CGMinerT3HPlus(CGMiner, T3HPlus):
else:
web_get_all = web_get_all["all"]
- fan_data = [Fan(), Fan(), Fan(), Fan()]
+ fans = [Fan() for _ in range(self.fan_count)]
if web_get_all:
try:
spd = web_get_all["fansSpeed"]
@@ -245,9 +245,9 @@ class CGMinerT3HPlus(CGMiner, T3HPlus):
else:
round((int(spd) * 6000) / 100)
for i in range(self.fan_count):
- fan_data[i] = Fan(spd)
+ fans[i].speed = spd
- return fan_data
+ return fans
async def get_pools(self, api_pools: dict = None) -> List[dict]:
groups = []
diff --git a/pyasic/miners/miner_factory.py b/pyasic/miners/miner_factory.py
index 6cd52b63..e9df842c 100644
--- a/pyasic/miners/miner_factory.py
+++ b/pyasic/miners/miner_factory.py
@@ -61,10 +61,10 @@ class MinerTypes(enum.Enum):
MINER_CLASSES = {
MinerTypes.ANTMINER: {
None: BMMiner,
- "ANTMINER DR5": CGMinerDR5,
"ANTMINER D3": CGMinerD3,
"ANTMINER HS3": BMMinerHS3,
"ANTMINER L3+": BMMinerL3Plus,
+ "ANTMINER DR5": CGMinerDR5,
"ANTMINER L7": BMMinerL7,
"ANTMINER E9 PRO": BMMinerE9Pro,
"ANTMINER S9": BMMinerS9,
@@ -322,6 +322,8 @@ MINER_CLASSES = {
MinerTypes.VNISH: {
None: VNish,
"ANTMINER L3+": VnishL3Plus,
+ "ANTMINER S17+": VNishS17Plus,
+ "ANTMINER S17 PRO": VNishS17Pro,
"ANTMINER S19": VNishS19,
"ANTMINER S19 PRO": VNishS19Pro,
"ANTMINER S19J": VNishS19j,
@@ -393,7 +395,9 @@ class MinerFactory:
ip = str(ip)
if ip in self.cache:
return self.cache[ip]
+
miner_type = None
+
for _ in range(RETRIES):
task = asyncio.create_task(self._get_miner_type(ip))
try:
@@ -406,23 +410,18 @@ class MinerFactory:
if miner_type is not None:
miner_model = None
- fn = None
- if miner_type == MinerTypes.ANTMINER:
- fn = self.get_miner_model_antminer
- if miner_type == MinerTypes.WHATSMINER:
- fn = self.get_miner_model_whatsminer
- if miner_type == MinerTypes.AVALONMINER:
- fn = self.get_miner_model_avalonminer
- if miner_type == MinerTypes.INNOSILICON:
- fn = self.get_miner_model_innosilicon
- if miner_type == MinerTypes.GOLDSHELL:
- fn = self.get_miner_model_goldshell
- if miner_type == MinerTypes.BRAIINS_OS:
- fn = self.get_miner_model_braiins_os
- if miner_type == MinerTypes.VNISH:
- fn = self.get_miner_model_vnish
- if miner_type == MinerTypes.HIVEON:
- fn = self.get_miner_model_hiveon
+ miner_model_fns = {
+ MinerTypes.ANTMINER: self.get_miner_model_antminer,
+ MinerTypes.WHATSMINER: self.get_miner_model_whatsminer,
+ MinerTypes.AVALONMINER: self.get_miner_model_avalonminer,
+ MinerTypes.INNOSILICON: self.get_miner_model_innosilicon,
+ MinerTypes.GOLDSHELL: self.get_miner_model_goldshell,
+ MinerTypes.BRAIINS_OS: self.get_miner_model_braiins_os,
+ MinerTypes.VNISH: self.get_miner_model_vnish,
+ MinerTypes.HIVEON: self.get_miner_model_hiveon,
+ }
+ fn = miner_model_fns.get(miner_type)
+
if fn is not None:
task = asyncio.create_task(fn(ip))
try:
@@ -433,6 +432,7 @@ class MinerFactory:
miner = self._select_miner_from_classes(
ip, miner_type=miner_type, miner_model=miner_model
)
+
if miner is not None and not isinstance(miner, UnknownMiner):
self.cache[ip] = miner
return miner
@@ -464,7 +464,7 @@ class MinerFactory:
try:
resp = await session.get(url)
return await resp.text(), resp
- except aiohttp.ClientError:
+ except (aiohttp.ClientError, asyncio.TimeoutError):
pass
return None, None
@@ -680,6 +680,22 @@ class MinerFactory:
try:
miner_model = sock_json_data["VERSION"][0]["Type"]
+ if " (" in miner_model:
+ split_miner_model = miner_model.split(" (")
+ miner_model = split_miner_model[0]
+
+ return miner_model
+ except (TypeError, LookupError):
+ pass
+
+ sock_json_data = await self.send_api_command(ip, "stats")
+ try:
+ miner_model = sock_json_data["STATS"][0]["Type"]
+
+ if " (" in miner_model:
+ split_miner_model = miner_model.split(" (")
+ miner_model = split_miner_model[0]
+
return miner_model
except (TypeError, LookupError):
pass
@@ -761,7 +777,8 @@ class MinerFactory:
try:
async with aiohttp.ClientSession() as session:
d = await session.post(
- url, json={"query": "{bosminer {info{modelName}}}"}
+ f"http://{ip}/graphql",
+ json={"query": "{bosminer {info{modelName}}}"},
)
if d.status == 200:
json_data = await d.json()
@@ -773,9 +790,9 @@ class MinerFactory:
async def get_miner_model_vnish(self, ip: str) -> Optional[str]:
sock_json_data = await self.send_api_command(ip, "stats")
try:
- miner_model = sock_json_data["STATS"][0]["Type"].upper()
- if " (VNISH" in miner_model:
- split_miner_model = miner_model.split(" (VNISH ")
+ miner_model = sock_json_data["STATS"][0]["Type"]
+ if " (" in miner_model:
+ split_miner_model = miner_model.split(" (")
miner_model = split_miner_model[0]
return miner_model
diff --git a/pyasic/miners/types/avalonminer/A11X/A1166.py b/pyasic/miners/types/avalonminer/A11X/A1166.py
index ed418da4..ec73ef09 100644
--- a/pyasic/miners/types/avalonminer/A11X/A1166.py
+++ b/pyasic/miners/types/avalonminer/A11X/A1166.py
@@ -22,8 +22,6 @@ class Avalon1166Pro(AvalonMiner): # noqa - ignore ABC method implementation
def __init__(self, ip: str, api_ver: str = "0.0.0"):
super().__init__(ip, api_ver)
self.ip = ip
- self.model = "Avalon 1166"
- warnings.warn(
- f"Unknown chip count for miner type {self.model}, please open an issue on GitHub (https://github.com/UpstreamData/pyasic)."
- )
+ self.model = "Avalon 1166 Pro"
+ self.nominal_chips = 120
self.fan_count = 4
diff --git a/pyasic/miners/types/innosilicon/A10X/A10X.py b/pyasic/miners/types/innosilicon/A10X/A10X.py
index 62e92817..aeeb0dca 100644
--- a/pyasic/miners/types/innosilicon/A10X/A10X.py
+++ b/pyasic/miners/types/innosilicon/A10X/A10X.py
@@ -20,3 +20,4 @@ class A10X(InnosiliconMiner): # noqa - ignore ABC method implementation
def __init__(self, ip: str, api_ver: str = "0.0.0") -> None:
super().__init__(ip, api_ver)
self.ip = ip
+ self.model = "A10X"
diff --git a/pyasic/web/bosminer.py b/pyasic/web/bosminer.py
index c80e2a2f..4710e532 100644
--- a/pyasic/web/bosminer.py
+++ b/pyasic/web/bosminer.py
@@ -31,10 +31,8 @@ class BOSMinerWebAPI(BaseWebAPI):
if isinstance(graphql_command, dict):
data = []
for key in graphql_command:
- if graphql_command[key]:
+ if graphql_command[key] is not None:
parsed = self.parse_command(graphql_command[key])
- if key.startswith("... on"):
- parsed = parsed.replace(",", "")
data.append(key + parsed)
else:
data.append(key)
@@ -80,10 +78,20 @@ class BOSMinerWebAPI(BaseWebAPI):
command = merge(*commands)
data = await self.send_command(command)
- if not data:
- data = {}
- data["multicommand"] = False
- return data
+ if data is not None:
+ if data.get("data") is None:
+ try:
+ commands = list(commands)
+ # noinspection PyTypeChecker
+ commands.remove({"bos": {"faultLight": None}})
+ command = merge(*commands)
+ data = await self.send_command(command)
+ except LookupError:
+ pass
+ if not data:
+ data = {}
+ data["multicommand"] = False
+ return data
async def auth(self, client: httpx.AsyncClient) -> None:
url = f"http://{self.ip}/graphql"