Package: pyasic
pyasicA simplified and standardized interface for Bitcoin ASICs.IntroWelcome topyasic!pyasicuses an asynchronous method of communicating with ASIC miners on your network, which makes it super fast.Click here to view supported miner typesGetting startedGetting started withpyasicis 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 minersTo scan for miners inpyasic, we use the classMinerNetwork, which abstracts the search, communication, identification, setup, and return of a miner to 1 command.
The commandMinerNetwork.scan()returns a list that contains any miners found.importasyncio# asyncio for handling the async partfrompyasic.networkimportMinerNetwork# miner network handles the scanningasyncdefscan_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=awaitnetwork.scan()print(miners)if__name__=="__main__":asyncio.run(scan_miners())# run the scan asynchronously with asyncio.run()Creating miners based on IPIf you already know the IP address of your miner or miners, you can use theMinerFactoryto communicate and identify the miners, or an abstraction of its functionality,get_miner().
The functionget_miner()will return any miner it found at the IP address specified, or anUnknownMinerif it cannot identify the miner.importasyncio# asyncio for handling the async partfrompyasicimportget_miner# handles miner creationasyncdefget_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=awaitget_miner("192.168.1.75")miner_2=awaitget_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 timetasks=[get_miner("192.168.1.75"),get_miner("192.168.1.76")]miners=awaitasyncio.gather(*tasks)print(miners)if__name__=="__main__":asyncio.run(get_miners())# get the miners asynchronously with asyncio.run()Data gatheringOnce 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 calledget_data().
This function will return an instance of the dataclassMinerDatawith all data it can gather from the miner.
Each piece of data in aMinerDatainstance can be referenced by getting it as an attribute, such asMinerData().hashrate.One minerimportasynciofrompyasicimportget_minerasyncdefgather_miner_data():miner=awaitget_miner("192.168.1.75")ifminerisnotNone:miner_data=awaitminer.get_data()print(miner_data)# all data from the dataclassprint(miner_data.hashrate)# hashrate of the miner in TH/sif__name__=="__main__":asyncio.run(gather_miner_data())Multiple minersYou can do something similar with multiple miners, with only needing to make a small change to get all the data at once.importasyncio# asyncio for handling the async partfrompyasic.networkimportMinerNetwork# miner network handles the scanningasyncdefgather_miner_data():# define async scan function to allow awaitingnetwork=MinerNetwork.from_subnet("192.168.1.50/24")miners=awaitnetwork.scan()# we need to asyncio.gather() all the miners get_data() functions to make them run togetherall_miner_data=awaitasyncio.gather(*[miner.get_data()forminerinminers])forminer_datainall_miner_data:print(miner_data)# print out all the data one by oneif__name__=="__main__":asyncio.run(gather_miner_data())Miner controlpyasicexposes a standard interface for each miner using control functions.
Every miner class inpyasicmust implement all the control functions defined inBaseMiner.These functions arecheck_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, andset_power_limit.Usageimportasynciofrompyasicimportget_minerasyncdefset_fault_light():miner=awaitget_miner("192.168.1.20")# call control functionawaitminer.fault_light_on()if__name__=="__main__":asyncio.run(set_fault_light())Helper dataclassesMinerConfigandMinerDatapyasicimplements 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 classmethodcls.fields().MinerDataMinerDatais a return from theget_data()function, and is used to have a consistent dataset across all returns.You can callMinerData.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.MinerDatainstances 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 -frompyasicimportMinerData# examples of miner datad1=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)MinerConfigMinerConfigispyasic'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 fromget_config().Each miner has a unique way to convert theMinerConfigto their specific type, there are helper functions in the class.
In most cases these helper functions should not be used, assend_config()takes a [MinerConfigand will do the conversion to the right type for you.You can use theMinerConfigas follows:importasynciofrompyasicimportget_minerasyncdefset_fault_light():miner=awaitget_miner("192.168.1.20")# get configcfg=awaitminer.get_config()# send configawaitminer.send_config(cfg)if__name__=="__main__":asyncio.run(set_fault_light())Settingspyasichas settings designed to make using large groups of miners easier.  You can set the default password for all types of miners using thepyasic.settingsmodule, used as follows:frompyasicimportsettingssettings.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,