Vim�UnDoε’ω=U‡¦3΅�q�3#'yϋ…Iχ ,Μ �]γτίΙ CCCC\Σ;μ_Π,����\Σ#�υ S access_key = CoinmineRequests.get("miner", MINARY_AWS_S3_CM_INSTALL_ACCESS_KEY)5�_Π����/ V/\Σ8υT access_key = CoinmineRequests.get("config", MINARY_AWS_S3_CM_INSTALL_ACCESS_KEY) awscli = AWS_Cli() pass5�_Π����/V/\Σ8 υ υ5�_Π����/V/\Σ9ƒυ υ5�_Π%����/V/\Σ9 υ2 s3_config = CoinmineRequests.get(s3_config, 1)5�_Π/����/V/\Σ9Άυ3 s3_config = CoinmineRequests.get('s3_config, 1)5�_Π/����/V/\Σ9£υfrom aws_cli import AWS_Cli+from utils.requests import CoinmineRequestsif __name__ == "__main__":4 s3_config = CoinmineRequests.get('s3_config', 1) pass5�_Π (����/V/\Σ9®υ υ5�_Π ����/V/\Σ9Όυ AWS_Cli()5�_Π ����/V/\Σ9Ζυ aws = AWS_Cli()5�_Π ����/V/\Σ9Πυ aws = AWS_Cli(s3_config)5�_Π '����/V/\Σ:υ* aws = AWS_Cli(s3_config['access_key'])5�_Π ����/V/\Σ:!υ υυ aws = AWS_Cli(s3_config['])5�_Π ����/V/\Σ:&υ aws = AWS_Cli(s3_config[])5�_Π����/V/\Σ:'υ aws = AWS_Cli()5�_Π#����/V/\Σ:+υ # "cm_install_host_path",5�_Π#����/V/\Σ:,υ from aws_cli import AWS_Cli+from utils.requests import CoinmineRequestsif __name__ == "__main__":4 s3_config = CoinmineRequests.get("s3_config", 1) aws = AWS_Cli($ "cm_install_access_key",$ "cm_install_secret_key", "cm_install_bucket", "cm_install_path",$ "cm_install_host_path",) pass5�_Π����/V/\Σ:2υ "cm_install_access_key",5�_Π����/V/\Σ:5υ + s3_config[]"cm_install_access_key",5�_Π ����/V/\Σ:9υ "cm_install_secret_key",υ 5�_Π ����/V/\Σ:;υ "cm_install_bucket",υ 5�_Π����/V/\Σ:=υ "cm_install_path",υ5�_Π����/V/\Σ:?υ "cm_install_host_path",υ 5�_Π����/V/\Σ:?υ * s3_config[]"cm_install_host_path",5�_Π����/V/\Σ:Aυ % s3_config[]"cm_install_path",5�_Π ����/V/\Σ:Aυ ' s3_config[]"cm_install_bucket",5�_Π ����/V/\Σ:Aυ + s3_config[]"cm_install_secret_key",5�_Π(����/V/\Σ:Dυ * s3_config["cm_install_access_key",υ 5�_Π (����/V/\Σ:Eυ * s3_config["cm_install_secret_key",υ 5�_Π $����/V/\Σ:Fυ & s3_config["cm_install_bucket",υ 5�_Π! "����/V/\Σ:Gυ $ s3_config["cm_install_path",υ5�_Π "!'����/V/\Σ:Hυ
Vim�UnDo�!�U��a�+~��`x;D���-Wr}n��[���(; self.bucket + "/" + self.s3_path, self.path7++++\�D�_�����\�����5�_�����\���5�_�����'V\���import boto3class AWS_Cli:K def __init__(self, access_key, secret_key, bucket, s3_path, host_path):$ self.access_key = access_key$ self.secret_key = secret_key def configure(self):% self.session = boto3.Session(T aws_access_key_id=self.access_key, aws_secret_access_key=self.secret_key ) def get_cm_install(self):T self.session.Object(self.bucket, self.s3_path).download_file(self.host_path) @staticmethod def get_credentials(self): pass5�_�����V\���R s3_session.Object(self.bucket, self.s3_path).download_file(self.host_path)5�_�����V\���0 s3_session = self.session.resource("s3")G Object(self.bucket, self.s3_path).download_file(self.host_path)5�_�1����V\���p s3_session = self.session.resource("s3") Object(self.bucket, self.s3_path).download_file(self.host_path)5�_� ����V\���p s3_session = self.session.resource("s3").Object(self.bucket, self.s3_path).download_file(self.host_path)5�_� ����V\���import boto3class AWS_Cli:K def __init__(self, access_key, secret_key, bucket, s3_path, host_path):$ self.access_key = access_key$ self.secret_key = secret_key def configure(self):% self.session = boto3.Session(T aws_access_key_id=self.access_key, aws_secret_access_key=self.secret_key ) def get_cm_install(self):c self.session.resource("s3").Object(self.bucket, self.s3_path).download_file(self.host_path) @staticmethod def get_credentials(self): pass5�_� ����V\��� � 5�_� ����V\��� � 5�_� ����V\��� self.s3_path5�_� ����V\��� � 5�_� ����V\��� �5�_�����V\��� def _make_executable()5�_�����V\��� def _make_executable():5�_�����V\�����5�_�����&&V&\���'s.chmod("/home/satoshi/testing", 0o775)5�_�����&&V&\���+ s.chmod("/home/satoshi/testing", 0o775)5�_�����&&V&\���/ s.chmod("/home/satoshi/testing", 0o775)5�_�����&&V&\����5�_�(����&&V&\���0 os.chmod("/home/satoshi/testing", 0o775)5�_�����&&V&\��� �5�_�����&&V&\� ��5�_�����&&V&\�r� �5�_�����&&V&\�� � def get_credentials(self):5�_�����&&V&\��� �5�_� ���� & &V&\��� import osimport boto3class AWS_Cli:K def __init__(self, access_key, secret_key, bucket, s3_path, host_path):$ self.access_key = access_key$ self.secret_key = secret_key self.bucket = bucket self.s3_path = s3_path" self.host_path = host_path def configure(self):% self.session = boto3.Session(T aws_access_key_id=self.access_key, aws_secret_access_key=self.secret_key ) def get_cm_install(self):T self.session.resource("s3").Object(self.bucket, self.s3_path).download_file( self.host_path )- self._make_executable(self.host_path) @staticmethod" def get_cm_install_info(self):% CoinmineRequests.get('miner') pass @staticmethod def _make_executable(path): os.chmod(path, 0o775)5�_�! ����&&V&\���5�_� "!����&&V&\��� pass5�_�!#"����&&V&\����5�_�"$#����&&V&\�;�� � 5�_�#%$����&&V&\�;��$ �#5�_�$&%>����&&V&\�<'�$D logger.info('successfully downloaded cm_install bucket={} ')5�_�%'&?����&&V&\�<,�$B logger.info('successfully downloaded cm_install path={} ')5�_�&('J����&&V&\�</�$L logger.info('successfully downloaded cm_install path={} host_path ')5�_�')(M����&&V&\�<0�$N logger.info('successfully downloaded cm_install path={} host_path={}')5�_�(*)d����&&V&\�<C�$f logger.info('successfully downloaded cm_install path={} host_path={}'.format(self.bucket+'/'))5�_�)+*{����&&V&\�<N�$ import osimport boto3+from utils.requests import CoinmineRequests from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class AWS_Cli:K def __init__(self, access_key, secret_key, bucket, s3_path, host_path):$ self.access_key = access_key$ self.secret_key = secret_key self.bucket = bucket self.s3_path = s3_path" self.host_path = host_path def configure(self):% self.session = boto3.Session(T aws_access_key_id=self.access_key, aws_secret_access_key=self.secret_key ) def get_cm_install(self):T self.session.resource("s3").Object(self.bucket, self.s3_path).download_file( self.host_path )- self._make_executable(self.host_path)~ logger.info('successfully downloaded cm_install path={} host_path={}'.format(self.bucket+'/'+self.s3_path, self.path)) @staticmethod" def get_cm_install_info(self):% CoinmineRequests.get("miner") @staticmethod def _make_executable(path): os.chmod(path, 0o775)5�_�*+7����\�D��(; self.bucket + "/" + self.s3_path, self.path5�_� ����&&V&\���5�_�����&&V&\�<�" def download_cm_install(self):5�_� ����V\��� �5�_�����V\���+ s3_se = self.session.resource("s3")5��
Vim�UnDoε�ΰ—ΖΨΨΛPΙ1Ύ/½1’‘�KR¦ΛΖ–6ΑρMΞ|Rξ�E return sorted(SystemHelpers.dict_to_string(miner_status))[[[[\]¦_Π����\8#υl:from coinmine_utils import CoinmineRequests, CoinmineUtils5�_Π����\8$υl,from import CoinmineRequests, CoinmineUtils5�_Π#����\9Άυ l+ return CoinmineRequests.get_config(5�_Π#����\9¤υ l# return CoinmineRequests.get5�_Π%����\9¥υ l% return CoinmineRequests.get()5�_Π ����\9©υ l def get_config():5�_Π /����\9΄υ l/ os.environ['MINARY_API_SERVER_URL']5�_Π ���� V=\9Ύυ @staticmethod def get_miner_stats():0 return CoinmineRequests.get_miner_stats(/ os.environ['MINARY_API_SERVER_URL'] )5�_Π ���� V=\9Δυ f def get_status():5�_Π '���� V=\9Υυf3 return CoinmineCli.get_config().get('coin')5�_Π %���� V=\9Ϋυf6 return CoinmineCli.get_config().get('address')5�_Π %���� V=\9αυf6 return CoinmineCli.get_config().get('api_url')5�_Π%���� V=\9γυf4 return CoinmineCli.get_config().get('token')5�_Π!*���� V=\9νυ "f< return CoinmineCli.get_miner_stats().get('hashrate')5�_Π0���� V=\:υ/0A 'timestamp': str(datetime.datetime.utcnow()),5�_Π%����%,V\:υ$%4 distro_info = CoinmineUtils.get_distro_info(* os.environ['DISTRO_INFO_PATH'] )& uuid = CoinmineUtils.get_uuid() os.environ['MACHINE_ID_PATH'] )3 miner_stats = CoinmineCli.get_miner_stats()) config = CoinmineCli.get_config()5�_Π$����%%V\:υ$&^ υ$&]5�_Π%����&&V\:υ$&^ miner_status5�_Π%����&&V\:υ$&^ miner_status = Coinmin]5�_Π'����'. v\:)υ&(^ return (5�_Π(����(. V\:+υ'( {! 'uuid': uuid," **distro_info," **miner_stats, **config } )5�_Π'����(( V\:/υ&(W return 5�_Π'����(( V\:7υ&(W return miner_status5�_Π'����(( V\:8υ&(W! return miner_status5�_Π)7����(( V\:@υ(*WC distro_info = CoinmineUtils.dict_to_string(distro_info)5�_Π)7����(( V\:Bυ(*W8 distro_info = CoinmineUtils.dict_to_string()5�_Π *����*B+9VB\:Jυ)*C miner_stats = CoinmineUtils.dict_to_string(miner_stats)9 config = CoinmineUtils.dict_to_string(config)5�_Π! )����*B*9VB\:Lυ(*UD distro_info = CoinmineUtils.dict_to_string(miner_status)5�_Π "!)����*B*9VB\:Lυ(*U9 = CoinmineUtils.dict_to_string(miner_status)5�_Π!#"+����+4 V\:Vυ*+ 'uuid: {}\n' '{}\n' '{}\n' '{}'.format(! uuid,( distro_info,( miner_stats," config ) )5�_Π"$#*����++ V\:Wυ)+K return (5�_Π#%$)����++ V\:\υ(*KE miner_status = CoinmineUtils.dict_to_string(miner_status)5�_Π$&%*����++ V\:_υ)* return 5�_Π%'&*����*JV\:wυ)*! @staticmethod$ def get_human_readible_config():) config = CoinmineCli.get_config() return (3 'Current coin being mined: {}\n'9 'Current address being mined to: {}'.format(C config.get('coin'),E config.get('address')1 ) ) @staticmethod) def get_human_readible_miner_stats():- stats = CoinmineCli.get_miner_stats() return (+ 'uptime: {} minutes\n'& 'hashrate: {} {}\n'# 'accepted shares: {}\n'# 'rejected shares: {}\n'$ 'fan speed: {}%\n'- 'temp: {}Β° Celsius\n') 'pool: {}'.format(8 stats.get('uptime'),: stats.get('hashrate'),* 'H/s',A stats.get('accepted_shares'),A stats.get('rejected_shares'),; stats.get('fan_speed'),6 stats.get('temp'),5 stats.get('pool')# ) )5�_Π&('����**V\:}υ )$ return CoinmineRequests.get(? os.environ['MINARY_API_SERVER_URL'], 'miner_status'5�_Π')(%����))V\:~υ (X return CoinmineRequests.get( os.environ['MINARY_API_SERVER_URL'], 'miner_status'5�_Π(*)����))V\:†υimport datetime5�_Π)+*����((V\:�υ(υ'5�_Π*,+!����))V\:‘ υ(!from utils import CoinmineRequest5�_Π+-,"����))V\:•υ(/from cli import CoinmineRequests, CoinmineUtils5�_Π,.-����))V\:™ υfrom cli import CoinmineUtils5�_Π-/.+����((V\:©υ'7 return CoinmineCli.get_miner_status.get('coin')5�_Π.0/!����((V\:Όυ(υ'5�_Π/10����))V\:ϊυfrom 5�_Π021"����((V\:ϋυ'"from utils import CoinmineRequests5�_Π132' ����((V\;υ&= return CoinmineUtils.dict_to_string(miner_status)5�_Π243
VimЯUnDoеb3длуе,=ЦХ–#¤#УUH[ы%кWоЖHhЃШƒP s.sendall(b'{"id":0,"jsonrpc":"2.0","method":"miner_getstat1"}')9L _†Џx _–(W¤¤¤¤^Вb-х')X miner_status["mining"] = MinerRequests._is_hashing(miner_status.get("hashrate"))5Б_–([¤¤¤¤^Вb/х import socketimport json from utils import CoinmineLogger+from utils.requests import CoinmineRequests!logger = CoinmineLogger(__name__)class MinerRequests: @staticmethod% def get_miner_status(coin, urls): # we assume not mining miner_status = { "uptime": 0, "hashrate": 0,! "hashrate_list": [0], "pool": "", "errors": [], } try: miners = {W "ethereum": lambda: MinerRequests.get_claymore_stats(urls["claymore"]),T "zcash": lambda: MinerRequests.get_claymore_stats(urls["claymore"]),O "monero": lambda: MinerRequests.get_xmrig_stats(urls["xmrig"]),S "grin": lambda: MinerRequests.get_lolminer_stats(urls["lolminer"]),G "hashcat": lambda: MinerRequests.get_hashtopolis_stats(' urls["hashtopolis"] ),X "handshake": lambda: MinerRequests.get_sixminer_stats(urls["sixminer"]),K None: lambda: {"errors": "missing coin value from config"}, }= miner_status = {**miner_status, **miners[coin]()}I logger.debug("received miner status {}".format(miner_status)) except Exception as e:G logger.warning("failed to get miner status e={}".format(e))] miner_status["mining"] = MinerRequests._is_hashing(miner_status.get("hashrate") or 0) return miner_status @staticmethod, def get_claymore_stats(claymore_socket): try:H with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: logger.debug(> "attempting to connect to claymore rpc on"1 " {}".format(claymore_socket) )* s.connect(claymore_socket)9 logger.debug("connected to claymore rpc") s.settimeout(60)P s.sendall(b'{"id":0,"jsonrpc":"2.0","method":"miner_getstat1"}')C logger.debug("sent json for stats to claymore rpc")# data = s.recv(1024)? logger.debug("received data from claymore rpc")' string_data = data.decode()/ json_data = json.loads(string_data)- result_list = json_data["result"]* uptime_in_min = result_list[1]: accepted_shares = result_list[2].split(";")[1]: rejected_shares = result_list[2].split(";")[2]% hashrate = result_list[3] # multigpu if ";" in hashrate:E hashrate_list = list(map(float, hashrate.split(";")))- hashrate = sum(hashrate_list) else:1 hashrate_list = [float(hashrate)]4 fan_speed = result_list[6].split(";")[1]/ temp = result_list[6].split(";")[0]! pool = result_list[7] stats = {4 "uptime": int(float(uptime_in_min)),* "hashrate": int(hashrate),/ "hashrate_list": hashrate_list,8 "accepted_shares": int(accepted_shares),8 "rejected_shares": int(rejected_shares),, "fan_speed": int(fan_speed)," "temp": int(temp), "pool": pool, }C logger.debug("claymore socket stats: {}".format(stats)) return stats except Exception as e: logger.warning(T "could not handle sending or receiving from socket:" " {}".format(e) )B return {"errors": "claymore http service unavailable"} @staticmethod) def get_xmr_stak_stats(xmr_stak_url): try:B stats = CoinmineRequests.get(xmr_stak_url, "api.json"). pool = stats["connection"]["pool"]9 uptime_in_sec = stats["connection"]["uptime"]4 # will report 0 if a single thread fails4 hashrate = stats["hashrate"]["total"][0] if hashrate is None: hashrate = 0= accepted_shares = stats["results"]["shares_good"]P rejected_shares = stats["results"]["shares_total"] - accepted_shares8 # None values come from failed gpus/threads,7 # we want to accurately report the hashrate$ # even if a thread fails8 hashrate_list = stats["hashrate"]["threads"] # convert None to 0P hashrate_list = [0 if i[0] is None else i[0] for i in hashrate_list]> total_hashrate_threads = round(sum(hashrate_list)) return {2 "uptime": int(uptime_in_sec / 60),D "hashrate": int(hashrate) or total_hashrate_threads,/ "hashrate_list": hashrate_list,8 "accepted_shares": int(accepted_shares),8 "rejected_shares": int(rejected_shares), "pool": pool, } except Exception as e:L logger.warning("could not return xmr-stak stats e={}".format(e))B return {"errors": "xmr-stak http service unavailable"} @staticmethod+ def get_nanominer_stats(nanominer_url): try: hashrate = 0 hashrate_list = [] accepted_shares = 0 rejected_shares = 0 uptime = 0@ stats = CoinmineRequests.get(nanominer_url, "stats")& algs = stats["Algorithms"] adapter = 0 for alg in algs:S values = next(iter(alg.values())) # gets the first value from dict/ algorithm = list(alg.keys())[0]> hashrate += float(values["Total"]["Hashrate"])C accepted_shares += int(values["Total"]["Accepted"])A rejected_shares += int(values["Total"]["Denied"])0 pool = values.pop("CurrentPool")/ del values["ReconnectionCount"]# del values["Total"]1 for key, value in values.items():7 if key == "GPU {}".format(adapter):$ adapter += 12 if algorithm == "RandomX":> # pass on gpu hashrates on randomx$ continueB hashrate_list.append(float(value["Hashrate"]))& uptime = stats["WorkTime"] return {% "hashrate": hashrate,/ "hashrate_list": hashrate_list,! "uptime": uptime,3 "accepted_shares": accepted_shares,3 "rejected_shares": rejected_shares, "pool": pool, } except Exception as e:M logger.warning("could not return nanominer stats e={}".format(e))C return {"errors": "nanominer http service unavailable"} @staticmethodF def get_teamredminer_stats(teamredminer_socket=("0.0.0.0", 4028)): stats = {} try:A s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) logger.debug(> "attempting to connect to teamredminer rpc on"1 " {}".format(teamredminer_socket) )* s.connect(teamredminer_socket)9 logger.debug("connected to teamredminer rpc") s.settimeout(60)! s.sendall(b"summary")C logger.debug("sent json for stats to teamredminer rpc") data = s.recv(1024)? logger.debug("received data from teamredminer rpc")' string_data = data.decode(). list_data = string_data.split(",")= stats["uptime"] = int(list_data[5].split("=")[1])I hashrate = round(float(list_data[6].split("=")[1]) * 10e5, 3)( stats["hashrate"] = hashrate/ stats["hashrate_list"] = [hashrate]G stats["hardware_errors"] = int(list_data[14].split("=")[1])G stats["accepted_shares"] = int(list_data[12].split("=")[1])G stats["rejected_shares"] = int(list_data[13].split("=")[1]) except Exception as e: logger.warning(Q "could not handle sending or receiving from socket: {}".format(e) ) return stats @staticmethod/ def get_hashtopolis_stats(hashtopolis_url):> stats = CoinmineRequests.get(hashtopolis_url, "stats"). stats["hashrate"] = stats.pop("speed")4 stats["hashrate_list"] = [stats["hashrate"]]8 stats["accepted_shares"] = stats.pop("accepted")8 stats["uptime"] = stats.pop("uptime_in_seconds") return stats @staticmethod) def get_lolminer_stats(lolminer_url): stats = {} try:@ data = CoinmineRequests.get(lolminer_url, "summary") stats = {4 "uptime": data["Session"]["Uptime"],C "hashrate": data["Session"]["Performance_Summary"],N "hashrate_list": [gpu["Performance"] for gpu in data["GPUs"]],? "accepted_shares": data["Session"]["Accepted"],? "rejected_shares": data["Session"]["Submitted"]. - data["Session"]["Accepted"],8 "pool": data["Stratum"]["Current_Pool"], } except Exception as e:H logger.warning("could not get lolminer stats: {}".format(e)) return stats @staticmethod* def get_sixminer_stats(handshake_url):; return MinerRequests.get_local_stats(handshake_url) @staticmethod# def get_xmrig_stats(xmrig_url): stats = {} try:? data = CoinmineRequests.get(xmrig_url, "1/summary") stats = {) "uptime": data["uptime"],9 "hashrate": data["hashrate"]["total"][0],W "hashrate_list": [thread[0] for thread in data["hashrate"]["threads"]],B "accepted_shares": data["results"]["shares_good"],B "rejected_shares": data["results"]["shares_total"]1 - data["results"]["shares_good"],3 "pool": data["connection"]["pool"], } except Exception as e:E logger.warning("could not get xmrig stats: {}".format(e)) return stats @staticmethod def get_local_stats(url): stats = {} try:5 data = CoinmineRequests.get(url, "stats")W stats = {"hashrate": data["hashrate"], "hashrate_list": [data["hashrate"]]} except Exception as e:E logger.warning("could not get local stats: {}".format(e)) return stats @staticmethod def _is_hashing(hashrate):$ return bool(float(hashrate))5Б_–yC¤¤¤¤^Вd)хxz D "hashrate": int(hashrate) or total_hashrate_threads,5Б_–ц8¤¤¤¤^Вdѓххч 9 "hashrate": data["hashrate"]["total"][0],5Б_–ч+¤¤¤¤^Вiохцш W "hashrate_list": [thread[0] for thread in data["hashrate"]["threads"]],5Б_– ч/¤¤¤¤^Вiрх import socketimport json from utils import CoinmineLogger+from utils.requests import CoinmineRequests!logger = CoinmineLogger(__name__)class MinerRequests: @staticmethod% def get_miner_status(coin, urls): # we assume not mining miner_status = { "uptime": 0, "hashrate": 0,! "hashrate_list": [0], "pool": "", "errors": [], } try: miners = {W "ethereum": lambda: MinerRequests.get_claymore_stats(urls["claymore"]),T "zcash": lambda: MinerRequests.get_claymore_stats(urls["claymore"]),O "monero": lambda: MinerRequests.get_xmrig_stats(urls["xmrig"]),S "grin": lambda: MinerRequests.get_lolminer_stats(urls["lolminer"]),G "hashcat": lambda: MinerRequests.get_hashtopolis_stats(' urls["hashtopolis"] ),X "handshake": lambda: MinerRequests.get_sixminer_stats(urls["sixminer"]),K None: lambda: {"errors": "missing coin value from config"}, }= miner_status = {**miner_status, **miners[coin]()}I logger.debug("received miner status {}".format(miner_status)) except Exception as e:G logger.warning("failed to get miner status e={}".format(e)); miner_status["mining"] = MinerRequests._is_hashing(- miner_status.get("hashrate") or 0 ) return miner_status @staticmethod, def get_claymore_stats(claymore_socket): try:H with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: logger.debug(> "attempting to connect to claymore rpc on"1 " {}".format(claymore_socket) )* s.connect(claymore_socket)9 logger.debug("connected to claymore rpc") s.settimeout(60)P s.sendall(b'{"id":0,"jsonrpc":"2.0","method":"miner_getstat1"}')C logger.debug("sent json for stats to claymore rpc")# data = s.recv(1024)? logger.debug("received data from claymore rpc")' string_data = data.decode()/ json_data = json.loads(string_data)- result_list = json_data["result"]* uptime_in_min = result_list[1]: accepted_shares = result_list[2].split(";")[1]: rejected_shares = result_list[2].split(";")[2]% hashrate = result_list[3] # multigpu if ";" in hashrate:E hashrate_list = list(map(float, hashrate.split(";")))- hashrate = sum(hashrate_list) else:1 hashrate_list = [float(hashrate)]4 fan_speed = result_list[6].split(";")[1]/ temp = result_list[6].split(";")[0]! pool = result_list[7] stats = {4 "uptime": int(float(uptime_in_min)),* "hashrate": int(hashrate),/ "hashrate_list": hashrate_list,8 "accepted_shares": int(accepted_shares),8 "rejected_shares": int(rejected_shares),, "fan_speed": int(fan_speed)," "temp": int(temp), "pool": pool, }C logger.debug("claymore socket stats: {}".format(stats)) return stats except Exception as e: logger.warning(T "could not handle sending or receiving from socket:" " {}".format(e) )B return {"errors": "claymore http service unavailable"} @staticmethod) def get_xmr_stak_stats(xmr_stak_url): try:B stats = CoinmineRequests.get(xmr_stak_url, "api.json"). pool = stats["connection"]["pool"]9 uptime_in_sec = stats["connection"]["uptime"]4 # will report 0 if a single thread fails4 hashrate = stats["hashrate"]["total"][0] if hashrate is None: hashrate = 0= accepted_shares = stats["results"]["shares_good"]P rejected_shares = stats["results"]["shares_total"] - accepted_shares8 # None values come from failed gpus/threads,7 # we want to accurately report the hashrate$ # even if a thread fails8 hashrate_list = stats["hashrate"]["threads"] # convert None to 0P hashrate_list = [0 if i[0] is None else i[0] for i in hashrate_list]> total_hashrate_threads = round(sum(hashrate_list)) return {2 "uptime": int(uptime_in_sec / 60),I "hashrate": int(hashrate) or total_hashrate_threads or 0,/ "hashrate_list": hashrate_list,8 "accepted_shares": int(accepted_shares),8 "rejected_shares": int(rejected_shares), "pool": pool, } except Exception as e:L logger.warning("could not return xmr-stak stats e={}".format(e))B return {"errors": "xmr-stak http service unavailable"} @staticmethod+ def get_nanominer_stats(nanominer_url): try: hashrate = 0 hashrate_list = [] accepted_shares = 0 rejected_shares = 0 uptime = 0@ stats = CoinmineRequests.get(nanominer_url, "stats")& algs = stats["Algorithms"] adapter = 0 for alg in algs:S values = next(iter(alg.values())) # gets the first value from dict/ algorithm = list(alg.keys())[0]> hashrate += float(values["Total"]["Hashrate"])C accepted_shares += int(values["Total"]["Accepted"])A rejected_shares += int(values["Total"]["Denied"])0 pool = values.pop("CurrentPool")/ del values["ReconnectionCount"]# del values["Total"]1 for key, value in values.items():7 if key == "GPU {}".format(adapter):$ adapter += 12 if algorithm == "RandomX":> # pass on gpu hashrates on randomx$ continueB hashrate_list.append(float(value["Hashrate"]))& uptime = stats["WorkTime"] return {% "hashrate": hashrate,/ "hashrate_list": hashrate_list,! "uptime": uptime,3 "accepted_shares": accepted_shares,3 "rejected_shares": rejected_shares, "pool": pool, } except Exception as e:M logger.warning("could not return nanominer stats e={}".format(e))C return {"errors": "nanominer http service unavailable"} @staticmethodF def get_teamredminer_stats(teamredminer_socket=("0.0.0.0", 4028)): stats = {} try:A s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) logger.debug(> "attempting to connect to teamredminer rpc on"1 " {}".format(teamredminer_socket) )* s.connect(teamredminer_socket)9 logger.debug("connected to teamredminer rpc") s.settimeout(60)! s.sendall(b"summary")C logger.debug("sent json for stats to teamredminer rpc") data = s.recv(1024)? logger.debug("received data from teamredminer rpc")' string_data = data.decode(). list_data = string_data.split(",")= stats["uptime"] = int(list_data[5].split("=")[1])I hashrate = round(float(list_data[6].split("=")[1]) * 10e5, 3)( stats["hashrate"] = hashrate/ stats["hashrate_list"] = [hashrate]G stats["hardware_errors"] = int(list_data[14].split("=")[1])G stats["accepted_shares"] = int(list_data[12].split("=")[1])G stats["rejected_shares"] = int(list_data[13].split("=")[1]) except Exception as e: logger.warning(Q "could not handle sending or receiving from socket: {}".format(e) ) return stats @staticmethod/ def get_hashtopolis_stats(hashtopolis_url):> stats = CoinmineRequests.get(hashtopolis_url, "stats"). stats["hashrate"] = stats.pop("speed")4 stats["hashrate_list"] = [stats["hashrate"]]8 stats["accepted_shares"] = stats.pop("accepted")8 stats["uptime"] = stats.pop("uptime_in_seconds") return stats @staticmethod) def get_lolminer_stats(lolminer_url): stats = {} try:@ data = CoinmineRequests.get(lolminer_url, "summary") stats = {4 "uptime": data["Session"]["Uptime"],C "hashrate": data["Session"]["Performance_Summary"],N "hashrate_list": [gpu["Performance"] for gpu in data["GPUs"]],? "accepted_shares": data["Session"]["Accepted"],? "rejected_shares": data["Session"]["Submitted"]. - data["Session"]["Accepted"],8 "pool": data["Stratum"]["Current_Pool"], } except Exception as e:H logger.warning("could not get lolminer stats: {}".format(e)) return stats @staticmethod* def get_sixminer_stats(handshake_url):; return MinerRequests.get_local_stats(handshake_url) @staticmethod# def get_xmrig_stats(xmrig_url): stats = {} try:? data = CoinmineRequests.get(xmrig_url, "1/summary") stats = {) "uptime": data["uptime"],> "hashrate": data["hashrate"]["total"][0] or 0,\ "hashrate_list": [thread[0] or 0 for thread in data["hashrate"]["threads"]],B "accepted_shares": data["results"]["shares_good"],B "rejected_shares": data["results"]["shares_total"]1 - data["results"]["shares_good"],3 "pool": data["connection"]["pool"], } except Exception as e:E logger.warning("could not get xmrig stats: {}".format(e)) return stats @staticmethod def get_local_stats(url): stats = {} try:5 data = CoinmineRequests.get(url, "stats")W stats = {"hashrate": data["hashrate"], "hashrate_list": [data["hashrate"]]} except Exception as e:E logger.warning("could not get local stats: {}".format(e)) return stats @staticmethod def _is_hashing(hashrate):$ return bool(float(hashrate))5Б_– 9L¤¤¤¤_†’w х8:P s.sendall(b'{"id":0,"jsonrpc":"2.0","method":"miner_getstat1"}')5Б_– 1¤¤¤¤>+1v_†Џxх0?D with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: logger.debug(: "attempting to connect to claymore rpc on"- " {}".format(claymore_socket) )& s.connect(claymore_socket)5 logger.debug("connected to claymore rpc") s.settimeout(60)L s.sendall(b'{"id":0,"jsonrpc":"2.0","method":"miner_getstat2"}')? logger.debug("sent json for stats to claymore rpc") data = s.recv(1024); logger.debug("received data from claymore rpc")# string_data = data.decode()+ json_data = json.loads(string_data)5Б_– 1¤¤¤¤>'1v_†Џxх0?@ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: logger.debug(6 "attempting to connect to claymore rpc on") " {}".format(claymore_socket) )" s.connect(claymore_socket)1 logger.debug("connected to claymore rpc") s.settimeout(60)H s.sendall(b'{"id":0,"jsonrpc":"2.0","method":"miner_getstat2"}'); logger.debug("sent json for stats to claymore rpc") data = s.recv(1024)7 logger.debug("received data from claymore rpc") string_data = data.decode()' json_data = json.loads(string_data)5Б_–1¤¤¤¤1>V_†Џyх0?<with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: logger.debug(2 "attempting to connect to claymore rpc on"% " {}".format(claymore_socket) ) s.connect(claymore_socket)- logger.debug("connected to claymore rpc") s.settimeout(60)D s.sendall(b'{"id":0,"jsonrpc":"2.0","method":"miner_getstat2"}')7 logger.debug("sent json for stats to claymore rpc") data = s.recv(1024)3 logger.debug("received data from claymore rpc")string_data = data.decode()#json_data = json.loads(string_data)5Б_–с¤¤¤¤^Вh™хрт stats = { }5Б_–с¤¤¤¤^ВhЂхстхтухту% "accepted_shares": 0,$ "hashrate": 1041.74,: "hashrate_list": [578.02, 231.77, 231.93],: "pool": "xmr-us-east1.nanopool.org:14444",% "rejected_shares": 0, "uptime": 205,5Бз™
Vim�UnDo������.��� U�{��~�`|8h��Q2 {'power-down': True})"%5555\��?_�����\��`�>�>5�_�����\��e�?Nfrom utils import SystemHelpers, CoinmineRequests, CoinmineLogger, sentry_init5�_�?����\�N��?5�_�@����\�N��@�A�@5�_�A����\�O�@A2signal.signal(signal.SIGTERM, signal_term_handler)5�_�����\�O�A�A�@5�_�����V\�O�B2signal.signal(signal.SIGTERM, signal_term_handler)5�_� ����V\�O�6 signal.signal(signal.SIGTERM, signal_term_handler)5�_� ����V\�O�A�A5�_� ����V\�O�C�B5�_� ����V\�O �5�_� B����V\�O8�B�C�B5�_� D ����V\�O?�CEE print 'got SIGTERM'5�_� D����V\�OA�CEE print ()'got SIGTERM'5�_�D����V\�OE�CD print ('got SIGTERM')5�_�C����V\�OF�CEE �CED5�_�D/����V\�OY�CEE0 logger.info('got signal handler, signal={}')5�_�B����V\�O_�BDE5�_�4+����V\�Of�36FL **CoinmineRequests.get(minary_api_server_url, 'config'),5�_�6+����V\�Oh�58GQ **CoinmineRequests.get(minary_api_server_url, 'system_info'),5�_�8+����V\�Oj �7:HR **CoinmineRequests.get(minary_api_server_url, 'miner_status'),5�_�<����V\�Om �;<5�_�D����DHV\�Ox�CD'def signal_term_handler(signal, frame):? logger.info('got signal handler, signal={}'.format(signal)) sys.exit(0)5�_� ����DDV\�O{�D�D� C5�_� ����JJV\�O|� 5�_�����IIV\�O}�H5�_�����JJV\�QK�I5�_�����KKV\�Q��K �J5�_�����LLV\�R�K CoinmineRequests.put()5�_�>����LLV\�R�K? CoinmineRequests.put(minary_api_server_url, 'miner_status')5�_� M����LLV\�R$ �KO CoinmineRequests.put(minary_api_server_url, 'miner_status', {'power-down'})5�_�! /����LLV\�R,�KU CoinmineRequests.put(minary_api_server_url, 'miner_status', {'power-down': True})5�_� "!(����MMV\�R.�L> 'miner_status', {'power-down': True})5�_�!#"���� V \�S��'def signal_term_handler(signal, frame):? logger.info('got signal handler, signal={}'.format(signal))/ CoinmineRequests.put(minary_api_server_url,( 'miner_status',. {'power-down': True}) sys.exit(0)5�_�"$#���� V \�S��G�G�F5�_�#%$����V\�S��N'def signal_term_handler(signal, frame):? logger.info('got signal handler, signal={}'.format(signal))/ CoinmineRequests.put(minary_api_server_url,( 'miner_status',. {'power-down': True}) sys.exit(0)5�_�$&%����V\�S��5�_�%'&����V\�S��5�_�&('����V\�S��+ def signal_term_handler(signal, frame):C logger.info('got signal handler, signal={}'.format(signal))3 CoinmineRequests.put(minary_api_server_url,+ 'miner_status',1 {'power-down': True}) sys.exit(0)5�_�')(����V\�S��F�F5�_�(*)����V\�S��L+ 'miner_status',5�_�)+*����V\�S��L1 {'power-down': True})5�_�*,+���� V\�S��5�_�+-,����V\�S��+ def signal_term_handler(signal, frame):C logger.info('got signal handler, signal={}'.format(signal))3 CoinmineRequests.put(minary_api_server_url,, 'miner_status',2 {'power-down': True}) sys.exit(0)6 signal.signal(signal.SIGTERM, signal_term_handler)5�_�,.-����V\�S��%B�B5�_�-/.����V\�S��K�J5�_�.0/#����\�X�#%K�#$K5�_�/10$����$$V\�X�#%L% ambiance.run(full_status)5�_�021#����04V\�X$�#)L�#$L5�_�132$����$(V\�X%�#)Q full_status = {@ **CoinmineRequests.get(minary_api_server_url, 'config'),E **CoinmineRequests.get(minary_api_server_url, 'system_info'),F **CoinmineRequests.get(minary_api_server_url, 'miner_status'), }5�_�243#����$(V\�Y �"# sys.exit(0)5�_�354(����#'V\�Y�(*P�()P5�_�45"%����\��>�!#Q2 {'power-down': True})5��
VimUnDoхЖvНІвHЏ!ы+няЇеRњД0Хш_; logger.warn("Health Monitor failed e={}".format(e))]^q8L_аџџџџ^_Яѕ> amdgpu_info_path = os.environ["MINARY_AMDGPU_PM_INFO"]5_аCџџџџ^_еѕBDaF amdgpu_info_path, num_of_gpus, integrated_graphics_enabled5_аCџџџџ^_жѕa import os/from utils import CoinmineLogger, SystemHelpers+from utils.requests import CoinmineRequestsXfrom health_monitor.docker import MinaryDocker, MinaryDockerCompose, DockerHealthChecker4from health_monitor.miner import AMDGPUHealthCheckerfrom adapters import AMDGPUInfo5from health_monitor.system import SystemHealthChecker3# from health_monitor.pool import PoolHealthChecker!logger = CoinmineLogger(__name__)if __name__ == "__main__":3 logger.info("Starting Coinmine Health Monitor") try:! hardreboot = "hardreboot"C restart_minary_compose = "systemctl restart minary-compose"G gpu_mineable_coins = ["ethereum", "zcash", "grin", "handshake"]' cpu_mineable_coins = ["monero"] # envsC minary_api_server_url = os.environ["MINARY_API_SERVER_URL"]@ compose_filename = os.environ["MINARY_COMPOSE_FILENAME"]W mem_clock_low_threshold = int(os.environ["MINARY_AMDGPU_MEMCLK_LOW_THRESHOLD"])' mem_clock_high_threshold = int(= os.environ["MINARY_AMDGPU_MEMCLK_HIGH_THRESHOLD"] )X gpu_load_low_threshold = int(os.environ["MINARY_AMDGPU_GPU_LOAD_LOW_THRESHOLD"])T gpu_watt_low_threshold = int(os.environ["MINARY_AMDGPU_WATT_LOW_THRESHOLD"])R mem_percent_threshold = int(os.environ["MINARY_MEMORY_PERCENT_THRESHOLD"])$ # wait for minary_api_server logger.info(7 "wait for minary_api_server: {}/{}".format(5 minary_api_server_url, "miner_status" ) )* SystemHelpers.wait_for_connection(V lambda: (CoinmineRequests.test_get(minary_api_server_url, "miner_status")) )R miner_status = CoinmineRequests.get(minary_api_server_url, "miner_status")' coin = miner_status.get("coin")8 num_of_gpus = miner_status.get("num_of_gpus", 0)- address = miner_status.get("address")3 admin_api_url = miner_status.get("api_url")1 short_uuid = miner_status.get("uuid")[:8]U integrated_graphics_enabled = miner_status.get("integrated_graphics_enabled") # Docker& minary_docker = MinaryDocker()) minary_docker.initialize_client()E minary_docker_compose = MinaryDockerCompose(compose_filename)0 oneshot_services = ["bootup_controller"]4 docker_health_checker = DockerHealthChecker( minary_docker," minary_docker_compose, oneshot_services,# restart_minary_compose, ) # AMDGPU! amdgpu_info = AMDGPUInfo(5 num_of_gpus, integrated_graphics_enabled )4 amdgpu_health_checker = AMDGPUHealthChecker( amdgpu_info, hardreboot,$ mem_clock_low_threshold,% mem_clock_high_threshold,# gpu_load_low_threshold,# gpu_watt_low_threshold, admin_api_url, miner_status, ) # System4 system_health_checker = SystemHealthChecker(; miner_status, mem_percent_threshold, hardreboot ) # PoolX # pool_health_checker = PoolHealthChecker(coin, address, short_uuid, hardreboot) # Checks% docker_health_checker.check()% system_health_checker.check()& if coin in gpu_mineable_coins:) amdgpu_health_checker.check()% # pool_health_checker.check() except Exception as e:; logger.warn("Health Monitor failed e={}".format(e))3 logger.info("Finished Coinmine Health Monitor")5_а]џџџџ^q8Kѕ\^_; logger.warn("Health Monitor failed e={}".format(e))5чЊ
VimUnDoוa_®�±¢±7�פM²�¨F~ך�°כ�+W�¯DIJ logger.warn("could not return grin miner stats", {"error": e})F,,,,\�ל5 _�$/����\��ץ#%I logger.debug("received miner status {}".format(miner_status))5_�$0����\��ץ#%> logger.debug("received miner status(miner_status))5_�$@����\��ץ#%@ logger.debug("received miner status", miner_status))5_�&4����\��ץ%'E logger.error("failed to get miner status e={}".format(e))5_�&4����\��ץ%'4 logger.error("failed to get miner status5_�&9����\��ץ%'9 logger.error("failed to get miner status", ""5_�&?����\��ץ%'@ logger.error("failed to get miner status", {"error"}5_� &C����\��ץ%'C logger.error("failed to get miner status", {"error": e}5_� 1:����\�מץ02> "attempting to connect to claymore rpc on"5_� 1:����\�ןץ02: "attempting to connect to claymore rpc5_� 1:����\�סץ02; "attempting to connect to claymore rpc"1 " {}".format(claymore_socket)5_� 1;����\�עץ02Y "attempting to connect to claymore rpc" " {}".format(claymore_socket)5_� 1<����\�ףץ02L "attempting to connect to claymore rpc"(claymore_socket)5_� 1=����\�רץ02N "attempting to connect to claymore rpc", "claymore_socket)5_�1?����\�שץ02P "attempting to connect to claymore rpc", {}"claymore_socket)5_�1N����\��ץ02O "attempting to connect to claymore rpc", {"claymore_socket)ץ125_�1a����\�ץ02b "attempting to connect to claymore rpc", {"claymore_socket": claymore_socket))5_�1b����\�ץ02b "attempting to connect to claymore rpc", {"claymore_socket": claymore_socket})5_�1`����\�ץ import socketimport json from utils import CoinmineLogger+from utils.requests import CoinmineRequests!logger = CoinmineLogger(__name__)class MinerRequests: @staticmethodN def get_miner_status(coin, claymore_socket, xmr_stak_url, grin_miner_url): # we assume not mining miner_status = { "uptime": 0, "hashrate": 0,! "hashrate_list": [0],! "accepted_shares": 0,! "rejected_shares": 0, "fan_speed": 0, "temp": 0, "pool": "", "errors": [], } try: miners = {V "ethereum": lambda: MinerRequests.get_claymore_stats(claymore_socket),S "zcash": lambda: MinerRequests.get_claymore_stats(claymore_socket),Q "monero": lambda: MinerRequests.get_xmr_stak_stats(xmr_stak_url),S "grin": lambda: MinerRequests.get_grin_miner_stats(grin_miner_url),K None: lambda: {"errors": "missing coin value from config"}, }= miner_status = {**miner_status, **miners[coin]()}? logger.debug("received miner status", miner_status) except Exception as e:D logger.error("failed to get miner status", {"error": e})X miner_status["mining"] = MinerRequests._is_hashing(miner_status.get("hashrate")) return miner_status @staticmethod, def get_claymore_stats(claymore_socket): try:H with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: logger.debug(a "attempting to connect to claymore rpc", {"claymore_socket": claymore_socket} )* s.connect(claymore_socket)9 logger.debug("connected to claymore rpc") s.settimeout(60)P s.sendall(b'{"id":0,"jsonrpc":"2.0","method":"miner_getstat1"}')C logger.debug("sent json for stats to claymore rpc")# data = s.recv(1024)? logger.debug("received data from claymore rpc")' string_data = data.decode()/ json_data = json.loads(string_data)- result_list = json_data["result"]* uptime_in_min = result_list[1]: accepted_shares = result_list[2].split(";")[1]: rejected_shares = result_list[2].split(";")[2]% hashrate = result_list[3] # multigpu if ";" in hashrate:E hashrate_list = list(map(float, hashrate.split(";")))- hashrate = sum(hashrate_list) else:1 hashrate_list = [float(hashrate)]4 fan_speed = result_list[6].split(";")[1]/ temp = result_list[6].split(";")[0]! pool = result_list[7] stats = {4 "uptime": int(float(uptime_in_min)),* "hashrate": int(hashrate),/ "hashrate_list": hashrate_list,8 "accepted_shares": int(accepted_shares),8 "rejected_shares": int(rejected_shares),, "fan_speed": int(fan_speed)," "temp": int(temp), "pool": pool, }C logger.debug("claymore socket stats: {}".format(stats)) return stats except Exception as e: logger.warn(T "could not handle sending or receiving from socket:" " {}".format(e) )B return {"errors": "claymore http service unavailable"} @staticmethod) def get_xmr_stak_stats(xmr_stak_url): try:B stats = CoinmineRequests.get(xmr_stak_url, "api.json"). pool = stats["connection"]["pool"]9 uptime_in_sec = stats["connection"]["uptime"]4 # will report 0 if a single thread fails4 hashrate = stats["hashrate"]["total"][0] if hashrate is None: hashrate = 0= accepted_shares = stats["results"]["shares_good"]P rejected_shares = stats["results"]["shares_total"] - accepted_shares8 # None values come from failed gpus/threads,7 # we want to accurately report the hashrate$ # even if a thread fails8 hashrate_list = stats["hashrate"]["threads"] # convert None to 0P hashrate_list = [0 if i[0] is None else i[0] for i in hashrate_list]> total_hashrate_threads = round(sum(hashrate_list)) return {2 "uptime": int(uptime_in_sec / 60),D "hashrate": int(hashrate) or total_hashrate_threads,/ "hashrate_list": hashrate_list,8 "accepted_shares": int(accepted_shares),8 "rejected_shares": int(rejected_shares), "pool": pool, } except Exception as e:I logger.warn("could not return xmr-stak stats e={}".format(e))B return {"errors": "xmr-stak http service unavailable"}- def get_grin_miner_stats(grin_miner_url): try:A stats = CoinmineRequests.get(grin_miner_url, "stats")5 hashrate = stats["results"]["graph_rate"]F return {"hashrate": hashrate, "hashrate_list": [hashrate]} except Exception as e:K logger.warn("could not return grin miner stats e={}".format(e))D return {"errors": "grin miner http service unavailable"} @staticmethod def _is_hashing(hashrate):) return bool(int(float(hashrate)))5_�U#����\�ץTVC logger.debug("claymore socket stats: {}".format(stats))5_�U#����\�ץTVC logger.debug("claymore socket stats: {}".format(stats))5_�U����\�ץTVC logger.debug("claymore socket stats: {}".format(stats))5_�U9����\� ץTVL logger.debug("recieved claymore socket stats: {}".format(stats))5_�U9����\�!ץTVL logger.debug("recieved claymore socket stats" {}".format(stats))5_�U9����\�"ץTV9 logger.debug("recieved claymore socket stats"5_�YB����\�.ץXZT "could not handle sending or receiving from socket:" " {}".format(e)5_�YB����\�0ץXZB "could not handle sending or receiving from socket5_�YM����\�4ץXZN "could not handle sending or receiving from socket", {"error"}5_� ~7����\�Eץ}I logger.warn("could not return xmr-stak stats e={}".format(e))ץ~5_�! ~G����\�Fץ}X logger.warn("could not return xmr-stak stats", {"error": e} e={}".format(e))5_� #!~G����\�Jץ}G logger.warn("could not return xmr-stak stats", {"error": e}5_�!$"#9����\�UץK logger.warn("could not return grin miner stats e={}".format(e))ץ5_�#%$J����\�V ץ[ logger.warn("could not return grin miner stats", {"error": e}) e={}".format(e))5_�$&%&@����\�ל'ץ%'D logger.error("failed to get miner status", {"error": e})ץ&'5_�%'&&F����\�ל( ץ%'H logger.error("failed to get miner status", {"error": str(e})5_�&('YN����\�ל+ץXZQ "could not handle sending or receiving from socket", {"error": e}ץYZ5_�')(YT����\�ל,ץXZU "could not handle sending or receiving from socket", {"error": str(e}5_�(*)~D����\�ל/ץ}H logger.warn("could not return xmr-stak stats", {"error": e})ץ~5_�)+*~J����\�ל0ץ}L logger.warn("could not return xmr-stak stats", {"error": str(e})5_�*,+F����\�ל3ץJ logger.warn("could not return grin miner stats", {"error": e})ץ5_�+,L����\�ל4 ץN logger.warn("could not return grin miner stats", {"error": str(e})5_�!#"~8����\�Qץ}8 logger.warn("could not return xmr-stak stats5_�YB����\�AץXZB "could not handle sending or receiving from socket5_�1?����\�תץ02? "attempting to connect to claymore rpc", {"5ח×
Vim�UnDo��8�o� ϖ�(����6��_v�8���,�(+9 logger.warn("No teensy device detected! Exiting")^q8�_�����^q8��+9 logger.warn("No teensy device detected! Exiting")5�_� =����++v]���+@ minary_ambiance_server_url = os.environ["MINARY_SERVER_URL"]5�_� 4����++v]���+D minary_ambiance_server_url = os.environ["MINARY_API_SERVER_URL"]5�_� ����++v]���+? minary_api_server_url = os.environ["MINARY_API_SERVER_URL"]5�_�>����++v]���+N "waiting for connection: {}/{}".format(minary_api_server_url, "state")5�_�9����++v]���+I lambda: CoinmineRequests.test_get(minary_api_server_url, "state")5�_�0����++v]��� +@ state = CoinmineRequests.get(minary_api_server_url, "state")5�_� "0����++v]���!#+G teensy_interface, state, minary_api_server_url, animation_queue5�_� "*����v]� �,) import os import sysDfrom thunder_and_lightning.utils import SerialUtils, TeensyInterfacePfrom thunder_and_lightning.controllers import AmbianceController, AnimationQueue<from utils import SystemHelpers, CoinmineLogger, sentry_init+from utils.requests import CoinmineRequests sentry_init()if __name__ == "__main__":% logger = CoinmineLogger(__name__)? minary_api_server_url = os.environ["MINARY_API_SERVER_URL"]5 script_path = os.environ["MINARY_TL_SCRIPT_PATH"]2 logger.info("Starting Light and Sound Worker")/ teensy_path = SerialUtils.get_teensy_port() if not teensy_path:9 logger.warn("No teensy device detected! Exiting") sys.exit(1)@ teensy_interface = TeensyInterface(teensy_path, script_path)& teensy_interface.set_serial_port()W logger.info("waiting for connection: {}/{}".format(minary_api_server_url, "state"))& SystemHelpers.wait_for_connection(I lambda: CoinmineRequests.test_get(minary_api_server_url, "state") )@ state = CoinmineRequests.get(minary_api_server_url, "state")& animation_queue = AnimationQueue()" ambiance = AmbianceController(G teensy_interface, state, minary_api_server_url, animation_queue ) try: while True:) ambiance.run_animation_step() except Exception as e:L logger.error("Could not run light and sound service e={}".format(e)) sys.exit(1)5�_� >����v]�"��)G state = CoinmineRequests.get(minary_api_server_url, "miner_status")5�_� G����v]�"��)P lambda: CoinmineRequests.test_get(minary_api_server_url, "miner_status")5��