upstreamdata / pyasic Goto Github PK
View Code? Open in Web Editor NEWA simplified and standardized interface for Bitcoin ASICs.
Home Page: https://docs.pyasic.org
License: Apache License 2.0
A simplified and standardized interface for Bitcoin ASICs.
Home Page: https://docs.pyasic.org
License: Apache License 2.0
Hello, I would like to know if you have added a feature when a user wants to automatically add a miner to the miner array using the "IP report" button ?
I really can't remember then pyasic return class Unknow miner when i use function pyasic.get_miner(ip).
Now this func return None then can't find miner. Is this okey or it's bug ?
Is your feature request related to a problem? Please describe.
To use commands on whatsminer you always have to use whatsminer tools to change default password
Is it possible to use the same protocol as they do with sending some TCP packages to port 8889?
Describe the bug
I am running a script every minute. On one occasion a T19 running BOS+ 23.03.2+ hung and the whole script failed to collect any data for about 15 minutes until T19 was reset. The error given by the script after about 3 minutes was:
Traceback (most recent call last):
File "/home/sf/temp/pyasic/production_test.py", line 66, in <module>
asyncio.run(scan_and_get_data())
File "/usr/lib/python3.9/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
return future.result()
File "/home/sf/temp/pyasic/production_test.py", line 28, in scan_and_get_data
data = await asyncio.gather(*[m.get_data(data_to_get = [
File "/home/sf/.local/lib/python3.9/site-packages/pyasic/miners/base.py", line 476, in get_data
gathered_data = await self._get_data(allow_warning, data_to_get=data_to_get)
File "/home/sf/.local/lib/python3.9/site-packages/pyasic/miners/base.py", line 417, in _get_data
if web_command_data.get("multicommand"):
AttributeError: 'NoneType' object has no attribute 'get'
here is the script
import asyncio
from pyasic.network import MinerNetwork
#from pyasic.settings import PyasicSettings
#PyasicSettings().network_ping_timeout = 30
import influxdb_client, os, time
from influxdb_client import InfluxDBClient, Point, WritePrecision
from influxdb_client.client.write_api import SYNCHRONOUS
# define asynchronous function to scan for miners
async def scan_and_get_data():
# Define network range to be used for scanning
# This can take a list of IPs, a constructor string, or an IP and subnet mask
# The standard mask is /24 (x.x.x.0-255), and you can pass any IP address in the subnet
net = MinerNetwork("172.16.1.1", mask=21)
# Scan the network for miners
# This function returns a list of miners of the correct type as a class
miners: list = await net.scan_network_for_miners()
# We can now get data from any of these miners
# To do them all we have to create a list of tasks and gather them
# tasks = [miner.get_data() for miner in miners]
# Gather all tasks asynchronously and run them
data = await asyncio.gather(*[m.get_data(data_to_get = [
"mac",
"model",
"api_ver",
"fw_ver",
"hashrate",
"nominal_hashrate",
"hashboards",
"env_temp",
"wattage",
"wattage_limit",
"fans",
"fan_psu",
"errors",
"fault_light",
"pools",
]) for m in miners])
data = [d.as_influxdb() for d in data]
# Data is now a list of MinerData, and we can reference any part of that
# Print out all data for now
for item in data:
print(item)
#initialize influxdb
token = "xxxx=="
org = "xxxx"
url = "http://10.10.10.1:8086"
write_client = influxdb_client.InfluxDBClient(url=url, token=token, org=org)
bucket="xxxx"
write_api = write_client.write_api(write_options=SYNCHRONOUS)
for item in data:
write_api.write(bucket=bucket, org="xxxx", record=item)
if __name__ == "__main__":
asyncio.run(scan_and_get_data())
Vnish miners when trying to get information via miner.api.pools or miner.get_config returns None.
Is your feature request related to a problem? Please describe.
Support for Avalon 1166Pro and 1246.
Describe the solution you'd like
For these to be recognized.
Describe alternatives you've considered
Running excel spreadsheet and importing csv exported by BTCtools
I've been looking for ways to make reading the Canaan Avalon logs easier and found this python library. However, there seems to be an issues with this scanning Avalon 1246 miners.
When scanning a single or range of Avalon 1246 miners, I get the following error:
Traceback (most recent call last):
File "C:\Users\WM\Desktop\CanaanLogger\Temppyasic.py", line 16, in <module>
asyncio.run(gather_miner_data())
File "C:\Users\WM\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 190, in run
return runner.run(main)
^^^^^^^^^^^^^^^^
File "C:\Users\WM\AppData\Local\Programs\Python\Python311\Lib\asyncio\runners.py", line 118, in run
return self._loop.run_until_complete(task)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\WM\AppData\Local\Programs\Python\Python311\Lib\asyncio\base_events.py", line 653, in run_until_complete
return future.result()
^^^^^^^^^^^^^^^
File "C:\Users\WM\Desktop\CanaanLogger\Temppyasic.py", line 10, in gather_miner_data
all_miner_data = await asyncio.gather(*[miner.get_data() for miner in miners])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\WM\Desktop\CanaanLogger\venv\Lib\site-packages\pyasic\miners\base.py", line 536, in get_data
gathered_data = await self._get_data(allow_warning, data_to_get=data_to_get)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\WM\Desktop\CanaanLogger\venv\Lib\site-packages\pyasic\miners\base.py", line 489, in _get_data
miner_data[data_name] = await function(**args_to_send)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\WM\Desktop\CanaanLogger\venv\Lib\site-packages\pyasic\miners\backends\cgminer_avalon.py", line 186, in get_hostname
return f"Avalon{mac.replace(':', '')[-6:]}"
^^^^^^^^^^^
AttributeError: 'dict' object has no attribute 'replace'
I've been testing it on a small range of miners available to me and it appears to work fine for Bitmain S19 Pros, S19J Pros and T19's, just not for Avalon miners currently. The code I've been using is the example from the pyasic read the docs site for collecting all the data from a miner.
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("192.168.1.50")
miners = await network.scan_network_for_miners()
# 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())
I'm on Windows 10 using Python 3.11.3. I tested the example GUI program shown on the "https://pypi.org/project/pyasic/" page which appears to work for the most part with the Avalon 1246 miners but it does seem to be using a much earlier version of pyasic. (v0.35.0 I believe).
As stated, the Miner's having issues in question is the Avalon 1246 miners (Avalon N 1246 as well which is pretty much the same thing)
Firmware version is "21042001_4ec6bb0_61407fa" and "22122701_66620f1_fcec056"
Can you guys add winforms and UWP api? Would love to have a program that can get all info in a json format. Parse it using Winforms and UWP. Thank you.
Would love to see the Antminer S19k Pro NoPic suported with the SW.
Return of await pyasic.miners.miner_factory._get_miner_type(IP)
MinerTypes.BRAIINS_OS
hi!
Is it possible to add the antMiner V9 to the supported devices?
Much appreciated thank you!
BR,
Egbert
Hello, is it possible to add support for IceRiver KS2 please?
I can provide some cooperation if necessary.
could you write your command for example download logs
{ "token":"str", "cmd":"download_logs" }
Add support for the S19 Pro Hydro as mentioned in Schnitzel/hass-miner#271
Describe the bug
I received different functionality with the same miners using 0.36.4 vs. 0.36.5.
To Reproduce
Steps to reproduce the behavior:
Install pyasic 0.36.5 via
python3.8 -m pip install pyasic==0.36.5
Use pyasic in a script
Steps to reproduce the behavior:
Install pyasic 0.36.4 via
python3.8 -m pip install pyasic==0.36.4
Use pyasic in a script
Expected behavior
Gives back appropriate data from the api, 0.36.5 I would assume works with more miners than older versions, however my script stops on 0.36.5 with key error, whereas 0.36.4 the same script will save to a database data relative to other miners.
Desktop (please complete the following information):
Additional context
0.36.5 output:
/home/administrator/.local/lib/python3.8/site-packages/pyasic/miners/types/whatsminer/M5X/M56S.py:28: UserWarning: Unknown chip count for miner type M56S VH30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic).
warnings.warn(
/home/administrator/.local/lib/python3.8/site-packages/pyasic/API/bmminer.py:72 in _x19_multicommand
[WARNING][07/06/23 23:25:25](root) - BMMinerAPI: 10.1.1.145 - ([Hidden] X19 Multicommand) - API Command Error 0
Traceback (most recent call last):
File "./main.py", line 33, in <module>
miner_data = asyncio.run(get_miner(miner_ip))
File "/usr/lib/python3.8/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.8/asyncio/base_events.py", line 608, in run_until_complete
return future.result()
File "./main.py", line 24, in get_miner
miner_data = await miner.get_data()
File "/home/administrator/.local/lib/python3.8/site-packages/pyasic/miners/base.py", line 501, in get_data
gathered_data = await self._get_data(allow_warning, data_to_get=data_to_get)
File "/home/administrator/.local/lib/python3.8/site-packages/pyasic/miners/base.py", line 454, in _get_data
miner_data[data_name] = await function(**args_to_send)
File "/home/administrator/.local/lib/python3.8/site-packages/pyasic/miners/backends/bmminer.py", line 172, in get_fw_ver
api_version = await self.api.version()
File "/home/administrator/.local/lib/python3.8/site-packages/pyasic/API/bmminer.py", line 86, in version
return await self.send_command("version")
File "/home/administrator/.local/lib/python3.8/site-packages/pyasic/API/__init__.py", line 86, in send_command
validation = self._validate_command_output(data)
File "/home/administrator/.local/lib/python3.8/site-packages/pyasic/API/__init__.py", line 246, in _validate_command_output
elif data["STATUS"][0]["STATUS"] not in ("S", "I"):
KeyError: 0
0.36.4 output:
/home/administrator/.local/lib/python3.8/site-packages/pyasic/miners/types/whatsminer/M5X/M56S.py:28: UserWarning: Unknown chip count for miner type M56S VH30, please open an issue on GitHub (https://github.com/UpstreamData/pyasic).
warnings.warn(
/home/administrator/.local/lib/python3.8/site-packages/pyasic/API/bmminer.py:72 in _x19_multicommand
[WARNING][07/06/23 23:26:52](root) - BMMinerAPI: 10.1.1.145 - ([Hidden] X19 Multicommand) - API Command Error 0
/home/administrator/.local/lib/python3.8/site-packages/pyasic/API/bmminer.py:72 in _x19_multicommand
[WARNING][07/06/23 23:26:56](root) - BMMinerAPI: 10.1.1.242 - ([Hidden] X19 Multicommand) - API Command Error 0
Now that the new MinerConfig scheme has been implemented, transition the ePIC UMC API to use the new config and give the ability to change settings. Just creating the feature request for tracking
May need some guidance @UpstreamData on your preferred way or thinking of how this should be implemented. My thoughts are to start with simply with changing the pool config which should be straightforward, then I can use that template/guidance to start implementing things like PerpetualTune (autotune settings).
Please assign this issue to me, will work to get this implemented and tested
Hi. Woulde you add Luxor API in your lib ?
Add error code listings to BraiinsOSError
and X19Error
, and possibly create and abstract base class for all error codes to inherit from to ensure consistency if someone wants to access an err.error_code
, as it is not consistent across miner error types.
Describe the bug
I am running .get_data() on a list of ips returned by .scan_network_for_miners() and then exporting to influxdb by using .as_influxdb().
For some miners fields _hashrate and hashrate are not equal, for more popular miners these fields are equal. For example
S17 Pro AP 2.0.3:
ip=.152,mac=00:00:00:00:00:00,model=Unknown,hostname=Unknown api_ver="0.0.0",fw_ver="Unknown",hashrate=42.07,_hashrate=0,nominal_hashrate=43.52
S17+ (Vnish 2.0.4)
ip=.177,mac=00:00:00:00:00:00,model=Unknown,hostname=Unknown api_ver="0.0.0",fw_ver="Unknown",hashrate=16.94,_hashrate=0,nominal_hashrate=17.47
and then the opposite for avalons:
ip=.164,mac=B4:A2:...,model=Avalon\ 1166,hostname=Unknown make="AvalonMiner",api_ver="0.0.0",fw_ver="4.11.1",hashrate=0.0,_hashrate=50.08,nominal_hashrate=0
Expected behavior
I would expect them to be equal, and just wondering how exactly these fields are calculated.
Miner Information (If applicable):
Manufacturer: Antminer
Type: S17+
Firmware Type: Vnish 2.0.4
Manufacturer: Antminer
Type: S17 Pro
Firmware Type: A.P. 2.0.3
Additional context
When querying data from influxdb I cant use hashrate or _hashrate because neither is accurate.
Is your feature request related to a problem? Please describe.
There are some print statements which fill the logs in tools like homeassistant when pyasic is used
Describe the solution you'd like
no print statements
Additional context
Found this one: https://github.com/UpstreamData/pyasic/blob/e1500bb75c9d365d33b5606cb55a06ca7cd4ef18/pyasic/web/bosminer.py#L149C1-L150
but there might also be others
After upgrading my ASIC's firmware I am unable to get the miner data
This is the miner data from an Antminer with stock firmware:
MinerData(ip='10.10.0.101', datetime=datetime.datetime(2023, 5, 29, 18, 15, 5, 343988, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200), 'CEST')), mac='02:F0:33:33:DB:7C', model='S19', make='AntMiner', api_ver='3.1', fw_ver='Thu Jun 9 13:06:22 CST 2022', hostname='S1982T-01', hashrate=80.48, _hashrate=81.39, nominal_hashrate=82.0, hashboards=[HashBoard(slot=0, hashrate=26.54, temp=68, chip_temp=63, chips=88, expected_chips=76, missing=False), HashBoard(slot=1, hashrate=26.56, temp=69, chip_temp=64, chips=88, expected_chips=76, missing=False), HashBoard(slot=2, hashrate=27.38, temp=69, chip_temp=64, chips=88, expected_chips=76, missing=False)], ideal_hashboards=3, left_board_hashrate=26.54, center_board_hashrate=26.56, right_board_hashrate=27.38, temperature_avg=69, env_temp=-1.0, left_board_temp=68, left_board_chip_temp=63, center_board_temp=69, center_board_chip_temp=64, right_board_temp=69, right_board_chip_temp=64, wattage=-1, wattage_limit=-1, fans=[Fan(speed=5760), Fan(speed=5700), Fan(speed=6000), Fan(speed=5790)], fan_1=5760, fan_2=5700, fan_3=6000, fan_4=5790, fan_psu=-1, left_chips=88, center_chips=88, right_chips=88, total_chips=264, ideal_chips=228, percent_ideal_chips=116, percent_ideal_hashrate=98, percent_ideal_wattage=100, nominal=False, pool_split='0', pool_1_url='sha256asicboost.auto.nicehash.com:9200', pool_1_user='SOMETHING.S1982T-01', pool_2_url='', pool_2_user='', errors=[], fault_light=False, efficiency=0) INFO:src.logger:MinerData(ip='10.10.0.101', datetime=datetime.datetime(2023, 5, 29, 18, 15, 5, 343988, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200), 'CEST')), mac='02:F0:33:33:DB:7C', model='S19', make='AntMiner', api_ver='3.1', fw_ver='Thu Jun 9 13:06:22 CST 2022', hostname='S1982T-01', hashrate=80.48, _hashrate=81.39, nominal_hashrate=82.0, hashboards=[HashBoard(slot=0, hashrate=26.54, temp=68, chip_temp=63, chips=88, expected_chips=76, missing=False), HashBoard(slot=1, hashrate=26.56, temp=69, chip_temp=64, chips=88, expected_chips=76, missing=False), HashBoard(slot=2, hashrate=27.38, temp=69, chip_temp=64, chips=88, expected_chips=76, missing=False)], ideal_hashboards=3, left_board_hashrate=26.54, center_board_hashrate=26.56, right_board_hashrate=27.38, temperature_avg=69, env_temp=-1.0, left_board_temp=68, left_board_chip_temp=63, center_board_temp=69, center_board_chip_temp=64, right_board_temp=69, right_board_chip_temp=64, wattage=-1, wattage_limit=-1, fans=[Fan(speed=5760), Fan(speed=5700), Fan(speed=6000), Fan(speed=5790)], fan_1=5760, fan_2=5700, fan_3=6000, fan_4=5790, fan_psu=-1, left_chips=88, center_chips=88, right_chips=88, total_chips=264, ideal_chips=228, percent_ideal_chips=116, percent_ideal_hashrate=98, percent_ideal_wattage=100, nominal=False, pool_split='0', pool_1_url='sha256asicboost.auto.nicehash.com:9200', pool_1_user='SOMETHING.S1982T-01', pool_2_url='', pool_2_user='', errors=[], fault_light=False, efficiency=0)
And this is from the Braiins OS firmware:
MinerData(ip='10.10.0.102', datetime=datetime.datetime(2023, 5, 29, 18, 15, 5, 344579, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200), 'CEST')), mac='00:00:00:00:00:00', model='Unknown', make='Unknown', api_ver='Unknown', fw_ver='Unknown', hostname='Unknown', hashrate=0, _hashrate=0, nominal_hashrate=0, hashboards=[], ideal_hashboards=1, left_board_hashrate=0, center_board_hashrate=0, right_board_hashrate=0, temperature_avg=0, env_temp=-1.0, left_board_temp=0, left_board_chip_temp=0, center_board_temp=0, center_board_chip_temp=0, right_board_temp=0, right_board_chip_temp=0, wattage=-1, wattage_limit=-1, fans=[], fan_1=None, fan_2=None, fan_3=None, fan_4=None, fan_psu=-1, left_chips=0, center_chips=0, right_chips=0, total_chips=0, ideal_chips=1, percent_ideal_chips=0, percent_ideal_hashrate=0, percent_ideal_wattage=100, nominal=False, pool_split='0', pool_1_url='Unknown', pool_1_user='Unknown', pool_2_url='', pool_2_user='', errors=[], fault_light=None, efficiency=0) INFO:src.logger:MinerData(ip='10.10.0.102', datetime=datetime.datetime(2023, 5, 29, 18, 15, 5, 344579, tzinfo=datetime.timezone(datetime.timedelta(seconds=7200), 'CEST')), mac='00:00:00:00:00:00', model='Unknown', make='Unknown', api_ver='Unknown', fw_ver='Unknown', hostname='Unknown', hashrate=0, _hashrate=0, nominal_hashrate=0, hashboards=[], ideal_hashboards=1, left_board_hashrate=0, center_board_hashrate=0, right_board_hashrate=0, temperature_avg=0, env_temp=-1.0, left_board_temp=0, left_board_chip_temp=0, center_board_temp=0, center_board_chip_temp=0, right_board_temp=0, right_board_chip_temp=0, wattage=-1, wattage_limit=-1, fans=[], fan_1=None, fan_2=None, fan_3=None, fan_4=None, fan_psu=-1, left_chips=0, center_chips=0, right_chips=0, total_chips=0, ideal_chips=1, percent_ideal_chips=0, percent_ideal_hashrate=0, percent_ideal_wattage=100, nominal=False, pool_split='0', pool_1_url='Unknown', pool_1_user='Unknown', pool_2_url='', pool_2_user='', errors=[], fault_light=None, efficiency=0)
I was using 0.33.11 and I upgraded to the latest version (0.33.16) and the issue persist,
This is the code I am using (based on docs):
all_miner_data = await asyncio.gather(*[miner.get_data() for miner in miners])
for miner_data in all_miner_data:
try:
logger.logger.info(f"{miner_data}")
# logger.logger.info(f"{miner_data.hostname}: {miner_data.hashrate}TH @ {miner_data.temperature_avg} หC")
except Exception as e:
logger.logger.info(f"failed with error {e}")
Describe the bug
Some s17 pro miners are not recognized and thus cannot be identified or queried as powered on miners.
For these miners Socket connect failed: Connection refused is written on their webgui.
To Reproduce
Seems to be inherent to the miner rather than certain steps.
Expected behavior
To return miner information saying that hash is 0 etc etc
Screenshots
Here is btctools screenshot for one of miners in question and webgui screenshot
Miner Information (If applicable):
Additional context
For S17+ models running Vnish 2.0.4 which also have socket connect failed messages on the webgui, they are still recognized by pyasic and .get_data returns correct values.
results of await pyasic.miners.miner_factory.MinerFactory()._get_miner_type
for s17 pro
WARNING:root:172.16.1.65 - Command devdetails+version: [Errno 111] Connect call failed ('172.16.1.65', 4028) WARNING:root:172.16.1.65 - Command devdetails: [Errno 111] Connect call failed ('172.16.1.65', 4028) WARNING:root:172.16.1.65 - Command version: [Errno 111] Connect call failed ('172.16.1.65', 4028) WARNING:root:172.16.1.65 - Command get_version: [Errno 111] Connect call failed ('172.16.1.65', 4028) WARNING:root:172.16.1.65: API Command Error: No API data. (None, None, None, None)
this:
Lines 461 to 462 in b5d2809
should probably this way:
miner_data["pool_2_url"] = pools_data[1]["pool_1_url"]
miner_data["pool_2_user"] = pools_data[1]["pool_1_user"]
I get this error
Traceback (most recent call last):
File "c:\Users\aipro\OneDrive\Desktop\SAM\core\asic_funcs.py", line 183, in get_miner_data
data_object = await controle_object.get_data()
File "c:\Users\aipro\OneDrive\Desktop\SAM\venv\lib\site-packages\pyasic\miners\base.py", line 543, in get_data
gathered_data = await self._get_data(
File "c:\Users\aipro\OneDrive\Desktop\SAM\venv\lib\site-packages\pyasic\miners\base.py", line 460, in get_data
api_command_data = await api_command_task
File "c:\Users\aipro\OneDrive\Desktop\SAM\venv\lib\site-packages\pyasic\API\bmminer.py", line 51, in multicommand
data = await self.send_command(command, allow_warning=allow_warning)
File "c:\Users\aipro\OneDrive\Desktop\SAM\venv\lib\site-packages\pyasic\API_init.py", line 76, in send_command
data = await self.send_bytes(json.dumps(cmd).encode("utf-8"))
File "c:\Users\aipro\OneDrive\Desktop\SAM\venv\lib\site-packages\pyasic\API_init.py", line 209, in _send_bytes
ret_data = await asyncio.wait_for(reader.read(4096), timeout=timeout)
File "C:\Users\aipro\AppData\Local\Programs\Python\Python310\lib\asyncio\tasks.py", line 445, in wait_for
return fut.result()
File "C:\Users\aipro\AppData\Local\Programs\Python\Python310\lib\asyncio\streams.py", line 668, in read
await self._wait_for_data('read')
File "C:\Users\aipro\AppData\Local\Programs\Python\Python310\lib\asyncio\streams.py", line 501, in _wait_for_data
await self._waiter
File "C:\Users\aipro\AppData\Local\Programs\Python\Python310\lib\asyncio\proactor_events.py", line 282, in _loop_reading
length = fut.result()
File "C:\Users\aipro\AppData\Local\Programs\Python\Python310\lib\asyncio\windows_events.py", line 817, in _poll
value = callback(transferred, key, ov)
File "C:\Users\aipro\AppData\Local\Programs\Python\Python310\lib\asyncio\windows_events.py", line 485, in finish_recv
return ov.getresult()
OSError: [WinError 121] The semaphore timeout period has expired
I tested it in AntMiner S19j Pro with firmware BMMiner
Is there a global command to
on each miner for different miner apis?
Is your feature request related to a problem? Please describe.
When the Antminer Z15 is configured with a pool configuration that is deliberately invalid (causing the miner to stop mining), the miner accepts the configuration change command over port 4028 and stops mining. Once the pool configuration takes effect, CGMiner stops listening on port 4028. This causes pyasic to be unable to communicate with the miner.
Describe the solution you'd like
Try sending CGI commands over port 80 in addition to trying 4028. In addition, make sure get_miner and scan_network_for_miners can identify miners that are still controllable via port 80.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Additional context
Add any other context or screenshots about the feature request here.
MinerData dataclass needs a distinction between current power usage and power limit, since they are both useful and braiins OS returns both.
Whatsminers should use total power draw for both for now.
Describe the bug
when the miner is offline (like no power) homeassistant fails with this error:
2023-06-29 23:12:27.357 ERROR (MainThread) [custom_components.miner.coordinator] Unexpected error fetching Antminer data: dict() argument after ** must be a mapping, not NoneType
Traceback (most recent call last):
File "/home/vscode/.local/lib/python3.11/site-packages/homeassistant/helpers/update_coordinator.py", line 283, in _async_refresh
self.data = await self._async_update_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/workspaces/miner/custom_components/miner/coordinator.py", line 49, in _async_update_data
miner_data = await self.miner.get_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vscode/.local/lib/python3.11/site-packages/pyasic/miners/base.py", line 497, in get_data
gathered_data = await self._get_data(allow_warning, data_to_get=data_to_get)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vscode/.local/lib/python3.11/site-packages/pyasic/miners/base.py", line 416, in _get_data
web_command_data = await self.web.multicommand(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/vscode/.local/lib/python3.11/site-packages/pyasic/web/bosminer.py", line 91, in multicommand
data = dict(**luci_data, **gql_data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: dict() argument after ** must be a mapping, not NoneType
Expected behavior
pyasic
returns an pyasic.APIError
which can be caught by Homeassistant
Miner Information (If applicable):
2023-03-05-0-8cbe158f-23.02-plus
resume_mining doesn't work on both stock firmware and BrainOS, calling it returns false on Braiins OS, it does return true in stock firmware but the miner never resumes mining
Hi, i updated pyasic
and get errors.
import pyasic
File "c:\Users\balak\scanner\venv\Lib\site-packages\pyasic\__init__.py", line 22, in <module>
from pyasic.config import MinerConfig
File "c:\Users\balak\scanner\venv\Lib\site-packages\pyasic\config\__init__.py", line 26, in <module>
@dataclass
^^^^^^^^^
File "C:\Python311\Lib\dataclasses.py", line 1221, in dataclass
return wrap(cls)
^^^^^^^^^
File "C:\Python311\Lib\dataclasses.py", line 1211, in wrap
return _process_class(cls, init, repr, eq, order, unsafe_hash,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Python311\Lib\dataclasses.py", line 959, in _process_class
cls_fields.append(_get_field(cls, name, type, kw_only))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Python311\Lib\dataclasses.py", line 816, in _get_field
raise ValueError(f'mutable default {type(f.default)} for field '
ValueError: mutable default <class 'pyasic.config.pools.PoolConfig'> for field pools is not allowed: use default_factory
Hello!
I try remove pool from my miner antminer S9 (BMMiner).
I get this error pyasic.errors.APIError: Access denied to 'removepool' command
.
My code:
miner = await pyasic.get_miner(ip)
try:
t = await miner.api.removepool(1)
miner_pools = await miner.api.pools()
except:
print(traceback.format_exc())
miner_pools = []
return miner_pools```
Most files need unit tests, comments, and documentation/typing added to them.
Current unit tests are located in .tests
.
rpc
are mostly done, these are all base level implementations of the miner APIs, although some standardization across files and possibly improved type hinting would be useful.network
have been written, but could always be better.rpc
- This may be tough, these rely on external connections heavily.ssh
- Extension of rpc
essentially, this handles more external calls.web
- Extension of rpc
, again, more external calls.config
- Partially done, but could use more tests for different conversions.miners
- Same issue as rpc
. Partially done, with checks for initialization and data locations.network
- The important parts here are done, such as making sure inputs turn into the right network values.rpc
- Maybe slight improvements to standardization, but overall good.web
- A part of data collection alongside rpc
. Could be used in the documentation alongside rpc
in the advanced section.ssh
- Another means of data collection. Same idea, this is an advanced topic.miners
- Auto generated with generate_miners.py
, this generates the supported list and the files for each.network
- Quite good. Easy to follow, short, and simple.settings
- Good enough, doesn't need a whole lot of mentions unless something changes.pyasic.config.MinerConfig
needs a rework, as it is clunky and hard to update, as well as being extremely difficult to use.
Ideally I would like the following attributes -
Please add any suggestions or questions here so I can track them and get a list going of what needs to be done here.
If you have a miner that is not on this list, or a miner that has not been tested on this list, please reply to this issue and we can work with you on adding support or testing support for your miner.
Anything not on this list has no support whatsoever, but I would love to get it added.
Anything on this list but not checked off is technically supported, but I have no access to the physical miner to test that the code works.
Braiins OS+ (ALL MODELS)
AntMiner S9, S9i, and T9
AntMiner S17, S17+, S19 Pro, S17e, T17, T17+, T17e
AntMiner S19, S19 Pro, S19a, S19j, S19 Pro, T19
WhatsMiner M20S, M20S+, M21, M21S, M21S+
WhatsMiner M30S, M30S+, M30S++, M31S, M31S+, M32S
AvalonMiner 721, 741, 761
AvalonMiner 821, 841, 851
AvalonMiner 921
AvalonMiner 1026, 1047
AvalonMiner 1066
A nice feature would be to include in get_miner_data information on how long miner has been up and what power mode its in.
Hello, i have several questions.
pool_split: "0"
? i really don't understand what it should give me :((pyasic\data
third pool or you think that it's useless ?Hello!!!
I install all dependents and wrote some code for test
import pyasic
from pyasic.network import MinerNetwork
async def get_data(ip_range):
h = time()
print(h)
net = MinerNetwork(ip_range)
miners = await net.scan_network_for_miners()
tasks = [miner.get_data() for miner in miners]
data_task = await asynvio.gather(*tasks)
print(data_task)
asyncio.run(get_data("192.168.10.10-192.168.10.250"))```
And i got this error
```(venv) C:\Users\Davis\Desktop\asyc_w7>python testW7.py
Traceback (most recent call last):
File "testW7.py", line 3, in <module>
import pyasic
File "C:\Users\Davis\Desktop\asyc_w7\venv\lib\site-packages\pyasic\__init__.py
", line 30, in <module>
from pyasic.miners import get_miner
File "C:\Users\Davis\Desktop\asyc_w7\venv\lib\site-packages\pyasic\miners\__in
it__.py", line 21, in <module>
from pyasic.miners.miner_factory import MinerFactory
File "C:\Users\Davis\Desktop\asyc_w7\venv\lib\site-packages\pyasic\miners\mine
r_factory.py", line 576, in <module>
class MinerFactory(metaclass=Singleton):
File "C:\Users\Davis\Desktop\asyc_w7\venv\lib\site-packages\pyasic\miners\mine
r_factory.py", line 584, in MinerFactory
) -> AsyncIterable[AnyMiner]:
TypeError: 'ABCMeta' object is not subscriptable```
Could u tell me what i did wrong?
I have Antminer S19J Pro with BMMiner backend and i take H/R, temperature but not wattage. I don't know
This function for miners search.
async def find_miners_data(ip_range: str | list[str], port: int = None) -> tuple[list, ...]:
resetCache()
net = MinerNetwork(ip_range)
pyasic_miners = await net.scan_network_for_miners()
async def get_miner_data_checked(miner):
try:
if port is not None:
await network.ping_miner(miner.ip, port)
return miner
except:
return None
tasks = [get_miner_data_checked(miner) for miner in pyasic_miners]
data_task = [item for item in await asyncio.gather(*tasks) if item is not None]
if len(data_task) > 0:
miners = [miner for miner in pyasic_miners if miner.ip in [item.ip for item in data_task]]
else:
miners = []
data_pools, data_summary, data_config = [], [], []
tasks = await asyncio.gather(*[get_miner_data([miner.api.pools, miner.api.summary, miner.get_config], miner) for miner in miners])
if len(tasks) == 0:
return [], [], []
miners_data = []
for item in tasks:
gather_miners_data, data_miner, miner = item
dict_miner = json.loads(data_miner.as_json())
dict_miner["software"] = miner.api_type
miners_data.append(dict_miner)
data_pools.append(gather_miners_data[0])
data_summary.append(gather_miners_data[1])
data_config.append(gather_miners_data[2].as_dict() if hasattr(gather_miners_data[2], 'as_dict') else gather_miners_data[2])
return miners_data, data_pools, data_config
this func for get correct pool and config of miner
async def get_miner_data(list_tasks: list, controle_object: Any) -> tuple:
rez_tasks = []
for task in list_tasks:
try:
rez = await task()
if rez is None:
rez = {}
except:
rez = {}
rez_tasks.append(rez)
data_object = await controle_object.get_data()
return rez_tasks, data_object, controle_object
MinerData(
ip='10.1.40.100',
datetime=datetime.datetime(2023, 6, 15, 6, 43, 38, 153053,
tzinfo=datetime.timezone(datetime.timedelta(days=-1, seconds=68400), 'Central Daylight Time')),
mac='02:B7:9D:7D:41:BB', model='S19j Pro',
make='AntMiner', api_ver='3.1',
fw_ver='Tue Oct 19 21:30:41 CST 2021',
hostname='Antminer', hashrate=107.4,
_hashrate=106.48,
nominal_hashrate=104.0,
hashboards=[HashBoard(slot=0, hashrate=33.95, temp=69, chip_temp=64, chips=126, expected_chips=126, missing=False), HashBoard(slot=1, hashrate=36.68, temp=67, chip_temp=62, chips=126, expected_chips=126, missing=False), HashBoard(slot=2, hashrate=36.77, temp=67, chip_temp=62, chips=126, expected_chips=126, missing=False)],
ideal_hashboards=3,
left_board_hashrate=33.95,
center_board_hashrate=36.68,
right_board_hashrate=36.77,
temperature_avg=68,
env_temp=-1.0,
left_board_temp=69,
left_board_chip_temp=64,
center_board_temp=67,
center_board_chip_temp=62,
right_board_temp=67,
right_board_chip_temp=62,
**wattage=-1** = THIS
**wattage_limit=-1** = THIS
fans=[Fan(speed=5790), Fan(speed=5760), Fan(speed=6000), Fan(speed=6000)],
fan_1=5790,
fan_2=5760,
fan_3=6000,
fan_4=6000,
fan_psu=-1,
left_chips=126,
center_chips=126,
right_chips=126,
total_chips=378,
ideal_chips=378,
percent_ideal_chips=100,
percent_ideal_hashrate=103, percent_ideal_wattage=100, nominal=True,
pool_split='0',
pool_1_url='btc.foundryusapool.com:3333',
pool_1_user='******',
pool_2_url='******',
pool_2_user='******',
errors=[],
fault_light=False,
efficiency=0)
MB i wrote smth wrong ?
Is your feature request related to a problem? Please describe.
On the BraiinsOS UI there is a "Temperature (Chip)" which takes the highest chip temperature, pyasic only exposes the individual chip temperatures, making it a bit hard to easily get the highest chip temperature
Describe the solution you'd like
it would be great if pyasic returns the highest chip temperature
Describe alternatives you've considered
I could do this also in HomeAssistant but I feel it's easier in pyasic as the way that temperature is reported could be different per miner type
Describe the bug
pyasic.miners.backends.cgminer.CGMiner's send_ssh_command catches exceptions (asyncssh.Error, OSError) and returns None. This causes functions like stop_mining and resume mining, which lack an isinstance check, that call send_ssh_command to not have an exception raised to them. With the way stop_mining is written, the function will return True as long as no exception was raised, which makes it hard to detect SSH failures.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
stop_mining() should return false when there are SSH connection errors.
Screenshots
If applicable, add screenshots to help explain your problem.
Miner Information (If applicable):
S19J Pro returns with a capital J, should switch model over to model.lower() to handle for edge cases like this.
Describe the bug
We are trying to install Pyasic but we are getting errors.
To Reproduce
Steps to reproduce the behavior:
tried poetry install --with dev
Installing dependencies from lock file
Get a log error from the Lock file.
Warning: poetry.lock is not consistent with pyproject.toml. You may be getting improper dependencies. Run poetry lock [--no-update]
to fix it.
Because pyasic depends on isort (^5.10.1) which doesn't match any versions, version solving failed.
Expected behavior
Poetry should be installing the dependencies but it fails to read de pyproject.toml
Screenshots
This is the main bug. This should install dependencies and get it ready to build but is not downloading anything bcs of a mismatch
The screenshot shows we are trying to run poetry lock [--no-update]
Desktop (please complete the following information):
Additional context
Do I need to run this only on ubuntu?
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
Describe the solution you'd like
A clear and concise description of what you want to happen.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Additional context
Add any other context or screenshots about the feature request here.
Originally posted by JustinHowes01 November 1, 2022
I'm trying to write a script that will collect miner data over time on Whatsminer M30s machines, but when I try to print the error codes, they don't show up. I've tested this with miners that I have confirmed have errors such as 300, 530, 410 (missing a hashboard) and so on, and they still don't show. I've checked the Whatsminer.py file in the library and it includes all the errors I've tested.
Here is my code:
import pyasic
import asyncio
import pyperclip
import time
async def gather_miner_data():
miner = await pyasic.MinerFactory().get_miner(miner_ip)
miner_data = await miner.get_data()
return miner_data.hashrate, miner_data.wattage, miner_data.errors, miner_data.env_temp
miner_ip = pyperclip.paste()
while True:
hashrate, wattage, errors, temp = asyncio.run(gather_miner_data())
print('Hashrate: %s\nWattage: %s\nErrors: %s\nTemperature: %s\n' % (hashrate, wattage, errors, temp))
time.sleep(1)
The script uses the IP address copied to the clipboard to scan a miner, since we have very many machines running.
After running the script, it will give continous readings from the miner that look like this:
Hashrate: 72.79
Wattage: 3211
Errors: []
Temperature: 58.5
This miner in particular has a 275 power overheat error, and yet the error is not reported here.
Hi, i tested speed of functions scan_network_for_miners() and get_miner(). Why scan_network_for_miners() took 4-5 seconds on action (it didn't matter if i put IP or IP_RANGE) and get_miner() took less then 0.5 seconds on same action?
I see that you add function set_static_ip
in antminer and bmminer backend. Could you add this function in BOS backend ?
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
I'd like to be able to poll a miner I have that responds with Antminer S19 XP, however I believe because it's replying in a REST format pyasic is unable to handle it.
Describe the solution you'd like
A clear and concise description of what you want to happen.
I'm curious if there may be a REST solution created somewhere in the code I'm not seeing at the moment in order to implement the change.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
I've thought about creating a new class of miner, but I hope this miner can be captured with functionality already built into pyasic.
Additional context
Add any other context or screenshots about the feature request here.
any/all suggestions would be greatly appreciated! Thank you.
I wrote code for test.
async def reboot_miners(ips:list, counter:int) -> None:
net = MinerNetwork(ips)
pyasic_miners = await net.scan_network_for_miners()
data = await asyncio.gather(*[item.get_data() for item in pyasic_miners])
await pyasic_miners[0].stop_mining()
Then i tried get miner's data
async def reboot_miners(ips:list, counter:int) -> None:
net = MinerNetwork(ips)
pyasic_miners = await net.scan_network_for_miners()
data = await asyncio.gather(*[item.get_data() for item in pyasic_miners])
And got this warning
192.168.1.49: Ping And Get Miner Exception: name 'url' is not defined
After that i can't take miner's information
I can't rewrite pools of BOSMiner S19j Pro.
# Get the miner object associated with the given IP address
miner = await pyasic.get_miner(ip)
# Check if the miner is accessible and get its configuration
if miner.api_type is not None:
ConfigMiner = await miner.get_config()
new_config_miner = rewrite_pool_config_by_worker(ConfigMiner, pools_info)
# Send the updated configuration to the miner and reboot it
await miner.send_config(new_config_miner)
# if hasattr(miner, "restart_bosminer"):
# rez = await miner.restart_bosminer()
#if hasattr(miner, "restart_backend"):
# rez = await miner.restart_backend()
#else:
# rez = await miner.reboot()
# Return True indicating success
else:
# Return False if the miner is not accessible
return False```
After this code i get next data:
url:stratum+tcp://eu.stratum.braiins.com:3
User:braiinstest.dummy_miner
Status: Alive
and etc.
But when i press "Restart BOSMiner" in BosMiner GUI i get latest pools before change
I can't find any information about how assign static ip on miner. what command should i use to do this?
Describe the bug
I got an S19J Pro with Braiins OS+, when i run stop_mining()
the attribute is_mining
always returns True
, even though the miner actually stops mining.
Expected behavior
is_mining
returns False
when stop_mining()
is sent
Miner Information (If applicable):
2023-03-05-0-8cbe158f-23.02-plus
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.