Compare commits

...

196 Commits

Author SHA1 Message Date
Upstream Data
c8a8315ad0 version: bump version number. 2024-06-04 09:28:15 -06:00
Upstream Data
dac9bcc3de refactor: improve _get_data implementation slightly. 2024-06-04 08:53:25 -06:00
Brett Rowan
46621d6b93 Merge pull request #151 from Ytemiloluwa/master 2024-06-02 13:50:51 -06:00
ytemiloluwa
35700f7e57 pools: MinerData 2024-06-02 20:47:58 +01:00
ytemiloluwa
08e6744595 index: unused variable 2024-06-02 07:26:43 +01:00
ytemiloluwa
2de3e5e328 update: _get_pools method 2024-06-02 07:13:39 +01:00
Temi
51f2eb1b1d Merge branch 'UpstreamData:master' into master 2024-06-02 06:51:28 +01:00
Brett Rowan
d40d92c1ca version: bump version number. 2024-05-28 21:46:41 -06:00
Brett Rowan
7ea63643a9 bug: fix a bunch of spelling mistakes. 2024-05-28 21:46:13 -06:00
upstreamdata
313c324771 bug: fix into naming on vnish with expected hashrate. 2024-05-27 15:57:06 -06:00
upstreamdata
a9fd9343d8 feature: add vnish fault light. 2024-05-26 21:59:59 -06:00
upstreamdata
8f41d4d0bc bug: fix MRO with vnish. 2024-05-26 21:59:57 -06:00
ytemiloluwa
521853863b base: _get_pools and get_pools 2024-05-26 13:21:53 +01:00
ytemiloluwa
b7a5a647b3 pools: DATA LOC 2024-05-26 00:36:07 +01:00
ytemiloluwa
4434f9ccad get_data: kwarg key 2024-05-26 00:22:57 +01:00
ytemiloluwa
82a1cc3cfe backends: _get_pools in antminer 2024-05-25 23:08:33 +01:00
Brett Rowan
6f10c91482 Merge pull request #150 from UpstreamData/snyk-fix-c1d73ce3e71f8a7a86f4d2be00564ee4 2024-05-25 09:00:39 -06:00
snyk-bot
f2d6bce165 fix: docs/requirements.txt to reduce vulnerabilities
The following vulnerabilities are fixed by pinning transitive dependencies:
- https://snyk.io/vuln/SNYK-PYTHON-JINJA2-6809379
2024-05-25 02:29:08 +00:00
Brett Rowan
61623cc44d version: bump version number. 2024-05-19 11:41:43 -06:00
Brett Rowan
a30a726324 bug: fix some issues with boser handlers. 2024-05-19 11:41:10 -06:00
Brett Rowan
0e90ad64cd Merge pull request #145 from Ytemiloluwa/master 2024-05-18 11:08:31 -06:00
ytemiloluwa
53572c6236 add new attributes 2024-05-18 16:53:06 +01:00
Brett Rowan
67da56a03b version: bump version number. 2024-05-17 21:06:23 -06:00
Brett Rowan
be8633185d bug: remove StrEnum references. 2024-05-17 21:02:57 -06:00
Brett Rowan
1d656da2a2 bug: remove StrEnum references. 2024-05-17 21:00:43 -06:00
Upstream Data
189deae3d1 version: bump version number. 2024-05-17 09:05:00 -06:00
Brett Rowan
46188ad52b Merge pull request #146 from UpstreamData/fix_typo
fix typo
2024-05-17 09:02:22 -06:00
John-Paul Compagnone
19e232ddb9 fix typo 2024-05-17 11:01:01 -04:00
ytemiloluwa
5d90b7e938 pools: updated metrics dataclass 2024-05-16 20:20:53 +01:00
ytemiloluwa
3f90799544 update metrics dataclass 2024-05-16 19:25:48 +01:00
Temi
1f70ec0d28 Merge branch 'UpstreamData:master' into master 2024-05-16 19:00:45 +01:00
Upstream Data
c26b78aa01 version: bump version number. 2024-05-16 08:27:38 -06:00
Brett Rowan
0debf16f7c Merge pull request #144 from jpcomps/master
ePIC: bug fixes
2024-05-16 08:27:07 -06:00
John-Paul Compagnone
d7f48d8f9f remove tuned from MinerConfig 2024-05-16 10:26:04 -04:00
ytemiloluwa
58c95559dd pools: dataclass metrics 2024-05-16 14:08:00 +01:00
JP Compagnone
03caa9fe94 Merge branch 'UpstreamData:master' into master 2024-05-15 21:03:32 -04:00
John-Paul Compagnone
afd8697f07 change from optimized to tuned, which is more generic for other FW 2024-05-15 21:03:12 -04:00
Upstream Data
fc77aded28 version: bump version number. 2024-05-15 14:21:27 -06:00
Brett Rowan
a5cafd1fb8 Merge pull request #137 from UpstreamData/dev_data
feature: Improve timestamp serialization,  add device_data to MinerData, and use enums for device information
2024-05-15 14:20:16 -06:00
John-Paul Compagnone
91d504fc1c add Vopt status, fix typo 2024-05-14 23:07:34 -04:00
Upstream Data
db0444a8eb tests: fix tests. 2024-05-14 13:36:26 -06:00
Upstream Data
0cab872baf bug: fix zero division cases with miner data. 2024-05-14 13:34:17 -06:00
Upstream Data
7f191eb2fd feature: add __getitem__ to config. 2024-05-14 13:34:16 -06:00
Upstream Data
52adc2553b feature: add keys to miner data. 2024-05-14 13:34:16 -06:00
Upstream Data
de49fd7e95 refactor: Optimize imports. 2024-05-14 13:34:16 -06:00
Upstream Data
7eb61473a8 feature: add custom hashrate types and conversion. 2024-05-14 13:34:14 -06:00
Upstream Data
f6a134342a feature: rename MinerModels to MinerModel, and add device info in as properties of MinerData. 2024-05-14 13:33:12 -06:00
Upstream Data
1d67e5ed68 refactor: clean and optimize imports. 2024-05-14 13:33:12 -06:00
Upstream Data
7d4aa80966 refactor: move models to pyasic.miners.devices 2024-05-14 13:33:12 -06:00
Upstream Data
742dde622b feature: add device models. 2024-05-14 13:33:12 -06:00
Upstream Data
497aa6a42c feature: add expected fans to miner data. 2024-05-14 13:33:10 -06:00
Upstream Data
40ebf42da1 feature: create device_info field for MinerData. 2024-05-14 13:32:12 -06:00
Upstream Data
2f8aea5285 bug: fix as_influx timestamp parsing. 2024-05-14 13:32:12 -06:00
Upstream Data
53f545ba13 feature: save datetime object as private in MinerData, and parse datetime in ISO format along with a timestamp. 2024-05-14 13:32:08 -06:00
Upstream Data
689b34611e version: bump version number. 2024-05-14 08:48:38 -06:00
Brett Rowan
d55c3f45ef Merge pull request #143 from jpcomps/master
feat: add additional ePIC UMC features, add Output Voltage to MinerData
2024-05-14 08:47:00 -06:00
John-Paul Compagnone
5ac533616f missed chiptune 2024-05-14 10:46:26 -04:00
John-Paul Compagnone
96ea5f5d16 remove passing self 2024-05-14 10:41:18 -04:00
John-Paul Compagnone
87526f5efc change target as well to get 2024-05-13 23:54:41 -04:00
John-Paul Compagnone
d31bafbc0e less lines 2024-05-13 23:51:23 -04:00
John-Paul Compagnone
66bae47bb9 seperate these out 2024-05-13 21:26:15 -04:00
John-Paul Compagnone
7a09b66d4e simplify 2024-05-13 21:22:31 -04:00
John-Paul Compagnone
de5932184f use get and cheap way to do full backwards compat 2024-05-13 21:17:48 -04:00
John-Paul Compagnone
2cba62e050 push self into secondary level 2024-05-13 21:03:26 -04:00
John-Paul Compagnone
c7520d98e0 better descriptions 2024-05-13 17:00:02 -04:00
John-Paul Compagnone
92e9f7bc08 fix typo 2024-05-13 16:57:19 -04:00
Upstream Data
e0becce349 bug: fix zero division cases with miner data. 2024-05-13 14:41:37 -06:00
John-Paul Compagnone
a65c4ba215 feat: add voltage param to minerdata 2024-05-13 15:44:12 -04:00
John-Paul Compagnone
4cd0c3357b remove prints 2024-05-12 16:05:08 -04:00
John-Paul Compagnone
d5cabf8af5 fix: fix send_config for epic, add throttle step and min throttle for Vopt 2024-05-12 14:08:12 -04:00
JP Compagnone
3120de757d Merge branch 'UpstreamData:master' into master 2024-05-12 13:20:50 -04:00
Upstream Data
0b69fe591e version: bump version number. 2024-05-10 13:34:00 -06:00
Upstream Data
032288d062 bug: fix k pro identification on latest versions. 2024-05-10 13:33:42 -06:00
Upstream Data
1d6618c1c0 feature: add __getitem__ to config. 2024-05-10 13:08:45 -06:00
Upstream Data
7126e03f0d feature: add keys to miner data. 2024-05-10 12:55:29 -06:00
Upstream Data
c27556c809 refactor: Optimize imports. 2024-05-09 15:04:36 -06:00
Upstream Data
99ff28d3e1 feature: add custom hashrate types and conversion. 2024-05-09 15:01:40 -06:00
Upstream Data
8ad6f60757 feature: rename MinerModels to MinerModel, and add device info in as properties of MinerData. 2024-05-09 12:48:30 -06:00
Brett Rowan
5f67b987a0 Merge pull request #139 from UpstreamData/snyk-fix-77dddc60686385a842810025bed37669
[Snyk] Security upgrade jinja2 from 3.1.2 to 3.1.4
2024-05-09 12:26:13 -06:00
snyk-bot
5842b3c4aa fix: docs/requirements.txt to reduce vulnerabilities
The following vulnerabilities are fixed by pinning transitive dependencies:
- https://snyk.io/vuln/SNYK-PYTHON-JINJA2-6809379
2024-05-08 20:27:28 +00:00
Upstream Data
e2e1d2f2fd version: bump version number. 2024-05-06 14:43:19 -06:00
Upstream Data
dd205c0f06 feature: use semaphore for scanning. 2024-05-06 14:43:03 -06:00
Upstream Data
79e247c0cf version: bump version number. 2024-05-03 11:19:50 -06:00
Upstream Data
836d045b65 bug: fix bosminer sometimes not being able to set config due to temp settings not being set. 2024-05-03 11:19:33 -06:00
Upstream Data
2d029b65e6 version: bump version number. 2024-05-03 08:31:39 -06:00
Upstream Data
993b7efeef bug: fix bosminer.toml writing to use only ssh, no sftp. 2024-05-03 08:30:51 -06:00
Upstream Data
7e02a6b932 refactor: clean and optimize imports. 2024-05-01 14:29:02 -06:00
Upstream Data
60e38fb8bc refactor: move models to pyasic.miners.devices 2024-05-01 14:18:22 -06:00
Upstream Data
4fc2757ffa feature: add device models. 2024-05-01 14:16:49 -06:00
Upstream Data
c89b25d7c9 feature: add expected fans to miner data. 2024-05-01 11:53:45 -06:00
Upstream Data
f2fc354f8c Merge remote-tracking branch 'origin/dev_data' into dev_data 2024-05-01 11:37:00 -06:00
Upstream Data
0e7eca339c feature: create device_info field for MinerData. 2024-05-01 11:36:54 -06:00
Upstream Data
5f76cb9f0a feature: create device_info field for MinerData. 2024-05-01 11:36:28 -06:00
Upstream Data
ed3a4bd32a bug: fix as_influx timestamp parsing. 2024-05-01 10:16:02 -06:00
Upstream Data
a0a1b68f68 feature: save datetime object as private in MinerData, and parse datetime in ISO format along with a timestamp. 2024-05-01 08:57:02 -06:00
Upstream Data
b7a81097a4 version: bump version number. 2024-04-30 15:50:37 -06:00
Upstream Data
651bef8203 bug: round mara fw wattage. 2024-04-30 14:43:35 -06:00
Upstream Data
a9e5c99ab2 bug: fix mara fw expected hashrate scaling. 2024-04-30 14:42:43 -06:00
Upstream Data
30216fdd5b bug: fix mara fw hashrate scaling. 2024-04-30 14:32:43 -06:00
Upstream Data
341cc13d83 bug: fix no firmware type for BOSer. 2024-04-30 13:12:01 -06:00
Upstream Data
05a4ae6f04 bug: reformat, and fix miner listener. 2024-04-30 11:50:21 -06:00
Brett Rowan
5971d9fd83 Merge pull request #125 from UpstreamData/dev_marafw
feature: Add maraFW support.
2024-04-30 10:01:35 -06:00
Brett Rowan
3968f2275c Merge branch 'master' into dev_marafw 2024-04-30 10:01:28 -06:00
Upstream Data
84344ca883 feature: make mara discover more consistent. 2024-04-30 09:11:23 -06:00
1e9abhi1e10
59b80254eb remove trailing whitespace 2024-04-30 09:11:23 -06:00
1e9abhi1e10
06fdb19e0b Add tess in config_tests 2024-04-30 09:11:23 -06:00
Upstream Data
75222e8cd2 docs: update docs generation to fix marathon miners. 2024-04-30 09:11:23 -06:00
Upstream Data
5a067d60e7 bug: remove some excepts that were catching propagated cancellations. 2024-04-30 09:11:21 -06:00
Upstream Data
2fbc4fcb4a version: bump version number. 2024-04-30 09:11:18 -06:00
Upstream Data
13fe60504a bug: fix bad naming of S19J Pro Plus NOPIC. 2024-04-30 09:11:18 -06:00
Upstream Data
cdc52c3605 docs: update docs. 2024-04-30 09:11:17 -06:00
Upstream Data
a9db097355 version: bump version number. 2024-04-30 09:11:17 -06:00
Upstream Data
ec5557cf88 feature: Add support for S19jPro+ No PIC. 2024-04-30 09:11:17 -06:00
Upstream Data
a8ea84d2f3 version: bump version number. 2024-04-30 09:11:17 -06:00
Upstream Data
58d369eedf bug: fix disabling fans when using immersion mode. 2024-04-30 09:11:17 -06:00
Abhishek Patidar
f8f9dd7070 Add tests in rpc_tests (#128) 2024-04-30 09:11:17 -06:00
Upstream Data
01b72e1ee6 version: bump version number. 2024-04-30 09:11:16 -06:00
Upstream Data
e367e630b8 bug: fix bosminer fan control for 2.0 versions. 2024-04-30 09:11:16 -06:00
upstreamdata
385cca6fc0 docs: update index and readme. 2024-04-30 09:11:16 -06:00
upstreamdata
75a3a466a3 docs: update documentation to include new web docstrings. 2024-04-30 09:11:16 -06:00
Harsh Singh Rawat
4bf08dbfe6 docs: add docstring for antminer and auradine in web (#127)
* docs: add docstring for antminer and auradine in web

Signed-off-by: PAINxNAGATO <harshrawat349@gmail.com>

* Remove Trailing whitespace from the docstring

Signed-off-by: PAINxNAGATO <harshrawat349@gmail.com>

* Remove Trailing whitespace from the docstring

Signed-off-by: PAINxNAGATO <harshrawat349@gmail.com>

* Remove Trailing whitespace from the docstring of the fucntion multicommand

Signed-off-by: PAINxNAGATO <harshrawat349@gmail.com>

---------

Signed-off-by: PAINxNAGATO <harshrawat349@gmail.com>
2024-04-30 09:11:16 -06:00
Abhishek Patidar
833d061315 docs: Add documentation for config (#121)
* docs: Add documentation for `config`

* Fix styling

* Add documentation for classmethods

* fixes some docstring
2024-04-30 09:11:16 -06:00
Abhishek Patidar
a85558278d docs: Add documentation for ssh (#126) 2024-04-30 09:11:15 -06:00
Upstream Data
bf5087b06d Merge remote-tracking branch 'origin/master' 2024-04-29 09:14:59 -06:00
Upstream Data
ec58d13bae docs: update docs generation to fix marathon miners. 2024-04-29 09:14:47 -06:00
Brett Rowan
75993564ab Merge pull request #131 from 1e9abhi1e10/config_tests 2024-04-27 12:16:30 -06:00
1e9abhi1e10
f3ea169dec remove trailing whitespace 2024-04-27 15:47:08 +05:30
1e9abhi1e10
39b3fe5c25 Add tess in config_tests 2024-04-27 15:40:03 +05:30
John-Paul Compagnone
3b2b586420 add new critical temp api, add board serial no 2024-04-26 19:27:19 -04:00
Upstream Data
5c79c6cb0c bug: remove some excepts that were catching propagated cancellations. 2024-04-26 13:00:16 -06:00
Upstream Data
bab4261bed version: bump version number. 2024-04-24 10:39:34 -06:00
Upstream Data
e1d5c89388 bug: fix bad naming of S19J Pro Plus NOPIC. 2024-04-24 10:37:07 -06:00
Upstream Data
5f6c8cca18 docs: update docs. 2024-04-24 10:04:46 -06:00
Upstream Data
39db14b002 version: bump version number. 2024-04-24 10:04:13 -06:00
Upstream Data
3be04c678b feature: Add support for S19jPro+ No PIC. 2024-04-24 10:03:36 -06:00
Upstream Data
099ec35a8f version: bump version number. 2024-04-22 12:28:20 -06:00
Upstream Data
113dfb9170 bug: fix disabling fans when using immersion mode. 2024-04-22 12:27:44 -06:00
Abhishek Patidar
8d19e0ebbb Add tests in rpc_tests (#128) 2024-04-22 09:30:20 -06:00
Upstream Data
ec064eba65 version: bump version number. 2024-04-22 08:58:28 -06:00
Upstream Data
3451127761 bug: fix bosminer fan control for 2.0 versions. 2024-04-22 08:58:06 -06:00
upstreamdata
b3be52ca77 docs: update index and readme. 2024-04-19 21:43:22 -06:00
upstreamdata
b6ec6caa72 docs: update documentation to include new web docstrings. 2024-04-19 21:41:17 -06:00
Harsh Singh Rawat
8e81e18622 docs: add docstring for antminer and auradine in web (#127)
* docs: add docstring for antminer and auradine in web

Signed-off-by: PAINxNAGATO <harshrawat349@gmail.com>

* Remove Trailing whitespace from the docstring

Signed-off-by: PAINxNAGATO <harshrawat349@gmail.com>

* Remove Trailing whitespace from the docstring

Signed-off-by: PAINxNAGATO <harshrawat349@gmail.com>

* Remove Trailing whitespace from the docstring of the fucntion multicommand

Signed-off-by: PAINxNAGATO <harshrawat349@gmail.com>

---------

Signed-off-by: PAINxNAGATO <harshrawat349@gmail.com>
2024-04-19 15:14:01 -06:00
Abhishek Patidar
6ea26e0e19 docs: Add documentation for config (#121)
* docs: Add documentation for `config`

* Fix styling

* Add documentation for classmethods

* fixes some docstring
2024-04-19 15:05:12 -06:00
Abhishek Patidar
be446f94c1 docs: Add documentation for ssh (#126) 2024-04-19 15:03:51 -06:00
Upstream Data
3d94e30f22 feature: Add wattage settings, reboot, restart backend, stop mining, and start mining. 2024-04-12 15:20:09 -06:00
Upstream Data
d5a7ff3a46 feature: add wattage limit data and set wattage to mara. 2024-04-12 15:15:23 -06:00
Upstream Data
bbfa97632d feature: add send_config for mara miners. 2024-04-12 14:56:18 -06:00
Upstream Data
ecf0ce22d6 feature: add mara config parsing. 2024-04-12 14:28:22 -06:00
Upstream Data
d56da007a5 feature: make mara discover more consistent. 2024-04-12 13:40:10 -06:00
Upstream Data
2c86b2da7e feature: Add mara fw light functions. 2024-04-12 13:16:55 -06:00
Upstream Data
c73b1ceb07 feature: update mara fw data locations. 2024-04-12 13:09:23 -06:00
Upstream Data
a320c8967d feature: remove some mara support in order to get rid of Antminer function calls. 2024-04-12 10:19:24 -06:00
Upstream Data
e21e340f60 feature: add mara miner models. 2024-04-12 10:02:13 -06:00
Upstream Data
f63d8f4b91 feature: add really basic MaraFW support. 2024-04-12 09:55:45 -06:00
Upstream Data
ba6a1606b6 version: bump version number. 2024-04-12 08:48:52 -06:00
Upstream Data
51b0c0456f bug: fix parsing of tuner algo modes into json. 2024-04-12 08:47:40 -06:00
Upstream Data
04bd03b496 version: bump version number. 2024-04-11 09:31:00 -06:00
Upstream Data
bc5764c8ff feature: add stock support for T21. 2024-04-11 09:30:24 -06:00
Brett Rowan
1f2e066f4c Merge pull request #122 from jpcomps/fix_is_mining
feature: add is_mining for ePIC, add T21, add BlockMiner 720i
2024-04-11 09:28:18 -06:00
Upstream Data
74c457a694 version: bump version number. 2024-04-11 09:23:55 -06:00
Upstream Data
4a1c53dfd7 bug: fix some issues with config on bosminer. 2024-04-11 09:23:33 -06:00
John-Paul Compagnone
81b77f8768 cleaner code 2024-04-11 11:06:45 -04:00
John-Paul Compagnone
3b127b6862 fix is_mining for ePIC 2024-04-11 09:34:40 -04:00
Upstream Data
2815d2ba11 version: bump version number. 2024-04-08 12:15:38 -06:00
Upstream Data
1ff20fc6f0 feature: add bosminer S21 support. 2024-04-08 12:15:18 -06:00
Brett Rowan
797c847055 version: bump version number. 2024-04-07 17:17:17 -06:00
Brett Rowan
65c7f2f66f bug: fix vnish shutting-down handling. 2024-04-07 17:16:37 -06:00
Brett Rowan
445d621590 version: bump version number. 2024-04-07 17:04:10 -06:00
Brett Rowan
d39ecfd6b4 feature: add is_mining for vnish. 2024-04-07 17:03:28 -06:00
Brett Rowan
36663471fb version: bump version number. 2024-04-06 12:34:43 -06:00
Brett Rowan
80293ac52f bug: fix incorrect model for XP. 2024-04-06 12:34:14 -06:00
UpstreamData
70b45f40f5 docs: update dev setup. 2024-03-29 11:19:17 -06:00
UpstreamData
a511fabd9c Update README.md with dev docs. 2024-03-29 11:17:39 -06:00
Jim Burtoft
8bc8f6f178 Comment on some code I didn't understand initially (#118) 2024-03-28 21:31:37 -06:00
Brett Rowan
b790ad58a7 version: bump version number. 2024-03-23 20:27:42 -06:00
Brett Rowan
354ab793a2 bug: fix vnish MAC not working on some versions. 2024-03-23 20:25:26 -06:00
Upstream Data
59346d641f version: bump version number. 2024-03-22 15:12:35 -06:00
Upstream Data
11d770771b feature: fix vnish not having the shutdown flag. 2024-03-22 15:12:20 -06:00
Upstream Data
1b6db7ed45 feature: add antminer new API. 2024-03-22 13:42:10 -06:00
Upstream Data
55c4e10fae tests: Update tests, and fix some bugs. 2024-03-22 13:19:44 -06:00
Upstream Data
77c06dad61 version: bump version number. 2024-03-19 14:24:54 -06:00
Upstream Data
68d250d2f2 bug: fix K pro naming. 2024-03-19 14:24:31 -06:00
Upstream Data
094a17ac68 version: bump version number. 2024-03-19 14:17:21 -06:00
Upstream Data
dbcdeaa3de feature: add support for S19K Pro. 2024-03-19 14:16:57 -06:00
Upstream Data
872cac811a version: bump version number. 2024-03-19 12:41:57 -06:00
Upstream Data
d324c2fee9 feature: add stock S21 support. 2024-03-19 12:41:37 -06:00
JP Compagnone
577e8df612 Merge branch 'UpstreamData:master' into master 2024-03-14 16:58:12 -04:00
Upstream Data
4b54cf67ba version: bump version number. 2024-03-12 16:16:40 -06:00
Upstream Data
0e00fe3114 feature: add antminer mode as str setting. 2024-03-12 16:16:15 -06:00
wilfredallyn
15d1dc5bb6 feature: add install docs (#117) 2024-03-10 09:09:06 -06:00
Brett Rowan
2af0003843 version: bump version number. 2024-03-06 21:56:10 -07:00
Brett Rowan
3c227be170 bug: update httpx to use compatible versioning. 2024-03-06 21:53:14 -07:00
Brett Rowan
e889780bad version: bump version number. 2024-03-03 11:16:16 -07:00
Brett Rowan
cc3d4fa805 feature: add S19 Hydro and S19 Pro+ Hydro. 2024-03-03 11:15:44 -07:00
John-Paul Compagnone
743823f66e add Blockminer 720i and Antminer T21 support 2024-02-25 17:44:20 -05:00
341 changed files with 5610 additions and 1173 deletions

View File

@@ -1,16 +1,16 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
rev: v4.5.0
hooks:
- id: trailing-whitespace
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/psf/black
rev: 22.6.0
rev: 24.3.0
hooks:
- id: black
- repo: https://github.com/pycqa/isort
rev: 5.10.1
rev: 5.13.2
hooks:
- id: isort
name: isort (python)

View File

@@ -19,6 +19,37 @@ Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with
[Click here to view supported miner types](https://docs.pyasic.org/en/latest/miners/supported_types/)
---
## Installation
It is recommended to install `pyasic` in a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/#what-other-popular-options-exist-aside-from-venv) to isolate it from the rest of your system. Options include:
- [pypoetry](https://python-poetry.org/): the reccommended way, since pyasic already uses it by default
```
poetry install
```
- [venv](https://docs.python.org/3/library/venv.html): included in Python standard library but has fewer features than other options
- [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv): [pyenv](https://github.com/pyenv/pyenv) plugin for managing virtualenvs
```
pyenv install <python version number>
pyenv virtualenv <python version number> <env name>
pyenv activate <env name>
```
- [conda](https://docs.conda.io/en/latest/)
##### Installing `pyasic`
`python -m pip install .` or `poetry install`
##### Additional Developer Setup
```
poetry install --with dev
pre-commit install
```
---
## Getting started

View File

@@ -47,8 +47,8 @@ def backend_str(backend: MinerTypes) -> str:
return "Stock Firmware Goldshells"
case MinerTypes.LUX_OS:
return "LuxOS Firmware Miners"
case MinerTypes.EPIC:
return "ePIC Firmware Miners"
case MinerTypes.MARATHON:
return "Mara Firmware Miners"
def create_url_str(mtype: str):

View File

@@ -18,6 +18,31 @@ Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with
[Click here to view supported miner types](miners/supported_types.md)
---
## Installation
It is recommended to install `pyasic` in a [virtual environment](https://realpython.com/python-virtual-environments-a-primer/#what-other-popular-options-exist-aside-from-venv) to isolate it from the rest of your system. Options include:
- [pypoetry](https://python-poetry.org/): the reccommended way, since pyasic already uses it by default
```
poetry install
```
- [venv](https://docs.python.org/3/library/venv.html): included in Python standard library but has fewer features than other options
- [pyenv-virtualenv](https://github.com/pyenv/pyenv-virtualenv): [pyenv](https://github.com/pyenv/pyenv) plugin for managing virtualenvs
```
pyenv install <python version number>
pyenv virtualenv <python version number> <env name>
pyenv activate <env name>
```
- [conda](https://docs.conda.io/en/latest/)
##### Installing `pyasic`
`python -m pip install .` or `poetry install`
---
## Getting started
---
@@ -236,6 +261,7 @@ settings.update("default_antminer_password", "my_pwd")
"factory_get_timeout": 3,
"get_data_retries": 1,
"api_function_timeout": 5,
"antminer_mining_mode_as_str": False,
"default_whatsminer_password": "admin",
"default_innosilicon_password": "admin",
"default_antminer_password": "root",

View File

@@ -85,6 +85,13 @@
show_root_heading: false
heading_level: 4
## S19 Hydro
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19Hydro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro Hydro
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19ProHydro
handler: python
@@ -92,6 +99,20 @@
show_root_heading: false
heading_level: 4
## S19 Pro+ Hydro
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19ProPlusHydro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19K Pro
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19KPro
handler: python
options:
show_root_heading: false
heading_level: 4
## T19
::: pyasic.miners.antminer.bmminer.X19.T19.BMMinerT19
handler: python
@@ -155,8 +176,8 @@
show_root_heading: false
heading_level: 4
## S19j Pro
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro
## S19j Pro No PIC
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jProNoPIC
handler: python
options:
show_root_heading: false
@@ -169,6 +190,20 @@
show_root_heading: false
heading_level: 4
## S19j Pro+
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jProPlus
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro+ No PIC
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jProPlusNoPIC
handler: python
options:
show_root_heading: false
heading_level: 4
## S19k Pro No PIC
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19kProNoPIC
handler: python
@@ -302,3 +337,94 @@
show_root_heading: false
heading_level: 4
## S19 Pro (LuxOS)
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro (LuxOS)
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19jPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro+ (LuxOS)
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19jProPlus
handler: python
options:
show_root_heading: false
heading_level: 4
## S19k Pro (LuxOS)
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19kPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 XP (LuxOS)
::: pyasic.miners.antminer.luxos.X19.S19.LUXMinerS19XP
handler: python
options:
show_root_heading: false
heading_level: 4
## T19 (LuxOS)
::: pyasic.miners.antminer.luxos.X19.T19.LUXMinerT19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19j
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j No PIC (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19jNoPIC
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19jPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 XP (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19XP
handler: python
options:
show_root_heading: false
heading_level: 4
## S19K Pro (MaraFW)
::: pyasic.miners.antminer.marathon.X19.S19.MaraS19KPro
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -1,6 +1,27 @@
# pyasic
## X21 Models
## S21
::: pyasic.miners.antminer.bmminer.X21.S21.BMMinerS21
handler: python
options:
show_root_heading: false
heading_level: 4
## T21
::: pyasic.miners.antminer.bmminer.X21.T21.BMMinerT21
handler: python
options:
show_root_heading: false
heading_level: 4
## S21
::: pyasic.miners.antminer.bosminer.X21.S21.BOSMinerS21
handler: python
options:
show_root_heading: false
heading_level: 4
## S21 (ePIC)
::: pyasic.miners.antminer.epic.X21.S21.ePICS21
handler: python
@@ -8,3 +29,31 @@
show_root_heading: false
heading_level: 4
## T21 (ePIC)
::: pyasic.miners.antminer.epic.X21.T21.ePICT21
handler: python
options:
show_root_heading: false
heading_level: 4
## S21 (LuxOS)
::: pyasic.miners.antminer.luxos.X21.S21.LUXMinerS21
handler: python
options:
show_root_heading: false
heading_level: 4
## S21 (MaraFW)
::: pyasic.miners.antminer.marathon.X21.S21.MaraS21
handler: python
options:
show_root_heading: false
heading_level: 4
## T21 (MaraFW)
::: pyasic.miners.antminer.marathon.X21.T21.MaraT21
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -1,11 +1,11 @@
# pyasic
## Miner Factory
[`MinerFactory`][pyasic.MinerFactory] is the way to create miner types in `pyasic`. The most important method is [`get_miner()`][pyasic.get_miner], which is mapped to [`pyasic.get_miner()`][pyasic.get_miner], and should be used from there.
[`MinerFactory`][pyasic.miners.factory.MinerFactory] is the way to create miner types in `pyasic`. The most important method is [`get_miner()`][pyasic.get_miner], which is mapped to [`pyasic.get_miner()`][pyasic.get_miner], and should be used from there.
The instance used for [`pyasic.get_miner()`][pyasic.get_miner] is `pyasic.miner_factory`.
[`MinerFactory`][pyasic.MinerFactory] also keeps a cache, which can be cleared if needed with `pyasic.miner_factory.clear_cached_miners()`.
[`MinerFactory`][pyasic.miners.factory.MinerFactory] also keeps a cache, which can be cleared if needed with `pyasic.miner_factory.clear_cached_miners()`.
Finally, there is functionality to get multiple miners without using `asyncio.gather()` explicitly. Use `pyasic.miner_factory.get_multiple_miners()` with a list of IPs as strings to get a list of miner instances. You can also get multiple miners with an `AsyncGenerator` by using `pyasic.miner_factory.get_miner_generator()`.
@@ -32,5 +32,5 @@ Finally, there is functionality to get multiple miners without using `asyncio.ga
heading_level: 4
[`AnyMiner`][pyasic.miners.base.AnyMiner] is a placeholder type variable used for typing returns of functions.
A function returning [`AnyMiner`][pyasic.miners.base.AnyMiner] will always return a subclass of [`BaseMiner`][pyasic.miners.BaseMiner],
A function returning [`AnyMiner`][pyasic.miners.base.AnyMiner] will always return a subclass of [`BaseMiner`][pyasic.miners.base.BaseMiner],
and is used to specify a function returning some arbitrary type of miner class instance.

View File

@@ -78,10 +78,20 @@ details {
<li><a href="../antminer/X19#s19-xp">S19 XP</a></li>
<li><a href="../antminer/X19#s19a">S19a</a></li>
<li><a href="../antminer/X19#s19a-pro">S19a Pro</a></li>
<li><a href="../antminer/X19#s19-hydro">S19 Hydro</a></li>
<li><a href="../antminer/X19#s19-pro-hydro">S19 Pro Hydro</a></li>
<li><a href="../antminer/X19#s19-pro_1-hydro">S19 Pro+ Hydro</a></li>
<li><a href="../antminer/X19#s19k-pro">S19K Pro</a></li>
<li><a href="../antminer/X19#t19">T19</a></li>
</ul>
</details>
<details>
<summary>X21 Series:</summary>
<ul>
<li><a href="../antminer/X21#s21">S21</a></li>
<li><a href="../antminer/X21#t21">T21</a></li>
</ul>
</details>
</ul>
</details>
<details>
@@ -444,13 +454,21 @@ details {
<li><a href="../antminer/X19#s19j">S19j</a></li>
<li><a href="../antminer/X19#s19j-no-pic">S19j No PIC</a></li>
<li><a href="../antminer/X19#s19j-pro">S19j Pro</a></li>
<li><a href="../antminer/X19#s19j-pro">S19j Pro</a></li>
<li><a href="../antminer/X19#s19j-pro-no-pic">S19j Pro No PIC</a></li>
<li><a href="../antminer/X19#s19j-pro_1">S19j Pro+</a></li>
<li><a href="../antminer/X19#s19j-pro_1">S19j Pro+</a></li>
<li><a href="../antminer/X19#s19j-pro_1-no-pic">S19j Pro+ No PIC</a></li>
<li><a href="../antminer/X19#s19k-pro-no-pic">S19k Pro No PIC</a></li>
<li><a href="../antminer/X19#s19-xp">S19 XP</a></li>
<li><a href="../antminer/X19#t19">T19</a></li>
</ul>
</details>
<details>
<summary>X21 Series:</summary>
<ul>
<li><a href="../antminer/X21#s21">S21</a></li>
</ul>
</details>
</ul>
</details>
<details>
@@ -510,12 +528,14 @@ details {
<summary>X21 Series:</summary>
<ul>
<li><a href="../antminer/X21#s21-epic">S21 (ePIC)</a></li>
<li><a href="../antminer/X21#t21-epic">T21 (ePIC)</a></li>
</ul>
</details>
<details>
<summary>blockminer Series:</summary>
<ul>
<li><a href="../blockminer/blockminer#blockminer-520i-epic">BlockMiner 520i (ePIC)</a></li>
<li><a href="../blockminer/blockminer#blockminer-720i-epic">BlockMiner 720i (ePIC)</a></li>
</ul>
</details>
</ul>
@@ -544,6 +564,18 @@ details {
<summary>X19 Series:</summary>
<ul>
<li><a href="../antminer/X19#s19-luxos">S19 (LuxOS)</a></li>
<li><a href="../antminer/X19#s19-pro-luxos">S19 Pro (LuxOS)</a></li>
<li><a href="../antminer/X19#s19j-pro-luxos">S19j Pro (LuxOS)</a></li>
<li><a href="../antminer/X19#s19j-pro_1-luxos">S19j Pro+ (LuxOS)</a></li>
<li><a href="../antminer/X19#s19k-pro-luxos">S19k Pro (LuxOS)</a></li>
<li><a href="../antminer/X19#s19-xp-luxos">S19 XP (LuxOS)</a></li>
<li><a href="../antminer/X19#t19-luxos">T19 (LuxOS)</a></li>
</ul>
</details>
<details>
<summary>X21 Series:</summary>
<ul>
<li><a href="../antminer/X21#s21-luxos">S21 (LuxOS)</a></li>
</ul>
</details>
</ul>
@@ -574,4 +606,28 @@ details {
</ul>
</details>
</ul>
</details>
<details>
<summary>Mara Firmware Miners:</summary>
<ul>
<details>
<summary>X19 Series:</summary>
<ul>
<li><a href="../antminer/X19#s19-marafw">S19 (MaraFW)</a></li>
<li><a href="../antminer/X19#s19-pro-marafw">S19 Pro (MaraFW)</a></li>
<li><a href="../antminer/X19#s19j-marafw">S19j (MaraFW)</a></li>
<li><a href="../antminer/X19#s19j-no-pic-marafw">S19j No PIC (MaraFW)</a></li>
<li><a href="../antminer/X19#s19j-pro-marafw">S19j Pro (MaraFW)</a></li>
<li><a href="../antminer/X19#s19-xp-marafw">S19 XP (MaraFW)</a></li>
<li><a href="../antminer/X19#s19k-pro-marafw">S19K Pro (MaraFW)</a></li>
</ul>
</details>
<details>
<summary>X21 Series:</summary>
<ul>
<li><a href="../antminer/X21#s21-marafw">S21 (MaraFW)</a></li>
<li><a href="../antminer/X21#t21-marafw">T21 (MaraFW)</a></li>
</ul>
</details>
</ul>
</details>

View File

@@ -1,3 +1,3 @@
jinja2<3.1.3
jinja2<3.1.4
mkdocs
mkdocstrings[python]

View File

@@ -1,10 +1,10 @@
# pyasic
## Miner APIs
Each miner has a unique API that is used to communicate with it.
## Miner RPC APIs
Each miner has a unique RPC API that is used to communicate with it.
Each of these API types has commands that differ between them, and some commands have data that others do not.
Each miner that is a subclass of [`BaseMiner`][pyasic.miners.BaseMiner] should have an API linked to it as `Miner.api`.
Each miner that is a subclass of [`BaseMiner`][pyasic.miners.base.BaseMiner] may have an API linked to it as `Miner.rpc`.
All API implementations inherit from [`BaseMinerRPCAPI`][pyasic.rpc.base.BaseMinerRPCAPI], which implements the basic communications protocols.
All RPC API implementations inherit from [`BaseMinerRPCAPI`][pyasic.rpc.base.BaseMinerRPCAPI], which implements the basic communications protocols.
[`BaseMinerRPCAPI`][pyasic.rpc.base.BaseMinerRPCAPI] should never be used unless inheriting to create a new miner API class for a new type of miner (which should be exceedingly rare).
[`BaseMinerRPCAPI`][pyasic.rpc.base.BaseMinerRPCAPI] cannot be instantiated directly, it will raise a `TypeError`.

View File

@@ -12,6 +12,7 @@ Settings options:
- `factory_get_timeout`
- `get_data_retries`
- `api_function_timeout`
- `antminer_mining_mode_as_str`
- `default_whatsminer_password`
- `default_innosilicon_password`
- `default_antminer_password`

14
docs/web/antminer.md Normal file
View File

@@ -0,0 +1,14 @@
# pyasic
## AntminerModernWebAPI
::: pyasic.web.antminer.AntminerModernWebAPI
handler: python
options:
show_root_heading: false
heading_level: 4
## AntminerOldWebAPI
::: pyasic.web.antminer.AntminerOldWebAPI
handler: python
options:
show_root_heading: false
heading_level: 4

27
docs/web/api.md Normal file
View File

@@ -0,0 +1,27 @@
# pyasic
## Miner Web APIs
Each miner has a unique Web API that is used to communicate with it.
Each of these API types has commands that differ between them, and some commands have data that others do not.
Each miner that is a subclass of [`BaseMiner`][pyasic.miners.base.BaseMiner] may have an API linked to it as `Miner.web`.
All API implementations inherit from [`BaseWebAPI`][pyasic.web.BaseWebAPI], which implements the basic communications protocols.
[`BaseWebAPI`][pyasic.web.BaseWebAPI] should never be used unless inheriting to create a new miner API class for a new type of miner (which should be exceedingly rare).
Use these instead -
#### [AntminerModerNWebAPI][pyasic.web.antminer.AntminerModernWebAPI]
#### [AntminerOldWebAPI][pyasic.web.antminer.AntminerOldWebAPI]
#### [AuradineWebAPI][pyasic.web.auradine.AuradineWebAPI]
#### [ePICWebAPI][pyasic.web.epic.ePICWebAPI]
#### [GoldshellWebAPI][pyasic.web.goldshell.GoldshellWebAPI]
#### [InnosiliconWebAPI][pyasic.web.innosilicon.InnosiliconWebAPI]
#### [MaraWebAPI][pyasic.web.marathon.MaraWebAPI]
#### [VNishWebAPI][pyasic.web.vnish.VNishWebAPI]
<br>
## BaseWebAPI
::: pyasic.web.BaseWebAPI
handler: python
options:
heading_level: 4

7
docs/web/auradine.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## AuradineWebAPI
::: pyasic.web.auradine.AuradineWebAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/web/epic.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## ePICWebAPI
::: pyasic.web.epic.ePICWebAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/web/goldshell.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## GoldshellWebAPI
::: pyasic.web.goldshell.GoldshellWebAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/web/innosilicon.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## InnosiliconWebAPI
::: pyasic.web.innosilicon.InnosiliconWebAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/web/marathon.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## MaraWebAPI
::: pyasic.web.marathon.MaraWebAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/web/vnish.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## VNishWebAPI
::: pyasic.web.vnish.VNishWebAPI
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -22,6 +22,15 @@ nav:
- CGMiner: "rpc/cgminer.md"
- LUXMiner: "rpc/luxminer.md"
- Unknown: "rpc/unknown.md"
- Web APIs:
- Intro: "web/api.md"
- Antminer: "web/antminer.md"
- Auradine: "web/auradine.md"
- ePIC: "web/epic.md"
- Goldshell: "web/goldshell.md"
- Innosilicon: "web/innosilicon.md"
- Marathon: "web/marathon.md"
- VNish: "web/vnish.md"
- Backends:
- BMMiner: "miners/backends/bmminer.md"
- BOSMiner: "miners/backends/bosminer.md"
@@ -50,10 +59,15 @@ nav:
- Whatsminer M2X: "miners/whatsminer/M2X.md"
- Whatsminer M3X: "miners/whatsminer/M3X.md"
- Whatsminer M5X: "miners/whatsminer/M5X.md"
- Whatsminer M6X: "miners/whatsminer/M6X.md"
- Innosilicon T3X: "miners/innosilicon/T3X.md"
- Innosilicon A10X: "miners/innosilicon/A10X.md"
- Goldshell X5: "miners/goldshell/X5.md"
- Goldshell XMax: "miners/goldshell/XMax.md"
- Goldshell XBox: "miners/goldshell/XBox.md"
- Auradine AD: "miners/auradine/AD.md"
- Auradine AI: "miners/auradine/AI.md"
- Auradine AT: "miners/auradine/AT.md"
- Base Miner: "miners/base_miner.md"
- Settings:
- Settings: "settings/settings.md"

1180
poetry.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,9 @@ from pyasic.misc import merge_dicts
@dataclass
class MinerConfig:
"""Represents the configuration for a miner including pool configuration,
fan mode, temperature settings, mining mode, and power scaling."""
pools: PoolConfig = field(default_factory=PoolConfig.default)
fan_mode: FanModeConfig = field(default_factory=FanModeConfig.default)
temperature: TemperatureConfig = field(default_factory=TemperatureConfig.default)
@@ -33,10 +36,18 @@ class MinerConfig:
default_factory=PowerScalingConfig.default
)
def __getitem__(self, item):
try:
return getattr(self, item)
except AttributeError:
raise KeyError
def as_dict(self) -> dict:
"""Converts the MinerConfig object to a dictionary."""
return asdict(self)
def as_am_modern(self, user_suffix: str = None) -> dict:
"""Generates the configuration in the format suitable for modern Antminers."""
return {
**self.fan_mode.as_am_modern(),
"freq-level": "100",
@@ -47,6 +58,7 @@ class MinerConfig:
}
def as_wm(self, user_suffix: str = None) -> dict:
"""Generates the configuration in the format suitable for Whatsminers."""
return {
**self.fan_mode.as_wm(),
**self.mining_mode.as_wm(),
@@ -56,6 +68,7 @@ class MinerConfig:
}
def as_am_old(self, user_suffix: str = None) -> dict:
"""Generates the configuration in the format suitable for old versions of Antminers."""
return {
**self.fan_mode.as_am_old(),
**self.mining_mode.as_am_old(),
@@ -65,6 +78,7 @@ class MinerConfig:
}
def as_goldshell(self, user_suffix: str = None) -> dict:
"""Generates the configuration in the format suitable for Goldshell miners."""
return {
**self.fan_mode.as_goldshell(),
**self.mining_mode.as_goldshell(),
@@ -74,6 +88,7 @@ class MinerConfig:
}
def as_avalon(self, user_suffix: str = None) -> dict:
"""Generates the configuration in the format suitable for Avalonminers."""
return {
**self.fan_mode.as_avalon(),
**self.mining_mode.as_avalon(),
@@ -83,6 +98,7 @@ class MinerConfig:
}
def as_inno(self, user_suffix: str = None) -> dict:
"""Generates the configuration in the format suitable for Innosilicon miners."""
return {
**self.fan_mode.as_inno(),
**self.mining_mode.as_inno(),
@@ -92,6 +108,7 @@ class MinerConfig:
}
def as_bosminer(self, user_suffix: str = None) -> dict:
"""Generates the configuration in the bosminer.toml format."""
return {
**merge_dicts(self.fan_mode.as_bosminer(), self.temperature.as_bosminer()),
**self.mining_mode.as_bosminer(),
@@ -100,6 +117,7 @@ class MinerConfig:
}
def as_boser(self, user_suffix: str = None) -> dict:
""" "Generates the configuration in the format suitable for BOSer."""
return {
**self.fan_mode.as_boser(),
**self.temperature.as_boser(),
@@ -109,6 +127,7 @@ class MinerConfig:
}
def as_epic(self, user_suffix: str = None) -> dict:
"""Generates the configuration in the format suitable for ePIC miners."""
return {
**merge_dicts(self.fan_mode.as_epic(), self.temperature.as_epic()),
**self.mining_mode.as_epic(),
@@ -117,6 +136,7 @@ class MinerConfig:
}
def as_auradine(self, user_suffix: str = None) -> dict:
"""Generates the configuration in the format suitable for Auradine miners."""
return {
**self.fan_mode.as_auradine(),
**self.temperature.as_auradine(),
@@ -125,8 +145,18 @@ class MinerConfig:
**self.power_scaling.as_auradine(),
}
def as_mara(self, user_suffix: str = None) -> dict:
return {
**self.fan_mode.as_mara(),
**self.temperature.as_mara(),
**self.mining_mode.as_mara(),
**self.pools.as_mara(user_suffix=user_suffix),
**self.power_scaling.as_mara(),
}
@classmethod
def from_dict(cls, dict_conf: dict) -> "MinerConfig":
"""Constructs a MinerConfig object from a dictionary."""
return cls(
pools=PoolConfig.from_dict(dict_conf.get("pools")),
mining_mode=MiningModeConfig.from_dict(dict_conf.get("mining_mode")),
@@ -137,10 +167,12 @@ class MinerConfig:
@classmethod
def from_api(cls, api_pools: dict) -> "MinerConfig":
"""Constructs a MinerConfig object from API pool data."""
return cls(pools=PoolConfig.from_api(api_pools))
@classmethod
def from_am_modern(cls, web_conf: dict) -> "MinerConfig":
"""Constructs a MinerConfig object from web configuration for modern Antminers."""
return cls(
pools=PoolConfig.from_am_modern(web_conf),
mining_mode=MiningModeConfig.from_am_modern(web_conf),
@@ -149,18 +181,22 @@ class MinerConfig:
@classmethod
def from_am_old(cls, web_conf: dict) -> "MinerConfig":
"""Constructs a MinerConfig object from web configuration for old versions of Antminers."""
return cls.from_am_modern(web_conf)
@classmethod
def from_goldshell(cls, web_conf: dict) -> "MinerConfig":
"""Constructs a MinerConfig object from web configuration for Goldshell miners."""
return cls(pools=PoolConfig.from_am_modern(web_conf))
@classmethod
def from_inno(cls, web_pools: list) -> "MinerConfig":
"""Constructs a MinerConfig object from web configuration for Innosilicon miners."""
return cls(pools=PoolConfig.from_inno(web_pools))
@classmethod
def from_bosminer(cls, toml_conf: dict) -> "MinerConfig":
"""Constructs a MinerConfig object from the bosminer.toml file, same as the `as_bosminer` dumps a dict for writing to that file as toml."""
return cls(
pools=PoolConfig.from_bosminer(toml_conf),
mining_mode=MiningModeConfig.from_bosminer(toml_conf),
@@ -171,6 +207,7 @@ class MinerConfig:
@classmethod
def from_boser(cls, grpc_miner_conf: dict) -> "MinerConfig":
"""Constructs a MinerConfig object from gRPC configuration for BOSer."""
return cls(
pools=PoolConfig.from_boser(grpc_miner_conf),
mining_mode=MiningModeConfig.from_boser(grpc_miner_conf),
@@ -181,6 +218,7 @@ class MinerConfig:
@classmethod
def from_epic(cls, web_conf: dict) -> "MinerConfig":
"""Constructs a MinerConfig object from web configuration for ePIC miners."""
return cls(
pools=PoolConfig.from_epic(web_conf),
fan_mode=FanModeConfig.from_epic(web_conf),
@@ -190,6 +228,7 @@ class MinerConfig:
@classmethod
def from_vnish(cls, web_settings: dict) -> "MinerConfig":
"""Constructs a MinerConfig object from web settings for VNish miners."""
return cls(
pools=PoolConfig.from_vnish(web_settings),
fan_mode=FanModeConfig.from_vnish(web_settings),
@@ -199,8 +238,17 @@ class MinerConfig:
@classmethod
def from_auradine(cls, web_conf: dict) -> "MinerConfig":
"""Constructs a MinerConfig object from web configuration for Auradine miners."""
return cls(
pools=PoolConfig.from_api(web_conf["pools"]),
fan_mode=FanModeConfig.from_auradine(web_conf["fan"]),
mining_mode=MiningModeConfig.from_auradine(web_conf["mode"]),
)
@classmethod
def from_mara(cls, web_miner_config: dict) -> "MinerConfig":
return cls(
pools=PoolConfig.from_mara(web_miner_config),
fan_mode=FanModeConfig.from_mara(web_miner_config),
mining_mode=MiningModeConfig.from_mara(web_miner_config),
)

View File

@@ -57,6 +57,9 @@ class MinerConfigOption(Enum):
def as_auradine(self) -> dict:
return self.value.as_auradine()
def as_mara(self) -> dict:
return self.value.as_mara()
def __call__(self, *args, **kwargs):
return self.value(*args, **kwargs)
@@ -64,6 +67,13 @@ class MinerConfigOption(Enum):
def default(cls):
pass
def __getitem__(self, item):
try:
return getattr(self, item)
except AttributeError:
raise KeyError
@dataclass
class MinerConfigValue:
@@ -106,3 +116,12 @@ class MinerConfigValue:
def as_auradine(self) -> dict:
return {}
def as_mara(self) -> dict:
return {}
def __getitem__(self, item):
try:
return getattr(self, item)
except AttributeError:
raise KeyError

View File

@@ -44,11 +44,21 @@ class FanModeNormal(MinerConfigValue):
cls_conf["minimum_speed"] = web_cooling_settings["fan_min_duty"]
return cls(**cls_conf)
@classmethod
def from_bosminer(cls, toml_fan_conf: dict):
cls_conf = {}
if toml_fan_conf.get("min_fans") is not None:
cls_conf["minimum_fans"] = toml_fan_conf["min_fans"]
return cls(**cls_conf)
def as_am_modern(self) -> dict:
return {"bitmain-fan-ctrl": False, "bitmain-fan-pwn": "100"}
def as_bosminer(self) -> dict:
return {"temp_control": {"mode": "auto"}}
return {
"temp_control": {"mode": "auto"},
"fan_control": {"min_fans": self.minimum_fans},
}
def as_epic(self) -> dict:
return {
@@ -61,6 +71,15 @@ class FanModeNormal(MinerConfigValue):
}
}
def as_mara(self) -> dict:
return {
"general-config": {"environment-profile": "AirCooling"},
"advance-config": {
"override-fan-control": False,
"fan-fixed-percent": 0,
},
}
@dataclass
class FanModeManual(MinerConfigValue):
@@ -96,7 +115,7 @@ class FanModeManual(MinerConfigValue):
return cls(**cls_conf)
def as_am_modern(self) -> dict:
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwn": str(self.speed)}
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwm": str(self.speed)}
def as_bosminer(self) -> dict:
return {
@@ -110,6 +129,15 @@ class FanModeManual(MinerConfigValue):
def as_epic(self) -> dict:
return {"fans": {"Manual": {"speed": self.speed}}}
def as_mara(self) -> dict:
return {
"general-config": {"environment-profile": "AirCooling"},
"advance-config": {
"override-fan-control": True,
"fan-fixed-percent": self.speed,
},
}
@dataclass
class FanModeImmersion(MinerConfigValue):
@@ -120,14 +148,19 @@ class FanModeImmersion(MinerConfigValue):
return cls()
def as_am_modern(self) -> dict:
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwn": "0"}
return {"bitmain-fan-ctrl": True, "bitmain-fan-pwm": "0"}
def as_bosminer(self) -> dict:
return {"temp_control": {"mode": "disabled"}}
return {
"fan_control": {"min_fans": 0},
}
def as_auradine(self) -> dict:
return {"fan": {"percentage": 0}}
def as_mara(self) -> dict:
return {"general-config": {"environment-profile": "OilImmersionCooling"}}
class FanModeConfig(MinerConfigOption):
normal = FanModeNormal
@@ -156,7 +189,10 @@ class FanModeConfig(MinerConfigOption):
if web_conf.get("bitmain-fan-ctrl") is not None:
fan_manual = web_conf["bitmain-fan-ctrl"]
if fan_manual:
return cls.manual(speed=web_conf["bitmain-fan-pwm"])
speed = int(web_conf["bitmain-fan-pwm"])
if speed == 0:
return cls.immersion()
return cls.manual(speed=speed)
else:
return cls.normal()
else:
@@ -175,20 +211,28 @@ class FanModeConfig(MinerConfigOption):
@classmethod
def from_bosminer(cls, toml_conf: dict):
if toml_conf.get("temp_control") is None:
return cls.default()
if toml_conf["temp_control"].get("mode") is None:
try:
mode = toml_conf["temp_control"]["mode"]
fan_config = toml_conf.get("fan_control", {})
if mode == "auto":
return cls.normal().from_bosminer(fan_config)
elif mode == "manual":
if toml_conf.get("fan_control"):
return cls.manual().from_bosminer(fan_config)
return cls.manual()
elif mode == "disabled":
return cls.immersion()
except KeyError:
pass
try:
min_fans = toml_conf["fan_control"]["min_fans"]
except KeyError:
return cls.default()
mode = toml_conf["temp_control"]["mode"]
if mode == "auto":
return cls.normal()
elif mode == "manual":
if toml_conf.get("fan_control"):
return cls.manual().from_bosminer(toml_conf["fan_control"])
return cls.manual()
elif mode == "disabled":
if min_fans == 0:
return cls.immersion()
return cls.normal(minimum_fans=min_fans)
@classmethod
def from_vnish(cls, web_settings: dict):
@@ -232,4 +276,18 @@ class FanModeConfig(MinerConfigOption):
fan_1_target = fan_data["Target"]
return cls.manual(speed=round((fan_1_target / fan_1_max) * 100))
except LookupError:
return cls.default()
pass
return cls.default()
@classmethod
def from_mara(cls, web_config: dict):
try:
mode = web_config["general-config"]["environment-profile"]
if mode == "AirCooling":
if web_config["advance-config"]["override-fan-control"]:
return cls.manual(web_config["advance-config"]["fan-fixed-percent"])
return cls.normal()
return cls.immersion()
except LookupError:
pass
return cls.default()

View File

@@ -17,6 +17,7 @@ from __future__ import annotations
from dataclasses import dataclass, field
from pyasic import settings
from pyasic.config.base import MinerConfigOption, MinerConfigValue
from pyasic.web.braiins_os.proto.braiins.bos.v1 import (
HashrateTargetMode,
@@ -39,7 +40,9 @@ class MiningModeNormal(MinerConfigValue):
return cls()
def as_am_modern(self) -> dict:
return {"miner-mode": "0"}
if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "0"}
return {"miner-mode": 0}
def as_wm(self) -> dict:
return {"mode": self.mode}
@@ -53,6 +56,13 @@ class MiningModeNormal(MinerConfigValue):
def as_goldshell(self) -> dict:
return {"settings": {"level": 0}}
def as_mara(self) -> dict:
return {
"mode": {
"work-mode-selector": "Stock",
}
}
@dataclass
class MiningModeSleep(MinerConfigValue):
@@ -63,7 +73,9 @@ class MiningModeSleep(MinerConfigValue):
return cls()
def as_am_modern(self) -> dict:
return {"miner-mode": "1"}
if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "1"}
return {"miner-mode": 1}
def as_wm(self) -> dict:
return {"mode": self.mode}
@@ -77,6 +89,13 @@ class MiningModeSleep(MinerConfigValue):
def as_goldshell(self) -> dict:
return {"settings": {"level": 3}}
def as_mara(self) -> dict:
return {
"mode": {
"work-mode-selector": "Sleep",
}
}
@dataclass
class MiningModeLPM(MinerConfigValue):
@@ -87,7 +106,9 @@ class MiningModeLPM(MinerConfigValue):
return cls()
def as_am_modern(self) -> dict:
return {"miner-mode": "3"}
if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "3"}
return {"miner-mode": 3}
def as_wm(self) -> dict:
return {"mode": self.mode}
@@ -108,7 +129,9 @@ class MiningModeHPM(MinerConfigValue):
return cls()
def as_am_modern(self) -> dict:
return {"miner-mode": "0"}
if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "0"}
return {"miner-mode": 0}
def as_wm(self) -> dict:
return {"mode": self.mode}
@@ -117,6 +140,7 @@ class MiningModeHPM(MinerConfigValue):
return {"mode": {"mode": "turbo"}}
@dataclass
class StandardTuneAlgo(MinerConfigValue):
mode: str = field(init=False, default="standard")
@@ -124,20 +148,23 @@ class StandardTuneAlgo(MinerConfigValue):
return VOptAlgo().as_epic()
@dataclass
class VOptAlgo(MinerConfigValue):
mode: str = field(init=False, default="standard")
mode: str = field(init=False, default="voltage_optimizer")
def as_epic(self) -> str:
return "VoltageOptimizer"
@dataclass
class ChipTuneAlgo(MinerConfigValue):
mode: str = field(init=False, default="standard")
mode: str = field(init=False, default="chip_tune")
def as_epic(self) -> str:
return "ChipTune"
@dataclass
class TunerAlgo(MinerConfigOption):
standard = StandardTuneAlgo
voltage_optimizer = VOptAlgo
@@ -147,6 +174,16 @@ class TunerAlgo(MinerConfigOption):
def default(cls):
return cls.standard()
@classmethod
def from_dict(cls, dict_conf: dict | None):
mode = dict_conf.get("mode")
if mode is None:
return cls.default()
cls_attr = getattr(cls, mode)
if cls_attr is not None:
return cls_attr().from_dict(dict_conf)
@dataclass
class MiningModePowerTune(MinerConfigValue):
@@ -160,12 +197,14 @@ class MiningModePowerTune(MinerConfigValue):
if dict_conf.get("power"):
cls_conf["power"] = dict_conf["power"]
if dict_conf.get("algo"):
cls_conf["algo"] = dict_conf["algo"]
cls_conf["algo"] = TunerAlgo.from_dict(dict_conf["algo"])
return cls(**cls_conf)
def as_am_modern(self) -> dict:
return {"miner-mode": "0"}
if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "0"}
return {"miner-mode": 0}
def as_wm(self) -> dict:
if self.power is not None:
@@ -173,7 +212,10 @@ class MiningModePowerTune(MinerConfigValue):
return {}
def as_bosminer(self) -> dict:
return {"autotuning": {"enabled": True, "psu_power_limit": self.power}}
conf = {"enabled": True, "mode": "power_target"}
if self.power is not None:
conf["power_target"] = self.power
return {"autotuning": conf}
def as_boser(self) -> dict:
return {
@@ -192,19 +234,50 @@ class MiningModePowerTune(MinerConfigValue):
def as_auradine(self) -> dict:
return {"mode": {"mode": "custom", "tune": "power", "power": self.power}}
def as_mara(self) -> dict:
return {
"mode": {
"work-mode-selector": "Auto",
"concorde": {
"mode-select": "PowerTarget",
"power-target": self.power,
},
}
}
@dataclass
class MiningModeHashrateTune(MinerConfigValue):
mode: str = field(init=False, default="hashrate_tuning")
hashrate: int = None
throttle_limit: int = None
throttle_step: int = None
algo: TunerAlgo = field(default_factory=TunerAlgo.default)
@classmethod
def from_dict(cls, dict_conf: dict | None) -> "MiningModeHashrateTune":
return cls(dict_conf.get("hashrate"))
cls_conf = {}
if dict_conf.get("hashrate"):
cls_conf["hashrate"] = dict_conf["hashrate"]
if dict_conf.get("throttle_limit"):
cls_conf["throttle_limit"] = dict_conf["throttle_limit"]
if dict_conf.get("throttle_step"):
cls_conf["throttle_step"] = dict_conf["throttle_step"]
if dict_conf.get("algo"):
cls_conf["algo"] = TunerAlgo.from_dict(dict_conf["algo"])
return cls(**cls_conf)
def as_am_modern(self) -> dict:
return {"miner-mode": "0"}
if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "0"}
return {"miner-mode": 0}
def as_bosminer(self) -> dict:
conf = {"enabled": True, "mode": "hashrate_target"}
if self.hashrate is not None:
conf["hashrate_target"] = self.hashrate
return {"autotuning": conf}
def as_boser(self) -> dict:
return {
@@ -226,7 +299,28 @@ class MiningModeHashrateTune(MinerConfigValue):
return {"mode": {"mode": "custom", "tune": "ths", "ths": self.hashrate}}
def as_epic(self) -> dict:
return {"ptune": {"algo": self.algo.as_epic(), "target": self.hashrate}}
mode = {
"ptune": {
"algo": self.algo.as_epic(),
"target": self.hashrate,
}
}
if self.throttle_limit is not None:
mode["ptune"]["min_throttle"] = self.throttle_limit
if self.throttle_step is not None:
mode["ptune"]["throttle_step"] = self.throttle_step
return mode
def as_mara(self) -> dict:
return {
"mode": {
"work-mode-selector": "Auto",
"concorde": {
"mode-select": "Hashrate",
"hash-target": self.hashrate,
},
}
}
@dataclass
@@ -239,7 +333,9 @@ class ManualBoardSettings(MinerConfigValue):
return cls(freq=dict_conf["freq"], volt=dict_conf["volt"])
def as_am_modern(self) -> dict:
return {"miner-mode": "0"}
if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "0"}
return {"miner-mode": 0}
@dataclass
@@ -259,7 +355,9 @@ class MiningModeManual(MinerConfigValue):
)
def as_am_modern(self) -> dict:
return {"miner-mode": "0"}
if settings.get("antminer_mining_mode_as_str", False):
return {"miner-mode": "0"}
return {"miner-mode": 0}
@classmethod
def from_vnish(cls, web_overclock_settings: dict) -> "MiningModeManual":
@@ -275,6 +373,17 @@ class MiningModeManual(MinerConfigValue):
}
return cls(global_freq=freq, global_volt=voltage, boards=boards)
def as_mara(self) -> dict:
return {
"mode": {
"work-mode-selector": "Fixed",
"fixed": {
"frequency": str(self.global_freq),
"voltage": self.global_volt,
},
}
}
class MiningModeConfig(MinerConfigOption):
normal = MiningModeNormal
@@ -324,13 +433,19 @@ class MiningModeConfig(MinerConfigOption):
algo_info = web_conf["PerpetualTune"]["Algorithm"]
if algo_info.get("VoltageOptimizer") is not None:
return cls.hashrate_tuning(
hashrate=algo_info["VoltageOptimizer"]["Target"],
algo=TunerAlgo.voltage_optimizer,
hashrate=algo_info["VoltageOptimizer"].get("Target"),
throttle_limit=algo_info["VoltageOptimizer"].get(
"Min Throttle Target"
),
throttle_step=algo_info["VoltageOptimizer"].get(
"Throttle Step"
),
algo=TunerAlgo.voltage_optimizer(),
)
else:
return cls.hashrate_tuning(
hashrate=algo_info["ChipTune"]["Target"],
algo=TunerAlgo.chip_tune,
hashrate=algo_info["ChipTune"].get("Target"),
algo=TunerAlgo.chip_tune(),
)
else:
return cls.normal()
@@ -423,3 +538,28 @@ class MiningModeConfig(MinerConfigOption):
return cls.power_tuning(mode_data["Power"])
except LookupError:
return cls.default()
@classmethod
def from_mara(cls, web_config: dict):
try:
mode = web_config["mode"]["work-mode-selector"]
if mode == "Fixed":
fixed_conf = web_config["mode"]["fixed"]
return cls.manual(
global_freq=int(fixed_conf["frequency"]),
global_volt=fixed_conf["voltage"],
)
elif mode == "Stock":
return cls.normal()
elif mode == "Sleep":
return cls.sleep()
elif mode == "Auto":
auto_conf = web_config["mode"]["concorde"]
auto_mode = auto_conf["mode-select"]
if auto_mode == "Hashrate":
return cls.hashrate_tuning(hashrate=auto_conf["hash-target"])
elif auto_mode == "PowerTarget":
return cls.power_tuning(power=auto_conf["power-target"])
except LookupError:
pass
return cls.default()

View File

@@ -118,6 +118,15 @@ class Pool(MinerConfigValue):
}
return {"pool": self.url, "login": self.user, "password": self.password}
def as_mara(self, user_suffix: str = None) -> dict:
if user_suffix is not None:
return {
"url": self.url,
"user": f"{self.user}{user_suffix}",
"pass": self.password,
}
return {"url": self.url, "user": self.user, "pass": self.password}
@classmethod
def from_dict(cls, dict_conf: dict | None) -> "Pool":
return cls(
@@ -177,6 +186,14 @@ class Pool(MinerConfigValue):
password=grpc_pool["password"],
)
@classmethod
def from_mara(cls, web_pool: dict) -> "Pool":
return cls(
url=web_pool["url"],
user=web_pool["user"],
password=web_pool["pass"],
)
@dataclass
class PoolGroup(MinerConfigValue):
@@ -264,9 +281,12 @@ class PoolGroup(MinerConfigValue):
def as_auradine(self, user_suffix: str = None) -> list:
return [p.as_auradine(user_suffix=user_suffix) for p in self.pools]
def as_epic(self, user_suffix: str = None) -> dict:
def as_epic(self, user_suffix: str = None) -> list:
return [p.as_epic(user_suffix=user_suffix) for p in self.pools]
def as_mara(self, user_suffix: str = None) -> list:
return [p.as_mara(user_suffix=user_suffix) for p in self.pools]
@classmethod
def from_dict(cls, dict_conf: dict | None) -> "PoolGroup":
cls_conf = {}
@@ -336,6 +356,10 @@ class PoolGroup(MinerConfigValue):
except LookupError:
return cls()
@classmethod
def from_mara(cls, web_config_pools: dict) -> "PoolGroup":
return cls(pools=[Pool.from_mara(pool_conf) for pool_conf in web_config_pools])
@dataclass
class PoolConfig(MinerConfigValue):
@@ -427,6 +451,11 @@ class PoolConfig(MinerConfigValue):
}
}
def as_mara(self, user_suffix: str = None) -> dict:
if len(self.groups) > 0:
return {"pools": self.groups[0].as_mara(user_suffix=user_suffix)}
return {"pools": []}
@classmethod
def from_api(cls, api_pools: dict) -> "PoolConfig":
try:
@@ -481,3 +510,7 @@ class PoolConfig(MinerConfigValue):
)
except LookupError:
return cls()
@classmethod
def from_mara(cls, web_config: dict) -> "PoolConfig":
return cls(groups=[PoolGroup.from_mara(web_config["pools"])])

View File

@@ -114,6 +114,8 @@ class PowerScalingEnabled(MinerConfigValue):
def from_bosminer(cls, power_scaling_conf: dict) -> "PowerScalingEnabled":
power_step = power_scaling_conf.get("power_step")
min_power = power_scaling_conf.get("min_psu_power_limit")
if min_power is None:
min_power = power_scaling_conf.get("min_power_target")
sd_mode = PowerScalingShutdown.from_bosminer(power_scaling_conf)
return cls(
@@ -138,12 +140,12 @@ class PowerScalingEnabled(MinerConfigValue):
if self.power_step is not None:
cfg["power_step"] = self.power_step
if self.minimum_power is not None:
cfg["min_psu_power_limit"] = self.minimum_power
cfg["min_power_target"] = self.minimum_power
if self.shutdown_enabled is not None:
cfg = {**cfg, **self.shutdown_enabled.as_bosminer()}
return {"power_scaling": cfg}
return {"performance_scaling": cfg}
def as_boser(self) -> dict:
return {
@@ -189,6 +191,8 @@ class PowerScalingConfig(MinerConfigOption):
@classmethod
def from_bosminer(cls, toml_conf: dict):
power_scaling = toml_conf.get("power_scaling")
if power_scaling is None:
power_scaling = toml_conf.get("performance_scaling")
if power_scaling is not None:
enabled = power_scaling.get("enabled")
if enabled is not None:

View File

@@ -38,6 +38,8 @@ class TemperatureConfig(MinerConfigValue):
temp_cfg["hot_temp"] = self.hot
if self.danger is not None:
temp_cfg["dangerous_temp"] = self.danger
if len(temp_cfg) == 0:
return {}
return {"temp_control": temp_cfg}
def as_epic(self) -> dict:
@@ -47,7 +49,9 @@ class TemperatureConfig(MinerConfigValue):
else:
temps_config["fans"]["Auto"]["Target Temperature"] = 60
if self.danger is not None:
temps_config["temps"]["shutdown"] = self.danger
temps_config["temps"]["critical"] = self.danger
if self.hot is not None:
temps_config["temps"]["shutdown"] = self.hot
return temps_config
@classmethod
@@ -67,20 +71,25 @@ class TemperatureConfig(MinerConfigValue):
hot=temp_control.get("hot_temp"),
danger=temp_control.get("dangerous_temp"),
)
return cls()
@classmethod
def from_epic(cls, web_conf: dict) -> "TemperatureConfig":
try:
dangerous_temp = web_conf["Misc"]["Shutdown Temp"]
dangerous_temp = web_conf["Misc"]["Critical Temp"]
except KeyError:
dangerous_temp = None
try:
hot_temp = web_conf["Misc"]["Shutdown Temp"]
except KeyError:
hot_temp = None
# Need to do this in two blocks to avoid KeyError if one is missing
try:
target_temp = web_conf["Fans"]["Fan Mode"]["Auto"]["Target Temperature"]
except KeyError:
target_temp = None
return cls(target=target_temp, danger=dangerous_temp)
return cls(target=target_temp, hot=hot_temp, danger=dangerous_temp)
@classmethod
def from_vnish(cls, web_settings: dict) -> "TemperatureConfig":

View File

@@ -25,8 +25,11 @@ from pyasic.config import MinerConfig
from pyasic.config.mining import MiningModePowerTune
from .boards import HashBoard
from .device import DeviceInfo
from .error_codes import BraiinsOSError, InnosiliconError, WhatsminerError, X19Error
from .fans import Fan
from .hashrate import AlgoHashRate, HashUnit
from pyasic.data.pools import PoolMetrics
@dataclass
@@ -38,8 +41,11 @@ class MinerData:
datetime: The time and date this data was generated.
uptime: The uptime of the miner in seconds.
mac: The MAC address of the miner as a str.
device_info: Info about the device, such as model, make, and firmware.
model: The model of the miner as a str.
make: The make of the miner as a str.
firmware: The firmware on the miner as a str.
algo: The mining algorithm 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.
@@ -50,8 +56,10 @@ class MinerData:
temperature_avg: The average temperature across the boards. Calculated automatically.
env_temp: The environment temps as a float.
wattage: Current power draw of the miner as an int.
voltage: Current output voltage of the PSU as an float.
wattage_limit: Power limit of the miner as an int.
fans: A list of fans on the miner with their speeds.
expected_fans: The number of fans expected on a miner.
fan_psu: The speed of the PSU on the fan if the miner collects it.
total_chips: The total number of chips on all boards. Calculated automatically.
expected_chips: The expected number of chips in the miner as an int.
@@ -64,40 +72,81 @@ class MinerData:
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.
is_mining: Whether the miner is mining.
pools: A list of PoolMetrics instances, each representing metrics for a pool.
"""
# general
ip: str
datetime: datetime = None
uptime: int = None
_datetime: datetime = field(repr=False, default=None)
datetime: str = field(init=False)
timestamp: int = field(init=False)
# about
device_info: DeviceInfo = None
make: str = field(init=False)
model: str = field(init=False)
firmware: str = field(init=False)
algo: str = field(init=False)
mac: str = None
model: str = None
make: str = None
api_ver: str = None
fw_ver: str = None
hostname: str = None
hashrate: float = field(init=False)
_hashrate: float = field(repr=False, default=None)
# hashrate
hashrate: AlgoHashRate = field(init=False)
_hashrate: AlgoHashRate = field(repr=False, default=None)
# expected
expected_hashrate: float = None
hashboards: List[HashBoard] = field(default_factory=list)
expected_hashboards: int = None
temperature_avg: int = field(init=False)
env_temp: float = None
wattage: int = None
wattage_limit: int = field(init=False)
_wattage_limit: int = field(repr=False, default=None)
fans: List[Fan] = field(default_factory=list)
fan_psu: int = None
total_chips: int = field(init=False)
expected_chips: int = None
expected_fans: int = None
# % expected
percent_expected_chips: float = field(init=False)
percent_expected_hashrate: float = field(init=False)
percent_expected_wattage: float = field(init=False)
# temperature
temperature_avg: int = field(init=False)
env_temp: float = None
# power
wattage: int = None
wattage_limit: int = field(init=False)
voltage: float = None
_wattage_limit: int = field(repr=False, default=None)
# fans
fans: List[Fan] = field(default_factory=list)
fan_psu: int = None
# boards
hashboards: List[HashBoard] = field(default_factory=list)
total_chips: int = field(init=False)
nominal: bool = field(init=False)
# config
config: MinerConfig = None
errors: List[Union[WhatsminerError, BraiinsOSError, X19Error, InnosiliconError]] = field(default_factory=list)
fault_light: Union[bool, None] = None
efficiency: int = field(init=False)
# errors
errors: List[
Union[
WhatsminerError,
BraiinsOSError,
X19Error,
InnosiliconError,
]
] = field(default_factory=list)
# mining state
is_mining: bool = True
uptime: int = None
efficiency: int = field(init=False)
# pools
pools: list[PoolMetrics] = field(default_factory=list)
@classmethod
def fields(cls):
@@ -108,7 +157,7 @@ class MinerData:
return {k: v for (k, v) in x if not k.startswith("_")}
def __post_init__(self):
self.datetime = datetime.now(timezone.utc).astimezone()
self._datetime = datetime.now(timezone.utc).astimezone()
def get(self, __key: str, default: Any = None):
try:
@@ -176,7 +225,7 @@ class MinerData:
if item.hashrate is not None:
hr_data.append(item.hashrate)
if len(hr_data) > 0:
return round(sum(hr_data), 2)
return sum(hr_data, start=type(hr_data[0])(0))
return self._hashrate
@hashrate.setter
@@ -235,9 +284,10 @@ class MinerData:
def percent_expected_hashrate(self): # noqa - Skip PyCharm inspection
if self.hashrate is None or self.expected_hashrate is None:
return None
if self.hashrate == 0 or self.expected_hashrate == 0:
try:
return round((self.hashrate / self.expected_hashrate) * 100)
except ZeroDivisionError:
return 0
return round((self.hashrate / self.expected_hashrate) * 100)
@percent_expected_hashrate.setter
def percent_expected_hashrate(self, val):
@@ -247,9 +297,10 @@ class MinerData:
def percent_expected_wattage(self): # noqa - Skip PyCharm inspection
if self.wattage_limit is None or self.wattage is None:
return None
if self.wattage_limit == 0 or self.wattage == 0:
try:
return round((self.wattage / self.wattage_limit) * 100)
except ZeroDivisionError:
return 0
return round((self.wattage / self.wattage_limit) * 100)
@percent_expected_wattage.setter
def percent_expected_wattage(self, val):
@@ -275,14 +326,70 @@ class MinerData:
def efficiency(self): # noqa - Skip PyCharm inspection
if self.hashrate is None or self.wattage is None:
return None
if self.hashrate == 0 or self.wattage == 0:
try:
return round(self.wattage / float(self.hashrate))
except ZeroDivisionError:
return 0
return round(self.wattage / self.hashrate)
@efficiency.setter
def efficiency(self, val):
pass
@property
def datetime(self): # noqa - Skip PyCharm inspection
return self._datetime.isoformat()
@datetime.setter
def datetime(self, val):
pass
@property
def timestamp(self): # noqa - Skip PyCharm inspection
return int(time.mktime(self._datetime.timetuple()))
@timestamp.setter
def timestamp(self, val):
pass
@property
def make(self): # noqa - Skip PyCharm inspection
if self.device_info.make is not None:
return str(self.device_info.make)
@make.setter
def make(self, val):
pass
@property
def model(self): # noqa - Skip PyCharm inspection
if self.device_info.model is not None:
return str(self.device_info.model)
@model.setter
def model(self, val):
pass
@property
def firmware(self): # noqa - Skip PyCharm inspection
if self.device_info.firmware is not None:
return str(self.device_info.firmware)
@firmware.setter
def firmware(self, val):
pass
@property
def algo(self): # noqa - Skip PyCharm inspection
if self.device_info.algo is not None:
return str(self.device_info.algo)
@algo.setter
def algo(self, val):
pass
def keys(self) -> list:
return [f.name for f in fields(self)]
def asdict(self) -> dict:
return asdict(self, dict_factory=self.dict_factory)
@@ -300,9 +407,7 @@ class MinerData:
Returns:
A JSON version of this class.
"""
data = self.asdict()
data["datetime"] = str(int(time.mktime(data["datetime"].timetuple())))
return json.dumps(data)
return json.dumps(self.as_dict())
def as_csv(self) -> str:
"""Get this dataclass as CSV.
@@ -311,7 +416,6 @@ class MinerData:
A CSV version of this class with no headers.
"""
data = self.asdict()
data["datetime"] = str(int(time.mktime(data["datetime"].timetuple())))
errs = []
for error in data["errors"]:
errs.append(error["error_message"])
@@ -376,6 +480,6 @@ class MinerData:
tags_str = ",".join(tag_data)
field_str = ",".join(field_data)
timestamp = str(int(time.mktime(self.datetime.timetuple()) * 1e9))
timestamp = str(self.timestamp * 1e9)
return " ".join([tags_str, field_str, timestamp])

View File

@@ -17,6 +17,8 @@
from dataclasses import dataclass
from typing import Any
from .hashrate import AlgoHashRate
@dataclass
class HashBoard:
@@ -34,7 +36,7 @@ class HashBoard:
"""
slot: int = 0
hashrate: float = None
hashrate: AlgoHashRate = None
temp: int = None
chip_temp: int = None
chips: int = None

14
pyasic/data/device.py Normal file
View File

@@ -0,0 +1,14 @@
from dataclasses import dataclass
from pyasic.device.algorithm import MinerAlgo
from pyasic.device.firmware import MinerFirmware
from pyasic.device.makes import MinerMake
from pyasic.device.models import MinerModel
@dataclass
class DeviceInfo:
make: MinerMake = None
model: MinerModel = None
firmware: MinerFirmware = None
algo: MinerAlgo = None

View File

@@ -0,0 +1,15 @@
from enum import Enum
from pyasic.data.hashrate.sha256 import SHA256HashRate
from pyasic.device.algorithm.sha256 import SHA256Unit
class AlgoHashRate(Enum):
SHA256 = SHA256HashRate
def __call__(self, *args, **kwargs):
return self.value(*args, **kwargs)
class HashUnit:
SHA256 = SHA256Unit

View File

@@ -0,0 +1,54 @@
from __future__ import annotations
from dataclasses import dataclass
from pyasic.device.algorithm import MinerAlgo
from pyasic.device.algorithm.sha256 import SHA256Unit
@dataclass
class SHA256HashRate:
rate: float
unit: SHA256Unit = MinerAlgo.SHA256.unit.default
def __float__(self):
return float(self.rate)
def __int__(self):
return int(self.rate)
def __repr__(self):
return f"{self.rate} {str(self.unit)}"
def __round__(self, n: int = None):
return round(self.rate, n)
def __add__(self, other: SHA256HashRate | int | float) -> SHA256HashRate:
if isinstance(other, SHA256HashRate):
return SHA256HashRate(self.rate + other.into(self.unit).rate, self.unit)
return SHA256HashRate(self.rate + other, self.unit)
def __sub__(self, other: SHA256HashRate | int | float) -> SHA256HashRate:
if isinstance(other, SHA256HashRate):
return SHA256HashRate(self.rate - other.into(self.unit).rate, self.unit)
return SHA256HashRate(self.rate - other, self.unit)
def __truediv__(self, other: SHA256HashRate | int | float):
if isinstance(other, SHA256HashRate):
return SHA256HashRate(self.rate / other.into(self.unit).rate, self.unit)
return SHA256HashRate(self.rate / other, self.unit)
def __floordiv__(self, other: SHA256HashRate | int | float):
if isinstance(other, SHA256HashRate):
return SHA256HashRate(self.rate // other.into(self.unit).rate, self.unit)
return SHA256HashRate(self.rate // other, self.unit)
def __mul__(self, other: SHA256HashRate | int | float):
if isinstance(other, SHA256HashRate):
return SHA256HashRate(self.rate * other.into(self.unit).rate, self.unit)
return SHA256HashRate(self.rate * other, self.unit)
def into(self, other: SHA256Unit) -> SHA256HashRate:
return SHA256HashRate(
rate=self.rate / (other.value / self.unit.value), unit=other
)

59
pyasic/data/pools.py Normal file
View File

@@ -0,0 +1,59 @@
from dataclasses import dataclass, field
@dataclass
class PoolMetrics:
"""A dataclass to standardize pool metrics returned from miners.
Attributes:
accepted: Number of accepted shares.
rejected: Number of rejected shares.
get_failures: Number of failures in obtaining work from the pool.
remote_failures: Number of failures communicating with the pool server.
active: Indicates if the miner is connected to the stratum server.
Alive : Indicates if a pool is alive.
url: URL of the pool.
index: Index of the pool.
user: Username for the pool.
pool_rejected_percent: Percentage of rejected shares by the pool.
pool_stale_percent: Percentage of stale shares by the pool.
"""
accepted: int = None
rejected: int = None
get_failures: int = None
remote_failures: int = None
active: bool = None
alive: bool = None
url: str = None
index: int = None
user: str = None
pool_rejected_percent: float = field(init=False)
pool_stale_percent: float = field(init=False)
@property
def pool_rejected_percent(self) -> float: # noqa - Skip PyCharm inspection
"""Calculate and return the percentage of rejected shares"""
return self._calculate_percentage(self.rejected, self.accepted + self.rejected)
@pool_rejected_percent.setter
def pool_rejected_percent(self, val):
pass
@property
def pool_stale_percent(self) -> float: # noqa - Skip PyCharm inspection
"""Calculate and return the percentage of stale shares."""
return self._calculate_percentage(
self.get_failures, self.accepted + self.rejected
)
@pool_stale_percent.setter
def pool_stale_percent(self, val):
pass
@staticmethod
def _calculate_percentage(value: int, total: int) -> float:
"""Calculate the percentage."""
if total == 0:
return 0
return (value / total) * 100

View File

@@ -0,0 +1,4 @@
from .algorithm import MinerAlgo
from .firmware import MinerFirmware
from .makes import MinerMake
from .models import MinerModel

View File

@@ -0,0 +1,5 @@
from pyasic.device.algorithm.sha256 import SHA256Algo
class MinerAlgo:
SHA256 = SHA256Algo

View File

@@ -0,0 +1,68 @@
from __future__ import annotations
from enum import IntEnum
class SHA256Unit(IntEnum):
H = 1
KH = int(H) * 1000
MH = int(KH) * 1000
GH = int(MH) * 1000
TH = int(GH) * 1000
PH = int(TH) * 1000
EH = int(PH) * 1000
ZH = int(EH) * 1000
default = TH
def __str__(self):
if self.value == self.H:
return "H/s"
if self.value == self.KH:
return "KH/s"
if self.value == self.MH:
return "MH/s"
if self.value == self.GH:
return "GH/s"
if self.value == self.TH:
return "TH/s"
if self.value == self.PH:
return "PH/s"
if self.value == self.EH:
return "EH/s"
if self.value == self.ZH:
return "ZH/s"
@classmethod
def from_str(cls, value: str):
if value == "H":
return cls.H
elif value == "KH":
return cls.KH
elif value == "MH":
return cls.MH
elif value == "GH":
return cls.GH
elif value == "TH":
return cls.TH
elif value == "PH":
return cls.PH
elif value == "EH":
return cls.EH
elif value == "ZH":
return cls.ZH
return cls.default
def __repr__(self):
return str(self)
# make this json serializable
class _SHA256Algo(str):
unit = SHA256Unit
def __repr__(self):
return "SHA256Algo"
SHA256Algo = _SHA256Algo("SHA256")

30
pyasic/device/firmware.py Normal file
View File

@@ -0,0 +1,30 @@
# ------------------------------------------------------------------------------
# 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 enum import Enum
class MinerFirmware(str, Enum):
STOCK = "Stock"
BRAIINS_OS = "BOS+"
VNISH = "VNish"
EPIC = "ePIC"
HIVEON = "Hive"
LUXOS = "LuxOS"
MARATHON = "MaraFW"
def __str__(self):
return self.value

30
pyasic/device/makes.py Normal file
View File

@@ -0,0 +1,30 @@
# ------------------------------------------------------------------------------
# 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 enum import Enum
class MinerMake(str, Enum):
WHATSMINER = "WhatsMiner"
ANTMINER = "AntMiner"
AVALONMINER = "AvalonMiner"
INNOSILICON = "Innosilicon"
GOLDSHELL = "Goldshell"
AURADINE = "Auradine"
EPIC = "ePIC"
def __str__(self):
return self.value

339
pyasic/device/models.py Normal file
View File

@@ -0,0 +1,339 @@
from enum import Enum
class AntminerModels(str, Enum):
D3 = "D3"
HS3 = "HS3"
L3Plus = "L3+"
DR5 = "DR5"
L7 = "L7"
E9Pro = "E9Pro"
S9 = "S9"
S9i = "S9i"
S9j = "S9j"
T9 = "T9"
Z15 = "Z15"
S17 = "S17"
S17Plus = "S17+"
S17Pro = "S17 Pro"
S17e = "S17e"
T17 = "T17"
T17Plus = "T17+"
T17e = "T17e"
S19 = "S19"
S19NoPIC = "S19 No PIC"
S19L = "S19L"
S19Pro = "S19 Pro"
S19j = "S19j"
S19i = "S19i"
S19Plus = "S19+"
S19jNoPIC = "S19j No PIC"
S19ProPlus = "S19 Pro+"
S19jPro = "S19j Pro"
S19jProNoPIC = "S19j Pro No PIC"
S19jProPlus = "S19j Pro+"
S19jProPlusNoPIC = "S19j Pro+ No PIC"
S19XP = "S19 XP"
S19a = "S19a"
S19aPro = "S19a Pro"
S19Hydro = "S19 Hydro"
S19ProHydro = "S19 Pro Hydro"
S19ProPlusHydro = "S19 Pro+ Hydro"
S19KPro = "S19K Pro"
S19kPro = "S19k Pro"
S19kProNoPIC = "S19k Pro No PIC"
T19 = "T19"
S21 = "S21"
T21 = "T21"
def __str__(self):
return self.value
class WhatsminerModels(str, Enum):
M20V10 = "M20 V10"
M20SV10 = "M20S V10"
M20SV20 = "M20S V20"
M20SV30 = "M20S V30"
M20PV10 = "M20P V10"
M20PV30 = "M20P V30"
M20SPlusV30 = "M20S+ V30"
M21V10 = "M21 V10"
M21SV20 = "M21S V20"
M21SV60 = "M21S V60"
M21SV70 = "M21S V70"
M21SPlusV20 = "M21S+ V20"
M29V10 = "M29 V10"
M30V10 = "M30 V10"
M30V20 = "M30 V20"
M30KV10 = "M30K V10"
M30LV10 = "M30L V10"
M30SV10 = "M30S V10"
M30SV20 = "M30S V20"
M30SV30 = "M30S V30"
M30SV40 = "M30S V40"
M30SV50 = "M30S V50"
M30SV60 = "M30S V60"
M30SV70 = "M30S V70"
M30SV80 = "M30S V80"
M30SVE10 = "M30S VE10"
M30SVE20 = "M30S VE20"
M30SVE30 = "M30S VE30"
M30SVE40 = "M30S VE40"
M30SVE50 = "M30S VE50"
M30SVE60 = "M30S VE60"
M30SVE70 = "M30S VE70"
M30SVF10 = "M30S VF10"
M30SVF20 = "M30S VF20"
M30SVF30 = "M30S VF30"
M30SVG10 = "M30S VG10"
M30SVG20 = "M30S VG20"
M30SVG30 = "M30S VG30"
M30SVG40 = "M30S VG40"
M30SVH10 = "M30S VH10"
M30SVH20 = "M30S VH20"
M30SVH30 = "M30S VH30"
M30SVH40 = "M30S VH40"
M30SVH50 = "M30S VH50"
M30SVH60 = "M30S VH60"
M30SVI20 = "M30S VI20"
M30SPlusV10 = "M30S+ V10"
M30SPlusV20 = "M30S+ V20"
M30SPlusV30 = "M30S+ V30"
M30SPlusV40 = "M30S+ V40"
M30SPlusV50 = "M30S+ V50"
M30SPlusV60 = "M30S+ V60"
M30SPlusV70 = "M30S+ V70"
M30SPlusV80 = "M30S+ V80"
M30SPlusV90 = "M30S+ V90"
M30SPlusV100 = "M30S+ V100"
M30SPlusVE30 = "M30S+ VE30"
M30SPlusVE40 = "M30S+ VE40"
M30SPlusVE50 = "M30S+ VE50"
M30SPlusVE60 = "M30S+ VE60"
M30SPlusVE70 = "M30S+ VE70"
M30SPlusVE80 = "M30S+ VE80"
M30SPlusVE90 = "M30S+ VE90"
M30SPlusVE100 = "M30S+ VE100"
M30SPlusVF20 = "M30S+ VF20"
M30SPlusVF30 = "M30S+ VF30"
M30SPlusVG20 = "M30S+ VG20"
M30SPlusVG30 = "M30S+ VG30"
M30SPlusVG40 = "M30S+ VG40"
M30SPlusVG50 = "M30S+ VG50"
M30SPlusVG60 = "M30S+ VG60"
M30SPlusVH10 = "M30S+ VH10"
M30SPlusVH20 = "M30S+ VH20"
M30SPlusVH30 = "M30S+ VH30"
M30SPlusVH40 = "M30S+ VH40"
M30SPlusVH50 = "M30S+ VH50"
M30SPlusVH60 = "M30S+ VH60"
M30SPlusPlusV10 = "M30S++ V10"
M30SPlusPlusV20 = "M30S++ V20"
M30SPlusPlusVE30 = "M30S++ VE30"
M30SPlusPlusVE40 = "M30S++ VE40"
M30SPlusPlusVE50 = "M30S++ VE50"
M30SPlusPlusVF40 = "M30S++ VF40"
M30SPlusPlusVG30 = "M30S++ VG30"
M30SPlusPlusVG40 = "M30S++ VG40"
M30SPlusPlusVG50 = "M30S++ VG50"
M30SPlusPlusVH10 = "M30S++ VH10"
M30SPlusPlusVH20 = "M30S++ VH20"
M30SPlusPlusVH30 = "M30S++ VH30"
M30SPlusPlusVH40 = "M30S++ VH40"
M30SPlusPlusVH50 = "M30S++ VH50"
M30SPlusPlusVH60 = "M30S++ VH60"
M30SPlusPlusVH70 = "M30S++ VH70"
M30SPlusPlusVH80 = "M30S++ VH80"
M30SPlusPlusVH90 = "M30S++ VH90"
M30SPlusPlusVH100 = "M30S++ VH100"
M30SPlusPlusVJ20 = "M30S++ VJ20"
M30SPlusPlusVJ30 = "M30S++ VJ30"
M31V10 = "M31 V10"
M31V20 = "M31 V20"
M31HV10 = "M31H V10"
M31HV40 = "M31H V40"
M31LV10 = "M30L V10"
M31SV10 = "M31S V10"
M31SV20 = "M31S V20"
M31SV30 = "M31S V30"
M31SV40 = "M31S V40"
M31SV50 = "M31S V50"
M31SV60 = "M31S V60"
M31SV70 = "M31S V70"
M31SV80 = "M31S V80"
M31SV90 = "M31S V90"
M31SVE10 = "M31S VE10"
M31SVE20 = "M31S VE20"
M31SVE30 = "M31S VE30"
M31SEV10 = "M31SE V10"
M31SEV20 = "M31SE V20"
M31SEV30 = "M31SE V30"
M31SPlusV10 = "M31S+ V10"
M31SPlusV20 = "M31S+ V20"
M31SPlusV30 = "M31S+ V30"
M31SPlusV40 = "M31S+ V40"
M31SPlusV50 = "M31S+ V50"
M31SPlusV60 = "M31S+ V60"
M31SPlusV80 = "M31S+ V80"
M31SPlusV90 = "M31S+ V90"
M31SPlusV100 = "M31S+ V100"
M31SPlusVE10 = "M31S+ VE10"
M31SPlusVE20 = "M31S+ VE20"
M31SPlusVE30 = "M31S+ VE30"
M31SPlusVE40 = "M31S+ VE40"
M31SPlusVE50 = "M31S+ VE50"
M31SPlusVE60 = "M31S+ VE60"
M31SPlusVE80 = "M31S+ VE80"
M31SPlusVF20 = "M31S+ VF20"
M31SPlusVF30 = "M31S+ VF30"
M31SPlusVG20 = "M31S+ VG20"
M31SPlusVG30 = "M31S+ VG30"
M32V10 = "M32 V10"
M32V20 = "M32 V20"
M32S = "M32S"
M33V10 = "M33 V10"
M33V20 = "M33 V20"
M33V30 = "M33 V30"
M33SVG30 = "M33S VG30"
M33SPlusVG20 = "M33S+ VG20"
M33SPlusVH20 = "M33S+ VH20"
M33SPlusVH30 = "M33S+ VH30"
M33SPlusPlusVH20 = "M33S++ VH20"
M33SPlusPlusVH30 = "M33S++ VH30"
M33SPlusPlusVG40 = "M33S++ VG40"
M34SPlusVE10 = "M34S+ VE10"
M36SVE10 = "M36S VE10"
M36SPlusVG30 = "M36S+ VG30"
M36SPlusPlusVH30 = "M36S++ VH30"
M39V10 = "M39 V10"
M39V20 = "M39 V20"
M39V30 = "M39 V30"
M50VE30 = "M50 VE30"
M50VG30 = "M50 VG30"
M50VH10 = "M50 VH10"
M50VH20 = "M50 VH20"
M50VH30 = "M50 VH30"
M50VH40 = "M50 VH40"
M50VH50 = "M50 VH50"
M50VH60 = "M50 VH60"
M50VH70 = "M50 VH70"
M50VH80 = "M50 VH80"
M50VJ10 = "M50 VJ10"
M50VJ20 = "M50 VJ20"
M50VJ30 = "M50 VJ30"
M50SVJ10 = "M50S VJ10"
M50SVJ20 = "M50S VJ20"
M50SVJ30 = "M50S VJ30"
M50SVH10 = "M50S VH10"
M50SVH20 = "M50S VH20"
M50SVH30 = "M50S VH30"
M50SVH40 = "M50S VH40"
M50SVH50 = "M50S VH50"
M50SPlusVH30 = "M50S+ VH30"
M50SPlusVH40 = "M50S+ VH40"
M50SPlusVJ30 = "M50S+ VJ30"
M50SPlusVK20 = "M50S+ VK20"
M50SPlusPlusVK10 = "M50S++ VK10"
M50SPlusPlusVK20 = "M50S++ VK20"
M50SPlusPlusVK30 = "M50S++ VK30"
M53VH30 = "M53 VH30"
M53SVH30 = "M53S VH30"
M53SVJ40 = "M53S VJ40"
M53SPlusVJ30 = "M53S+ VJ30"
M53SPlusPlusVK10 = "M53S++ VK10"
M56VH30 = "M56 VH30"
M56SVH30 = "M56S VH30"
M56SPlusVJ30 = "M56S+ VJ30"
M59VH30 = "M59 VH30"
M60VK10 = "M60 VK10"
M60VK20 = "M60 VK20"
M60VK30 = "M60 VK30"
M60VK40 = "M60 VK40"
M60SVK10 = "M60S VK10"
M60SVK20 = "M60S VK20"
M60SVK30 = "M60S VK30"
M60SVK40 = "M60S VK40"
M63VK10 = "M63 VK10"
M63VK20 = "M63 VK20"
M63VK30 = "M63 VK30"
M63SVK10 = "M63S VK10"
M63SVK20 = "M63S VK20"
M63SVK30 = "M63S VK30"
M66VK20 = "M66 VK20"
M66VK30 = "M66 VK30"
M66SVK20 = "M66S VK20"
M66SVK30 = "M66S VK30"
M66SVK40 = "M66S VK40"
def __str__(self):
return self.value
class AvalonminerModels(str, Enum):
Avalon721 = "Avalon 721"
Avalon741 = "Avalon 741"
Avalon761 = "Avalon 761"
Avalon821 = "Avalon 821"
Avalon841 = "Avalon 841"
Avalon851 = "Avalon 851"
Avalon921 = "Avalon 921"
Avalon1026 = "Avalon 1026"
Avalon1047 = "Avalon 1047"
Avalon1066 = "Avalon 1066"
Avalon1166Pro = "Avalon 1166 Pro"
Avalon1246 = "Avalon 1246"
def __str__(self):
return self.value
class InnosiliconModels(str, Enum):
T3HPlus = "T3H+"
A10X = "A10X"
def __str__(self):
return self.value
class GoldshellModels(str, Enum):
CK5 = "CK5"
HS5 = "HS5"
KD5 = "KD5"
KDMax = "KD Max"
KDBoxII = "KD Box II"
KDBoxPro = "KD Box Pro"
def __str__(self):
return self.value
class ePICModels(str, Enum):
BM520i = "BlockMiner 520i"
BM720i = "BlockMiner 720i"
def __str__(self):
return self.value
class AuradineModels(str, Enum):
AT1500 = "AT1500"
AT2860 = "AT2860"
AT2880 = "AT2880"
AI2500 = "AI2500"
AI3680 = "AI3680"
AD2500 = "AD2500"
AD3500 = "AD3500"
def __str__(self):
return self.value
class MinerModel:
ANTMINER = AntminerModels
WHATSMINER = WhatsminerModels
AVALONMINER = AvalonminerModels
INNOSILICON = InnosiliconModels
GOLDSHELL = GoldshellModels
AURADINE = AuradineModels
EPIC = ePICModels

View File

@@ -20,7 +20,16 @@ from typing import List, Union
from pyasic.errors import APIError
from pyasic.miners import AnyMiner
from pyasic.miners.backends import AntminerModern, BOSMiner, BTMiner
from pyasic.miners.models import S9, S17, T17, S17e, S17Plus, S17Pro, T17e, T17Plus
from pyasic.miners.device.models import (
S9,
S17,
T17,
S17e,
S17Plus,
S17Pro,
T17e,
T17Plus,
)
FAN_USAGE = 50 # 50 W per fan

View File

@@ -20,4 +20,5 @@ from .cgminer import *
from .epic import *
from .hiveon import *
from .luxos import *
from .marathon import *
from .vnish import *

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerOld
from pyasic.miners.models import S17, S17e, S17Plus, S17Pro
from pyasic.miners.device.models import S17, S17e, S17Plus, S17Pro
class BMMinerS17(AntminerOld, S17):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerOld
from pyasic.miners.models import T17, T17e, T17Plus
from pyasic.miners.device.models import T17, T17e, T17Plus
class BMMinerT17(AntminerOld, T17):

View File

@@ -15,20 +15,23 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerModern
from pyasic.miners.models import (
from pyasic.miners.device.models import (
S19,
S19L,
S19XP,
S19a,
S19aPro,
S19Hydro,
S19i,
S19j,
S19jNoPIC,
S19jPro,
S19KPro,
S19Plus,
S19Pro,
S19ProHydro,
S19ProPlus,
S19ProPlusHydro,
)
@@ -82,3 +85,15 @@ class BMMinerS19L(AntminerModern, S19L):
class BMMinerS19ProHydro(AntminerModern, S19ProHydro):
pass
class BMMinerS19Hydro(AntminerModern, S19Hydro):
pass
class BMMinerS19ProPlusHydro(AntminerModern, S19ProPlusHydro):
pass
class BMMinerS19KPro(AntminerModern, S19KPro):
pass

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerModern
from pyasic.miners.models import T19
from pyasic.miners.device.models import T19
class BMMinerT19(AntminerModern, T19):

View File

@@ -18,6 +18,7 @@ from .S19 import (
BMMinerS19,
BMMinerS19a,
BMMinerS19aPro,
BMMinerS19Hydro,
BMMinerS19i,
BMMinerS19j,
BMMinerS19jNoPIC,
@@ -27,6 +28,8 @@ from .S19 import (
BMMinerS19Pro,
BMMinerS19ProHydro,
BMMinerS19ProPlus,
BMMinerS19ProPlusHydro,
BMMinerS19XP,
BMMinerS19KPro,
)
from .T19 import BMMinerT19

View File

@@ -0,0 +1,22 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerModern
from pyasic.miners.device.models import S21
class BMMinerS21(AntminerModern, S21):
pass

View File

@@ -0,0 +1,22 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerModern
from pyasic.miners.device.models import T21
class BMMinerT21(AntminerModern, T21):
pass

View File

@@ -0,0 +1,17 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from .S21 import BMMinerS21
from .T21 import BMMinerT21

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerModern
from pyasic.miners.models import HS3
from pyasic.miners.device.models import HS3
class BMMinerHS3(AntminerModern, HS3):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerOld
from pyasic.miners.models import L3Plus
from pyasic.miners.device.models import L3Plus
class BMMinerL3Plus(AntminerOld, L3Plus):

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerModern
from pyasic.miners.models import L7
from pyasic.miners.device.models import L7
class BMMinerL7(AntminerModern, L7):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerModern
from pyasic.miners.models import E9Pro
from pyasic.miners.device.models import E9Pro
class BMMinerE9Pro(AntminerModern, E9Pro):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import BMMiner
from pyasic.miners.models import S9, S9i, S9j
from pyasic.miners.device.models import S9, S9i, S9j
class BMMinerS9(BMMiner, S9):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import BMMiner
from pyasic.miners.models import T9
from pyasic.miners.device.models import T9
class BMMinerT9(BMMiner, T9):

View File

@@ -18,3 +18,4 @@ from .X7 import *
from .X9 import *
from .X17 import *
from .X19 import *
from .X21 import *

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import BOSMiner
from pyasic.miners.models import S17, S17e, S17Plus, S17Pro
from pyasic.miners.device.models import S17, S17e, S17Plus, S17Pro
class BOSMinerS17(BOSMiner, S17):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import BOSMiner
from pyasic.miners.models import T17, T17e, T17Plus
from pyasic.miners.device.models import T17, T17e, T17Plus
class BOSMinerT17(BOSMiner, T17):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import BOSer
from pyasic.miners.models import (
from pyasic.miners.device.models import (
S19,
S19XP,
S19a,
@@ -23,7 +23,9 @@ from pyasic.miners.models import (
S19j,
S19jNoPIC,
S19jPro,
S19jProNoPIC,
S19jProPlus,
S19jProPlusNoPIC,
S19kProNoPIC,
S19Plus,
S19Pro,
@@ -58,6 +60,10 @@ class BOSMinerS19jPro(BOSer, S19jPro):
pass
class BOSMinerS19jProNoPIC(BOSer, S19jProNoPIC):
pass
class BOSMinerS19kProNoPIC(BOSer, S19kProNoPIC):
pass
@@ -70,5 +76,9 @@ class BOSMinerS19jProPlus(BOSer, S19jProPlus):
pass
class BOSMinerS19jProPlusNoPIC(BOSer, S19jProPlusNoPIC):
pass
class BOSMinerS19XP(BOSer, S19XP):
pass

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import BOSer
from pyasic.miners.models import T19
from pyasic.miners.device.models import T19
class BOSMinerT19(BOSer, T19):

View File

@@ -21,7 +21,9 @@ from .S19 import (
BOSMinerS19j,
BOSMinerS19jNoPIC,
BOSMinerS19jPro,
BOSMinerS19jProNoPIC,
BOSMinerS19jProPlus,
BOSMinerS19jProPlusNoPIC,
BOSMinerS19kProNoPIC,
BOSMinerS19Plus,
BOSMinerS19Pro,

View File

@@ -0,0 +1,22 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import BOSer
from pyasic.miners.device.models import S21
class BOSMinerS21(BOSer, S21):
pass

View File

@@ -14,6 +14,4 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from .S21 import (
S21,
)
from .S21 import BOSMinerS21

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import BOSMiner
from pyasic.miners.models import S9
from pyasic.miners.device.models import S9
class BOSMinerS9(BOSMiner, S9):

View File

@@ -17,3 +17,4 @@
from .X9 import *
from .X17 import *
from .X19 import *
from .X21 import *

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerOld
from pyasic.miners.models import Z15
from pyasic.miners.device.models import Z15
class CGMinerZ15(AntminerOld, Z15):

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerOld
from pyasic.miners.models import D3
from pyasic.miners.device.models import D3
class CGMinerD3(AntminerOld, D3):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AntminerOld
from pyasic.miners.models import DR5
from pyasic.miners.device.models import DR5
class CGMinerDR5(AntminerOld, DR5):

View File

@@ -15,7 +15,15 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import ePIC
from pyasic.miners.models import S19, S19XP, S19j, S19jPro, S19jProPlus, S19kPro, S19Pro
from pyasic.miners.device.models import (
S19,
S19XP,
S19j,
S19jPro,
S19jProPlus,
S19kPro,
S19Pro,
)
class ePICS19(ePIC, S19):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import ePIC
from pyasic.miners.models import S21
from pyasic.miners.device.models import S21
class ePICS21(ePIC, S21):

View File

@@ -0,0 +1,22 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import ePIC
from pyasic.miners.device.models import T21
class ePICT21(ePIC, T21):
pass

View File

@@ -17,3 +17,7 @@
from .S21 import (
ePICS21,
)
from .T21 import (
ePICT21,
)

View File

@@ -18,11 +18,11 @@ from typing import List, Optional
import asyncssh
from pyasic.data import HashBoard
from pyasic.data import AlgoHashRate, HashBoard, HashUnit
from pyasic.errors import APIError
from pyasic.miners.backends import Hiveon
from pyasic.miners.data import DataFunction, DataLocations, DataOptions, RPCAPICommand
from pyasic.miners.models import T9
from pyasic.miners.device.models import T9
HIVEON_T9_DATA_LOC = DataLocations(
**{
@@ -121,7 +121,9 @@ class HiveonT9(Hiveon, T9):
chips += rpc_stats["STATS"][1][f"chain_acn{chipset}"]
except (KeyError, IndexError):
pass
hashboards[board].hashrate = round(hashrate / 1000, 2)
hashboards[board].hashrate = AlgoHashRate.SHA256(
hashrate, HashUnit.SHA256.GH
).into(self.algo.unit.default)
hashboards[board].chips = chips
return hashboards

View File

@@ -15,7 +15,14 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import LUXMiner
from pyasic.miners.models import S19, S19XP, S19jPro, S19jProPlus, S19kPro, S19Pro
from pyasic.miners.device.models import (
S19,
S19XP,
S19jPro,
S19jProPlus,
S19kPro,
S19Pro,
)
class LUXMinerS19(LUXMiner, S19):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import LUXMiner
from pyasic.miners.models import T19
from pyasic.miners.device.models import T19
class LUXMinerT19(LUXMiner, T19):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import LUXMiner
from pyasic.miners.models import S21
from pyasic.miners.device.models import S21
class LUXMinerS21(LUXMiner, S21):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import LUXMiner
from pyasic.miners.models import S9
from pyasic.miners.device.models import S9
class LUXMinerS9(LUXMiner, S9):

View File

@@ -0,0 +1,54 @@
# ------------------------------------------------------------------------------
# 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 MaraMiner
from pyasic.miners.device.models import (
S19,
S19XP,
S19j,
S19jNoPIC,
S19jPro,
S19KPro,
S19Pro,
)
class MaraS19(MaraMiner, S19):
pass
class MaraS19Pro(MaraMiner, S19Pro):
pass
class MaraS19XP(MaraMiner, S19XP):
pass
class MaraS19j(MaraMiner, S19j):
pass
class MaraS19jNoPIC(MaraMiner, S19jNoPIC):
pass
class MaraS19jPro(MaraMiner, S19jPro):
pass
class MaraS19KPro(MaraMiner, S19KPro):
pass

View File

@@ -0,0 +1,9 @@
from .S19 import (
MaraS19,
MaraS19j,
MaraS19jNoPIC,
MaraS19jPro,
MaraS19KPro,
MaraS19Pro,
MaraS19XP,
)

View File

@@ -0,0 +1,22 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import MaraMiner
from pyasic.miners.device.models import S21
class MaraS21(MaraMiner, S21):
pass

View File

@@ -0,0 +1,22 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import MaraMiner
from pyasic.miners.device.models import T21
class MaraT21(MaraMiner, T21):
pass

View File

@@ -0,0 +1,2 @@
from .S21 import MaraS21
from .T21 import MaraT21

View File

@@ -0,0 +1,2 @@
from .X19 import *
from .X21 import *

View File

@@ -14,7 +14,7 @@
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import VNish
from pyasic.miners.models import S17Plus, S17Pro
from pyasic.miners.device.models import S17Plus, S17Pro
class VNishS17Plus(VNish, S17Plus):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import VNish
from pyasic.miners.models import (
from pyasic.miners.device.models import (
S19,
S19XP,
S19a,

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import VNish
from pyasic.miners.models import T19
from pyasic.miners.device.models import T19
class VNishT19(VNish, T19):

View File

@@ -0,0 +1,22 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from pyasic.miners.backends import VNish
from pyasic.miners.device.models import S21
class VNishS21(VNish, S21):
pass

View File

@@ -0,0 +1,17 @@
# ------------------------------------------------------------------------------
# Copyright 2022 Upstream Data Inc -
# -
# Licensed under the Apache License, Version 2.0 (the "License"); -
# you may not use this file except in compliance with the License. -
# You may obtain a copy of the License at -
# -
# http://www.apache.org/licenses/LICENSE-2.0 -
# -
# Unless required by applicable law or agreed to in writing, software -
# distributed under the License is distributed on an "AS IS" BASIS, -
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -
# See the License for the specific language governing permissions and -
# limitations under the License. -
# ------------------------------------------------------------------------------
from .S21 import VNishS21

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import VNish
from pyasic.miners.models import L3Plus
from pyasic.miners.device.models import L3Plus
class VnishL3Plus(VNish, L3Plus):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import VNish
from pyasic.miners.models import L7
from pyasic.miners.device.models import L7
class VnishL7(VNish, L7):

View File

@@ -18,3 +18,4 @@ from .X3 import *
from .X7 import *
from .X17 import *
from .X19 import *
from .X21 import *

View File

@@ -1,5 +1,5 @@
from pyasic.miners.backends import Auradine
from pyasic.miners.models import AuradineAT1500
from pyasic.miners.device.models import AuradineAT1500
class AuradineFluxAT1500(AuradineAT1500, Auradine):

View File

@@ -1,5 +1,5 @@
from pyasic.miners.backends import Auradine
from pyasic.miners.models import AuradineAT2860, AuradineAT2880
from pyasic.miners.device.models import AuradineAT2860, AuradineAT2880
class AuradineFluxAT2860(AuradineAT2860, Auradine):

View File

@@ -1,5 +1,5 @@
from pyasic.miners.backends import Auradine
from pyasic.miners.models import AuradineAI2500
from pyasic.miners.device.models import AuradineAI2500
class AuradineFluxAI2500(AuradineAI2500, Auradine):

View File

@@ -1,5 +1,5 @@
from pyasic.miners.backends import Auradine
from pyasic.miners.models import AuradineAI3680
from pyasic.miners.device.models import AuradineAI3680
class AuradineFluxAI3680(AuradineAI3680, Auradine):

View File

@@ -1,5 +1,5 @@
from pyasic.miners.backends import Auradine
from pyasic.miners.models import AuradineAD2500
from pyasic.miners.device.models import AuradineAD2500
class AuradineFluxAD2500(AuradineAD2500, Auradine):

View File

@@ -1,5 +1,5 @@
from pyasic.miners.backends import Auradine
from pyasic.miners.models import AuradineAD3500
from pyasic.miners.device.models import AuradineAD3500
class AuradineFluxAD3500(AuradineAD3500, Auradine):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AvalonMiner
from pyasic.miners.models import Avalon1026
from pyasic.miners.device.models import Avalon1026
class CGMinerAvalon1026(AvalonMiner, Avalon1026):

View File

@@ -15,7 +15,7 @@
# ------------------------------------------------------------------------------
from pyasic.miners.backends import AvalonMiner
from pyasic.miners.models import Avalon1047
from pyasic.miners.device.models import Avalon1047
class CGMinerAvalon1047(AvalonMiner, Avalon1047):

Some files were not shown because too many files have changed in this diff Show More