Code Monkey home page Code Monkey logo

pyasic's People

Contributors

1e9abhi1e10 avatar b-rowan avatar checksum0 avatar crc32 avatar dcreason avatar dellsauce avatar eliask avatar fdeh75 avatar jamescox13 avatar jimburtoft avatar jpcomps avatar murraymack avatar painxnagato avatar s0kil avatar schnitzel avatar snyk-bot avatar upstreamdata avatar wilfredallyn avatar ytemiloluwa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyasic's Issues

script hangs when t19 bosminer hangs

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())

support for avalon 1166Pro and 1246

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

Issues with scanning Avalon miners

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"

Winforms - UWP Support

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.

Support of Antminer S19k Pro NoPic

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

V9 integration

hi!
Is it possible to add the antMiner V9 to the supported devices?

Much appreciated thank you!

BR,
Egbert

IceRiver KS2

Hello, is it possible to add support for IceRiver KS2 please?

I can provide some cooperation if necessary.

Issues on versions > 0.36.4

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):

  • OS: [e.g. iOS]
    Ubuntu 18.04 using python3.8

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

implement MinerConfig scheme for ePIC UMC

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

Luxor

Hi. Woulde you add Luxor API in your lib ?

Error codes for `BraiinsOSError` and `X19Error` classes

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.

_hashrate and hashrate are not equal when using as_influxdb()

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.

Braiins OS issue

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}")
              

s17 pro not recognized in some instances

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
65 btctools
65 webgui

Miner Information (If applicable):

  • Antminer
  • S17 Pro
  • Firmware Type: Stock
  • Firmware Version: "Hardware Version Socket connect failed: Connection refused"

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)

One miner don't give data when i use miner.get_data() and await about 200+ seconds

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

CGMinerZ15: Add Port 80 to List of Network Ports

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.

Add miner power usage vs power limit in miner data

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.

TypeError when Miner Offline

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):

  • Manufacturer: Bitmain
  • Type: S19J Pro
  • Firmware Type: Braiins OS+
  • Firmware Version: 2023-03-05-0-8cbe158f-23.02-plus

resume_mining doesn't work

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

problem with pyasic 0.43.0

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 

Cannot removepool from antminer S9

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```

Add Unit Tests, Comments, and Documentation/Docstrings

Most files need unit tests, comments, and documentation/typing added to them.

Current unit tests are located in .tests.

  • Docstrings in 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.
  • Unit tests for network have been written, but could always be better.
  • Generally all files need some level of comments added, in my opinion it is a good idea to be as descriptive as possible, as an end goal is for even novice programmers to be able to design a simple program with this repo.

TODO:

  • Add unit tests:

    • 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.
  • Add docstrings/documentation:

    • 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.
    • #124
    • 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.
  • Additional Comments:

    • Overall the docs could use a restructure, I'm not sure what the best way to do this is, but things are a bit jumbled right now.

Re-work `MinerConfig` for usability

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 -

  • Small, manageable chunks of config options, separated into reasonable micro-configs (temperature/fans, tuning, pools, etc)
  • Extensibility.
  • Combined config that takes multiple micro-configs in and creates a large config that can then be parsed into a per miner type config.
  • Ways of sending individual configs and keeping all other settings, as well as using commands that only change small parts of the miner config.

Please add any suggestions or questions here so I can track them and get a list going of what needs to be done here.

LIST OF ALL SUPPORTED MINERS - Add/test support for new miners

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

Question about pools in pyasic/data

Hello, i have several questions.

  1. For what you read first and second pools?
  2. Does they show that miner use both pools ?
  3. Why i got pool_split: "0" ? i really don't understand what it should give me :((
  4. If i got only one pool, does it mean that second pool don't work?
  5. Will you add in pyasic\data third pool or you think that it's useless ?
    I'm sorry i new in mining theme and don't know a lot .

pyasic don't work on WIndows 7, python 3.8.10

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?

Can't get BMMiner wattage

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 ?

expose highest chip temperature

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

CGMiner: send_ssh_command hides exceptions raised by _get_ssh_connection

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:

  1. Close or filter the SSH port on a cgminer
  2. Try and call miner.stop_mining()

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):

  • Manufacturer: Bitmain
  • Type: Z15
  • Firmware Type: Stock
  • Firmware Version: CGMiner 4.9.0

Unable to run build

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
image

The screenshot shows we are trying to run poetry lock [--no-update]
image

Desktop (please complete the following information):

  • OS: Windows / WSL
  • Version Windows 11 / Ubuntu 22

Additional context
Do I need to run this only on ubuntu?

Thanks for this project guys. It is awesome. Will you add MAC address in miner's data ?

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.

BTMiner `self.get_data()` not including errors in data (M30)

Discussed in #21

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.

different time on scan_network_for_miners() and get_miner()

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?

Antminer S19 XP REST API

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.

The problem when I stop the miner and then try to connect to it

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 BosMiner pools

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

`is_mining` on Braiins OS+ with S19J Pro returns `True` even not mining

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):

  • Manufacturer: Bitmain
  • Type: S19J Pro
  • Firmware Type: Braiins OS+
  • Firmware Version: 2023-03-05-0-8cbe158f-23.02-plus

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.