Compare commits

...

1337 Commits

Author SHA1 Message Date
b-rowan
a2c2aa2377 version: bump version number. 2024-01-27 09:26:13 -07:00
b-rowan
4f0eb49a02 bug: fix some issues with epic send config. 2024-01-27 09:25:20 -07:00
b-rowan
a821357b4f Merge pull request #102 from jpcomps/master
fix send_config for ePIC
2024-01-27 09:05:23 -07:00
John-Paul Compagnone
3c7679a22d fix send_config for ePIC 2024-01-27 10:50:37 -05:00
UpstreamData
a52737e236 refactor: add some type hints for epic config. 2024-01-26 13:58:08 -07:00
UpstreamData
7c96bbe153 version: bump version number. 2024-01-26 13:56:15 -07:00
UpstreamData
e8bbf22aa7 bug: fix a bug with epic mining mode configs. 2024-01-26 13:55:54 -07:00
UpstreamData
5ac8b27cb6 version: bump version number. 2024-01-26 12:49:45 -07:00
UpstreamData
6c14902484 Add ePIC send_config and config.as_epic (#101)
* feature: Add epic send_config.

* feature: remove UID from epic config.

* feature: add default for temp configs in epic.
2024-01-26 12:47:19 -07:00
UpstreamData
96aa346f00 refactor: rename miner.api to miner.rpc. Add miner.api property linked to miner.rpc. 2024-01-26 10:15:20 -07:00
UpstreamData
c2b6cc7468 refactor: improve validate_command_output, and move it out of the miner rpc api. 2024-01-26 09:51:09 -07:00
UpstreamData
ac7f41be44 refactor: move bind addr to init in MinerListener. 2024-01-25 16:34:46 -07:00
UpstreamData
718b87fd12 refactor: rename overwritten method. 2024-01-25 16:32:33 -07:00
UpstreamData
5ad23c6cd0 refactor: remove unused imports. 2024-01-25 16:31:19 -07:00
UpstreamData
66be443dc3 refactor: re-arrange some imports. 2024-01-25 16:25:25 -07:00
UpstreamData
a9135e21d4 docs: update docs. 2024-01-25 14:35:31 -07:00
UpstreamData
dd4c087749 refactor: move base classes to base.py in their directories, move data locations to miners.data, and rename types to models. 2024-01-25 14:26:53 -07:00
UpstreamData
aa1d7c1b6f refactor: make web handlers much more consistent across types, remove graphql, and make luci and grpc the dedicated web apis for BOSer and BOSMiner respectively. 2024-01-25 13:50:04 -07:00
UpstreamData
b328a27f04 refactor: Update config to use future annotations and move merge_dicts to misc. 2024-01-25 11:32:03 -07:00
UpstreamData
c5eed797ec refactor: update type annotations in config. 2024-01-25 10:07:19 -07:00
b-rowan
4fd2199435 version: bump version number. 2024-01-24 18:39:50 -07:00
b-rowan
3226d47846 Merge branch 'dev_fluxos' 2024-01-24 18:39:12 -07:00
b-rowan
6c1931fe7e bug: fix some naming issues with auradine, and add chip count for AT1500. 2024-01-24 18:37:29 -07:00
b-rowan
1dd87ac102 feature: add expected chips for M50S++VK10 2024-01-24 18:32:50 -07:00
b-rowan
95d1e40b4f bug: fix auradine fan config parsing. 2024-01-24 18:28:10 -07:00
b-rowan
31682b7fae bug: fix auradine fan data and config parsing. 2024-01-24 18:22:28 -07:00
b-rowan
e6523fc7d5 bug: fix auradine wattage data. 2024-01-24 18:18:11 -07:00
b-rowan
91de12467b bug: add multicommand flag to auradine multicommand output. 2024-01-24 18:08:22 -07:00
b-rowan
d81e3e9f88 bug: fix auradine multicommand format for get_data. 2024-01-24 18:05:32 -07:00
b-rowan
49fc0f3c54 bug: fix auradine hashboards. 2024-01-24 17:55:47 -07:00
b-rowan
4b36044e56 bug: fix auradine web api token format. 2024-01-24 17:45:42 -07:00
b-rowan
90fb67f586 bug: fix auradine web api token. 2024-01-24 17:38:49 -07:00
b-rowan
edf31ae7df bug: fix auradine identification. 2024-01-24 17:33:41 -07:00
b-rowan
af354fd8e2 feature: add auradine to web selection options. 2024-01-24 17:17:03 -07:00
UpstreamData
6a2a3e836d bug: fix auradine selection. 2024-01-24 16:23:25 -07:00
b-rowan
41709e4706 feature: add auradine data functions. 2024-01-23 16:15:34 -07:00
b-rowan
b60c7a55d4 feature: add auradine control functions. 2024-01-23 15:28:37 -07:00
b-rowan
eed1973345 feature: add auradine models. 2024-01-23 14:23:57 -07:00
b-rowan
64774d2017 feature: add basic auradine miner framework. 2024-01-23 14:06:54 -07:00
b-rowan
e9751d6cd1 version: bump version number. 2024-01-22 19:54:52 -07:00
b-rowan
e2b0a76e67 bug: fix unneeded error handling when getting hostname fails. 2024-01-22 19:40:07 -07:00
b-rowan
1c5c39fa97 version: bump version number. 2024-01-22 18:43:34 -07:00
b-rowan
27c48764a8 refactor: remove miner factory cache. 2024-01-22 18:41:19 -07:00
UpstreamData
5e01f7517b version: bump version number. 2024-01-22 13:39:52 -07:00
b-rowan
569f659fac Merge pull request #96 from fdeh75/fix-vnish-wattage-dimension
Fix vnish wattage dimension
2024-01-22 13:38:27 -07:00
fdeh
dd9c6f1f63 Fix vnish wattage dimension
Update backend vnish.py
2024-01-22 23:17:27 +03:00
b-rowan
0958f47cfe version: bump version number. 2024-01-21 14:39:35 -07:00
b-rowan
3820b40f44 bug: Fix DataLocations defaulting to all get_config. 2024-01-21 14:39:01 -07:00
b-rowan
cce1917c00 version: bump version number. 2024-01-21 12:28:44 -07:00
b-rowan
2ee19f47e7 bug: fix failing configuration on BOSminer. 2024-01-21 12:28:11 -07:00
b-rowan
ff526a3273 version: bump version number. 2024-01-21 10:39:48 -07:00
b-rowan
7811245ec9 Merge pull request #95 from UpstreamData/dev_quality
Improve overall code quality, move ssh to `miner.ssh`, remove `pwd` for miners.
2024-01-21 10:39:01 -07:00
b-rowan
cbab76847a refactor: remove BBB check for BOSMiner. 2024-01-21 10:15:44 -07:00
upstreamdata
ce981d1787 refactor: reformat. 2024-01-18 15:47:52 -07:00
upstreamdata
4b5314a8f6 refactor: move ssh to miner.ssh 2024-01-18 15:32:09 -07:00
UpstreamData
3be3086a38 docs: fix issues with docs. 2024-01-16 15:55:01 -07:00
UpstreamData
a0c76fe24f refactor: remove unused imports. 2024-01-16 15:36:55 -07:00
UpstreamData
acdcfd04cd refactor: remove unneeded lambda and remove pass. 2024-01-16 15:34:06 -07:00
UpstreamData
91a5998b4e refactor: remove unneeded lambda. 2024-01-16 15:31:31 -07:00
UpstreamData
7292af450c refactor: improve RPC handlers. 2024-01-16 15:26:32 -07:00
UpstreamData
307926afbb refactor: use protocol for BaseMiner and update attributes to be part of the class rather than a __init__ method. 2024-01-16 14:47:43 -07:00
UpstreamData
10293ae24a refactor: add default values for data locations to reduce duplication. 2024-01-16 09:31:23 -07:00
UpstreamData
f820372532 refactor: remove some duplicated code in rpc APIs. 2024-01-16 08:57:46 -07:00
UpstreamData
22965ffefa refactor: fix not x is None 2024-01-16 08:40:47 -07:00
UpstreamData
34ca5ba68f refactor: shorten some lines. 2024-01-16 08:39:15 -07:00
UpstreamData
468134e754 refactor: fix some not x in y and not x not in y 2024-01-16 08:36:31 -07:00
UpstreamData
5327b3fe3d refactor: remove unused variables. 2024-01-16 08:16:21 -07:00
UpstreamData
68b85aa7da refactor: remove some useless logging statements, and remove some unused imports. 2024-01-16 08:15:24 -07:00
UpstreamData
b78652b279 refactor: remove some unused variables. 2024-01-15 16:23:54 -07:00
UpstreamData
832a276f4b refactor: remove some unused pass statements. 2024-01-15 16:16:08 -07:00
UpstreamData
2b82b29690 refactor: remove some duplicate classes, and rename UnknownMiner get methods. 2024-01-15 16:03:40 -07:00
UpstreamData
56dd1c80b5 refactor: remove and fix some hardcoded passwords. 2024-01-15 15:53:10 -07:00
UpstreamData
d686cdacc8 refactor: change some if statements to if is not None. 2024-01-15 15:43:31 -07:00
UpstreamData
aab8825997 refactor: rename API to rpc, and classes from {X}API to {X}RPCAPI to clarify naming. 2024-01-15 15:09:51 -07:00
UpstreamData
4ed49c2321 version: bump version number. 2024-01-15 14:59:29 -07:00
UpstreamData
c069468803 bug: fix some bugs with epic, update miner repr, and remove get_model from braiinsOS. 2024-01-15 14:58:54 -07:00
UpstreamData
707cf8b848 version: bump version number. 2024-01-15 14:29:04 -07:00
UpstreamData
170843aae7 bug: add handler for failed get_data calls to make errors more verbose. 2024-01-15 14:28:39 -07:00
UpstreamData
f5acf9ec62 Merge branch 'dev_boser'
# Conflicts:
#	pyasic/miners/antminer/hiveon/X9/T9.py
#	pyasic/miners/backends/bosminer_old.py
#	pyasic/miners/backends/braiins_os.py
#	pyasic/miners/backends/btminer.py
#	pyasic/miners/backends/cgminer_avalon.py
#	pyasic/miners/backends/epic.py
#	pyasic/miners/backends/hiveon.py
#	pyasic/miners/backends/innosilicon.py
#	pyasic/miners/base.py
#	tests/miners_tests/__init__.py
2024-01-15 14:25:02 -07:00
UpstreamData
edaf89c73a refactor: fix some formatting issues and bugs. 2024-01-15 14:18:41 -07:00
UpstreamData
ce34dfdde8 bug: fix fault_light check for boser. 2024-01-15 14:00:51 -07:00
UpstreamData
e45e51ce65 refactor: fix merge. 2024-01-15 13:09:23 -07:00
UpstreamData
f1501718a3 feature: finish get_data functions for bosminer 2024-01-15 10:48:03 -07:00
UpstreamData
831d6ee955 feature: add boser fault light functions. 2024-01-15 10:48:02 -07:00
UpstreamData
7be6596fdd refactor: swap except (KeyError, ValueError) to except LookupError. 2024-01-15 10:48:02 -07:00
b-rowan
928e0dd028 feature: start refactoring BOSer and BOSMiner into separate classes. 2024-01-15 10:48:00 -07:00
UpstreamData
672e753afb bug: add test to cross check function arguments, and fix some method implementations and naming. 2024-01-15 10:47:56 -07:00
UpstreamData
269e6aac14 bug: add more tests and finish renaming methods. 2024-01-15 10:47:40 -07:00
UpstreamData
1a4f3f7dc7 bug: make sure all data locations are accurate. 2024-01-15 10:47:40 -07:00
UpstreamData
b0337e8417 refactor: swap (KeyError, IndexError) for LookupError. 2024-01-15 10:47:40 -07:00
UpstreamData
60f3687d02 refactor: optimize imports. 2024-01-15 10:47:39 -07:00
UpstreamData
a8c45cb95d refactor: remove parameters from get_{x} functions and move them to _get_{x}(**params). Add miner.fw_str, and miner.raw_model. Remove model from get_data exclude. Swap fan_count to expected_fans. 2024-01-15 10:47:39 -07:00
UpstreamData
aa9ba66f8e bug: add test to cross check function arguments, and fix some method implementations and naming. 2024-01-15 10:47:39 -07:00
UpstreamData
06cc84f16d refactor: remove parameters from get_{x} functions and move them to _get_{x}(**params). Add miner.fw_str, and miner.raw_model. Remove model from get_data exclude. Swap fan_count to expected_fans. 2024-01-15 10:47:38 -07:00
fdeh
067d5c98f5 Fix VNish get_hashrate and get_fans errors
Update vnish.py. Fix data locations according to the method arguments
2024-01-15 10:47:38 -07:00
UpstreamData
b4b84c773f refactor: remove bad function. 2024-01-15 10:47:38 -07:00
UpstreamData
cd1768aae9 refactor: swap (KeyError, IndexError) for LookupError. 2024-01-15 10:47:37 -07:00
UpstreamData
2ef85d3868 refactor: optimize imports. 2024-01-15 10:47:36 -07:00
UpstreamData
6f64cc5e0d refactor: remove parameters from get_{x} functions and move them to _get_{x}(**params). Add miner.fw_str, and miner.raw_model. Remove model from get_data exclude. Swap fan_count to expected_fans. 2024-01-15 10:47:33 -07:00
b-rowan
d44907435c Merge pull request #91 from UpstreamData/dev_get_params
Move parameters to private methods for `get_{x}` methods
2024-01-15 10:43:08 -07:00
b-rowan
04ca75d00e Merge branch 'master' into dev_get_params 2024-01-15 10:42:37 -07:00
UpstreamData
b56e94ce8c bug: add more tests and finish renaming methods. 2024-01-15 10:35:15 -07:00
UpstreamData
e7d30aad84 bug: make sure all data locations are accurate. 2024-01-15 10:29:39 -07:00
UpstreamData
194fb539a1 refactor: swap (KeyError, IndexError) for LookupError. 2024-01-15 10:23:58 -07:00
UpstreamData
416ea2964b refactor: optimize imports. 2024-01-15 10:23:57 -07:00
UpstreamData
3234f7e06f refactor: remove parameters from get_{x} functions and move them to _get_{x}(**params). Add miner.fw_str, and miner.raw_model. Remove model from get_data exclude. Swap fan_count to expected_fans. 2024-01-15 10:23:57 -07:00
UpstreamData
8fb357544b bug: add test to cross check function arguments, and fix some method implementations and naming. 2024-01-15 10:23:55 -07:00
UpstreamData
34006941ad bug: add test to cross check function arguments, and fix some method implementations and naming. 2024-01-15 10:16:47 -07:00
UpstreamData
3c3c34c54b Merge branch 'master' into dev_get_params 2024-01-15 08:10:46 -07:00
b-rowan
5a61a87766 docs: update docs. 2024-01-14 12:59:13 -07:00
b-rowan
ef9a026ee8 docs: update docs. 2024-01-14 12:58:11 -07:00
b-rowan
71c85e0603 bug: fix a possible failed authentication when using gRPC. 2024-01-14 12:09:29 -07:00
UpstreamData
c5224b808e refactor: remove parameters from get_{x} functions and move them to _get_{x}(**params). Add miner.fw_str, and miner.raw_model. Remove model from get_data exclude. Swap fan_count to expected_fans. 2024-01-14 10:02:50 -07:00
b-rowan
e4c6d751a1 version: bump version number. 2024-01-14 10:02:38 -07:00
fdeh
ff4dfa124b Fix VNish get_hashrate and get_fans errors
Update vnish.py. Fix data locations according to the method arguments
2024-01-14 10:02:38 -07:00
b-rowan
d0eb5119aa version: bump version number. 2024-01-14 10:00:15 -07:00
fdeh
cfa51623c4 Fix VNish get_hashrate and get_fans errors
Update vnish.py. Fix data locations according to the method arguments
2024-01-14 10:00:15 -07:00
b-rowan
96bb56ebd1 version: bump version number. 2024-01-14 09:59:06 -07:00
b-rowan
cdd7beccbe Merge pull request #92 from fdeh75/fix-vnish-data-gathering
Fix VNish get_hashrate and get_fans errors
2024-01-14 09:58:16 -07:00
fdeh
1a544851df Fix VNish get_hashrate and get_fans errors
Update vnish.py. Fix data locations according to the method arguments
2024-01-14 19:53:47 +03:00
UpstreamData
aa2dc5a53d feature: update some gRPC functions, and add as_boser for some of the MinerConfig values. 2024-01-12 15:06:44 -07:00
UpstreamData
361d6e07cc feature: finish get_data functions for bosminer 2024-01-12 13:29:46 -07:00
UpstreamData
53a018f526 feature: add boser fault light functions. 2024-01-12 11:58:26 -07:00
UpstreamData
6c9a378eee feature: add boser config parsing. 2024-01-12 11:54:17 -07:00
UpstreamData
be67ef3471 refactor: remove bad function. 2024-01-11 15:29:29 -07:00
UpstreamData
a094d28a36 refactor: swap (KeyError, IndexError) for LookupError. 2024-01-11 15:20:33 -07:00
UpstreamData
4156f93c0d refactor: optimize imports. 2024-01-11 15:00:48 -07:00
UpstreamData
ed6eb11653 bug: fix being unable to get fw version as part of multicommand. 2024-01-11 13:57:48 -07:00
snyk-bot
39299f2cfa fix: docs/requirements.txt to reduce vulnerabilities
The following vulnerabilities are fixed by pinning transitive dependencies:
- https://snyk.io/vuln/SNYK-PYTHON-JINJA2-6150717
2024-01-11 11:37:01 -07:00
snyk-bot
c80ca1415a fix: docs/requirements.txt to reduce vulnerabilities
The following vulnerabilities are fixed by pinning transitive dependencies:
- https://snyk.io/vuln/SNYK-PYTHON-JINJA2-6150717
2024-01-11 11:36:05 -07:00
UpstreamData
a8428a2739 refactor: remove parameters from get_{x} functions and move them to _get_{x}(**params). Add miner.fw_str, and miner.raw_model. Remove model from get_data exclude. Swap fan_count to expected_fans. 2024-01-11 11:33:44 -07:00
UpstreamData
895fb1b43e refactor: swap except (KeyError, ValueError) to except LookupError. 2024-01-11 10:20:18 -07:00
UpstreamData
014896ae1b bug: fix data passed by get_version to BOSminer. 2024-01-11 09:53:06 -07:00
snyk-bot
84ac991685 fix: docs/requirements.txt to reduce vulnerabilities
The following vulnerabilities are fixed by pinning transitive dependencies:
- https://snyk.io/vuln/SNYK-PYTHON-JINJA2-6150717
2024-01-11 16:00:03 +00:00
b-rowan
bb481553fa bug: fix missing message in grpc command. 2024-01-10 22:46:58 -07:00
b-rowan
7ab3d8b54e feature: improve data gathering slightly on BOSMiner. 2024-01-10 22:26:28 -07:00
b-rowan
36494f2aca bug: remove boser check in miner_factory, and fix bad syntax on comparison. 2024-01-10 22:15:31 -07:00
b-rowan
bea44a72ea feature: start refactoring BOSer and BOSMiner into separate classes. 2024-01-10 22:12:27 -07:00
b-rowan
9da7b44177 feature: add vnish config parsing. 2024-01-06 11:31:12 -07:00
UpstreamData
e7f05f7a28 version: bump version number. 2024-01-05 16:22:03 -07:00
UpstreamData
2d229be9fd feature: add board serial numbers to whatsminers. 2024-01-05 16:18:03 -07:00
UpstreamData
de5038e57a feature: add AntminerModern serial numbers to Hashboard data. 2024-01-05 15:57:26 -07:00
UpstreamData
8ad1b3f72a refactor: fix formatting issue. 2024-01-05 08:49:44 -07:00
b-rowan
070fb26dbc version: bump version number. 2024-01-04 20:58:44 -07:00
b-rowan
80d9d7df1d bug: fix possible empty command when getting small data points. 2024-01-04 20:58:15 -07:00
UpstreamData
928c24f56f version: bump version number. 2024-01-04 13:07:13 -07:00
UpstreamData
6e7442f90d Update data locations to be typed with dataclasses and enums. (#82)
* feature: swap AntminerModern to new data location style.

* bug: fix a bunch of missed instances of `nominal_` naming.

* feature: add support for S19 Pro Hydro.

* version: bump version number.

* dependencies: bump httpx version

* version: bump version number.

* feature: implement data locations for all remaining miners.

* refactor: remove some unused docstrings.

* feature: swap AntminerModern to new data location style.

* feature: implement data locations for all remaining miners.

* refactor: remove some unused docstrings.

* bug: fix misnamed data locations, and update base miner get_data to use new data locations.

* bug: fix include/exclude implementation on get_data.

* bug: swap ePIC to BaseMiner subclass.

* feature: add DataOptions to __all__

* tests: update data tests with new data locations method.

* bug: remove bad command from bosminer commands.

* dependencies: update dependencies.

* bug: fix some typing issues with python 3.8, and remove useless semaphore and scan threads.

* bug: fix KeyError when pools rpc command returns broken data.
2024-01-04 13:03:45 -07:00
b-rowan
936474ed3b Merge pull request #84 from jpcomps/master 2023-12-23 13:07:47 -07:00
John-Paul Compagnone
2e28060e05 fixes, changes, and formatting 2023-12-23 15:01:42 -05:00
John-Paul Compagnone
07f92557c6 cover chiptune case 2023-12-22 23:35:13 -05:00
John-Paul Compagnone
6f6f5743cf add get_config to ePIC backend 2023-12-22 23:35:13 -05:00
Upstream Data
b89ea1fa92 version: bump version number. 2023-12-22 16:29:03 -07:00
Upstream Data
3588197741 dependencies: bump httpx version 2023-12-22 16:28:46 -07:00
Upstream Data
8adc3d2adf version: bump version number. 2023-12-22 15:47:25 -07:00
Upstream Data
040c0b6842 feature: add support for S19 Pro Hydro. 2023-12-22 15:40:23 -07:00
Upstream Data
550b4a97a1 bug: fix a bunch of missed instances of nominal_ naming. 2023-12-22 15:32:01 -07:00
UpstreamData
d84d95fe5f version: bump version number. 2023-12-21 15:25:57 -07:00
UpstreamData
0e5b811fb9 Add config attribute to data and refactor data naming (#81)
* feature: add config to MinerData.  Remove related attributes.

* feature: rename ideal and nominal to expected to make data naming consistent across files.

* refactor: run isort on all files.

* docs: update docstrings.
2023-12-21 15:20:50 -07:00
UpstreamData
3d31179562 feature: add more BOS+ supported types. 2023-12-19 08:40:31 -07:00
UpstreamData
69f39bef0c docs: update tagline 2023-12-19 08:18:06 -07:00
UpstreamData
1076dab7f5 Update README.md 2023-12-19 08:17:39 -07:00
UpstreamData
3ae1f700c2 docs: update README.md 2023-12-18 14:48:19 -07:00
UpstreamData
dc3f061b9b docs: update shields. 2023-12-18 14:44:43 -07:00
UpstreamData
52758dd8b3 docs: update README. 2023-12-18 14:33:42 -07:00
UpstreamData
0e492f1cfd tests: add more tests for miners. 2023-12-18 14:11:16 -07:00
UpstreamData
659dc55f3c bug: add missing key to epic data locations. 2023-12-18 14:07:46 -07:00
UpstreamData
eb9b29aca1 tests: add tests for config and update tests. 2023-12-18 14:00:40 -07:00
UpstreamData
b045abe76e bug: reorder config information and fix bad key. 2023-12-18 13:59:56 -07:00
Upstream Data
7a75818a20 version: bump version number. 2023-12-17 09:09:00 -07:00
Upstream Data
d2be68d35e bug: fix MinerConfig default values for 3.11+. Add MinerConfig.as_epic default implementation. 2023-12-17 09:08:14 -07:00
Upstream Data
c5c4bb10ee version: bump version number. 2023-12-16 10:59:23 -07:00
Upstream Data
c4dfdda448 Merge branch 'dev_bugs'
# Conflicts:
#	pyasic/miners/miner_factory.py
#	pyasic/miners/types/whatsminer/M6X/M60.py
#	pyasic/miners/types/whatsminer/M6X/M60S.py
#	pyasic/miners/types/whatsminer/M6X/M63.py
#	pyasic/miners/types/whatsminer/M6X/M63S.py
#	pyasic/miners/types/whatsminer/M6X/M66.py
#	pyasic/miners/types/whatsminer/M6X/M66S.py
#	pyasic/miners/types/whatsminer/M6X/__init__.py
#	pyasic/miners/whatsminer/btminer/M6X/M60.py
#	pyasic/miners/whatsminer/btminer/M6X/M60S.py
#	pyasic/miners/whatsminer/btminer/M6X/M66S.py
#	pyasic/miners/whatsminer/btminer/M6X/__init__.py
#	pyasic/miners/whatsminer/btminer/__init__.py
2023-12-16 10:55:27 -07:00
Upstream Data
4459de2260 feature: add support for S19kProNoPIC BOS. Reformat. 2023-12-16 10:54:51 -07:00
UpstreamData
201cfd7ef9 docs: update documentation to be more readable on the main page. 2023-12-13 11:15:03 -07:00
UpstreamData
4201905fdd bug: fix some tasks not being cancelled properly in miner factory. 2023-12-13 10:18:28 -07:00
checksum0
497ffb5bc0 Add all the currently known Whatsminer M6X machines (#77)
* Create new BTMiner M6X backend class to represent Whatsminer new M6X generation

* Add all new known types of Whatsminer M6X

* Ensure all new types are imported in their respective __init__.py

* Create all BTMiner API class for known types of new M6X generation

* Ensure all new BTMiner API class are imported in __init__.py

* Fix erroneous M6X models data

* Ensure M6X miners are imported and add them to their MinerTypes dictionary in miner_factory.py
2023-12-12 19:38:36 -07:00
checksum0
2f762c95db Add all the currently known Whatsminer M6X machines (#77)
* Create new BTMiner M6X backend class to represent Whatsminer new M6X generation

* Add all new known types of Whatsminer M6X

* Ensure all new types are imported in their respective __init__.py

* Create all BTMiner API class for known types of new M6X generation

* Ensure all new BTMiner API class are imported in __init__.py

* Fix erroneous M6X models data

* Ensure M6X miners are imported and add them to their MinerTypes dictionary in miner_factory.py
2023-12-12 19:32:12 -07:00
UpstreamData
67aed79330 bug: fix mode spec in bosminer config. 2023-12-12 13:21:50 -07:00
UpstreamData
073e048726 bug: fix bosminer config missing format information. 2023-12-12 13:11:49 -07:00
UpstreamData
02234f3d1e feature: improve dict merging speed 2023-12-12 09:25:43 -07:00
UpstreamData
dc22df0280 refactor: remove innosilicon pool comment, as it is correct. 2023-12-12 08:54:24 -07:00
UpstreamData
02056b8c88 refactor: remove config prints. 2023-12-11 15:36:02 -07:00
UpstreamData
3a43cd293c bug: Fix improper naming of fan mode. 2023-12-11 15:18:23 -07:00
UpstreamData
6941d9f349 bug: add default case for work mode when there is no work mode returned from bitmain. 2023-12-11 15:08:57 -07:00
UpstreamData
f6b0b64d86 bug: set default quota to 1. 2023-12-11 14:07:17 -07:00
UpstreamData
8d68dd9dac refactor: re-order config keys 2023-12-11 14:06:22 -07:00
UpstreamData
27368a9bd2 bug: fix some issues, and remove unused imports. 2023-12-11 13:48:26 -07:00
UpstreamData
c919b00312 feature: allow config conversion to and from dict. 2023-12-11 13:40:10 -07:00
UpstreamData
f162529883 feature: allow dps conversion for bos grpc. 2023-12-11 11:40:46 -07:00
Upstream Data
bb182bb22d bug: fix some issues with return types and missing return statements. 2023-12-10 20:28:06 -07:00
Upstream Data
af15c4fbd1 bug: pin working betterproto version. 2023-12-10 20:25:27 -07:00
Upstream Data
47c2eb9f0e feature: use betterproto + grpclib. 2023-12-10 20:10:11 -07:00
Upstream Data
1ab39f5873 bug: fix bosminer config parsing. 2023-12-10 17:40:39 -07:00
Upstream Data
43200a7354 feature: Add bosminer.toml parser. 2023-12-10 13:20:03 -07:00
Upstream Data
4fc57832e1 feature: Finish fixing get and send config handlers for miners. 2023-12-10 10:14:57 -07:00
Upstream Data
9ee63cc3ab feature: Update get and send config methods for most miners, and add as_inno. 2023-12-10 10:10:55 -07:00
Upstream Data
b22b506d55 feature: Add whatsminer send_config. 2023-12-10 09:55:05 -07:00
Upstream Data
468fba3465 feature: Add whatsminer set mode commands. 2023-12-10 09:49:24 -07:00
Upstream Data
0399094197 feature: add AM old and goldshell configs. 2023-12-10 09:45:34 -07:00
Upstream Data
bfdfa8a6ab feature: Add AM modern send and get config. 2023-12-10 09:30:31 -07:00
Upstream Data
83d0d09b0d feature: Add whatsminer get_config. 2023-12-09 17:35:47 -07:00
Upstream Data
f892c3a0fd feature: Add from am_modern to config. 2023-12-09 16:59:39 -07:00
Upstream Data
81b974f565 bug: fix bad indentation. 2023-12-09 15:12:36 -07:00
UpstreamData
5eaf876c6d feature: add bos to config miner types. 2023-12-09 13:27:23 -07:00
Upstream Data
d7d1b845a7 feature: add MinerConfig.from_api(). 2023-12-09 13:06:52 -07:00
UpstreamData
242517a36a feature: add inno to config miner types. 2023-12-08 11:03:36 -07:00
UpstreamData
791249bf3d feature: add avalon and goldshell to miner config types. 2023-12-08 10:57:57 -07:00
UpstreamData
5a70a27f07 reformat: remove some useless files. 2023-12-08 10:11:43 -07:00
UpstreamData
bca81f3bca feature: add AM old and modern, and WM config implementation. 2023-12-08 10:10:21 -07:00
UpstreamData
6d75565baf feature: start adding new config implementation. 2023-12-08 09:16:04 -07:00
JP Compagnone
9f42e6a3be add new Antminer models (S19jPro+ and S19k Pro) (#75)
* Add S19jPro+ and S19K Pro

* typo
2023-12-08 08:34:30 -07:00
Upstream Data
362b204c91 version: bump version number. 2023-11-29 20:45:46 -07:00
Upstream Data
952b660c05 bug: re-add missing socket check during scan. 2023-11-29 20:45:25 -07:00
UpstreamData
fbd73881d4 version: bump version number. 2023-11-28 16:42:15 -07:00
JP Compagnone
68c4dadb63 hotfix: fix epic api error handling (#74)
* hotfix: fix epic api error handling

* much cleaner way to handle the retry
2023-11-28 16:39:57 -07:00
UpstreamData
87016670d4 version: bump version number. 2023-11-28 10:50:56 -07:00
JP Compagnone
8701bbe4e2 Feature - Add initial ePIC UMC support (#71)
* prelim support of ePIC UMC

* slowly adding things

* add most api calls

* add some guards

* fix post commands

* remove print

* catch when API returns error

* missing guard

* remove semicolon

* recommended changes

* add docs and changes

* respect ignore_errors
2023-11-28 10:49:49 -07:00
UpstreamData
7d1f125b0b docs: update settings docs to list. 2023-11-27 11:07:43 -07:00
UpstreamData
e433902bd5 docs: update settings docs. 2023-11-27 10:57:13 -07:00
UpstreamData
a653772968 docs: update network docs. 2023-11-27 10:53:40 -07:00
UpstreamData
d8b938cd5b version: bump version number. 2023-11-27 10:39:10 -07:00
UpstreamData
47d76e325a docs: update docs to include new information. 2023-11-27 10:37:38 -07:00
UpstreamData
7ee7868094 feature: change so_linger_time to socket_linger_time. 2023-11-27 10:19:30 -07:00
UpstreamData
3f1183a4f9 feature: add so_linger option to settings. 2023-11-27 09:24:28 -07:00
Upstream Data
2b443497ea bug: improve handling of whatsminers in get_miner. 2023-11-25 12:48:45 -07:00
Upstream Data
c3972f9524 feature: add default ssl ctx to all httpx clients to speed up initialization. 2023-11-25 01:08:04 -07:00
Upstream Data
92bbb21c11 bug: handle OSError as ConnectionError, and handle Vnish Msg bug because of missing id key. 2023-11-25 00:05:03 -07:00
Upstream Data
1980ff2563 bug: do additional checks on refused connection when scanning. 2023-11-24 23:32:22 -07:00
Upstream Data
93d09a1483 bug: handle unhandled error in pings. 2023-11-24 23:28:16 -07:00
Upstream Data
690d0d99df feature: added new setting for api command timeouts. 2023-11-24 23:19:14 -07:00
Upstream Data
78f689eb2c feature: update scan method to use port 80 when possible, and add .scan() method. 2023-11-24 23:13:56 -07:00
Upstream Data
e68f188e8f bug: fix timeout references in MinerFactory and fix MinerNetwork instantiation. 2023-11-24 23:00:06 -07:00
Upstream Data
7eda611fe9 bug: fix scanning size being too large. 2023-11-24 22:50:43 -07:00
Upstream Data
1d12817942 feature: improve network parsing and implementation. 2023-11-24 22:38:43 -07:00
UpstreamData
b24efd4c69 bug: fix miner network not working with lists. 2023-11-24 13:27:09 -07:00
UpstreamData
5533135b05 docs: update supported miners. 2023-11-23 11:54:01 -07:00
UpstreamData
475054fbe0 feature: finish support for most whatsminer subtypes. 2023-11-23 11:52:44 -07:00
Daniel Sokil
06bad1bbe0 Add More Whatsminer Models, and Additional Config For Existing Models (#70) 2023-11-23 11:35:18 -07:00
UpstreamData
f3746ff756 version: bump version number. 2023-11-20 11:19:45 -07:00
UpstreamData
9f16d37c8b feature: hide GRPC and GQL if BOSer is not found. 2023-11-20 11:19:13 -07:00
UpstreamData
8a13c7940a docs: update pyproject.toml description. 2023-11-20 10:33:25 -07:00
UpstreamData
8bea76ff67 feature: add chip count for M30S+VG50. 2023-11-20 10:32:51 -07:00
Upstream Data
1504bd744c version: bump version number. 2023-11-18 22:45:38 -07:00
Upstream Data
6449f10615 feature: implement GPRC set commands properly. 2023-11-18 22:45:09 -07:00
UpstreamData
d79509bda7 version: bump version number. Pin httpx to 0.25.0 min. 2023-11-12 18:36:45 -07:00
UpstreamData
630b847466 version: bump version number. Pin httpx to 0.25.0 min. 2023-11-12 18:35:52 -07:00
Colin Crossman
ed11611919 Bump version number
Note: some issues with HTTPX may be resolved by using 1.0.0b, but I did not bump the requirement at this time to the beta.
2023-11-11 13:59:14 -07:00
Colin Crossman
e2431c938d Address unknown password issue on Whatsminers
When a whatsminer had an unknown password (not the default one), it would result in a timeout error. By moving the password check to before the data pull step, the timeout issue can be caught and addressed efficiently.
2023-11-11 13:52:04 -07:00
Colin Crossman
60f4b4a5ed Address a situation which causes many asyncio errors 2023-11-11 13:49:51 -07:00
UpstreamData
d41097af20 version: bump vbersion number. 2023-11-08 11:13:24 -07:00
UpstreamData
8a5d505731 bug: fix anyio stream error on some linux distros when getting miner. 2023-11-08 11:12:46 -07:00
UpstreamData
36e76c6f41 Add support for the grpc set_performance_mode command. 2023-11-07 08:54:06 -07:00
UpstreamData
717b9421dd Merge branch 'dev_grpc'
# Conflicts:
#	pyasic/web/bosminer.py
#	pyproject.toml
2023-10-30 16:36:06 -06:00
UpstreamData
d2f71e8c94 version: bump version number. 2023-10-30 16:34:05 -06:00
UpstreamData
697991f28f bug: fix some cases where a warning could still be passed when it was unexpected. 2023-10-30 16:33:01 -06:00
UpstreamData
b0e18ab766 feature: implement most of the GRPC functions for BOS, except for some configuration options which will require complex enums. 2023-10-27 16:35:09 -06:00
UpstreamData
e39a6921d0 refactor: improve settings handling to not use a dataclass, and not use singleton. 2023-10-26 10:28:59 -06:00
UpstreamData
aac1be0565 feature: refactor BOS web class into multiple classes. 2023-10-26 10:28:57 -06:00
UpstreamData
683fcb2138 version: bump version number. 2023-10-26 10:28:56 -06:00
UpstreamData
9fbbef9b18 bug: fix an issue with bosminer not responding correctly on older models with fans. 2023-10-26 10:28:56 -06:00
UpstreamData
6e0b9a0a7b version: bump version number. 2023-10-26 10:28:56 -06:00
UpstreamData
7f472f6f4f bug: fix possible missing value for bitmain work mode when checking is_mining. 2023-10-26 10:28:55 -06:00
UpstreamData
b7d7b33ab9 bug: round hashrate data in MinerData, and remove some unused imports. 2023-10-26 10:28:55 -06:00
UpstreamData
da11c0bb1f version: bump version number. 2023-10-26 10:28:55 -06:00
UpstreamData
eae433d2bd bug: update get_miner to work with latest whatsminer version. 2023-10-26 10:28:54 -06:00
UpstreamData
c16bc37aff refactor: improve settings handling to not use a dataclass, and not use singleton. 2023-10-26 10:28:53 -06:00
UpstreamData
255b06ac9e version: bump version number. 2023-10-23 13:01:44 -06:00
UpstreamData
29ec619126 bug: fix an issue with bosminer not responding correctly on older models with fans. 2023-10-23 12:59:52 -06:00
UpstreamData
247def04ff version: bump version number. 2023-10-12 13:19:38 -06:00
UpstreamData
4600e7d953 bug: fix possible missing value for bitmain work mode when checking is_mining. 2023-10-12 13:19:11 -06:00
UpstreamData
850c266555 bug: round hashrate data in MinerData, and remove some unused imports. 2023-10-10 13:59:28 -06:00
UpstreamData
ad374fe2fb version: bump version number. 2023-10-05 10:18:10 -06:00
UpstreamData
5ca39b6fe7 bug: update get_miner to work with latest whatsminer version. 2023-10-05 10:17:45 -06:00
UpstreamData
b50dd26e6f feature: refactor BOS web class into multiple classes. 2023-10-03 15:07:39 -06:00
UpstreamData
53eaccaa9b docs: update documentation. 2023-10-03 15:07:39 -06:00
UpstreamData
91f207316a version: bump version number. 2023-10-03 15:07:39 -06:00
UpstreamData
1e37418909 bug: fix some issues with early version of whatsminers, and handle some possible errors with BOS. 2023-10-03 15:07:38 -06:00
UpstreamData
4c09ba5529 version: bump version number. 2023-10-03 15:07:38 -06:00
UpstreamData
7bab4747ad refactor: improve settings handling to not use a dataclass, and not use singleton. 2023-10-03 15:07:37 -06:00
UpstreamData
fd8cc7378c version: bump version number. 2023-10-03 15:07:33 -06:00
UpstreamData
8aeef4d5e7 feature: add support for M20P, and add chips for M20SV30. 2023-10-03 15:07:33 -06:00
UpstreamData
4bafde9da7 docs: update documentation. 2023-10-03 14:59:25 -06:00
UpstreamData
5a3107aecf version: bump version number. 2023-10-03 11:12:11 -06:00
UpstreamData
7e758720f0 bug: fix some issues with early version of whatsminers, and handle some possible errors with BOS. 2023-10-03 11:11:32 -06:00
UpstreamData
39e3e249f8 version: bump version number. 2023-10-02 13:14:21 -06:00
UpstreamData
118c5b056e refactor: improve settings handling to not use a dataclass, and not use singleton. 2023-10-02 13:13:31 -06:00
UpstreamData
2c3b5599fe version: bump version number. 2023-10-02 09:20:24 -06:00
UpstreamData
e421eaa324 feature: add support for M20P, and add chips for M20SV30. 2023-10-02 09:20:01 -06:00
UpstreamData
75d6bc6808 version: bump version number. 2023-09-28 15:49:23 -06:00
UpstreamData
98c547e416 bug: fAdd new commands added in whatsminer API 2.0.5. 2023-09-28 15:49:23 -06:00
UpstreamData
45250e36e4 bug: fix whatsminer identification to work with backwards incompatible changes in API 2.0.5. 2023-09-28 15:49:23 -06:00
UpstreamData
fa7544d052 Update README.md 2023-09-28 15:49:22 -06:00
UpstreamData
53f3fc5ee9 version: bump version number. 2023-09-28 15:47:49 -06:00
UpstreamData
1b36de4131 bug: fAdd new commands added in whatsminer API 2.0.5. 2023-09-28 15:47:20 -06:00
UpstreamData
6f0c6f6284 bug: fix whatsminer identification to work with backwards incompatible changes in API 2.0.5. 2023-09-28 15:42:12 -06:00
UpstreamData
b7dda5bf87 Update README.md 2023-09-26 11:50:56 -06:00
UpstreamData
14f33a40c3 feature: add grpc BOS class and add grpc requests to requirements. 2023-09-22 09:44:25 -06:00
UpstreamData
5c904aced0 feature: refactor BOS web class into multiple classes. 2023-09-22 09:32:59 -06:00
UpstreamData
53a3bbf531 version: bump version number. 2023-09-19 13:59:56 -06:00
UpstreamData
50586f1ce7 feature: add S19+. 2023-09-19 13:59:03 -06:00
UpstreamData
9f6235a0fc feature: add S19i. 2023-09-19 13:56:40 -06:00
UpstreamData
4d21f150ce version: bump version number. 2023-09-18 09:35:38 -06:00
UpstreamData
7c0dfc49dd bug: fix wrong fault light setting when setting fault light to off. 2023-09-18 09:35:19 -06:00
UpstreamData
269b13f6c1 version: bump version number. 2023-09-15 08:57:56 -06:00
Elias Kunnas
a9bb7d2e5a Fix btminer pre_power_on (#62) 2023-09-15 08:56:29 -06:00
Upstream Data
11295f27a7 version: bump version number. 2023-09-12 19:21:04 -06:00
Upstream Data
55aa3dd85b bug: handle edge cases where a missed get_config on bosminer can cause an empty config to be applied to a miner. 2023-09-12 19:20:48 -06:00
UpstreamData
20272d4360 version: bump version number. 2023-09-11 13:45:52 -06:00
UpstreamData
623dc92ef2 feature: Add MinerData.as_dict(). 2023-09-11 13:45:23 -06:00
Upstream Data
2d59394b1e version: bump version number. 2023-09-07 19:07:11 -06:00
Upstream Data
26c2095ff1 bug: fix uncaught error in get_hashboards with BMMiner if a key doesnt exist. 2023-09-07 19:06:51 -06:00
Upstream Data
ec7d241caa version: bump version number. 2023-09-05 17:22:23 -06:00
Upstream Data
d0432ed1aa bug: handle for some weird edge cases with boards plugged into the wrong slots on X19. 2023-09-05 17:22:02 -06:00
Upstream Data
8c5503d002 version: bump version number. 2023-08-30 17:47:20 -06:00
Upstream Data
6d6f950c95 bug: add modified changed from [Issue 57](https://github.com/UpstreamData/pyasic/issues/57#issuecomment-1699984187) 2023-08-30 17:46:23 -06:00
UpstreamData
30745e54ba feature: add chip count for M30S+VE50 2023-08-30 11:18:25 -06:00
UpstreamData
c3fd94e79e version: bump version number. 2023-08-28 08:53:59 -06:00
UpstreamData
2924a8d67b feature: add more whatsminer error codes. 2023-08-28 08:53:27 -06:00
UpstreamData
9f4c4bb9cf feature: add exclude to get_data, and change data_to_get to include. 2023-08-28 08:32:29 -06:00
UpstreamData
3d6eebf06e bug: fix a bug with hostname gathering on some Avalons. 2023-08-28 08:31:54 -06:00
Upstream Data
b3d9b6ff7e version: bump version number. 2023-08-26 11:21:21 -06:00
Upstream Data
60facacc48 bug: fix a bug with bosminer commands. 2023-08-26 11:21:10 -06:00
Upstream Data
b8a6063838 version: bumnp version number. 2023-08-26 10:57:40 -06:00
Upstream Data
bcba2be524 bug: remove bad await calls to httpx response.json(). 2023-08-26 10:56:53 -06:00
UpstreamData
f7187d2017 bug: add chip count for M29V10. 2023-08-25 08:58:34 -06:00
Upstream Data
d91b7c4406 version: bump version number. 2023-08-07 17:02:50 -06:00
Upstream Data
248a7e6d69 bug: fix some WM models reporting https first and being identified as BOS+. 2023-08-07 17:02:26 -06:00
Upstream Data
4f2c3e772a version: bump version number. 2023-08-06 17:25:21 -06:00
Upstream Data
95f7146eef feature: add VNish pause/resume commands. 2023-08-06 17:24:36 -06:00
UpstreamData
9d5d19cc6b version: bump version number. 2023-07-27 20:45:42 -06:00
UpstreamData
cc38129571 bug: add back pwd for ssh connections. 2023-07-27 20:45:08 -06:00
UpstreamData
3dfd9f237d version: bump version number. 2023-07-27 20:18:58 -06:00
UpstreamData
f3fe478dbb feature: add support for S19J Pro No PIC. 2023-07-27 20:18:36 -06:00
UpstreamData
e10f32ae3d feature: speed up getting older antminer types with concurrent web and api requests. 2023-07-24 21:05:07 -06:00
UpstreamData
4e0924aa0e feature: add support for AML vnish miners. 2023-07-24 20:45:30 -06:00
UpstreamData
d0d3fd3117 bug: fix failed verification of SSL cert on whatsminer. 2023-07-24 20:19:00 -06:00
UpstreamData
4de950d8f4 feature: revert miner_factory to use httpx, as it now seems to be the same speed, and aiohttp doesnt support digest auth. 2023-07-24 13:09:30 -06:00
UpstreamData
03f2a1f9ba feature: optimize multicommand on new X19 models. 2023-07-24 11:34:16 -06:00
UpstreamData
2653db90e3 feature: optimize the way multicommand is handled on BTMiner. 2023-07-24 09:44:23 -06:00
UpstreamData
ddc8c53eb9 feature: add chip count for M50 VH60. 2023-07-13 10:59:27 -06:00
UpstreamData
eb5d1a24ea version: bump version number. 2023-07-12 08:56:59 -06:00
UpstreamData
6c0e80265b bug: revert X19 miner mode to string. 2023-07-12 08:56:23 -06:00
UpstreamData
ad3a4ae414 docs: update some bad code, and add references to new miner types and API types. 2023-07-11 11:18:28 -06:00
UpstreamData
3484d43510 version: bump version number. 2023-07-07 14:09:22 -06:00
UpstreamData
dd7e352391 bug: fix some addition issues with MinerData sums. 2023-07-07 14:09:08 -06:00
UpstreamData
a32b61fe5d version: bump version number. 2023-07-07 12:37:34 -06:00
UpstreamData
597a178009 feature: Update MinerData to use None. 2023-07-07 12:37:20 -06:00
Michael Schmid
409b2527f0 use None instead of -1 for temps and wattages (#55)
* use `None` instead of `-1` for temps and wattages
this way it's easier for other tools like HomeAssistant to understand if the temperature is really negative or not available

* also handle cases where we look for `-1`
2023-07-07 12:06:24 -06:00
UpstreamData
58234fcf7f version: bump version number. 2023-07-07 12:03:28 -06:00
UpstreamData
1bf863cca8 bug: set miner_mode to int instead of str to fix some issues with some X19 models. 2023-07-07 12:03:00 -06:00
UpstreamData
6482d04185 version: bump version number. 2023-07-07 11:56:41 -06:00
UpstreamData
3b58b11501 bug: remove 0 frequency level when setting sleep mode on X19, as it seems to bug some types. 2023-07-07 11:56:06 -06:00
UpstreamData
7485b8ef77 version: bump version number. 2023-07-04 10:04:20 -06:00
UpstreamData
d2bea227db bug: fix an issue with a possible SSH command in BOS+. 2023-07-04 10:01:24 -06:00
UpstreamData
1b7afaaf7e version: bump version number. 2023-06-30 08:49:31 -06:00
UpstreamData
96898d639c bug: fix some handling errors with graphql. 2023-06-30 08:49:08 -06:00
UpstreamData
eb439f4dcf version: bump version number. 2023-06-30 08:44:01 -06:00
UpstreamData
69f4349393 feature: create pwd and username property in miner object that sets web and api passwords and usernames. 2023-06-30 08:43:30 -06:00
UpstreamData
e371bb577c version: bump version number. 2023-06-29 18:10:35 -06:00
UpstreamData
2500ec3869 bug: fix possible None return from some bosminer webcommands. 2023-06-29 18:10:10 -06:00
UpstreamData
5be3187eec version: bump version number. 2023-06-29 16:51:29 -06:00
UpstreamData
be1e9127b0 bug: fix weird pool info when multiple groups are defined. 2023-06-29 16:51:15 -06:00
UpstreamData
13572c4770 version: bump version number. 2023-06-29 16:48:09 -06:00
UpstreamData
08fa3961fe bug: fix bosminer on X19 not reporting pause mode correctly. 2023-06-29 16:47:27 -06:00
UpstreamData
b5d2809e9c format: remove random print statements. 2023-06-29 15:53:53 -06:00
UpstreamData
aa538d3079 docs: add miner docs generation file. 2023-06-28 11:21:19 -06:00
UpstreamData
e1500bb75c docs: update docs. 2023-06-28 11:20:22 -06:00
UpstreamData
7f00a65598 version: bump version number. 2023-06-27 16:23:46 -06:00
UpstreamData
64c473a7d4 bug: fix improper stats key when getting uptime. 2023-06-27 16:23:21 -06:00
UpstreamData
96d9fe8e6c version: bump version number. 2023-06-27 14:56:11 -06:00
UpstreamData
0b27400d27 feature: add set_static_ip and set_dhcp for bosminer. 2023-06-27 14:55:05 -06:00
UpstreamData
666b9dfe94 version: bump version number. 2023-06-27 09:36:06 -06:00
UpstreamData
df3a080c9d feature: add uptime check for some miners, and fix a bug with get_mac on BOS. 2023-06-27 09:35:07 -06:00
UpstreamData
bf3bd7c2b9 feature: add basic support for LuxOS 2023-06-26 15:35:52 -06:00
UpstreamData
37fd60b462 version: bump version number. 2023-06-26 09:53:21 -06:00
UpstreamData
2245904740 feature: remove ssh references when getting MAC on bosminer. 2023-06-26 09:52:30 -06:00
UpstreamData
7b1b23016e feature: add support for VNish S19 No PIC. 2023-06-26 08:20:45 -06:00
UpstreamData
b5fcd62e23 version: bump version number. 2023-06-23 14:50:14 -06:00
UpstreamData
9057cde274 docs: add is_mining to docs. 2023-06-23 14:49:38 -06:00
UpstreamData
f6d35888fe feature: add is_mining to MinerData and get_data. 2023-06-23 14:47:12 -06:00
UpstreamData
f2abe9fd9e feature: add is_mining to all miner types. 2023-06-23 14:38:38 -06:00
UpstreamData
7d1a702804 feature: make is_mining abstract method. 2023-06-23 14:34:44 -06:00
UpstreamData
65d1695ce4 bug: fix is_mining for some miners. 2023-06-23 14:33:32 -06:00
UpstreamData
65fd66b8bf feature: add is_mining for antminer. 2023-06-23 14:08:54 -06:00
UpstreamData
5db52c46f3 feature: add is_mining for btminer, and fix some minor bugs. 2023-06-23 13:38:45 -06:00
UpstreamData
d06cb19da3 feature: add is_mining for bosminers. 2023-06-23 12:39:00 -06:00
UpstreamData
4530d086da bug: fix some cases where web command data can fail. 2023-06-23 11:23:20 -06:00
UpstreamData
0bd679f259 version: bump version number. 2023-06-22 15:07:25 -06:00
UpstreamData
1ce5bd0566 Update miner data and fix various bugs related to the fix. (#47)
* feature: fix influxdb data.

* bug: fix an issue with some avalon stats parsing.

* bug: add chip count for 1166 Pro.

* bug: fix some issues with bosminer scanning and some data bugs.

* bug: remove print statement.

* bug: fix failed data gathering multicommand via graphql.

* feature: add partial support for M50S+VK20

* version: bump version number.

* bug: add chip count for M50S+VK20.

* version: bump version number.

* bug: attempt to fix offset check issue on BOS+.

* bug: fix NoneType subscription on BOS+.

* bug: add support for Vnish S17+.

* bug: remove web references for Avalons.

* bug: add support for VNish S17Pro.

* bug: Try secondary identification method for antminers.

* feature: fix a bunch of functionality for avalonminers.

* bug: fix avalonminer fan speed being set as str.

* bug: fix fans speeds being represented as strings.

* bug: fix some get_fan formatting.

* docs: update supported miners list, and fix A10X model name.

* docs: update MinerData docstrings.

* docs: update factory documentation.
2023-06-22 15:06:30 -06:00
UpstreamData
67c3d05ac3 version: bump version number. 2023-06-20 12:11:43 -06:00
UpstreamData
c691868e9b bug: add chip count for M50S+VK20. 2023-06-20 12:11:05 -06:00
UpstreamData
f5e15b4046 version: bump version number. 2023-06-19 16:10:34 -06:00
UpstreamData
e14df696ee feature: add partial support for M50S+VK20 2023-06-19 16:10:00 -06:00
UpstreamData
ce5dfad850 version: bump version number. 2023-06-12 13:04:11 -06:00
UpstreamData
5cb45390be bug: add chip count for avalon 1246. 2023-06-12 13:03:41 -06:00
UpstreamData
b5216a24a6 version: bump version number. 2023-06-12 12:47:58 -06:00
UpstreamData
dd175ff3a2 bug: fix an issue with 2020 versions of Braiins OS not identifying correctly. 2023-06-12 12:47:38 -06:00
UpstreamData
9b504a3157 version: bump version number. 2023-06-12 12:42:16 -06:00
UpstreamData
0bc3bf20ee bug: fix possible missing models. 2023-06-12 12:41:50 -06:00
UpstreamData
de5380715c version: bump version number. 2023-06-12 11:06:20 -06:00
UpstreamData
00a108252d version: bump version number. 2023-06-12 11:04:22 -06:00
UpstreamData
e446176922 refactor: refactor miner types. 2023-06-12 11:02:51 -06:00
UpstreamData
134c44aedc Improve get_miner (#43)
* feature: Start refactor to new style of get_miner.  Needs testing and stability fixes.

* feature: refactor to aiohttp and fix a lot of bugs with factory.  Still needs support for some miners.

* feature: refactor miner class list to be much more readable.

* bug: remove some redundant .upper() calls.

* bug: remove some redundant .upper() calls.

* feature: add Avalonminer support in update miner factory, and add support for A1166 and A1246.

* feature: refactor get_miner to allow models to be selected as strings then selected in the top level get_miner function.

* bug: fix some naming issues, and add timeout to getting miner model.

* bug: fix not instantiating some web sessions properly.
2023-06-12 09:09:51 -06:00
UpstreamData
a2bb8b5d9b version: bump version number. 2023-06-02 09:29:42 -06:00
UpstreamData
62aaf36fd7 bug: re-order config sent to S19 to be consistent with stock. 2023-06-02 09:28:50 -06:00
UpstreamData
63023650a9 version: bump version number. 2023-06-01 09:57:21 -06:00
UpstreamData
0025c613f0 bug: fix 2 AA's in AANTMINER. 2023-06-01 09:56:54 -06:00
UpstreamData
e4ec3b2b28 version: bump version number. 2023-06-01 09:45:26 -06:00
UpstreamData
08af02a394 bug: fix wrong constructor for S19Pro+. 2023-06-01 09:45:05 -06:00
UpstreamData
afca497d8a version: bump version number. 2023-06-01 09:03:31 -06:00
UpstreamData
d50896a896 bug: add support for S19ProPlus 2023-06-01 09:02:54 -06:00
UpstreamData
117737afb5 version: bump version number. 2023-05-29 11:40:56 -06:00
UpstreamData
eabae92da6 bug: fix some issues with S19j88NoPic on braiinsOS. 2023-05-29 11:40:08 -06:00
Upstream Data
f816551d7a version: bump version number. 2023-05-25 21:10:04 -06:00
Upstream Data
4e3ea4eabb feature: add support for M50S++ models. 2023-05-25 21:08:47 -06:00
UpstreamData
74c13806fb bug: fix incorrect variable name in avalonminers. 2023-05-23 15:07:33 -06:00
UpstreamData
934d469def version: bump version number. 2023-05-23 09:37:23 -06:00
UpstreamData
0c563ef538 bug: Fix bad type hinting on ABCMeta instead of type. 2023-05-23 09:36:50 -06:00
Upstream Data
ecc76d09af bug: add chip count for M32V10. 2023-05-21 19:38:37 -06:00
Upstream Data
caa66531b7 version: bump version number. 2023-05-21 16:56:52 -06:00
Upstream Data
23ea90b56f bug: add chip count for M31SVE10. 2023-05-21 16:56:28 -06:00
UpstreamData
9e2d3aeebd version: bump version number. 2023-05-16 16:09:17 -06:00
UpstreamData
0cead26872 feature: add support for S9j. 2023-05-16 16:08:49 -06:00
UpstreamData
706844264b version: bump version number. 2023-05-16 13:22:59 -06:00
UpstreamData
3257af975a bug: fix error with type hinting. 2023-05-16 13:21:39 -06:00
UpstreamData
83a4f86e15 bug: fix a bug with connection errors rarely being raised on read in API commands. 2023-05-12 10:46:43 -06:00
UpstreamData
f1c4cb400a version: bump version number. 2023-05-12 08:44:41 -06:00
UpstreamData
d21d67a18b version: bump version number. 2023-05-12 08:33:20 -06:00
UpstreamData
db1beceb2e bug: fix some issues with dependencies, format, and remove poetry.lock 2023-05-12 08:31:56 -06:00
UpstreamData
827834a119 bug: fix ssh commands not working properly because of error handling inside inner functions. 2023-05-12 08:23:29 -06:00
UpstreamData
8e430b149b version: bump version number. 2023-05-02 10:18:09 -06:00
UpstreamData
031dc534c7 bug: add chip count for M50VH80 2023-05-02 10:17:11 -06:00
Upstream Data
ac9905717d bug: fix some issues with antminers on stock. 2023-05-01 20:21:49 -06:00
Upstream Data
ae835dbdb2 version: bump version number. 2023-04-27 18:24:31 -06:00
Upstream Data
d59f29b582 bug: add kwargs to send_command. 2023-04-27 18:23:58 -06:00
UpstreamData
c7d6f6cd9f version: bump version number. 2023-04-27 10:02:14 -06:00
UpstreamData
bf19232ad9 bug: add chip counts for M30S++ VH100 2023-04-27 10:01:43 -06:00
UpstreamData
b495f22f31 version: bump version number. 2023-04-20 13:35:19 -06:00
UpstreamData
78213c682b feature: add % ideal hashrate and wattage. 2023-04-20 13:34:40 -06:00
Upstream Data
3706c8fb75 version: bump version nuber. 2023-04-16 20:40:49 -06:00
Upstream Data
ed9d386dc2 bug: fix bosminer configs not loading in fan control properly. 2023-04-16 20:39:39 -06:00
UpstreamData
1183b5deb2 version: bump version number. 2023-04-14 13:07:58 -06:00
UpstreamData
c4676438a8 bug: fix a bug with failing to get hashboards and hashrate breaking data. 2023-04-14 13:07:35 -06:00
UpstreamData
5ea9126c77 version: bump version number. 2023-04-13 14:26:34 -06:00
UpstreamData
853756ebcb feature: sum hashrate in MinerData from hashboards, with the hashrate item being a backup. 2023-04-13 14:26:03 -06:00
UpstreamData
05e82b85c5 bug: fix T9+ support. 2023-04-13 14:09:05 -06:00
UpstreamData
9c4c8503d6 feature: add support for antminer D3. 2023-04-13 13:43:41 -06:00
UpstreamData
e25cc1d85e bug: catch errors when sending commands to vnish with a bad token. 2023-04-13 13:34:55 -06:00
UpstreamData
8e37d72337 feature: add support for L3+ and Vnish L3+. 2023-04-13 13:33:02 -06:00
Upstream Data
f84a054ecc version: bump version number. 2023-04-12 22:16:57 -06:00
Upstream Data
6b54607588 feature: add chip count for M30S++VH20. 2023-04-12 22:16:38 -06:00
Upstream Data
85ee8a479b version: bump version number. 2023-04-12 19:53:56 -06:00
Upstream Data
9decbf2a4b bug: fix incorrect board count for M33S++. 2023-04-12 19:53:26 -06:00
UpstreamData
15ce3a3140 tests: Improve binding to 0.0.0.0 in tests. 2023-04-04 09:25:33 -06:00
UpstreamData
d4d48f5582 docs: update docs. 2023-04-04 09:22:36 -06:00
UpstreamData
a577f64d59 bug: add additional whatsminer error codes. 2023-03-31 10:44:51 -06:00
UpstreamData
aaf48cc686 version: bump version number. 2023-03-28 11:40:54 -06:00
UpstreamData
aa6dc74471 minor: reformat a bunch of files to try to make backends more cohesive, add static dict for get_data instead of using inspect, refactored graphql into a bosminer web API, and added supports_autotuning and supports_shutdown attributes to miners. 2023-03-28 11:39:03 -06:00
UpstreamData
63c8fe6868 version: bump version number. 2023-03-27 08:43:03 -06:00
UpstreamData
ee1502c6a0 bug: fix BOSMiner default password. 2023-03-27 08:42:41 -06:00
UpstreamData
2960295385 version: bump version number. 2023-03-23 13:25:11 -06:00
UpstreamData
a9e09f7b1a bug: Check stderr on ssh. 2023-03-23 13:24:38 -06:00
UpstreamData
fd17a20a1b version: bump version number. 2023-03-23 08:15:58 -06:00
UpstreamData
1e03ec5fa3 bug: fix new issue with X19 "NoPic" on braiins. 2023-03-23 08:15:21 -06:00
UpstreamData
a67e4ada8e version: bump version number. 2023-03-14 09:53:26 -06:00
UpstreamData
2d08b10076 feature: add support for S19L. 2023-03-14 09:53:05 -06:00
UpstreamData
92e972aa57 docs: update documentation. 2023-03-14 09:07:26 -06:00
Upstream Data
05cfe8cc5d version: bump version number. 2023-03-05 16:26:36 -07:00
Upstream Data
b4d9e60bff bug: fix E9Pro strop_mining and resume_mining 2023-03-05 16:26:13 -07:00
Upstream Data
6bcf372be6 version: bump version number. 2023-03-04 17:55:46 -07:00
Upstream Data
092a586329 bug: fix an issue with innosilicon A10X not allowing pool config. 2023-03-04 17:46:11 -07:00
Upstream Data
e598d4b63c version: bump version number. 2023-03-04 16:14:02 -07:00
Upstream Data
848acedd52 feature: add support for E9Pro and fix some bugs and update finding chip data for Goldshell models. 2023-03-04 16:13:03 -07:00
DCreason
e3c4464556 fix internal error when not using vnish preset (#33) 2023-03-04 07:54:27 -07:00
UpstreamData
9e28f7968a version: bump version number. 2023-03-03 13:16:14 -07:00
UpstreamData
6159a72d46 feature: add support for antminer HS3. 2023-03-03 13:15:22 -07:00
UpstreamData
932c034e0e feature: improve load balancer to handle for bad boards. 2023-03-03 12:25:12 -07:00
UpstreamData
645828f35b bug: fix btminer adjust power limit and add poweroff for innosilicon miners (though it breaks the miner) 2023-03-03 10:58:16 -07:00
UpstreamData
841a546505 bug: fix some bugs. 2023-03-02 16:17:32 -07:00
UpstreamData
e65b718699 version: bump version number. 2023-03-02 13:10:27 -07:00
UpstreamData
15e4338046 feature: add support for DR5, KD5, KDMax, CK5, and A10X. 2023-03-02 13:09:46 -07:00
UpstreamData
720d4aec3d feature: add support for Goldshell HS5 2023-03-02 11:32:28 -07:00
UpstreamData
09f9028ab5 format: reformat miner files to improve readability. 2023-03-02 08:58:10 -07:00
Upstream Data
25d971b699 version: bump version number. 2023-03-01 21:46:03 -07:00
Upstream Data
cd16ef3a25 feature: add Z15 support. 2023-03-01 21:45:37 -07:00
Upstream Data
b70010272f feature: add L7 support. 2023-03-01 20:32:03 -07:00
Upstream Data
140a457445 Merge branch 'dev' 2023-03-01 19:56:27 -07:00
Upstream Data
f4775e6311 bug: better fix for the issue with whatsminer pools. 2023-03-01 19:37:51 -07:00
Upstream Data
a4ecda93a2 bug: Fix an issue with sending None to whatsminers. 2023-03-01 19:34:14 -07:00
Arceris
ba90f2f082 Add VH40 and VH20 chip counts to M50.py 2023-03-01 18:56:41 -07:00
UpstreamData
44ac958bbb version: bump version number. 2023-02-28 16:23:36 -07:00
UpstreamData
e9bcf2ec9f bug: fix an issue with missing a check for bosminer config when getting data. 2023-02-28 16:23:04 -07:00
UpstreamData
c73dfad01a format: move vnish over to the new web API style. 2023-02-28 11:32:42 -07:00
UpstreamData
d222912e30 format: update a bunch of formatting and remove a lot of useless imports. 2023-02-28 09:35:11 -07:00
UpstreamData
6f1c1e0290 format: swap X9 and Innosilicon over to the new web api format. 2023-02-27 16:07:34 -07:00
UpstreamData
ba0bb73aa3 format: swap X17 over to the new web api format. 2023-02-27 15:44:58 -07:00
UpstreamData
13fcf1d4aa format: swap X19 over to the new web api format. 2023-02-27 15:32:02 -07:00
UpstreamData
6be1e94216 version: bump version number. 2023-02-24 12:32:22 -07:00
UpstreamData
709b3efa81 bug: fix mis-identification of X19 on some new versions of stock. 2023-02-24 12:31:55 -07:00
UpstreamData
5ac5770331 version: bump version number. 2023-02-24 08:58:11 -07:00
UpstreamData
f131ebbdf5 bug: fix miner mode needing to be parsed as an int not a str. 2023-02-24 08:57:28 -07:00
UpstreamData
5441e50f73 version: bump version number. 2023-02-24 08:49:29 -07:00
UpstreamData
dc6a952de4 bug: fix backwards modes for X19. 2023-02-24 08:49:13 -07:00
UpstreamData
b781d215fb version: bump version number. 2023-02-24 08:44:20 -07:00
UpstreamData
086b31ba23 feature: add enum for miner mode in config. 2023-02-24 08:43:52 -07:00
UpstreamData
46b7352769 version: bump version number. 2023-02-23 15:39:37 -07:00
UpstreamData
e218c5039d bug: fix wrong LPM mode number for X19. 2023-02-23 15:39:08 -07:00
UpstreamData
3bb392980e version: bump version number. 2023-02-23 15:22:49 -07:00
UpstreamData
92264619d2 bug: fix missing autotuning wattage. 2023-02-23 15:22:23 -07:00
UpstreamData
3e21829fae version: bump version number. 2023-02-23 15:16:23 -07:00
UpstreamData
d3619b0e48 bug: fix insane amount of warnings when getting config. 2023-02-23 15:15:58 -07:00
UpstreamData
0fbb05d62d version: bump version number. 2023-02-23 15:05:29 -07:00
UpstreamData
01fc2591ad bug: fix a missed check for missing pool info. 2023-02-23 15:03:54 -07:00
UpstreamData
c08d7fa5cd version: bump version number. 2023-02-23 14:47:30 -07:00
UpstreamData
91c0e1c125 feature: add low power mode ability for X19 possibly. 2023-02-23 14:44:43 -07:00
UpstreamData
3d137f95d9 version: bump version number. 2023-02-23 12:16:56 -07:00
UpstreamData
d5e8062f09 bug: make sure self.config is set in all send or get config methods. 2023-02-23 12:16:19 -07:00
UpstreamData
2dc4b2cb8a tests: Update unittests. 2023-02-23 11:42:20 -07:00
UpstreamData
5ff0074d33 bug: update pyproject.toml and poetry.lock to be on recent versions and consistent. 2023-02-23 09:42:55 -07:00
UpstreamData
bbc88e175c version: bump version number. 2023-02-22 16:14:23 -07:00
UpstreamData
ff54bea0ed feature: add miner load balancer. 2023-02-22 16:13:48 -07:00
UpstreamData
bcfa807e12 version: bump version number. 2023-02-22 13:00:29 -07:00
UpstreamData
728e94f120 bug: fix OSError.winerror missing on some systems with errno. 2023-02-22 13:00:09 -07:00
UpstreamData
5f2832d632 version: bump version number. 2023-02-22 12:11:37 -07:00
UpstreamData
59e5be280f bug: fix a division by 0 error edge case in MinerData. 2023-02-22 12:10:53 -07:00
UpstreamData
e6424acf5f version: bump version number. 2023-02-22 11:43:42 -07:00
UpstreamData
34389e9133 feature: add M30S++ VH70 chip count. 2023-02-22 11:43:22 -07:00
UpstreamData
b0f7629607 version: bump version number. 2023-02-22 11:22:29 -07:00
UpstreamData
6e50f1f769 feature: add chip counts for M30S++VH50. 2023-02-22 11:21:49 -07:00
Upstream Data
708b506f6f version: bump version number. 2023-02-18 10:10:42 -07:00
Upstream Data
673d63daf0 bug: fix from_dict loading of MinerConfig for new version of BOSMiner. 2023-02-18 10:10:27 -07:00
Upstream Data
ea55fed8d1 version: bump version number. 2023-02-18 09:45:59 -07:00
Upstream Data
f5fd539eba bug: fix weird configuration format with BOS+ machines. 2023-02-18 09:45:38 -07:00
Upstream Data
51a56f441c version: bump version number. 2023-02-18 09:34:29 -07:00
Upstream Data
54310b1d79 bug: fix bad capitalization on S99Bosminer. 2023-02-18 09:34:03 -07:00
Upstream Data
cb30b761dc version: bump version number. 2023-02-16 18:36:38 -07:00
Upstream Data
cb50a7cac8 feature: add support for configuring BOS+ BBB, and add support for new BOS+ config version 2.0. 2023-02-16 18:36:03 -07:00
UpstreamData
738af245cb version: bump version number. 2023-02-16 13:35:45 -07:00
UpstreamData
71e9af1b91 format: improve warning locations to remove warnings when connections are refused. 2023-02-16 13:35:20 -07:00
UpstreamData
1cd2566d0a version: bump version number. 2023-02-16 12:23:29 -07:00
UpstreamData
1f1e5f23a2 bug: fix a bug where not all errors could be handled when scanning. 2023-02-16 12:22:58 -07:00
UpstreamData
3394234e4f version: bump version number. 2023-02-16 08:58:17 -07:00
UpstreamData
e9882124ff formatting: removed print statements. 2023-02-16 08:57:51 -07:00
UpstreamData
1e5b19c149 version: bump version number. 2023-02-16 08:47:15 -07:00
UpstreamData
c9339fec2f bug: fix issues with new versions of braiins OS, and fix bugs with innosilicon miners not returning much data at all. 2023-02-16 08:46:32 -07:00
UpstreamData
018c09e84f version: bump version number. 2023-02-15 14:34:08 -07:00
UpstreamData
46e7f9a569 bug: remove a missed print statement. 2023-02-15 14:31:32 -07:00
UpstreamData
996ab58252 version: bump version number. 2023-02-15 14:19:57 -07:00
UpstreamData
04974d5287 bug: fix reboot and restart on btminer not returning data. 2023-02-15 14:17:57 -07:00
UpstreamData
1a8a5ccb0e version: bump version number. 2023-02-14 10:33:46 -07:00
UpstreamData
4c61c4c345 bug: add MAC address support for stock S9s. 2023-02-14 10:33:14 -07:00
UpstreamData
a6d6bfe73d version: bump version number. 2023-02-14 10:19:20 -07:00
UpstreamData
f159e9ccb4 bug: add additional X19 MAC address check. 2023-02-14 10:18:52 -07:00
UpstreamData
8ae2932274 version: bump version number. 2023-02-14 10:12:59 -07:00
UpstreamData
52786ba954 feature: add support for VNISH miners. 2023-02-14 10:12:13 -07:00
Upstream Data
f5cc526e8a version: bump version number. 2023-02-13 19:38:04 -07:00
Upstream Data
a616aaba04 bug: fix an issue where GQL can fail to get hostname for permission errors. 2023-02-13 19:37:07 -07:00
UpstreamData
15b4177ce4 formatting: update copyright formatting. 2023-02-13 16:03:38 -07:00
UpstreamData
5b382cdb0b version: bump version number. 2023-02-13 14:52:42 -07:00
UpstreamData
16622099c8 feature: add static IP configuration for whatsminers. 2023-02-13 14:52:18 -07:00
UpstreamData
a75434fe7b version: bump version number. 2023-02-13 12:39:20 -07:00
UpstreamData
020558ed4d Add the ability to set static IP and hostname on X19. 2023-02-13 12:38:03 -07:00
Upstream Data
39a82d03bc version: bump version number. 2023-02-11 21:28:16 -07:00
Upstream Data
41ecb5dbc6 bug: fix a bug with power_off not working properly with the respbefore flag by faking data, hopefully will be fixed by Whatsminer in a later update. 2023-02-11 21:27:51 -07:00
Upstream Data
2d057ca9f6 version: bump version number. 2023-02-11 19:45:03 -07:00
Upstream Data
b71b23d2a0 bug: add a check for power_on in reboot check. 2023-02-11 19:44:26 -07:00
UpstreamData
b32649435d version: bump version number. 2023-02-09 15:48:49 -07:00
UpstreamData
c0096126df bug: Reverse check for whatsminer fault light as it was backwards. 2023-02-09 15:47:11 -07:00
UpstreamData
d632360932 version: bump version number. 2023-02-09 10:37:19 -07:00
UpstreamData
400001fa38 version: bump version number. 2023-02-07 13:41:06 -07:00
UpstreamData
4ff32a8081 feature: allow get_data to pick which data to gather in the first place to allow for speed optimizations. 2023-02-07 13:40:09 -07:00
UpstreamData
33b4ae2f2f version: bump version number. 2023-01-31 09:56:16 -07:00
UpstreamData
62194bd627 bug: add chip counts for M31S+ V30, V40, and V100. 2023-01-31 09:54:35 -07:00
UpstreamData
83bb2950fa version: bump version number. 2023-01-30 15:02:49 -07:00
UpstreamData
262dee3cfd bug: update whatsminer fan counts for water cooled racks. 2023-01-30 15:01:42 -07:00
UpstreamData
7ccf6ed610 bug: update whatsminer error codes. 2023-01-30 14:49:25 -07:00
UpstreamData
21b189f5a8 version: bump version number. 2023-01-30 13:46:32 -07:00
UpstreamData
d8d8a050ce docs: update docs to reflect new whatsminers. 2023-01-30 13:45:50 -07:00
UpstreamData
b9ca810903 feature: Add every whatsminer type known to man (or at least microBT). 2023-01-30 13:07:35 -07:00
Upstream Data
6ad750d3e9 small fix to BTMiner error codes to make things a bit more efficient. 2023-01-27 22:14:51 -07:00
UpstreamData
8423b64825 docs: update documentation. 2023-01-27 09:51:58 -07:00
UpstreamData
742ddef227 version: bump version number. 2023-01-27 09:42:01 -07:00
UpstreamData
85d7f0abfb feature: add nominal_hashrate to miner data 2023-01-27 09:41:25 -07:00
UpstreamData
c4b4fa293d version: bump version number 2023-01-27 08:39:13 -07:00
UpstreamData
0204abfead bug: fix a bug with older M20 units not identifying version correctly. 2023-01-27 08:38:43 -07:00
Upstream Data
3510f7b9d3 bump version number 2023-01-26 22:24:44 -07:00
UpstreamData
2d4c063dfa Update get_data to us get_some_data sub functions. (#27) 2023-01-26 22:18:03 -07:00
Colin Crossman
67b3e2f312 version: bump version number 2022-12-19 08:42:56 -07:00
Arceris
82006de30f Merge dev branch into main (#25) 2022-12-19 08:35:29 -07:00
Arceris
5bde9d7fe6 Improvement to fault_light_on
Allow user to set a flash pattern, and if not, set a nice default flash pattern.
2022-12-18 16:30:06 -07:00
Arceris
f7cd428366 updates to set_led
Fix typo in param=auto, and set better raw defaults for flashing
2022-12-18 16:27:34 -07:00
Colin Crossman
d5e797de9e Squash Whatsminer LED bug
old implementation broke command syntax due to since required command parameters would be left off in certain cases.
2022-12-13 11:42:36 -07:00
UpstreamData
b9d5e7b206 version: bump version number. 2022-12-13 10:05:55 -07:00
UpstreamData
2d8c7eb4fd feature: add support for whatsminer M30S+ VG40 2022-12-13 10:05:07 -07:00
UpstreamData
f69e07fe68 version: bump version number. 2022-12-05 09:49:03 -07:00
UpstreamData
84aab38954 bug: properly shorten stratum URLs when gathering data from graphql. 2022-12-05 09:48:40 -07:00
UpstreamData
dcf37481bd version: bump version number. 2022-12-05 09:35:44 -07:00
UpstreamData
1a9cca84d5 bug: fix pool split not being found correctly with braiinsOS. 2022-12-05 09:34:43 -07:00
UpstreamData
c5272d67de version: bump version number 2022-12-03 14:20:57 -07:00
UpstreamData
3bcfb14177 feature: add support for Whatsminer M31SV20, and fix a bug with miner factory not identifying the miners properly by removing a V prefix. 2022-12-03 14:20:37 -07:00
UpstreamData
566280f280 docs: fix some missing data in the docs. 2022-12-02 16:10:30 -07:00
UpstreamData
a814f7eefb Update README.md 2022-12-02 16:06:22 -07:00
UpstreamData
097b8ed534 version: bump version number. 2022-12-02 15:57:52 -07:00
UpstreamData
da47d72749 feature: add wattage limit in get_config when getting config from whatsminers. 2022-12-02 15:57:31 -07:00
UpstreamData
abd4d18a01 feature: add whatsminer M31SV10 and V60. 2022-12-02 15:51:27 -07:00
UpstreamData
2adbce3c21 version: bump version number. 2022-12-02 09:26:53 -07:00
UpstreamData
c41324b324 bug: fix a bug with MinerAPI.commands causing an infinite recursion loop when checking a list of commands with get_commands, and ficx some weirdness where BTMiner doesnt return any data. 2022-12-02 09:26:17 -07:00
UpstreamData
151a4f6c2d version: bump version number. 2022-12-01 16:18:07 -07:00
UpstreamData
d23777a83f feature: Switch to using semaphores in miner network to rate limit as they are much more friendly. 2022-12-01 16:17:46 -07:00
UpstreamData
bb0aee8337 version: bump version number. 2022-12-01 15:54:09 -07:00
UpstreamData
2a23acb73a bug: fix BTMiner not responding to pause_mining and resume_mining causing an exception. 2022-12-01 15:53:47 -07:00
UpstreamData
ad5eb0cef6 bug: fix a bug with updated logging. 2022-12-01 15:40:40 -07:00
UpstreamData
07dd8f55fe format: improve logging. 2022-12-01 15:02:17 -07:00
UpstreamData
bafa91cc47 version: bump version number. 2022-11-30 10:48:20 -07:00
UpstreamData
16399510fa feature: add set_power_limit to all miners that support it. 2022-11-30 10:47:45 -07:00
UpstreamData
e9f54eec0a version: bump version number. 2022-11-30 10:01:27 -07:00
UpstreamData
fbbbc9f215 bug: Add VH60 to miner factory as it was missing. 2022-11-30 10:01:01 -07:00
UpstreamData
69e4f575c0 bug: fix a bug wth bosminer where it will sometimes not get data from graphql 2022-11-30 09:59:12 -07:00
UpstreamData
e95659d2e0 version: bump version number 2022-11-29 09:36:41 -07:00
UpstreamData
35f34310ec bug: fix an issue with incorrect type hinting. 2022-11-29 09:36:24 -07:00
UpstreamData
acc18e20fd Merge remote-tracking branch 'origin/master'
# Conflicts:
#	pyproject.toml
2022-11-24 11:04:19 -07:00
UpstreamData
72460eac08 version: bump version number 2022-11-24 11:03:54 -07:00
UpstreamData
3e5f9d4eca version: bump version number 2022-11-24 11:01:30 -07:00
UpstreamData
e873fa252c feature: add support for setting wattage on whatsminers with the new 2.0.5 API 2022-11-24 09:56:25 -07:00
UpstreamData
ff2c083a19 feature: add new whatsminer commands for version 2.0.5 2022-11-24 09:51:40 -07:00
UpstreamData
a30a84c34b version: bump version number 2022-11-22 18:28:02 -07:00
UpstreamData
97d2023298 feature: add support for whatsminer M31S V70 2022-11-22 18:27:35 -07:00
UpstreamData
1ce8430a14 version: bump version number 2022-11-21 11:28:29 -07:00
UpstreamData
1c0b638818 feature: add S19a Pro 2022-11-21 11:27:52 -07:00
UpstreamData
e852588eeb version: bump version number 2022-11-18 11:15:07 -07:00
UpstreamData
08b9bfd854 bug: fix error with getting miner failing to find a description key. 2022-11-18 11:14:35 -07:00
UpstreamData
7ee2f3a29a version: bump version number 2022-11-17 15:27:24 -07:00
UpstreamData
5ee6a38f39 bug: fix a bug with identifying some older version of BOSMiner. 2022-11-17 15:27:06 -07:00
UpstreamData
8f0bfd5f83 version: bump version number. 2022-11-16 14:30:52 -07:00
UpstreamData
c54f39fc77 bug: fix int and str addition in graphQL. 2022-11-16 14:30:29 -07:00
UpstreamData
eb40769ccf format: improve formatting 2022-11-15 11:28:35 -07:00
UpstreamData
418c62b40d version: bump version number 2022-11-14 13:50:28 -07:00
UpstreamData
198a480c35 bug: fix bug with read timeout not being caught when sending graphql query 2022-11-14 13:49:57 -07:00
UpstreamData
2d4bf4e847 version: bump version number 2022-11-14 11:20:54 -07:00
UpstreamData
774e3d1a62 bug: fix wattage not setting correctly for some BOS+ miners with issues. 2022-11-14 11:20:27 -07:00
UpstreamData
ade3cd6fee version: bump version number 2022-11-14 09:56:18 -07:00
UpstreamData
28dc3ccb84 version: bump version number 2022-11-14 09:51:34 -07:00
UpstreamData
6ca8582ec3 bug: improve robustness of identifying new versions of bosminer running BOSer. 2022-11-14 09:49:19 -07:00
UpstreamData
74b4aeb44a version: bump version number 2022-11-14 09:14:28 -07:00
UpstreamData
9c7ab5ac57 bug: fix support for new miners that return a BOSer string in version data. 2022-11-14 09:10:18 -07:00
Upstream Data
65ecf1fea2 version: bump version number 2022-11-13 19:36:25 -07:00
Upstream Data
44142c658b format: remove print statements 2022-11-13 19:36:07 -07:00
Upstream Data
25a205ce6c version: bump version number 2022-11-13 19:27:55 -07:00
Upstream Data
25094084cf bug: clarify uppercasing data from __get_model_from_graphql() 2022-11-13 19:27:32 -07:00
Upstream Data
4eac601153 version: bump version number 2022-11-13 19:17:43 -07:00
Upstream Data
f0d8d66b9b bug: fix not handling errors in send_graphql_query 2022-11-13 19:16:48 -07:00
Upstream Data
cfa550f8c0 version: bump version number 2022-11-13 19:07:56 -07:00
Arceris
91f6a5bf41 bug: catch TypeError on temps 2022-11-13 19:06:52 -07:00
Upstream Data
464bd6be65 version: bump version number. 2022-11-13 18:58:31 -07:00
Upstream Data
031d7e2186 bug: fix missing catching IndexError 2022-11-13 18:58:05 -07:00
Upstream Data
126b0d124c version: bump version number 2022-11-13 18:54:46 -07:00
Upstream Data
81c84a3e8f bug: fix a bug with no try except blocks on pools. 2022-11-13 18:54:26 -07:00
Upstream Data
406d5bd549 version: bump version number 2022-11-13 18:21:18 -07:00
Upstream Data
cd5fe09fd9 bug: fix wrong formatting for multiple error handling 2022-11-13 18:20:15 -07:00
Upstream Data
766fc4efed bug: fix check light not responding properly from graphQL. 2022-11-13 17:06:35 -07:00
Upstream Data
b70fed40c8 bug: add try except statements to get_data to fix bugs with getting data from graphql. 2022-11-13 17:03:41 -07:00
Upstream Data
255d98fd08 bug: fix some issues with validating data from graphql properly 2022-11-13 16:48:22 -07:00
Upstream Data
78304631f7 bug: fix errors not registering properly on braiins OS miners 2022-11-13 16:34:26 -07:00
Upstream Data
ab230844fc bug: fix an issue with chip count not receiving properly in some cases. 2022-11-13 16:31:41 -07:00
Upstream Data
8a58cb9fd3 format: remove extra print 2022-11-13 16:28:36 -07:00
Upstream Data
70b6ed73dc bug: fix manual return from __get_devdetails_and_version 2022-11-13 16:27:42 -07:00
Upstream Data
d2400bf44e bug: fix identifying stock as bosminer. 2022-11-13 16:22:57 -07:00
Upstream Data
db780fe876 version: bump version number 2022-11-13 15:14:16 -07:00
Upstream Data
cd84ae828a bug: fix a bug with some missing temperatures in graphql. 2022-11-13 15:13:56 -07:00
Upstream Data
970d5d1031 version: bump version number 2022-11-13 14:39:23 -07:00
Upstream Data
da0e327ec7 feature: add support for graphQL for BOS miners which may be having API issues, such as BBB. 2022-11-13 14:38:44 -07:00
Upstream Data
4c84a8d572 bug: ensure bosminer check_light backwards compatibility 2022-11-13 11:06:28 -07:00
Upstream Data
1cfd895deb feature: improve speed of bosminer check_light by 10x using graphql. 2022-11-13 11:01:22 -07:00
Upstream Data
d0da08eb10 version: bump version number 2022-11-12 14:51:30 -07:00
Upstream Data
ee4f2cd87d bug: fix win error check not being cross platform 2022-11-12 14:51:10 -07:00
UpstreamData
8a6577c8aa docs: Update README.md. 2022-11-10 14:20:41 -07:00
UpstreamData
ed5eae4187 format: add isort to dev requirements. 2022-11-10 14:17:31 -07:00
UpstreamData
f3b25027ad format: add isort to pre-commit and sort imports. 2022-11-10 14:15:45 -07:00
UpstreamData
228daecbbf version: bump version number 2022-11-08 15:09:32 -07:00
UpstreamData
81aa569d07 feature: rework whatsminer error codes to be able to allow an arbitrary slot number to be returned from the BTMiner API. 2022-11-08 15:08:47 -07:00
upstreamdata
aba8d7b8b9 bug: fix an issue with get data on unknown miners. 2022-11-08 13:38:19 -07:00
Upstream Data
449403bc57 version: bump version number. 2022-11-07 20:35:51 -07:00
Upstream Data
997a1bbe31 feature: add allow_warning to get_data to allow suppressing warnings. 2022-11-07 20:35:23 -07:00
Arceris
2c7e0e3efe Merge pull request #24 from UpstreamData/crc
Merge in branch refactoring the hashboard data
2022-11-07 19:25:06 -07:00
UpstreamData
6051a46654 docs: update docs to show cls.fields() 2022-11-07 12:54:40 -07:00
UpstreamData
c7847d2789 feature: add fields classmethod to all dataclasses to show what the fields are in each class. 2022-11-07 12:53:01 -07:00
UpstreamData
215af72a6b feature: add 0 as error_code for bos errors and X19 errors to make them consistent with the other types of errors. 2022-11-07 12:49:01 -07:00
UpstreamData
b33586f8eb feature: add fields() method to MinerData dataclass. 2022-11-07 10:51:34 -07:00
UpstreamData
8db81d9b3c format: remove prints. 2022-11-07 10:18:50 -07:00
UpstreamData
cf3b2fedf4 bug: fix a missed key step in btminer get errors. 2022-11-07 10:18:22 -07:00
UpstreamData
81db6d8e28 format: remove print in tunerstatus. 2022-11-07 10:11:08 -07:00
UpstreamData
d47e59d057 bug: fix a bug with older versions of BOSMiner having tuner status in a different place. 2022-11-07 10:09:56 -07:00
UpstreamData
8388d2f4ac bug: change MinerData().total_chips from reduce to sum, as reduce was causing issues when instantiating MinerData with a hashboard list that is empty. 2022-11-07 09:37:22 -07:00
UpstreamData
f5ec513ce0 bug: fix BMMiner warning when getting data from X19. 2022-11-07 09:07:32 -07:00
UpstreamData
8975842f0b bug: fix for some BMMiner models which report no boards causing an error when getting data. 2022-11-07 08:52:24 -07:00
Upstream Data
c6ca1df112 bug: fix some issues with get data on X19 from CGMiner on Vnish to BMMiner on stock. 2022-11-05 10:15:18 -06:00
Upstream Data
92f58a9682 bug: fix fan count and ideal chips for M34S+. 2022-11-05 10:04:17 -06:00
Upstream Data
5dc19dbd78 feature: add support for avalonminers using new hashboard model. 2022-11-05 10:03:02 -06:00
Upstream Data
b0fc11bcc1 bug: fix M34S+ not having ideal board count. 2022-11-05 09:50:03 -06:00
Upstream Data
23ebe460a4 format: Reformat some files. 2022-11-05 09:47:25 -06:00
Upstream Data
92db8c8161 format: Improve T9 formatting with get data on hiveon. 2022-11-05 09:44:38 -06:00
Upstream Data
d9b522734a format: reformat T3H+ get_data to improve error handling and checking of data. 2022-11-05 09:40:56 -06:00
Colin Crossman
e02457f0b2 bug: fix import for HashBoard 2022-11-04 21:55:44 -06:00
Colin Crossman
104b4c18c2 format: remove vestigial elements of btminer 2022-11-04 21:28:59 -06:00
Colin Crossman
1970f8c924 feature: add innosilicon support for new HashBoard format. 2022-11-04 21:28:33 -06:00
Colin Crossman
e431a06ac5 feature: add cgminer support for new HashBoard structure 2022-11-04 21:28:07 -06:00
Upstream Data
6da9b58088 bug: fix missing initialization variables on HashBoard when being called from within get_data on bos, T9, and btminer. 2022-11-04 20:26:28 -06:00
Upstream Data
3108443041 feature: add bosminer support for new HashBoard format. 2022-11-04 20:22:07 -06:00
Upstream Data
37ebb9e6c3 feature: add T9 support for new HashBoard format. 2022-11-04 20:10:50 -06:00
Upstream Data
6c2e0f59b1 feature: add the remainder of the backwards compatible MinerData board related parts that were lost in converting to HashBoard dataclass. 2022-11-04 20:00:03 -06:00
Upstream Data
6eb9cdce90 feature: add left_chips, center_chips, and right_chips to MinerData as properties that compute the correct board position from hashboards. 2022-11-04 19:55:13 -06:00
Upstream Data
e96d9447d1 format: reformat btminer.py 2022-11-04 19:44:49 -06:00
Upstream Data
d3cca11322 feature: add new HashBoard data structure to bmminer, and add ideal_hashboards to BaseMiner. 2022-11-04 19:44:19 -06:00
Colin Crossman
86155db455 Initial modifications to account for differential hashboard counts
Now storing the hasboard data as an array of datastructs. Not fully fleshed out yet, but this is where I'm going.
2022-11-04 15:48:30 -06:00
UpstreamData
5b078b4b27 feature: add support for M34S+ and M34S+ VE10 2022-11-04 13:12:28 -06:00
UpstreamData
9672dd6873 bug: fix warnings when new whatsminer API commands don't exist. 2022-11-02 10:32:33 -06:00
Upstream Data
1587f65196 version: bump version number 2022-11-01 22:52:56 -06:00
Upstream Data
5ff10c0cdd bug: fix the v2.0.4 whatsminer error codes bug to work with new versions where it was fixed. 2022-11-01 22:15:13 -06:00
UpstreamData
aa0a028564 Update .gitignore 2022-11-01 14:17:07 -06:00
UpstreamData
82f6d2f274 version: bump version number
resolves #22
2022-11-01 12:59:55 -06:00
UpstreamData
833de3ab43 feature: add support for whatsminer API v2.0.4, which moves the location of error codes to a new function (that happens to have very incorrect JSON) 2022-11-01 12:57:33 -06:00
UpstreamData
08d273c7c1 version: bump version number 2022-11-01 08:14:56 -06:00
UpstreamData
aac7598187 bug: Fix whatsminers not reporting error codes due to self.api.get_psu() causing a failed multicommand when used with older miners. 2022-11-01 08:14:06 -06:00
UpstreamData
5c0ac4e665 feature: added the ability to call btminer privileged commands as their own function, and abstracted out most of the complexity. 2022-10-31 09:46:28 -06:00
Upstream Data
7bd5e49412 bug: fix for btminer get_data() for cases where arbitrary amounts of errors with no error information are returned from the api to have them not be added to the error list. 2022-10-30 21:17:26 -06:00
Upstream Data
53ff3c5f79 bug: fix _load_api_data() raising an error when api data is an arbitrarily large size and overflows the receive buffer by parsing out the last incomplete item and repairing the json. 2022-10-30 21:14:14 -06:00
Upstream Data
36ae6e5272 docs: add M5X to nav directory 2022-10-21 18:43:13 -06:00
Upstream Data
fb3dffb216 docs: add relative paths to supported miner types to fix read the docs not going to the correct page. 2022-10-21 18:39:15 -06:00
Colin Crossman
ff6a6d2ec6 Add support for M50, forgot to update this file 2022-10-21 18:13:54 -06:00
Colin Crossman
f4bbc2c3e5 Add support for M50
Received M50 units, added support for them.
2022-10-21 18:12:05 -06:00
UpstreamData
4dbfdbe29c bump version number 2022-10-12 15:50:12 -06:00
UpstreamData
5e2a18f91e add fan_psu to MinerData, only works for whatsminers. 2022-10-12 15:42:27 -06:00
UpstreamData
3363bdc592 add MinerData().as_csv() to documentation. 2022-10-04 14:44:02 -06:00
UpstreamData
08180a2d59 bump version number 2022-10-04 08:30:26 -06:00
UpstreamData
1a64ff4038 add support for whatsminer in miner listener, and fix space in MinerData.as_csv() 2022-10-04 08:28:24 -06:00
UpstreamData
8ad90a6abb bump version number 2022-10-03 13:52:04 -06:00
UpstreamData
8cdd5ff015 improve MinerData().as_csv()` 2022-10-03 13:51:44 -06:00
UpstreamData
a08f434e1f bump version number 2022-10-03 13:43:08 -06:00
UpstreamData
9acd6d2fea add MinerData().as_csv() 2022-10-03 13:42:47 -06:00
UpstreamData
0a1cdea2e3 bump version number 2022-09-30 16:01:28 -06:00
UpstreamData
73b1a0493c Add the ability to add MinerData together and sum them, as well as compute division and floor division on them. 2022-09-30 16:00:45 -06:00
UpstreamData
d3a5517fa9 bump version number 2022-09-29 14:10:19 -06:00
UpstreamData
ad42251ee9 add S19 XP to docs 2022-09-29 14:09:26 -06:00
Arceris
0670938ed3 Add in S19 XP spec, and also make an adjustment to BMMiner so it won't fail when hashboards are missing (#20)
* Add in spec for S19 XP

* Adjust BMMiner to account for missing hashboards
2022-09-29 14:03:53 -06:00
UpstreamData
3e96889976 improve poetry setup instructions and improve documentation 2022-09-28 12:54:04 -06:00
UpstreamData
5a7b43ad74 Update README.md 2022-09-28 11:46:56 -06:00
UpstreamData
08c4863a2e improve poetry setup and install instructions 2022-09-28 11:39:25 -06:00
UpstreamData
4dbab75cf4 bump version number 2022-09-28 10:20:17 -06:00
UpstreamData
a90ad3ba6e fix incorrect chip count on M31S+ V30 2022-09-28 10:19:56 -06:00
UpstreamData
98a94ce4a6 bump version number 2022-09-28 10:06:53 -06:00
UpstreamData
f0a8b6e1c7 add support for whatsminer M31S+ V30 2022-09-28 10:05:28 -06:00
UpstreamData
e07bd3bffb bump version number 2022-09-26 13:08:27 -06:00
UpstreamData
dcce944390 Fix a bug where older version of bosminer return excessive hashboard error information 2022-09-26 12:27:37 -06:00
UpstreamData
03ecd118a3 add support for M31S+ V60 and V90 2022-09-26 11:51:47 -06:00
UpstreamData
97c0331762 bump version number 2022-09-26 11:33:42 -06:00
UpstreamData
eda9804dea add support for some new whatsminers types, M31S+ v40 and v80, and improve documentation of supported types. 2022-09-26 11:32:55 -06:00
UpstreamData
e94c81ce44 improve miner network functionality 2022-09-26 09:15:37 -06:00
UpstreamData
c95c58138e bump version number 2022-09-22 10:07:31 -06:00
UpstreamData
03c93b4de1 added pause_mining and resume_mining to all miners, added get_errors to whatsminers, and improved get_errors type hinting 2022-09-22 10:06:27 -06:00
UpstreamData
ff0d15c365 bump version number 2022-09-22 09:06:51 -06:00
UpstreamData
eadcb76d31 add stop_mining and resume_mining for X19 devices 2022-09-22 09:06:22 -06:00
UpstreamData
b7ce9288f8 bump version number 2022-09-13 09:53:03 -06:00
UpstreamData
e077a099d9 add global Innosilicon password option to settings 2022-09-13 09:52:33 -06:00
UpstreamData
8542acfb01 improve documentation 2022-09-13 09:11:15 -06:00
UpstreamData
0d80ce5a0e bump version number 2022-09-12 15:28:22 -06:00
UpstreamData
ddcafe0f2b finish abstracting BaseMiner by implementing get_data() as abstract 2022-09-12 15:27:51 -06:00
UpstreamData
ea195b34db update tests and add code coverage with coverage, although coverage is not required 2022-09-12 15:18:00 -06:00
UpstreamData
7377cb0d26 refactor some classes into their own files and fill base __init__.py with imports 2022-09-12 15:15:13 -06:00
UpstreamData
24b66de971 bump version number 2022-09-06 11:18:34 -06:00
UpstreamData
62d664a14c strip file output when checking for fault light in bosminer 2022-09-06 11:18:17 -06:00
UpstreamData
03b9a90f68 bump version number 2022-09-06 11:02:05 -06:00
UpstreamData
fefe0324b9 fix a bug with checking miner fault lights in bosminer 2022-09-06 11:01:42 -06:00
UpstreamData
62b14a78b7 bump version number 2022-09-06 10:49:16 -06:00
UpstreamData
0ff505bbb4 add support for innosilicon T3H+ 2022-09-06 10:48:04 -06:00
UpstreamData
b6c8c930a2 bump version number 2022-08-30 16:01:48 -06:00
UpstreamData
903bb93c4e add check_light() for bosminers by checking if delay_on exists in the Red LED directory 2022-08-30 10:51:22 -06:00
UpstreamData
59667cf104 bump version number 2022-08-29 09:53:01 -06:00
UpstreamData
3fd1b41bec add support for whatsminer VH60 2022-08-29 09:52:35 -06:00
UpstreamData
6569107f64 bump version number 2022-08-29 09:07:02 -06:00
UpstreamData
9d746a6dcb add errors to MinerData().as_influxdb() 2022-08-29 09:06:20 -06:00
UpstreamData
fce4c07c32 bump version number 2022-08-25 15:34:28 -06:00
UpstreamData
094857758a update MinerData().as_influxdb() to include properties. 2022-08-25 15:34:04 -06:00
UpstreamData
2a49b89849 bump version number 2022-08-25 13:09:19 -06:00
UpstreamData
4ecd135734 fix a bug with incorrect types in miner data 2022-08-25 13:09:03 -06:00
UpstreamData
836defc216 bump version number 2022-08-25 13:04:06 -06:00
UpstreamData
f8f777b5b5 fix tag data to be escaped properly 2022-08-25 13:03:46 -06:00
UpstreamData
b15e0a7363 bump version number 2022-08-25 12:50:55 -06:00
UpstreamData
5c1d06f743 attempt to fix a bug with influx db miner data 2022-08-25 12:50:30 -06:00
UpstreamData
51de56feb3 bump version number 2022-08-25 12:43:05 -06:00
UpstreamData
256a4ac909 fix boolean bug in miner data 2022-08-25 12:39:57 -06:00
UpstreamData
09800c8ad2 bump version number 2022-08-24 15:18:04 -06:00
UpstreamData
83a7d8c60f add MinerData().as_json() 2022-08-24 15:17:36 -06:00
UpstreamData
ee2698be50 update poetry.lock 2022-08-24 13:56:05 -06:00
UpstreamData
dc43087b0d bump version number 2022-08-24 13:51:25 -06:00
UpstreamData
4fa3511725 add float support to MinerData().as_influx() 2022-08-24 13:50:55 -06:00
UpstreamData
4b9ae70424 bump version number 2022-08-24 13:35:48 -06:00
UpstreamData
74ebffb4fc add MinerData().as_influx() to write miner data as influx db line format data. 2022-08-24 13:34:57 -06:00
UpstreamData
54206da449 add getitem and setitem methods to MinerData 2022-08-24 10:02:51 -06:00
UpstreamData
dd54ff7ee4 bump version number 2022-08-22 15:19:08 -06:00
UpstreamData
abef0c3d59 add efficiency to MinerData 2022-08-22 14:50:49 -06:00
UpstreamData
957c9a3678 Refactor MinerFactory._get_miner_type(), move BaseMiner to its own file, and improve interface of miner.send_config() (#17) 2022-08-22 14:10:37 -06:00
Arceris
50ccfec1b3 Add a check in _parse_type_from_version (#16) 2022-08-18 10:12:19 -06:00
UpstreamData
8e7d6751e2 update docs to include all currently supported miners including BOS devices. 2022-08-12 12:30:29 -06:00
UpstreamData
b77c4173c6 update supported miners in docs and add link to it in README.md 2022-08-12 12:22:49 -06:00
UpstreamData
4941cffb70 fix a bad character in requirements.txt caused by pre-commit 2022-08-12 12:14:12 -06:00
UpstreamData
81d5d23189 Revert "Revert "attempt to improve the readability of miner_factory.py""
This reverts commit 9da5a836ce.
2022-08-11 15:22:00 -06:00
UpstreamData
9da5a836ce Revert "attempt to improve the readability of miner_factory.py"
This reverts commit c9a536fc60.
2022-08-11 15:16:42 -06:00
UpstreamData
c9a536fc60 attempt to improve the readability of miner_factory.py 2022-08-11 15:12:45 -06:00
UpstreamData
fa172b56b0 bump version number 2022-08-11 15:11:09 -06:00
UpstreamData
ee45f2342e improve how the fault light looks on whatsminers 2022-08-11 11:58:42 -06:00
UpstreamData
1f59ef025d bump version number 2022-08-10 16:26:24 -06:00
UpstreamData
d6a153144f remove print statement from btminer configuration 2022-08-10 16:25:54 -06:00
UpstreamData
99001e2e13 added the ability to configure whatsminer via API 2022-08-10 16:21:47 -06:00
UpstreamData
92b847656e add light functions for btminer, and add a way to reset to admin password for btminers to allow unlocking of priviledged API. 2022-08-10 15:31:42 -06:00
UpstreamData
a41525e828 bump version number 2022-08-10 11:18:44 -06:00
UpstreamData
5e9588cc56 add M32V20 2022-08-10 11:17:12 -06:00
UpstreamData
b8239703c1 move M32 to separate file. 2022-08-10 11:14:06 -06:00
Colin Crossman
5d49135b59 Add hooks for M32 (not S) 2022-08-10 11:06:54 -06:00
UpstreamData
3a5a76080b add pre-commit hooks 2022-08-10 09:57:31 -06:00
UpstreamData
f23e10d629 add better hiveon support and improve T9 functionality. 2022-08-10 09:04:01 -06:00
UpstreamData
b7d4891140 bump version number 2022-08-09 11:12:10 -06:00
UpstreamData
5f5cbd9060 add support for setting X19 web passwords and X17 web passwords. 2022-08-09 11:04:08 -06:00
UpstreamData
8379359caf update documentation and make BaseMiner and BaseMinerAPI unable to be instantiated directly. Add more unittests for miners. 2022-08-08 13:19:59 -06:00
UpstreamData
62238192ce bump version number 2022-08-05 16:34:00 -06:00
UpstreamData
1997003643 fix a bug with whatsminer crashing if hitting a S19 condition 2022-08-05 16:33:40 -06:00
UpstreamData
3a81844898 bump version number 2022-08-05 12:12:25 -06:00
UpstreamData
0ac80fb205 fix a bug with vnish miner identification 2022-08-05 12:12:10 -06:00
UpstreamData
9494018c12 bump version number 2022-08-05 12:08:05 -06:00
UpstreamData
0bc86c98c5 add support for some X19 models running vnish to be able to get miner type from them 2022-08-05 12:07:33 -06:00
UpstreamData
f0d69c9ca7 bump version number 2022-08-05 10:23:22 -06:00
UpstreamData
b81590bd2e add support for X19 miner errors codes shown on their dashboard 2022-08-05 10:23:03 -06:00
UpstreamData
a53e01df6f bump version number 2022-08-02 08:19:03 -06:00
UpstreamData
f63e063954 fix a bug with not capitalizing BITMAIN for a model check 2022-08-02 08:18:46 -06:00
upstreamdata
9cbaf7076a bump version number 2022-07-28 12:29:24 -06:00
upstreamdata
daa5ac5870 fixed a bug with capitalization of "Pro" in antminer models 2022-07-28 12:28:55 -06:00
upstreamdata
0b8c08016b bump version number. 2022-07-27 23:48:42 -06:00
upstreamdata
8c768d351b fix a bug with braiinsOS+ miners which return with a capital letter in their model instead of a lowercase letter. 2022-07-27 23:44:19 -06:00
UpstreamData
c9e7fa2629 bump version number 2022-07-22 13:05:13 -06:00
UpstreamData
9d3f2b5968 add support for M20 versions and update docs 2022-07-22 13:04:47 -06:00
UpstreamData
283e3d5e11 bump version number 2022-07-21 08:43:30 -06:00
UpstreamData
add4b575c2 update shields and improve typing and handling of fault light checks 2022-07-21 08:42:35 -06:00
UpstreamData
af2f1e9ad5 misc docs changes 2022-07-20 14:54:59 -06:00
UpstreamData
8258320a7b fix a bug with avalonminer imports and bump version number 2022-07-20 14:42:33 -06:00
UpstreamData
a5dc7f485b bump version number 2022-07-20 14:37:04 -06:00
UpstreamData
025b5bf6f0 improved avalonminer handler and added fault light to get_data 2022-07-20 14:36:13 -06:00
UpstreamData
3d3064d78e improve some type hinting compatibility 2022-07-20 11:19:13 -06:00
UpstreamData
2e3991355b Update README.md 2022-07-20 10:05:23 -06:00
UpstreamData
73a4cf5834 bump version number 2022-07-19 16:16:56 -06:00
UpstreamData
b120064e80 fixed a bug with miner factory not handling ConnectionRefused errors properly 2022-07-19 16:16:36 -06:00
UpstreamData
3ec833e700 add copyright license, using Apache 2.0 license 2022-07-19 15:43:24 -06:00
UpstreamData
29aeea1194 bump version number 2022-07-19 13:02:55 -06:00
UpstreamData
994d53ae3b removed arbitrary scan thread limitation dividing 2022-07-19 13:01:39 -06:00
UpstreamData
a95333eb1c removed arbitrary scan thread limitation dividing 2022-07-19 13:01:28 -06:00
UpstreamData
c5f2d71791 improved the speed of scanning by only checking secondary ports if the 4028 connection is refused 2022-07-19 13:00:15 -06:00
UpstreamData
26ae6ebfb2 bump version number 2022-07-19 11:19:32 -06:00
UpstreamData
e65cb0573d update miner factory to handle some types of stock fw S9s 2022-07-19 11:18:55 -06:00
UpstreamData
f8590b0c5f improve more typing 2022-07-18 14:46:17 -06:00
UpstreamData
43b4992cee improve logging and some documentation 2022-07-18 14:38:54 -06:00
UpstreamData
98e2cfae84 bump version number 2022-07-18 12:05:44 -06:00
UpstreamData
cb01c1a8ee update network to scan fast even if some miners are not responding properly 2022-07-18 12:05:22 -06:00
UpstreamData
36a273ec2b bump version number 2022-07-18 11:45:14 -06:00
UpstreamData
6a0dc03b9d update to a better way to handle settings 2022-07-18 11:44:22 -06:00
UpstreamData
ce7b006c8f bump version number 2022-07-18 11:23:15 -06:00
UpstreamData
88cc05bcea handle for BraiinsOS miners that dont have bosminer running for some reason 2022-07-18 11:21:40 -06:00
UpstreamData
ae749f4a90 add additional scan ports as backups in case 4028 doesn't respond 2022-07-18 10:03:39 -06:00
UpstreamData
36b30a2cdd added supported miners to the docs 2022-07-14 16:32:43 -06:00
UpstreamData
ae9f103578 bump version number 2022-07-14 11:49:34 -06:00
UpstreamData
13b583b739 fixed some bugs and added support for M20Sv10 and 20 2022-07-14 11:39:55 -06:00
UpstreamData
aaf0d7fa75 bump version number 2022-07-14 09:47:36 -06:00
UpstreamData
a8cbb6394e fix a bug with ints being passed to miner network 2022-07-14 09:45:21 -06:00
UpstreamData
ca6980b1ad update documentation and add docs from config 2022-07-13 16:17:08 -06:00
UpstreamData
c6c87a864d fix pyproject.toml 2022-07-13 14:29:06 -06:00
UpstreamData
ed17a0f436 update documentation and bump version number 2022-07-13 14:25:12 -06:00
UpstreamData
36fead3dd1 Update README.md 2022-07-13 11:57:33 -06:00
UpstreamData
ecb16c10ca Update README.md 2022-07-13 11:56:28 -06:00
UpstreamData
a540db3246 update docs requirements 2022-07-13 11:28:12 -06:00
UpstreamData
81a2f99fbf add jinja 2 to docs requirements to fix mkdocs bug 2022-07-13 11:22:00 -06:00
UpstreamData
1dd9f742ad Revert "dealete readthedocs.yaml"
This reverts commit 7bd6a0f136.
2022-07-13 11:18:56 -06:00
UpstreamData
7bd6a0f136 dealete readthedocs.yaml 2022-07-13 11:17:53 -06:00
UpstreamData
7297f12e88 update readthedocs info 2022-07-13 11:15:34 -06:00
UpstreamData
0e009c3a16 add readthedocs info 2022-07-13 11:12:29 -06:00
UpstreamData
95b0cc364b add miner data documentation 2022-07-13 11:08:12 -06:00
UpstreamData
2dcc4f0cfc add docs for miner factory and miner network 2022-07-13 10:52:42 -06:00
UpstreamData
d7e9498018 add docs for the rest of the APIs 2022-07-13 10:11:05 -06:00
UpstreamData
0324a21e79 add bmminer docs 2022-07-13 09:13:21 -06:00
UpstreamData
5700bd1c9c start adding some basic documentation 2022-07-12 16:25:05 -06:00
UpstreamData
abc6494f18 bump version number 2022-07-12 11:58:59 -06:00
UpstreamData
5de8fc064e fix a bug with hashrate parsing on braiins os devices with kh hashrates 2022-07-12 11:58:21 -06:00
UpstreamData
c9d620105b add support for braiins OS errors 2022-07-12 11:55:42 -06:00
UpstreamData
5d6fc5b26d add support for whatsminer error codes in get_data() 2022-07-12 11:41:38 -06:00
UpstreamData
6bd319355d bump version number 2022-07-12 10:26:25 -06:00
UpstreamData
31827e7dd1 fix a bug with old versions of bosminer returning not ready from fans 2022-07-12 10:25:48 -06:00
UpstreamData
26961a5d8c bump version number 2022-07-11 15:02:45 -06:00
UpstreamData
2ff09a3765 add support for getting hashrates from each board for bosminer, bmminer, and btminer 2022-07-11 15:02:04 -06:00
UpstreamData
18c26adbb6 remove dockerignore 2022-07-11 13:23:19 -06:00
UpstreamData
4bfafabe9d bump version number 2022-07-11 10:45:34 -06:00
UpstreamData
19e6ed90ec update README.md 2022-07-11 10:28:18 -06:00
UpstreamData
eca60d1eae improved whatsminer power limit handling 2022-07-11 10:15:55 -06:00
UpstreamData
8b8a592308 bump version number to 0.9.3 2022-07-11 08:29:36 -06:00
UpstreamData
c3de4188d6 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	pyproject.toml
2022-07-11 08:25:36 -06:00
UpstreamData
490138fd1a bump version number 2022-07-11 08:25:24 -06:00
UpstreamData
f566b7fcb9 bump version number 2022-07-11 08:23:04 -06:00
upstreamdata
7fb4237e51 update publish workflow to use correct secret name 2022-07-07 15:44:28 -06:00
upstreamdata
eeffdecde1 update publish workflow 2022-07-07 15:34:26 -06:00
UpstreamData
477a411c87 Create python-publish.yml 2022-07-07 15:12:38 -06:00
upstreamdata
ca77573624 update pyproject.toml 2022-07-07 14:40:07 -06:00
upstreamdata
3ec147990b added power limit vs power draw in get_data 2022-07-07 14:34:21 -06:00
upstreamdata
082240bdb6 add some missing imports 2022-07-07 14:30:19 -06:00
UpstreamData
7a7fc2c5a6 Update README.md 2022-07-07 08:09:00 -06:00
UpstreamData
dcc3e07998 Dev (#12)
* changed over to package format and removed tools, added poetry

* reformat into miner_interface project

* add dist to .gitignore

* update readme and finish reformatting

* Added couple missing imports. (#13)

* change name to pyasic

Co-authored-by: upstreamdata <brett@upstreamdata.ca>
Co-authored-by: Mika Impola <mika@impola.fi>
2022-07-07 07:57:34 -06:00
UpstreamData
5261b00aad fixed logfile in settings to allow for adding or removing a logfile 2022-06-22 13:28:37 -06:00
UpstreamData
f18d37a19e add gitignore and fix a small bug with settings if the file doesn't exist 2022-06-14 09:42:20 -06:00
UpstreamData
7c3af3da41 fixed a bug with old bosminers not updating properly 2022-06-10 13:21:31 -06:00
UpstreamData
8948af55f2 fixed a small bug with bosminer MAC 2022-06-10 11:30:24 -06:00
UpstreamData
dd8fe41ad1 added estimate env temp for X19 and change format of X19 and X17 files 2022-06-10 11:22:41 -06:00
UpstreamData
198eedcd43 added env_temp for whatsminers 2022-06-10 11:03:09 -06:00
UpstreamData
f7309decdb finish adding support for a bunch of new avalonminers 2022-06-09 14:38:51 -06:00
UpstreamData
078579d8e1 add a ton of new avalonminers to be added to miner factory later. 2022-06-09 14:10:12 -06:00
UpstreamData
39eeb13409 improved the implementation of fault lights on avalonminers by fixing a bad implementation of ascset. 2022-06-09 13:49:15 -06:00
UpstreamData
dfccd67ccb added fault lights to 1066 miners, and framework for configuring (although it may not work, the documentation implementation is broken) 2022-06-08 15:43:34 -06:00
UpstreamData
10949225c0 fix generate report pie chart to fix overlapping labels when all boards are working 2022-06-08 10:59:52 -06:00
UpstreamData
3a60a3584a added support for avalon 1066 miners 2022-06-08 10:42:19 -06:00
UpstreamData
480aab550c added advanced config file generator 2022-06-07 15:55:43 -06:00
UpstreamData
fa83e61249 fix a bug with config tool generating configs 2022-06-07 14:47:21 -06:00
UpstreamData
2f3411e12d add documentation for MinerConfig 2022-06-07 13:17:44 -06:00
UpstreamData
3e7311687e Update README.md 2022-06-07 12:01:31 -06:00
UpstreamData
bc2d549ce5 moved MinerConfig to config.__init__.py and removed old config methods 2022-06-07 11:50:36 -06:00
UpstreamData
3d31d89c9e update dev-requirements.txt 2022-06-07 11:43:00 -06:00
UpstreamData
15fc27e6fa added configuration for X19 miners 2022-06-07 11:12:26 -06:00
UpstreamData
943ebc77a1 switch braiins miners over to using new config dataclass 2022-06-07 10:49:41 -06:00
UpstreamData
733437ef03 create basic config dataclass to be used to configure miners 2022-06-06 16:05:09 -06:00
UpstreamData
b444245e98 added new whatsminer types to miner factory 2022-06-06 10:09:11 -06:00
UpstreamData
481d31a0f1 added more new whatsminer types 2022-06-06 10:06:17 -06:00
UpstreamData
264db3bdd6 fix a bug with whatsminer M21S missing import 2022-06-06 09:41:10 -06:00
UpstreamData
d292b9c195 improved whatsminer handling, and added VF20 to miner dict 2022-06-06 09:26:38 -06:00
UpstreamData
dce25a679f added new miner type M30S+VF20 2022-06-06 09:17:42 -06:00
UpstreamData
c903631742 improved build process 2022-06-06 09:17:22 -06:00
Colin Crossman
e70bfdc886 Fix indent issue that caused missing MAC addresses (#10) 2022-06-05 15:50:07 -06:00
UpstreamData
8e1803add1 made slight optimizations to get_data and the way the miner gets mac data 2022-06-03 15:30:09 -06:00
UpstreamData
7d61056ea3 added whatsminer M30S+ VE40 2022-06-03 15:00:04 -06:00
UpstreamData
0d497baa45 added mac for M20 series 2022-06-03 14:55:03 -06:00
UpstreamData
d3a71c5a93 added mac addresses to get_data 2022-06-03 14:29:10 -06:00
UpstreamData
895a5b7ac8 fixed more bugs with whatsminers and added more versions 2022-06-03 11:20:34 -06:00
UpstreamData
7a5a0b287c fixed a bug with some versions of whatsminer and improved logging 2022-06-03 09:35:55 -06:00
UpstreamData
c7d73276c8 fixed a small bug with sorting 2022-06-03 08:59:15 -06:00
UpstreamData
4bbb9d0b08 added a basis for configuration of X17 and X19 miners by getting pool info from config file. 2022-06-02 16:06:36 -06:00
UpstreamData
3ee49e6fd7 fixed a warning with ylim being set to 0 2022-06-02 14:52:17 -06:00
UpstreamData
dcd3e99d73 added interval to recording 2022-06-02 14:25:55 -06:00
UpstreamData
64018cdad8 completed basic recording functionality 2022-06-02 14:17:08 -06:00
UpstreamData
e7d269008c added the basics of the recording functionality, just need to write out to file. 2022-06-02 11:08:14 -06:00
UpstreamData
7dfe25e5d2 added base for recording miner data to pdf file. 2022-06-01 16:13:30 -06:00
UpstreamData
382f9cff76 added reboot command for X19 and X17 models on BMMiner 2022-06-01 14:02:34 -06:00
UpstreamData
a5195ff1db fix a bug with testbench where toolbox finds braiins but bench does not 2022-06-01 11:44:07 -06:00
UpstreamData
b1ec726d18 added some docstrings to data 2022-06-01 11:22:30 -06:00
UpstreamData
5ae2cb2b22 fixed a bug with not all table data getting reset on data update 2022-06-01 11:22:12 -06:00
UpstreamData
472a15f4ca added fault light function for X17 BMMiner models 2022-06-01 10:54:45 -06:00
UpstreamData
7cc7973587 fixed a bug with some BOS S17e not returning data frm devdetails and fans 2022-06-01 10:19:58 -06:00
UpstreamData
ab964e4c88 fixed a bug with sorting by chip % 2022-06-01 08:15:35 -06:00
UpstreamData
4087874b4a added get hostname to X19 miners 2022-05-31 17:05:05 -06:00
UpstreamData
844deec0d3 add fault light command to X19 miners 2022-05-31 16:54:56 -06:00
UpstreamData
d36eef4c33 switched to httpx 2022-05-31 16:08:17 -06:00
UpstreamData
69d4ee5570 Revert "add .readthedocs.yaml"
This reverts commit e7b01ccdab.
2022-05-31 13:23:41 -06:00
UpstreamData
e6d3ec01fe Merge remote-tracking branch 'origin/master' 2022-05-31 13:18:59 -06:00
UpstreamData
e7b01ccdab add .readthedocs.yaml 2022-05-31 13:18:52 -06:00
UpstreamData
38506903ea fixed an issue with BMMiner get data and bosminer get data not identifying correct board number. 2022-05-31 08:45:49 -06:00
UpstreamData
c9a1560052 Merge remote-tracking branch 'origin/master' 2022-05-30 14:20:48 -06:00
UpstreamData
88f8ff10b7 fixed a bug with sorting 2022-05-30 14:20:37 -06:00
UpstreamData
11d38c9c3b fixed a bug with sorting 2022-05-30 14:19:57 -06:00
UpstreamData
0082037f45 add dev-requirements and remove cx-freeze from requirements 2022-05-30 13:29:47 -06:00
UpstreamData
dd5ccafa1e added listener function to cfg util 2022-05-30 13:27:56 -06:00
UpstreamData
739126935a fixed some bugs with differing version of BTMiner and different versions of M30S++ having different chip counts 2022-05-30 11:13:37 -06:00
UpstreamData
5c850a43a9 ignore errors with S19 multicommands 2022-05-30 09:46:05 -06:00
UpstreamData
24b037f273 fixed a bug with bmminer stats 2022-05-30 09:40:30 -06:00
UpstreamData
f847700c05 fixed a bug with antminers not reporting type because of fans in testbench, and added a long running get data for long tests 2022-05-27 11:54:51 -06:00
UpstreamData
69820dd9d2 slightly improved getting data from bmminer X9, X17, and X19 with an improvement to finding offset 2022-05-27 11:47:44 -06:00
UpstreamData
ad4b710cb7 miner is no longer cached in miner factory if it is unknown 2022-05-27 11:05:35 -06:00
UpstreamData
c53c18654b improved bmminer with a fan and board offset 2022-05-27 11:01:25 -06:00
UpstreamData
18797f4b56 added S9 data for bmminer 2022-05-27 10:41:41 -06:00
UpstreamData
e86c93e287 fixed refreshing data 2022-05-26 16:19:15 -06:00
UpstreamData
89cfde28f5 added chips for M30S 2022-05-26 16:05:48 -06:00
UpstreamData
0f2a867828 fix wrong import from collections 2022-05-26 15:53:38 -06:00
UpstreamData
4f5aef2d45 update some type hints and comments in miner factory, and remove some uneeded imports 2022-05-26 15:51:57 -06:00
UpstreamData
96801f93d1 made fault lights and async generator to make them much faster 2022-05-26 15:41:41 -06:00
UpstreamData
a8ce73c3d6 fixed an issue with the windows event loop not working with asyncio.create_subprocess_shell 2022-05-26 15:25:04 -06:00
UpstreamData
513dd2b981 fixed abug with testbench not removing miners when there were 0 online 2022-05-26 13:48:49 -06:00
UpstreamData
c35b30e949 fixed formatting issues 2022-05-26 13:23:32 -06:00
UpstreamData
942f2a1c8d improved type hinting and formatting in miner factory 2022-05-26 12:14:28 -06:00
UpstreamData
9078df680e added get_data to web_monitor dashboard 2022-05-26 11:15:01 -06:00
UpstreamData
527997cc58 fixed a bug with refreshing data 2022-05-26 11:13:39 -06:00
UpstreamData
41433bcaf5 change hashrate data to 1m as it seems more consistent, and add get_data to web monitor 2022-05-26 11:12:31 -06:00
UpstreamData
3451b88669 added temps and fans for bmminer and cgminer 2022-05-26 10:57:52 -06:00
UpstreamData
a42af2764e fixed a bug with ideal chips not getting set fast enough 2022-05-26 10:43:10 -06:00
UpstreamData
baaad73eb8 fixed a bug with pool prefix not getting removed when getting data 2022-05-26 10:39:39 -06:00
UpstreamData
34c9f85098 added btminer fan data and per chip temps 2022-05-26 10:36:39 -06:00
UpstreamData
d6638fa4d2 added fan counts to miners, and added more data to bosminer and miner data 2022-05-26 10:26:40 -06:00
UpstreamData
0f51487d3f added miner data to base miner 2022-05-26 08:41:51 -06:00
UpstreamData
3a11b173c3 added chip percent to config tool 2022-05-25 15:02:48 -06:00
UpstreamData
568f86700b improved X19 miner scan speed and implemented miner data in miners 2022-05-25 14:44:23 -06:00
UpstreamData
3b702aac2c improved handling of MinerData by improving dataclass 2022-05-25 14:01:52 -06:00
UpstreamData
6fbd9faffd updated network test to use unittest 2022-05-25 11:49:38 -06:00
UpstreamData
9eb2259aae removed extra print statements and a loop that wasnt needed in miner factory 2022-05-25 09:02:37 -06:00
UpstreamData
149c386a4c fix a bug with X17 not responding 2022-05-25 08:56:02 -06:00
UpstreamData
726e7ff0f0 add support for basic S9is 2022-05-24 14:43:22 -06:00
UpstreamData
87a690eb00 create basic dataclass for miner data 2022-05-20 10:12:51 -06:00
UpstreamData
fd5dba4036 fixed some bugs and improved testbench look 2022-05-19 15:54:29 -06:00
UpstreamData
e54847337a update testbench color palette 2022-05-19 15:31:12 -06:00
UpstreamData
3ff43c3ccd removed old tools that will no longer work 2022-05-19 11:56:12 -06:00
UpstreamData
ec5563f2f0 slightly improved network functionality and added tests for network 2022-05-19 11:55:38 -06:00
UpstreamData
40f14876cc made miner count a fixed position bar 2022-05-19 11:05:40 -06:00
UpstreamData
6abfe8a503 switch testbench to dark mode and add miner count 2022-05-19 10:47:36 -06:00
Dewey Cox
0a4d52ef03 fixed a bug with matplotlib.pyplot.subplots() causing resizing of windows 2022-05-19 09:11:28 -06:00
Colin Crossman
e4207e0120 Allow MinerFactory to take a list of discrete IPs (#7) 2022-05-18 20:16:47 -06:00
UpstreamData
ed89476866 fixed a bug with temp not displaying on the cfg tool 2022-05-18 12:50:44 -06:00
UpstreamData
7f7964526c fixed some bugs with scanning being too fast to get data and killing the tasks 2022-05-18 12:13:20 -06:00
UpstreamData
85b282740a update scanning in web interface 2022-05-18 11:39:14 -06:00
UpstreamData
8cbf3a20a3 make miner ips a true ip address, and allow sorting miners using __lt__ and __gt__ 2022-05-18 11:34:39 -06:00
UpstreamData
8ebcbd3c33 vastly improved scanning in web monitor 2022-05-18 11:12:38 -06:00
UpstreamData
c3e285a9ee fix some bugs in web monitor 2022-05-18 11:06:21 -06:00
UpstreamData
9f19b42de5 fixed some bugs with older versions of braiins OS +, and fixed a bug in testbench 2022-05-17 13:09:10 -06:00
UpstreamData
3d265e823b update README.md 2022-05-17 09:08:50 -06:00
UpstreamData
5e6bc8c8ef add mac addresses for bosminer, and reformat 2022-05-17 08:51:56 -06:00
UpstreamData
871499b77f fix some bugs in miner listener 2022-05-16 16:22:05 -06:00
UpstreamData
117a161fd5 added miner listener to listen for ip reporting 2022-05-16 16:16:22 -06:00
UpstreamData
40bacbf41c add getting mac for whatsminers 2022-05-16 15:01:04 -06:00
UpstreamData
e091863aa7 fixed a bug with suspended whatsminers 2022-05-16 14:06:23 -06:00
UpstreamData
85e8ac63f1 update light column 2022-05-16 13:46:16 -06:00
UpstreamData
a5252e3a84 update README.md 2022-05-16 12:30:04 -06:00
UpstreamData
404d6590db improved resizing and light 2022-05-16 11:55:13 -06:00
UpstreamData
1d04399daf made the window of the cfg util resizeable 2022-05-16 11:35:45 -06:00
UpstreamData
03ebcacca5 added an old version of Bosminer for non plus miners to be able to update 2022-05-16 11:24:32 -06:00
UpstreamData
75934fd7fe fixed another bug with testbench putting miners into recovery mode 2022-05-16 10:50:07 -06:00
UpstreamData
bbeca15799 attempted to fix a bug with testbench 2022-05-16 10:40:28 -06:00
UpstreamData
45befb569b updated a bunch of miner chip counts, added S19a, and fixed a bug with whatsminer M30S++ 2022-05-16 08:42:26 -06:00
UpstreamData
61334ed99e Merge remote-tracking branch 'origin/combine_board_cfg_util' into combine_board_cfg_util 2022-05-13 15:37:27 -06:00
UpstreamData
2bf059df01 remove board util 2022-05-13 15:35:42 -06:00
UpstreamData
9c2de26182 switched over to hashrate av to be more accurate when getting data 2022-05-13 15:35:42 -06:00
UpstreamData
714983cddc added exporting reports from config tool 2022-05-13 15:35:42 -06:00
UpstreamData
191f1d24b9 improved send command functionality with a generator and added progress to it 2022-05-13 15:35:42 -06:00
UpstreamData
5a0bafb964 fixed a bug for scanning S9s with no boards for testing 2022-05-13 15:35:42 -06:00
UpstreamData
67aedd319d update README.md 2022-05-13 15:35:41 -06:00
UpstreamData
44012c50d6 finished updating the miner type handlers to create subclasses of the backend and type to create a miner, each of which handles its own data to simplify creation of new miner types 2022-05-13 15:35:41 -06:00
UpstreamData
06540efc98 changed the way antminers and whatsminers are handled in the factory to allow for more precision on chip counts 2022-05-13 15:35:41 -06:00
UpstreamData
9d0d1a24d9 added S19 board handler 2022-05-13 15:35:41 -06:00
UpstreamData
8568f91482 added btminer board data 2022-05-13 15:35:41 -06:00
UpstreamData
64918e5552 added bosminer board data 2022-05-13 15:35:41 -06:00
UpstreamData
53d5ecd04a added images for boards 2022-05-13 15:35:41 -06:00
UpstreamData
1b0e80a418 added basic framework for boards in config util 2022-05-13 15:35:41 -06:00
UpstreamData
9ad506a313 remove board util 2022-05-13 15:35:11 -06:00
UpstreamData
18c4bbd09c switched over to hashrate av to be more accurate when getting data 2022-05-13 15:31:32 -06:00
UpstreamData
0d123d5dd8 added exporting reports from config tool 2022-05-13 15:23:51 -06:00
UpstreamData
b9b91293fe improved send command functionality with a generator and added progress to it 2022-05-13 14:28:51 -06:00
UpstreamData
47a702c94c fixed a bug for scanning S9s with no boards for testing 2022-05-13 14:03:27 -06:00
UpstreamData
6d5a288120 update README.md 2022-05-13 11:35:37 -06:00
UpstreamData
038aae95ac finished updating the miner type handlers to create subclasses of the backend and type to create a miner, each of which handles its own data to simplify creation of new miner types 2022-05-13 11:27:56 -06:00
UpstreamData
dd84aede25 changed the way antminers and whatsminers are handled in the factory to allow for more precision on chip counts 2022-05-12 16:42:02 -06:00
UpstreamData
dc8ad271de added S19 board handler 2022-05-12 15:16:05 -06:00
UpstreamData
b78c1cdca5 added wattage to configure tab 2022-05-12 14:42:37 -06:00
UpstreamData
0eb7ced932 added btminer board data 2022-05-12 13:20:57 -06:00
UpstreamData
8e58f4492f added bosminer board data 2022-05-12 13:12:54 -06:00
UpstreamData
95fb32de19 added images for boards 2022-05-12 12:35:33 -06:00
UpstreamData
5145dc19f8 added basic framework for boards in config util 2022-05-12 11:29:28 -06:00
UpstreamData
1808d62bba fix references to some table headers 2022-05-11 14:42:47 -06:00
UpstreamData
97ef4dfe37 fixed some bugs with testbench on the latest version 2022-05-11 14:28:53 -06:00
UpstreamData
174a132e75 attempt to fix a bug in testbench 2022-05-11 14:04:05 -06:00
UpstreamData
84d6e58ebe change progress bar completion animation 2022-05-11 13:24:54 -06:00
UpstreamData
e9a1483e5f fixed some small bugs with whatsminers and progress bar 2022-05-11 13:20:14 -06:00
UpstreamData
4eb51eed20 update CFG-Util-README.md 2022-05-11 10:51:36 -06:00
UpstreamData
066fc1a4b3 changed Temperature to Temp and added more spacing to pool user 2022-05-11 08:43:32 -06:00
UpstreamData
cc24236c0a update requirements.txt 2022-05-11 08:40:00 -06:00
UpstreamData
564cd42eae added ctrl c and ctrl a functionality to the tables 2022-05-11 08:37:17 -06:00
UpstreamData
8677eff491 moved miner count and hashrate to top of tool 2022-05-10 14:00:50 -06:00
UpstreamData
63a21ea9aa updated formatting on scrollbars 2022-05-10 13:53:18 -06:00
UpstreamData
1c9d3dc84d updated formatting on page 2022-05-10 13:44:08 -06:00
UpstreamData
0dacd3d294 changed sorting to show up on the table headers 2022-05-10 11:51:26 -06:00
UpstreamData
6fa74613b4 updated look of CFG util 2022-05-10 11:13:27 -06:00
UpstreamData
f7fb7a3acb update requirements.txt 2022-05-09 10:25:25 -06:00
UpstreamData
666c5bfc64 added new text buttons to show total hashrate and current sort key 2022-05-09 10:24:48 -06:00
UpstreamData
1f8d92f6bb fixed some bugs with sorting 2022-05-09 09:59:48 -06:00
UpstreamData
ef336a9e23 added asyncio event loop policy update to fix some bugs 2022-05-09 09:20:21 -06:00
UpstreamData
7fe6fd47fb added sorting to command table (Tree) 2022-05-09 09:14:32 -06:00
UpstreamData
91a0298d96 fix a bug where unknown miners would break configuration 2022-05-06 16:29:07 -06:00
UpstreamData
ed3d8fc815 Merge branch 'pyqt_gui_cfg_util' 2022-05-06 16:22:28 -06:00
UpstreamData
4f2d630746 fix formatting on readme 2022-05-06 16:22:13 -06:00
UpstreamData
a8c685a883 switched cfg_util over to new version 2022-05-06 16:20:02 -06:00
UpstreamData
09660e1934 added indicators of what function is running 2022-05-06 16:12:17 -06:00
UpstreamData
c01908ff9a added custom command functionality 2022-05-06 16:01:50 -06:00
UpstreamData
267c388a95 added restarting and rebooting miner backends 2022-05-06 15:52:21 -06:00
UpstreamData
8215d33241 added configuration button 2022-05-06 15:39:18 -06:00
UpstreamData
f4258a304a add importing configuration from miners 2022-05-06 15:14:49 -06:00
UpstreamData
514fafea58 add generate command and change config converters to non async 2022-05-06 15:06:18 -06:00
UpstreamData
e324369fe0 fixed some bugs with sorting when refreshing data and added refreshing data 2022-05-06 14:55:58 -06:00
UpstreamData
3bc9287668 add scan retries to getting data 2022-05-06 13:51:20 -06:00
UpstreamData
d90bf190c5 added reverse sorting and fixed hashrate sorting 2022-05-06 13:34:12 -06:00
UpstreamData
8cc6f66458 added sorting to the 3 main tables 2022-05-06 12:03:43 -06:00
UpstreamData
a2b071af4f fully implemented fault light command 2022-05-06 11:36:57 -06:00
UpstreamData
b7b589802f added avalon1 1066 to board util tentatively 2022-05-06 09:11:08 -06:00
UpstreamData
93912a6df6 fixed a bug with hashrate data not getting sent with some miners 2022-05-06 08:41:04 -06:00
UpstreamData
ffce15f653 fixed some bugs with latest version of toolbox 2022-05-06 08:41:04 -06:00
UpstreamData
725b14e583 added table manager, to manage tables and handle the treeview 2022-05-05 15:53:13 -06:00
UpstreamData
26c6e47f1e added the ability to update the treeview and images in it no longer are as buggy 2022-05-05 14:47:18 -06:00
UpstreamData
51dae7375f added select all button and functionality 2022-05-05 13:48:57 -06:00
UpstreamData
801cfc4ff8 updated some formatting and improved pool return format 2022-05-05 13:02:00 -06:00
UpstreamData
ac3ff7a63e justify hostname to the left 2022-05-05 12:12:10 -06:00
UpstreamData
1b22810f4b fixed formatting on hashrate 2022-05-05 12:07:57 -06:00
UpstreamData
b756c9e4a1 added getting data for btminer 2022-05-05 11:37:04 -06:00
UpstreamData
64b5e6c032 added getting data for bmminer and cgminer 2022-05-05 11:19:11 -06:00
UpstreamData
a13f5dd2d1 fix some bugs and start adding bmminer get_data function 2022-05-05 10:52:18 -06:00
UpstreamData
e6ea8d3e16 added hostname logging and a generalized get dta function for braiins OS 2022-05-05 10:35:47 -06:00
UpstreamData
af37850289 greatly improved functionality of miner factory 2022-05-05 09:17:20 -06:00
UpstreamData
6ecdfa1cf8 scanning now gets data 2022-05-04 16:04:46 -06:00
UpstreamData
c0b21ebc23 fixed scanning to the tree for commands 2022-05-04 15:06:15 -06:00
UpstreamData
184ada417f added tables and basic scanning 2022-05-04 14:44:19 -06:00
UpstreamData
b636860ecb started basic cfg util changes 2022-05-04 13:08:58 -06:00
UpstreamData
0107fdacde update requirements.txt 2022-05-02 10:36:20 -06:00
UpstreamData
ce5e1cad40 added the option to append the last octet of the IP address to the username when configuring 2022-04-29 15:37:07 -06:00
UpstreamData
d877ba01a0 fix spelling issue 2022-04-29 15:02:54 -06:00
UpstreamData
b0ed990d5a update requirements.txt 2022-04-29 14:38:33 -06:00
UpstreamData
89c8a16900 fix light functionality to work as intended 2022-04-29 13:25:08 -06:00
UpstreamData
247cf0ccc2 added fault light option to the board utility 2022-04-29 10:18:16 -06:00
UpstreamData
d0aa219a7a add first page and pie chart to board report 2022-04-28 11:12:33 -06:00
UpstreamData
87291e2a89 change some formatting with the board report and fix some bugs 2022-04-27 16:58:47 -06:00
UpstreamData
9c88d21db6 add basic board report to board util 2022-04-27 16:35:11 -06:00
UpstreamData
8b7415042f fixed a bug with the webserver 2022-04-25 14:40:32 -06:00
UpstreamData
59ab6e6c8a reformatted and clarified some code 2022-04-21 10:09:30 -06:00
UpstreamData
0724a376ea refactored some code in board util 2022-04-21 09:43:22 -06:00
UpstreamData
f9f26a5587 added better logging and process to testbench 2022-04-20 11:36:09 -06:00
UpstreamData
ed4122fb21 added better logging to testbench 2022-04-19 10:29:13 -06:00
UpstreamData
0739a7f689 added a try except block for logging errors per miner in the testbench 2022-04-19 10:15:12 -06:00
UpstreamData
c7b7a6e7c5 made sure there will always be board 6, 7, and 8 in tunerstatus 2022-04-18 16:12:12 -06:00
UpstreamData
2a132c8325 addded basic tuner status data on testbench 2022-04-18 16:02:21 -06:00
UpstreamData
154882a668 fixed an issue with pinging when done. 2022-04-18 14:29:54 -06:00
UpstreamData
3f64c9dd67 Merge remote-tracking branch 'origin/testbench-webserver' into testbench-webserver
# Conflicts:
#	miners/bosminer.py
#	tools/bad_board_util/func/decorators.py
#	tools/bad_board_util/layout.py
#	tools/bad_board_util/ui.py
2022-04-18 14:17:29 -06:00
UpstreamData
d8d66e4244 fixed a bug with not hiding the light button 2022-04-18 14:17:04 -06:00
UpstreamData
a9cdefcd43 finished adding timer 2022-04-18 14:17:04 -06:00
UpstreamData
029d3ef596 added online timer for testing 2022-04-18 14:17:04 -06:00
UpstreamData
0e474402c0 reformatted files 2022-04-18 14:17:04 -06:00
UpstreamData
b6560cdedb added fixing file exists bug 2022-04-18 14:17:04 -06:00
UpstreamData
767575703e fixed some bugs with finishing the install 2022-04-18 14:17:04 -06:00
UpstreamData
4b4d9060ed changed some printing to logging logs 2022-04-18 14:17:04 -06:00
UpstreamData
ad75b1d25c added web testbench to main apps 2022-04-18 14:17:03 -06:00
UpstreamData
4b767c5427 fixed more bugs 2022-04-18 14:17:03 -06:00
UpstreamData
a6df7a83d6 fixed many remaining bugs in testbench webserver, should be ready for use. 2022-04-18 14:17:03 -06:00
UpstreamData
93f2990399 finished miner install to be tested 2022-04-18 14:17:03 -06:00
UpstreamData
e74f67089e finished light functionality 2022-04-18 14:17:03 -06:00
UpstreamData
41a6078790 added partial fault light functionality and fixed stdout output direction 2022-04-18 14:17:03 -06:00
UpstreamData
4d93926fee added output when running install process 2022-04-18 14:17:03 -06:00
UpstreamData
03f5cafe76 added sending output from miners 2022-04-18 14:17:03 -06:00
UpstreamData
4f6ebff880 set graphs to show and hide when getting data 2022-04-18 14:17:03 -06:00
UpstreamData
af27cbbe2c set graphs to update when receiving data 2022-04-18 14:17:03 -06:00
UpstreamData
3604957c83 added auto port finding to both web apps 2022-04-18 14:17:03 -06:00
UpstreamData
3670a02aec add feeds updater to startup process 2022-04-18 14:17:03 -06:00
UpstreamData
7ebfdb3f33 added feeds auto-updater for web testbench 2022-04-18 14:17:03 -06:00
UpstreamData
b9b7da8746 add base files for web interface 2022-04-18 14:17:03 -06:00
UpstreamData
eaaf137b9b added temp fake data to the app for it to send to the JS side. 2022-04-18 14:15:46 -06:00
UpstreamData
a0311e3ce3 add base files for web interface 2022-04-18 14:15:44 -06:00
UpstreamData
8864aa7b4b added install file to do the basic install 2022-04-18 14:15:24 -06:00
UpstreamData
4d58129eee fixed a bug with not hiding the light button 2022-04-18 13:12:08 -06:00
UpstreamData
4468fe9fbb finished adding timer 2022-04-18 12:29:55 -06:00
UpstreamData
3b716a044b added online timer for testing 2022-04-18 12:13:41 -06:00
UpstreamData
25e657729c reformatted files 2022-04-18 10:24:53 -06:00
UpstreamData
cace399ed2 added fixing file exists bug 2022-04-18 10:13:48 -06:00
UpstreamData
045e1ca6ba fixed some bugs with finishing the install 2022-04-18 09:52:45 -06:00
UpstreamData
4f86dec560 changed some printing to logging logs 2022-04-18 08:49:21 -06:00
UpstreamData
13f033440d added web testbench to main apps 2022-04-14 18:43:36 -06:00
UpstreamData
b5c455ffa4 fixed more bugs 2022-04-14 18:38:29 -06:00
UpstreamData
eb5a00b706 fixed many remaining bugs in testbench webserver, should be ready for use. 2022-04-14 18:17:23 -06:00
UpstreamData
3a560472e6 finished miner install to be tested 2022-04-14 14:40:31 -06:00
UpstreamData
4776dce038 finished light functionality 2022-04-14 13:16:16 -06:00
UpstreamData
2d6891c6d2 added partial fault light functionality and fixed stdout output direction 2022-04-14 11:34:21 -06:00
UpstreamData
f5a41f7b13 added output when running install process 2022-04-14 11:08:52 -06:00
UpstreamData
4a2926df94 added sending output from miners 2022-04-14 10:57:32 -06:00
UpstreamData
8736f33a56 set graphs to show and hide when getting data 2022-04-14 10:43:26 -06:00
UpstreamData
89eb77588f set graphs to update when receiving data 2022-04-14 10:34:51 -06:00
UpstreamData
c930510226 added auto port finding to both web apps 2022-04-14 09:43:43 -06:00
UpstreamData
b7c58e5d34 add feeds updater to startup process 2022-04-14 09:37:06 -06:00
UpstreamData
ce48ae020b added feeds auto-updater for web testbench 2022-04-11 16:13:04 -06:00
UpstreamData
7809bfc0d1 added exporting a report from bad board utility 2022-04-01 15:19:12 -06:00
UpstreamData
d84fcaafdf added bos get version 2022-04-01 13:33:05 -06:00
UpstreamData
a9f600b797 add base files for web interface 2022-03-31 11:32:42 -06:00
UpstreamData
f0a8e7ba9f reformatted all files to use the Black formatting style 2022-03-31 11:30:34 -06:00
UpstreamData
c57a523553 reformatted all files to use the Black formatting style 2022-03-31 11:27:57 -06:00
UpstreamData
d905f6f414 added temp fake data to the app for it to send to the JS side. 2022-03-30 08:42:21 -06:00
UpstreamData
22f78ac405 add base files for web interface 2022-03-25 16:02:50 -06:00
UpstreamData
7a098b1c7e added install file to do the basic install 2022-03-25 15:29:30 -06:00
UpstreamData
e1383f2002 Added support for X19 models with BraiinsOS 2022-03-25 09:06:25 -06:00
UpstreamData
c3b23313ba added changing model when configuring for BOS S9s 2022-03-25 08:58:02 -06:00
UpstreamData
02581e917d add temperature graph to miner page 2022-03-21 10:02:11 -06:00
UpstreamData
e267073f76 add the start of a temperature graph to miner page 2022-03-21 09:39:54 -06:00
UpstreamData
4038dae446 fixed some bugs on linux with pipes 2022-03-18 12:02:42 -06:00
UpstreamData
134b5fe0ff added CTRL+A select all binding to cfg util and board util tables 2022-03-17 16:10:12 -06:00
UpstreamData
d452ca36b7 fixed copying from the board util table 2022-03-17 16:05:48 -06:00
UpstreamData
fdec35cd2e added disable button decorator to board util 2022-03-17 16:01:02 -06:00
UpstreamData
d488c8458c added the ability to scan a range of IPs as part of the miner network by passing a string formatted as {ip_range_1_start}-{ip_range_1_end}, {ip_range_2_start}-{ip_range_2_end} to the miner network 2022-03-17 12:05:58 -06:00
UpstreamData
6d2e40c81d added support for avalon10xx miners 2022-03-16 15:21:09 -06:00
UpstreamData
594b5d0448 improved logging format and sent output to a file 2022-03-16 14:03:32 -06:00
UpstreamData
1be12e5d4c moved _get_ssh_connection to the base miner class 2022-03-16 13:34:18 -06:00
UpstreamData
bae2ee4245 changed MinerFactory to a singleton class to ensure clearing its cache is easier and removed creation of independant miner factories for each utility 2022-03-16 12:05:44 -06:00
UpstreamData
57bd606f21 add logging to base miner API 2022-03-16 10:56:33 -06:00
UpstreamData
eb8cefa461 add logging to btminer and fix some bugs 2022-03-16 08:40:41 -06:00
UpstreamData
9edcd866bb added more logging for bosminer models. 2022-03-15 09:07:07 -06:00
UpstreamData
07a8b00a93 added logging to bmminer and X19 models 2022-03-14 16:07:47 -06:00
UpstreamData
c22be7ded8 started adding some basic logging functionality 2022-03-14 15:52:46 -06:00
UpstreamData
2380b94db1 update unknown API docstring 2022-03-14 14:12:31 -06:00
UpstreamData
d8e59afee0 Upsdated bosminer API docstrings, and fixed some errors in CGMiner API docstings 2022-03-14 14:07:17 -06:00
UpstreamData
05e14baa68 added some todos 2022-03-14 11:26:53 -06:00
UpstreamData
ff56148732 fixed some bugs with cgminer, and included VC redistributables in CXFreeze build for CFG util 2022-03-14 10:18:28 -06:00
UpstreamData
bfc5668d24 fixed some bugs with running the web app from docker 2022-03-09 10:53:26 -07:00
UpstreamData
b3103ae700 fixed fan formatting on smaller devices 2022-03-08 12:23:38 -07:00
UpstreamData
43834203a8 reformatted file structure and reformatted for phones, as well as fixed web sockets for remote devices 2022-03-08 11:39:10 -07:00
UpstreamData
7ba8044564 added dockerfile and removed cxfreeze from web_monitor requirements due to it breaking the docker setup 2022-03-08 09:09:28 -07:00
UpstreamData
7e91fe12e7 updated some ports and fixed a bug with summary keys when getting data 2022-03-07 14:54:36 -07:00
UpstreamData
02114aac65 Merge pull request #6 from UpstreamData/web_monitor
Web monitor
2022-03-07 12:40:11 -07:00
UpstreamData
244dac76af finished adding settings page 2022-03-07 12:38:56 -07:00
UpstreamData
2bd25c3f35 started adding settings page 2022-03-07 11:17:41 -07:00
UpstreamData
23350ea4b6 updated requirements, and fixed some formatting issues 2022-03-07 10:36:38 -07:00
UpstreamData
8a6917878e Merge remote-tracking branch 'origin/web_monitor' into web_monitor 2022-03-07 09:40:42 -07:00
UpstreamData
7dd00954e4 fixed some issues with the rounding on floats in the JS 2022-03-07 09:39:56 -07:00
UpstreamData
f3710f618e added miner model and hashrate as a table in the per miner stuff 2022-03-07 09:39:56 -07:00
UpstreamData
8ecdb6f5e8 fixed a bug with scanning and adding miner which didnt append to the navbar 2022-03-07 09:39:56 -07:00
UpstreamData
309b4d44fc updated some formatting on charts 2022-03-07 09:39:56 -07:00
UpstreamData
80f941d912 added remove miner functionality 2022-03-07 09:39:56 -07:00
UpstreamData
4534b09532 added custom TH/s formatting to graphs 2022-03-07 09:39:56 -07:00
UpstreamData
97a9b59acc added dashboard hashrate info 2022-03-07 09:39:56 -07:00
UpstreamData
87b8de9029 strated on basic framework for dashboard in web_monitor 2022-03-07 09:39:56 -07:00
UpstreamData
42f5146632 added different select gradient 2022-03-07 09:39:56 -07:00
UpstreamData
f613cc039f added spinner to scan 2022-03-07 09:39:56 -07:00
UpstreamData
e974c77359 added fan and hashrate data for S19s and Whatsminers 2022-03-07 09:39:56 -07:00
UpstreamData
0f324177cb added fan data for braiins OS 2022-03-07 09:39:56 -07:00
UpstreamData
46a4508cd7 updated more gradient formatting an added gradients to navbar 2022-03-07 09:39:56 -07:00
UpstreamData
d4d9b1ad3c added gradients to fan data 2022-03-07 09:39:56 -07:00
UpstreamData
322ee05fdf added bounding box to the chart 2022-03-07 09:39:56 -07:00
UpstreamData
85569366a2 sorted current miners for the navbar 2022-03-07 09:39:56 -07:00
UpstreamData
dea6ff2a96 improved chart functionality in the web monitor and added handlers for errors such as no response from the miner 2022-03-07 09:39:56 -07:00
UpstreamData
3fcd2edf6f charts on miner pages work now, they gather data from miners and put it into the graph, with a max size of 49 entried per graph 2022-03-07 09:39:56 -07:00
UpstreamData
16b84310ec added graph with fake data on each miner page, and added basic formatting to it. 2022-03-07 09:39:56 -07:00
UpstreamData
f8899521bc improved navbar formatting, added active formats for all miners, moved add miners to a miner subtab 2022-03-07 09:39:56 -07:00
UpstreamData
3558a1a6b1 finished up scan page, added the ability to add miners and them get listed in the miner list, and started adding the individual miner pages 2022-03-07 09:39:56 -07:00
UpstreamData
385943755d further improved formatting of scan page, added disabled checkboxes on scan, updated miner count on add 2022-03-07 09:39:56 -07:00
UpstreamData
3002cb4e97 added basic addition of miners to the list and improved some functionality of the web tool 2022-03-07 09:39:56 -07:00
UpstreamData
6d711520fc added add selected miners button 2022-03-07 09:39:56 -07:00
UpstreamData
584de40983 improved formatting on scan page and made the scan a bit more robust 2022-03-07 09:39:56 -07:00
UpstreamData
81911ba549 fixed some formwatting on the scan page 2022-03-07 09:39:55 -07:00
UpstreamData
e37e9e2251 added the scan page to scan for miners on a subnet 2022-03-07 09:39:55 -07:00
UpstreamData
92a65c8977 switched to fastAPi and jinja 2 for templates and html 2022-03-07 09:39:55 -07:00
UpstreamData
ae8b2cbd07 added the required directories for settings and scanning 2022-03-07 09:39:55 -07:00
UpstreamData
cda13edf85 improved formatting of index.html 2022-03-07 09:39:55 -07:00
UpstreamData
610ee57963 started adding HTML files for the web monitor program 2022-03-07 09:39:55 -07:00
UpstreamData
2ef809db54 fixed some issues with the rounding on floats in the JS 2022-03-07 09:32:06 -07:00
UpstreamData
f315c0c051 added miner model and hashrate as a table in the per miner stuff 2022-03-04 16:10:27 -07:00
UpstreamData
936c230aa3 fixed a bug with scanning and adding miner which didnt append to the navbar 2022-03-04 15:48:17 -07:00
UpstreamData
2c93f1f395 updated some formatting on charts 2022-03-04 14:36:43 -07:00
UpstreamData
727ebd9c42 added remove miner functionality 2022-03-04 14:08:27 -07:00
UpstreamData
1e4fc897e3 added custom TH/s formatting to graphs 2022-03-04 13:39:23 -07:00
UpstreamData
3945a86004 added dashboard hashrate info 2022-03-04 11:53:31 -07:00
UpstreamData
58cc64d17b strated on basic framework for dashboard in web_monitor 2022-03-04 11:24:06 -07:00
UpstreamData
b66cf6f0ba added different select gradient 2022-03-02 15:54:49 -07:00
UpstreamData
1db15a741e added spinner to scan 2022-03-02 15:47:17 -07:00
UpstreamData
5f355c833b added fan and hashrate data for S19s and Whatsminers 2022-03-02 15:38:29 -07:00
UpstreamData
a76b32e3ff added fan data for braiins OS 2022-03-02 15:15:20 -07:00
UpstreamData
f2c01dca25 updated more gradient formatting an added gradients to navbar 2022-03-02 14:36:34 -07:00
UpstreamData
abc542a0ca added gradients to fan data 2022-03-02 13:12:20 -07:00
UpstreamData
9e598ebd8c added bounding box to the chart 2022-03-02 12:15:46 -07:00
UpstreamData
7801ca5819 sorted current miners for the navbar 2022-03-02 11:16:02 -07:00
UpstreamData
482edabd27 improved chart functionality in the web monitor and added handlers for errors such as no response from the miner 2022-03-02 11:11:34 -07:00
UpstreamData
3e5998de6e charts on miner pages work now, they gather data from miners and put it into the graph, with a max size of 49 entried per graph 2022-03-01 16:17:28 -07:00
UpstreamData
c3d19607f6 added graph with fake data on each miner page, and added basic formatting to it. 2022-03-01 16:01:39 -07:00
UpstreamData
2c2648cbe7 improved navbar formatting, added active formats for all miners, moved add miners to a miner subtab 2022-03-01 12:51:49 -07:00
UpstreamData
a72c4f7797 finished up scan page, added the ability to add miners and them get listed in the miner list, and started adding the individual miner pages 2022-03-01 12:28:36 -07:00
UpstreamData
19ee9eb18f further improved formatting of scan page, added disabled checkboxes on scan, updated miner count on add 2022-03-01 11:30:48 -07:00
UpstreamData
3ae29c3883 added basic addition of miners to the list and improved some functionality of the web tool 2022-02-28 16:28:40 -07:00
UpstreamData
d9f8f53a10 added add selected miners button 2022-02-28 15:15:57 -07:00
UpstreamData
6b3e525f45 improved formatting on scan page and made the scan a bit more robust 2022-02-28 14:10:43 -07:00
UpstreamData
c8824f86af fixed some formwatting on the scan page 2022-02-25 16:11:06 -07:00
UpstreamData
cf3163dccf added the scan page to scan for miners on a subnet 2022-02-25 15:58:01 -07:00
UpstreamData
da5a784214 switched to fastAPi and jinja 2 for templates and html 2022-02-24 15:59:48 -07:00
UpstreamData
30b3315084 added the required directories for settings and scanning 2022-02-24 15:25:49 -07:00
UpstreamData
5a7dcc7fcf fixed some bugs in getting ssh connections 2022-02-24 14:42:34 -07:00
UpstreamData
c6305c57cf improved formatting of index.html 2022-02-24 09:13:07 -07:00
UpstreamData
d330e2e978 started adding HTML files for the web monitor program 2022-02-24 08:57:23 -07:00
UpstreamData
1ec2a2a4a6 update CFG-Util-README.md 2022-02-23 14:39:29 -07:00
UpstreamData
c97d384cf4 updated red row color on fault light to work with tkinter tags and be sortable. 2022-02-23 14:35:29 -07:00
UpstreamData
ca52e40a6a fixed a bug with fault lighting bugging the tool 2022-02-23 11:56:21 -07:00
UpstreamData
4a10efd7a4 added send command option in the window 2022-02-22 13:53:07 -07:00
UpstreamData
128aab1b88 switched to a monospace font in the board util. 2022-02-22 11:01:00 -07:00
UpstreamData
bb89be64f4 switched to a monospace font in the cfg tool, padded the hashrates to appear as decimal centered, and left justified hostnames for better readability. 2022-02-22 10:49:23 -07:00
UpstreamData
ef0a507306 changed the disabling buttons to use a decorator as it looks much cleaner 2022-02-18 11:10:44 -07:00
UpstreamData
908594970e disabled the buttons that can break each other when another coroutine is running 2022-02-18 10:59:10 -07:00
UpstreamData
36ff5e96a4 Merge remote-tracking branch 'origin/master' 2022-02-14 10:02:16 -07:00
UpstreamData
9bf9f8342a added export csv button to export all data from the tool 2022-02-14 10:01:43 -07:00
UpstreamData
f3660c1f68 Update README.md 2022-02-11 11:11:42 -07:00
UpstreamData
d58aa871b5 updated CGMiner and BMMiner docstrings 2022-02-11 11:06:35 -07:00
UpstreamData
4f90eb65ad updated btminer docstrings 2022-02-11 10:50:04 -07:00
UpstreamData
b50da98322 fixed some issues in CFG-Util-README.md, and started reformatting docstrings and cleaning API code. 2022-01-31 15:35:08 -07:00
UpstreamData
ca47f2817f added bad board util files, and fixed imports in README.md 2022-01-31 09:13:49 -07:00
UpstreamData
c489a4bed9 refactored location of config utility, and changed sizing of some items 2022-01-31 09:10:23 -07:00
UpstreamData
54c7e996db fixed a bug with the config export not converting 2022-01-27 15:02:55 -07:00
UpstreamData
0426bb289e fixed a bug with tags not getting assigned to second and third boards with multiple chains 2022-01-27 14:04:08 -07:00
UpstreamData
8e253ffa05 fixed a bug with tags not getting assigned to second and third boards 2022-01-27 12:38:59 -07:00
UpstreamData
102f365003 added tags to board util bad miners, so when sorting they stay the same 2022-01-27 12:30:14 -07:00
UpstreamData
48d2f6ec07 fixed board util progress bar sizing 2022-01-26 15:37:14 -07:00
UpstreamData
58f0ce8e2d reformatted the board util slightly 2022-01-26 15:35:44 -07:00
UpstreamData
3178083533 added whatsminer get bad boards 2022-01-26 14:53:51 -07:00
UpstreamData
516075db6d reformatted many base commands, and moved them to the BaseMiner class 2022-01-26 08:57:14 -07:00
UpstreamData
d6c8335162 changed board_util copy format 2022-01-25 16:11:15 -07:00
UpstreamData
e7a45efe15 changed board util copy/paste to copy the whole line instead of just the IP 2022-01-25 16:00:22 -07:00
UpstreamData
1c0b5e6441 tracks boards by left/center/right now in lieu of board numbers, and works with Hive T9s and BOS S9s and X17s 2022-01-25 15:53:36 -07:00
UpstreamData
66792e1ab9 added chip count and fixed refreshing data 2022-01-25 15:20:21 -07:00
UpstreamData
6fd631df5b added red highlight to miners with bad boards 2022-01-25 15:14:33 -07:00
UpstreamData
dcf1a805c5 fixed a bug with the board utility 2022-01-24 16:39:11 -07:00
UpstreamData
8edfde96dc cleaned the board utility a bit 2022-01-24 16:31:51 -07:00
UpstreamData
ae911ec775 started adding the board utility 2022-01-24 16:29:21 -07:00
UpstreamData
465d0e6f1c fixed formatting on getting bad boards 2022-01-24 11:15:14 -07:00
UpstreamData
6d9de87fb8 changed bos get_bad_boards to be consistent with hive 2022-01-21 16:30:26 -07:00
UpstreamData
a93027369e added Hive get bad boards, and started on a bad board utility 2022-01-21 16:15:46 -07:00
UpstreamData
a1839aae46 added T9s 2022-01-21 14:42:01 -07:00
UpstreamData
d5fc7650ef fixed some small bugs with miner factory 2022-01-12 11:50:43 -07:00
UpstreamData
cdc6c898ae reformatted, added a bunch of comments to improve readability, and added a whatsminer admin password in settings 2022-01-12 09:04:15 -07:00
UpstreamData
574432ec0d Merge remote-tracking branch 'origin/master' 2022-01-12 08:23:58 -07:00
UpstreamData
a89486d6ad refactored cgf_util_sg to its own folder 2022-01-12 08:23:47 -07:00
Dewey Cox
56d7234ccb moved pysg files into a directory inside cfg_util, and refactored imports. 2022-01-12 08:17:43 -07:00
UpstreamData
c7f1b00e13 Update CFG-Util-README.md 2022-01-12 08:12:46 -07:00
Dewey Cox
60f5137115 fixed progress bar width on different screens 2022-01-11 15:23:54 -07:00
UpstreamData
a90239e3c5 added updates after changing progress bar length to not get ridiculously over length progress bars 2022-01-11 14:02:59 -07:00
UpstreamData
a105429d99 changed refresh_data to only refresh data of selected miners if miners are selected 2022-01-11 13:49:54 -07:00
Dewey Cox
8e73b8f7a1 fixed a bug with getting model when it gets empty bytes 2022-01-11 13:33:29 -07:00
Dewey Cox
53af55a87d fixed a bug with model not reading if there are no hashboards in the miner 2022-01-11 12:58:20 -07:00
UpstreamData
0711bcb259 added misc folder with bos get_bad_tuners, to get tuner errors from all miners on a network 2022-01-11 10:18:31 -07:00
UpstreamData
282e00f93a change get data to refresh data and made scan do both scanning and getting data, and refresh data only refreshes whats currently in the IP list or selected 2022-01-11 09:04:00 -07:00
UpstreamData
2e11527416 improved README.md 2022-01-10 15:04:59 -07:00
UpstreamData
01a64e63c6 fixed more bugs with avalonminers 2022-01-10 13:48:25 -07:00
UpstreamData
2610d642fa fixed a bug with getting data not filling in total hashrate because of a key error on data points with no data 2022-01-10 09:00:45 -07:00
UpstreamData
e1e93aea66 added screeninfo and a resized progress bar because for some reason it is too big on some screens 2022-01-10 08:38:17 -07:00
UpstreamData
ab208d0d2f added rebooting and restarting backend to the GUI 2022-01-08 19:55:26 -07:00
UpstreamData
e9210eb37d added rebooting, still need to add the buttons 2022-01-08 19:49:12 -07:00
UpstreamData
93665772c3 added the avalonminer estats pattern for parsing their garbage output 2022-01-08 15:51:30 -07:00
UpstreamData
44bcc30130 fixed more bugs with avalonminers, and added temps 2022-01-08 15:25:43 -07:00
UpstreamData
d8bccbccaa fixed some bugs with canaan miners not responding properly and returning empty bytes 2022-01-08 14:33:05 -07:00
454 changed files with 31660 additions and 4098 deletions

17
.coveragerc Normal file
View File

@@ -0,0 +1,17 @@
[report]
exclude_lines =
# Skip @abstractmethod
@abstractmethod
@abc.abstractmethod
# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
raise NotImplementedError
# Don't complain about missing debug-only code:
def __repr__
if self\.debug
# Don't complain if non-runnable code isn't run:
if 0:
if __name__ == .__main__.:

22
.github/workflows/python-publish.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
name: PyPI
on:
push:
tags:
- "v*.*.*"
paths-ignore:
- '**.md'
- 'docs/**'
- 'docsrc/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Publish GH release
uses: softprops/action-gh-release@v0.1.14
- name: Build using poetry and publish to PyPi
uses: JRubics/poetry-publish@v1.11
with:
pypi_token: ${{ secrets.PYPI_API_KEY }}

9
.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
venv/
build/
dist/
__pycache__/
pyvenv.cfg
.env/
bin/
lib/
.idea/

27
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,27 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
- id: trailing-whitespace
- id: check-yaml
- id: check-added-large-files
- repo: https://github.com/psf/black
rev: 22.6.0
hooks:
- id: black
- repo: https://github.com/pycqa/isort
rev: 5.10.1
hooks:
- id: isort
name: isort (python)
- repo: local
hooks:
- id: unittest
name: unittest
entry: python -m unittest discover
language: system
'types': [python]
args: ["-p '*test.py'"] # Probably this option is absolutely not needed.
pass_filenames: false
stages: [commit]

20
.readthedocs.yaml Normal file
View File

@@ -0,0 +1,20 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
tools:
python: "3.9"
mkdocs:
configuration: mkdocs.yml
# Optionally declare the Python requirements required to build your docs
python:
install:
- requirements: docs/requirements.txt

View File

@@ -1,181 +0,0 @@
import asyncio
import json
import ipaddress
import warnings
class APIError(Exception):
def __init__(self, *args):
if args:
self.message = args[0]
else:
self.message = None
def __str__(self):
if self.message:
return f"{self.message}"
else:
return "Incorrect API parameters."
class APIWarning(Warning):
def __init__(self, *args):
if args:
self.message = args[0]
else:
self.message = None
def __str__(self):
if self.message:
return f"{self.message}"
else:
return "Incorrect API parameters."
class BaseMinerAPI:
def __init__(self, ip: str, port: int = 4028) -> None:
# api port, should be 4028
self.port = port
# ip address of the miner
self.ip = ipaddress.ip_address(ip)
def get_commands(self) -> list:
"""Get a list of command accessible to a specific type of API on the miner."""
return [func for func in
# each function in self
dir(self) if callable(getattr(self, func)) and
# no __ methods
not func.startswith("__") and
# remove all functions that are in this base class
func not in
[func for func in
dir(BaseMinerAPI) if callable(getattr(BaseMinerAPI, func))
]
]
async def multicommand(self, *commands: str) -> dict:
"""Creates and sends multiple commands as one command to the miner."""
# split the commands into a proper list
user_commands = [*commands]
allowed_commands = self.get_commands()
# make sure we can actually run the command, otherwise it will fail
commands = [command for command in user_commands if command in allowed_commands]
for item in list(set(user_commands) - set(commands)):
warnings.warn(f"""Removing incorrect command: {item}
If you are sure you want to use this command please use API.send_command("{item}") instead.""",
APIWarning)
# standard multicommand format is "command1+command2"
# doesnt work for S19 which is dealt with in the send command function
command = "+".join(commands)
data = None
try:
data = await self.send_command(command)
except APIError:
try:
data = {}
# S19 handler, try again
for cmd in command.split("+"):
data[cmd] = []
data[cmd].append(await self.send_command(cmd))
except APIError as e:
raise APIError(e)
except Exception as e:
print(e)
if data:
return data
async def send_command(self, command: str, parameters: str or int or bool = None) -> dict:
"""Send an API command to the miner and return the result."""
try:
# get reader and writer streams
reader, writer = await asyncio.open_connection(str(self.ip), self.port)
# handle OSError 121
except OSError as e:
if e.winerror == "121":
print("Semaphore Timeout has Expired.")
return {}
# create the command
cmd = {"command": command}
if parameters is not None:
cmd["parameter"] = parameters
# send the command
writer.write(json.dumps(cmd).encode('utf-8'))
await writer.drain()
# instantiate data
data = b""
# loop to receive all the data
try:
while True:
d = await reader.read(4096)
if not d:
break
data += d
except Exception as e:
print(e)
data = self.load_api_data(data)
# close the connection
writer.close()
await writer.wait_closed()
# validate the command succeeded
validation = self.validate_command_output(data)
if not validation[0]:
raise APIError(validation[1])
return data
@staticmethod
def validate_command_output(data: dict) -> tuple[bool, str | None]:
"""Check if the returned command output is correctly formatted."""
# check if the data returned is correct or an error
# if status isn't a key, it is a multicommand
if "STATUS" not in data.keys():
for key in data.keys():
# make sure not to try to turn id into a dict
if not key == "id":
# make sure they succeeded
if "STATUS" in data[key][0].keys():
if data[key][0]["STATUS"][0]["STATUS"] not in ["S", "I"]:
# this is an error
return False, f"{key}: " + data[key][0]["STATUS"][0]["Msg"]
elif "id" not in data.keys():
if data["STATUS"] not in ["S", "I"]:
return False, data["Msg"]
else:
# make sure the command succeeded
if data["STATUS"][0]["STATUS"] not in ("S", "I"):
# this is an error
if data["STATUS"][0]["STATUS"] not in ("S", "I"):
return False, data["STATUS"][0]["Msg"]
return True, None
@staticmethod
def load_api_data(data: bytes) -> dict:
"""Convert API data from JSON to dict"""
try:
# some json from the API returns with a null byte (\x00) on the end
if data.endswith(b"\x00"):
# handle the null byte
str_data = data.decode('utf-8')[:-1]
else:
# no null byte
str_data = data.decode('utf-8')
# fix an error with a btminer return having an extra comma that breaks json.loads()
str_data = str_data.replace(",}", "}")
# fix an error with a btminer return having a newline that breaks json.loads()
str_data = str_data.replace("\n", "")
# fix an error with a bmminer return not having a specific comma that breaks json.loads()
str_data = str_data.replace("}{", "},{")
# parse the json
parsed_data = json.loads(str_data)
# handle bad json
except json.decoder.JSONDecodeError as e:
print(e)
raise APIError(f"Decode Error: {data}")
return parsed_data

View File

@@ -1,536 +0,0 @@
from API import BaseMinerAPI
class BMMinerAPI(BaseMinerAPI):
"""
A class that abstracts the BMMiner API in the miners.
Each method corresponds to an API command in BMMiner.
BMMiner API documentation:
https://github.com/jameshilliard/bmminer/blob/master/API-README
Parameters:
ip: the IP address of the miner.
port (optional): the port of the API on the miner (standard is 4028)
"""
def __init__(self, ip: str, port: int = 4028) -> None:
super().__init__(ip, port)
async def version(self) -> dict:
"""
API 'version' command.
Returns a dict containing version information.
"""
return await self.send_command("version")
async def config(self) -> dict:
"""
API 'config' command.
Returns a dict containing some miner configuration information:
ASC Count <- the number of ASCs
PGA Count <- the number of PGAs
Pool Count <- the number of Pools
Strategy <- the current pool strategy
Log Interval <- the interval of logging
Device Code <- list of compiled device drivers
OS <- the current operating system
Failover-Only <- failover-only setting
Scan Time <- scan-time setting
Queue <- queue setting
Expiry <- expiry setting
"""
return await self.send_command("config")
async def summary(self) -> dict:
"""
API 'summary' command.
Returns a dict containing the status summary of the miner.
"""
return await self.send_command("summary")
async def pools(self) -> dict:
"""
API 'pools' command.
Returns a dict containing the status of each pool.
"""
return await self.send_command("pools")
async def devs(self) -> dict:
"""
API 'devs' command.
Returns a dict containing each PGA/ASC with their details.
"""
return await self.send_command("devs")
async def edevs(self, old: bool = False) -> dict:
"""
API 'edevs' command.
Returns a dict containing each PGA/ASC with their details,
ignoring blacklisted devices and zombie devices.
Parameters:
old (optional): include zombie devices that became zombies less than 'old' seconds ago
"""
if old:
return await self.send_command("edevs", parameters="old")
else:
return await self.send_command("edevs")
async def pga(self, n: int) -> dict:
"""
API 'pga' command.
Returns a dict containing the details of a single PGA of number N.
Parameters:
n: the number of the PGA to get details of.
"""
return await self.send_command("pga", parameters=n)
async def pgacount(self) -> dict:
"""
API 'pgacount' command.
Returns a dict containing the number of PGA devices.
"""
return await self.send_command("pgacount")
async def switchpool(self, n: int) -> dict:
"""
API 'switchpool' command.
Returns the STATUS section with the results of switching pools.
Parameters:
n: the number of the pool to switch to.
"""
return await self.send_command("switchpool", parameters=n)
async def enablepool(self, n: int) -> dict:
"""
API 'enablepool' command.
Returns the STATUS section with the results of enabling the pool.
Parameters:
n: the number of the pool to enable.
"""
return await self.send_command("enablepool", parameters=n)
async def addpool(self, url: str, username: str, password: str) -> dict:
"""
API 'addpool' command.
Returns the STATUS section with the results of adding the pool.
Parameters:
url: the URL of the new pool to add.
username: the users username on the new pool.
password: the worker password on the new pool.
"""
return await self.send_command("addpool", parameters=f"{url}, {username}, {password}")
async def poolpriority(self, *n: int) -> dict:
"""
API 'poolpriority' command.
Returns the STATUS section with the results of setting pool priority.
Parameters:
n: pool numbers in order of priority.
"""
return await self.send_command("poolpriority", parameters=f"{','.join([str(item) for item in n])}")
async def poolquota(self, n: int, q: int) -> dict:
"""
API 'poolquota' command.
Returns the STATUS section with the results of setting pool quota.
Parameters:
n: pool number to set quota on.
q: quota to set the pool to.
"""
return await self.send_command("poolquota", parameters=f"{n}, {q}")
async def disablepool(self, n: int) -> dict:
"""
API 'disablepool' command.
Returns the STATUS section with the results of disabling the pool.
Parameters:
n: the number of the pool to disable.
"""
return await self.send_command("disablepool", parameters=n)
async def removepool(self, n: int) -> dict:
"""
API 'removepool' command.
Returns the STATUS section with the results of removing the pool.
Parameters:
n: the number of the pool to remove.
"""
return await self.send_command("removepool", parameters=n)
async def save(self, filename: str = None) -> dict:
"""
API 'save' command.
Returns the STATUS section with the results of saving the config file..
Parameters:
filename (optional): the filename to save the config as.
"""
if filename:
return await self.send_command("save", parameters=filename)
else:
return await self.send_command("save")
async def quit(self) -> dict:
"""
API 'quit' command.
Returns a single "BYE" before BMMiner quits.
"""
return await self.send_command("quit")
async def notify(self) -> dict:
"""
API 'notify' command.
Returns a dict containing the last status and count of each devices problem(s).
"""
return await self.send_command("notify")
async def privileged(self) -> dict:
"""
API 'privileged' command.
Returns the STATUS section with an error if you have no privileged access.
"""
return await self.send_command("privileged")
async def pgaenable(self, n: int) -> dict:
"""
API 'pgaenable' command.
Returns the STATUS section with the results of enabling the PGA device N.
Parameters:
n: the number of the PGA to enable.
"""
return await self.send_command("pgaenable", parameters=n)
async def pgadisable(self, n: int) -> dict:
"""
API 'pgadisable' command.
Returns the STATUS section with the results of disabling the PGA device N.
Parameters:
n: the number of the PGA to disable.
"""
return await self.send_command("pgadisable", parameters=n)
async def pgaidentify(self, n: int) -> dict:
"""
API 'pgaidentify' command.
Returns the STATUS section with the results of identifying the PGA device N.
Parameters:
n: the number of the PGA to identify.
"""
return await self.send_command("pgaidentify", parameters=n)
async def devdetails(self) -> dict:
"""
API 'devdetails' command.
Returns a dict containing all devices with their static details.
"""
return await self.send_command("devdetails")
async def restart(self) -> dict:
"""
API 'restart' command.
Returns a single "RESTART" before BMMiner restarts.
"""
return await self.send_command("restart")
async def stats(self) -> dict:
"""
API 'stats' command.
Returns a dict containing stats for all device/pool with more than 1 getwork.
"""
return await self.send_command("stats")
async def estats(self, old: bool = False) -> dict:
"""
API 'estats' command.
Returns a dict containing stats for all device/pool with more than 1 getwork,
ignoring zombie devices.
Parameters:
old (optional): include zombie devices that became zombies less than 'old' seconds ago.
"""
if old:
return await self.send_command("estats", parameters="old")
else:
return await self.send_command("estats")
async def check(self, command: str) -> dict:
"""
API 'check' command.
Returns information about a command:
Exists (Y/N) <- the command exists in this version
Access (Y/N) <- you have access to use the command
Parameters:
command: the command to get information about.
"""
return await self.send_command("check", parameters=command)
async def failover_only(self, failover: bool) -> dict:
"""
API 'failover-only' command.
Returns the STATUS section with what failover-only was set to.
Parameters:
failover: what to set failover-only to.
"""
return await self.send_command("failover-only", parameters=failover)
async def coin(self) -> dict:
"""
API 'coin' command.
Returns information about the current coin being mined:
Hash Method <- the hashing algorithm
Current Block Time <- blocktime as a float, 0 means none
Current Block Hash <- the hash of the current block, blank means none
LP <- whether LP is in use on at least 1 pool
Network Difficulty: the current network difficulty
"""
return await self.send_command("coin")
async def debug(self, setting: str) -> dict:
"""
API 'debug' command.
Returns which debug setting was enabled or disabled.
Parameters:
setting: which setting to switch to. Options are:
Silent,
Quiet,
Verbose,
Debug,
RPCProto,
PerDevice,
WorkTime,
Normal.
"""
return await self.send_command("debug", parameters=setting)
async def setconfig(self, name: str, n: int) -> dict:
"""
API 'setconfig' command.
Returns the STATUS section with the results of setting 'name' to N.
Parameters:
name: name of the config setting to set. Options are:
queue,
scantime,
expiry.
n: the value to set the 'name' setting to.
"""
return await self.send_command("setconfig", parameters=f"{name}, {n}")
async def usbstats(self) -> dict:
"""
API 'usbstats' command.
Returns a dict containing the stats of all USB devices except ztex.
"""
return await self.send_command("usbstats")
async def pgaset(self, n: int, opt: str, val: int = None) -> dict:
"""
API 'pgaset' command.
Returns the STATUS section with the results of setting PGA N with opt[,val].
Parameters:
n: the PGA to set the options on.
opt: the option to set. Setting this to 'help' returns a help message.
val: the value to set the option to.
Options:
MMQ -
opt: clock
val: 160 - 230 (multiple of 2)
CMR -
opt: clock
val: 100 - 220
"""
if val:
return await self.send_command("pgaset", parameters=f"{n}, {opt}, {val}")
else:
return await self.send_command("pgaset", parameters=f"{n}, {opt}")
async def zero(self, which: str, summary: bool) -> dict:
"""
API 'zero' command.
Returns the STATUS section with info on the zero and optional summary.
Parameters:
which: which device to zero.
Setting this to 'all' zeros all devices.
Setting this to 'bestshare' zeros only the bestshare values for each pool and global.
summary: whether or not to show a full summary.
"""
return await self.send_command("zero", parameters=f"{which}, {summary}")
async def hotplug(self, n: int) -> dict:
"""
API 'hotplug' command.
Returns the STATUS section with whether or not hotplug was enabled.
"""
return await self.send_command("hotplug", parameters=n)
async def asc(self, n: int) -> dict:
"""
API 'asc' command.
Returns a dict containing the details of a single ASC of number N.
n: the ASC device to get details of.
"""
return await self.send_command("asc", parameters=n)
async def ascenable(self, n: int) -> dict:
"""
API 'ascenable' command.
Returns the STATUS section with the results of enabling the ASC device N.
Parameters:
n: the number of the ASC to enable.
"""
return await self.send_command("ascenable", parameters=n)
async def ascdisable(self, n: int) -> dict:
"""
API 'ascdisable' command.
Returns the STATUS section with the results of disabling the ASC device N.
Parameters:
n: the number of the ASC to disable.
"""
return await self.send_command("ascdisable", parameters=n)
async def ascidentify(self, n: int) -> dict:
"""
API 'ascidentify' command.
Returns the STATUS section with the results of identifying the ASC device N.
Parameters:
n: the number of the PGA to identify.
"""
return await self.send_command("ascidentify", parameters=n)
async def asccount(self) -> dict:
"""
API 'asccount' command.
Returns a dict containing the number of ASC devices.
"""
return await self.send_command("asccount")
async def ascset(self, n: int, opt: str, val: int = None) -> dict:
"""
API 'ascset' command.
Returns the STATUS section with the results of setting ASC N with opt[,val].
Parameters:
n: the ASC to set the options on.
opt: the option to set. Setting this to 'help' returns a help message.
val: the value to set the option to.
Options:
AVA+BTB -
opt: freq
val: 256 - 1024 (chip frequency)
BTB -
opt: millivolts
val: 1000 - 1400 (core voltage)
MBA -
opt: reset
val: 0 - # of chips (reset a chip)
opt: freq
val: 0 - # of chips, 100 - 1400 (chip frequency)
opt: ledcount
val: 0 - 100 (chip count for LED)
opt: ledlimit
val: 0 - 200 (LED off below GH/s)
opt: spidelay
val: 0 - 9999 (SPI per I/O delay)
opt: spireset
val: i or s, 0 - 9999 (SPI regular reset)
opt: spisleep
val: 0 - 9999 (SPI reset sleep in ms)
BMA -
opt: volt
val: 0 - 9
opt: clock
val: 0 - 15
"""
if val:
return await self.send_command("ascset", parameters=f"{n}, {opt}, {val}")
else:
return await self.send_command("ascset", parameters=f"{n}, {opt}")
async def lcd(self) -> dict:
"""
API 'lcd' command.
Returns a dict containing an all in one status summary of the miner.
"""
return await self.send_command("lcd")
async def lockstats(self) -> dict:
"""
API 'lockstats' command.
Returns the STATUS section with the result of writing the lock stats to STDERR.
"""
return await self.send_command("lockstats")

View File

@@ -1,219 +0,0 @@
from API import BaseMinerAPI
class BOSMinerAPI(BaseMinerAPI):
"""
A class that abstracts the BOSMiner API in the miners.
Each method corresponds to an API command in BOSMiner.
BOSMiner API documentation:
https://docs.braiins.com/os/plus-en/Development/1_api.html
Parameters:
ip: the IP address of the miner.
port (optional): the port of the API on the miner (standard is 4028)
"""
def __init__(self, ip, port=4028):
super().__init__(ip, port)
async def asccount(self) -> dict:
"""
API 'asccount' command.
Returns a dict containing the number of ASC devices.
"""
return await self.send_command("asccount")
async def asc(self, n: int) -> dict:
"""
API 'asc' command.
Returns a dict containing the details of a single ASC of number N.
n: the ASC device to get details of.
"""
return await self.send_command("asc", parameters=n)
async def devdetails(self) -> dict:
"""
API 'devdetails' command.
Returns a dict containing all devices with their static details.
"""
return await self.send_command("devdetails")
async def devs(self) -> dict:
"""
API 'devs' command.
Returns a dict containing each PGA/ASC with their details.
"""
return await self.send_command("devs")
async def edevs(self, old: bool = False) -> dict:
"""
API 'edevs' command.
Returns a dict containing each PGA/ASC with their details,
ignoring blacklisted devices and zombie devices.
Parameters:
old (optional): include zombie devices that became zombies less than 'old' seconds ago
"""
if old:
return await self.send_command("edevs", parameters="old")
else:
return await self.send_command("edevs")
async def pools(self) -> dict:
"""
API 'pools' command.
Returns a dict containing the status of each pool.
"""
return await self.send_command("pools")
async def summary(self) -> dict:
"""
API 'summary' command.
Returns a dict containing the status summary of the miner.
"""
return await self.send_command("summary")
async def stats(self) -> dict:
"""
API 'stats' command.
Returns a dict containing stats for all device/pool with more than 1 getwork.
"""
return await self.send_command("stats")
async def version(self) -> dict:
"""
API 'version' command.
Returns a dict containing version information.
"""
return await self.send_command("version")
async def estats(self) -> dict:
"""
API 'estats' command.
Returns a dict containing stats for all device/pool with more than 1 getwork,
ignoring zombie devices.
"""
return await self.send_command("estats")
async def check(self, command: str) -> dict:
"""
API 'check' command.
Returns information about a command:
Exists (Y/N) <- the command exists in this version
Access (Y/N) <- you have access to use the command
Parameters:
command: the command to get information about.
"""
return await self.send_command("check", parameters=command)
async def coin(self) -> dict:
"""
API 'coin' command.
Returns information about the current coin being mined:
Hash Method <- the hashing algorithm
Current Block Time <- blocktime as a float, 0 means none
Current Block Hash <- the hash of the current block, blank means none
LP <- whether LP is in use on at least 1 pool
Network Difficulty: the current network difficulty
"""
return await self.send_command("coin")
async def lcd(self) -> dict:
"""
API 'lcd' command.
Returns a dict containing an all in one status summary of the miner.
"""
return await self.send_command("lcd")
async def switchpool(self, n: int) -> dict:
# BOS has not implemented this yet, they will in the future
raise NotImplementedError
# return await self.send_command("switchpool", parameters=n)
async def enablepool(self, n: int) -> dict:
# BOS has not implemented this yet, they will in the future
raise NotImplementedError
# return await self.send_command("enablepool", parameters=n)
async def disablepool(self, n: int) -> dict:
# BOS has not implemented this yet, they will in the future
raise NotImplementedError
# return await self.send_command("disablepool", parameters=n)
async def addpool(self, url: str, username: str, password: str) -> dict:
# BOS has not implemented this yet, they will in the future
raise NotImplementedError
# return await self.send_command("addpool", parameters=f"{url}, {username}, {password}")
async def removepool(self, n: int) -> dict:
# BOS has not implemented this yet, they will in the future
raise NotImplementedError
# return await self.send_command("removepool", parameters=n)
async def fans(self) -> dict:
"""
API 'fans' command.
Returns a dict containing information on fans and fan speeds.
"""
return await self.send_command("fans")
async def tempctrl(self) -> dict:
"""
API 'tempctrl' command.
Returns a dict containing temp control configuration.
"""
return await self.send_command("tempctrl")
async def temps(self) -> dict:
"""
API 'temps' command.
Returns a dict containing temperature information.
"""
return await self.send_command("temps")
async def tunerstatus(self) -> dict:
"""
API 'tunerstatus' command.
Returns a dict containing tuning stats.
"""
return await self.send_command("tunerstatus")
async def pause(self) -> dict:
"""
API 'pause' command.
Pauses mining and stops power consumption and waits for resume command.
Returns a dict stating that the miner paused mining.
"""
return await self.send_command("pause")
async def resume(self) -> dict:
"""
API 'pause' command.
Resumes mining on the miner.
Returns a dict stating that the miner resumed mining.
"""
return await self.send_command("resume")

View File

@@ -1,543 +0,0 @@
from API import BaseMinerAPI, APIError
from passlib.handlers.md5_crypt import md5_crypt
import asyncio
import re
import json
import hashlib
import binascii
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
import base64
### IMPORTANT ###
# you need to change the password of the miners using
# the whatsminer tool, then you can set them back to
# admin with this tool, but they must be changed to
# something else and set back to admin with this or
# the privileged API will not work using admin as
# the password.
def _crypt(word: str, salt: str) -> str:
# compile a standard format for the salt
standard_salt = re.compile('\s*\$(\d+)\$([\w\./]*)\$')
# check if the salt matches
match = standard_salt.match(salt)
# if the matching fails, the salt is incorrect
if not match:
raise ValueError("salt format is not correct")
# save the matched salt in a new variable
new_salt = match.group(2)
# encrypt the word with the salt using md5
result = md5_crypt.hash(word, salt=new_salt)
return result
def _add_to_16(s: str) -> bytes:
"""Add null bytes to a string until the length is 16"""
while len(s) % 16 != 0:
s += '\0'
return str.encode(s) # return bytes
def parse_btminer_priviledge_data(token_data, data):
# get the encoded data from the dict
enc_data = data['enc']
# get the aes key from the token data
aeskey = hashlib.sha256(token_data['host_passwd_md5'].encode()).hexdigest()
# unhexlify the aes key
aeskey = binascii.unhexlify(aeskey.encode())
# create the required decryptor
aes = Cipher(algorithms.AES(aeskey), modes.ECB())
decryptor = aes.decryptor()
# decode the message with the decryptor
ret_msg = json.loads(decryptor.update(
base64.decodebytes(bytes(enc_data, encoding='utf8'))
).rstrip(b'\0').decode("utf8"))
return ret_msg
def create_privileged_cmd(token_data: dict, command: dict) -> bytes:
# add token to command
command['token'] = token_data['host_sign']
# encode host_passwd data and get hexdigest
aeskey = hashlib.sha256(token_data['host_passwd_md5'].encode()).hexdigest()
# unhexlify the encoded host_passwd
aeskey = binascii.unhexlify(aeskey.encode())
# create a new AES key
aes = Cipher(algorithms.AES(aeskey), modes.ECB())
encryptor = aes.encryptor()
# dump the command to json
api_json_str = json.dumps(command)
# encode the json command with the aes key
api_json_str_enc = base64.encodebytes(encryptor.update(_add_to_16(api_json_str))).decode("utf-8").replace("\n", "")
# label the data as being encoded
data_enc = {'enc': 1, 'data': api_json_str_enc}
# dump the labeled data to json
api_packet_str = json.dumps(data_enc)
return api_packet_str.encode('utf-8')
class BTMinerAPI(BaseMinerAPI):
def __init__(self, ip, port=4028, pwd: str = "admin"):
super().__init__(ip, port)
self.admin_pwd = pwd
self.current_token = None
async def send_command(self, command: str | bytes, **kwargs) -> dict:
"""Send an API command to the miner and return the result."""
# check if command is a string, if its bytes its encoded and needs to be send raw
if isinstance(command, str):
# if it is a string, put it into the standard command format
command = json.dumps({"command": command}).encode("utf-8")
try:
# get reader and writer streams
reader, writer = await asyncio.open_connection(str(self.ip), self.port)
# handle OSError 121
except OSError as e:
if e.winerror == "121":
print("Semaphore Timeout has Expired.")
return {}
# send the command
writer.write(command)
await writer.drain()
# instantiate data
data = b""
# loop to receive all the data
try:
while True:
d = await reader.read(4096)
if not d:
break
data += d
except Exception as e:
print(e)
data = self.load_api_data(data)
# close the connection
writer.close()
await writer.wait_closed()
# check if th returned data is encoded
if 'enc' in data.keys():
# try to parse the encoded data
try:
data = parse_btminer_priviledge_data(self.current_token, data)
except Exception as e:
print(e)
# if it fails to validate, it is likely an error
validation = self.validate_command_output(data)
if not validation[0]:
raise APIError(validation[1])
# return the parsed json as a dict
return data
async def get_token(self):
"""
API 'get_token' command.
Returns an encoded token and md5 password, which are used for the privileged API.
"""
data = await self.send_command("get_token")
pwd = _crypt(self.admin_pwd, "$1$" + data["Msg"]["salt"] + '$')
pwd = pwd.split('$')
host_passwd_md5 = pwd[3]
tmp = _crypt(pwd[3] + data["Msg"]["time"], "$1$" + data["Msg"]["newsalt"] + '$')
tmp = tmp.split('$')
host_sign = tmp[3]
self.current_token = {'host_sign': host_sign, 'host_passwd_md5': host_passwd_md5}
return {'host_sign': host_sign, 'host_passwd_md5': host_passwd_md5}
#### PRIVILEGED COMMANDS ####
# Please read the top of this file to learn
# how to configure the whatsminer API to
# use these commands.
async def update_pools(self,
pool_1: str, worker_1: str, passwd_1: str,
pool_2: str = None, worker_2: str = None, passwd_2: str = None,
pool_3: str = None, worker_3: str = None, passwd_3: str = None):
# get the token and password from the miner
token_data = await self.get_token()
# parse pool data
if not pool_1:
raise APIError("No pools set.")
elif pool_2 and pool_3:
command = {
"cmd": "update_pools",
"pool1": pool_1, "worker1": worker_1, "passwd1": passwd_1,
"pool2": pool_2, "worker2": worker_2, "passwd2": passwd_2,
"pool3": pool_3, "worker3": worker_3, "passwd3": passwd_3,
}
elif pool_2:
command = {
"cmd": "update_pools",
"pool1": pool_1, "worker1": worker_1, "passwd1": passwd_1,
"pool2": pool_2, "worker2": worker_2, "passwd2": passwd_2
}
else:
command = {
"cmd": "update_pools",
"pool1": pool_1, "worker1": worker_1, "passwd1": passwd_1,
}
# encode the command with the token data
enc_command = create_privileged_cmd(token_data, command)
# send the command
return await self.send_command(enc_command)
async def restart(self):
"""
API 'restart_btminer' command
Returns a reply informing of the restart and restarts BTMiner.
"""
command = {"cmd": "restart_btminer"}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def power_off(self, respbefore: bool = True):
"""
API 'power_off' command.
Powers off the mining of the miner.
Returns info on the power off.
Parameters:
respbefore (optional): respond before powering off.
"""
if respbefore:
command = {"cmd": "power_off", "respbefore": "true"}
else:
command = {"cmd": "power_off", "respbefore": "false"}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def power_on(self):
"""
API 'power_on' command.
Powers on the mining of the miner.
Returns info on the power on.
"""
command = {"cmd": "power_on"}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def reset_led(self):
"""
API 'reset_led' command.
Resets the LED flashing to normal.
Returns a confirmation of resetting the LED.
"""
command = {"cmd": "set_led", "param": "auto"}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def set_led(self, color: str = "red", period: int = 2000, duration: int = 1000, start: int = 0):
"""
API 'set_led' command.
Sets the LED to do some pattern set with parameters.
Returns a confirmation of setting the LED.
Parameters:
color: 'red' or 'green'
period: flash cycle in ms
duration: led on time in the cycle in ms
start: led on time offset in the cycle in ms
"""
command = {"cmd": "set_led", "color": color, "period": period, "duration": duration, "start": start}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def set_low_power(self):
"""
API 'set_low_power' command.
Sets the miner to low power mode.
Returns the status of setting the miner to low power mode.
"""
command = {"cmd": "set_low_power"}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def update_firmware(self):
# to be determined if this will be added later
# requires a file stream in bytes
return NotImplementedError
async def reboot(self):
"""
API 'reboot' command.
Reboots the miner.
Returns the status of the command then reboots.
"""
command = {"cmd": "reboot"}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def factory_reset(self):
"""
API 'factory_reset' command.
Resets the miner to factory defaults.
Returns the status of the command then resets.
"""
command = {"cmd": "factory_reset"}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def update_pwd(self, old_pwd: str, new_pwd: str):
"""
API 'update_pwd' command.
Updates the admin user's password.
Returns the status of setting the password to the new password.
Parameters:
old_pwd: the old admin password.
new_pwd: the new password to set. Max length of 8 bytes, using letters, numbers, and underscores.
"""
# check if password length is greater than 8 bytes
if len(new_pwd.encode('utf-8')) > 8:
return APIError(
f"New password too long, the max length is 8. Password size: {len(new_pwd.encode('utf-8'))}")
command = {"cmd": "update_pwd", "old": old_pwd, "new": new_pwd}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def set_target_freq(self, percent: int):
"""
API 'set_target_freq' command.
Sets the frequency for the miner ot use.
Returns the status of setting the frequency.
"""
if not -10 < percent < 100:
return APIError(f"Frequency % is outside of the allowed range. Please set a % between -10 and 100")
command = {"cmd": "set_target_freq", "percent": str(percent)}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def enable_fast_boot(self):
"""
API 'enable_fast_boot' command.
Turns on the fast boot feature on the miner.
Returns the status of setting the fast boot to on.
"""
command = {"cmd": "enable_btminer_fast_boot"}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def disable_fast_boot(self):
"""
API 'disable'_fast_boot' command.
Turns off the fast boot feature on the miner.
Returns the status of setting the fast boot to off.
"""
command = {"cmd": "disable_btminer_fast_boot"}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def enable_web_pools(self):
"""
API 'enable_web_pools' command.
Turns on the ability to change the pools through the web interface.
Returns the status of setting the web pools to enabled.
"""
command = {"cmd": "enable_web_pools"}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def disable_web_pools(self):
"""
API 'disable_web_pools' command.
Turns off the ability to change the pools through the web interface.
Returns the status of setting the web pools to disabled.
"""
command = {"cmd": "disable_web_pools"}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def set_hostname(self, hostname: str):
"""
API 'set_hostname' command.
Sets the hostname of the miner.
Returns the status of setting the hostname.
"""
command = {"cmd": "set_hostname", "hostname": hostname}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def set_power_pct(self, percent: int):
"""
API 'set_power_pct' command.
Sets the percent of power the miner should use.
Returns the status of setting the power usage to this percent.
Parameters:
percent: the percent to set the power usage to, between 0 and 100.
"""
if not 0 < percent < 100:
return APIError(f"Power PCT % is outside of the allowed range. Please set a % between 0 and 100")
command = {"cmd": "set_power_pct", "percent": str(percent)}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
async def pre_power_on(self, complete: bool, msg: str):
"""
API 'pre_power_on' command.
Preheats the miner for the 'power_on' command. Can also be used to query the status of pre powering on.
Returns status of pre powering on.
Parameters:
complete: check whether or not it is complete.
msg: the message to check. "wait for adjust temp" or "adjust complete" or "adjust continue"
"""
if not msg == "wait for adjust temp" or "adjust complete" or "adjust continue":
return APIError(
'Message is incorrect, please choose one of '
'["wait for adjust temp", "adjust complete", "adjust continue"]'
)
if complete:
complete = "true"
else:
complete = "false"
command = {"cmd": "pre_power_on", "complete": complete, "msg": msg}
token_data = await self.get_token()
enc_command = create_privileged_cmd(token_data, command)
return await self.send_command(enc_command)
#### END privileged COMMANDS ####
async def summary(self):
"""
API 'summary' command.
Returns a dict containing the status summary of the miner.
"""
return await self.send_command("summary")
async def pools(self):
"""
API 'pools' command.
Returns a dict containing the status of each pool.
"""
return await self.send_command("pools")
async def devs(self):
"""
API 'devs' command.
Returns a dict containing each PGA/ASC with their details.
"""
return await self.send_command("devs")
async def edevs(self):
"""
API 'edevs' command.
Returns a dict containing each PGA/ASC with their details,
ignoring blacklisted devices and zombie devices.
"""
return await self.send_command("edevs")
async def devdetails(self):
"""
API 'devdetails' command.
Returns a dict containing all devices with their static details.
"""
return await self.send_command("devdetails")
async def get_psu(self):
"""
API 'get_psu' command.
Returns a dict containing PSU and power information.
"""
return await self.send_command("get_psu")
async def version(self):
"""
API 'get_version' command.
Returns a dict containing version information.
"""
return await self.get_version()
async def get_version(self):
"""
API 'get_version' command.
Returns a dict containing version information.
"""
return await self.send_command("get_version")
async def status(self):
"""
API 'status' command.
Returns a dict containing BTMiner status and firmware version.
"""
return await self.send_command("status")
async def get_miner_info(self):
"""
API 'get_miner_info' command.
Returns a dict containing general miner info.
"""
return await self.send_command("get_miner_info")

View File

@@ -1,532 +0,0 @@
from API import BaseMinerAPI
class CGMinerAPI(BaseMinerAPI):
"""
A class that abstracts the CGMiner API in the miners.
Each method corresponds to an API command in CGMiner.
CGMiner API documentation:
https://github.com/ckolivas/cgminer/blob/master/API-README
Parameters:
ip: the IP address of the miner.
port (optional): the port of the API on the miner (standard is 4028)
"""
def __init__(self, ip, port=4028):
super().__init__(ip, port)
async def version(self) -> dict:
"""
API 'version' command.
Returns a dict containing version information.
"""
return await self.send_command("version")
async def config(self) -> dict:
"""
API 'config' command.
Returns a dict containing some miner configuration information:
ASC Count <- the number of ASCs
PGA Count <- the number of PGAs
Pool Count <- the number of Pools
Strategy <- the current pool strategy
Log Interval <- the interval of logging
Device Code <- list of compiled device drivers
OS <- the current operating system
"""
return await self.send_command("config")
async def summary(self) -> dict:
"""
API 'summary' command.
Returns a dict containing the status summary of the miner.
"""
return await self.send_command("summary")
async def pools(self) -> dict:
"""
API 'pools' command.
Returns a dict containing the status of each pool.
"""
return await self.send_command("pools")
async def devs(self) -> dict:
"""
API 'devs' command.
Returns a dict containing each PGA/ASC with their details.
"""
return await self.send_command("devs")
async def edevs(self, old: bool = False) -> dict:
"""
API 'edevs' command.
Returns a dict containing each PGA/ASC with their details,
ignoring blacklisted devices and zombie devices.
Parameters:
old (optional): include zombie devices that became zombies less than 'old' seconds ago
"""
if old:
return await self.send_command("edevs", parameters="old")
else:
return await self.send_command("edevs")
async def pga(self, n: int) -> dict:
"""
API 'pga' command.
Returns a dict containing the details of a single PGA of number N.
Parameters:
n: the number of the PGA to get details of.
"""
return await self.send_command("pga", parameters=n)
async def pgacount(self) -> dict:
"""
API 'pgacount' command.
Returns a dict containing the number of PGA devices.
"""
return await self.send_command("pgacount")
async def switchpool(self, n: int) -> dict:
"""
API 'switchpool' command.
Returns the STATUS section with the results of switching pools.
Parameters:
n: the number of the pool to switch to.
"""
return await self.send_command("switchpool", parameters=n)
async def enablepool(self, n: int) -> dict:
"""
API 'enablepool' command.
Returns the STATUS section with the results of enabling the pool.
Parameters:
n: the number of the pool to enable.
"""
return await self.send_command("enablepool", parameters=n)
async def addpool(self, url: str, username: str, password: str) -> dict:
"""
API 'addpool' command.
Returns the STATUS section with the results of adding the pool.
Parameters:
url: the URL of the new pool to add.
username: the users username on the new pool.
password: the worker password on the new pool.
"""
return await self.send_command("addpool", parameters=f"{url}, {username}, {password}")
async def poolpriority(self, *n: int) -> dict:
"""
API 'poolpriority' command.
Returns the STATUS section with the results of setting pool priority.
Parameters:
n: pool numbers in order of priority.
"""
return await self.send_command("poolpriority", parameters=f"{','.join([str(item) for item in n])}")
async def poolquota(self, n: int, q: int) -> dict:
"""
API 'poolquota' command.
Returns the STATUS section with the results of setting pool quota.
Parameters:
n: pool number to set quota on.
q: quota to set the pool to.
"""
return await self.send_command("poolquota", parameters=f"{n}, {q}")
async def disablepool(self, n: int) -> dict:
"""
API 'disablepool' command.
Returns the STATUS section with the results of disabling the pool.
Parameters:
n: the number of the pool to disable.
"""
return await self.send_command("disablepool", parameters=n)
async def removepool(self, n: int) -> dict:
"""
API 'removepool' command.
Returns the STATUS section with the results of removing the pool.
Parameters:
n: the number of the pool to remove.
"""
return await self.send_command("removepool", parameters=n)
async def save(self, filename: str = None) -> dict:
"""
API 'save' command.
Returns the STATUS section with the results of saving the config file..
Parameters:
filename (optional): the filename to save the config as.
"""
if filename:
return await self.send_command("save", parameters=filename)
else:
return await self.send_command("save")
async def quit(self) -> dict:
"""
API 'quit' command.
Returns a single "BYE" before CGMiner quits.
"""
return await self.send_command("quit")
async def notify(self) -> dict:
"""
API 'notify' command.
Returns a dict containing the last status and count of each devices problem(s).
"""
return await self.send_command("notify")
async def privileged(self) -> dict:
"""
API 'privileged' command.
Returns the STATUS section with an error if you have no privileged access.
"""
return await self.send_command("privileged")
async def pgaenable(self, n: int) -> dict:
"""
API 'pgaenable' command.
Returns the STATUS section with the results of enabling the PGA device N.
Parameters:
n: the number of the PGA to enable.
"""
return await self.send_command("pgaenable", parameters=n)
async def pgadisable(self, n: int) -> dict:
"""
API 'pgadisable' command.
Returns the STATUS section with the results of disabling the PGA device N.
Parameters:
n: the number of the PGA to disable.
"""
return await self.send_command("pgadisable", parameters=n)
async def pgaidentify(self, n: int) -> dict:
"""
API 'pgaidentify' command.
Returns the STATUS section with the results of identifying the PGA device N.
Parameters:
n: the number of the PGA to identify.
"""
return await self.send_command("pgaidentify", parameters=n)
async def devdetails(self) -> dict:
"""
API 'devdetails' command.
Returns a dict containing all devices with their static details.
"""
return await self.send_command("devdetails")
async def restart(self) -> dict:
"""
API 'restart' command.
Returns a single "RESTART" before CGMiner restarts.
"""
return await self.send_command("restart")
async def stats(self) -> dict:
"""
API 'stats' command.
Returns a dict containing stats for all device/pool with more than 1 getwork.
"""
return await self.send_command("stats")
async def estats(self, old: bool = False) -> dict:
"""
API 'estats' command.
Returns a dict containing stats for all device/pool with more than 1 getwork,
ignoring zombie devices.
Parameters:
old (optional): include zombie devices that became zombies less than 'old' seconds ago.
"""
if old:
return await self.send_command("estats", parameters="old")
else:
return await self.send_command("estats")
async def check(self, command) -> dict:
"""
API 'check' command.
Returns information about a command:
Exists (Y/N) <- the command exists in this version
Access (Y/N) <- you have access to use the command
Parameters:
command: the command to get information about.
"""
return await self.send_command("check", parameters=command)
async def failover_only(self, failover: bool) -> dict:
"""
API 'failover-only' command.
Returns the STATUS section with what failover-only was set to.
Parameters:
failover: what to set failover-only to.
"""
return await self.send_command("failover-only", parameters=failover)
async def coin(self) -> dict:
"""
API 'coin' command.
Returns information about the current coin being mined:
Hash Method <- the hashing algorithm
Current Block Time <- blocktime as a float, 0 means none
Current Block Hash <- the hash of the current block, blank means none
LP <- whether LP is in use on at least 1 pool
Network Difficulty: the current network difficulty
"""
return await self.send_command("coin")
async def debug(self, setting: str) -> dict:
"""
API 'debug' command.
Returns which debug setting was enabled or disabled.
Parameters:
setting: which setting to switch to. Options are:
Silent,
Quiet,
Verbose,
Debug,
RPCProto,
PerDevice,
WorkTime,
Normal.
"""
return await self.send_command("debug", parameters=setting)
async def setconfig(self, name: str, n: int) -> dict:
"""
API 'setconfig' command.
Returns the STATUS section with the results of setting 'name' to N.
Parameters:
name: name of the config setting to set. Options are:
queue,
scantime,
expiry.
n: the value to set the 'name' setting to.
"""
return await self.send_command("setconfig", parameters=f"{name}, {n}")
async def usbstats(self) -> dict:
"""
API 'usbstats' command.
Returns a dict containing the stats of all USB devices except ztex.
"""
return await self.send_command("usbstats")
async def pgaset(self, n: int, opt: str, val: int = None) -> dict:
"""
API 'pgaset' command.
Returns the STATUS section with the results of setting PGA N with opt[,val].
Parameters:
n: the PGA to set the options on.
opt: the option to set. Setting this to 'help' returns a help message.
val: the value to set the option to.
Options:
MMQ -
opt: clock
val: 160 - 230 (multiple of 2)
CMR -
opt: clock
val: 100 - 220
"""
if val:
return await self.send_command("pgaset", parameters=f"{n}, {opt}, {val}")
else:
return await self.send_command("pgaset", parameters=f"{n}, {opt}")
async def zero(self, which: str, summary: bool) -> dict:
"""
API 'zero' command.
Returns the STATUS section with info on the zero and optional summary.
Parameters:
which: which device to zero.
Setting this to 'all' zeros all devices.
Setting this to 'bestshare' zeros only the bestshare values for each pool and global.
summary: whether or not to show a full summary.
"""
return await self.send_command("zero", parameters=f"{which}, {summary}")
async def hotplug(self, n: int) -> dict:
"""
API 'hotplug' command.
Returns the STATUS section with whether or not hotplug was enabled.
"""
return await self.send_command("hotplug", parameters=n)
async def asc(self, n: int) -> dict:
"""
API 'asc' command.
Returns a dict containing the details of a single ASC of number N.
n: the ASC device to get details of.
"""
return await self.send_command("asc", parameters=n)
async def ascenable(self, n: int) -> dict:
"""
API 'ascenable' command.
Returns the STATUS section with the results of enabling the ASC device N.
Parameters:
n: the number of the ASC to enable.
"""
return await self.send_command("ascenable", parameters=n)
async def ascdisable(self, n: int) -> dict:
"""
API 'ascdisable' command.
Returns the STATUS section with the results of disabling the ASC device N.
Parameters:
n: the number of the ASC to disable.
"""
return await self.send_command("ascdisable", parameters=n)
async def ascidentify(self, n: int) -> dict:
"""
API 'ascidentify' command.
Returns the STATUS section with the results of identifying the ASC device N.
Parameters:
n: the number of the PGA to identify.
"""
return await self.send_command("ascidentify", parameters=n)
async def asccount(self) -> dict:
"""
API 'asccount' command.
Returns a dict containing the number of ASC devices.
"""
return await self.send_command("asccount")
async def ascset(self, n: int, opt: str, val: int = None) -> dict:
"""
API 'ascset' command.
Returns the STATUS section with the results of setting ASC N with opt[,val].
Parameters:
n: the ASC to set the options on.
opt: the option to set. Setting this to 'help' returns a help message.
val: the value to set the option to.
Options:
AVA+BTB -
opt: freq
val: 256 - 1024 (chip frequency)
BTB -
opt: millivolts
val: 1000 - 1400 (core voltage)
MBA -
opt: reset
val: 0 - # of chips (reset a chip)
opt: freq
val: 0 - # of chips, 100 - 1400 (chip frequency)
opt: ledcount
val: 0 - 100 (chip count for LED)
opt: ledlimit
val: 0 - 200 (LED off below GH/s)
opt: spidelay
val: 0 - 9999 (SPI per I/O delay)
opt: spireset
val: i or s, 0 - 9999 (SPI regular reset)
opt: spisleep
val: 0 - 9999 (SPI reset sleep in ms)
BMA -
opt: volt
val: 0 - 9
opt: clock
val: 0 - 15
"""
if val:
return await self.send_command("ascset", parameters=f"{n}, {opt}, {val}")
else:
return await self.send_command("ascset", parameters=f"{n}, {opt}")
async def lcd(self) -> dict:
"""
API 'lcd' command.
Returns a dict containing an all in one status summary of the miner.
"""
return await self.send_command("lcd")
async def lockstats(self) -> dict:
"""
API 'lockstats' command.
Returns the STATUS section with the result of writing the lock stats to STDERR.
"""
return await self.send_command("lockstats")

View File

@@ -1,73 +0,0 @@
from API import BaseMinerAPI
class UnknownAPI(BaseMinerAPI):
def __init__(self, ip, port=4028):
super().__init__(ip, port)
async def asccount(self) -> dict:
return await self.send_command("asccount")
async def asc(self, n: int) -> dict:
return await self.send_command("asc", parameters=n)
async def devdetails(self) -> dict:
return await self.send_command("devdetails")
async def devs(self) -> dict:
return await self.send_command("devs")
async def edevs(self, old: bool = False) -> dict:
if old:
return await self.send_command("edevs", parameters="old")
else:
return await self.send_command("edevs")
async def pools(self) -> dict:
return await self.send_command("pools")
async def summary(self) -> dict:
return await self.send_command("summary")
async def stats(self) -> dict:
return await self.send_command("stats")
async def version(self) -> dict:
return await self.send_command("version")
async def estats(self) -> dict:
return await self.send_command("estats")
async def check(self) -> dict:
return await self.send_command("check")
async def coin(self) -> dict:
return await self.send_command("coin")
async def lcd(self) -> dict:
return await self.send_command("lcd")
async def switchpool(self, n: int) -> dict:
# BOS has not implemented this yet, they will in the future
raise NotImplementedError
# return await self.send_command("switchpool", parameters=n)
async def enablepool(self, n: int) -> dict:
# BOS has not implemented this yet, they will in the future
raise NotImplementedError
# return await self.send_command("enablepool", parameters=n)
async def disablepool(self, n: int) -> dict:
# BOS has not implemented this yet, they will in the future
raise NotImplementedError
# return await self.send_command("disablepool", parameters=n)
async def addpool(self, url: str, username: str, password: str) -> dict:
# BOS has not implemented this yet, they will in the future
raise NotImplementedError
# return await self.send_command("addpool", parameters=f"{url}, {username}, {password}")
async def removepool(self, n: int) -> dict:
# BOS has not implemented this yet, they will in the future
raise NotImplementedError
# return await self.send_command("removepool", parameters=n)

176
LICENSE.txt Normal file
View File

@@ -0,0 +1,176 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

321
README.md
View File

@@ -1,146 +1,249 @@
# minerInterface
*A set of modules for interfacing with many common types of ASIC bitcoin miners, using both their API and SSH.*
## Usage
To use this repo, first download it, create a virtual environment, enter the virtual environment, and install relevant packages by navigating to this directory and running ```pip install -r requirements.txt``` on Windows or ```pip3 install -r requirements.txt``` on Mac or UNIX if the first command fails.
# pyasic
*A simplified and standardized interface for Bitcoin ASICs.*
### CFG Util
*CFG Util is a GUI for interfacing with the miners easily, it is mostly self-explanatory.*
[![PyPI - Version](https://img.shields.io/pypi/v/pyasic.svg)](https://pypi.org/project/pyasic/)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/pyasic)](https://pypi.org/project/pyasic/)
To use CFG Util you have 2 options -
1. Run it directly with the file ```config_tool.py``` or import it with ```from cfg_util import main```, then run the ```main()``` function in an asyncio event loop like -
[![Python - Supported Versions](https://img.shields.io/pypi/pyversions/pyasic.svg)](https://pypi.org/project/pyasic/)
[![CodeFactor - Grade](https://img.shields.io/codefactor/grade/github/UpstreamData/pyasic)](https://www.codefactor.io/repository/github/upstreamdata/pyasic)
[![Commit Activity - master](https://img.shields.io/github/commit-activity/y/UpstreamData/pyasic)](https://github.com/UpstreamData/pyasic/commits/master/)
[![Code Style - Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Read The Docs - Docs](https://img.shields.io/readthedocs/pyasic)](https://pyasic.readthedocs.io/en/latest/)
[![License - Apache 2.0](https://img.shields.io/github/license/UpstreamData/pyasic)](https://github.com/UpstreamData/pyasic/blob/master/LICENSE.txt)
---
## Intro
Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with ASIC miners on your network, which makes it super fast.
[Click here to view supported miner types](miners/supported_types.md)
---
## Getting started
Getting started with `pyasic` is easy. First, find your miner (or miners) on the network by scanning for them or getting the correct class automatically for them if you know the IP.
##### Scanning for miners
To scan for miners in `pyasic`, we use the class `MinerNetwork`, which abstracts the search, communication, identification, setup, and return of a miner to 1 command.
The command `MinerNetwork.scan()` returns a list that contains any miners found.
```python
from cfg_util import main
import asyncio # asyncio for handling the async part
from pyasic.network import MinerNetwork # miner network handles the scanning
if __name__ == '__main__':
main()
```
2. Make a build of the CFG Util for your system using cx_freeze and ```make_cfg_tool_exe.py```
(Alternatively, you can get a build made by me here -> https://drive.google.com/drive/folders/1nzojuGRu0IszIGpwx7SvG5RlJ2_KXIOv)
1. Open either Command Prompt on Windows or Terminal on Mac or UNIX.
2. Navigate to this directory, and run ```make_cfg_tool_exe.py build``` on Windows or ```python3 make_cfg_tool_exe.py``` on Mac or UNIX.
### Interfacing with miners programmatically
<br>
async def scan_miners(): # define async scan function to allow awaiting
# create a miner network
# you can pass in any IP and it will use that in a subnet with a /24 mask (255 IPs).
network = MinerNetwork.from_subnet("192.168.1.50/24") # this uses the 192.168.1.0-255 network
##### Note: If you are trying to interface with Whatsminers, there is a bug in the way they are interacted with on Windows, so to fix that you need to change the event loop policy using this code:
```python
# need to import these 2 libraries, you need asyncio anyway so make sure you have sys imported
import sys
import asyncio
# scan for miners asynchronously
# this will return the correct type of miners if they are supported with all functionality.
miners = await network.scan()
print(miners)
# if the computer is windows, set the event loop policy to a WindowsSelector policy
if sys.version_info[0] == 3 and sys.version_info[1] >= 8 and sys.platform.startswith('win'):
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
if __name__ == "__main__":
asyncio.run(scan_miners()) # run the scan asynchronously with asyncio.run()
```
##### It is likely a good idea to use this code in your program anyway to be preventative.
<br>
---
##### Creating miners based on IP
If you already know the IP address of your miner or miners, you can use the `MinerFactory` to communicate and identify the miners, or an abstraction of its functionality, `get_miner()`.
The function `get_miner()` will return any miner it found at the IP address specified, or an `UnknownMiner` if it cannot identify the miner.
```python
import asyncio # asyncio for handling the async part
from pyasic import get_miner # handles miner creation
To write your own custom programs with this repo, you have many options.
It is recommended that you explore the files in this repo to familiarize yourself with them, try starting with the miners module and going from there.
async def get_miners(): # define async scan function to allow awaiting
# get the miner with the miner factory
# the miner factory is a singleton, and will always use the same object and cache
# this means you can always call it as MinerFactory().get_miner(), or just get_miner()
miner_1 = await get_miner("192.168.1.75")
miner_2 = await get_miner("192.168.1.76")
print(miner_1, miner_2)
A basic script to find all miners on the network and get the hashrate from them looks like this -
# can also gather these, since they are async
# gathering them will get them both at the same time
# this makes it much faster to get a lot of miners at a time
tasks = [get_miner("192.168.1.75"), get_miner("192.168.1.76")]
miners = await asyncio.gather(*tasks)
print(miners)
if __name__ == "__main__":
asyncio.run(get_miners()) # get the miners asynchronously with asyncio.run()
```
---
## Data gathering
Once you have your miner(s) identified, you will likely want to get data from the miner(s). You can do this using a built-in function in each miner called `get_data()`.
This function will return an instance of the dataclass `MinerData` with all data it can gather from the miner.
Each piece of data in a `MinerData` instance can be referenced by getting it as an attribute, such as `MinerData().hashrate`.
##### One miner
```python
import asyncio
from network import MinerNetwork
from cfg_util.func.parse_data import safe_parse_api_data
from pyasic import get_miner
async def get_hashrate():
# Miner Network class allows for easy scanning of a network
# Give it any IP on a network and it will find the whole subnet
# It can also be passed a subnet mask:
# miner_network = MinerNetwork('192.168.1.55', mask=23)
miner_network = MinerNetwork('192.168.1.1')
# Miner Network scan function returns Miner classes for all miners found
miners = await miner_network.scan_network_for_miners()
# Each miner will return with its own set of functions, and an API class instance
tasks = [miner.api.summary() for miner in miners]
# Gather all tasks asynchronously and run them
data = await asyncio.gather(*tasks)
parse_tasks = []
for item in data:
# safe_parse_api_data parses the data from a miner API
# It will raise an APIError (from API import APIError) if there is a problem
parse_tasks.append(safe_parse_api_data(item, 'SUMMARY', 0, 'MHS 5s'))
# Gather all tasks asynchronously and run them
data = await asyncio.gather(*parse_tasks)
# Print a list of all the hashrates
print(data)
async def gather_miner_data():
miner = await get_miner("192.168.1.75")
if miner is not None:
miner_data = await miner.get_data()
print(miner_data) # all data from the dataclass
print(miner_data.hashrate) # hashrate of the miner in TH/s
if __name__ == '__main__':
asyncio.new_event_loop().run_until_complete(get_hashrate())
if __name__ == "__main__":
asyncio.run(gather_miner_data())
```
<br>
You can also create your own miner without scanning if you know the IP:
---
##### Multiple miners
You can do something similar with multiple miners, with only needing to make a small change to get all the data at once.
```python
import asyncio # asyncio for handling the async part
from pyasic.network import MinerNetwork # miner network handles the scanning
async def gather_miner_data(): # define async scan function to allow awaiting
network = MinerNetwork.from_subnet("192.168.1.50/24")
miners = await network.scan()
# we need to asyncio.gather() all the miners get_data() functions to make them run together
all_miner_data = await asyncio.gather(*[miner.get_data() for miner in miners])
for miner_data in all_miner_data:
print(miner_data) # print out all the data one by one
if __name__ == "__main__":
asyncio.run(gather_miner_data())
```
---
## Miner control
`pyasic` exposes a standard interface for each miner using control functions.
Every miner class in `pyasic` must implement all the control functions defined in `BaseMiner`.
These functions are
`check_light`,
`fault_light_off`,
`fault_light_on`,
`get_config`,
`get_data`,
`get_errors`,
`get_hostname`,
`get_model`,
`reboot`,
`restart_backend`,
`stop_mining`,
`resume_mining`,
`is_mining`,
`send_config`, and
`set_power_limit`.
##### Usage
```python
import asyncio
import ipaddress
from miners.miner_factory import MinerFactory
from cfg_util.func.parse_data import safe_parse_api_data
from pyasic import get_miner
async def get_miner_hashrate(ip: str):
# Instantiate a Miner Factory to generate miners from their IP
miner_factory = MinerFactory()
# Make the string IP into an IP address
miner_ip = ipaddress.ip_address(ip)
# Wait for the factory to return the miner
miner = await miner_factory.get_miner(miner_ip)
# Get the API data
summary = await miner.api.summary()
# safe_parse_api_data parses the data from a miner API
# It will raise an APIError (from API import APIError) if there is a problem
data = await safe_parse_api_data(summary, 'SUMMARY', 0, 'MHS 5s')
print(data)
if __name__ == '__main__':
asyncio.new_event_loop().run_until_complete(get_miner_hashrate(str("192.168.1.69")))
async def set_fault_light():
miner = await get_miner("192.168.1.20")
# call control function
await miner.fault_light_on()
if __name__ == "__main__":
asyncio.run(set_fault_light())
```
<br>
Or generate a miner directly without the factory:
---
## Helper dataclasses
##### `MinerConfig` and `MinerData`
`pyasic` implements a few dataclasses as helpers to make data return types consistent across different miners and miner APIs. The different fields of these dataclasses can all be viewed with the classmethod `cls.fields()`.
---
##### MinerData
`MinerData` is a return from the [`get_data()`](#get-data) function, and is used to have a consistent dataset across all returns.
You can call `MinerData.as_dict()` to get the dataclass as a dictionary, and there are many other helper functions contained in the class to convert to different data formats.
`MinerData` instances can also be added to each other to combine their data and can be divided by a number to divide all their data, allowing you to get average data from many miners by doing -
```python
from pyasic import MinerData
# examples of miner data
d1 = MinerData("192.168.1.1")
d2 = MinerData("192.168.1.2")
list_of_miner_data = [d1, d2]
average_data = sum(list_of_miner_data, start=MinerData("0.0.0.0"))/len(list_of_miner_data)
```
---
##### MinerConfig
`MinerConfig` is `pyasic`'s way to represent a configuration file from a miner.
It is designed to unionize the configuration of all supported miner types, and is the return from [`get_config()`](#get-config).
Each miner has a unique way to convert the `MinerConfig` to their specific type, there are helper functions in the class.
In most cases these helper functions should not be used, as [`send_config()`](#send-config) takes a [`MinerConfig` and will do the conversion to the right type for you.
You can use the `MinerConfig` as follows:
```python
import asyncio
from miners.bosminer import BOSminer
from cfg_util.func.parse_data import safe_parse_api_data
from pyasic import get_miner
async def get_miner_hashrate(ip: str):
# Create a BOSminer miner object
miner = BOSminer(ip)
# Get the API data
summary = await miner.api.summary()
# safe_parse_api_data parses the data from a miner API
# It will raise an APIError (from API import APIError) if there is a problem
data = await safe_parse_api_data(summary, 'SUMMARY', 0, 'MHS 5s')
print(data)
if __name__ == '__main__':
asyncio.new_event_loop().run_until_complete(get_miner_hashrate(str("192.168.1.69")))
async def set_fault_light():
miner = await get_miner("192.168.1.20")
# get config
cfg = await miner.get_config()
# send config
await miner.send_config(cfg)
if __name__ == "__main__":
asyncio.run(set_fault_light())
```
<br>
Or finally, just get the API directly:
---
## Settings
`pyasic` has settings designed to make using large groups of miners easier. You can set the default password for all types of miners using the `pyasic.settings` module, used as follows:
```python
import asyncio
from API.bosminer import BOSMinerAPI
from cfg_util.func.parse_data import safe_parse_api_data
from pyasic import settings
async def get_miner_hashrate(ip: str):
# Create a BOSminerAPI object
# Port can be declared manually, if not it defaults to 4028
api = BOSMinerAPI(ip, port=4028)
# Get the API data
summary = await api.summary()
# safe_parse_api_data parses the data from a miner API
# It will raise an APIError (from API import APIError) if there is a problem
data = await safe_parse_api_data(summary, 'SUMMARY', 0, 'MHS 5s')
print(data)
if __name__ == '__main__':
asyncio.new_event_loop().run_until_complete(get_miner_hashrate(str("192.168.1.69")))
settings.update("default_antminer_password", "my_pwd")
```
##### Default values:
```
"network_ping_retries": 1,
"network_ping_timeout": 3,
"network_scan_threads": 300,
"factory_get_retries": 1,
"factory_get_timeout": 3,
"get_data_retries": 1,
"api_function_timeout": 5,
"default_whatsminer_password": "admin",
"default_innosilicon_password": "admin",
"default_antminer_password": "root",
"default_bosminer_password": "root",
"default_vnish_password": "admin",
"default_goldshell_password": "123456789",
# ADVANCED
# Only use this if you know what you are doing
"socket_linger_time": 1000,
```

View File

@@ -1,15 +0,0 @@
from cfg_util.miner_factory import miner_factory
from cfg_util.layout import window
from cfg_util.ui import ui
import asyncio
import sys
# Fix bug with some whatsminers and asyncio because of a socket not being shut down:
if sys.version_info[0] == 3 and sys.version_info[1] >= 8 and sys.platform.startswith('win'):
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
def main():
loop = asyncio.new_event_loop()
loop.run_until_complete(ui())

View File

@@ -1,68 +0,0 @@
import ipaddress
import os
import re
import time
import aiofiles
import toml
from cfg_util.func.ui import update_ui_with_data
from cfg_util.layout import window
from config.bos import bos_config_convert, general_config_convert_bos
async def import_iplist(file_location):
await update_ui_with_data("status", "Importing")
if not os.path.exists(file_location):
return
else:
ip_list = []
async with aiofiles.open(file_location, mode='r') as file:
async for line in file:
ips = [x.group() for x in re.finditer(
"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)", line)]
for ip in ips:
if ip not in ip_list:
ip_list.append(ipaddress.ip_address(ip))
ip_list.sort()
window["ip_table"].update([[str(ip), "", "", "", ""] for ip in ip_list])
await update_ui_with_data("ip_count", str(len(ip_list)))
await update_ui_with_data("status", "")
async def export_iplist(file_location, ip_list_selected):
await update_ui_with_data("status", "Exporting")
if not os.path.exists(file_location):
return
else:
if ip_list_selected is not None and not ip_list_selected == []:
async with aiofiles.open(file_location, mode='w') as file:
for item in ip_list_selected:
await file.write(str(item) + "\n")
else:
async with aiofiles.open(file_location, mode='w') as file:
for item in window['ip_table'].Values:
await file.write(str(item[0]) + "\n")
await update_ui_with_data("status", "")
async def import_config_file(file_location):
await update_ui_with_data("status", "Importing")
if not os.path.exists(file_location):
return
else:
async with aiofiles.open(file_location, mode='r') as file:
config = await file.read()
await update_ui_with_data("config", await bos_config_convert(toml.loads(config)))
await update_ui_with_data("status", "")
async def export_config_file(file_location, config):
await update_ui_with_data("status", "Exporting")
config = toml.loads(config)
config['format']['generator'] = 'upstream_config_util'
config['format']['timestamp'] = int(time.time())
config = toml.dumps(config)
async with aiofiles.open(file_location, mode='w+') as file:
await file.write(await general_config_convert_bos(config))
await update_ui_with_data("status", "")

View File

@@ -1,301 +0,0 @@
import asyncio
import ipaddress
import time
import warnings
from API import APIError
from cfg_util.func.parse_data import safe_parse_api_data
from cfg_util.func.ui import update_ui_with_data, update_prog_bar, set_progress_bar_len
from cfg_util.layout import window
from cfg_util.miner_factory import miner_factory
from config.bos import bos_config_convert
from settings import CFG_UTIL_CONFIG_THREADS as CONFIG_THREADS
async def import_config(idx):
await update_ui_with_data("status", "Importing")
miner = await miner_factory.get_miner(ipaddress.ip_address(window["ip_table"].Values[idx[0]][0]))
await miner.get_config()
config = miner.config
await update_ui_with_data("config", str(config))
await update_ui_with_data("status", "")
async def scan_network(network):
await update_ui_with_data("status", "Scanning")
await update_ui_with_data("ip_count", "")
await update_ui_with_data("hr_total", "")
window["ip_table"].update([])
network_size = len(network)
miner_generator = network.scan_network_generator()
await set_progress_bar_len(2 * network_size)
progress_bar_len = 0
miners = []
async for miner in miner_generator:
if miner:
miners.append(miner)
# can output "Identifying" for each found item, but it gets a bit cluttered
# and could possibly be confusing for the end user because of timing on
# adding the IPs
# window["ip_table"].update([["Identifying...", "", "", "", ""] for miner in miners])
progress_bar_len += 1
asyncio.create_task(update_prog_bar(progress_bar_len))
progress_bar_len += network_size - len(miners)
asyncio.create_task(update_prog_bar(progress_bar_len))
get_miner_genenerator = miner_factory.get_miner_generator(miners)
all_miners = []
async for found_miner in get_miner_genenerator:
all_miners.append(found_miner)
all_miners.sort(key=lambda x: x.ip)
window["ip_table"].update([[str(miner.ip)] for miner in all_miners])
progress_bar_len += 1
asyncio.create_task(update_prog_bar(progress_bar_len))
await update_ui_with_data("ip_count", str(len(all_miners)))
await update_ui_with_data("status", "")
async def miner_light(ips: list):
await asyncio.gather(*[flip_light(ip) for ip in ips])
async def flip_light(ip):
ip_list = window['ip_table'].Widget
miner = await miner_factory.get_miner(ip)
index = [item[0] for item in window["ip_table"].Values].index(ip)
index_tags = ip_list.item(index)['tags']
if "light" not in index_tags:
ip_list.item(index, tags=([*index_tags, "light"]))
window['ip_table'].update(row_colors=[(index, "white", "red")])
await miner.fault_light_on()
else:
index_tags.remove("light")
ip_list.item(index, tags=index_tags)
window['ip_table'].update(row_colors=[(index, "black", "white")])
await miner.fault_light_off()
async def send_config_generator(miners: list, config):
loop = asyncio.get_event_loop()
config_tasks = []
for miner in miners:
if len(config_tasks) >= CONFIG_THREADS:
configured = asyncio.as_completed(config_tasks)
config_tasks = []
for sent_config in configured:
yield await sent_config
config_tasks.append(loop.create_task(miner.send_config(config)))
configured = asyncio.as_completed(config_tasks)
for sent_config in configured:
yield await sent_config
async def send_config(ips: list, config):
await update_ui_with_data("status", "Configuring")
await set_progress_bar_len(2 * len(ips))
progress_bar_len = 0
get_miner_genenerator = miner_factory.get_miner_generator(ips)
all_miners = []
async for miner in get_miner_genenerator:
all_miners.append(miner)
progress_bar_len += 1
asyncio.create_task(update_prog_bar(progress_bar_len))
config_sender_generator = send_config_generator(all_miners, config)
async for _config_sender in config_sender_generator:
progress_bar_len += 1
asyncio.create_task(update_prog_bar(progress_bar_len))
await update_ui_with_data("status", "")
async def get_data(ip_list: list):
await update_ui_with_data("status", "Getting Data")
ips = [ipaddress.ip_address(ip) for ip in ip_list]
if len(ips) == 0:
ips = [ipaddress.ip_address(ip) for ip in [item[0] for item in window["ip_table"].Values]]
await set_progress_bar_len(len(ips))
progress_bar_len = 0
data_gen = asyncio.as_completed([get_formatted_data(miner) for miner in ips])
ip_table_data = window["ip_table"].Values
ordered_all_ips = [item[0] for item in ip_table_data]
for all_data in data_gen:
data_point = await all_data
if data_point["IP"] in ordered_all_ips:
ip_table_index = ordered_all_ips.index(data_point["IP"])
ip_table_data[ip_table_index] = [
data_point["IP"], data_point["model"], data_point["host"], str(data_point['TH/s']) + " TH/s", data_point["temp"],
data_point['user'], str(data_point['wattage']) + " W"
]
window["ip_table"].update(ip_table_data)
progress_bar_len += 1
asyncio.create_task(update_prog_bar(progress_bar_len))
hashrate_list = [float(item[3].replace(" TH/s", "")) if not item[3] == '' else 0 for item in window["ip_table"].Values]
total_hr = round(sum(hashrate_list), 2)
window["hr_total"].update(f"{total_hr} TH/s")
await update_ui_with_data("status", "")
async def scan_and_get_data(network):
await update_ui_with_data("status", "Scanning")
network_size = len(network)
miner_generator = network.scan_network_generator()
await set_progress_bar_len(3 * network_size)
progress_bar_len = 0
miners = []
async for miner in miner_generator:
if miner:
miners.append(miner)
# can output "Identifying" for each found item, but it gets a bit cluttered
# and could possibly be confusing for the end user because of timing on
# adding the IPs
# window["ip_table"].update([["Identifying..."] for miner in miners])
progress_bar_len += 1
asyncio.create_task(update_prog_bar(progress_bar_len))
progress_bar_len += network_size - len(miners)
asyncio.create_task(update_prog_bar(progress_bar_len))
get_miner_genenerator = miner_factory.get_miner_generator(miners)
all_miners = []
async for found_miner in get_miner_genenerator:
all_miners.append(found_miner)
all_miners.sort(key=lambda x: x.ip)
window["ip_table"].update([[str(miner.ip)] for miner in all_miners])
progress_bar_len += 1
asyncio.create_task(update_prog_bar(progress_bar_len))
await update_ui_with_data("ip_count", str(len(all_miners)))
data_gen = asyncio.as_completed([get_formatted_data(miner) for miner in miners])
ip_table_data = window["ip_table"].Values
ordered_all_ips = [item[0] for item in ip_table_data]
progress_bar_len += (network_size - len(miners))
asyncio.create_task(update_prog_bar(progress_bar_len))
await update_ui_with_data("status", "Getting Data")
for all_data in data_gen:
data_point = await all_data
if data_point["IP"] in ordered_all_ips:
ip_table_index = ordered_all_ips.index(data_point["IP"])
ip_table_data[ip_table_index] = [
data_point["IP"], data_point["model"], data_point["host"], str(data_point['TH/s']) + " TH/s", data_point["temp"],
data_point['user'], str(data_point['wattage']) + " W"
]
window["ip_table"].update(ip_table_data)
progress_bar_len += 1
asyncio.create_task(update_prog_bar(progress_bar_len))
hashrate_list = [float(item[3].replace(" TH/s", "")) for item in window["ip_table"].Values if not item[3] == '']
total_hr = round(sum(hashrate_list), 2)
await update_ui_with_data("hr_total", f"{total_hr} TH/s")
await update_ui_with_data("status", "")
async def get_formatted_data(ip: ipaddress.ip_address):
miner = await miner_factory.get_miner(ip)
warnings.filterwarnings('ignore')
try:
miner_data = await miner.api.multicommand("summary", "devs", "temps", "tunerstatus", "pools", "stats")
except APIError:
return {'TH/s': "Unknown", 'IP': str(miner.ip), 'host': "Unknown", 'user': "Unknown", 'wattage': 0}
host = await miner.get_hostname()
model = await miner.get_model()
temps = 0
if "summary" in miner_data.keys():
if "Temperature" in miner_data['summary'][0]['SUMMARY'][0].keys():
if not round(miner_data['summary'][0]['SUMMARY'][0]["Temperature"]) == 0:
temps = miner_data['summary'][0]['SUMMARY'][0]["Temperature"]
if 'MHS av' in miner_data['summary'][0]['SUMMARY'][0].keys():
th5s = round(await safe_parse_api_data(miner_data, 'summary', 0, 'SUMMARY', 0, 'MHS av') / 1000000, 2)
elif 'GHS av' in miner_data['summary'][0]['SUMMARY'][0].keys():
if not miner_data['summary'][0]['SUMMARY'][0]['GHS av'] == "":
th5s = round(float(await safe_parse_api_data(miner_data, 'summary', 0, 'SUMMARY', 0, 'GHS av')) / 1000,
2)
else:
th5s = 0
else:
th5s = 0
else:
th5s = 0
if "temps" in miner_data.keys() and not miner_data["temps"][0]['TEMPS'] == []:
if "Chip" in miner_data["temps"][0]['TEMPS'][0].keys():
for board in miner_data["temps"][0]['TEMPS']:
if board["Chip"] is not None and not board["Chip"] == 0.0:
temps = board["Chip"]
if "devs" in miner_data.keys() and not miner_data["devs"][0]['DEVS'] == []:
if "Chip Temp Avg" in miner_data["devs"][0]['DEVS'][0].keys():
for board in miner_data["devs"][0]['DEVS']:
if board['Chip Temp Avg'] is not None and not board['Chip Temp Avg'] == 0.0:
temps = board['Chip Temp Avg']
if "stats" in miner_data.keys() and not miner_data["stats"][0]['STATS'] == []:
for temp in ["temp2", "temp1", "temp3"]:
if temp in miner_data["stats"][0]['STATS'][1].keys():
if miner_data["stats"][0]['STATS'][1][temp] is not None and not miner_data["stats"][0]['STATS'][1][
temp] == 0.0:
temps = miner_data["stats"][0]['STATS'][1][temp]
if "pools" not in miner_data.keys():
user = "?"
elif not miner_data['pools'][0]['POOLS'] == []:
user = await safe_parse_api_data(miner_data, 'pools', 0, 'POOLS', 0, 'User')
else:
user = "Blank"
if "tunerstatus" in miner_data.keys():
wattage = await safe_parse_api_data(miner_data, "tunerstatus", 0, 'TUNERSTATUS', 0, "PowerLimit")
elif "Power" in miner_data["summary"][0]["SUMMARY"][0].keys():
wattage = await safe_parse_api_data(miner_data, "summary", 0, 'SUMMARY', 0, "Power")
else:
wattage = 0
return {'TH/s': th5s, 'IP': str(miner.ip), 'model': model,
'temp': round(temps), 'host': host, 'user': user,
'wattage': wattage}
async def generate_config(username, workername, v2_allowed):
if username and workername:
user = f"{username}.{workername}"
elif username and not workername:
user = username
else:
return
if v2_allowed:
url_1 = 'stratum2+tcp://v2.us-east.stratum.slushpool.com/u95GEReVMjK6k5YqiSFNqqTnKU4ypU2Wm8awa6tmbmDmk1bWt'
url_2 = 'stratum2+tcp://v2.stratum.slushpool.com/u95GEReVMjK6k5YqiSFNqqTnKU4ypU2Wm8awa6tmbmDmk1bWt'
url_3 = 'stratum+tcp://stratum.slushpool.com:3333'
else:
url_1 = 'stratum+tcp://ca.stratum.slushpool.com:3333'
url_2 = 'stratum+tcp://us-east.stratum.slushpool.com:3333'
url_3 = 'stratum+tcp://stratum.slushpool.com:3333'
config = {'group': [{
'name': 'group',
'quota': 1,
'pool': [{
'url': url_1,
'user': user,
'password': '123'
}, {
'url': url_2,
'user': user,
'password': '123'
}, {
'url': url_3,
'user': user,
'password': '123'
}]
}],
'format': {
'version': '1.2+',
'model': 'Antminer S9',
'generator': 'upstream_config_util',
'timestamp': int(time.time())
},
'temp_control': {
'target_temp': 80.0,
'hot_temp': 90.0,
'dangerous_temp': 120.0
},
'autotuning': {
'enabled': True,
'psu_power_limit': 900
}
}
window['config'].update(await bos_config_convert(config))

View File

@@ -1,50 +0,0 @@
from API import APIError
# noinspection PyPep8
async def safe_parse_api_data(data: dict or list, *path: str or int, idx: int = 0):
path = [*path]
if len(path) == idx+1:
if isinstance(path[idx], str):
if isinstance(data, dict):
if path[idx] in data.keys():
return data[path[idx]]
elif isinstance(path[idx], int):
if isinstance(data, list):
if len(data) > path[idx]:
return data[path[idx]]
else:
if isinstance(path[idx], str):
if isinstance(data, dict):
if path[idx] in data.keys():
parsed_data = await safe_parse_api_data(data[path[idx]], idx=idx+1, *path)
# has to be == None, or else it fails on 0.0 hashrates
# noinspection PyPep8
if parsed_data == None:
raise APIError(f"Data parsing failed on path index {idx} - \nKey: {path[idx]} \nData: {data}")
return parsed_data
else:
if idx == 0:
raise APIError(f"Data parsing failed on path index {idx} - \nKey: {path[idx]} \nData: {data}")
return False
else:
if idx == 0:
raise APIError(f"Data parsing failed on path index {idx} - \nKey: {path[idx]} \nData: {data}")
return False
elif isinstance(path[idx], int):
if isinstance(data, list):
if len(data) > path[idx]:
parsed_data = await safe_parse_api_data(data[path[idx]], idx=idx+1, *path)
# has to be == None, or else it fails on 0.0 hashrates
# noinspection PyPep8
if parsed_data == None:
raise APIError(f"Data parsing failed on path index {idx} - \nKey: {path[idx]} \nData: {data}")
return parsed_data
else:
if idx == 0:
raise APIError(f"Data parsing failed on path index {idx} - \nKey: {path[idx]} \nData: {data}")
return False
else:
if idx == 0:
raise APIError(f"Data parsing failed on path index {idx} - \nKey: {path[idx]} \nData: {data}")
return False

View File

@@ -1,72 +0,0 @@
import ipaddress
import re
from cfg_util.layout import window
import pyperclip
def copy_from_table(table):
selection = table.selection()
copy_values = []
for each in selection:
try:
value = table.item(each)["values"][0]
copy_values.append(str(value))
except:
pass
copy_string = "\n".join(copy_values)
pyperclip.copy(copy_string)
async def update_ui_with_data(key, message, append=False):
if append:
message = window[key].get_text() + message
window[key].update(message)
async def update_prog_bar(amount):
window["progress"].Update(amount)
percent_done = 100 * (amount / window['progress'].maxlen)
window["progress_percent"].Update(f"{round(percent_done, 2)} %")
if percent_done == 100:
window["progress_percent"].Update("")
async def set_progress_bar_len(amount):
window["progress"].Update(0, max=amount)
window["progress"].maxlen = amount
window["progress_percent"].Update("0.0 %")
async def sort_data(index: int or str):
await update_ui_with_data("status", "Sorting Data")
data_list = window['ip_table'].Values
# wattage
if re.match("[0-9]* W", str(data_list[0][index])):
new_list = sorted(data_list, key=lambda x: int(x[index].replace(" W", "")))
if data_list == new_list:
new_list = sorted(data_list, reverse=True, key=lambda x: int(x[index].replace(" W", "")))
# hashrate
elif re.match("[0-9]*\.?[0-9]* TH\/s", str(data_list[0][index])):
new_list = sorted(data_list, key=lambda x: float(x[index].replace(" TH/s", "")))
if data_list == new_list:
new_list = sorted(data_list, reverse=True, key=lambda x: float(x[index].replace(" TH/s", "")))
# ip addresses
elif re.match("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",
str(data_list[0][index])):
new_list = sorted(data_list, key=lambda x: ipaddress.ip_address(x[index]))
if data_list == new_list:
new_list = sorted(data_list, reverse=True, key=lambda x: ipaddress.ip_address(x[index]))
# everything else, hostname, temp, and user
else:
new_list = sorted(data_list, key=lambda x: x[index])
if data_list == new_list:
new_list = sorted(data_list, reverse=True, key=lambda x: x[index])
await update_ui_with_data("ip_table", new_list)
await update_ui_with_data("status", "")

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +0,0 @@
"""
This file stores the MinerFactory instance used by the ConfigUtility for use in other files.
"""
from miners.miner_factory import MinerFactory
miner_factory = MinerFactory()

View File

@@ -1,87 +0,0 @@
import asyncio
import sys
import PySimpleGUI as sg
from cfg_util.layout import window, generate_config_layout
from cfg_util.func.miners import scan_network, send_config, miner_light, get_data, generate_config, import_config, \
scan_and_get_data
from cfg_util.func.files import import_iplist, import_config_file, export_iplist, export_config_file
from cfg_util.func.ui import sort_data, copy_from_table
from network import MinerNetwork
import webbrowser
async def ui():
window.read(timeout=0)
table = window["ip_table"].Widget
table.bind("<Control-Key-c>", lambda x: copy_from_table(table))
while True:
event, value = window.read(timeout=10)
if event in (None, 'Close', sg.WIN_CLOSED):
sys.exit()
if isinstance(event, tuple):
if len(window["ip_table"].Values) > 0:
if event[0] == 'ip_table':
if event[2][0] == -1:
await sort_data(event[2][1])
if event == 'open_in_web':
for row in value["ip_table"]:
webbrowser.open("http://" + window["ip_table"].Values[row][0])
if event == 'scan':
if len(value['miner_network'].split("/")) > 1:
network = value['miner_network'].split("/")
miner_network = MinerNetwork(ip_addr=network[0], mask=network[1])
else:
miner_network = MinerNetwork(value['miner_network'])
asyncio.create_task(scan_network(miner_network))
if event == 'select_all_ips':
if len(value["ip_table"]) == len(window["ip_table"].Values):
window["ip_table"].update(select_rows=())
else:
window["ip_table"].update(select_rows=([row for row in range(len(window["ip_table"].Values))]))
if event == 'import_config':
if 2 > len(value['ip_table']) > 0:
asyncio.create_task(import_config(value['ip_table']))
if event == 'light':
asyncio.create_task(miner_light([window['ip_table'].Values[item][0] for item in value['ip_table']]))
if event == "import_iplist":
asyncio.create_task(import_iplist(value["file_iplist"]))
if event == "export_iplist":
asyncio.create_task(export_iplist(value["file_iplist"], [window['ip_table'].Values[item][0] for item in value['ip_table']]))
if event == "send_config":
asyncio.create_task(send_config([window['ip_table'].Values[item][0] for item in value['ip_table']], value['config']))
if event == "import_file_config":
asyncio.create_task(import_config_file(value['file_config']))
if event == "export_file_config":
asyncio.create_task(export_config_file(value['file_config'], value["config"]))
if event == "get_data":
if len(window["ip_table"].Values) == 0:
if len(value['miner_network'].split("/")) > 1:
network = value['miner_network'].split("/")
miner_network = MinerNetwork(ip_addr=network[0], mask=network[1])
else:
miner_network = MinerNetwork(value['miner_network'])
asyncio.create_task(scan_and_get_data(miner_network))
else:
asyncio.create_task(get_data([window["ip_table"].Values[item][0] for item in value["ip_table"]]))
if event == "generate_config":
await generate_config_ui()
if event == "__TIMEOUT__":
await asyncio.sleep(0)
async def generate_config_ui():
generate_config_window = sg.Window("Generate Config", generate_config_layout(), modal=True)
while True:
event, values = generate_config_window.read()
if event in (None, 'Close', sg.WIN_CLOSED):
break
if event == "generate_config_window_generate":
if values['generate_config_window_username']:
await generate_config(values['generate_config_window_username'],
values['generate_config_window_workername'],
values['generate_config_window_allow_v2'])
generate_config_window.close()
break

View File

@@ -1,78 +0,0 @@
"""
SAMPLE CONFIG
-------------------
{
"format": {
"version": "1.2+", # -> (default = "1.2+", str, (bos: format.version))
"model": "Antminer S9", # -> (default = "Antminer S9", str, (bos: format.model))
"generator": "upstream_config_util", # -> (hidden, always = "upstream_config_util", str, (bos: format.generator))
"timestamp": 1606842000, # -> (hidden, always = int(time.time()) (current unix time), int, (bos: format.timestamp))
},
"temperature": {
"mode": "auto", # -> (default = "auto", str["auto", "manual", "disabled"], (bos: temp_control.mode))
"target": 70.0, # -> (default = 70.0, float, (bos: temp_control.target_temp))
"hot": 80.0, # -> (default = 80.0, float, (bos: temp_control.hot_temp))
"danger": 90.0, # -> (default = 90.0, float, (bos: temp_control.dangerous_temp))
},
"fans": { # -> (optional, required if temperature["mode"] == "disabled", (bos: fan_control))
"min_fans": 1, # -> (default = 1, int, (bos: fan_control.min_fans))
"speed": 100, # -> (default = 100, 0 < int < 100, (bos: fan_control.speed))
},
"asicboost": True, # -> (default = True, bool, (bos : hash_chain_global.asic_boost))
"pool_groups": [
{
"group_name": "Upstream", # -> (default = "group_{index}" (group_0), str, (bos: group.[index].name))
"quota": 1, # -> (default = 1, int, (bos: group.[index].quota))
"pools": [
{
"url": "stratum+tcp://stratum.slushpool.com:3333", # -> (str, (bos: group.[index].pool.[index].url))
"username": "UpstreamDataInc.test", # -> (str, (bos: group.[index].pool.[index].user))
"password": "123", # -> (str, (bos: group.[index].pool.[index].password))
},
{
"url": "stratum+tcp://us-east.stratum.slushpool.com:3333", # -> (str, (bos: group.[index].pool.[index].url))
"username": "UpstreamDataInc.test", # -> (str, (bos: group.[index].pool.[index].user))
"password": "123", # -> (str, (bos: group.[index].pool.[index].password))
},
{
"url": "stratum+tcp://ca.stratum.slushpool.com:3333", # -> (str, (bos: group.[index].pool.[index].url))
"username": "UpstreamDataInc.test", # -> (str, (bos: group.[index].pool.[index].user))
"password": "123", # -> (str, (bos: group.[index].pool.[index].password))
},
]
},
{
"group_name": "Upstream2", # -> (default = "group_{index}" (group_1), str, (bos: group.[index].name))
"quota": 4, # -> (default = 1, int, (bos: group.[index].quota))
"pools": [
{
"url": "stratum+tcp://stratum.slushpool.com:3333", # -> (str, (bos: group.[index].pool.[index].url))
"username": "UpstreamDataTesting.test", # -> (str, (bos: group.[index].pool.[index].user))
"password": "123", # -> (str, (bos: group.[index].pool.[index].password))
},
{
"url": "stratum+tcp://us-east.stratum.slushpool.com:3333", # -> (str, (bos: group.[index].pool.[index].url))
"username": "UpstreamDataTesting.test", # -> (str, (bos: group.[index].pool.[index].user))
"password": "123", # -> (str, (bos: group.[index].pool.[index].password))
},
{
"url": "stratum+tcp://ca.stratum.slushpool.com:3333", # -> (str, (bos: group.[index].pool.[index].url))
"username": "UpstreamDataTesting.test", # -> (str, (bos: group.[index].pool.[index].user))
"password": "123", # -> (str, (bos: group.[index].pool.[index].password))
},
]
},
],
"autotuning": {
"enabled": True, # -> (default = True, bool), (bos: autotuning.enabled)
"wattage": 900, # -> (default = 900, int, (bos: autotuning.psu_power_limit))
},
"power_scaling": {
"enabled": False, # -> (default = False, bool, (bos: power_scaling.enabled))
"power_step": 100, # -> (default = 100, int, (bos: power_scaling.power_step))
"min_psu_power_limit": 800, # -> (default = 800, int, (bos: power_scaling.min_psu_power_limit))
"shutdown_enabled": True, # -> (default = False, bool, (bos: power_scaling.shutdown_enabled))
"shutdown_duration": 3.0, # -> (default = 3.0, float, (bos: power_scaling.shutdown_duration))
}
}
"""

View File

@@ -1,188 +0,0 @@
import time
import yaml
import toml
async def bos_config_convert(config: dict):
out_config = {}
for opt in config:
if opt == "format":
out_config["format"] = config[opt]
out_config["format"]["generator"] = 'upstream_config_util'
out_config["format"]["timestamp"] = int(time.time())
elif opt == "temp_control":
out_config["temperature"] = {}
if "mode" in config[opt].keys():
out_config["temperature"]["mode"] = config[opt]["mode"]
else:
out_config["temperature"]["mode"] = "auto"
if "target_temp" in config[opt].keys():
out_config["temperature"]["target"] = config[opt]["target_temp"]
else:
out_config["temperature"]["target"] = 70.0
if "hot_temp" in config[opt].keys():
out_config["temperature"]["hot"] = config[opt]["hot_temp"]
else:
out_config["temperature"]["hot"] = 80.0
if "dangerous_temp" in config[opt].keys():
out_config["temperature"]["danger"] = config[opt]["dangerous_temp"]
else:
out_config["temperature"]["danger"] = 90.0
elif opt == "fan_control":
out_config["fans"] = {}
if "min_fans" in config[opt].keys():
out_config["fans"]["min_fans"] = config[opt]["min_fans"]
else:
out_config["fans"]["min_fans"] = 1
if "speed" in config[opt].keys():
out_config["fans"]["speed"] = config[opt]["speed"]
else:
out_config["fans"]["speed"] = 100
elif opt == "group":
out_config["pool_groups"] = [{} for _item in range(len(config[opt]))]
for idx in range(len(config[opt])):
out_config["pool_groups"][idx]["pools"] = []
out_config["pool_groups"][idx] = {}
if "name" in config[opt][idx].keys():
out_config["pool_groups"][idx]["group_name"] = config[opt][idx]["name"]
else:
out_config["pool_groups"][idx]["group_name"] = f"group_{idx}"
if "quota" in config[opt][idx].keys():
out_config["pool_groups"][idx]["quota"] = config[opt][idx]["quota"]
else:
out_config["pool_groups"][idx]["quota"] = 1
out_config["pool_groups"][idx]["pools"] = [{} for _item in range(len(config[opt][idx]["pool"]))]
for pool_idx in range(len(config[opt][idx]["pool"])):
out_config["pool_groups"][idx]["pools"][pool_idx]["url"] = config[opt][idx]["pool"][pool_idx]["url"]
out_config["pool_groups"][idx]["pools"][pool_idx]["username"] = config[opt][idx]["pool"][pool_idx][
"user"]
out_config["pool_groups"][idx]["pools"][pool_idx]["password"] = config[opt][idx]["pool"][pool_idx][
"password"]
elif opt == "autotuning":
out_config["autotuning"] = {}
if "enabled" in config[opt].keys():
out_config["autotuning"]["enabled"] = config[opt]["enabled"]
else:
out_config["autotuning"]["enabled"] = True
if "psu_power_limit" in config[opt].keys():
out_config["autotuning"]["wattage"] = config[opt]["psu_power_limit"]
else:
out_config["autotuning"]["wattage"] = 900
elif opt == "power_scaling":
out_config["power_scaling"] = {}
if "enabled" in config[opt].keys():
out_config["power_scaling"]["enabled"] = config[opt]["enabled"]
else:
out_config["power_scaling"]["enabled"] = False
if "power_step" in config[opt].keys():
out_config["power_scaling"]["power_step"] = config[opt]["power_step"]
else:
out_config["power_scaling"]["power_step"] = 100
if "min_psu_power_limit" in config[opt].keys():
out_config["power_scaling"]["min_psu_power_limit"] = config[opt]["min_psu_power_limit"]
else:
out_config["power_scaling"]["min_psu_power_limit"] = 800
if "shutdown_enabled" in config[opt].keys():
out_config["power_scaling"]["shutdown_enabled"] = config[opt]["shutdown_enabled"]
else:
out_config["power_scaling"]["shutdown_enabled"] = False
if "shutdown_duration" in config[opt].keys():
out_config["power_scaling"]["shutdown_duration"] = config[opt]["shutdown_duration"]
else:
out_config["power_scaling"]["shutdown_duration"] = 3.0
return yaml.dump(out_config, sort_keys=False)
async def general_config_convert_bos(yaml_config):
config = yaml.load(yaml_config, Loader=yaml.SafeLoader)
out_config = {}
for opt in config:
if opt == "format":
out_config["format"] = config[opt]
out_config["format"]["generator"] = 'upstream_config_util'
out_config["format"]["timestamp"] = int(time.time())
elif opt == "temperature":
out_config["temp_control"] = {}
if "mode" in config[opt].keys():
out_config["temp_control"]["mode"] = config[opt]["mode"]
else:
out_config["temp_control"]["mode"] = "auto"
if "target" in config[opt].keys():
out_config["temp_control"]["target_temp"] = config[opt]["target"]
else:
out_config["temp_control"]["target_temp"] = 70.0
if "hot" in config[opt].keys():
out_config["temp_control"]["hot_temp"] = config[opt]["hot"]
else:
out_config["temp_control"]["hot_temp"] = 80.0
if "danger" in config[opt].keys():
out_config["temp_control"]["dangerous_temp"] = config[opt]["danger"]
else:
out_config["temp_control"]["dangerous_temp"] = 90.0
elif opt == "fans":
out_config["fan_control"] = {}
if "min_fans" in config[opt].keys():
out_config["fan_control"]["min_fans"] = config[opt]["min_fans"]
else:
out_config["fan_control"]["min_fans"] = 1
if "speed" in config[opt].keys():
out_config["fan_control"]["speed"] = config[opt]["speed"]
else:
out_config["fan_control"]["speed"] = 100
elif opt == "pool_groups":
out_config["group"] = [{} for _item in range(len(config[opt]))]
for idx in range(len(config[opt])):
out_config["group"][idx]["pools"] = []
out_config["group"][idx] = {}
if "group_name" in config[opt][idx].keys():
out_config["group"][idx]["name"] = config[opt][idx]["group_name"]
else:
out_config["group"][idx]["name"] = f"group_{idx}"
if "quota" in config[opt][idx].keys():
out_config["group"][idx]["quota"] = config[opt][idx]["quota"]
else:
out_config["group"][idx]["quota"] = 1
out_config["group"][idx]["pool"] = [{} for _item in range(len(config[opt][idx]["pools"]))]
for pool_idx in range(len(config[opt][idx]["pools"])):
out_config["group"][idx]["pool"][pool_idx]["url"] = config[opt][idx]["pools"][pool_idx]["url"]
out_config["group"][idx]["pool"][pool_idx]["user"] = config[opt][idx]["pools"][pool_idx]["username"]
out_config["group"][idx]["pool"][pool_idx]["password"] = config[opt][idx]["pools"][pool_idx]["password"]
elif opt == "autotuning":
out_config["autotuning"] = {}
if "enabled" in config[opt].keys():
out_config["autotuning"]["enabled"] = config[opt]["enabled"]
else:
out_config["autotuning"]["enabled"] = True
if "wattage" in config[opt].keys():
out_config["autotuning"]["psu_power_limit"] = config[opt]["wattage"]
else:
out_config["autotuning"]["psu_power_limit"] = 900
elif opt == "power_scaling":
out_config["power_scaling"] = {}
if "enabled" in config[opt].keys():
out_config["power_scaling"]["enabled"] = config[opt]["enabled"]
else:
out_config["power_scaling"]["enabled"] = False
if "power_step" in config[opt].keys():
out_config["power_scaling"]["power_step"] = config[opt]["power_step"]
else:
out_config["power_scaling"]["power_step"] = 100
if "min_psu_power_limit" in config[opt].keys():
out_config["power_scaling"]["min_psu_power_limit"] = config[opt]["min_psu_power_limit"]
else:
out_config["power_scaling"]["min_psu_power_limit"] = 800
if "shutdown_enabled" in config[opt].keys():
out_config["power_scaling"]["shutdown_enabled"] = config[opt]["shutdown_enabled"]
else:
out_config["power_scaling"]["shutdown_enabled"] = False
if "shutdown_duration" in config[opt].keys():
out_config["power_scaling"]["shutdown_duration"] = config[opt]["shutdown_duration"]
else:
out_config["power_scaling"]["shutdown_duration"] = 3.0
return toml.dumps(out_config)

View File

@@ -1,17 +0,0 @@
config cgminer 'default'
option pool1pw 'x'
option pool2pw 'x'
option pool3pw 'x'
option voltage_level_offset '0'
option fan '10'
option api_allow 'W:0/0'
option power_mode 'balance'
option pool1url 'stratum+tcp://ca.stratum.slushpool.com:3333'
option pool1user 'poolacct.worker1'
option pool2url 'stratum+tcp://ca.stratum.slushpool.com:3333'
option pool2user 'poolacct.worker2'
option pool3url 'stratum+tcp://ca.stratum.slushpool.com:3333'
option pool3user 'poolacct.worker3'
option ntp_enable 'openwrt'

View File

@@ -1,4 +0,0 @@
from cfg_util import main
if __name__ == '__main__':
main()

View File

@@ -0,0 +1,8 @@
# pyasic
## Miner Config
::: pyasic.config.MinerConfig
handler: python
options:
show_root_heading: false
heading_level: 4

33
docs/data/error_codes.md Normal file
View File

@@ -0,0 +1,33 @@
# pyasic
<br>
## Whatsminer Error Codes
::: pyasic.data.error_codes.WhatsminerError
handler: python
options:
show_root_heading: false
heading_level: 4
<br>
## Braiins OS Error Codes
::: pyasic.data.error_codes.BraiinsOSError
handler: python
options:
show_root_heading: false
heading_level: 4
<br>
## X19 Error Codes
::: pyasic.data.error_codes.X19Error
handler: python
options:
show_root_heading: false
heading_level: 4
<br>
## Innosilicon Error Codes
::: pyasic.data.error_codes.InnosiliconError
handler: python
options:
show_root_heading: false
heading_level: 4

22
docs/data/miner_data.md Normal file
View File

@@ -0,0 +1,22 @@
# pyasic
## Miner Data
::: pyasic.data.MinerData
handler: python
options:
show_root_heading: false
heading_level: 4
## HashBoard Data
::: pyasic.data.HashBoard
handler: python
options:
show_root_heading: false
heading_level: 4
## Fan Data
::: pyasic.data.Fan
handler: python
options:
show_root_heading: false
heading_level: 4

165
docs/generate_miners.py Normal file
View File

@@ -0,0 +1,165 @@
import asyncio
import importlib
import os
import warnings
from pyasic.miners.factory import MINER_CLASSES, MinerTypes
warnings.filterwarnings("ignore")
def path(cls):
module = importlib.import_module(cls.__module__)
return module.__name__ + "." + cls.__name__
def make(cls):
p = path(cls)
return p.split(".")[2]
def model_type(cls):
p = path(cls)
return p.split(".")[4]
def backend_str(backend: MinerTypes) -> str:
match backend:
case MinerTypes.ANTMINER:
return "Stock Firmware Antminers"
case MinerTypes.AVALONMINER:
return "Stock Firmware Avalonminers"
case MinerTypes.VNISH:
return "Vnish Firmware Miners"
case MinerTypes.EPIC:
return "ePIC Firmware Miners"
case MinerTypes.BRAIINS_OS:
return "BOS+ Firmware Miners"
case MinerTypes.HIVEON:
return "HiveOS Firmware Miners"
case MinerTypes.INNOSILICON:
return "Stock Firmware Innosilicons"
case MinerTypes.WHATSMINER:
return "Stock Firmware Whatsminers"
case MinerTypes.GOLDSHELL:
return "Stock Firmware Goldshells"
case MinerTypes.LUX_OS:
return "LuxOS Firmware Miners"
def create_url_str(mtype: str):
return (
mtype.lower()
.replace(" ", "-")
.replace("(", "")
.replace(")", "")
.replace("+", "_1")
)
HEADER_FORMAT = "# pyasic\n## {} Models\n\n"
MINER_HEADER_FORMAT = "## {}\n"
DATA_FORMAT = """::: {}
handler: python
options:
show_root_heading: false
heading_level: 4
"""
SUPPORTED_TYPES_HEADER = """# pyasic
## Supported Miners
Supported miner types are here on this list. If your miner (or miner version) is not on this list, please feel free to [open an issue on GitHub](https://github.com/UpstreamData/pyasic/issues) to get it added.
##### pyasic currently supports the following miners and subtypes:
<style>
details {
margin:0px;
padding-top:0px;
padding-bottom:0px;
}
</style>
"""
BACKEND_TYPE_HEADER = """
<details>
<summary>{}:</summary>
<ul>"""
MINER_TYPE_HEADER = """
<details>
<summary>{} Series:</summary>
<ul>"""
MINER_DETAILS = """
<li><a href="../{}/{}#{}">{}</a></li>"""
MINER_TYPE_CLOSER = """
</ul>
</details>"""
BACKEND_TYPE_CLOSER = """
</ul>
</details>"""
m_data = {}
for m in MINER_CLASSES:
for t in MINER_CLASSES[m]:
if t is not None:
miner = MINER_CLASSES[m][t]
if make(miner) not in m_data:
m_data[make(miner)] = {}
if model_type(miner) not in m_data[make(miner)]:
m_data[make(miner)][model_type(miner)] = []
m_data[make(miner)][model_type(miner)].append(miner)
async def create_directory_structure(directory, data):
if not os.path.exists(directory):
os.makedirs(directory)
for key, value in data.items():
subdirectory = os.path.join(directory, key)
if isinstance(value, dict):
await create_directory_structure(subdirectory, value)
elif isinstance(value, list):
file_path = os.path.join(subdirectory + ".md")
with open(file_path, "w") as file:
file.write(HEADER_FORMAT.format(key))
for item in value:
header = await item("1.1.1.1").get_model()
file.write(MINER_HEADER_FORMAT.format(header))
file.write(DATA_FORMAT.format(path(item)))
async def create_supported_types(directory):
with open(os.path.join(directory, "supported_types.md"), "w") as file:
file.write(SUPPORTED_TYPES_HEADER)
for mback in MINER_CLASSES:
backend_types = {}
file.write(BACKEND_TYPE_HEADER.format(backend_str(mback)))
for mtype in MINER_CLASSES[mback]:
if mtype is None:
continue
m = MINER_CLASSES[mback][mtype]
if model_type(m) not in backend_types:
backend_types[model_type(m)] = []
backend_types[model_type(m)].append(m)
for mtype in backend_types:
file.write(MINER_TYPE_HEADER.format(mtype))
for minstance in backend_types[mtype]:
model = await minstance("1.1.1.1").get_model()
file.write(
MINER_DETAILS.format(
make(minstance), mtype, create_url_str(model), model
)
)
file.write(MINER_TYPE_CLOSER)
file.write(BACKEND_TYPE_CLOSER)
root_directory = os.path.join(os.getcwd(), "miners")
asyncio.run(create_directory_structure(root_directory, m_data))
asyncio.run(create_supported_types(root_directory))

249
docs/index.md Normal file
View File

@@ -0,0 +1,249 @@
# pyasic
*A simplified and standardized interface for Bitcoin ASICs.*
[![PyPI - Version](https://img.shields.io/pypi/v/pyasic.svg)](https://pypi.org/project/pyasic/)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/pyasic)](https://pypi.org/project/pyasic/)
[![Python - Supported Versions](https://img.shields.io/pypi/pyversions/pyasic.svg)](https://pypi.org/project/pyasic/)
[![CodeFactor - Grade](https://img.shields.io/codefactor/grade/github/UpstreamData/pyasic)](https://www.codefactor.io/repository/github/upstreamdata/pyasic)
[![Commit Activity - master](https://img.shields.io/github/commit-activity/y/UpstreamData/pyasic)](https://github.com/UpstreamData/pyasic/commits/master/)
[![Code Style - Black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Read The Docs - Docs](https://img.shields.io/readthedocs/pyasic)](https://pyasic.readthedocs.io/en/latest/)
[![License - Apache 2.0](https://img.shields.io/github/license/UpstreamData/pyasic)](https://github.com/UpstreamData/pyasic/blob/master/LICENSE.txt)
---
## Intro
---
Welcome to `pyasic`! `pyasic` uses an asynchronous method of communicating with ASIC miners on your network, which makes it super fast.
[Click here to view supported miner types](miners/supported_types.md)
---
## Getting started
---
Getting started with `pyasic` is easy. First, find your miner (or miners) on the network by scanning for them or getting the correct class automatically for them if you know the IP.
##### Scanning for miners
To scan for miners in `pyasic`, we use the class [`MinerNetwork`][pyasic.network.MinerNetwork], which abstracts the search, communication, identification, setup, and return of a miner to 1 command.
The command [`MinerNetwork.scan()`][pyasic.network.MinerNetwork.scan] returns a list that contains any miners found.
```python
import asyncio # asyncio for handling the async part
from pyasic.network import MinerNetwork # miner network handles the scanning
async def scan_miners(): # define async scan function to allow awaiting
# create a miner network
# you can pass in any IP and it will use that in a subnet with a /24 mask (255 IPs).
network = MinerNetwork.from_subnet("192.168.1.50/24") # this uses the 192.168.1.0-255 network
# scan for miners asynchronously
# this will return the correct type of miners if they are supported with all functionality.
miners = await network.scan()
print(miners)
if __name__ == "__main__":
asyncio.run(scan_miners()) # run the scan asynchronously with asyncio.run()
```
---
##### Creating miners based on IP
If you already know the IP address of your miner or miners, you can use the [`MinerFactory`][pyasic.miners.factory.MinerFactory] to communicate and identify the miners, or an abstraction of its functionality, [`get_miner()`][pyasic.miners.get_miner].
The function [`get_miner()`][pyasic.miners.get_miner] will return any miner it found at the IP address specified, or an `UnknownMiner` if it cannot identify the miner.
```python
import asyncio # asyncio for handling the async part
from pyasic import get_miner # handles miner creation
async def get_miners(): # define async scan function to allow awaiting
# get the miner with the miner factory
# the miner factory is a singleton, and will always use the same object and cache
# this means you can always call it as MinerFactory().get_miner(), or just get_miner()
miner_1 = await get_miner("192.168.1.75")
miner_2 = await get_miner("192.168.1.76")
print(miner_1, miner_2)
# can also gather these, since they are async
# gathering them will get them both at the same time
# this makes it much faster to get a lot of miners at a time
tasks = [get_miner("192.168.1.75"), get_miner("192.168.1.76")]
miners = await asyncio.gather(*tasks)
print(miners)
if __name__ == "__main__":
asyncio.run(get_miners()) # get the miners asynchronously with asyncio.run()
```
---
## Data gathering
---
Once you have your miner(s) identified, you will likely want to get data from the miner(s). You can do this using a built-in function in each miner called `get_data()`.
This function will return an instance of the dataclass [`MinerData`][pyasic.data.MinerData] with all data it can gather from the miner.
Each piece of data in a [`MinerData`][pyasic.data.MinerData] instance can be referenced by getting it as an attribute, such as [`MinerData().hashrate`][pyasic.data.MinerData].
##### One miner
```python
import asyncio
from pyasic import get_miner
async def gather_miner_data():
miner = await get_miner("192.168.1.75")
if miner is not None:
miner_data = await miner.get_data()
print(miner_data) # all data from the dataclass
print(miner_data.hashrate) # hashrate of the miner in TH/s
if __name__ == "__main__":
asyncio.run(gather_miner_data())
```
---
##### Multiple miners
You can do something similar with multiple miners, with only needing to make a small change to get all the data at once.
```python
import asyncio # asyncio for handling the async part
from pyasic.network import MinerNetwork # miner network handles the scanning
async def gather_miner_data(): # define async scan function to allow awaiting
network = MinerNetwork.from_subnet("192.168.1.50/24")
miners = await network.scan()
# we need to asyncio.gather() all the miners get_data() functions to make them run together
all_miner_data = await asyncio.gather(*[miner.get_data() for miner in miners])
for miner_data in all_miner_data:
print(miner_data) # print out all the data one by one
if __name__ == "__main__":
asyncio.run(gather_miner_data())
```
---
## Miner control
---
`pyasic` exposes a standard interface for each miner using control functions.
Every miner class in `pyasic` must implement all the control functions defined in [`MinerProtocol`][pyasic.miners.base.MinerProtocol].
These functions are
[`check_light`][pyasic.miners.base.MinerProtocol.check_light],
[`fault_light_off`][pyasic.miners.base.MinerProtocol.fault_light_off],
[`fault_light_on`][pyasic.miners.base.MinerProtocol.fault_light_on],
[`get_config`][pyasic.miners.base.MinerProtocol.get_config],
[`get_data`][pyasic.miners.base.MinerProtocol.get_data],
[`get_errors`][pyasic.miners.base.MinerProtocol.get_errors],
[`get_hostname`][pyasic.miners.base.MinerProtocol.get_hostname],
[`get_model`][pyasic.miners.base.MinerProtocol.get_model],
[`reboot`][pyasic.miners.base.MinerProtocol.reboot],
[`restart_backend`][pyasic.miners.base.MinerProtocol.restart_backend],
[`stop_mining`][pyasic.miners.base.MinerProtocol.stop_mining],
[`resume_mining`][pyasic.miners.base.MinerProtocol.resume_mining],
[`is_mining`][pyasic.miners.base.MinerProtocol.is_mining],
[`send_config`][pyasic.miners.base.MinerProtocol.send_config], and
[`set_power_limit`][pyasic.miners.base.MinerProtocol.set_power_limit].
##### Usage
```python
import asyncio
from pyasic import get_miner
async def set_fault_light():
miner = await get_miner("192.168.1.20")
# call control function
await miner.fault_light_on()
if __name__ == "__main__":
asyncio.run(set_fault_light())
```
---
## Helper dataclasses
---
##### [`MinerConfig`][pyasic.config.MinerConfig] and [`MinerData`][pyasic.data.MinerData]
`pyasic` implements a few dataclasses as helpers to make data return types consistent across different miners and miner APIs. The different fields of these dataclasses can all be viewed with the classmethod `cls.fields()`.
---
##### [`MinerData`][pyasic.data.MinerData]
[`MinerData`][pyasic.data.MinerData] is a return from the [`get_data()`](#get-data) function, and is used to have a consistent dataset across all returns.
You can call [`MinerData.as_dict()`][pyasic.data.MinerData.as_dict] to get the dataclass as a dictionary, and there are many other helper functions contained in the class to convert to different data formats.
[`MinerData`][pyasic.data.MinerData] instances can also be added to each other to combine their data and can be divided by a number to divide all their data, allowing you to get average data from many miners by doing -
```python
from pyasic import MinerData
# examples of miner data
d1 = MinerData("192.168.1.1")
d2 = MinerData("192.168.1.2")
list_of_miner_data = [d1, d2]
average_data = sum(list_of_miner_data, start=MinerData("0.0.0.0"))/len(list_of_miner_data)
```
---
##### [`MinerConfig`][pyasic.config.MinerConfig]
[`MinerConfig`][pyasic.config.MinerConfig] is `pyasic`'s way to represent a configuration file from a miner.
It is designed to unionize the configuration of all supported miner types, and is the return from [`get_config()`](#get-config).
Each miner has a unique way to convert the [`MinerConfig`][pyasic.config.MinerConfig] to their specific type, there are helper functions in the class.
In most cases these helper functions should not be used, as [`send_config()`](#send-config) takes a [`MinerConfig`][pyasic.config.MinerConfig] and will do the conversion to the right type for you.
You can use the [`MinerConfig`][pyasic.config.MinerConfig] as follows:
```python
import asyncio
from pyasic import get_miner
async def set_fault_light():
miner = await get_miner("192.168.1.20")
# get config
cfg = await miner.get_config()
# send config
await miner.send_config(cfg)
if __name__ == "__main__":
asyncio.run(set_fault_light())
```
---
## Settings
---
`pyasic` has settings designed to make using large groups of miners easier. You can set the default password for all types of miners using the `pyasic.settings` module, used as follows:
```python
from pyasic import settings
settings.update("default_antminer_password", "my_pwd")
```
##### Default values:
```
"network_ping_retries": 1,
"network_ping_timeout": 3,
"network_scan_threads": 300,
"factory_get_retries": 1,
"factory_get_timeout": 3,
"get_data_retries": 1,
"api_function_timeout": 5,
"default_whatsminer_password": "admin",
"default_innosilicon_password": "admin",
"default_antminer_password": "root",
"default_bosminer_password": "root",
"default_vnish_password": "admin",
"default_goldshell_password": "123456789",
# ADVANCED
# Only use this if you know what you are doing
"socket_linger_time": 1000,
```

View File

@@ -0,0 +1,10 @@
# pyasic
## X15 Models
## Z15
::: pyasic.miners.antminer.cgminer.X15.Z15.CGMinerZ15
handler: python
options:
show_root_heading: false
heading_level: 4

115
docs/miners/antminer/X17.md Normal file
View File

@@ -0,0 +1,115 @@
# pyasic
## X17 Models
## S17
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17
handler: python
options:
show_root_heading: false
heading_level: 4
## S17+
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17Plus
handler: python
options:
show_root_heading: false
heading_level: 4
## S17 Pro
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S17e
::: pyasic.miners.antminer.bmminer.X17.S17.BMMinerS17e
handler: python
options:
show_root_heading: false
heading_level: 4
## T17
::: pyasic.miners.antminer.bmminer.X17.T17.BMMinerT17
handler: python
options:
show_root_heading: false
heading_level: 4
## T17+
::: pyasic.miners.antminer.bmminer.X17.T17.BMMinerT17Plus
handler: python
options:
show_root_heading: false
heading_level: 4
## T17e
::: pyasic.miners.antminer.bmminer.X17.T17.BMMinerT17e
handler: python
options:
show_root_heading: false
heading_level: 4
## S17 (BOS)
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17
handler: python
options:
show_root_heading: false
heading_level: 4
## S17+ (BOS)
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Plus
handler: python
options:
show_root_heading: false
heading_level: 4
## S17 Pro (BOS)
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S17e (BOS)
::: pyasic.miners.antminer.bosminer.X17.S17.BOSMinerS17e
handler: python
options:
show_root_heading: false
heading_level: 4
## T17 (BOS)
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17
handler: python
options:
show_root_heading: false
heading_level: 4
## T17+ (BOS)
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17Plus
handler: python
options:
show_root_heading: false
heading_level: 4
## T17e (BOS)
::: pyasic.miners.antminer.bosminer.X17.T17.BOSMinerT17e
handler: python
options:
show_root_heading: false
heading_level: 4
## S17+ (VNish)
::: pyasic.miners.antminer.vnish.X17.S17.VNishS17Plus
handler: python
options:
show_root_heading: false
heading_level: 4
## S17 Pro (VNish)
::: pyasic.miners.antminer.vnish.X17.S17.VNishS17Pro
handler: python
options:
show_root_heading: false
heading_level: 4

234
docs/miners/antminer/X19.md Normal file
View File

@@ -0,0 +1,234 @@
# pyasic
## X19 Models
## S19
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19L
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19L
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19j
handler: python
options:
show_root_heading: false
heading_level: 4
## S19i
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19i
handler: python
options:
show_root_heading: false
heading_level: 4
## S19+
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19Plus
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j No PIC
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19jNoPIC
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro+
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19ProPlus
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19jPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 XP
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19XP
handler: python
options:
show_root_heading: false
heading_level: 4
## S19a
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19a
handler: python
options:
show_root_heading: false
heading_level: 4
## S19a Pro
::: pyasic.miners.antminer.bmminer.X19.S19.BMMinerS19aPro
handler: python
options:
show_root_heading: false
heading_level: 4
## T19
::: pyasic.miners.antminer.bmminer.X19.T19.BMMinerT19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 (BOS)
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro (BOS)
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j (BOS)
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19j
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j No PIC (BOS)
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jNoPIC
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro (BOS)
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro (BOS)
::: pyasic.miners.antminer.bosminer.X19.S19.BOSMinerS19jPro
handler: python
options:
show_root_heading: false
heading_level: 4
## T19 (BOS)
::: pyasic.miners.antminer.bosminer.X19.T19.BOSMinerT19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 (VNish)
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 No PIC (VNish)
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19NoPIC
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro (VNish)
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j (VNish)
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19j
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro (VNish)
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19jPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19a (VNish)
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19a
handler: python
options:
show_root_heading: false
heading_level: 4
## S19a Pro (VNish)
::: pyasic.miners.antminer.vnish.X19.S19.VNishS19aPro
handler: python
options:
show_root_heading: false
heading_level: 4
## T19 (VNish)
::: pyasic.miners.antminer.vnish.X19.T19.VNishT19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 (ePIC)
::: pyasic.miners.antminer.epic.X19.S19.ePICS19
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 Pro (ePIC)
::: pyasic.miners.antminer.epic.X19.S19.ePICS19Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j (ePIC)
::: pyasic.miners.antminer.epic.X19.S19.ePICS19j
handler: python
options:
show_root_heading: false
heading_level: 4
## S19j Pro (ePIC)
::: pyasic.miners.antminer.epic.X19.S19.ePICS19jPro
handler: python
options:
show_root_heading: false
heading_level: 4
## S19 XP (ePIC)
::: pyasic.miners.antminer.epic.X19.S19.ePICS19XP
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,31 @@
# pyasic
## X3 Models
## D3
::: pyasic.miners.antminer.cgminer.X3.D3.CGMinerD3
handler: python
options:
show_root_heading: false
heading_level: 4
## HS3
::: pyasic.miners.antminer.bmminer.X3.HS3.BMMinerHS3
handler: python
options:
show_root_heading: false
heading_level: 4
## L3+
::: pyasic.miners.antminer.bmminer.X3.L3.BMMinerL3Plus
handler: python
options:
show_root_heading: false
heading_level: 4
## L3+ (VNish)
::: pyasic.miners.antminer.vnish.X3.L3.VnishL3Plus
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,10 @@
# pyasic
## X5 Models
## DR5
::: pyasic.miners.antminer.cgminer.X5.DR5.CGMinerDR5
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,10 @@
# pyasic
## X7 Models
## L7
::: pyasic.miners.antminer.bmminer.X7.L7.BMMinerL7
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,59 @@
# pyasic
## X9 Models
## E9Pro
::: pyasic.miners.antminer.bmminer.X9.E9.BMMinerE9Pro
handler: python
options:
show_root_heading: false
heading_level: 4
## S9
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9
handler: python
options:
show_root_heading: false
heading_level: 4
## S9i
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9i
handler: python
options:
show_root_heading: false
heading_level: 4
## S9j
::: pyasic.miners.antminer.bmminer.X9.S9.BMMinerS9j
handler: python
options:
show_root_heading: false
heading_level: 4
## T9
::: pyasic.miners.antminer.bmminer.X9.T9.BMMinerT9
handler: python
options:
show_root_heading: false
heading_level: 4
## S9 (BOS)
::: pyasic.miners.antminer.bosminer.X9.S9.BOSMinerS9
handler: python
options:
show_root_heading: false
heading_level: 4
## T9 (Hiveon)
::: pyasic.miners.antminer.hiveon.X9.T9.HiveonT9
handler: python
options:
show_root_heading: false
heading_level: 4
## S9 (LuxOS)
::: pyasic.miners.antminer.luxos.X9.S9.LUXMinerS9
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,24 @@
# pyasic
## A10X Models
## Avalon 1026
::: pyasic.miners.avalonminer.cgminer.A10X.A1026.CGMinerAvalon1026
handler: python
options:
show_root_heading: false
heading_level: 4
## Avalon 1047
::: pyasic.miners.avalonminer.cgminer.A10X.A1047.CGMinerAvalon1047
handler: python
options:
show_root_heading: false
heading_level: 4
## Avalon 1066
::: pyasic.miners.avalonminer.cgminer.A10X.A1066.CGMinerAvalon1066
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,10 @@
# pyasic
## A11X Models
## Avalon 1166 Pro
::: pyasic.miners.avalonminer.cgminer.A11X.A1166.CGMinerAvalon1166Pro
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,10 @@
# pyasic
## A12X Models
## Avalon 1246
::: pyasic.miners.avalonminer.cgminer.A12X.A1246.CGMinerAvalon1246
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,24 @@
# pyasic
## A7X Models
## Avalon 721
::: pyasic.miners.avalonminer.cgminer.A7X.A721.CGMinerAvalon721
handler: python
options:
show_root_heading: false
heading_level: 4
## Avalon 741
::: pyasic.miners.avalonminer.cgminer.A7X.A741.CGMinerAvalon741
handler: python
options:
show_root_heading: false
heading_level: 4
## Avalon 761
::: pyasic.miners.avalonminer.cgminer.A7X.A761.CGMinerAvalon761
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,24 @@
# pyasic
## A8X Models
## Avalon 821
::: pyasic.miners.avalonminer.cgminer.A8X.A821.CGMinerAvalon821
handler: python
options:
show_root_heading: false
heading_level: 4
## Avalon 841
::: pyasic.miners.avalonminer.cgminer.A8X.A841.CGMinerAvalon841
handler: python
options:
show_root_heading: false
heading_level: 4
## Avalon 851
::: pyasic.miners.avalonminer.cgminer.A8X.A851.CGMinerAvalon851
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,10 @@
# pyasic
## A9X Models
## Avalon 921
::: pyasic.miners.avalonminer.cgminer.A9X.A921.CGMinerAvalon921
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,8 @@
# pyasic
## BFGMiner Backend
::: pyasic.miners.backends.bfgminer.BFGMiner
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,8 @@
# pyasic
## BMMiner Backend
::: pyasic.miners.backends.bmminer.BMMiner
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,16 @@
# pyasic
## BOSMiner Backend
::: pyasic.miners.backends.braiins_os.BOSMiner
handler: python
options:
show_root_heading: false
heading_level: 4
## BOSer Backend
::: pyasic.miners.backends.braiins_os.BOSer
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,8 @@
# pyasic
## BTMiner Backend
::: pyasic.miners.backends.btminer.BTMiner
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,8 @@
# pyasic
## CGMiner Backend
::: pyasic.miners.backends.cgminer.CGMiner
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,8 @@
# pyasic
## ePIC Backend
::: pyasic.miners.backends.epic.ePIC
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,8 @@
# pyasic
## Hiveon Backend
::: pyasic.miners.backends.hiveon.Hiveon
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,8 @@
# pyasic
## LUXMiner Backend
::: pyasic.miners.backends.luxminer.LUXMiner
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,8 @@
# pyasic
## VNish Backend
::: pyasic.miners.backends.vnish.VNish
handler: python
options:
show_root_heading: false
heading_level: 4

17
docs/miners/base_miner.md Normal file
View File

@@ -0,0 +1,17 @@
# pyasic
## Base Miner
[`BaseMiner`][pyasic.miners.base.BaseMiner] is the basis for all miner classes, they all subclass (usually indirectly) from this class.
This class inherits from the [`MinerProtocol`][pyasic.miners.base.MinerProtocol], which outlines functionality for miners.
You may not instantiate this class on its own, only subclass from it.
::: pyasic.miners.base.BaseMiner
handler: python
options:
heading_level: 4
::: pyasic.miners.base.MinerProtocol
handler: python
options:
heading_level: 4

91
docs/miners/functions.md Normal file
View File

@@ -0,0 +1,91 @@
## Control functionality
### Check Light
::: pyasic.miners.base.MinerProtocol.check_light
handler: python
options:
heading_level: 4
### Fault Light Off
::: pyasic.miners.base.MinerProtocol.fault_light_off
handler: python
options:
heading_level: 4
### Fault Light On
::: pyasic.miners.base.MinerProtocol.fault_light_on
handler: python
options:
heading_level: 4
### Get Config
::: pyasic.miners.base.MinerProtocol.get_config
handler: python
options:
heading_level: 4
### Get Data
::: pyasic.miners.base.MinerProtocol.get_data
handler: python
options:
heading_level: 4
### Get Errors
::: pyasic.miners.base.MinerProtocol.get_errors
handler: python
options:
heading_level: 4
### Get Hostname
::: pyasic.miners.base.MinerProtocol.get_hostname
handler: python
options:
heading_level: 4
### Get Model
::: pyasic.miners.base.MinerProtocol.get_model
handler: python
options:
heading_level: 4
### Reboot
::: pyasic.miners.base.MinerProtocol.reboot
handler: python
options:
heading_level: 4
### Restart Backend
::: pyasic.miners.base.MinerProtocol.restart_backend
handler: python
options:
heading_level: 4
### Stop Mining
::: pyasic.miners.base.MinerProtocol.stop_mining
handler: python
options:
heading_level: 4
### Resume Mining
::: pyasic.miners.base.MinerProtocol.resume_mining
handler: python
options:
heading_level: 4
### Is Mining
::: pyasic.miners.base.MinerProtocol.is_mining
handler: python
options:
heading_level: 4
### Send Config
::: pyasic.miners.base.MinerProtocol.send_config
handler: python
options:
heading_level: 4
### Set Power Limit
::: pyasic.miners.base.MinerProtocol.set_power_limit
handler: python
options:
heading_level: 4

View File

@@ -0,0 +1,23 @@
# pyasic
## X5 Models
## CK5
::: pyasic.miners.goldshell.bfgminer.X5.CK5.GoldshellCK5
handler: python
options:
show_root_heading: false
heading_level: 4
## HS5
::: pyasic.miners.goldshell.bfgminer.X5.HS5.GoldshellHS5
handler: python
options:
show_root_heading: false
heading_level: 4
## KD5
::: pyasic.miners.goldshell.bfgminer.X5.KD5.GoldshellKD5
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,9 @@
# pyasic
## XMax Models
## KD Max
::: pyasic.miners.goldshell.bfgminer.XMax.KDMax.KDMax
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,9 @@
# pyasic
## A10X Models
## A10X
::: pyasic.miners.innosilicon.cgminer.A10X.A10X.InnosiliconA10X
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,9 @@
# pyasic
## T3X Models
## T3H+
::: pyasic.miners.innosilicon.cgminer.T3X.T3H.InnosiliconT3HPlus
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,36 @@
# 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.
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()`.
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()`.
::: pyasic.miners.factory.MinerFactory
handler: python
options:
show_root_heading: false
heading_level: 4
<br>
## Get Miner
::: pyasic.miners.get_miner
handler: python
options:
show_root_heading: false
heading_level: 4
<br>
## AnyMiner
::: pyasic.miners.base.AnyMiner
handler: python
options:
show_root_heading: false
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],
and is used to specify a function returning some arbitrary type of miner class instance.

View File

@@ -0,0 +1,483 @@
# pyasic
## Supported Miners
Supported miner types are here on this list. If your miner (or miner version) is not on this list, please feel free to [open an issue on GitHub](https://github.com/UpstreamData/pyasic/issues) to get it added.
##### pyasic currently supports the following miners and subtypes:
<style>
details {
margin:0px;
padding-top:0px;
padding-bottom:0px;
}
</style>
<details>
<summary>Stock Firmware Antminers:</summary>
<ul>
<details>
<summary>X3 Series:</summary>
<ul>
<li><a href="../antminer/X3#d3">D3</a></li>
<li><a href="../antminer/X3#hs3">HS3</a></li>
<li><a href="../antminer/X3#l3_1">L3+</a></li>
</ul>
</details>
<details>
<summary>X5 Series:</summary>
<ul>
<li><a href="../antminer/X5#dr5">DR5</a></li>
</ul>
</details>
<details>
<summary>X7 Series:</summary>
<ul>
<li><a href="../antminer/X7#l7">L7</a></li>
</ul>
</details>
<details>
<summary>X9 Series:</summary>
<ul>
<li><a href="../antminer/X9#e9pro">E9Pro</a></li>
<li><a href="../antminer/X9#s9">S9</a></li>
<li><a href="../antminer/X9#s9i">S9i</a></li>
<li><a href="../antminer/X9#s9j">S9j</a></li>
<li><a href="../antminer/X9#t9">T9</a></li>
</ul>
</details>
<details>
<summary>X15 Series:</summary>
<ul>
<li><a href="../antminer/X15#z15">Z15</a></li>
</ul>
</details>
<details>
<summary>X17 Series:</summary>
<ul>
<li><a href="../antminer/X17#s17">S17</a></li>
<li><a href="../antminer/X17#s17_1">S17+</a></li>
<li><a href="../antminer/X17#s17-pro">S17 Pro</a></li>
<li><a href="../antminer/X17#s17e">S17e</a></li>
<li><a href="../antminer/X17#t17">T17</a></li>
<li><a href="../antminer/X17#t17_1">T17+</a></li>
<li><a href="../antminer/X17#t17e">T17e</a></li>
</ul>
</details>
<details>
<summary>X19 Series:</summary>
<ul>
<li><a href="../antminer/X19#s19">S19</a></li>
<li><a href="../antminer/X19#s19l">S19L</a></li>
<li><a href="../antminer/X19#s19-pro">S19 Pro</a></li>
<li><a href="../antminer/X19#s19j">S19j</a></li>
<li><a href="../antminer/X19#s19i">S19i</a></li>
<li><a href="../antminer/X19#s19_1">S19+</a></li>
<li><a href="../antminer/X19#s19j-no-pic">S19j No PIC</a></li>
<li><a href="../antminer/X19#s19-pro_1">S19 Pro+</a></li>
<li><a href="../antminer/X19#s19j-pro">S19j Pro</a></li>
<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#t19">T19</a></li>
</ul>
</details>
</ul>
</details>
<details>
<summary>Stock Firmware Whatsminers:</summary>
<ul>
<details>
<summary>M2X Series:</summary>
<ul>
<li><a href="../whatsminer/M2X#m20-v10">M20 V10</a></li>
<li><a href="../whatsminer/M2X#m20s-v10">M20S V10</a></li>
<li><a href="../whatsminer/M2X#m20s-v20">M20S V20</a></li>
<li><a href="../whatsminer/M2X#m20s-v30">M20S V30</a></li>
<li><a href="../whatsminer/M2X#m20p-v10">M20P V10</a></li>
<li><a href="../whatsminer/M2X#m20p-v30">M20P V30</a></li>
<li><a href="../whatsminer/M2X#m20s_1-v30">M20S+ V30</a></li>
<li><a href="../whatsminer/M2X#m21-v10">M21 V10</a></li>
<li><a href="../whatsminer/M2X#m21s-v20">M21S V20</a></li>
<li><a href="../whatsminer/M2X#m21s-v60">M21S V60</a></li>
<li><a href="../whatsminer/M2X#m21s-v70">M21S V70</a></li>
<li><a href="../whatsminer/M2X#m21s_1-v20">M21S+ V20</a></li>
<li><a href="../whatsminer/M2X#m29-v10">M29 V10</a></li>
</ul>
</details>
<details>
<summary>M3X Series:</summary>
<ul>
<li><a href="../whatsminer/M3X#m30-v10">M30 V10</a></li>
<li><a href="../whatsminer/M3X#m30-v20">M30 V20</a></li>
<li><a href="../whatsminer/M3X#m30k-v10">M30K V10</a></li>
<li><a href="../whatsminer/M3X#m30l-v10">M30L V10</a></li>
<li><a href="../whatsminer/M3X#m30s-v10">M30S V10</a></li>
<li><a href="../whatsminer/M3X#m30s-v20">M30S V20</a></li>
<li><a href="../whatsminer/M3X#m30s-v30">M30S V30</a></li>
<li><a href="../whatsminer/M3X#m30s-v40">M30S V40</a></li>
<li><a href="../whatsminer/M3X#m30s-v50">M30S V50</a></li>
<li><a href="../whatsminer/M3X#m30s-v60">M30S V60</a></li>
<li><a href="../whatsminer/M3X#m30s-v70">M30S V70</a></li>
<li><a href="../whatsminer/M3X#m30s-v80">M30S V80</a></li>
<li><a href="../whatsminer/M3X#m30s-ve10">M30S VE10</a></li>
<li><a href="../whatsminer/M3X#m30s-ve20">M30S VE20</a></li>
<li><a href="../whatsminer/M3X#m30s-ve30">M30S VE30</a></li>
<li><a href="../whatsminer/M3X#m30s-ve40">M30S VE40</a></li>
<li><a href="../whatsminer/M3X#m30s-ve50">M30S VE50</a></li>
<li><a href="../whatsminer/M3X#m30s-ve60">M30S VE60</a></li>
<li><a href="../whatsminer/M3X#m30s-ve70">M30S VE70</a></li>
<li><a href="../whatsminer/M3X#m30s-vf10">M30S VF10</a></li>
<li><a href="../whatsminer/M3X#m30s-vf20">M30S VF20</a></li>
<li><a href="../whatsminer/M3X#m30s-vf30">M30S VF30</a></li>
<li><a href="../whatsminer/M3X#m30s-vg10">M30S VG10</a></li>
<li><a href="../whatsminer/M3X#m30s-vg20">M30S VG20</a></li>
<li><a href="../whatsminer/M3X#m30s-vg30">M30S VG30</a></li>
<li><a href="../whatsminer/M3X#m30s-vg40">M30S VG40</a></li>
<li><a href="../whatsminer/M3X#m30s-vh10">M30S VH10</a></li>
<li><a href="../whatsminer/M3X#m30s-vh20">M30S VH20</a></li>
<li><a href="../whatsminer/M3X#m30s-vh30">M30S VH30</a></li>
<li><a href="../whatsminer/M3X#m30s-vh40">M30S VH40</a></li>
<li><a href="../whatsminer/M3X#m30s-vh50">M30S VH50</a></li>
<li><a href="../whatsminer/M3X#m30s-vh60">M30S VH60</a></li>
<li><a href="../whatsminer/M3X#m30s-vi20">M30S VI20</a></li>
<li><a href="../whatsminer/M3X#m30s_1-v10">M30S+ V10</a></li>
<li><a href="../whatsminer/M3X#m30s_1-v20">M30S+ V20</a></li>
<li><a href="../whatsminer/M3X#m30s_1-v30">M30S+ V30</a></li>
<li><a href="../whatsminer/M3X#m30s_1-v40">M30S+ V40</a></li>
<li><a href="../whatsminer/M3X#m30s_1-v50">M30S+ V50</a></li>
<li><a href="../whatsminer/M3X#m30s_1-v60">M30S+ V60</a></li>
<li><a href="../whatsminer/M3X#m30s_1-v70">M30S+ V70</a></li>
<li><a href="../whatsminer/M3X#m30s_1-v80">M30S+ V80</a></li>
<li><a href="../whatsminer/M3X#m30s_1-v90">M30S+ V90</a></li>
<li><a href="../whatsminer/M3X#m30s_1-v100">M30S+ V100</a></li>
<li><a href="../whatsminer/M3X#m30s_1-ve30">M30S+ VE30</a></li>
<li><a href="../whatsminer/M3X#m30s_1-ve40">M30S+ VE40</a></li>
<li><a href="../whatsminer/M3X#m30s_1-ve50">M30S+ VE50</a></li>
<li><a href="../whatsminer/M3X#m30s_1-ve60">M30S+ VE60</a></li>
<li><a href="../whatsminer/M3X#m30s_1-ve70">M30S+ VE70</a></li>
<li><a href="../whatsminer/M3X#m30s_1-ve80">M30S+ VE80</a></li>
<li><a href="../whatsminer/M3X#m30s_1-ve90">M30S+ VE90</a></li>
<li><a href="../whatsminer/M3X#m30s_1-ve100">M30S+ VE100</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vf20">M30S+ VF20</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vf30">M30S+ VF30</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vg20">M30S+ VG20</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vg30">M30S+ VG30</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vg40">M30S+ VG40</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vg50">M30S+ VG50</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vg60">M30S+ VG60</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vh10">M30S+ VH10</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vh20">M30S+ VH20</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vh30">M30S+ VH30</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vh40">M30S+ VH40</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vh50">M30S+ VH50</a></li>
<li><a href="../whatsminer/M3X#m30s_1-vh60">M30S+ VH60</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-v10">M30S++ V10</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-v20">M30S++ V20</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-ve30">M30S++ VE30</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-ve40">M30S++ VE40</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-ve50">M30S++ VE50</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vf40">M30S++ VF40</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vg30">M30S++ VG30</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vg40">M30S++ VG40</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vg50">M30S++ VG50</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vh10">M30S++ VH10</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vh20">M30S++ VH20</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vh30">M30S++ VH30</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vh40">M30S++ VH40</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vh50">M30S++ VH50</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vh60">M30S++ VH60</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vh70">M30S++ VH70</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vh80">M30S++ VH80</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vh90">M30S++ VH90</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vh100">M30S++ VH100</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vj20">M30S++ VJ20</a></li>
<li><a href="../whatsminer/M3X#m30s_1_1-vj30">M30S++ VJ30</a></li>
<li><a href="../whatsminer/M3X#m31-v10">M31 V10</a></li>
<li><a href="../whatsminer/M3X#m31-v20">M31 V20</a></li>
<li><a href="../whatsminer/M3X#m31h-v10">M31H V10</a></li>
<li><a href="../whatsminer/M3X#m31h-v40">M31H V40</a></li>
<li><a href="../whatsminer/M3X#m30l-v10">M30L V10</a></li>
<li><a href="../whatsminer/M3X#m31s-v10">M31S V10</a></li>
<li><a href="../whatsminer/M3X#m31s-v20">M31S V20</a></li>
<li><a href="../whatsminer/M3X#m31s-v30">M31S V30</a></li>
<li><a href="../whatsminer/M3X#m31s-v40">M31S V40</a></li>
<li><a href="../whatsminer/M3X#m31s-v50">M31S V50</a></li>
<li><a href="../whatsminer/M3X#m31s-v60">M31S V60</a></li>
<li><a href="../whatsminer/M3X#m31s-v70">M31S V70</a></li>
<li><a href="../whatsminer/M3X#m31s-v80">M31S V80</a></li>
<li><a href="../whatsminer/M3X#m31s-v90">M31S V90</a></li>
<li><a href="../whatsminer/M3X#m31s-ve10">M31S VE10</a></li>
<li><a href="../whatsminer/M3X#m31s-ve20">M31S VE20</a></li>
<li><a href="../whatsminer/M3X#m31s-ve30">M31S VE30</a></li>
<li><a href="../whatsminer/M3X#m31se-v10">M31SE V10</a></li>
<li><a href="../whatsminer/M3X#m31se-v20">M31SE V20</a></li>
<li><a href="../whatsminer/M3X#m31se-v30">M31SE V30</a></li>
<li><a href="../whatsminer/M3X#m31s_1-v10">M31S+ V10</a></li>
<li><a href="../whatsminer/M3X#m31s_1-v20">M31S+ V20</a></li>
<li><a href="../whatsminer/M3X#m31s_1-v30">M31S+ V30</a></li>
<li><a href="../whatsminer/M3X#m31s_1-v40">M31S+ V40</a></li>
<li><a href="../whatsminer/M3X#m31s_1-v50">M31S+ V50</a></li>
<li><a href="../whatsminer/M3X#m31s_1-v60">M31S+ V60</a></li>
<li><a href="../whatsminer/M3X#m31s_1-v80">M31S+ V80</a></li>
<li><a href="../whatsminer/M3X#m31s_1-v90">M31S+ V90</a></li>
<li><a href="../whatsminer/M3X#m31s_1-v100">M31S+ V100</a></li>
<li><a href="../whatsminer/M3X#m31s_1-ve10">M31S+ VE10</a></li>
<li><a href="../whatsminer/M3X#m31s_1-ve20">M31S+ VE20</a></li>
<li><a href="../whatsminer/M3X#m31s_1-ve30">M31S+ VE30</a></li>
<li><a href="../whatsminer/M3X#m31s_1-ve40">M31S+ VE40</a></li>
<li><a href="../whatsminer/M3X#m31s_1-ve50">M31S+ VE50</a></li>
<li><a href="../whatsminer/M3X#m31s_1-ve60">M31S+ VE60</a></li>
<li><a href="../whatsminer/M3X#m31s_1-ve80">M31S+ VE80</a></li>
<li><a href="../whatsminer/M3X#m31s_1-vf20">M31S+ VF20</a></li>
<li><a href="../whatsminer/M3X#m31s_1-vf30">M31S+ VF30</a></li>
<li><a href="../whatsminer/M3X#m31s_1-vg20">M31S+ VG20</a></li>
<li><a href="../whatsminer/M3X#m31s_1-vg30">M31S+ VG30</a></li>
<li><a href="../whatsminer/M3X#m32-v10">M32 V10</a></li>
<li><a href="../whatsminer/M3X#m32-v20">M32 V20</a></li>
<li><a href="../whatsminer/M3X#m33-v10">M33 V10</a></li>
<li><a href="../whatsminer/M3X#m33-v20">M33 V20</a></li>
<li><a href="../whatsminer/M3X#m33-v30">M33 V30</a></li>
<li><a href="../whatsminer/M3X#m33s-vg30">M33S VG30</a></li>
<li><a href="../whatsminer/M3X#m33s_1-vg20">M33S+ VG20</a></li>
<li><a href="../whatsminer/M3X#m33s_1-vh20">M33S+ VH20</a></li>
<li><a href="../whatsminer/M3X#m33s_1-vh30">M33S+ VH30</a></li>
<li><a href="../whatsminer/M3X#m33s_1_1-vh20">M33S++ VH20</a></li>
<li><a href="../whatsminer/M3X#m33s_1_1-vh30">M33S++ VH30</a></li>
<li><a href="../whatsminer/M3X#m33s_1_1-vg40">M33S++ VG40</a></li>
<li><a href="../whatsminer/M3X#m34s_1-ve10">M34S+ VE10</a></li>
<li><a href="../whatsminer/M3X#m36s-ve10">M36S VE10</a></li>
<li><a href="../whatsminer/M3X#m36s_1-vg30">M36S+ VG30</a></li>
<li><a href="../whatsminer/M3X#m36s_1_1-vh30">M36S++ VH30</a></li>
<li><a href="../whatsminer/M3X#m39-v10">M39 V10</a></li>
<li><a href="../whatsminer/M3X#m39-v20">M39 V20</a></li>
<li><a href="../whatsminer/M3X#m39-v30">M39 V30</a></li>
</ul>
</details>
<details>
<summary>M5X Series:</summary>
<ul>
<li><a href="../whatsminer/M5X#m50-ve30">M50 VE30</a></li>
<li><a href="../whatsminer/M5X#m50-vg30">M50 VG30</a></li>
<li><a href="../whatsminer/M5X#m50-vh10">M50 VH10</a></li>
<li><a href="../whatsminer/M5X#m50-vh20">M50 VH20</a></li>
<li><a href="../whatsminer/M5X#m50-vh30">M50 VH30</a></li>
<li><a href="../whatsminer/M5X#m50-vh40">M50 VH40</a></li>
<li><a href="../whatsminer/M5X#m50-vh50">M50 VH50</a></li>
<li><a href="../whatsminer/M5X#m50-vh60">M50 VH60</a></li>
<li><a href="../whatsminer/M5X#m50-vh70">M50 VH70</a></li>
<li><a href="../whatsminer/M5X#m50-vh80">M50 VH80</a></li>
<li><a href="../whatsminer/M5X#m50-vj10">M50 VJ10</a></li>
<li><a href="../whatsminer/M5X#m50-vj20">M50 VJ20</a></li>
<li><a href="../whatsminer/M5X#m50-vj30">M50 VJ30</a></li>
<li><a href="../whatsminer/M5X#m50s-vj10">M50S VJ10</a></li>
<li><a href="../whatsminer/M5X#m50s-vj20">M50S VJ20</a></li>
<li><a href="../whatsminer/M5X#m50s-vj30">M50S VJ30</a></li>
<li><a href="../whatsminer/M5X#m50s-vh10">M50S VH10</a></li>
<li><a href="../whatsminer/M5X#m50s-vh20">M50S VH20</a></li>
<li><a href="../whatsminer/M5X#m50s-vh30">M50S VH30</a></li>
<li><a href="../whatsminer/M5X#m50s-vh40">M50S VH40</a></li>
<li><a href="../whatsminer/M5X#m50s-vh50">M50S VH50</a></li>
<li><a href="../whatsminer/M5X#m50s_1-vh30">M50S+ VH30</a></li>
<li><a href="../whatsminer/M5X#m50s_1-vh40">M50S+ VH40</a></li>
<li><a href="../whatsminer/M5X#m50s_1-vj30">M50S+ VJ30</a></li>
<li><a href="../whatsminer/M5X#m50s_1-vk20">M50S+ VK20</a></li>
<li><a href="../whatsminer/M5X#m50s_1_1-vk10">M50S++ VK10</a></li>
<li><a href="../whatsminer/M5X#m50s_1_1-vk20">M50S++ VK20</a></li>
<li><a href="../whatsminer/M5X#m50s_1_1-vk30">M50S++ VK30</a></li>
<li><a href="../whatsminer/M5X#m53-vh30">M53 VH30</a></li>
<li><a href="../whatsminer/M5X#m53s-vh30">M53S VH30</a></li>
<li><a href="../whatsminer/M5X#m53s_1-vj30">M53S+ VJ30</a></li>
<li><a href="../whatsminer/M5X#m56-vh30">M56 VH30</a></li>
<li><a href="../whatsminer/M5X#m56s-vh30">M56S VH30</a></li>
<li><a href="../whatsminer/M5X#m56s_1-vj30">M56S+ VJ30</a></li>
<li><a href="../whatsminer/M5X#m59-vh30">M59 VH30</a></li>
</ul>
</details>
</ul>
</details>
<details>
<summary>Stock Firmware Avalonminers:</summary>
<ul>
<details>
<summary>A7X Series:</summary>
<ul>
<li><a href="../avalonminer/A7X#avalon-721">Avalon 721</a></li>
<li><a href="../avalonminer/A7X#avalon-741">Avalon 741</a></li>
<li><a href="../avalonminer/A7X#avalon-761">Avalon 761</a></li>
</ul>
</details>
<details>
<summary>A8X Series:</summary>
<ul>
<li><a href="../avalonminer/A8X#avalon-821">Avalon 821</a></li>
<li><a href="../avalonminer/A8X#avalon-841">Avalon 841</a></li>
<li><a href="../avalonminer/A8X#avalon-851">Avalon 851</a></li>
</ul>
</details>
<details>
<summary>A9X Series:</summary>
<ul>
<li><a href="../avalonminer/A9X#avalon-921">Avalon 921</a></li>
</ul>
</details>
<details>
<summary>A10X Series:</summary>
<ul>
<li><a href="../avalonminer/A10X#avalon-1026">Avalon 1026</a></li>
<li><a href="../avalonminer/A10X#avalon-1047">Avalon 1047</a></li>
<li><a href="../avalonminer/A10X#avalon-1066">Avalon 1066</a></li>
</ul>
</details>
<details>
<summary>A11X Series:</summary>
<ul>
<li><a href="../avalonminer/A11X#avalon-1166-pro">Avalon 1166 Pro</a></li>
</ul>
</details>
<details>
<summary>A12X Series:</summary>
<ul>
<li><a href="../avalonminer/A12X#avalon-1246">Avalon 1246</a></li>
</ul>
</details>
</ul>
</details>
<details>
<summary>Stock Firmware Innosilicons:</summary>
<ul>
<details>
<summary>T3X Series:</summary>
<ul>
<li><a href="../innosilicon/T3X#t3h_1">T3H+</a></li>
</ul>
</details>
<details>
<summary>A10X Series:</summary>
<ul>
<li><a href="../innosilicon/A10X#a10x">A10X</a></li>
</ul>
</details>
</ul>
</details>
<details>
<summary>Stock Firmware Goldshells:</summary>
<ul>
<details>
<summary>X5 Series:</summary>
<ul>
<li><a href="../goldshell/X5#ck5">CK5</a></li>
<li><a href="../goldshell/X5#hs5">HS5</a></li>
<li><a href="../goldshell/X5#kd5">KD5</a></li>
</ul>
</details>
<details>
<summary>XMax Series:</summary>
<ul>
<li><a href="../goldshell/XMax#kd-max">KD Max</a></li>
</ul>
</details>
</ul>
</details>
<details>
<summary>BOS+ Firmware Miners:</summary>
<ul>
<details>
<summary>X9 Series:</summary>
<ul>
<li><a href="../antminer/X9#s9-bos">S9 (BOS)</a></li>
</ul>
</details>
<details>
<summary>X17 Series:</summary>
<ul>
<li><a href="../antminer/X17#s17-bos">S17 (BOS)</a></li>
<li><a href="../antminer/X17#s17_1-bos">S17+ (BOS)</a></li>
<li><a href="../antminer/X17#s17-pro-bos">S17 Pro (BOS)</a></li>
<li><a href="../antminer/X17#s17e-bos">S17e (BOS)</a></li>
<li><a href="../antminer/X17#t17-bos">T17 (BOS)</a></li>
<li><a href="../antminer/X17#t17_1-bos">T17+ (BOS)</a></li>
<li><a href="../antminer/X17#t17e-bos">T17e (BOS)</a></li>
</ul>
</details>
<details>
<summary>X19 Series:</summary>
<ul>
<li><a href="../antminer/X19#s19-bos">S19 (BOS)</a></li>
<li><a href="../antminer/X19#s19-pro-bos">S19 Pro (BOS)</a></li>
<li><a href="../antminer/X19#s19j-bos">S19j (BOS)</a></li>
<li><a href="../antminer/X19#s19j-no-pic-bos">S19j No PIC (BOS)</a></li>
<li><a href="../antminer/X19#s19j-pro-bos">S19j Pro (BOS)</a></li>
<li><a href="../antminer/X19#s19j-pro-bos">S19j Pro (BOS)</a></li>
<li><a href="../antminer/X19#t19-bos">T19 (BOS)</a></li>
</ul>
</details>
</ul>
</details>
<details>
<summary>Vnish Firmware Miners:</summary>
<ul>
<details>
<summary>X3 Series:</summary>
<ul>
<li><a href="../antminer/X3#l3_1-vnish">L3+ (VNish)</a></li>
</ul>
</details>
<details>
<summary>X17 Series:</summary>
<ul>
<li><a href="../antminer/X17#s17_1-vnish">S17+ (VNish)</a></li>
<li><a href="../antminer/X17#s17-pro-vnish">S17 Pro (VNish)</a></li>
</ul>
</details>
<details>
<summary>X19 Series:</summary>
<ul>
<li><a href="../antminer/X19#s19-vnish">S19 (VNish)</a></li>
<li><a href="../antminer/X19#s19-no-pic-vnish">S19 No PIC (VNish)</a></li>
<li><a href="../antminer/X19#s19-pro-vnish">S19 Pro (VNish)</a></li>
<li><a href="../antminer/X19#s19j-vnish">S19j (VNish)</a></li>
<li><a href="../antminer/X19#s19j-pro-vnish">S19j Pro (VNish)</a></li>
<li><a href="../antminer/X19#s19a-vnish">S19a (VNish)</a></li>
<li><a href="../antminer/X19#s19a-pro-vnish">S19a Pro (VNish)</a></li>
<li><a href="../antminer/X19#t19-vnish">T19 (VNish)</a></li>
</ul>
</details>
</ul>
</details>
<details>
<summary>ePIC Firmware Miners:</summary>
<ul>
<details>
<summary>X19 Series:</summary>
<ul>
<li><a href="../antminer/X19#s19-epic">S19 (ePIC)</a></li>
<li><a href="../antminer/X19#s19-pro-epic">S19 Pro (ePIC)</a></li>
<li><a href="../antminer/X19#s19j-epic">S19j (ePIC)</a></li>
<li><a href="../antminer/X19#s19j-pro-epic">S19j Pro (ePIC)</a></li>
<li><a href="../antminer/X19#s19-xp-epic">S19 XP (ePIC)</a></li>
</ul>
</details>
</ul>
</details>
<details>
<summary>HiveOS Firmware Miners:</summary>
<ul>
<details>
<summary>X9 Series:</summary>
<ul>
<li><a href="../antminer/X9#t9-hiveon">T9 (Hiveon)</a></li>
</ul>
</details>
</ul>
</details>
<details>
<summary>LuxOS Firmware Miners:</summary>
<ul>
<details>
<summary>X9 Series:</summary>
<ul>
<li><a href="../antminer/X9#s9-luxos">S9 (LuxOS)</a></li>
</ul>
</details>
</ul>
</details>

View File

@@ -0,0 +1,94 @@
# pyasic
## M2X Models
## M20 V10
::: pyasic.miners.whatsminer.btminer.M2X.M20.BTMinerM20V10
handler: python
options:
show_root_heading: false
heading_level: 4
## M20S V10
::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV10
handler: python
options:
show_root_heading: false
heading_level: 4
## M20S V20
::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV20
handler: python
options:
show_root_heading: false
heading_level: 4
## M20S V30
::: pyasic.miners.whatsminer.btminer.M2X.M20S.BTMinerM20SV30
handler: python
options:
show_root_heading: false
heading_level: 4
## M20P V10
::: pyasic.miners.whatsminer.btminer.M2X.M20P.BTMinerM20PV10
handler: python
options:
show_root_heading: false
heading_level: 4
## M20P V30
::: pyasic.miners.whatsminer.btminer.M2X.M20P.BTMinerM20PV30
handler: python
options:
show_root_heading: false
heading_level: 4
## M20S+ V30
::: pyasic.miners.whatsminer.btminer.M2X.M20S_Plus.BTMinerM20SPlusV30
handler: python
options:
show_root_heading: false
heading_level: 4
## M21 V10
::: pyasic.miners.whatsminer.btminer.M2X.M21.BTMinerM21V10
handler: python
options:
show_root_heading: false
heading_level: 4
## M21S V20
::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV20
handler: python
options:
show_root_heading: false
heading_level: 4
## M21S V60
::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV60
handler: python
options:
show_root_heading: false
heading_level: 4
## M21S V70
::: pyasic.miners.whatsminer.btminer.M2X.M21S.BTMinerM21SV70
handler: python
options:
show_root_heading: false
heading_level: 4
## M21S+ V20
::: pyasic.miners.whatsminer.btminer.M2X.M21S_Plus.BTMinerM21SPlusV20
handler: python
options:
show_root_heading: false
heading_level: 4
## M29 V10
::: pyasic.miners.whatsminer.btminer.M2X.M29.BTMinerM29V10
handler: python
options:
show_root_heading: false
heading_level: 4

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,248 @@
# pyasic
## M5X Models
## M50 VE30
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VE30
handler: python
options:
show_root_heading: false
heading_level: 4
## M50 VG30
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VG30
handler: python
options:
show_root_heading: false
heading_level: 4
## M50 VH10
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH10
handler: python
options:
show_root_heading: false
heading_level: 4
## M50 VH20
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH20
handler: python
options:
show_root_heading: false
heading_level: 4
## M50 VH30
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH30
handler: python
options:
show_root_heading: false
heading_level: 4
## M50 VH40
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH40
handler: python
options:
show_root_heading: false
heading_level: 4
## M50 VH50
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH50
handler: python
options:
show_root_heading: false
heading_level: 4
## M50 VH60
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH60
handler: python
options:
show_root_heading: false
heading_level: 4
## M50 VH70
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH70
handler: python
options:
show_root_heading: false
heading_level: 4
## M50 VH80
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VH80
handler: python
options:
show_root_heading: false
heading_level: 4
## M50 VJ10
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VJ10
handler: python
options:
show_root_heading: false
heading_level: 4
## M50 VJ20
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VJ20
handler: python
options:
show_root_heading: false
heading_level: 4
## M50 VJ30
::: pyasic.miners.whatsminer.btminer.M5X.M50.BTMinerM50VJ30
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S VJ10
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ10
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S VJ20
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ20
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S VJ30
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVJ30
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S VH10
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH10
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S VH20
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH20
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S VH30
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH30
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S VH40
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH40
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S VH50
::: pyasic.miners.whatsminer.btminer.M5X.M50S.BTMinerM50SVH50
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S+ VH30
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVH30
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S+ VH40
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVH40
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S+ VJ30
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVJ30
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S+ VK20
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus.BTMinerM50SPlusVK20
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S++ VK10
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus_Plus.BTMinerM50SPlusPlusVK10
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S++ VK20
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus_Plus.BTMinerM50SPlusPlusVK20
handler: python
options:
show_root_heading: false
heading_level: 4
## M50S++ VK30
::: pyasic.miners.whatsminer.btminer.M5X.M50S_Plus_Plus.BTMinerM50SPlusPlusVK30
handler: python
options:
show_root_heading: false
heading_level: 4
## M53 VH30
::: pyasic.miners.whatsminer.btminer.M5X.M53.BTMinerM53VH30
handler: python
options:
show_root_heading: false
heading_level: 4
## M53S VH30
::: pyasic.miners.whatsminer.btminer.M5X.M53S.BTMinerM53SVH30
handler: python
options:
show_root_heading: false
heading_level: 4
## M53S+ VJ30
::: pyasic.miners.whatsminer.btminer.M5X.M53S_Plus.BTMinerM53SPlusVJ30
handler: python
options:
show_root_heading: false
heading_level: 4
## M56 VH30
::: pyasic.miners.whatsminer.btminer.M5X.M56.BTMinerM56VH30
handler: python
options:
show_root_heading: false
heading_level: 4
## M56S VH30
::: pyasic.miners.whatsminer.btminer.M5X.M56S.BTMinerM56SVH30
handler: python
options:
show_root_heading: false
heading_level: 4
## M56S+ VJ30
::: pyasic.miners.whatsminer.btminer.M5X.M56S_Plus.BTMinerM56SPlusVJ30
handler: python
options:
show_root_heading: false
heading_level: 4
## M59 VH30
::: pyasic.miners.whatsminer.btminer.M5X.M59.BTMinerM59VH30
handler: python
options:
show_root_heading: false
heading_level: 4

View File

@@ -0,0 +1,8 @@
# pyasic
## Miner Network
::: pyasic.network.MinerNetwork
handler: python
options:
show_root_heading: false
heading_level: 4

3
docs/requirements.txt Normal file
View File

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

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

@@ -0,0 +1,27 @@
# pyasic
## Miner APIs
Each miner has a unique 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`.
All 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`.
Use these instead -
#### [BFGMiner API][pyasic.rpc.bfgminer.BFGMinerRPCAPI]
#### [BMMiner API][pyasic.rpc.bmminer.BMMinerRPCAPI]
#### [BOSMiner API][pyasic.rpc.bosminer.BOSMinerRPCAPI]
#### [BTMiner API][pyasic.rpc.btminer.BTMinerRPCAPI]
#### [CGMiner API][pyasic.rpc.cgminer.CGMinerRPCAPI]
#### [LUXMiner API][pyasic.rpc.luxminer.LUXMinerRPCAPI]
#### [Unknown API][pyasic.rpc.unknown.UnknownRPCAPI]
<br>
## BaseMinerRPCAPI
::: pyasic.rpc.base.BaseMinerRPCAPI
handler: python
options:
heading_level: 4

7
docs/rpc/bfgminer.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## BFGMinerRPCAPI
::: pyasic.rpc.bfgminer.BFGMinerRPCAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/rpc/bmminer.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## BMMinerRPCAPI
::: pyasic.rpc.bmminer.BMMinerRPCAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/rpc/bosminer.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## BOSMinerRPCAPI
::: pyasic.rpc.bosminer.BOSMinerRPCAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/rpc/btminer.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## BTMinerRPCAPI
::: pyasic.rpc.btminer.BTMinerRPCAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/rpc/cgminer.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## CGMinerRPCAPI
::: pyasic.rpc.cgminer.CGMinerRPCAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/rpc/luxminer.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## LUXMinerRPCAPI
::: pyasic.rpc.luxminer.LUXMinerRPCAPI
handler: python
options:
show_root_heading: false
heading_level: 4

7
docs/rpc/unknown.md Normal file
View File

@@ -0,0 +1,7 @@
# pyasic
## UnknownRPCAPI
::: pyasic.rpc.unknown.UnknownRPCAPI
handler: python
options:
show_root_heading: false
heading_level: 4

36
docs/settings/settings.md Normal file
View File

@@ -0,0 +1,36 @@
# pyasic
## settings
All settings here are global settings for all of pyasic. Set these settings with `update(key, value)`.
Settings options:
- `network_ping_retries`
- `network_ping_timeout`
- `network_scan_threads`
- `factory_get_retries`
- `factory_get_timeout`
- `get_data_retries`
- `api_function_timeout`
- `default_whatsminer_password`
- `default_innosilicon_password`
- `default_antminer_password`
- `default_bosminer_password`
- `default_vnish_password`
- `default_goldshell_password`
- `socket_linger_time`
### get
::: pyasic.settings.get
handler: python
options:
show_root_heading: false
heading_level: 4
### update
::: pyasic.settings.update
handler: python
options:
show_root_heading: false
heading_level: 4

BIN
icon.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

View File

@@ -1,31 +0,0 @@
"""
Make a build of the config tool.
Usage: make_config_tool.py build
The build will show up in the build directory.
"""
import datetime
import sys
import os
from cx_Freeze import setup, Executable
base = None
if sys.platform == "win32":
base = "Win32GUI"
version = datetime.datetime.now()
version = version.strftime("%y.%m.%d")
print(version)
setup(name="UpstreamCFGUtil.exe",
version=version,
description="Upstream Data Config Utility Build",
options={"build_exe": {"build_exe": f"{os.getcwd()}\\build\\UpstreamCFGUtil-{version}-{sys.platform}\\",
"include_files": [os.path.join(os.getcwd(), "settings/settings.toml"),
os.path.join(os.getcwd(), "static/CFG-Util-README.md")],
},
},
executables=[Executable("config_tool.py", base=base, icon="icon.ico", target_name="UpstreamCFGUtil.exe")]
)

View File

@@ -1,14 +0,0 @@
from API.bmminer import BMMinerAPI
from API.bosminer import BOSMinerAPI
from API.cgminer import CGMinerAPI
from API.btminer import BTMinerAPI
from API.unknown import UnknownAPI
import ipaddress
class BaseMiner:
def __init__(self, ip: str, api: BMMinerAPI | BOSMinerAPI | CGMinerAPI | BTMinerAPI | UnknownAPI) -> None:
self.ip = ipaddress.ip_address(ip)
self.api = api
self.api_type = None
self.model = None

View File

@@ -1,11 +0,0 @@
from miners.bmminer import BMMiner
class BMMinerS9(BMMiner):
def __init__(self, ip: str) -> None:
super().__init__(ip)
self.model = "S9"
self.api_type = "BMMiner"
def __repr__(self) -> str:
return f"BMMinerS9: {str(self.ip)}"

View File

@@ -1,11 +0,0 @@
from miners.bosminer import BOSminer
class BOSMinerS9(BOSminer):
def __init__(self, ip: str) -> None:
super().__init__(ip)
self.model = "S9"
self.api_type = "BOSMiner"
def __repr__(self) -> str:
return f"BOSminerS9: {str(self.ip)}"

View File

@@ -1,11 +0,0 @@
from miners.cgminer import CGMiner
class CGMinerS9(CGMiner):
def __init__(self, ip: str) -> None:
super().__init__(ip)
self.model = "S9"
self.api_type = "CGMiner"
def __repr__(self) -> str:
return f"CGMinerS9: {str(self.ip)}"

View File

@@ -1,9 +0,0 @@
from miners.bmminer import BMMiner
class BMMinerX17(BMMiner):
def __init__(self, ip: str) -> None:
super().__init__(ip)
def __repr__(self) -> str:
return f"CGMinerX17: {str(self.ip)}"

View File

@@ -1,10 +0,0 @@
from miners.bosminer import BOSminer
class BOSMinerX17(BOSminer):
def __init__(self, ip: str) -> None:
super().__init__(ip)
self.api_type = "BOSMiner"
def __repr__(self) -> str:
return f"BOSminerX17: {str(self.ip)}"

View File

@@ -1,10 +0,0 @@
from miners.cgminer import CGMiner
class CGMinerX17(CGMiner):
def __init__(self, ip: str) -> None:
super().__init__(ip)
self.api_type = "CGMiner"
def __repr__(self) -> str:
return f"CGMinerX17: {str(self.ip)}"

View File

@@ -1,18 +0,0 @@
from miners.bmminer import BMMiner
class BMMinerX19(BMMiner):
def __init__(self, ip: str) -> None:
super().__init__(ip)
def __repr__(self) -> str:
return f"BMMinerX19: {str(self.ip)}"
async def get_model(self):
if self.model:
return self.model
version_data = await self.api.version()
if version_data:
self.model = version_data["VERSION"][0]["Type"].replace("Antminer ", "")
return self.model
return None

View File

@@ -1,19 +0,0 @@
from miners.cgminer import CGMiner
class CGMinerX19(CGMiner):
def __init__(self, ip: str) -> None:
super().__init__(ip)
self.api_type = "CGMiner"
def __repr__(self) -> str:
return f"CGMinerX19: {str(self.ip)}"
async def get_model(self):
if self.model:
return self.model
version_data = await self.api.version()
if version_data:
self.model = version_data["VERSION"][0]["Type"].replace("Antminer ", "")
return self.model
return None

View File

@@ -1,36 +0,0 @@
from API.bmminer import BMMinerAPI
from miners import BaseMiner
class BMMiner(BaseMiner):
def __init__(self, ip: str) -> None:
api = BMMinerAPI(ip)
self.model = None
super().__init__(ip, api)
def __repr__(self) -> str:
return f"BMMiner: {str(self.ip)}"
async def get_model(self):
if self.model:
return self.model
version_data = await self.api.devdetails()
if version_data:
self.model = version_data["DEVDETAILS"][0]["Model"].replace("Antminer ", "")
return self.model
return None
async def get_hostname(self) -> str:
return "?"
async def send_config(self, _):
return None # ignore for now
async def restart_backend(self) -> None:
return None # Murray
async def reboot(self) -> None:
return None # Murray
async def get_config(self) -> None:
return None # Murray

View File

@@ -1,128 +0,0 @@
from miners import BaseMiner
from API.bosminer import BOSMinerAPI
import asyncssh
import toml
from config.bos import bos_config_convert, general_config_convert_bos
class BOSminer(BaseMiner):
def __init__(self, ip: str) -> None:
api = BOSMinerAPI(ip)
super().__init__(ip, api)
self.model = None
self.config = None
self.uname = 'root'
self.pwd = 'admin'
def __repr__(self) -> str:
return f"BOSminer: {str(self.ip)}"
async def _get_ssh_connection(self) -> asyncssh.connect:
"""Create a new asyncssh connection"""
conn = await asyncssh.connect(str(self.ip), known_hosts=None, username=self.uname, password=self.pwd,
server_host_key_algs=['ssh-rsa'])
# return created connection
return conn
async def send_ssh_command(self, cmd: str) -> None:
"""Sends SSH command to miner."""
# creates result variable
result = None
# runs the command on the miner
async with (await self._get_ssh_connection()) as conn:
# attempt to run command up to 3 times
for i in range(3):
try:
# save result of the command
result = await conn.run(cmd)
except Exception as e:
print(f"{cmd} error: {e}")
if i == 3:
return
continue
# let the user know the result of the command
if result is not None:
if result.stdout != "":
print(result.stdout)
if result.stderr != "":
print("ERROR: " + result.stderr)
elif result.stderr != "":
print("ERROR: " + result.stderr)
else:
print(cmd)
async def fault_light_on(self) -> None:
"""Sends command to turn on fault light on the miner."""
await self.send_ssh_command('miner fault_light on')
async def fault_light_off(self) -> None:
"""Sends command to turn off fault light on the miner."""
await self.send_ssh_command('miner fault_light off')
async def restart_backend(self) -> None:
"""Restart bosminer hashing process."""
await self.send_ssh_command('/etc/init.d/bosminer restart')
async def reboot(self) -> None:
"""Reboots power to the physical miner."""
await self.send_ssh_command('/sbin/reboot')
async def get_config(self) -> None:
async with (await self._get_ssh_connection()) as conn:
async with conn.start_sftp_client() as sftp:
async with sftp.open('/etc/bosminer.toml') as file:
toml_data = toml.loads(await file.read())
cfg = await bos_config_convert(toml_data)
self.config = cfg
async def get_hostname(self) -> str:
"""Attempts to get hostname from miner."""
try:
async with (await self._get_ssh_connection()) as conn:
data = await conn.run('cat /proc/sys/kernel/hostname')
return data.stdout.strip()
except Exception as e:
print(self.ip, e)
return "BOSMiner Unknown"
async def get_model(self):
if self.model:
return self.model + " (BOS)"
version_data = await self.api.devdetails()
if version_data:
self.model = version_data["DEVDETAILS"][0]["Model"].replace("Antminer ", "")
return self.model + " (BOS)"
return None
async def send_config(self, yaml_config) -> None:
"""Configures miner with yaml config."""
toml_conf = await general_config_convert_bos(yaml_config)
async with (await self._get_ssh_connection()) as conn:
async with conn.start_sftp_client() as sftp:
async with sftp.open('/etc/bosminer.toml', 'w+') as file:
await file.write(toml_conf)
await conn.run("/etc/init.d/bosminer restart")
async def get_bad_boards(self) -> list:
"""Checks for and provides list of non working boards."""
devs = await self.api.devdetails()
bad = 0
chains = devs['DEVDETAILS']
for chain in chains:
if chain['Chips'] == 0:
bad += 1
if bad > 0:
return [str(self.ip), bad]
async def check_good_boards(self) -> str:
"""Checks for and provides list for working boards."""
devs = await self.api.devdetails()
bad = 0
chains = devs['DEVDETAILS']
for chain in chains:
if chain['Chips'] == 0:
bad += 1
if not bad > 0:
return str(self.ip)

View File

@@ -1,42 +0,0 @@
from API.btminer import BTMinerAPI
from miners import BaseMiner
from API import APIError
class BTMiner(BaseMiner):
def __init__(self, ip: str) -> None:
api = BTMinerAPI(ip)
self.model = None
super().__init__(ip, api)
def __repr__(self) -> str:
return f"BTMiner: {str(self.ip)}"
async def get_model(self):
if self.model:
return self.model
version_data = await self.api.devdetails()
if version_data:
self.model = version_data["DEVDETAILS"][0]["Model"].split("V")[0]
return self.model
return None
async def get_hostname(self) -> str:
try:
host_data = await self.api.get_miner_info()
if host_data:
return host_data["Msg"]["hostname"]
except APIError:
return "?"
async def send_config(self, _):
return None # ignore for now
async def restart_backend(self) -> None:
return None
async def reboot(self) -> None:
return None
async def get_config(self) -> None:
return None

View File

@@ -1,133 +0,0 @@
from miners import BaseMiner
from API.cgminer import CGMinerAPI
import asyncssh
class CGMiner(BaseMiner):
def __init__(self, ip: str) -> None:
api = CGMinerAPI(ip)
super().__init__(ip, api)
self.model = None
self.config = None
self.uname = 'root'
self.pwd = 'admin'
def __repr__(self) -> str:
return f"CGMiner: {str(self.ip)}"
async def get_model(self):
if self.model:
return self.model
version_data = await self.api.devdetails()
if version_data:
self.model = version_data["DEVDETAILS"][0]["Model"].replace("Antminer ", "")
return self.model
return None
async def get_hostname(self) -> str:
try:
async with (await self._get_ssh_connection()) as conn:
if conn is not None:
data = await conn.run('cat /proc/sys/kernel/hostname')
return data.stdout.strip()
else:
return "?"
except Exception:
return "?"
async def send_config(self, _):
return None # ignore for now
async def _get_ssh_connection(self) -> asyncssh.connect:
try:
conn = await asyncssh.connect(str(self.ip),
known_hosts=None,
username=self.uname,
password=self.pwd,
server_host_key_algs=['ssh-rsa'])
return conn
except asyncssh.misc.PermissionDenied:
try:
conn = await asyncssh.connect(str(self.ip),
known_hosts=None,
username="admin",
password="admin",
server_host_key_algs=['ssh-rsa'])
return conn
except Exception as e:
print(e)
except OSError:
print(str(self.ip) + " Connection refused.")
return None
async def send_ssh_command(self, cmd):
result = None
async with (await self._get_ssh_connection()) as conn:
for i in range(3):
try:
result = await conn.run(cmd)
except Exception as e:
print(f"{cmd} error: {e}")
if i == 3:
return
continue
# handle result
self._result_handler(result)
@staticmethod
def _result_handler(result: asyncssh.process.SSHCompletedProcess) -> None:
if result is not None:
# noinspection PyUnresolvedReferences
if len(result.stdout) > 0:
# noinspection PyUnresolvedReferences
print("ssh stdout: \n" + result.stdout)
# noinspection PyUnresolvedReferences
if len(result.stderr) > 0:
# noinspection PyUnresolvedReferences
print("ssh stderr: \n" + result.stderrr)
# noinspection PyUnresolvedReferences
if len(result.stdout) <= 0 and len(result.stderr) <= 0:
print("ssh stdout stderr empty")
# if result.stdout != "":
# print(result.stdout)
# if result.stderr != "":
# print("ERROR: " + result.stderr)
# elif result.stderr != "":
# print("ERROR: " + result.stderr)
# else:
# print(cmd)
async def restart_cgminer(self) -> None:
commands = ['cgminer-api restart',
'/usr/bin/cgminer-monitor >/dev/null 2>&1']
commands = ';'.join(commands)
await self.send_ssh_command(commands)
async def reboot(self) -> None:
commands = ['reboot']
commands = ';'.join(commands)
await self.send_ssh_command(commands)
async def start_cgminer(self) -> None:
commands = ['mkdir -p /etc/tmp/',
'echo \"*/3 * * * * /usr/bin/cgminer-monitor\" > /etc/tmp/root',
'crontab -u root /etc/tmp/root',
'/usr/bin/cgminer-monitor >/dev/null 2>&1']
commands = ';'.join(commands)
await self.send_ssh_command(commands)
async def stop_cgminer(self) -> None:
commands = ['mkdir -p /etc/tmp/',
'echo \"\" > /etc/tmp/root',
'crontab -u root /etc/tmp/root',
'killall cgminer']
commands = ';'.join(commands)
await self.send_ssh_command(commands)
async def get_config(self) -> None:
async with (await self._get_ssh_connection()) as conn:
command = 'cat /etc/config/cgminer'
result = await conn.run(command, check=True)
self._result_handler(result)
self.config = result.stdout
print(str(self.config))

View File

@@ -1,215 +0,0 @@
from miners.antminer.S9.bosminer import BOSMinerS9
from miners.antminer.S9.bmminer import BMMinerS9
from miners.antminer.S9.cgminer import CGMinerS9
from miners.antminer.X17.bosminer import BOSMinerX17
from miners.antminer.X17.bmminer import BMMinerX17
from miners.antminer.X17.cgminer import CGMinerX17
from miners.antminer.X19.bmminer import BMMinerX19
from miners.antminer.X19.cgminer import CGMinerX19
from miners.whatsminer.M20 import BTMinerM20
from miners.whatsminer.M21 import BTMinerM21
from miners.whatsminer.M30 import BTMinerM30
from miners.whatsminer.M31 import BTMinerM31
from miners.whatsminer.M32 import BTMinerM32
from miners.bmminer import BMMiner
from miners.cgminer import CGMiner
from miners.unknown import UnknownMiner
from API import APIError
import asyncio
import ipaddress
import json
from settings import MINER_FACTORY_GET_VERSION_RETRIES as GET_VERSION_RETRIES
class MinerFactory:
def __init__(self):
self.miners = {}
async def get_miner_generator(self, ips: list):
"""
Get Miner objects from ip addresses using an async generator.
Returns an asynchronous generator containing Miners.
Parameters:
ips: a list of ip addresses to get miners for.
"""
loop = asyncio.get_event_loop()
scan_tasks = []
for miner in ips:
scan_tasks.append(loop.create_task(self.get_miner(miner)))
scanned = asyncio.as_completed(scan_tasks)
for miner in scanned:
yield await miner
async def get_miner(self, ip: ipaddress.ip_address):
"""Decide a miner type using the IP address of the miner."""
# check if the miner already exists in cache
if ip in self.miners:
return self.miners[ip]
miner = UnknownMiner(str(ip))
api = None
for i in range(GET_VERSION_RETRIES):
api = await self._get_api_type(ip)
if api:
break
model = None
for i in range(GET_VERSION_RETRIES):
model = await self._get_miner_model(ip)
if model:
break
if model:
if "Antminer" in model:
if "Antminer S9" in model:
if "BOSMiner" in api:
miner = BOSMinerS9(str(ip))
elif "CGMiner" in api:
miner = CGMinerS9(str(ip))
elif "BMMiner" in api:
miner = BMMinerS9(str(ip))
elif "17" in model:
if "BOSMiner" in api:
miner = BOSMinerX17(str(ip))
elif "CGMiner" in api:
miner = CGMinerX17(str(ip))
elif "BMMiner" in api:
miner = BMMinerX17(str(ip))
elif "19" in model:
if "CGMiner" in api:
miner = CGMinerX19(str(ip))
elif "BMMiner" in api:
miner = BMMinerX19(str(ip))
elif "M20" in model:
miner = BTMinerM20(str(ip))
elif "M21" in model:
miner = BTMinerM21(str(ip))
elif "M30" in model:
miner = BTMinerM30(str(ip))
elif "M31" in model:
miner = BTMinerM31(str(ip))
elif "M32" in model:
miner = BTMinerM32(str(ip))
self.miners[ip] = miner
return miner
def clear_cached_miners(self):
"""Clear the miner factory cache."""
self.miners = {}
async def _get_miner_model(self, ip: ipaddress.ip_address or str) -> dict or None:
model = None
try:
data = await self._send_api_command(str(ip), "devdetails")
if data.get("STATUS"):
if not isinstance(data["STATUS"], str):
if data["STATUS"][0].get("STATUS") not in ["I", "S"]:
try:
data = await self._send_api_command(str(ip), "version")
model = data["VERSION"][0]["Type"]
except:
print(f"Get Model Exception: {ip}")
else:
model = data["DEVDETAILS"][0]["Model"]
else:
try:
data = await self._send_api_command(str(ip), "version")
model = data["VERSION"][0]["Type"]
except:
print(f"Get Model Exception: {ip}")
if model:
return model
except OSError as e:
if e.winerror == 121:
return None
else:
print(ip, e)
return None
async def _send_api_command(self, ip: ipaddress.ip_address or str, command: str):
try:
# get reader and writer streams
reader, writer = await asyncio.open_connection(str(ip), 4028)
# handle OSError 121
except OSError as e:
if e.winerror == "121":
print("Semaphore Timeout has Expired.")
return {}
# create the command
cmd = {"command": command}
# send the command
writer.write(json.dumps(cmd).encode('utf-8'))
await writer.drain()
# instantiate data
data = b""
# loop to receive all the data
try:
while True:
d = await reader.read(4096)
if not d:
break
data += d
except Exception as e:
print(e)
try:
# some json from the API returns with a null byte (\x00) on the end
if data.endswith(b"\x00"):
# handle the null byte
str_data = data.decode('utf-8')[:-1]
else:
# no null byte
str_data = data.decode('utf-8')
# fix an error with a btminer return having an extra comma that breaks json.loads()
str_data = str_data.replace(",}", "}")
# fix an error with a btminer return having a newline that breaks json.loads()
str_data = str_data.replace("\n", "")
# fix an error with a bmminer return not having a specific comma that breaks json.loads()
str_data = str_data.replace("}{", "},{")
# parse the json
parsed_data = json.loads(str_data)
# handle bad json
except json.decoder.JSONDecodeError as e:
print(e)
raise APIError(f"Decode Error: {data}")
data = parsed_data
# close the connection
writer.close()
await writer.wait_closed()
return data
async def _get_api_type(self, ip: ipaddress.ip_address or str) -> dict or None:
"""Get data on the version of the miner to return the right miner."""
api = None
try:
data = await self._send_api_command(str(ip), "version")
if data.get("STATUS") and not data.get("STATUS") == "E":
if data["STATUS"][0].get("STATUS") in ["I", "S"]:
if any("BMMiner" in string for string in data["VERSION"][0].keys()):
api = "BMMiner"
elif any("CGMiner" in string for string in data["VERSION"][0].keys()):
api = "CGMiner"
elif any("BOSminer" in string for string in data["VERSION"][0].keys()):
api = "BOSMiner"
elif data.get("Description") and "whatsminer" in data.get("Description"):
api = "BTMiner"
if api:
return api
except OSError as e:
if e.winerror == 121:
return None
else:
print(ip, e)
return None

View File

@@ -1,20 +0,0 @@
from API.unknown import UnknownAPI
from miners import BaseMiner
class UnknownMiner(BaseMiner):
def __init__(self, ip: str) -> None:
api = UnknownAPI(ip)
super().__init__(ip, api)
def __repr__(self) -> str:
return f"Unknown: {str(self.ip)}"
async def get_model(self):
return "Unknown"
async def send_config(self, _):
return None
async def get_hostname(self):
return "Unknown"

View File

@@ -1,9 +0,0 @@
from miners.btminer import BTMiner
class BTMinerM20(BTMiner):
def __init__(self, ip: str) -> None:
super().__init__(ip)
def __repr__(self) -> str:
return f"M20 - BTMiner: {str(self.ip)}"

View File

@@ -1,9 +0,0 @@
from miners.btminer import BTMiner
class BTMinerM21(BTMiner):
def __init__(self, ip: str) -> None:
super().__init__(ip)
def __repr__(self) -> str:
return f"M21 - BTMiner: {str(self.ip)}"

View File

@@ -1,9 +0,0 @@
from miners.btminer import BTMiner
class BTMinerM30(BTMiner):
def __init__(self, ip: str) -> None:
super().__init__(ip)
def __repr__(self) -> str:
return f"M30- BTMiner: {str(self.ip)}"

View File

@@ -1,9 +0,0 @@
from miners.btminer import BTMiner
class BTMinerM31(BTMiner):
def __init__(self, ip: str) -> None:
super().__init__(ip)
def __repr__(self) -> str:
return f"M31 - BTMiner: {str(self.ip)}"

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