Vim�UnDo��U�'�������(Ɣ��j��^��DX amdgpu_info, amdgpu_remedy_cmd, mem_clock_threshold, admin_api_url, miner_status52 \��_�-����\���!>� >5�_� ����\���!?K mem_clock_threshold = int(os.environ["MINARY_AMDGPU_MEMCLK_THRESHOLD"])5�_�����\��� ?K mem_clock_threshold = int(os.environ["MINARY_AMDGPU_MEMCLK_THRESHOLD"])5�_�C����\��� ?O mem_clock_low_threshold = int(os.environ["MINARY_AMDGPU_MEMCLK_THRESHOLD"])5�_� D����\���!?P mem_clock_high_threshold = int(os.environ["MINARY_AMDGPU_MEMCLK_THRESHOLD"])5�_�52����\���46?X amdgpu_info, amdgpu_remedy_cmd, mem_clock_threshold, admin_api_url, miner_status5�_� 5@����5'5?v?\���46?\ amdgpu_info, amdgpu_remedy_cmd, mem_clock_low_threshold, admin_api_url, miner_status�56?5�_� 5O����5'5?v?\���46?u amdgpu_info, amdgpu_remedy_cmd, mem_clock_low_threshold, mem_clock_low_threshold,admin_api_url, miner_status5�_� 5O����5'5?v?\���? import os/from utils import CoinmineLogger, SystemHelpers+from utils.requests import CoinmineRequestsXfrom health_monitor.docker import MinaryDocker, MinaryDockerCompose, DockerHealthChecker@from health_monitor.miner import AMDGPUHealthChecker, AMDGPUInfo5from health_monitor.system import SystemHealthChecker!logger = CoinmineLogger(__name__)if __name__ == "__main__":3 logger.info("Starting Coinmine Health Monitor") # Docker" minary_docker = MinaryDocker()% minary_docker.initialize_client()< compose_filename = os.environ["MINARY_COMPOSE_FILENAME"]A minary_docker_compose = MinaryDockerCompose(compose_filename): docker_remedy_cmd = "systemctl restart minary-compose"0 docker_health_checker = DockerHealthChecker(? minary_docker, minary_docker_compose, docker_remedy_cmd )! docker_health_checker.check() # AMDGPU: amdgpu_info_path = os.environ["MINARY_AMDGPU_PM_INFO"]S mem_clock_low_threshold = int(os.environ["MINARY_AMDGPU_MEMCLK_LOW_THRESHOLD"])U mem_clock_high_threshold = int(os.environ["MINARY_AMDGPU_MEMCLK_HIGH_THRESHOLD"])? minary_api_server_url = os.environ["MINARY_API_SERVER_URL"]$ amdgpu_remedy_cmd = "hardreboot" # wait for minary_api_server logger.info(3 "wait for minary_api_server: {}/{}".format(1 minary_api_server_url, "miner_status" ) )& SystemHelpers.wait_for_connection(R lambda: (CoinmineRequests.test_get(minary_api_server_url, "miner_status")) )N miner_status = CoinmineRequests.get(minary_api_server_url, "miner_status")# coin = miner_status.get("coin")X admin_api_url = CoinmineRequests.get(minary_api_server_url, "config").get("api_url")T num_of_gpus = CoinmineRequests.sanitize_redis_value(miner_status, "num_of_gpus"); amdgpu_info = AMDGPUInfo(amdgpu_info_path, num_of_gpus)0 amdgpu_health_checker = AMDGPUHealthChecker(v amdgpu_info, amdgpu_remedy_cmd, mem_clock_low_threshold, mem_clock_high_threshold,admin_api_url, miner_status )! amdgpu_health_checker.check() # SystemN mem_percent_threshold = int(os.environ["MINARY_MEMORY_PERCENT_THRESHOLD"])$ system_remedy_cmd = "hardreboot"0 system_health_checker = SystemHealthChecker(> miner_status, mem_percent_threshold, system_remedy_cmd )! system_health_checker.check()5�_� ����\���!?J mem_clock_threshol = int(os.environ["MINARY_AMDGPU_MEMCLK_THRESHOLD"])5��
VimUnDoхє§УCф~зuЗЛјЁил&Уѓ`Цm:fТTj-/]ЉѓЭ_аџџџџ]Іѕѕ5_аџџџџ]Іѕ5_аџџџџ]Іѕѕ5_аџџџџ]Іѕ$logger = logging.getLogger(__name__)5_аџџџџ]Іѕimport logging5_аџџџџ]Іѕ5_аџџџџ]Јrѕ,ѕѕ5_а џџџџ V]Јtѕimport logging$logger = logging.getLogger(__name__)5_а (џџџџ(7V]Јyѕ'( class PubSub:, def __init__(self, url, channel_prefix): self.url = url, self.channel_prefix = channel_prefix def key(self, channel_id): if not channel_id:F raise ("No prefix supplied for {}".format(self.__class__))> return "{}:{}".format(self.channel_prefix, channel_id) def close(self): try:# self.connection.close() except Exception as e:K logger.warn("Could not close pubsub connection e={}".format(e))5_а 'џџџџ((V]Јzѕ' from utils import CoinmineLogger!logger = CoinmineLogger(__name__) class PubSub:W def __init__(self, url, channel_prefix, channel_id, environment=None, region=None): self.url = url, self.channel_prefix = channel_prefix$ self.channel_id = channel_id self.env = environment self.region = region def configure(self): pass def publish(self): pass def subscribe(self): pass def get_message(self): pass def key(self): if not self.channel_id:F raise ("No prefix supplied for {}".format(self.__class__))C return "{}:{}".format(self.channel_prefix, self.channel_id) def close(self): try:# self.connection.close() except Exception as e:K logger.warn("Could not close pubsub connection e={}".format(e)) def cleanup(self): pass5_а #џџџџ''V]Јѕ"$&K logger.warn("Could not close pubsub connection e={}".format(e))5_а #џџџџ''V]ЈЃѕ"$&N logger.warning("Could not close pubsub connection e={}".format(e))5_а џџџџ]ЉѓШѕ1&ѕ&5_а џџџџ]ЉѓЩѕ5_а0џџџџ0QV]ЉѓЬѕ/0" class PubSub:W def __init__(self, url, channel_prefix, channel_id, environment=None, region=None): self.url = url, self.channel_prefix = channel_prefix$ self.channel_id = channel_id self.env = environment self.region = region def configure(self): pass def publish(self): pass def subscribe(self): pass def get_message(self): pass def key(self): if not self.channel_id:F raise ("No prefix supplied for {}".format(self.__class__))C return "{}:{}".format(self.channel_prefix, self.channel_id) def close(self): try:# self.connection.close() except Exception as e:K logger.warn("Could not close pubsub connection e={}".format(e)) def cleanup(self): pass5чЊ
����/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υ ) s3_config["cm_install_host_path",υ 5�_Π!#" ����/V/\Σ:Kυ υ
VimUnDoх3ОрЋc|@HЉцтSрЂP"м@'веJ((((].CЫ_аџџџџ].@,ѕѕ5_аџџџџ].@<ѕѕ5_аџџџџ].@=ѕ5_аџџџџ].@Dѕ ѕ 5_а џџџџ].@Fѕ pass5_а џџџџ].@ѕ@ logger.debug("docker health check reported healthy")5_а,џџџџ].@Ђѕ? logger.debug("docke health check reported healthy")5_а .џџџџ].@Їѕ/ logger.debug("{} reported healthy")5_а Lџџџџ].@Вѕclass BaseHealthChecker: def check(self): if self._is_healthy():O logger.debug("{} reported healthy".format(self.__class__.__name__)) else:W logger.error("docker health check reported unhealthy, restarting services")H DockerHealthChecker._restart_minary_compose(self.remedy_cmd) def _is_healthy(self): pass def remedy(self): pass5_а -џџџџ].@Йѕ W logger.error("docker health check reported unhealthy, restarting services")5_а Dџџџџ].@Пѕ F logger.error("{} reported unhealthy, restarting services")5_аHџџџџ].@Чѕ I logger.error("{} reported unhealthy, running remedy command")5_а Oџџџџ].@Яѕ R logger.error("{} reported unhealthy, running remedy command".format())ѕ 5_аfџџџџ].@аѕ class BaseHealthChecker: def check(self): if self._is_healthy():O logger.debug("{} reported healthy".format(self.__class__.__name__)) else:i logger.error("{} reported unhealthy, running remedy command".format(self.__class__.__name__))H DockerHealthChecker._restart_minary_compose(self.remedy_cmd) def _is_healthy(self): pass def remedy(self): pass5_аџџџџ].Bѕѕ5_аџџџџ].Bѕ5_аџџџџ].Bѕ from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class BaseHealthChecker: def check(self): if self._is_healthy():O logger.debug("{} reported healthy".format(self.__class__.__name__)) else: logger.error(G "{} reported unhealthy, running remedy command".format(+ self.__class__.__name__ ) )H DockerHealthChecker._restart_minary_compose(self.remedy_cmd) def _is_healthy(self): pass def remedy(self): pass5_аџџџџ].BѕH DockerHealthChecker._restart_minary_compose(self.remedy_cmd)5_а(џџџџ].BЁѕ9 self._restart_minary_compose(self.remedy_cmd)5_аџџџџ].Bѕ1 self._run_remedy_cmd(self.remedy_cmd)5_аџџџџ].BЧѕѕ5_аџџџџ].BШѕ pass5_аџџџџ].BЩѕ def remedy(self):5_аџџџџ].BЮѕ! def _run_remedy_remedy(self):5_аџџџџ].Bиѕѕ5_аџџџџ].Bйѕ5_аџџџџ].Bрѕ def _run_remedy_cmd(self):5_а#џџџџ].Bчѕ, subprocess.run(shlex.split(command))5_а.џџџџ].Bь ѕ7 subprocess.run(shlex.split(self.remed_command))5_а џџџџ].Bё ѕ def _run_remedy_cmd(self):5_а! џџџџ].Bїѕ1 self._run_remedy_cmd(self.remedy_cmd)5_а "!џџџџV"].Cѕ ѕ5_а!#"џџџџV"].Cѕ$ raise("Should be implement")5_а"$#џџџџV"].Cѕ0 raise("This method Should be implement")5_а#%$.џџџџV"].Cѕ0 raise("This method should be implement")5_а$&%DџџџџV"].Cѕimport subprocessimport shlex from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class BaseHealthChecker: def check(self): if self._is_healthy():O logger.debug("{} reported healthy".format(self.__class__.__name__)) else: logger.error(G "{} reported unhealthy, running remedy command".format(+ self.__class__.__name__ ) )5 self._run_remedy_command(self.remedy_cmd) def _is_healthy(self):G raise("This method should be implemented by the derived class") pass" def _run_remedy_command(self):8 subprocess.run(shlex.split(self.remedy_command))5_а%'&џџџџV"].Cѕ pass5_а&('џџџџV].CЩѕimport subprocessimport shlex from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class BaseHealthChecker: def check(self): if self._is_healthy():O logger.debug("{} reported healthy".format(self.__class__.__name__)) else: logger.error(G "{} reported unhealthy, running remedy command".format(+ self.__class__.__name__ ) )5 self._run_remedy_command(self.remedy_cmd) def _is_healthy(self):H raise ("This method should be implemented by the derived class")" def _run_remedy_command(self):8 subprocess.run(shlex.split(self.remedy_command))5_а'(џџџџV].CЪѕ5_а 6џџџџ].@Эѕ 8 logger.debug("{} reported healthy".format())5чЊ
Vim�UnDo��a�K�*���߸��UV��W�1��5q�7class RedisPubSub(PubSub): ]�� _� ����]�M�57from coinmine.pubsub.services.pubsub_base import PubSub5�_� ����]�Q�56from coinmin.pubsub.services.pubsub_base import PubSub5�_�����]�X�54from minarypubsub.services.pubsub_base import PubSub5�_�����]�\�5;from minary.pubsubpubsub.services.pubsub_base import PubSub5�_� ����]�a�5 from minary.pubsub import PubSub5�_� ����]�j� 5class RedisPubSub(PubSub):5�_� ����]�"�55�_� ����]�'�6�65�_� ����]�(�$logger = logging.getLogger(__name__)5�_� ����]�*�import logging5�_� ����]�-�5�55�_� ����]����76� 65�_� 7����7dV]����67.class RedisPubSub(PubSubBase): def initialize(self): try:C self.redis = self.connection = redis.from_url(self.url)K self.pubsub = self.redis.pubsub(ignore_subscribe_messages=True)0 except redis.exceptions.ConnectionError:A logger.error("Could not connect to Redis for pubsub") return self+ def publish(self, channel_id, message): try:I self.redis.publish(self.key(channel_id), json.dumps(message)) except Exception as e: logger.error(P "Could not publish to pubsub uuid={} e={}".format(channel_id, e) )$ def subscribe(self, channel_id):& channel = self.key(channel_id) if "*" in channel: try:< self.pubsub.psubscribe(self.key(channel_id))" except Exception as e: logger.error(L "Could not psubscribe to pubsub pattern={} e={}".format(% channel_id, e ) ) else: try:. self.pubsub.subscribe(channel)" except Exception as e: logger.error(V "Could not subscribe to pubsub uuid={} e={}".format(channel_id, e) ) def get_message(self): message = None try:/ message = self.pubsub.get_message(): if message["type"] in ["message", "pmessage"]:2 return json.loads(message["data"]) except TypeError: pass return message5�_�6����77V]����6import jsonimport redis.from minary.pubsub import PubSub as PubSubBase from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class RedisPubSub(PubSub): def configure(self): try:C self.redis = self.connection = redis.from_url(self.url)K self.pubsub = self.redis.pubsub(ignore_subscribe_messages=True)0 except redis.exceptions.ConnectionError:A logger.error("Could not connect to Redis for pubsub") def publish(self, message): try:? self.redis.publish(self.key(), json.dumps(message)) except Exception as e: logger.error(U "Could not publish to pubsub uuid={} e={}".format(self.channel_id, e) ) def subscribe(self): channel = self.key() if "*" in channel: try:/ self.pubsub.psubscribe(channel)" except Exception as e: logger.error(L "Could not psubscribe to pubsub pattern={} e={}".format(* self.channel_id, e ) ) else: try:. self.pubsub.subscribe(channel)" except Exception as e: logger.error(H "Could not subscribe to pubsub uuid={} e={}".format(* self.channel_id, e ) ) def get_message(self): message = None try:/ message = self.pubsub.get_message(): if message["type"] in ["message", "pmessage"]:2 return json.loads(message["data"]) except TypeError: pass return message5�_�����88V]����5�_� ����77V]�� � 6class RedisPubSub(PubSub):5�_� ����77V]���6import jsonimport redis.from minary.pubsub import PubSub as PubSubBase from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class RedisPubSub(PubSubBase): def configure(self): try:C self.redis = self.connection = redis.from_url(self.url)K self.pubsub = self.redis.pubsub(ignore_subscribe_messages=True)0 except redis.exceptions.ConnectionError:A logger.error("Could not connect to Redis for pubsub") def publish(self, message): try:? self.redis.publish(self.key(), json.dumps(message)) except Exception as e: logger.error(U "Could not publish to pubsub uuid={} e={}".format(self.channel_id, e) ) def subscribe(self): channel = self.key() if "*" in channel: try:/ self.pubsub.psubscribe(channel)" except Exception as e: logger.error(L "Could not psubscribe to pubsub pattern={} e={}".format(* self.channel_id, e ) ) else: try:. self.pubsub.subscribe(channel)" except Exception as e: logger.error(H "Could not subscribe to pubsub uuid={} e={}".format(* self.channel_id, e ) ) def get_message(self): message = None try:/ message = self.pubsub.get_message(): if message["type"] in ["message", "pmessage"]:2 return json.loads(message["data"]) except TypeError: pass return message5�_� ����]�i� 5(class RedisPubSub(PubSub): as PubSubBase5��
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�[�'�:��K~|!VE�ڵ_��f�t��Պ���2 logger.debug("running cmd={}".format(cmd))� \���_�++����\��3�*,�H logger.debug("Light & Sound has " "firmware={}".format(fw_hash))5�_�+����+','V'\��;�*+E logger.debug("Light & Sound has firmware={}".format(fw_hash))W logger.debug("Light & Sound repo has " "firmware={}".format(published_fw_hash))5�_�+����+'+'V'\��<�*+5�_��-����+'+'V'\��P����D chunk_data = result[(chunk * 128) : ((chunk + 1) * 128)]5�_��-����+'+'V'\��Q��import waveimport zlib import struct import serialimport time import reimport subprocessimport shlex from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class TeensyInterface:J def __init__(self, serial_path, script_path=None, serial_baud=115200):& self.serial_path = serial_path& self.serial_baud = serial_baud? self.firmware_path = "{}/firmware/".format(script_path)5 self.helpers_path = script_path + "/helpers/"2 self.asset_path = script_path + "/assets/" def set_serial_port(self):) self.serial_port = serial.Serial(; self.serial_path, self.serial_baud, timeout=0.1 )3 def update_firmware_if_version_different(self):$ fw_hash = self.get_version() published_fw_hash = "" try:U version_file = open(self.firmware_path + "thunder-and-lightning.version")? published_fw_hash = version_file.readline().strip() except IOError: logger.warn(A "Could not open {}thunder-and-lightning.version."M "Skipping firmware update checks.".format(self.firmware_path) ) return( if fw_hash != published_fw_hash: logger.warn(Q "Need to update from {} to {}".format(fw_hash, published_fw_hash) )# self._update_firmware() return True return False+ def flash_audio_files_if_changed(self):: # Map all of the slots on the flash to audio files audio_files = [1 (0, self.asset_path + "PowerOn.wav"),3 (1, self.asset_path + "PowerDown.wav"),5 (2, self.asset_path + "WifiConnect.wav"),8 (3, self.asset_path + "StartedSuccess.wav"), ]& for audio_file in audio_files:5 file_crc = self.calc_crc32(audio_file[1]) device_crc = 0 try:; device_crc = self.read_crc32(audio_file[0]) except ValueError: device_crc = 0 logger.info(' "{} -- File CRC32: {} "Q "-- Device CRC32: {}".format(audio_file[1], file_crc, device_crc) )& if file_crc != device_crc:- self.store_audio(*audio_file); def send_packet(self, op_code, argument, data=bytes()):V send_data = bytes([0xAA, op_code, argument, len(data)]) + data + bytes([0x55])) self.serial_port.write(send_data) def read_response(self): ret = []5 chr = self.serial_port.read().decode("utf-8") while chr != "\n": if chr != "\r": ret += chr9 chr = self.serial_port.read().decode("utf-8") return "".join(ret)7 def handle_response(self, function_name, response): """O OpCode:[OpCode]::[Return String]::Command [Success|Failed]::[ErrorCode]6 E.g. OpCode:23::2253080301::Command Success::0 """ try:# regex_match = re.match(- "OpCode:(?P<opcode>[0-9]+)::") "(?P<return_string>.*)::"> "Command (?P<success_string>Success|Failed)::") "(?P<error_code>[0-9]+)", response, ) if regex_match:B return_string = regex_match.group("return_string")J success = regex_match.group("success_string") == "Success"? err_code = int(regex_match.group("error_code")) if not success:% raise ValueError(; "ThunderAndLightningInterface::{} "B "error {}".format(function_name, err_code) )$ return return_string else:! raise ValueError(4 "ThunderAndLightningInterface::"? "Bad Response Format ({})".format(response) ) except Exception: pass def get_version(self): self.send_packet(0, 0)H return self.handle_response("get_version", self.read_response())1 def set_lights(self, state_bin, duration=33):K # Keep polling the device until we have a free command slot to fill while self.query() == 0: time.sleep(0.1)8 self.send_packet(0x04, int(duration), state_bin)@ self.handle_response("set_lights", self.read_response()) def query(self):$ self.send_packet(0x07, 0x00)G return int(self.handle_response("query", self.read_response()))' def play_audio(self, sample_index):) self.send_packet(1, sample_index)@ self.handle_response("play_audio", self.read_response())3 def store_audio(self, sample_index, file_name):/ wave_reader = wave.open(file_name, "r")> chans, res, fs, length, _, _ = wave_reader.getparams()* nframes = wave_reader.getnframes()O data = struct.unpack("<%dh" % nframes, wave_reader.readframes(nframes)) converted = [] for value in data:- converted.append(value + 2 ** 15): result = struct.pack("<%dH" % nframes, *converted) crc = zlib.crc32(result)8 # calculate number of chunks to send (fake ceil)/ chunks = int(len(result) / 128.0 + 0.5)+ # initiate a sample write operationS self.send_packet(2, sample_index, struct.pack("=3I", crc, chunks, nframes))A self.handle_response("store_audio", self.read_response())# for chunk in range(chunks):C chunk_data = result[(chunk * 128): ((chunk + 1) * 128)]@ packed_bytes = struct.pack("=I", chunk) + chunk_dataH logger.debug("Sending chunk {} of {}".format(chunk, chunks))< self.send_packet(22, sample_index, packed_bytes)E self.handle_response("store_audio", self.read_response())$ def calc_crc32(self, file_name):/ wave_reader = wave.open(file_name, "r")> chans, res, fs, length, _, _ = wave_reader.getparams()* nframes = wave_reader.getnframes()O data = struct.unpack("<%dh" % nframes, wave_reader.readframes(nframes)) converted = [] for value in data:- converted.append(value + 2 ** 15): result = struct.pack("<%dH" % nframes, *converted)! return zlib.crc32(result)' def read_crc32(self, sample_index):* self.send_packet(23, sample_index)L return int(self.handle_response("read_crc32", self.read_response())) def _update_firmware(self):@ # teensy_loader_cli --mcu=TEENSYLC -s $(HEX_OUTPUT_FILE) cmd = (" "{}teensy_loader_cli " "--mcu=TEENSYLC "7 "-s -v {}thunder-and-lightning.hex".format(5 self.helpers_path, self.firmware_path ) )2 logger.debug("running cmd={}".format(cmd))4 subprocess.run(shlex.split(cmd), timeout=10)5�_��-����''V'\��S����D chunk_data = result[(chunk * 128) : ((chunk + 1) * 128)]5�_��-����''V'\��T��import waveimport zlib import struct import serialimport time import reimport subprocessimport shlex from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class TeensyInterface:J def __init__(self, serial_path, script_path=None, serial_baud=115200):& self.serial_path = serial_path& self.serial_baud = serial_baud? self.firmware_path = "{}/firmware/".format(script_path)5 self.helpers_path = script_path + "/helpers/"2 self.asset_path = script_path + "/assets/" def set_serial_port(self):) self.serial_port = serial.Serial(; self.serial_path, self.serial_baud, timeout=0.1 )3 def update_firmware_if_version_different(self):$ fw_hash = self.get_version() published_fw_hash = "" try:U version_file = open(self.firmware_path + "thunder-and-lightning.version")? published_fw_hash = version_file.readline().strip() except IOError: logger.warn(A "Could not open {}thunder-and-lightning.version."M "Skipping firmware update checks.".format(self.firmware_path) ) return( if fw_hash != published_fw_hash: logger.warn(Q "Need to update from {} to {}".format(fw_hash, published_fw_hash) )# self._update_firmware() return True return False+ def flash_audio_files_if_changed(self):: # Map all of the slots on the flash to audio files audio_files = [1 (0, self.asset_path + "PowerOn.wav"),3 (1, self.asset_path + "PowerDown.wav"),5 (2, self.asset_path + "WifiConnect.wav"),8 (3, self.asset_path + "StartedSuccess.wav"), ]& for audio_file in audio_files:5 file_crc = self.calc_crc32(audio_file[1]) device_crc = 0 try:; device_crc = self.read_crc32(audio_file[0]) except ValueError: device_crc = 0 logger.info(' "{} -- File CRC32: {} "Q "-- Device CRC32: {}".format(audio_file[1], file_crc, device_crc) )& if file_crc != device_crc:- self.store_audio(*audio_file); def send_packet(self, op_code, argument, data=bytes()):V send_data = bytes([0xAA, op_code, argument, len(data)]) + data + bytes([0x55])) self.serial_port.write(send_data) def read_response(self): ret = []5 chr = self.serial_port.read().decode("utf-8") while chr != "\n": if chr != "\r": ret += chr9 chr = self.serial_port.read().decode("utf-8") return "".join(ret)7 def handle_response(self, function_name, response): """O OpCode:[OpCode]::[Return String]::Command [Success|Failed]::[ErrorCode]6 E.g. OpCode:23::2253080301::Command Success::0 """ try:# regex_match = re.match(- "OpCode:(?P<opcode>[0-9]+)::") "(?P<return_string>.*)::"> "Command (?P<success_string>Success|Failed)::") "(?P<error_code>[0-9]+)", response, ) if regex_match:B return_string = regex_match.group("return_string")J success = regex_match.group("success_string") == "Success"? err_code = int(regex_match.group("error_code")) if not success:% raise ValueError(; "ThunderAndLightningInterface::{} "B "error {}".format(function_name, err_code) )$ return return_string else:! raise ValueError(4 "ThunderAndLightningInterface::"? "Bad Response Format ({})".format(response) ) except Exception: pass def get_version(self): self.send_packet(0, 0)H return self.handle_response("get_version", self.read_response())1 def set_lights(self, state_bin, duration=33):K # Keep polling the device until we have a free command slot to fill while self.query() == 0: time.sleep(0.1)8 self.send_packet(0x04, int(duration), state_bin)@ self.handle_response("set_lights", self.read_response()) def query(self):$ self.send_packet(0x07, 0x00)G return int(self.handle_response("query", self.read_response()))' def play_audio(self, sample_index):) self.send_packet(1, sample_index)@ self.handle_response("play_audio", self.read_response())3 def store_audio(self, sample_index, file_name):/ wave_reader = wave.open(file_name, "r")> chans, res, fs, length, _, _ = wave_reader.getparams()* nframes = wave_reader.getnframes()O data = struct.unpack("<%dh" % nframes, wave_reader.readframes(nframes)) converted = [] for value in data:- converted.append(value + 2 ** 15): result = struct.pack("<%dH" % nframes, *converted) crc = zlib.crc32(result)8 # calculate number of chunks to send (fake ceil)/ chunks = int(len(result) / 128.0 + 0.5)+ # initiate a sample write operationS self.send_packet(2, sample_index, struct.pack("=3I", crc, chunks, nframes))A self.handle_response("store_audio", self.read_response())# for chunk in range(chunks):C chunk_data = result[(chunk * 128): ((chunk + 1) * 128)]@ packed_bytes = struct.pack("=I", chunk) + chunk_dataH logger.debug("Sending chunk {} of {}".format(chunk, chunks))< self.send_packet(22, sample_index, packed_bytes)E self.handle_response("store_audio", self.read_response())$ def calc_crc32(self, file_name):/ wave_reader = wave.open(file_name, "r")> chans, res, fs, length, _, _ = wave_reader.getparams()* nframes = wave_reader.getnframes()O data = struct.unpack("<%dh" % nframes, wave_reader.readframes(nframes)) converted = [] for value in data:- converted.append(value + 2 ** 15): result = struct.pack("<%dH" % nframes, *converted)! return zlib.crc32(result)' def read_crc32(self, sample_index):* self.send_packet(23, sample_index)L return int(self.handle_response("read_crc32", self.read_response())) def _update_firmware(self):@ # teensy_loader_cli --mcu=TEENSYLC -s $(HEX_OUTPUT_FILE) cmd = (" "{}teensy_loader_cli " "--mcu=TEENSYLC "7 "-s -v {}thunder-and-lightning.hex".format(5 self.helpers_path, self.firmware_path ) )2 logger.debug("running cmd={}".format(cmd))4 subprocess.run(shlex.split(cmd), timeout=10)5�_� �����''V'\�������2 logger.debug("running cmd={}".format(cmd))5�_� �.����''V'\�������C logger.debug("running firmware updater cmd={}".format(cmd))5�_� �.����''V'\�������C logger.debug("running firmware update" cmd={}".format(cmd))5�_� �.����''V'\�������. logger.debug("running firmware update"5�_� �6����''V'\�������7 logger.debug("running firmware update", {"cmd"}5�_� �<����''V'\�������< logger.debug("running firmware update", {"cmd": cmd}5��
VimUnDoון0l�Bg� :jw÷ר��[£b Q³°�± ?F logger.info("could not humanize wifi scan e={}".format(e))*5!!!!\�ל_�����\��gץ:T logger.info("scan_number={} scan={}".format(scan_count, self.wifi_scan))5_�'����\��mץ:c logger.info("scanning wifi" scan_number={} scan={}".format(scan_count, self.wifi_scan))5_�)����\��oץ:d logger.info("scanning wifi", scan_number={} scan={}".format(scan_count, self.wifi_scan))5_�*����\��qץ:e logger.info("scanning wifi", {scan_number={} scan={}".format(scan_count, self.wifi_scan))5_�6����\��sץ:f logger.info("scanning wifi", {"scan_number={} scan={}".format(scan_count, self.wifi_scan))5_�7����\��tץ:g logger.info("scanning wifi", {"scan_number"={} scan={}".format(scan_count, self.wifi_scan))5_�8����\��uץ:d logger.info("scanning wifi", {"scan_number" scan={}".format(scan_count, self.wifi_scan))5_� 7����\��xץ:d logger.info("scanning wifi", {"scan_number" scan={}".format(scan_count, self.wifi_scan))5_� C����\��zץ:p logger.info("scanning wifi", {"scan_number": scan_count scan={}".format(scan_count, self.wifi_scan))5_� E����\��~ץ:q logger.info("scanning wifi", {"scan_number": scan_count, scan={}".format(scan_count, self.wifi_scan))5_� J����\��ץ:r logger.info("scanning wifi", {"scan_number": scan_count, "scan={}".format(scan_count, self.wifi_scan))5_� K����\��ץ:s logger.info("scanning wifi", {"scan_number": scan_count, "scan"={}".format(scan_count, self.wifi_scan))5_� K����\��ץ:h logger.info("scanning wifi", {"scan_number": scan_count, "scan"(scan_count, self.wifi_scan))5_� L����\��ץ:\ logger.info("scanning wifi", {"scan_number": scan_count, "scan" self.wifi_scan))5_�[����\��ץ:\ logger.info("scanning wifi", {"scan_number": scan_count, "scan": self.wifi_scan)5_�[����\��ץ:from time import sleep from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class Scanner: def __init__(self, netman): self.wifi_scan = {} self.netman = netman def scan_wifi(self):- logger.info("starting wifi scanning") scan_count = 03 self.wifi_scan = self._humanize_wifi_scan()! while not self.wifi_scan:] logger.info("scanning wifi", {"scan_number": scan_count, "scan": self.wifi_scan}) scan_count += 1 sleep(0.5)7 self.wifi_scan = self._humanize_wifi_scan()P logger.info("scan_number={} scan={}".format(scan_count, self.wifi_scan)) # Helper methods" def _humanize_wifi_scan(self): try: wifi_list = []P wlan_device = self.netman.NetworkManager.GetDeviceByIpIface("wlan0")4 for ap in wlan_device.GetAccessPoints():L wifi_list.append({"ssid": ap.Ssid, "strength": ap.Strength}) wifi_list.reverse(); logger.info("successfully humanized wifi scan")7 return Scanner._merge_like_ssids(wifi_list) except Exception as e:F logger.info("could not humanize wifi scan e={}".format(e)) raise e @staticmethod% def _merge_like_ssids(wifi_list): new_wifi_list = []+ strength_sorted_wifi_scan = sorted(@ wifi_list, key=lambda k: k["strength"], reverse=True ). for wifi in strength_sorted_wifi_scan:) if wifi not in new_wifi_list:X duplicate_ssid = Scanner._find_dict_in_list(new_wifi_list, wifi["ssid"]) if (* duplicate_ssid is NoneD or duplicate_ssid["strength"] < wifi["strength"] ):. new_wifi_list.append(wifi) return new_wifi_list @staticmethod* def _find_dict_in_list(my_list, ssid):M return next((item for item in my_list if item["ssid"] == ssid), None)5_�����\��§ץ<ץ<5_�����\��×ץ=P logger.info("scan_number={} scan={}".format(scan_count, self.wifi_scan))5_�����\��×ץ= logger.info(T "scanning wifi", {"scan_number": scan_count, "scan": self.wifi_scan}5_�����\��«ץ<Y logger.info( "scanning wifi", {"scan_number": scan_count, "scan": self.wifi_scan}5_�����\��¬ץ<X logger.info("scanning wifi", {"scan_number": scan_count, "scan": self.wifi_scan}5_�a����\��·ץ<a logger.info("finished scanning wifi", {"scan_number": scan_count, "scan": self.wifi_scan}5_�a����\��¸ץ<from time import sleep from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class Scanner: def __init__(self, netman): self.wifi_scan = {} self.netman = netman def scan_wifi(self):- logger.info("starting wifi scanning") scan_count = 03 self.wifi_scan = self._humanize_wifi_scan()! while not self.wifi_scan: logger.info(T "scanning wifi", {"scan_number": scan_count, "scan": self.wifi_scan} ) scan_count += 1 sleep(0.5)7 self.wifi_scan = self._humanize_wifi_scan()b logger.info("finished scanning wifi", {"scan_number": scan_count, "scan": self.wifi_scan}) # Helper methods" def _humanize_wifi_scan(self): try: wifi_list = []P wlan_device = self.netman.NetworkManager.GetDeviceByIpIface("wlan0")4 for ap in wlan_device.GetAccessPoints():L wifi_list.append({"ssid": ap.Ssid, "strength": ap.Strength}) wifi_list.reverse(); logger.info("successfully humanized wifi scan")7 return Scanner._merge_like_ssids(wifi_list) except Exception as e:F logger.info("could not humanize wifi scan e={}".format(e)) raise e @staticmethod% def _merge_like_ssids(wifi_list): new_wifi_list = []+ strength_sorted_wifi_scan = sorted(@ wifi_list, key=lambda k: k["strength"], reverse=True ). for wifi in strength_sorted_wifi_scan:) if wifi not in new_wifi_list:X duplicate_ssid = Scanner._find_dict_in_list(new_wifi_list, wifi["ssid"]) if (* duplicate_ssid is NoneD or duplicate_ssid["strength"] < wifi["strength"] ):. new_wifi_list.append(wifi) return new_wifi_list @staticmethod* def _find_dict_in_list(my_list, ssid):M return next((item for item in my_list if item["ssid"] == ssid), None)5_�*5����\���ץ)+?F logger.info("could not humanize wifi scan e={}".format(e))5_�*5����\���ץ)+?5 logger.info("could not humanize wifi scan5_�*8����\���ץ)+?: logger.info("could not humanize wifi scan", ""5_�*:����\���ץ)+?< logger.info("could not humanize wifi scan", {}""5_�*:����\���ץ)+?; logger.info("could not humanize wifi scan", {""5_�*@����\���ץ)+?@ logger.info("could not humanize wifi scan", {"error"5_� *F����\���ץ)+?F logger.info("could not humanize wifi scan", {"error": e}))5_�! *A����\�לץ)+?E logger.info("could not humanize wifi scan", {"error": e})ץ*+?5_� !*G����\�לץ)+?I logger.info("could not humanize wifi scan", {"error": str(e})5_�����\���ץ5ח×
VimUnDoεhγ0βθέϊΕW w-WPy0?ΈG{L7ΎQ< "zcash": nanopool_hashrate("zec", self.address),:LLLL]9ξ�_Π����]/[ύυ υ5_Π����]/\υ {}5_Π����]/\υ hashrate = {}5_Π����]/\υ hashrate = {"ethereum"}5_Π����]/\υυ5_Π ����]/\«υ/from health_monitor.pool import HashrateGateway5_Π ����]/\«υ from health_monitor.pool import 5_Π (����]/\±υ(from health_monitor.pool import hashrate5_Π ����]/\Γυ! hashrate = {"ethereum": }5_Π 7����]/\Μυ9 hashrate = {"ethereum": nanopool_hashrate('eth')}5_Π D����]/\�υ,from health_monitor import BaseHealthChecker from utils import CoinmineLogger=from health_monitor.pool import hashrate as nanopool_hashrate!logger = CoinmineLogger(__name__)+class PoolHealthChecker(BaseHealthChecker):& def __init__(self, coin, address): self.coin = coin self.address = address def _is_healthy(self):' hashrate = self._get_hashrate() if hashrate: return True else: return False def _get_hashrate(self):G hashrate = {"ethereum": nanopool_hashrate('eth', self.address)} pass5_Π F����]/\ΪυG hashrate = {"ethereum": nanopool_hashrate("eth", self.address)}5_Π ����]/\άυυυ5_Π����22V2]/\έυ3"ethereum": nanopool_hashrate("eth", self.address)}5_Π����22V2]/\έυ7 "ethereum": nanopool_hashrate("eth", self.address)}5_Π����22V2]/\έυ; "ethereum": nanopool_hashrate("eth", self.address)}5_Π����22V2]/\ήυ? "ethereum": nanopool_hashrate("eth", self.address)}5_Π����22V2]/\ήυC "ethereum": nanopool_hashrate("eth", self.address)}5_Π����22V2]/\ΰυG "ethereum": nanopool_hashrate("eth", self.address)}5_Π4����22V2]/\δυE "monero": nanopool_hashrate("eth", self.address)}5_Π3����22V2]/\ηυυ5_Π����22V2]/\ιυE "monero": nanopool_hashrate("xmr", self.address)}5_Π����22V2]/\μυυ5_Π����22V2]/\νυE "monero": nanopool_hashrate("xmr", self.address)}5_Π3����22V2]/\ρυD "zcash": nanopool_hashrate("xmr", self.address)}5_Π2����22V2]/\χυC "grin": nanopool_hashrate("xmr", self.address)}5_ΠD����22V2]/\ύυD "zcash": nanopool_hashrate("zec", self.address)}5_ΠE����22V2]/]υE "monero": nanopool_hashrate("xmr", self.address)}5_ΠD����22V2]/]υD "grin": nanopool_hashrate("grin", self.address)}5_Π C����22V2]/]υC "grin": nanopool_hashrate("grin", self.address)5_Π! C����22V2]/]υ,from health_monitor import BaseHealthChecker from utils import CoinmineLogger=from health_monitor.pool import hashrate as nanopool_hashrate!logger = CoinmineLogger(__name__)+class PoolHealthChecker(BaseHealthChecker):& def __init__(self, coin, address): self.coin = coin self.address = address def _is_healthy(self):' hashrate = self._get_hashrate() if hashrate: return True else: return False def _get_hashrate(self):G hashrate = {"ethereum": nanopool_hashrate("eth", self.address),E "monero": nanopool_hashrate("xmr", self.address),D "zcash": nanopool_hashrate("zec", self.address),D "grin": nanopool_hashrate("grin", self.address), } pass5_Π "!����22V2]/]υ υ5_Π!#"����22V2]/] υ hashrate[]5_Π"$#����22V2]/]υ pass5_Π#%$����22V2]/]υ return hashrate[]5_Π$&% ����22V2]/]~υ=from health_monitor.pool import hashrate as nanopool_hashrate5_Π%'& ����22V2]/]~υ5from health_monitor.pool import as nanopool_hashrate5_Π&(' ����22V2]/] υ,from health_monitor import BaseHealthChecker from utils import CoinmineLogger2from health_monitor.pool import nanopool_hashrate!logger = CoinmineLogger(__name__)+class PoolHealthChecker(BaseHealthChecker):& def __init__(self, coin, address): self.coin = coin self.address = address def _is_healthy(self):' hashrate = self._get_hashrate() if hashrate: return True else: return False def _get_hashrate(self): hashrate = {? "ethereum": nanopool_hashrate("eth", self.address),= "monero": nanopool_hashrate("xmr", self.address),< "zcash": nanopool_hashrate("zec", self.address),< "grin": nanopool_hashrate("grin", self.address), }" return hashrate[self.coin]5_Π')(����22V2]/]ηυ υ5_Π(*)/����22V2]/]ϋυ0 logger.info("Pool side hashrate={}")5_Π)+*����22V2]/^υυ5_Π*,+����22V2]/^υA logger.info("Pool side hashrate={}".format(hashrate))5_Π+-,����22V2]/^ υA logger.warn("Pool side hashrate={}".format(hashrate))5_Π,.-����22V2]/^bυA logger.warn("Pool side hashrate={}".format(hashrate))5_Π-/.!����22V2]/_ϋ υ υ5_Π.0/"����22V2]/`Zυ" return hashrate[self.coin]5_Π/10����22V2]/`zυ print(hashrate)5_Π021#����22V2]/aΩυ. return hashrate[self.coin]["hashrate"]5_Π132(����22V2]/aΫυ3 return hashrate[self.coin].get()"hashrate"]5_Π2432����22V2]/aάυ2 return hashrate[self.coin].get("hashrate"]5_Π354����22V2]/erυυ5_Π465����22V2]/evυ1from health_monitor.pool import nanopool_hashrate5_Π5761����22V2]/evυ1from health_monitor.pool import nanopool_hashrate5_Π687����22V2]/e|υ< "grin": nanopool_hashrate("grin", self.address),5_Π798����]/l υ υ5_Π8:9 $����]/lυ & def __init__(self, coin, address):5_Π9;:����]/{υJ logger.warn("Warning! Pool side hashrate={}".format(hashrate))5_Π:<;!����]/{υK logger.error("Warning! Pool side hashrate={}".format(hashrate))5_Π;><!����]/{υJ logger.error("Warnin! Pool side hashrate={}".format(hashrate))5_Π<?=>����]/{2υ υ5_Π>@?����]/{:υ return False5_Π?A@����]/{;υ return True5_Π@BA.����]/Eυ< "grin": grinmint_hashrate("grin", self.address),5_ΠACB2����]/Iυ4 "grin": grinmint_hashrate(self.address),5_ΠBDC����]/Nυ υ5_ΠCED ����]/Pυ self.uuid5_ΠDFE ����]/Tυ self.uuid = uuid5_ΠEGF ����]/Wυ self.short_uuid = uuid5_ΠFHG %����]/Zυ 6 def __init__(self, coin, address, remedy_command):5_ΠGIH 0����]/]υ A def __init__(self, coin, address, short_uuid remedy_command):5_ΠHJI9����]/ύυ? "grin": grinmint_hashrate(self.address, self.uuid),5_ΠIKJ=����]9ξ€υ? "ethereum": nanopool_hashrate("eth", self.address),5_ΠJLK;����]9ξ¬υ= "monero": nanopool_hashrate("xmr", self.address),5_ΠKL:����]9ξυ< "zcash": nanopool_hashrate("zec", self.address),5_Π<>=����]/{*υ5_Π ����]/\Ωυ hashrate = {5ηͺ
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�b�ΩAx'�P@�r.���.���e"��M5<��hJ logger.warn("{} {}".format(self.operation, self.full_url))X....^q8o_�P����]�B�WR requests.get(self.full_url, headers=self.headers, timeout=(5, 10))5�_�P����]�G�WR requests.get(self.full_url, headers=self.headers, timeout=(5, 10))5�_�!S����]�J� "WU requests.delete(self.full_url, headers=self.headers, timeout=(5, 10))5�_�%W����]�M�$&WX self.full_url, json=self.json, headers=self.headers, timeout=(5, 10)5�_�*W����]�O�)+WX self.full_url, json=self.json, headers=self.headers, timeout=(5, 10)5�_� ����]��� X� W5�_� 5����]��� X5REQUEST_TIMEOUT = os.environ[REQUEST_TIMEOUT_CONNECT]5�_� 6����]��� X6REQUEST_TIMEOUT = os.environ[REQUEST_TIMEOUT_CONNECT])5�_� Z����]��� XZREQUEST_TIMEOUT = os.environ[REQUEST_TIMEOUT_CONNECT]), os,environ["REQUEST_TIMEOUT_READ"]5�_� 8����]��� X\REQUEST_TIMEOUT = os.environ[REQUEST_TIMEOUT_CONNECT]), os,environ["REQUEST_TIMEOUT_READ"]))5�_� ����]��� X`REQUEST_TIMEOUT = os.environ[REQUEST_TIMEOUT_CONNECT]), int(os,environ["REQUEST_TIMEOUT_READ"]))5�_� ����]���Ximport jsonimport requests from utils import CoinmineLogger!logger = CoinmineLogger(__name__)!OK_STATUS_CODES = [200, 201, 204]eREQUEST_TIMEOUT = (int(os.environ[REQUEST_TIMEOUT_CONNECT]), int(os,environ["REQUEST_TIMEOUT_READ"]))class RequestFactory:C def __init__(self, full_url, operation, json=None, token=None): self.full_url = full_url" self.operation = operation self.json = json self.token = token if token is None: self.headers = None else:E self.headers = {"Authorization": "Token %s" % self.token} def make_request(self): response = None request = {! "TEST_GET": lambda: (R requests.get(self.full_url, headers=self.headers, timeout=(5, 25)) ), "GET": lambda: (R requests.get(self.full_url, headers=self.headers, timeout=(5, 25)) ), "DELETE": lambda: (U requests.delete(self.full_url, headers=self.headers, timeout=(5, 25)) ), "PUT": lambda: ( requests.put(X self.full_url, json=self.json, headers=self.headers, timeout=(5, 25) ) ), "POST": lambda: ( requests.post(X self.full_url, json=self.json, headers=self.headers, timeout=(5, 25) ) ), } try:I response = self._sanitize_response(request[self.operation]()) try:+ resp_json = response.json()5 except json.decoder.JSONDecodeError as e: resp_json = NoneJ logger.warn("could not form json response e={}".format(e))7 if response.status_code in OK_STATUS_CODES: logger.debug(: "{} {} status={} resp_json={}".format(V self.operation, self.full_url, response.status_code, resp_json ) ) else: logger.warn(: "{} {} status={} resp_json={}".format(V self.operation, self.full_url, response.status_code, resp_json ) ) except Exception as e:, if self.operation == "TEST_GET":J logger.warn("{} {}".format(self.operation, self.full_url)) else: logger.error(8 "e={} {} {} request_json={}".format(C e, self.operation, self.full_url, self.json ) ) raise e return response # helpers/ def _sanitize_response(self, raw_response):. # clean up xmr-stak invalid charactersS raw_response.__text = raw_response.text.replace("\n", "").replace("\r", "") return raw_response5�_�����]��� [- int(os, environ["REQUEST_TIMEOUT_READ"]),5�_� ����]���\�[5�_�����]��� \- int(os.environ[REQUEST_TIMEOUT_CONNECT]),5�_�+����]��� \. int(os.environ["REQUEST_TIMEOUT_CONNECT]),5�_� Q����]� �!\R requests.get(self.full_url, headers=self.headers, timeout=(5, 25))5�_�#Q����]� �"$\R requests.get(self.full_url, headers=self.headers, timeout=(5, 25))5�_�&T����]� �%'\U requests.delete(self.full_url, headers=self.headers, timeout=(5, 25))5�_�*X����]� �)+\X self.full_url, json=self.json, headers=self.headers, timeout=(5, 25)5�_�/X����]� �.0\X self.full_url, json=self.json, headers=self.headers, timeout=(5, 25)5�_�\����]� �\ import osimport jsonimport requests from utils import CoinmineLogger!logger = CoinmineLogger(__name__)!OK_STATUS_CODES = [200, 201, 204]REQUEST_TIMEOUT = (/ int(os.environ["REQUEST_TIMEOUT_CONNECT"]),, int(os.environ["REQUEST_TIMEOUT_READ"]),)class RequestFactory:C def __init__(self, full_url, operation, json=None, token=None): self.full_url = full_url" self.operation = operation self.json = json self.token = token if token is None: self.headers = None else:E self.headers = {"Authorization": "Token %s" % self.token} def make_request(self): response = None request = {! "TEST_GET": lambda: (Z requests.get(self.full_url, headers=self.headers, timeout=REQUEST_TIMEOUT) ), "GET": lambda: (Z requests.get(self.full_url, headers=self.headers, timeout=REQUEST_TIMEOUT) ), "DELETE": lambda: (] requests.delete(self.full_url, headers=self.headers, timeout=REQUEST_TIMEOUT) ), "PUT": lambda: ( requests.put(` self.full_url, json=self.json, headers=self.headers, timeout=REQUEST_TIMEOUT ) ), "POST": lambda: ( requests.post(` self.full_url, json=self.json, headers=self.headers, timeout=REQUEST_TIMEOUT ) ), } try:I response = self._sanitize_response(request[self.operation]()) try:+ resp_json = response.json()5 except json.decoder.JSONDecodeError as e: resp_json = NoneJ logger.warn("could not form json response e={}".format(e))7 if response.status_code in OK_STATUS_CODES: logger.debug(: "{} {} status={} resp_json={}".format(V self.operation, self.full_url, response.status_code, resp_json ) ) else: logger.warn(: "{} {} status={} resp_json={}".format(V self.operation, self.full_url, response.status_code, resp_json ) ) except Exception as e:, if self.operation == "TEST_GET":J logger.warn("{} {}".format(self.operation, self.full_url)) else: logger.error(8 "e={} {} {} request_json={}".format(C e, self.operation, self.full_url, self.json ) ) raise e return response # helpers/ def _sanitize_response(self, raw_response):. # clean up xmr-stak invalid charactersS raw_response.__text = raw_response.text.replace("\n", "").replace("\r", "") return raw_response5�_�����V]���� h/ int(os.environ["REQUEST_TIMEOUT_CONNECT"]),5�_�����V]���� h, int(os.environ["REQUEST_TIMEOUT_READ"]),5�_�,����V]���� h. int(os.getenv["REQUEST_TIMEOUT_CONNECT"]),5�_�)����V]���� h+ int(os.getenv["REQUEST_TIMEOUT_READ"]),5�_�.����V]���� h/ int(os.getenv["REQUEST_TIMEOUT_READ"], 30),5�_� /����V]���� h1 int(os.getenv["REQUEST_TIMEOUT_CONNECT"], 5),5�_�! 0����V]���� h1 int(os.getenv["REQUEST_TIMEOUT_CONNECT"], 5),5�_� "!)����V]����
Vim�UnDo�G�B�v$���{P�&ub&��0#p�D logger.warn("could not get wifi device info from lspci")QQQQ^q7_�����^b���5�_�����^b����5�_�����^b���5�_�����^b���5�_�����^b���"�5�_�"����")V^b���!" def get_cpu_info(self):. cpus = Converters.json_string_to_dict(; Converters.cmd_to_string(self.detailed_cpu_cmd) )["cpus"] for cpu in cpus:. cpu["max_mhz"] = cpu.pop("maxmhz"). cpu["min_mhz"] = cpu.pop("minmhz") return cpus5�_�����""V^b��� ! base_cmd = "lscpu"5�_� ����""V^b���!class Lscpu:5�_� %����""V^b���"�!5�_� ����##V^b���" import re]5�_� ����##V^b���"5�_� ����$$V^b�� ; cpu_columns = "--extended=CPU,SOCKET,MAXMHZ,MINMHZ"5�_� ����##V^b�� "L self.detailed_cpu_cmd = "{} --json {}".format(base_cmd, cpu_columns)5�_� ����##V^b�� "< self. = "{} --json {}".format(base_cmd, cpu_columns)5�_�����##V^b�� "? self.cmd = "{} --json {}".format(base_cmd, cpu_columns)5�_�����##V^b�� " self.cmd = 5�_�����##V^b�� self.cmd = bas5�_� ����""V^b�� ! base_cmd = "lsusb"5�_�����""V^b�'�" �!5�_� ����##V^b�1� " Converters.cmd_to_string()5�_�����""V^b�2�" �!5�_�����##V^b�4�"�"5�_�����V^b�5�#" Converters.cmd_to_string()5�_�����V^b�6� 5�_�%����V^b�>�"& Converters.cmd_to_string()5�_�����V^b�B�0 output = self._get_detailed_output()5�_�����V^b�C�!. Converters.cmd_to_string(self.cmd)5�_�����V^b�;�!5�_�����V^b�<�"�"5�_� ����V^b�=�" r"Bus (.*)\n"5�_�! ����V^b�=�" r"Bus (.*)\n"5�_� "!����V^b�=�" r"Bus (.*)\n"5�_�!#"����V^b�=�" r"Bus (.*)\n"5�_�"$#����V^b�@�/ r"Class:.*Network controller\n"! "Vendor:\t(.*)\n"! "Device:\t(.*)\n"" "SVendor:\t(.*)\n"! "SDevice:\t(.*)",5�_�#%$����V^b�@� re.MULTILINE,5�_�$&%����V^b�C� r"Bus (.*)\n"5�_�%'&����V^b�D � import re,from utils import CoinmineLogger, Converters!logger = CoinmineLogger(__name__)class Lsusb: def __init__(self): self.cmd = "lsusb"# def get_wifi_device_info(self): info = {} try:7 output = Converters.cmd_to_string(self.cmd)! matches = re.findall( r"Bus (.*)\n", output, ) info = {( "vendor": matches[0][0],( "device": matches[0][1],, "sub_vendor": matches[0][2],, "sub_device": matches[0][3], } except Exception:D logger.warn("could not get wifi device info from lspci") return info5�_�&('����V^b�G� �5�_�')( ����V^b�N� �5�_�(*) ����V^b�R� � 5�_�)+*"����V^b�Y� # self.keywords = ["Network"]5�_�*,+#����V^b�r� % self.keywords = ["Network", ]5�_�+-,.����V^b�v� 0 self.keywords = ["Network", "Wireless" ]5�_�,.-����V^b�{ � if 5�_�-/.����V^b�~� if5�_�.0/
Vim�UnDo������&�y���=SӴw�ځcSZ����!=] �_�=����] ��> ambiance_app.config["state"] = {"state": "some-value"}5�_�Q����] ��R ambiance_app.config["state"] = {"state": "some-value", "ambiance_enabled"}5�_�T����] ��U ambiance_app.config["state"] = {"state": "some-value", "ambiance_enabled": "}5�_�W����] �� import osfrom unittest import TestCase.from thunder_and_lightning import ambiance_app from utils import CoinmineLoggerclass TestApiServer(TestCase): def setUp(self):6 self.ambiance_app = ambiance_app.test_client()) logger = CoinmineLogger(__name__) # connect logger. ambiance_app.config["logger"] = loggerY ambiance_app.config["state"] = {"state": "some-value", "ambiance_enabled": False} def test_get_config(self):2 response = self.ambiance_app.get("/state")J self.assertDictEqual({"state": "some-value"}, response.get_json()) def test_put_config(self):) response = self.ambiance_app.put(C "/state", json={"state": "another-value", "foo": "bar"} )3 self.assertEqual(200, response.status_code)2 response = self.ambiance_app.get("/state") self.assertDictEqual(I {"state": "another-value", "foo": "bar"}, response.get_json() )5�_�����] �� import os5��
VimЪUnDoтјШЭотqужcЧ«xіQ>Я┴жъ|$p%ЊpЧz,9\Г)б _л ,-V\Г(пшG print('Device Paths detected: {}'.format(device_paths))5Ђ_л. +,V\Г(Тш-/04 logger.warn('could not open serial '5Ђ_л. +,V\Г(Вш-/0. print('could not open serial '; 'port={} e={}'.format(port, e))5Ђ_л ./ +,V\Г(ьш-0/N print('could not open serial ' 'port={} e={}'.format(port, e))5Ђ_л . +,V\Г(Ьш-/0. print('could not open serial '5 'port={} e={}'.format(port, e))5Ђ_л ./ +,V\Г(№ш-//N print('could not open serial ' 'port={} e={}'.format(port, e))5Ђ_л .- +,V\Г(ыш-//K print('could not open serial'port={} e={}'.format(port, e))5Ђ_л .- +,V\Г(Ыш-0/K print('could not open serial port={} e={}'.format(port, e))5Ђ_л + +,V\Г(шш*-0> logger.info('found appropriate serial device '5Ђ_л + +-V\Г(Чш*+ 5Ђ_л+ +,V\Г( ш*,08 print('found appropriate serial device '3 'port={}'.format(port))5Ђ_л+9 ++-V\Г( ш*-/P print('found appropriate serial device ' 'port={}'.format(port))5Ђ_л V\Г)Ъш from utils import CoinmineLogger!logger = CoinmineLogger(__name__)5Ђ_л V\Г)аш5Ђ_л V\Г)А ш+5Ђ_л \Г(├ш5Ђ_л+ ,-V\Г(╚ш*-5Ђ_л, ,,V\Г(╔ш+.5Ђ_л% ++V\Г(¤ш$&5Ђуф
VimUnDoו�8¨��+�@פ1�Z=��½g�1K¹¢ב¦Bl¾Z! {"error": e},O\�לB_�68����\�pץ57WJ logger.warn("could not form json response e={}".format(e))5_�68����\�qץ57W8 logger.warn("could not form json respons5_�6D����\�vץ57WE logger.warn("could not form json response", {"error"}5_� 6H����\�wץ57WH logger.warn("could not form json response", {"error": e}5_� :$����\�µץ9;W: "{} {} status={} resp_json={}".format(5_� ;K����\�¸ץ:<WV self.operation, self.full_url, response.status_code, resp_json5_� <����\�÷ץ;=W )5_� <����\�¾ץWimport jsonimport requests from utils import CoinmineLogger!logger = CoinmineLogger(__name__)!OK_STATUS_CODES = [200, 201, 204]class RequestFactory:C def __init__(self, full_url, operation, json=None, token=None): self.full_url = full_url" self.operation = operation self.json = json self.token = token if token is None: self.headers = None else:E self.headers = {"Authorization": "Token %s" % self.token} def make_request(self): response = None request = {! "TEST_GET": lambda: (R requests.get(self.full_url, headers=self.headers, timeout=(5, 10)) ), "GET": lambda: (R requests.get(self.full_url, headers=self.headers, timeout=(5, 10)) ), "DELETE": lambda: (U requests.delete(self.full_url, headers=self.headers, timeout=(5, 10)) ), "PUT": lambda: ( requests.put(X self.full_url, json=self.json, headers=self.headers, timeout=(5, 10) ) ), "POST": lambda: ( requests.post(X self.full_url, json=self.json, headers=self.headers, timeout=(5, 10) ) ), } try:I response = self._sanitize_response(request[self.operation]()) try:+ resp_json = response.json()5 except json.decoder.JSONDecodeError as e: resp_json = NoneI logger.warn("could not form json response", {"error": e})7 if response.status_code in OK_STATUS_CODES: logger.debug(- "{} {} status={}".format(K self.operation, self.full_url, response.status_code ), resp_json ) else: logger.warn(: "{} {} status={} resp_json={}".format(V self.operation, self.full_url, response.status_code, resp_json ) ) except Exception as e:, if self.operation == "TEST_GET":J logger.warn("{} {}".format(self.operation, self.full_url)) else: logger.error(8 "e={} {} {} request_json={}".format(C e, self.operation, self.full_url, self.json ) ) raise e return response # helpers/ def _sanitize_response(self, raw_response):. # clean up xmr-stak invalid charactersS raw_response.__text = raw_response.text.replace("\n", "").replace("\r", "") return raw_response5_� C����\��ץCEXץCDX5_�C����\��ץBDY )5_�A$����\��ץ@BY: "{} {} status={} resp_json={}".format(5_�BK����\��ץACYV self.operation, self.full_url, response.status_code, resp_json5_�M����\��ץLNYC e, self.operation, self.full_url, self.json5_�L����\��ץKMY8 "e={} {} {} request_json={}".format(5_�N����\�דץMOY )5_�N����\�זץMOY ), {"error"}5_�N!����\�טץYimport jsonimport requests from utils import CoinmineLogger!logger = CoinmineLogger(__name__)!OK_STATUS_CODES = [200, 201, 204]class RequestFactory:C def __init__(self, full_url, operation, json=None, token=None): self.full_url = full_url" self.operation = operation self.json = json self.token = token if token is None: self.headers = None else:E self.headers = {"Authorization": "Token %s" % self.token} def make_request(self): response = None request = {! "TEST_GET": lambda: (R requests.get(self.full_url, headers=self.headers, timeout=(5, 10)) ), "GET": lambda: (R requests.get(self.full_url, headers=self.headers, timeout=(5, 10)) ), "DELETE": lambda: (U requests.delete(self.full_url, headers=self.headers, timeout=(5, 10)) ), "PUT": lambda: ( requests.put(X self.full_url, json=self.json, headers=self.headers, timeout=(5, 10) ) ), "POST": lambda: ( requests.post(X self.full_url, json=self.json, headers=self.headers, timeout=(5, 10) ) ), } try:I response = self._sanitize_response(request[self.operation]()) try:+ resp_json = response.json()5 except json.decoder.JSONDecodeError as e: resp_json = NoneI logger.warn("could not form json response", {"error": e})7 if response.status_code in OK_STATUS_CODES: logger.debug(- "{} {} status={}".format(K self.operation, self.full_url, response.status_code ), resp_json, ) else: logger.warn(- "{} {} status={}".format(K self.operation, self.full_url, response.status_code ), resp_json, ) except Exception as e:, if self.operation == "TEST_GET":J logger.warn("{} {}".format(self.operation, self.full_url)) else: logger.error(3 "{} {} request_json={}".format(@ self.operation, self.full_url, self.json# ), {"error": e} ) raise e return response # helpers/ def _sanitize_response(self, raw_response):. # clean up xmr-stak invalid charactersS raw_response.__text = raw_response.text.replace("\n", "").replace("\r", "") return raw_response5_�6E����\�ל:ץ57ZI logger.warn("could not form json response", {"error": e})ץ67Z5_�6K����\�ל;ץ57ZM logger.warn("could not form json response", {"error": str(e})5_�O����\�ל@ץNPZ! {"error": e},ץOPZ5_�O#����\�לAץNPZ% {"error": str(e},5_�A$����\��ץ@BY& "{} {} status={}t(5_� =����\��ץ<>5_� :$����\�×ץ9;W< "{} {} status={}"" resp_json={}".format(5_� :%����\�¬ץ9;W; "{} {} status={}" resp_json={}".format(5_� :%����\�®ץ9;W< "{} {} status={}", resp_json={}".format(5_�:����\�ץ9;W; "{} {}" status={} resp_json={}".format(5_�68����\�kץ67Wץ57W[ logger.warn("could not form json response e={}".format(e)) e={}".format(e))5ח×
VimЪUnDoтJiЫЫмв┴ГH5ЁЬі\йъ@╝ExGЪ7йъ:PEEEE\Оё*_л9 \оП¤ш9 ш95Ђ_л3$ \оПЩш24:$ gpu_info["amd_type"]5Ђ_л6' \ояш57:' gpu_info["memory_type"]5Ђ_л5* \ояОш46:: if re.search(gpu, memory_types, re.MULTILINE):5Ђ_л8S \оящш79:V re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE).strip().split()[3]5Ђ_л8B \оячш: import reimport shleximport subprocess from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class AmdMemInfo:( def __init__(self, amdmeminfo_path):. self.amdmeminfo_path = amdmeminfo_path def get_all_gpu_info(self): all_gpu_info = [] try:1 amdmeminfo = subprocess.check_output(J shlex.split("{} --no-opencl".format(self.amdmeminfo_path)) ).decode("utf-8")P split_info = amdmeminfo.split("-----------------------------------") adapter_num = 0# for line in split_info:9 gpu_info = AmdMemInfo._get_gpu_info(line) if gpu_info: logger.info(F "AMD GPU found adapter_num={} type={}".format(1 adapter_num, gpu_info ) )1 all_gpu_info.append(gpu_info) except Exception as e:D logger.error("could not run amdmeminfo! e={}".format(e)) if not all_gpu_info:, logger.warn("No AMD GPUs found") return all_gpu_info% def get_num_of_amd_devices(self):+ return len(self.get_all_gpu_info()) # helpers @staticmethod" def _get_gpu_info(amdmeminfo): gpu_info = {}( amd_types = ["RX 580", "RX 570"]? memory_types = ["Hynix", "Samsung", "Micron", "Elpida"] for gpu in amd_types:8 if re.search(gpu, amdmeminfo, re.MULTILINE):* gpu_info["amd_type"] = gpu for gpu in memory_types:8 if re.search(gpu, amdmeminfo, re.MULTILINE):- gpu_info["memory_type"] = gpu% gpu_info["memory_serial"] = (F re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE)[3] ) return gpu_info5Ђ_л 9 \о▀ш8:: )[3]5Ђ_л 9 \о▀2ш8:: )[0].split()[3]5Ђ_л (* \оРЪш'):+ return len(self.get_all_gpu_info())5Ђ_л (0 \оР║ш'):1 return len(self.get_all_gpu_info.items())5Ђ_л ' \оРКш&(:% def get_num_of_amd_devices(self):5Ђ_л ' \оР╩ш&(:! def get_num_of_devices(self):5Ђ_л 9 \осю ш8:: )[0].split()[4]5Ђ_л6 79v\ос┐ш68;ш68:5Ђ_л7 8:v\ос├ш6:; print(ш78;5Ђ_л9 :<v\ос┼ш8:= )[0].split()5Ђ_л7 :<v\осош68=/ print(gpu_info["memory_serial"] = re.findall(7 r"Memory Model.*", amdmeminfo, re.MULTILINE5Ђ_л70 9;v\осош68<[ print(gpu_info["memory_serial"] = re.findall( r"Memory Model.*", amdmeminfo, re.MULTILINE5Ђ_л7 9;v\освш68<Z print(gpu_info["memory_serial"] = re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE )[0].split())5Ђ_л7g 8:v\осьш68;g print(gpu_info["memory_serial"] = re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE)[0].split())5Ђ_л7$ 8:v\осЗш68;h print(gpu_info["memory_serial"] = re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE)[0].split()))5Ђ_л7L 8:v\осщш68;L print(re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE)[0].split()))5Ђ_л6, 8:v\ос■ш57;- gpu_info["memory_type"] = gpuK print(re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE)[0].split())5Ђ_л6. 79v\ос■ш58:w gpu_info["memory_type"] = gpu print(re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE)[0].split())5Ђ_л7 8:v\оСш68;Iprint(re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE)[0].split())5Ђ_л7 8:v\оСш68;K print(re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE)[0].split())5Ђ_л 7 8:v\оСш68;R print(re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE)[0].split())5Ђ_л! 7 8:v\оСXш67Q print(re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE)[0].split())5Ђ_л "!9 79v\оС[ш9;;ш9;:5Ђ_л!#": 79v\оСdш9;; print(gpu_info)5Ђ_л"$#$ 79v\отfш$&<ш$&;5Ђ_л#%$% 8:v\отlш$&< print(all5Ђ_л$&%; 8:v\отoш:; print(gpu_info)5Ђ_л%'&% 8:v\отrш$&; print(all_gpu_info)5Ђ_л&('% 8:v\отtш$&; print(all_gpu_info)5Ђ_л'-( \оЩ└ш!< ш!;5Ђ_л(.)- \о§vш= ш<5Ђ_л-/. \о§|ш=! print(split_info)5Ђ_л.0/ \о■bш> ш=5Ђ_л/10= \о■еш=?? ш=?>5Ђ_л021> \о■«ш=?? print(gpu_ifno)5Ђ_л132: \о■░ш:<?ш:;?5Ђ_л2437 \о■▒ш79@ш78@5Ђ_л3544 \о■▓ш46Aш45A5Ђ_л465 \о ш "Bш !B5Ђ_л576! \о ш !# print(gpu_info)5Ђ_л687 \о шBшB5Ђ_л798 V\о !шC# print(gpu_info)5Ђ_л8:9 V\о д%шC ).decode("utf-8")5Ђ_л9;:" V\О»&шC# ).decode("utf-8")[0:-1]5Ђ_л:<; V\Ожш print(gpu_info)5Ђ_л;=< V\ОЖш print(line)5Ђ_л<>=! V\ОВ'ш !# print(gpu_info)5Ђ_л=?> V\Ош@! ).decode("utf-8")[1:]5Ђ_л>@?P V\О(ш@P split_info = amdmeminfo.split("-----------------------------------")ш@5Ђ_л?A@ V\О8)ш print(split_info)5Ђ_л@BA% V\О~ш$% print(all_gpu_info)5Ђ_лACB= V\Ођш<= print(gpu_info)5Ђ_лBDC9 V\ОЂш89 print(gpu_info)5Ђ_лCED5 V\Оѓш45 print(gpu_info)5Ђ_лDE1 V\ОЃ*ш01 print(gpu_info)5Ђ_л(*-); \оЩыш;<< ш;== print(gpu_info)5Ђ_л)+*8 \о§ш89=ш89= print(gpu_info)5Ђ_л*,+5 \о§$ш56>ш56> print(gpu_info)5Ђ_л+,2 \о§Tш23?ш23? print(gpu_info)5Ђ_л7. 8:v\осОш69<g print(gpu_info["memory_serial"] = re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE)[0].split())5Ђ_л7g 8:v\осР ш68;f print(gpu_info["memory_serial"] = re.findall(r"Memory Model.*", amdmeminfo, re.MULTILINE)[0].split()5Ђ_л6 9;v\осйш67:ш57:0 gpu_info["memory_serial"] = re.findall(7 r"Memory Model.*", amdmeminfo, re.MULTILINE8 )[0].split() gpu_info["memory_type"] = gpu5Ђ_л6& \ояш67:ш67:a5Ђуф
Vim�UnDo�f0�C<?�'��Gz��㤓:o<e2Tn~���pMC logger.warn("could not get memory info e={}".format(e))L^q7_�����^a4~� <<<<<<< HEAD5�_�����V^a4�� O info["version"] = re.findall(r"Version: (.*)", output, re.MULTILINE)[0]O info["voltage"] = re.findall(r"Voltage: (.*)", output, re.MULTILINE)[0]W info["num_of_cores"] = re.findall(r"Core Count: (.*)", output, re.MULTILINE)[0], info["num_of_threads"] = re.findall(7 r"Thread Count: (.*)", output, re.MULTILINE )[0]W info["max_frequency"] = re.findall(r"Max Speed: (.*)", output, re.MULTILINE)[0]/ info["current_frequency"] = re.findall(8 r"Current Speed: (.*)", output, re.MULTILINE )[0]5�_�����V^a4��I�I�H5�_�����V^a4��S O info["version"] = re.findall(r"Version: (.*)", output, re.MULTILINE)[0]O info["voltage"] = re.findall(r"Voltage: (.*)", output, re.MULTILINE)[0]W info["num_of_cores"] = re.findall(r"Core Count: (.*)", output, re.MULTILINE)[0], info["num_of_threads"] = re.findall(7 r"Thread Count: (.*)", output, re.MULTILINE )[0]W info["max_frequency"] = re.findall(r"Max Speed: (.*)", output, re.MULTILINE)[0]/ info["current_frequency"] = re.findall(8 r"Current Speed: (.*)", output, re.MULTILINE )[0]5�_�����%V^a4��S info["version"] = re.findall(r"Version: (.*)", output, re.MULTILINE)[0]S info["voltage"] = re.findall(r"Voltage: (.*)", output, re.MULTILINE)[0]. info["num_of_cores"] = re.findall(9 r"Core Count: (.*)", output, re.MULTILINE )[0]0 info["num_of_threads"] = re.findall(; r"Thread Count: (.*)", output, re.MULTILINE )[0]5�_� ����V^a4�� 0>>>>>>> a12a311df8e785e8097c59ca61a1fae694685f985�_�����V^a4�� =======5�_� ����V^a4��I import re,from utils import CoinmineLogger, Converters!logger = CoinmineLogger(__name__)class Dmidecode:= def __init__(self, dmidecode_path="/usr/sbin/dmidecode"):, self.dmidecode_path = dmidecode_path def get_cpu_info(self): info = {} arg = "processor"9 cmd = "{} -t {}".format(self.dmidecode_path, arg) try:2 output = Converters.cmd_to_string(cmd)S info["version"] = re.findall(r"Version: (.*)", output, re.MULTILINE)[0]S info["voltage"] = re.findall(r"Voltage: (.*)", output, re.MULTILINE)[0][ info["num_of_cores"] = re.findall(r"Core Count: (.*)", output, re.MULTILINE)[0]0 info["num_of_threads"] = re.findall(; r"Thread Count: (.*)", output, re.MULTILINE )[0][ info["max_frequency"] = re.findall(r"Max Speed: (.*)", output, re.MULTILINE)[0]3 info["current_frequency"] = re.findall(< r"Current Speed: (.*)", output, re.MULTILINE )[0] except Exception as e:@ logger.warn("could not get cpu info e={}".format(e)) return info# def get_motherboard_info(self): info = {} arg = "system"9 cmd = "{} -t {}".format(self.dmidecode_path, arg) try:2 output = Converters.cmd_to_string(cmd). info["manufacturer"] = re.findall(; r"Manufacturer: (.*)", output, re.MULTILINE )[0]. info["product_name"] = re.findall(; r"Product Name: (.*)", output, re.MULTILINE )[0] except Exception as e:H logger.warn("could not get motherboard info e={}".format(e)) return info def get_memory_info(self): info = {} arg = "memory"9 cmd = "{} -t {}".format(self.dmidecode_path, arg) try:2 output = Converters.cmd_to_string(cmd)D size = re.findall(r"\tSize: (.*)", output, re.MULTILINE)D type = re.findall(r"\tType: (.*)", output, re.MULTILINE)F speed = re.findall(r"\tSpeed: (.*)", output, re.MULTILINE)D rank = re.findall(r"\tRank: (.*)", output, re.MULTILINE)S voltage = re.findall(r"Configured Voltage: (.*)", output, re.MULTILINE)$ num_of_banks = len(size)/ for bank in range(0, num_of_banks):0 info["bank_{}".format(bank)] = {' "size": size[bank],' "type": type[bank],) "speed": speed[bank],' "rank": rank[bank],- "voltage": voltage[bank], } except Exception as e:C logger.warn("could not get memory info e={}".format(e)) return info5�_� "����^q7 �!#M@ logger.warn("could not get cpu info e={}".format(e))5�_� 2����^q7�13MH logger.warn("could not get motherboard info e={}".format(e))5�_� L����^q7�KMMC logger.warn("could not get memory info e={}".format(e))5��
Vim�UnDo�'t8�����w�v�t�d�0E���։�W�o�)T logger.warn("could not open serial " "port={} e={}".format(port, e))(\�?_�����V\�3� from utils import CoinmineLogger!logger = CoinmineLogger(__name__)5�_�����V\�4�. import sysimport glob import serialimport timeclass SerialUtils: @staticmethod def get_teensy_ports():# for attempt in range(0, 5):: device_paths = SerialUtils._get_teensy_ports() time.sleep(1) if device_paths:G print('Device Paths detected: {}'.format(device_paths))# return device_paths @staticmethod def _get_teensy_ports(): # windows* if sys.platform.startswith('win'):; ports = ['COM%s' % (i + 1) for i in range(256)] # linux.android1 elif (sys.platform.startswith('linux') or1 sys.platform.startswith('cygwin')):- ports = glob.glob('/dev/ttyACM*') # mac/ elif sys.platform.startswith('darwin'):3 ports = glob.glob('/dev/tty.usbmodem*') else:: raise EnvironmentError('Unsupported platform') result = []1 print('Ports detected: {}'.format(ports)) for port in ports: try:- s = serial.Serial(port, 9600) s.close()# result.append(port)> logger.info('found appropriate serial device '3 'port={}'.format(port)): except (OSError, serial.SerialException) as e:4 logger.warn('could not open serial '; 'port={} e={}'.format(port, e)) return result5�_�&����V\�9�%')V logger.info("found appropriate serial device " "port={}".format(port))5�_�(����V\�>�'))T logger.warn("could not open serial " "port={} e={}".format(port, e))5��
Vim�UnDo����Zd�E8��V?>��~;xf���ŢГ oBDg9 memory_serial = (7????\�ܟ_� ����\�V�� 1class GPUDevices:5�_�)����\�V��1? possible_gpu = GPUDevices._get_amd_device(line)5�_�,����\�W��+-1$ def _get_amd_device(amdmeminfo):5�_�1����\�X�1? possible_gpu = AmdMemInfo._get_amd_device(line)�0 return gpu5�_�+����\�XY�19 possible_gpu = AmdMemInfo._gpu_info(line)5�_�����\�Xq�1= possible_gpu = AmdMemInfo._get_gpu_info(line)5�_�����\�Xt�14 gpu = AmdMemInfo._get_gpu_info(line)5�_� 5����\�X��15 adapter_num, possible_gpu5�_� ����\�X�� 1 def get_amd_devices(self):5�_� ,����\�X�� 1- gpus.append(possible_gpu)5�_� )����\�X�� 1* gpus.append(gpu_info))5�_� ����\�X�� 1) gpus.append(gpu_info)5�_� ����\�X�� 1- all_gpus.append(gpu_info)5�_� ����\�X� �1 gpus = []5�_�('����\�X� �')1* return len(self.get_amd_devices())5�_�,����\�Y�,.2 �,.15�_�2����\�Y$�1$ return {"amd_typegpu5�_�2����\�Y,�1( gpu_info = {"amd_typegpu5�_�2����\�Y.�1& gpu_info[]"amd_typegpu5�_�2%����\�Y/�1% gpu_info["amd_typegpu5�_�2&����\�Y0�1& gpu_info["amd_typegpu}5�_�2%����\�Y2�1& gpu_info["amd_typegpu]5�_�����\�YK�2 if possible_gpu:5�_�#����\�YS�"$2 if not gpus:5�_�%����\�YY�$&2 return gpus5�_�%����\�YY �$&2 return 5�_�#����\�Yr�"$2 if not :5�_�.����\�Y��.03 �.025�_�/����\�Y��.03 memory_types = ["Hynix"]5�_� /)����\�Y��.03* memory_types = ["Hynix", "Samsun"]5�_�! /4����\�Y��.035 memory_types = ["Hynix", "Samsung", "Micron"]5�_� "!/7����\����.039 memory_types = ["Hynix", "Samsung", "Micron", ""]5�_�!#"3����23V\���3�35�_�"$#3����23V\��!�356�3555�_�#%$4����23V\��.�356 for gpu in mem5�_�$&%5(����23V\��7�4668 if re.search(gpu, amdmeminfo, re.MULTILINE):5�_�%'&5#����23V\��=�4663 if re.search(gpu, memoy, re.MULTILINE):5�_�&('6����23V\��C�5$ gpu_info["amd_type"]5�_�')(5����\��~�466: if re.search(gpu, memory_types, re.MULTILINE):5�_�(*)6����\�ۃ�5' gpu_info["memory_type"]5�_�)+*6����\�ۆ�5# gpu_info["memory_type"]5�_�*,+4 ����\�ۉ�356 for gpu in memory_types:: if re.search(gpu, memory_types, re.MULTILINE):5�_�+-,4����\�ۊ�365I for gpu in memory_types: if re.search(gpu, memory_types, re.MULTILINE):5�_�,.-3����\�ۓ�246$ gpu_info["amd_type"] for gpu in memory_types:5�_�-/.3%����\�۔�255= gpu_info["amd_type"] for gpu in memory_types:5�_�.0/4����\�ە�356( for gpu in memory_types:5�_�/104����\�ۖ�356$ for gpu in memory_types:5�_�021/����\�۶�/17 �/165�_�1320����\�ۼ�/0 memory_serial =5�_�2436����\�۾�6 �65�_�3547����\����7 import reimport shleximport subprocess from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class AmdMemInfo:( def __init__(self, amdmeminfo_path):. self.amdmeminfo_path = amdmeminfo_path def get_all_gpu_info(self): all_gpu_info = [] try:1 amdmeminfo = subprocess.check_output(J shlex.split("{} --no-opencl".format(self.amdmeminfo_path)) ).decode("utf-8")P split_info = amdmeminfo.split("-----------------------------------") adapter_num = 0# for line in split_info:9 gpu_info = AmdMemInfo._get_gpu_info(line) if gpu_info: logger.info(F "AMD GPU found adapter_num={} type={}".format(1 adapter_num, gpu_info ) )1 all_gpu_info.append(gpu_info) except Exception as e:D logger.error("could not run amdmeminfo! e={}".format(e)) if not all_gpu_info:, logger.warn("No AMD GPUs found") return all_gpu_info% def get_num_of_amd_devices(self):+ return len(self.get_all_gpu_info()) # helpers @staticmethod" def _get_gpu_info(amdmeminfo): gpu_info = {}( amd_types = ["RX 580", "RX 570"]? memory_types = ["Hynix", "Samsung", "Micron", "Elpida"] for gpu in amd_types:8 if re.search(gpu, amdmeminfo, re.MULTILINE):$ gpu_info["amd_type"] for gpu in memory_types:: if re.search(gpu, memory_types, re.MULTILINE):' gpu_info["memory_type"] 5�_�4656����\����6�65�_�5767 ����\����689. gps = re.findall(r'[0-9].[0-9]*\sgps',5�_�6877(����\��_�6895 gps = re.findall(r'Memory Model.[0-9]*\sgps',5�_�7987(����\��a�689* gps = re.findall(r'Memory Model.',5�_�8:99<����\��j�8= re.MULTILINE)[-1].strip().split()[0]5�_�9;:9*����\��y�8= re.MULTILINE)[-1].strip().split()[3]5�_�:<;7����\�܃�689+ gps = re.findall(r'Memory Model.*',5�_�;=<8����\�܊�799 log,5�_�<>=8"����\�ܒ�9 import reimport shleximport subprocess from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class AmdMemInfo:( def __init__(self, amdmeminfo_path):. self.amdmeminfo_path = amdmeminfo_path def get_all_gpu_info(self): all_gpu_info = [] try:1 amdmeminfo = subprocess.check_output(J shlex.split("{} --no-opencl".format(self.amdmeminfo_path)) ).decode("utf-8")P split_info = amdmeminfo.split("-----------------------------------") adapter_num = 0# for line in split_info:9 gpu_info = AmdMemInfo._get_gpu_info(line) if gpu_info: logger.info(F "AMD GPU found adapter_num={} type={}".format(1 adapter_num, gpu_info ) )1 all_gpu_info.append(gpu_info) except Exception as e:D logger.error("could not run amdmeminfo! e={}".format(e)) if not all_gpu_info:, logger.warn("No AMD GPUs found") return all_gpu_info% def get_num_of_amd_devices(self):+ return len(self.get_all_gpu_info()) # helpers @staticmethod" def _get_gpu_info(amdmeminfo): gpu_info = {}( amd_types = ["RX 580", "RX 570"]? memory_types = ["Hynix", "Samsung", "Micron", "Elpida"] for gpu in amd_types:8 if re.search(gpu, amdmeminfo, re.MULTILINE):$ gpu_info["amd_type"] for gpu in memory_types:: if re.search(gpu, memory_types, re.MULTILINE):' gpu_info["memory_type"]5 memory_serial = re.findall(r'Memory Model.*',$ amdmeminfo,9 re.MULTILINE).strip().split()[3]5�_�=?>7����\�ܙ�689 memory_serial = (5�_�>?7����\�ܞ�689# gpu_info["memory_serial = (5�_�#����\�Yn�"$2& if not get_all_current_straps:5��
Vim�UnDo����}}"'�q��K�j�[|u��!Km/�|φ��! logger.info(response)<2222^{_�9����996v6]�8:�8 time.sleep(0.03333 - (self.start - time.time()))5�_�8����996v6]�8:� �9:��8:�5�_�:����::6v6]�9;� time.sleep()5�_�9����::6v6]�9;� �9;�5�_�:&����;;6v6]�9;�' logger.debug("sleeping for {}")5�_�1����;;6v6]���13��12�5�_�2����<<6v6]���13�: logger.debug("sleeping for {}".format(sleep_time))5�_� 2����<<6v6]���13� logger.debug("))5�_� 2����<<6v6]���13� logger.debug("")5�_� A����<<6v6]���BD��BC��AC�5�_� C����<<6v6]��BD�. logger.debug("running animation step")5�_� C����<<6v6]��BD� logger.debug("")5�_� C����<<6v6]��BD�; logger.debug("updating state of ambiance from api")5�_� C,����<<6v6]��BD�I logger.debug("attempting to updating state of ambiance from api")5�_�D)����<<6v6]��DF��DE�5�_�E����EEV]��DF�G logger.debug("attempting to update state of ambiance from api")5�_�E����EEV]��DF�K logger.debug("attempting to update state of ambiance from api")5�_�E����EEV]��DF� logger.debug("")5�_�EB����EEV]�'�DF�C logger.debug("accumulated seconds waiting reacher 10s")5�_�EA����EEV]�/�DF�b logger.debug("accumulated seconds waiting reacher 10s".format(self.accum_ten_seconds))5�_�CD����EEV]�6�BD�G logger.debug("attempting to update state of ambiance from api")�CD�5�_�Co����EEV]�<�BD�q logger.debug("attempting to update state of ambiance from api timer={}".format(self.accum_ten_seconds))")5�_�Cn����EEV]�<��import timeUfrom thunder_and_lightning.animations import WifiSearch, WifiFound, Mining, PowerDown from utils import CoinmineLogger+from utils.requests import CoinmineRequests!logger = CoinmineLogger(__name__)class AmbianceController: def __init__( self, teensy_interface, state_json,# minary_ambiance_server_url, animation_queue, num_led=10, ): self.state = None% self.last_state_json = dict()$ self.state_json = state_json self.num_led = num_led$ self.ambiance_enabled = True0 self.teensy_interface = teensy_interfaceD self.minary_ambiance_server_url = minary_ambiance_server_url" self.accum_ten_seconds = 0. self.animation_queue = animation_queue def turn_lights_off(self): self.state.reset()= self.teensy_interface.set_lights(self.state.render())% def run_poweroff_animation(self):! if self.ambiance_enabled:9 if self.teensy_interface.serial_port.is_open:9 self.teensy_interface.serial_port.close()8 self.teensy_interface.serial_port.open()1 self.run_state_animation(PowerDown())" self.turn_lights_off()) def run_state_animation(self, state): self.state = state while True: if self.state.done: return4 self._play_audio_and_animate_one_frame()! def run_animation_step(self):. logger.debug("running animation step") self._start_timer()! self._update_state_json()% self._set_prioritized_state() if self.state:4 self._play_audio_and_animate_one_frame()) self.accum_ten_seconds += 0.033339 sleep_time = 0.03333 - (self.start - time.time()): logger.debug("sleeping for {}".format(sleep_time)) time.sleep(sleep_time) def _start_timer(self): self.start = time.time()! def _update_state_json(self):o logger.debug("attempting to update state of ambiance from api timer={}".format(self.accum_ten_seconds))* if self.accum_ten_seconds >= 10.0:k logger.debug("accumulated seconds waiting reacher 10s timer={}".format(self.accum_ten_seconds))& self.accum_ten_seconds = 03 self.state_json = CoinmineRequests.get(8 self.minary_ambiance_server_url, "state" )K self.ambiance_enabled = self.state_json.get("ambiance_enabled")% def _set_prioritized_state(self):9 if not (self.state_json == self.last_state_json): updated = set( [ item[0]< for item in set(self.state_json.items())7 ^ set(self.last_state_json.items()) ] )? logger.info("full_status diff: {}".format(updated)) field = "none" queue_list = []O if "wifi_search" in updated and self.state_json.get("wifi_search"):% field = "wifi_search"4 queue_list.append((0, WifiSearch()))M if "wifi_found" in updated and self.state_json.get("wifi_found"):$ field = "wifi_found"3 queue_list.append((0, WifiFound()))A if "coin" in updated and self.state_json.get("coin"): field = "coin"G queue_list.append((1, Mining(self.state_json["coin"])))M if "power_down" in updated and self.state_json.get("power_down"):$ field = "power_down"3 queue_list.append((0, PowerDown())); self.animation_queue.set_animations(queue_list)F next_animation = self.animation_queue.get_next_animation() if next_animation:+ self.state = next_animation logger.info(8 "triggering {} switch: {} -> {}".format(2 self.state.__class__.__name__,< self.last_state_json.get(field, "none"),/ self.state_json.get(field), ) )2 self.last_state_json = self.state_json0 def _play_audio_and_animate_one_frame(self):! if self.ambiance_enabled:, if hasattr(self.state, "index"):) if self.state.index == 0:( if self.state.sound:J self.teensy_interface.play_audio(self.state.sound)% elif self.state.done:& self.state.reset()! self.state.step()E self.teensy_interface.set_lights(self.state.render()) else:2 logger.debug("skipping animation") else:" self.turn_lights_off()5�_�5����V]�F�57�5�_�7����V]�G�79� �79�5�_�8$����V]�V�79�& logger.debug("new state=")5�_�8&����V]�X�79�) logger.debug("new state={]}")5�_�8'����V]�X�79�( logger.debug("new state={}")5�_�8����V]�e�79�; logger.debug("new state={}".format(self.state))5�_�!8����V]���79�7 logger.debug("state={}".format(self.state))5�_�" !6����V]���69��67�5�_�!#"7����V]���67 if self.state:5�_�"$#7����77V]���68�? logger.debug("setting state={}".format(self.state))5�_�#%$7����77V]���68�; logger.debug("setting state={}".format(self.state))5�_�$&%L����LP V]��#�KL logger.debug(J "accumulated seconds waiting reacher 10s timer={}".format(* self.accum_ten_seconds ) )5�_�%'&F����JFV]��%�EF logger.debug(N "attempting to update state of ambiance from api timer={}".format(& self.accum_ten_seconds ) )5�_�&('E����FFV]��(�DE5�_�')(>����EEV]�� �=>: logger.debug("sleeping for {}".format(sleep_time))5�_�(*)7����DDV]��(�673 logger.debug("state={}".format(self.state))5�_�)+*2����CCV]���12. logger.debug("running animation step")5�_�*,+7����BBV]���67? logger.debug("setting state={}".format(self.state))5�_�+-,:����^z��;=��;<��:<�5�_�,.-<����<<V^z��;=�! logger.info(response)5�_�-/.<����<<V^z��;=� logger.info(response)5�_�.0/<����<<V^z��;=� logger.info()5�_�/10<����<<V^z��;=� logger.info(sleep_timee)5�_�021<����<<V^z��;=� logger.info(sleep_time)5�_�12<7����<<V^z��;=�7 logger.info("sleep time: {}".format(sleep_time)5�_�! 6����V]���67��67� if self.state:? logger.debug("setting state={}".format(self.state))5�_�EA����EEV]�5�DF�A logger.debug("accumulated seconds waiting reacher 10s5��
Vim�UnDoεjUυΈ'†©`a€+ Ν_eG�uΛ―Ω'¶σΜ >ώάUGD logger.error("could not run amdmeminfo! e={}".format(e))++++^‚{ξ_Π.����]Mά�υ-.<<<<<<< HEAD5�_Π.(����]Mά§υ-/E> amd_types = ["RX 580", "RX 570", "Vega 56", "Vega 64"]5�_Π19����]Mά�υ02E; amd_types = ["RX 580", "Coinmine RX 580", "RX 570"]υ12E5�_Π1:����]Mάυ02EP amd_types = ["RX 580", "Coinmine RX 580", "RX 570" "Vega 56", "Vega 64"]5�_Π.����.(/V:]Mά±υ-.) amd_types = ["RX 580", "RX 570",]=======5�_Π0����.(.V:]Mάµυ/00>>>>>>> 430daa9af71a140786e15634a6d3ecfb507628c45�_Π/P����]–Xiυ.0BQ amd_types = ["RX 580", "Coinmine RX 580", "RX 570", "Vega 56", "Vega 64"]5�_Π /\����]–XvυB import reimport shleximport subprocess from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class AmdMemInfo:( def __init__(self, amdmeminfo_path):. self.amdmeminfo_path = amdmeminfo_path def get_all_gpu_info(self): all_gpu_info = [] try:1 amdmeminfo = subprocess.check_output(G shlex.split("{} --opencl".format(self.amdmeminfo_path)) ).decode("utf-8")T split_info = amdmeminfo.split("-----------------------------------")[1:] adapter_num = 0# for line in split_info:9 gpu_info = AmdMemInfo._get_gpu_info(line) if gpu_info: logger.info(F "AMD GPU found adapter_num={} type={}".format(1 adapter_num, gpu_info ) )1 all_gpu_info.append(gpu_info) except Exception as e:D logger.error("could not run amdmeminfo! e={}".format(e)) if not all_gpu_info:- logger.error("No AMD GPUs found") return all_gpu_info def get_num_of_gpus(self):+ return len(self.get_all_gpu_info()) # helpers @staticmethod" def _get_gpu_info(amdmeminfo): gpu_info = {}, # least specific to more specific ->_ amd_types = ["RX 580", "Coinmine RX 580", "RX 570", "Vega 56", "Vega 64", "Radeon VII"]? memory_types = ["Hynix", "Samsung", "Micron", "Elpida"] for gpu in amd_types:8 if re.search(gpu, amdmeminfo, re.MULTILINE):' gpu_info["model"] = gpu for gpu in memory_types:8 if re.search(gpu, amdmeminfo, re.MULTILINE):- gpu_info["memory_type"] = gpu/ gpu_info["memory_serial"] = re.findall(7 r"Memory Model.*", amdmeminfo, re.MULTILINE )[0].split()[-1]W gpu_info["adapter_num"] = re.findall(r"OpenCL ID.*", amdmeminfo, re.MULTILINE)[ 0 ].split()[-1]. gpu_info["bios_version"] = re.findall(7 r"BIOS Version.*", amdmeminfo, re.MULTILINE )[0].split()[-1] return gpu_info5�_Π 5����]³φtυ57Iυ56I5�_Π 6 ����]³φvυ57J "Radeon VII",5�_Π 6 ����]³φ|υ57J "",5�_Π 6 ����]³φ�υ57J "5700 XT",5�_Π 6����]³ωκυ68K υ68J5�_Π 7����]³ωμυK import reimport shleximport subprocess from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class AmdMemInfo:( def __init__(self, amdmeminfo_path):. self.amdmeminfo_path = amdmeminfo_path def get_all_gpu_info(self): all_gpu_info = [] try:1 amdmeminfo = subprocess.check_output(G shlex.split("{} --opencl".format(self.amdmeminfo_path)) ).decode("utf-8")T split_info = amdmeminfo.split("-----------------------------------")[1:] adapter_num = 0# for line in split_info:9 gpu_info = AmdMemInfo._get_gpu_info(line) if gpu_info: logger.info(F "AMD GPU found adapter_num={} type={}".format(1 adapter_num, gpu_info ) )1 all_gpu_info.append(gpu_info) except Exception as e:D logger.error("could not run amdmeminfo! e={}".format(e)) if not all_gpu_info:- logger.error("No AMD GPUs found") return all_gpu_info def get_num_of_gpus(self):+ return len(self.get_all_gpu_info()) # helpers @staticmethod" def _get_gpu_info(amdmeminfo): gpu_info = {}, # least specific to more specific -> amd_types = [ "RX 580", "Coinmine RX 580", "RX 570", "Vega 56", "Vega 64", "Radeon VII", "RX 5700 XT", "Radeon Rx 5700 XT" ]? memory_types = ["Hynix", "Samsung", "Micron", "Elpida"] for gpu in amd_types:8 if re.search(gpu, amdmeminfo, re.MULTILINE):' gpu_info["model"] = gpu for gpu in memory_types:8 if re.search(gpu, amdmeminfo, re.MULTILINE):- gpu_info["memory_type"] = gpu/ gpu_info["memory_serial"] = re.findall(7 r"Memory Model.*", amdmeminfo, re.MULTILINE )[0].split()[-1]W gpu_info["adapter_num"] = re.findall(r"OpenCL ID.*", amdmeminfo, re.MULTILINE)[ 0 ].split()[-1]. gpu_info["bios_version"] = re.findall(7 r"BIOS Version.*", amdmeminfo, re.MULTILINE )[0].split()[-1] return gpu_info5�_Π7����]³ωρυ68K "Radeon Rx 5700 XT",5�_Π6����]³ωτ υ56 "RX 5700 XT",5�_Π6����]³ωώυ57J "Rx 5700 XT",5�_Π8>����]ΐΘ§ υ79J? memory_types = ["Hynix", "Samsung", "Micron", "Elpida"]5�_Π8>����88 v ]Σfυ79JJ memory_types = ["Hynix", "Samsung", "Micron", "Elpida", "Unknown"]5�_Π8����88 v ]Σiυ79J? memory_types = ["Hynix", "Samsung", "Micron", "Elpida"]υ89J5�_Π8#����88 v ]Σjυ79JJ memory_types = [, "Unknown""Hynix", "Samsung", "Micron", "Elpida"]5�_Π 8����88 v ]Σlυ79JL memory_types = [, "Unknown", "Hynix", "Samsung", "Micron", "Elpida"]5�_Π! ����^X!8υK υJ5�_Π "!����^X!>υKG shlex.split("{} --opencl".format(self.amdmeminfo_path))5�_Π!#"����^X!?υK cmd = υK5�_Π"$#=����^X!?υK= cmd = "{} --opencl".format(self.amdmeminfo_path))5�_Π#%$ ����^X!HυK from utils import CoinmineLogger5�_Π$&%����^X!UυK1 amdmeminfo = subprocess.check_output(5�_Π%'&5����^X!`υKM amdmeminfo = Converter.cmd_to_string(cmd)subprocess.check_output(5�_Π&('����V4^X!aυ shlex.split( ).decode("utf-8")5�_Π')(����V^X!dυimport shleximport subprocess5�_Π(*)"����V^X!iυG5 amdmeminfo = Converter.cmd_to_string(cmd)5�_Π)+*!����^‚{ζυ "G- logger.error("No AMD GPUs found")5�_Π*+����^‚{νυGD logger.error("could not run amdmeminfo! e={}".format(e))5�_Π8>����88 v ]Σ`υ89Jυ79JU memory_types = ["Hynix", "Samsung", "Micron", "Elpida",, "Unknown" "Unknown"]5�_Π8I����88 v ]Σ`υ89Jυ79J` memory_types = ["Hynix", "Samsung", "Micron", "Elpida",, "Unknown", "Unknown" "Unknown"]5�_Π8>����]Σ!υ79J? memory_types = ["Hynix", "Samsung", "Micron", "Elpida"]5�_Π8����]Σ$υ89Jυ79JJ memory_types = [, "Unknown""Hynix", "Samsung", "Micron", "Elpida"]5�_Π8#����]Σ%υ79JL memory_types = [, "Unknown", "Hynix", "Samsung", "Micron", "Elpida"]5�_Π8����]Σ'υ79JI memory_types = "Unknown", "Hynix", "Samsung", "Micron", "Elpida"]5�_Π8����]Σ(υ79JK memory_types = []"Unknown", "Hynix", "Samsung", "Micron", "Elpida"]5�_Π8����]Σ)υ79JJ memory_types = ["Unknown", "Hynix", "Samsung", "Micron", "Elpida"]5�_Π6����]³ωϊυ57J Rx 5700 XT",5�η�
Vim�UnDo�� �����\��=*mA�/��uN, D f?$ return EstimatedEarningsGateway( ####]/S- _�����]/RC��5�_�����]/RD�5�_�����V]/RI�+def load_account(coin_short_name, address): return LoadAccountGateway( Connection.get(D "https://{}.nanopool.org/api/v1/load_account/{}".format(( coin_short_name, address ) ) )'def payments(coin_short_name, address): return PaymentsGateway( Connection.get(@ "https://{}.nanopool.org/api/v1/payments/{}".format(( coin_short_name, address ) ) )5�_�����V]/RI�5�_�����V]/Rm�\2def estimated_earnings(coin_short_name, hashrate):5�_�&����V]/R�\(def hashrate(coin_short_name, hashrate):5�_�$����V]/R��\'def hashrate(coin_short_name, address):$ return EstimatedEarningsGateway( Connection.get(M "https://api.nanopool.org/v1/{}/approximated_earnings/{}".format() coin_short_name, hashrate ) ) )class Connection: def get(url): response = None try:( response = requests.get(url)' response.raise_for_status() except HTTPError:E logger.warning("FAILURE {}".format(make_error_message())) except RequestException:O logger.error("FAILURE {} url={}".format(make_error_message(), url)) return responseclass NanopoolGateway:& def __init__(self, response_json): try:, self.data = response_json.json() except Exception: self.data = {} def status(self):- return self.data.get("status", False) def error(self):+ return self.data.get("error", None) def to_dict(self): return self.data*class LoadAccountGateway(NanopoolGateway): def to_dict(self):! if self.status() is True: try: return {W "unpaid_balance": float(self.data["data"]["userParams"]["balance"]) }" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}'class PaymentsGateway(NanopoolGateway): def to_dict(self):! if self.status() is True: try:W return {"balance": float(self._parse_payments_dict(self.data["data"]))}" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}2 def _parse_payments_dict(self, payments_dict): total = 0* for payment_dict in payments_dict:+ total += payment_dict["amount"] return total0class EstimatedEarningsGateway(NanopoolGateway): def to_dict(self):! if self.status() is True: try:@ return {"estimated_earnings": self.data["data"]}" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}5�_� )����V]/R��[) coin_short_name, hashrate5�_� ,����V]/R��[M "https://api.nanopool.org/v1/{}/approximated_earnings/{}".format(5�_� ,����V]/R��[8 "https://api.nanopool.org/v1/{}//{}".format(5�_� ����V]/R��\�[5�_� ����V]/R��\import requests'def hashrate(coin_short_name, address):$ return EstimatedEarningsGateway( Connection.get(@ "https://api.nanopool.org/v1/{}/hashrate/{}".format(( coin_short_name, address ) ) )class Connection: def get(url): response = None try:( response = requests.get(url)' response.raise_for_status() except HTTPError:E logger.warning("FAILURE {}".format(make_error_message())) except RequestException:O logger.error("FAILURE {} url={}".format(make_error_message(), url)) return responseclass NanopoolGateway:& def __init__(self, response_json): try:, self.data = response_json.json() except Exception: self.data = {} def status(self):- return self.data.get("status", False) def error(self):+ return self.data.get("error", None) def to_dict(self): return self.data*class LoadAccountGateway(NanopoolGateway): def to_dict(self):! if self.status() is True: try: return {W "unpaid_balance": float(self.data["data"]["userParams"]["balance"]) }" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}'class PaymentsGateway(NanopoolGateway): def to_dict(self):! if self.status() is True: try:W return {"balance": float(self._parse_payments_dict(self.data["data"]))}" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}2 def _parse_payments_dict(self, payments_dict): total = 0* for payment_dict in payments_dict:+ total += payment_dict["amount"] return total0class EstimatedEarningsGateway(NanopoolGateway): def to_dict(self):! if self.status() is True: try:@ return {"estimated_earnings": self.data["data"]}" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}5�_� ����V]/R��^�^5�_� ����V]/R��aimport requests from utils import CoinmineLogger!logger = CoinmineLogger(__name__)'def hashrate(coin_short_name, address):$ return EstimatedEarningsGateway( Connection.get(@ "https://api.nanopool.org/v1/{}/hashrate/{}".format(( coin_short_name, address ) ) )class Connection: def get(url): response = None try:( response = requests.get(url)' response.raise_for_status() except HTTPError:E logger.warning("FAILURE {}".format(make_error_message())) except RequestException:O logger.error("FAILURE {} url={}".format(make_error_message(), url)) return responseclass NanopoolGateway:& def __init__(self, response_json): try:, self.data = response_json.json() except Exception: self.data = {} def status(self):- return self.data.get("status", False) def error(self):+ return self.data.get("error", None) def to_dict(self): return self.data*class LoadAccountGateway(NanopoolGateway): def to_dict(self):! if self.status() is True: try: return {W "unpaid_balance": float(self.data["data"]["userParams"]["balance"]) }" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}'class PaymentsGateway(NanopoolGateway): def to_dict(self):! if self.status() is True: try:W return {"balance": float(self._parse_payments_dict(self.data["data"]))}" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}2 def _parse_payments_dict(self, payments_dict): total = 0* for payment_dict in payments_dict:+ total += payment_dict["amount"] return total0class EstimatedEarningsGateway(NanopoolGateway): def to_dict(self):! if self.status() is True: try:@ return {"estimated_earnings": self.data["data"]}" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}5�_�����v]/R��b except HTTPError:5�_�/����v]/R��bE logger.warning("FAILURE {}".format(make_error_message()))5�_�/����v]/R��b2 logger.warning("FAILURE {}".format()))5�_�����v]/R��b except RequestException:5�_�4����v]/R��bO logger.error("FAILURE {} url={}".format(make_error_message(), url))5�_�4����v]/R��b< logger.error("FAILURE {} url={}".format(), url))5�_�6����v]/R��b= logger.error("FAILURE {} url={}".format(e), url))5�_�3����v]/R��b3 logger.warning("FAILURE {}".format(e)))5�_�����v]/R� �b�b5�_�4����4UV]/R��34"*class LoadAccountGateway(NanopoolGateway): def to_dict(self):! if self.status() is True: try: return {W "unpaid_balance": float(self.data["data"]["userParams"]["balance"]) }" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}'class PaymentsGateway(NanopoolGateway): def to_dict(self):! if self.status() is True: try:W return {"balance": float(self._parse_payments_dict(self.data["data"]))}" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}2 def _parse_payments_dict(self, payments_dict): total = 0* for payment_dict in payments_dict:+ total += payment_dict["amount"] return total5�_�4����44V]/R��345�_�3����44V]/R��235�_�4����33V]/R��35?0class EstimatedEarningsGateway(NanopoolGateway):5�_�4����33V]/R� �35?class Gateway(NanopoolGateway):5�_�8����33V]/R��79?@ return {"estimated_earnings": self.data["data"]}5�_�8����33V]/R��79?. return {"": self.data["data"]}5�_� ;.����33V]/S�:<?G logger.error("{} e={}".format(make_error_message(), e))5�_�! ;0����33V]/S�:<?4 logger.error("{} e={}".format(), e))5�_� "!;-����33V]/S�:<?1 logger.error("{} e={}".format e))5�_�!#";-����33V]/S�:<?0 logger.error("{} e={}".forma e))5�_�"# ����33V]/S, � ?$ return EstimatedEarningsGateway(5��
Vim�UnDo�L��ϸ�x�/�6 ��ub\������5���?1 logger.error("{} e={}".format(e));.'''']/h�_�����]/`���5�_�����]/`��5�_�����]/`��4from coinmine.worker.utils import make_error_message5�_�����]/`��]�]5�_�����]/`��^�^5�_�����]/`��import logging5�_�����]/`��1logger = logging.getLogger("worker.grinmint.api")5�_� ����]/`��]import requests;from requests.exceptions import RequestException, HTTPError from utils import CoinmineLogger!logger = CoinmineLogger(__name__)def user_stats(username): return UserStatsGateway(X Connection.get("https://api.grinmint.com/v1/user/{}/userStats".format(username)) )#def worker_stats(username, worker): return WorkerStatsGateway( Connection.get(O "https://api.grinmint.com/v1/user/{}/worker/{}/workerStats".format( username, worker ) ) )class Connection: def get(url): response = None try:( response = requests.get(url)' response.raise_for_status() except HTTPError:E logger.warning("FAILURE {}".format(make_error_message())) except RequestException:O logger.error("FAILURE {} url={}".format(make_error_message(), url)) return responseclass Gateway:& def __init__(self, response_json): try:, self.data = response_json.json() except Exception: self.data = {} def status(self):- return self.data.get("status", False) def error(self):+ return self.data.get("error", None) def to_dict(self): return self.data class UserStatsGateway(Gateway): def to_dict(self):! if self.status() is True: try: balance = (V float(self.data["unpaid_balance"] + self.data["immature_balance"]) / 1000000000 )K return {"amount_mined": balance, "unpaid_balance": balance}" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}"class WorkerStatsGateway(Gateway): def to_dict(self):! if self.status() is True: try: return {K "accepted_shares": self.data["worker"]["valid_shares"],( "rejected_shares": (= self.data["worker"]["invalid_shares"]= + self.data["worker"]["stale_shares"] ), }" except Exception as e:G logger.error("{} e={}".format(make_error_message(), e)) return {} else: return {}5�_� ����]/`��!] except HTTPError:5�_� !/����]/`�� "]E logger.warning("FAILURE {}".format(make_error_message()))5�_� !0����]/`�� "]2 logger.warning("FAILURE {}".format()))5�_� !2����]/`�� "]2 logger.warning("FAILURE {}".format(e))5�_� !1����]/`�� "]1 logger.warning("FAILURE {}".format(e)5�_� $4����]/`��#%]O logger.error("FAILURE {} url={}".format(make_error_message(), url))5�_�$6����]/`��#%]< logger.error("FAILURE {} url={}".format(), url))5�_�$5����]/`��#%]; logger.error("FAILURE {} url={}".format(e url))5�_�#����]/`��"$] except RequestException:5�_�E.����]/`��DF]G logger.error("{} e={}".format(make_error_message(), e))5�_�E1����]/`��DF]4 logger.error("{} e={}".format(), e))5�_�E/����]/`��DF]2 logger.error("{} e={}".format()e))5�_�Y.����]/`��XZ]G logger.error("{} e={}".format(make_error_message(), e))5�_�Y1����]/`��XZ]4 logger.error("{} e={}".format(), e))5�_� ���� V]/a�� def user_stats(username): return UserStatsGateway(X Connection.get("https://api.grinmint.com/v1/user/{}/userStats".format(username)) )5�_� ���� V]/a��Ximport requests;from requests.exceptions import RequestException, HTTPError from utils import CoinmineLogger!logger = CoinmineLogger(__name__)#def worker_stats(username, worker): return WorkerStatsGateway( Connection.get(O "https://api.grinmint.com/v1/user/{}/worker/{}/workerStats".format( username, worker ) ) )class Connection: def get(url): response = None try:( response = requests.get(url)' response.raise_for_status() except HTTPError as e:2 logger.warning("FAILURE {}".format(e))% except RequestException as e:< logger.error("FAILURE {} url={}".format(e, url)) return responseclass Gateway:& def __init__(self, response_json): try:, self.data = response_json.json() except Exception: self.data = {} def status(self):- return self.data.get("status", False) def error(self):+ return self.data.get("error", None) def to_dict(self): return self.data class UserStatsGateway(Gateway): def to_dict(self):! if self.status() is True: try: balance = (V float(self.data["unpaid_balance"] + self.data["immature_balance"]) / 1000000000 )K return {"amount_mined": balance, "unpaid_balance": balance}" except Exception as e:1 logger.error("{} e={}".format(e)) return {} else: return {}"class WorkerStatsGateway(Gateway): def to_dict(self):! if self.status() is True: try: return {K "accepted_shares": self.data["worker"]["valid_shares"],( "rejected_shares": (= self.data["worker"]["invalid_shares"]= + self.data["worker"]["stale_shares"] ), }" except Exception as e:1 logger.error("{} e={}".format(e)) return {} else: return {}5�_�4����C4V]/a��34 class UserStatsGateway(Gateway): def to_dict(self):! if self.status() is True: try: balance = (V float(self.data["unpaid_balance"] + self.data["immature_balance"]) / 1000000000 )K return {"amount_mined": balance, "unpaid_balance": balance}" except Exception as e:1 logger.error("{} e={}".format(e)) return {} else: return {}5�_�4����44V]/a��Gimport requests;from requests.exceptions import RequestException, HTTPError from utils import CoinmineLogger!logger = CoinmineLogger(__name__)#def worker_stats(username, worker): return WorkerStatsGateway( Connection.get(O "https://api.grinmint.com/v1/user/{}/worker/{}/workerStats".format( username, worker ) ) )class Connection: def get(url): response = None try:( response = requests.get(url)' response.raise_for_status() except HTTPError as e:2 logger.warning("FAILURE {}".format(e))% except RequestException as e:< logger.error("FAILURE {} url={}".format(e, url)) return responseclass Gateway:& def __init__(self, response_json): try:, self.data = response_json.json() except Exception: self.data = {} def status(self):- return self.data.get("status", False) def error(self):+ return self.data.get("error", None) def to_dict(self): return self.data"class WorkerStatsGateway(Gateway): def to_dict(self):! if self.status() is True: try: return {K "accepted_shares": self.data["worker"]["valid_shares"],( "rejected_shares": (= self.data["worker"]["invalid_shares"]= + self.data["worker"]["stale_shares"] ), }" except Exception as e:1 logger.error("{} e={}".format(e)) return {} else: return {}5�_�9����V]/a��8:EK "accepted_shares": self.data["worker"]["valid_shares"],5�_�9/����V]/a��8:Ee "current_secondary_hashrateaccepted_shares": self.data["worker"]["valid_shares"],5�_�:����:'</V/]/a� �9:( "rejected_shares": (= self.data["worker"]["invalid_shares"]= + self.data["worker"]["stale_shares"]5�_�9'����:':/V/]/a��8:BV "current_secondary_hashrate": self.data["worker"]["valid_shares"],5�_� 9����:':/V/]/a��8:BF "cuhashrate": self.data["worker"]["valid_shares"],5�_�! 95����:':/V/]/a��8:BD "hashrate": self.data["worker"]["valid_shares"],5�_� "!9O����:':/V/]/a� �8:B^ "hashrate": self.data["worker"]["current_secondary_hashratevalid_shares"],5�_�!#":����:':/V/]/a��9: ),5�_�"$#9R����:':/V/]/a��8:AR "hashrate": self.data["worker"]["current_secondary_hashrate"],5�_�#%$9P����:':/V/]/a��Aimport requests;from requests.exceptions import RequestException, HTTPError from utils import CoinmineLogger!logger = CoinmineLogger(__name__)#def worker_stats(username, worker): return WorkerStatsGateway( Connection.get(O "https://api.grinmint.com/v1/user/{}/worker/{}/workerStats".format( username, worker ) ) )class Connection: def get(url): response = None try:( response = requests.get(url)' response.raise_for_status() except HTTPError as e:2 logger.warning("FAILURE {}".format(e))% except RequestException as e:< logger.error("FAILURE {} url={}".format(e, url)) return responseclass Gateway:& def __init__(self, response_json): try:, self.data = response_json.json() except Exception: self.data = {} def status(self):- return self.data.get("status", False) def error(self):+ return self.data.get("error", None) def to_dict(self): return self.data"class WorkerStatsGateway(Gateway): def to_dict(self):! if self.status() is True: try: return {Q "hashrate": self.data["worker"]["current_secondary_hashrate"] }" except Exception as e:1 logger.error("{} e={}".format(e)) return {} else: return {}5�_�$&%����'/V/]/c��? )5�_�%'&;.����'/V/]/h��:<?1 logger.error("{} e={}".format(e))5�_�&';.����'/V/]/h��:<?3 logger.error("{} e={}".format(, e))5��
Vim�UnDo�� ����|6�d!�+}�0�6��v^����<ͿB logger.error("could not connect to redis", connection)7 \��� _�0����\����2 "successfully connected to redis "5�_�0����\����0 "successfully connected to redis5�_�0����\����1 "successfully connected to redis"> "host={} port={}".format(self.host, self.port)5�_�1����\����` "successfully connected to redis" "host={} port={}".format(self.host, self.port)5�_�2����\����G "successfully connected to redis"(self.host, self.port)5�_� F����\����Q "successfully connected to redis", {"host": self.host, self.port)5�_� M����\����X "successfully connected to redis", {"host": self.host, "port" self.port)5�_� X����\����Y "successfully connected to redis", {"host": self.host, "port": self.port)5�_� Y����\����Z "successfully connected to redis", {"host": self.host, "port": self.port})5�_� X����\����import redis from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class MinaryRedis:# def __init__(self, host, port): self.host = host self.port = port def init_redis(self): try:S self.r = redis.StrictRedis(self.host, self.port, decode_responses=True) logger.info(Y "successfully connected to redis", {"host": self.host, "port": self.port} ) return self.r except Exception as e: logger.error(- "could not connect to redis "? "host={} port={} ".format(self.host, self.port) ) raise e5�_� ,����\�����5�_�+����\����- "could not connect to redis "5�_�,����\����, "could not connect to redis"5�_�����\����? "host={} port={} ".format(self.host, self.port)5�_�����\����import redis from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class MinaryRedis:# def __init__(self, host, port): self.host = host self.port = port def init_redis(self): try:S self.r = redis.StrictRedis(self.host, self.port, decode_responses=True) logger.info(2 "successfully connected to redis",7 {"host": self.host, "port": self.port}, ) return self.r except Exception as e: logger.error(- "could not connect to redis",7 {"host": self.host, "port": self.port}, ) raise e5�_�����\���� � 5�_�����\���� self.connection =� 5�_�@����\���� @ self.connection ={"host": self.host, "port": self.port},5�_�����\���� ? self.connection ={"host": self.host, "port": self.port}5�_�����\����7 {"host": self.host, "port": self.port},5�_�2����\����2 "successfully connected to redis",5�_�A����\����import redis from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class MinaryRedis:# def __init__(self, host, port): self.host = host self.port = port@ self.connection = {"host": self.host, "port": self.port} def init_redis(self): try:S self.r = redis.StrictRedis(self.host, self.port, decode_responses=True) logger.info(B "successfully connected to redis", self.connection ) return self.r except Exception as e: logger.error(T "could not connect to redis", {"host": self.host, "port": self.port} ) raise e5�_�.����\����T "could not connect to redis", {"host": self.host, "port": self.port}5�_�.����\����. "could not connect to redis", 5�_�7����\����import redis from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class MinaryRedis:# def __init__(self, host, port): self.host = host self.port = port@ self.connection = {"host": self.host, "port": self.port} def init_redis(self): try:S self.r = redis.StrictRedis(self.host, self.port, decode_responses=True)K logger.info("successfully connected to redis", self.connection) return self.r except Exception as e: logger.error(8 "could not connect to redis", connection ) raise e5�_� 7����\��� �B logger.error("could not connect to redis", connection)5�_� 7����\��� �G logger.error("could not connect to redis", self.connection)5�_�����\���� 5�_�����\����5�_� Y����\����Z "successfully connected to redis", {"host": self.host, "port": self.port)}5�_�1����\����1 "successfully connected to redis"5�_�1����\����3 "successfully connected to redis", 5��
Vim�UnDoεακό6Hζ0Θ0΅<ε[βo Ή�ΧQ�Σ¦ρω mΫY hotspot_controller = HotspotController( minary_wifi_server_url, minary_api_server_url , ]{οL_Π7����]{ι¶υυ 5�_Π ����]{ιΈυ? minary_api_server_url = os.environ["MINARY_API_SERVER_URL"]5�_Π 5����]{ιΎυE minary_admin_api_server_url = os.environ["MINARY_API_SERVER_URL"]5�_Π :����]{ιΏυ import os-from wifi_controller import HotspotController from utils import CoinmineLogger!logger = CoinmineLogger(__name__)if __name__ == "__main__":/ logger.debug("Starting Hotspot Controller")A minary_wifi_server_url = os.environ["MINARY_WIFI_SERVER_URL"]? minary_api_server_url = os.environ["MINARY_API_SERVER_URL"]K minary_admin_api_server_url = os.environ["MINARY_ADMIN_API_SERVER_URL"]Y hotspot_controller = HotspotController(minary_wifi_server_url, minary_api_server_url)% hotspot_controller.update_state()5�_Π5����]{ιΑυ5 minary_wifi_server_url, minary_api_server_url5�_Π ����]{ο#υ K minary_admin_api_server_url = os.environ["MINARY_ADMIN_API_SERVER_URL"]5�_Π5����]{οEυ R minary_wifi_server_url, minary_api_server_url, minary_admin_api_server_url5�_Π *����]{οIυ+ hotspot_controller = HotspotController(5 minary_wifi_server_url, minary_api_server_url5�_Π ,����]{οJυY hotspot_controller = HotspotController( minary_wifi_server_url, minary_api_server_url5�_Π *����]{οKυ import os-from wifi_controller import HotspotController from utils import CoinmineLogger!logger = CoinmineLogger(__name__)if __name__ == "__main__":/ logger.debug("Starting Hotspot Controller")A minary_wifi_server_url = os.environ["MINARY_WIFI_SERVER_URL"]? minary_api_server_url = os.environ["MINARY_API_SERVER_URL"]X hotspot_controller = HotspotController(minary_wifi_server_url, minary_api_server_url )% hotspot_controller.update_state()5�η�
Vim�UnDo��\��p���f���%d�����\c�3�8" return ["coin", "address"] !$$$$^D�_� ����^D}�� 3 � 25�_� ����^D}�� 5�_� ����^D}�� 3� 25�_�����^D}�� 3 def important_values(slef)5�_� ����^D}�� 4� 35�_�����^D}�� 4 @attribute5�_�����^D}��5 �45�_� ����^D}��5 return ["coin"]5�_� !����^D~�5" return ["coin", "address"]5�_� "����^D~ �5# return ["coin", "address",]5�_� ����^D~ � 55�_�' ����^D~ �&)6S "old_config={}\nnew_config={}".format(self.old_config, self.config)5�_�*����^D,�*-8 �*,75�_�,&����^DB�+-9& def important_values_changed(self)5�_�,&����^DF�,.: �,.95�_�-&����^DP�-/; �-/:5�_�.;����^Dd�-/;= if self.value_change(self.old_config.get("coin"))5�_�.;����^Df�-/;< if self.value_change(self.old_config.get(value))5�_�.T����^Do�-/;T if self.value_change(self.old_config.get(value), self.config.get(value))5�_�.T����^Dq�.0< �.0;5�_�/����^Dt�/1= �/1<5�_�,����^D}�= from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class ConfigMonitor: def __init__(self, config): self.config = config self.old_config = {} @property def important_values(self):" return ["coin", "address"] def update(self, config):% self.old_config = self.config1 self.config = ConfigMonitor._sort(config) def _sort(config): sorted_config = config! if config.get("amdgpus"):. sorted_config["amdgpus"] = sorted(E config["amdgpus"], key=lambda i: i.get("adapter_num") ) return sorted_config def has_changed(self): changed = (S self.value_change(self.old_config.get("coin"), self.config.get("coin"))! or self.value_change(J self.old_config.get("address"), self.config.get("address") )* or self.amdgpu_config_change() ) if changed: logger.info(- "monitor detected a change\n"! "old_config={}\n"D "new_config={}".format(self.old_config, self.config) ) return changed ' def important_values_changed(self):' for values in important_values:U if self.value_change(self.old_config.get(value), self.config.get(value)): return True return False1 def value_change(self, old_value, new_value):% return old_value != new_value# def amdgpu_config_change(self):9 amdgpu_configs = self.config.get("amdgpus") or []A old_amdgpu_configs = self.old_config.get("amdgpus") or [] i = 0" for gpu in amdgpu_configs:, if gpu != old_amdgpu_configs[i]: return True i += 1 return False5�_�-����^D��,.=' for values in important_values:5�_�-����^D��,.=, for values in self.important_values:5�_�����! V^D��S self.value_change(self.old_config.get("coin"), self.config.get("coin"))! or self.value_change(J self.old_config.get("address"), self.config.get("address") )5�_����� V^D�� 9 )5�_����� V^D��9 changed = (5�_�0���� V^D��91 changed = self.important_values_changed()* or self.amdgpu_config_change()5�_� 1����;3V^D� �8 from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class ConfigMonitor: def __init__(self, config): self.config = config self.old_config = {}
Vim�UnDo��H)U �Hoۡ����(y�wi[A�ɢA# logger.warn(5555^q6�_�<����V].@�1P "docker health check reported unhealthy, " "restarting services"5�_�8����V].@�1import subprocessimport shlex from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class DockerHealthChecker:; def __init__(self, docker, docker_compose, remedy_cmd): self.docker = docker, self.docker_compose = docker_compose$ self.remedy_cmd = remedy_cmd def check(self): if self._is_healthy():@ logger.debug("docker health check reported healthy") else: logger.error(M "docker health check reported unhealthy, restarting services" )H DockerHealthChecker._restart_minary_compose(self.remedy_cmd) def _is_healthy(self):J running_containers = self.docker.get_names_of_running_containers()> services = self.docker_compose.get_names_of_services(): healthy = len(running_containers) == len(services) if not healthy: logger.warn(3 "some containers are not running, "/ "running containers={}".format(V DockerHealthChecker._diff_containers(running_containers, services) ) ) logger.debug(T "running_containers={} services={}".format(running_containers, services) ) return healthy @staticmethod) def _restart_minary_compose(command):, subprocess.run(shlex.split(command)) @staticmethod7 def _diff_containers(running_containers, services): running_containers = [F s.replace("satoshi_", "")[:-2] for s in running_containers ]< return list(set(services) - set(running_containers))5�_� ����V].C%� /class DockerHealthChecker:5�_� ����V].C/� /class DockerHealthChecker():5�_�����V].C��/5�_�����V].C�� 1� 05�_� ����V].C�� 1from health_check import Bas[]� 15�_� )����V].C��0import subprocessimport shlex from utils import CoinmineLogger!logger = CoinmineLogger(__name__)*from health_check import BaseHealthChecker-class DockerHealthChecker(BaseHealthChecker):; def __init__(self, docker, docker_compose, remedy_cmd): self.docker = docker, self.docker_compose = docker_compose$ self.remedy_cmd = remedy_cmd def check(self): if self._is_healthy():@ logger.debug("docker health check reported healthy") else:W logger.error("docker health check reported unhealthy, restarting services")H DockerHealthChecker._restart_minary_compose(self.remedy_cmd) def _is_healthy(self):J running_containers = self.docker.get_names_of_running_containers()> services = self.docker_compose.get_names_of_services(): healthy = len(running_containers) == len(services) if not healthy: logger.warn(3 "some containers are not running, "/ "running containers={}".format(V DockerHealthChecker._diff_containers(running_containers, services) ) ) logger.debug(T "running_containers={} services={}".format(running_containers, services) ) return healthy @staticmethod) def _restart_minary_compose(command):, subprocess.run(shlex.split(command)) @staticmethod7 def _diff_containers(running_containers, services): running_containers = [F s.replace("satoshi_", "")[:-2] for s in running_containers ]< return list(set(services) - set(running_containers))5�_� ����V].C�� 1*from health_check import BaseHealthChecker5�_� ����V].C�� def check(self): if self._is_healthy():@ logger.debug("docker health check reported healthy") else:W logger.error("docker health check reported unhealthy, restarting services")H DockerHealthChecker._restart_minary_compose(self.remedy_cmd)5�_� "����"$V].D�!" @staticmethod) def _restart_minary_compose(command):, subprocess.run(shlex.split(command))5�_� "����""V].D�(import subprocessimport shlex from utils import CoinmineLogger!logger = CoinmineLogger(__name__),from health_monitor import BaseHealthChecker-class DockerHealthChecker(BaseHealthChecker):; def __init__(self, docker, docker_compose, remedy_cmd): self.docker = docker, self.docker_compose = docker_compose$ self.remedy_cmd = remedy_cmd def _is_healthy(self):J running_containers = self.docker.get_names_of_running_containers()> services = self.docker_compose.get_names_of_services(): healthy = len(running_containers) == len(services) if not healthy: logger.warn(3 "some containers are not running, "/ "running containers={}".format(V DockerHealthChecker._diff_containers(running_containers, services) ) ) logger.debug(T "running_containers={} services={}".format(running_containers, services) ) return healthy @staticmethod7 def _diff_containers(running_containers, services): running_containers = [F s.replace("satoshi_", "")[:-2] for s in running_containers ]< return list(set(services) - set(running_containers))5�_� ����V].D �import subprocessimport shlex5�_� ����V].D�,from health_monitor import BaseHealthChecker5�_�����V].D �#�#5�_�����V].D�5�_�����V].D�5�_�����V].DR� "$ self.remedy_cmd = remedy_cmd5�_�'����V].DU� "( self.remedy_command = remedy_cmd5�_�9����V].DZ� "; def __init__(self, docker, docker_compose, remedy_cmd):5�_�����]�k� �# �"5�_�&����&]�m� �$ �#5�_�����&]�n/�$) services.pop("bootup_controller")5�_�����&]�n�!% �$5�_� ����&]�n��!'3 def _remove_oneshot(services, oneshot_services)5�_� @����&]�n��!'@ def _remove_oneshot(long_running_services, oneshot_services)5�_� @����&]�n�� "( � "'5�_�!'����&]�n��!#) �!#(5�_�����&]�n��* �)5�_� ����&]�n��* self.5�_� ����&+V9]�n�� print(services), services.remove("bootup_controller")5�_�! ����&!V]�p�� @staticmethodA def _remove_oneshot(long_running_services, oneshot_services):( for service in oneshot_services:1 long_running_services.remove(service)5�_� "!'����&V]�qE�#= self._remove_oneshot(services, ["bootup_controller"])5�_�!$"����&V]�qQ �( self._remove_oneshot(services, )5�_�"%#$<����&V]�q��"> services = self.docker_compose.get_names_of_services()�"5�_�$&% +����&V]�v� # � "5�_�%'&.����&V]�v� #? def __init__(self, docker, docker_compose, remedy_command):5�_�&('����&V]�v"� #. self.oneshot_servies = oneshot_servies5�_�')(-����&V]�v%� #/ self.oneshot_services = oneshot_servies5�_�(*)=����&V]�v*�#S services = self.docker_compose.get_names_of_services(["bootup_controller"])5�_�)+*=����&V]�v*�#> services = self.docker_compose.get_names_of_services()5�_�*,+����&V]�v8� # def _is_healthy(self):5�_�+2,B����&V]�v=�#S services = self.docker_compose.get_names_of_services(self.oneshot_services)5�_�,3-2����&V]�v��
Vim�UnDo���fXQ�h?Y��|� �]�8�b�!�+\\/3_E def send_powereddown_status_to_admin_api(config_path, uuid_path):M\ۗ_�Q����\ۍ��Q5�_�J����\ۍ��JWR�JKR5�_�K����\ۍ��JM^5�_�L����\ۍ��_import json import ast/from utils import CoinmineLogger, SystemHelpers)from utils.requests import RequestFactory!logger = CoinmineLogger(__name__)class CoinmineRequests: @staticmethod0 def get_request(base_url, path, token=None):1 full_url = "{}/{}".format(base_url, path)> request = RequestFactory(full_url, "GET", token=token)) response = request.make_request() return response @staticmethod< def post_request(base_url, path, json=None, token=None):1 full_url = "{}/{}".format(base_url, path)J request = RequestFactory(full_url, "POST", json=json, token=token)) response = request.make_request() return response @staticmethod- def test_get(base_url, path, token=None):1 full_url = "{}/{}".format(base_url, path)C request = RequestFactory(full_url, "TEST_GET", token=token)) response = request.make_request() return response.json() @staticmethod( def get(base_url, path, token=None):1 full_url = "{}/{}".format(base_url, path)> request = RequestFactory(full_url, "GET", token=token)) response = request.make_request() return response.json() @staticmethod3 def put(base_url, path, json=None, token=None):1 full_url = "{}/{}".format(base_url, path)I request = RequestFactory(full_url, "PUT", json=json, token=token)) response = request.make_request() return response.json() @staticmethod4 def post(base_url, path, json=None, token=None):1 full_url = "{}/{}".format(base_url, path)J request = RequestFactory(full_url, "POST", json=json, token=token)) response = request.make_request() return response.json() @staticmethod+ def delete(base_url, path, token=None):1 full_url = "{}/{}".format(base_url, path)A request = RequestFactory(full_url, "DELETE", token=token)) response = request.make_request() try:" return response.json(), except json.decoder.JSONDecodeError:= logger.warn("no json returned with this request") return {} @staticmethod* def get_ngrok_info(config_server_url): """G returns a boolean rather than a string 'True' or 'False', which" always evaluates as truthy """B config = CoinmineRequests.get(config_server_url, "config") return (8 SystemHelpers.str2bool(config.get("debug")),* config.get("ngrok_authtoken"), ) @staticmethod/ def send_powereddown_status_to_admin_api():+ config = SystemHelpers.get_config()) admin_api_url = config["api_url"] token = config["token"] CoinmineRequests.put( admin_api_url,< "mineosminer/{}/status".format(self.short_uuid),( json={"powered_down": True}, token=token, )2 def sanitize_redis_value(miner_status, field):/ string_result = miner_status.get(field) if string_result:" # if "None", returns 07 return ast.literal_eval(string_result) or 0 return 05�_�X����\ێ�XZ_�XZ^5�_�Y����\ێ�XY @staticmethd5�_� T0����\ێ �SU^< "mineosminer/{}/status".format(self.short_uuid),5�_� P����\ێ6�PR_ �PR^5�_� Q.����\ێn�PR_/ short_uuid = SystemHelpers.get_uuid('')5�_� M-����\ێ��LN_/ def send_powereddown_status_to_admin_api():5�_� M-����\ێ��LN_8 def send_powereddown_status_to_admin_api(uuid_path):5�_� N*����\ێ��MO_+ config = SystemHelpers.get_config()5�_� Q6����\ێ��PR_6 short_uuid = SystemHelpers.get_uuid(uuid_path)5�_�Q'����\ۏ��PR_8 short_uuid = SystemHelpers.get_uuid(uuid_path)[]5�_�Q&����\ۏ��PR_' short_uuid = SystemHelpers.get_5�_�Q1����\ۏ��PR_1 short_uuid = SystemHelpers.get_short_uuid5�_�M����\ۗ�LN_E def send_powereddown_status_to_admin_api(config_path, uuid_path):5�_�R����\ۍ��RS�RS/ def send_powereddown_status_to_admin_api():+ config = SystemHelpers.get_config()) admin_api_url = config["api_url"] token = config["token"] CoinmineRequests.put( admin_api_url,< "mineosminer/{}/status".format(self.short_uuid),( json={"powered_down": True}, token=token, )5��
VimЯUnDoхЪїл╙ y!г╪Фw▒∙╡їSЛ╒,`╘т;┘#м┴│y=Н2 "user": ""self.wallet_address,^^гLI_╨К* ^|·SїЙЛJ logger.info("Stopped {} API", format(self.__class__.__name__))5Б_╨п" ^г0Аїо░КE self.wallet_address = "{}:{}".format(address, self.worker_id)5Б_╨U ^г3sїUWЛ їVWЛїUWК5Б_╨V ^г3yїUWЛ "-rig-id"5Б_╨V ^г3{їUWЛ "rig-id"5Б_╨V ^г3ЯїUWЛ "rig-id":5Б_╨V$ ^г3жїUWЛ$ "rig-id": self.worker_id5Б_╨ V ^г4oїUWЛ% "rig-id": self.worker_id,5Б_╨ V ^г4ВїUWЛ, "api": {rig-id": self.worker_id,5Б_╨ V1 ^г4ИїUWЛ2 "api": {"worker-idid": self.worker_id,5Б_╨ V ^г4РїUWЛ3 "api": {"worker-idid": self.worker_id},5Б_╨V ^г;╫їVXМ їWXМїVXЛ5Б_╨ V ^г;▌їUWМ1 "api": {"worker-id": self.worker_id},5Б_╨W ^г;▐їVXМ "rig-id"їWXМ5Б_╨W# ^г;рїVXМ# "rig-id" self.worker_id5Б_╨V ^г;с їUV" "api": {"worker-id":},5Б_╨V ^г;чїUWЛ$ "rig-id" self.worker_id,5Б_╨V ^г;щ їЛimport jsonimport configparserimport subprocessimport shlex from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class Miner: def __init__(self):# self.miner_exec_path = None self.pool_url = None self.pool_host = None self.pool_port = None! self.pool_password = None! self.pool_username = None self.worker_id = None" self.wallet_address = None def make_cmd(self): pass( def configure(self, gpu_info, coin): pass* def set_wallet_address(self, address):% self.wallet_address = address def set_worker_id(self, id): self.worker_id = id def set_pool_url(self, url): if url: self.pool_url = url1 pool_split = self.pool_url.split(":")# if len(pool_split) > 2:( protocol = pool_split[0]H self.pool_host = "{}:{}".format(protocol, pool_split[1])3 self.pool_port = int(pool_split[2]) else:. self.pool_host = pool_split[0]3 self.pool_port = int(pool_split[1])* def set_pool_username(self, username):% self.pool_username = username* def set_pool_password(self, password):% self.pool_password = password def start_http_server(self): pass def stop_http_server(self): passclass ClaymoreMiner(Miner):# def __init__(self, miner_path):O self.miner_exec_path = "{}/claymore/./ethdcrminer64".format(miner_path)* def set_wallet_address(self, address):E self.wallet_address = "{}/{}".format(address, self.worker_id) def make_cmd(self):6 return "{} -epool {} -ewal {} -mode 1".format(D self.miner_exec_path, self.pool_url, self.wallet_address )class XmrStakMiner(Miner):# def __init__(self, miner_path):J self.miner_exec_path = "{}/xmr-stak/./xmr-stak".format(miner_path)G self.amd_config_path = "{}/xmr-stak/amd.txt".format(miner_path)* def set_wallet_address(self, address):E self.wallet_address = "{}.{}".format(address, self.worker_id)- def configure(self, gpu_info, coin=None):2 with open(self.amd_config_path, "w") as f:3 f.write(self.generate_config(gpu_info))$ def generate_config(self, gpus):S config = '"auto_tune" : 20,\n"platform_index" : 0,\n"gpu_threads_conf" : [' gpu_config = { "Coinmine RX 580": {! "intensity": 880,) "affine_to_cpu": "false",$ "comp_mode": "true", "worksize": 8, "unroll": 8, }, "RX 580": {! "intensity": 880,) "affine_to_cpu": "false",$ "comp_mode": "true", "worksize": 8, "unroll": 8, }, "RX 570": {! "intensity": 800,) "affine_to_cpu": "false",$ "comp_mode": "true", "worksize": 8, "unroll": 8, }, "Vega 56": {" "intensity": 1932,) "affine_to_cpu": "false",% "comp_mode": "false", "worksize": 8, "unroll": 8, }, "Vega 64": {" "intensity": 1932,) "affine_to_cpu": "false",% "comp_mode": "false", "worksize": 8, "unroll": 8, }, "Radeon VII": {" "intensity": 1920,) "affine_to_cpu": "false",% "comp_mode": "false", "worksize": 16, "unroll": 4, }, } adapter_num = 0 for gpu in gpus:# double_thread_gpu = """ {{ "index" : {0},( "intensity" : {1}, "worksize" : {2},@ "affine_to_cpu" : {3}, "strided_index" : 2, "mem_chunk" : 2,8 "unroll" : {4}, "comp_mode" : {5}, "interleave" : 40 }}, {{ "index" : {0},( "intensity" : {1}, "worksize" : {2},@ "affine_to_cpu" : {3}, "strided_index" : 2, "mem_chunk" : 2,8 "unroll" : {4}, "comp_mode" : {5}, "interleave" : 40 }},"""= intensity = gpu_config[gpu["model"]]["intensity"]; worksize = gpu_config[gpu["model"]]["worksize"]E affine_to_cpu = gpu_config[gpu["model"]]["affine_to_cpu"]7 unroll = gpu_config[gpu["model"]]["unroll"]= comp_mode = gpu_config[gpu["model"]]["comp_mode"]/ config += double_thread_gpu.format(R adapter_num, intensity, worksize, affine_to_cpu, unroll, comp_mode ) adapter_num += 1 # end gpus config += "],\n" return config def make_cmd(self): return (7 "{} -O {} -u {} --currency monero -i 5004 "2 '-p "" -r "" --noCPU --amd {}'.format(% self.miner_exec_path, self.pool_url,$ self.wallet_address,% self.amd_config_path, ) ) class ClaymoreZcashMiner(Miner):# def __init__(self, miner_path):R self.miner_exec_path = "{}/claymore-zcash/./zecminer64".format(miner_path)* def set_wallet_address(self, address):E self.wallet_address = "{}.{}".format(address, self.worker_id) def make_cmd(self):? return "{} -zpool {} -zwal {} -zpsw z -ftime 1".format(D self.miner_exec_path, self.pool_url, self.wallet_address )class NanoMiner(Miner):# def __init__(self, miner_path):L self.miner_exec_path = "{}/nanominer/./nanominer".format(miner_path)M self.miner_config_path = "{}/nanominer/config.ini".format(miner_path) def make_cmd(self):K return "{} {}".format(self.miner_exec_path, self.miner_config_path)/ def configure(self, gpu_info, coin="grin"):, config = configparser.ConfigParser()0 pool_password = self.pool_password or "" if coin == "grin":$ algorithm = "Cuckaroo29"! config[algorithm] = { "coin": coin,N "wallet": "{}/{}".format(self.wallet_address, self.worker_id),' "pool1": self.pool_url,D "rigName": "", # left blank for grinmint email form- "rigPassword": pool_password, } elif coin == "monero":& algorithm = "CryptoNightR"? # During Monero hardfork nanominer will auto switchN # from CryptoNightR to RandomX on CPU (GPU mining will be stopped)! config[algorithm] = { "coin": coin,. "wallet": self.wallet_address,' "pool1": self.pool_url,* "rigName": self.worker_id, }4 with open(self.miner_config_path, "w") as f: config.write(f)class TeamRedMiner(Miner):# def __init__(self, miner_path):R self.miner_exec_path = "{}/teamredminer/./teamredminer".format(miner_path) self.pool_password = "******"G self.algorithms = {"monero": "cnr", "grin": "cuckarood29_grin"}! self.monero_cn_config = { "RX 570": "8+8", "RX 580": "8+8",% "Coinmine RX 580": "8+8", "Vega 56": "14*14", "Vega 64": "15*15", } def make_cmd(self):B return "{} {}".format(self.miner_exec_path, self.cmd_args)/ def configure(self, gpu_info, coin="grin"): self.cmd_args = ( "--algo={} " "--url=stratum+{} " "--user={}/{} " "--pass={} "/ "--api_listen=0.0.0.0:4028".format(& self.algorithms[coin], self.pool_url,$ self.wallet_address, self.worker_id,# self.pool_password, ) ) if coin == "monero":& cn_config = "--cn_config=" for gpu in gpu_info:@ cn_config += self.monero_cn_config[gpu["model"]]D self.cmd_args = "{} {}".format(self.cmd_args, cn_config)class HashtopolisMiner(Miner):# def __init__(self, miner_path):R self.miner_exec_path = "{}/hashtopolis/hashtopolis.zip".format(miner_path)M self.config_path = "/app/minary/miner/config.json".format(miner_path) def make_cmd(self):8 return "python3 {}".format(self.miner_exec_path)2 def configure(self, gpu_info, coin="hashcat"):. with open(self.config_path, "w") as f:M json.dump({"url": self.pool_url, "token": self.pool_password}, f) def set_pool_url(self, url): self.pool_url = urlclass LolMiner(Miner):# def __init__(self, miner_path):J self.miner_exec_path = "{}/lolminer/./lolMiner".format(miner_path)L self.config_path = "{}/lolminer/user_config.json".format(miner_path) def make_cmd(self):5 return "{} --userCFG {} --profile {}".format(E self.miner_exec_path, self.config_path, self.coin_profile )/ def configure(self, gpu_info, coin="grin"): if coin == "grin": # 31) self.coin_profile = "GRIN_31"" coin_alg = "GRIN-AT31" # 29+ # self.coin_profile = "GRIN_29"$ # coin_alg = "GRIN-C29M". with open(self.config_path, "w") as f: json.dump( {E "DEFAULTS": {"DEVICES": "AUTO", "APIPORT": 8001},( self.coin_profile: {) "COIN": coin_alg," "POOLS": [ {7 "POOL": self.pool_host,< "PORT": str(self.pool_port),7 "USER": "******".format(G self.wallet_address, self.worker_id" ),; "PASS": self.pool_password,) "TLS": 1, } ], }, }, f, )class XmrigMiner(Miner):# def __init__(self, miner_path):D self.miner_exec_path = "{}/xmrig/./xmrig".format(miner_path)D self.config_path = "{}/xmrig/config.json".format(miner_path) def make_cmd(self):0 return "{}".format(self.miner_exec_path)1 def configure(self, gpu_info, coin="monero"): opencl = False if gpu_info: opencl = True config = { "http": { "enabled": True," "host": "0.0.0.0", "port": 53390,% "access-token": None,# "restricted": True, }, "autosave": True, "donate-level": 0, "cpu": True, "opencl": opencl, "cuda": False,% "rig-id" :self.worker_id, "pools": [ {% "coin": "monero",! "algo": None,) "url": self.pool_url,0 "user": self.wallet_address,/ "pass": self.pool_password,! "tls": False,& "keepalive": True,& "nicehash": False, } ], }. with open(self.config_path, "w") as f: json.dump(config, f)class SixMiner(Miner):# def __init__(self, miner_path):F self.miner_exec_path = "{}/6miner/./6miner".format(miner_path)B self.server_exec_path = "/app/minary/miner/./sixminer_api" def make_cmd(self):G return "{} {}".format(self.miner_exec_path, self.configuration)4 def configure(self, gpu_info, coin="handshake"):" algorithm = "hns/bl2bsha3" vendor = "amd" mode = "opencl" self.configuration = (. "--algo={} --url={} --user={}.{} "@ "--pass={} --opcl-vendor={} --mode={} --api".format( algorithm, self.pool_url,# self.pool_username, self.worker_id,# self.pool_password, vendor, mode, ) ) def start_http_server(self):W self.http_server_process = subprocess.Popen(shlex.split(self.server_exec_path))E logger.info("Started {} API".format(self.__class__.__name__)) def stop_http_server(self):$ if self.http_server_process:0 self.http_server_process.terminate()+ self.http_server_process.wait()I logger.info("Stopped {} API".format(self.__class__.__name__))5Б_╨V ^г;ЎїUV% "rig-id": self.worker_id,5Б_╨W ^г;ўїXZЛїXYЛїWYК5Б_╨Y ^г;∙їМimport jsonimport configparserimport subprocessimport shlex from utils import CoinmineLogger!logger = CoinmineLogger(__name__)class Miner: def __init__(self):# self.miner_exec_path = None self.pool_url = None self.pool_host = None self.pool_port = None! self.pool_password = None! self.pool_username = None self.worker_id = None" self.wallet_address = None def make_cmd(self): pass( def configure(self, gpu_info, coin): pass* def set_wallet_address(self, address):% self.wallet_address = address def set_worker_id(self, id): self.worker_id = id def set_pool_url(self, url): if url: self.pool_url = url1 pool_split = self.pool_url.split(":")# if len(pool_split) > 2:( protocol = pool_split[0]H self.pool_host = "{}:{}".format(protocol, pool_split[1])3 self.pool_port = int(pool_split[2]) else:. self.pool_host = pool_split[0]3 self.pool_port = int(pool_split[1])* def set_pool_username(self, username):% self.pool_username = username* def set_pool_password(self, password):% self.pool_password = password def start_http_server(self): pass def stop_http_server(self): passclass ClaymoreMiner(Miner):# def __init__(self, miner_path):O self.miner_exec_path = "{}/claymore/./ethdcrminer64".format(miner_path)* def set_wallet_address(self, address):E self.wallet_address = "{}/{}".format(address, self.worker_id) def make_cmd(self):6 return "{} -epool {} -ewal {} -mode 1".format(D self.miner_exec_path, self.pool_url, self.wallet_address )class XmrStakMiner(Miner):# def __init__(self, miner_path):J self.miner_exec_path = "{}/xmr-stak/./xmr-stak".format(miner_path)G self.amd_config_path = "{}/xmr-stak/amd.txt".format(miner_path)* def set_wallet_address(self, address):E self.wallet_address = "{}.{}".format(address, self.worker_id)- def configure(self, gpu_info, coin=None):2 with open(self.amd_config_path, "w") as f:3 f.write(self.generate_config(gpu_info))$ def generate_config(self, gpus):S config = '"auto_tune" : 20,\n"platform_index" : 0,\n"gpu_threads_conf" : [' gpu_config = { "Coinmine RX 580": {! "intensity": 880,) "affine_to_cpu": "false",$ "comp_mode": "true", "worksize": 8, "unroll": 8, }, "RX 580": {! "intensity": 880,) "affine_to_cpu": "false",$ "comp_mode": "true", "worksize": 8, "unroll": 8, }, "RX 570": {! "intensity": 800,) "affine_to_cpu": "false",$ "comp_mode": "true", "worksize": 8, "unroll": 8, }, "Vega 56": {" "intensity": 1932,) "affine_to_cpu": "false",% "comp_mode": "false", "worksize": 8, "unroll": 8, }, "Vega 64": {" "intensity": 1932,) "affine_to_cpu": "false",% "comp_mode": "false", "worksize": 8, "unroll": 8, }, "Radeon VII": {" "intensity": 1920,) "affine_to_cpu": "false",% "comp_mode": "false", "worksize": 16, "unroll": 4, }, } adapter_num = 0 for gpu in gpus:# double_thread_gpu = """ {{ "index" : {0},( "intensity" : {1}, "worksize" : {2},@ "affine_to_cpu" : {3}, "strided_index" : 2, "mem_chunk" : 2,8 "unroll" : {4}, "comp_mode" : {5}, "interleave" : 40 }}, {{ "index" : {0},( "intensity" : {1}, "worksize" : {2},@ "affine_to_cpu" : {3}, "strided_index" : 2, "mem_chunk" : 2,8 "unroll" : {4}, "comp_mode" : {5}, "interleave" : 40 }},"""= intensity = gpu_config[gpu["model"]]["intensity"]; worksize = gpu_config[gpu["model"]]["worksize"]E affine_to_cpu = gpu_config[gpu["model"]]["affine_to_cpu"]7 unroll = gpu_config[gpu["model"]]["unroll"]= comp_mode = gpu_config[gpu["model"]]["comp_mode"]/ config += double_thread_gpu.format(R adapter_num, intensity, worksize, affine_to_cpu, unroll, comp_mode ) adapter_num += 1 # end gpus config += "],\n" return config def make_cmd(self): return (7 "{} -O {} -u {} --currency monero -i 5004 "2 '-p "" -r "" --noCPU --amd {}'.format(% self.miner_exec_path, self.pool_url,$ self.wallet_address,% self.amd_config_path, ) ) class ClaymoreZcashMiner(Miner):# def __init__(self, miner_path):R self.miner_exec_path = "{}/claymore-zcash/./zecminer64".format(miner_path)* def set_wallet_address(self, address):E self.wallet_address = "{}.{}".format(address, self.worker_id) def make_cmd(self):? return "{} -zpool {} -zwal {} -zpsw z -ftime 1".format(D self.miner_exec_path, self.pool_url, self.wallet_address )class NanoMiner(Miner):# def __init__(self, miner_path):L self.miner_exec_path = "{}/nanominer/./nanominer".format(miner_path)M self.miner_config_path = "{}/nanominer/config.ini".format(miner_path) def make_cmd(self):K return "{} {}".format(self.miner_exec_path, self.miner_config_path)/ def configure(self, gpu_info, coin="grin"):, config = configparser.ConfigParser()0 pool_password = self.pool_password or "" if coin == "grin":$ algorithm = "Cuckaroo29"! config[algorithm] = { "coin": coin,N "wallet": "{}/{}".format(self.wallet_address, self.worker_id),' "pool1": self.pool_url,D "rigName": "", # left blank for grinmint email form- "rigPassword": pool_password, } elif coin == "monero":& algorithm = "CryptoNightR"? # During Monero hardfork nanominer will auto switchN # from CryptoNightR to RandomX on CPU (GPU mining will be stopped)! config[algorithm] = { "coin": coin,. "wallet": self.wallet_address,' "pool1": self.pool_url,* "rigName": self.worker_id, }4 with open(self.miner_config_path, "w") as f: config.write(f)class TeamRedMiner(Miner):# def __init__(self, miner_path):R self.miner_exec_path = "{}/teamredminer/./teamredminer".format(miner_path) self.pool_password = "******"G self.algorithms = {"monero": "cnr", "grin": "cuckarood29_grin"}! self.monero_cn_config = { "RX 570": "8+8", "RX 580": "8+8",% "Coinmine RX 580": "8+8", "Vega 56": "14*14", "Vega 64": "15*15", } def make_cmd(self):B return "{} {}".format(self.miner_exec_path, self.cmd_args)/ def configure(self, gpu_info, coin="grin"): self.cmd_args = ( "--algo={} " "--url=stratum+{} " "--user={}/{} " "--pass={} "/ "--api_listen=0.0.0.0:4028".format(& self.algorithms[coin], self.pool_url,$ self.wallet_address, self.worker_id,# self.pool_password, ) ) if coin == "monero":& cn_config = "--cn_config=" for gpu in gpu_info:@ cn_config += self.monero_cn_config[gpu["model"]]D self.cmd_args = "{} {}".format(self.cmd_args, cn_config)class HashtopolisMiner(Miner):# def __init__(self, miner_path):R self.miner_exec_path = "{}/hashtopolis/hashtopolis.zip".format(miner_path)M self.config_path = "/app/minary/miner/config.json".format(miner_path) def make_cmd(self):8 return "python3 {}".format(self.miner_exec_path)2 def configure(self, gpu_info, coin="hashcat"):. with open(self.config_path, "w") as f:M json.dump({"url": self.pool_url, "token": self.pool_password}, f) def set_pool_url(self, url): self.pool_url = urlclass LolMiner(Miner):# def __init__(self, miner_path):J self.miner_exec_path = "{}/lolminer/./lolMiner".format(miner_path)L self.config_path = "{}/lolminer/user_config.json".format(miner_path) def make_cmd(self):5 return "{} --userCFG {} --profile {}".format(E self.miner_exec_path, self.config_path, self.coin_profile )/ def configure(self, gpu_info, coin="grin"): if coin == "grin": # 31) self.coin_profile = "GRIN_31"" coin_alg = "GRIN-AT31" # 29+ # self.coin_profile = "GRIN_29"$ # coin_alg = "GRIN-C29M". with open(self.config_path, "w") as f: json.dump( {E "DEFAULTS": {"DEVICES": "AUTO", "APIPORT": 8001},( self.coin_profile: {) "COIN": coin_alg," "POOLS": [ {7 "POOL": self.pool_host,< "PORT": str(self.pool_port),7 "USER": "******".format(G self.wallet_address, self.worker_id" ),; "PASS": self.pool_password,) "TLS": 1, } ], }, }, f, )class XmrigMiner(Miner):# def __init__(self, miner_path):D self.miner_exec_path = "{}/xmrig/./xmrig".format(miner_path)D self.config_path = "{}/xmrig/config.json".format(miner_path) def make_cmd(self):0 return "{}".format(self.miner_exec_path)1 def configure(self, gpu_info, coin="monero"): opencl = False if gpu_info: opencl = True config = { "http": { "enabled": True," "host": "0.0.0.0", "port": 53390,% "access-token": None,# "restricted": True, }, "autosave": True, "donate-level": 0, "cpu": True, "opencl": opencl, "cuda": False, "pools": [ {% "rig-id": self.worker_id,% "coin": "monero",! "algo": None,) "url": self.pool_url,0 "user": self.wallet_address,/ "pass": self.pool_password,! "tls": False,& "keepalive": True,& "nicehash": False, } ], }. with open(self.config_path, "w") as f: json.dump(config, f)class SixMiner(Miner):# def __init__(self, miner_path):F self.miner_exec_path = "{}/6miner/./6miner".format(miner_path)B self.server_exec_path = "/app/minary/miner/./sixminer_api" def make_cmd(self):G return "{} {}".format(self.miner_exec_path, self.configuration)4 def configure(self, gpu_info, coin="handshake"):" algorithm = "hns/bl2bsha3" vendor = "amd" mode = "opencl" self.configuration = (. "--algo={} --url={} --user={}.{} "@ "--pass={} --opcl-vendor={} --mode={} --api".format( algorithm, self.pool_url,# self.pool_username, self.worker_id,# self.pool_password, vendor, mode, ) ) def start_http_server(self):W self.http_server_process = subprocess.Popen(shlex.split(self.server_exec_path))E logger.info("Started {} API".format(self.__class__.__name__)) def stop_http_server(self):$ if self.http_server_process:0 self.http_server_process.terminate()+ self.http_server_process.wait()I logger.info("Stopped {} API".format(self.__class__.__name__))5Б_╨\ ^гK∙ї[]Л0 "user": self.wallet_address,5Б_╨C MNV^гL9їCFЛїCDЛ5Б_╨C MNV^гL:їCEН5Б_╨[ MNV^гL> їZ[- "rig-id": self.worker_id,5Б_╨^ MNV^гLHї]_Н2 "user": ""self.wallet_address,5Б_╨C V^гL%їCDЛїCDЛ* def set_wallet_address(self, address):% self.wallet_address = address5Б_╨\ ^гK·ї[]Л7 "user": "******"self.wallet_address,5Б_╨V ^г;фїUWЛ% "rig-id:" self.worker_id,5Б_╨ V ^г;█їUWМ. "api": {"worker-idself.worker_id},5Бчк
Vim�UnDo�gN|��{|7�N$D�.�N[��$g_6�d F�FI,]B,�_�����]$�<�1 �05�_�����]$�R�2 logger.warn)5�_�6����]$�`�3 �25�_�@����]@z��3@from thunder_and_lightning.controllers import AmbianceController5�_�+U����]@z��*,3V ambiance = AmbianceController(teensy_interface, state, minary_ambiance_server_url)5�_�*D����]@z��*,4 �*,35�_�+"����]@z��4 import os import sysPfrom thunder_and_lightning.controllers import AmbianceController, AnimationQueue<from thunder_and_lightning.interfaces import TeensyInterface5from thunder_and_lightning.helpers import SerialUtils<from utils import SystemHelpers, CoinmineLogger, sentry_init+from utils.requests import CoinmineRequests sentry_init()if __name__ == "__main__":% logger = CoinmineLogger(__name__)5 script_path = os.environ["MINARY_TL_SCRIPT_PATH"]I minary_ambiance_server_url = os.environ["MINARY_AMBIANCE_SERVER_URL"]2 logger.info("Starting Light and Sound Worker")6 # Open the connection to the Lights & Sound Device% # and check that it is up to date/ 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()? if teensy_interface.update_firmware_if_version_different():3 teensy_path = SerialUtils.get_teensy_port()D teensy_interface = TeensyInterface(teensy_path, script_path)* teensy_interface.set_serial_port()0 fw_hash = teensy_interface.get_version()K logger.info("Light & Sound updated to firmware {}".format(fw_hash))3 teensy_interface.flash_audio_files_if_changed() logger.info(S "waiting for connection: {}/{}".format(minary_ambiance_server_url, "state") )& SystemHelpers.wait_for_connection(N lambda: CoinmineRequests.test_get(minary_ambiance_server_url, "state") )E state = CoinmineRequests.get(minary_ambiance_server_url, "state")# animation_queue= AnimationQueueg ambiance = AmbianceController(teensy_interface, state, minary_ambiance_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�_� +$����]@���*,6$ animation_queue = AnimationQueue5�_� 2����]@�M�247 �2465�_� ����]@�T�8�75�_� 4����]@���34 time.sleep(5)5�_� ����0v]@�o �import time5�_� ���� V]B,\�6 # Open the connection to the Lights & Sound Device% # and check that it is up to date/ 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()? if teensy_interface.update_firmware_if_version_different():3 teensy_path = SerialUtils.get_teensy_port()D teensy_interface = TeensyInterface(teensy_path, script_path)* teensy_interface.set_serial_port()0 fw_hash = teensy_interface.get_version()K logger.info("Light & Sound updated to firmware {}".format(fw_hash))5�_� ����V]B,\�3 teensy_interface.flash_audio_files_if_changed()5�_�����V]B,]�5�_�����V]B,a�<from thunder_and_lightning.interfaces import TeensyInterface5from thunder_and_lightning.helpers import SerialUtils5�_�����V]B,��5 script_path = os.environ["MINARY_TL_SCRIPT_PATH"]5�_� ����V]B,� � "� "5�_�����V]B,�� 5 script_path = os.environ["MINARY_TL_SCRIPT_PATH"]5�_�����V]B,��*� *5�_�����V]B,��+5�_�����V]B,��6 # Open the connection to the Lights & Sound Device% # and check that it is up to date5�_�����V]B,��*�*5�_�����V]B,��5from thunder_and_lightning.helpers import SerialUtils5�_�����V]B,��*�*5�_�����V]B,��+�+5��