Schnitzel/hass-miner

Status.UNAUTHENTICATED when trying to set the power limit

Closed this issue · 10 comments

Version of the custom_component

Miner
V1.1.0-beta2

HA
Core 2024.1.1
Supervisor 2023.12.0
Operating System 11.3
Frontend 20240104.0

Describe the bug

When trying to set the power limit from within Home Assistant it gets the following error.
image

log


Logger: homeassistant.components.websocket_api.http.connection
Source: components/websocket_api/commands.py:238
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 16:26:37 (3 occurrences)
Last logged: 16:27:45

[547794924736] (<Status.UNAUTHENTICATED: 16>, 'Missing or invalid authentication token', None)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 238, in handle_call_service
    response = await hass.services.async_call(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2149, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2186, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 272, in handle_service
    return await service.entity_service_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 882, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 952, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/number/__init__.py", line 111, in async_set_value
    await entity.async_set_native_value(native_value)
  File "/config/custom_components/miner/number.py", line 130, in async_set_native_value
    result = await miner.web.grpc.decrement_power_target(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/pyasic/web/bosminer/__init__.py", line 448, in decrement_power_target
    return await self.send_command(
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/pyasic/web/bosminer/__init__.py", line 326, in send_command
    return (await endpoint(message, metadata=metadata)).to_pydict()
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/pyasic/web/bosminer/proto/braiins/bos/v1/__init__.py", line 1837, in decrement_power_target
    return await self._unary_unary(
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/betterproto/grpc/grpclib_client.py", line 85, in _unary_unary
    response = await stream.recv_message()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/grpclib/client.py", line 425, in recv_message
    await self.recv_initial_metadata()
  File "/usr/local/lib/python3.11/site-packages/grpclib/client.py", line 393, in recv_initial_metadata
    self._raise_for_grpc_status(status, message, details)
  File "/usr/local/lib/python3.11/site-packages/grpclib/client.py", line 345, in _raise_for_grpc_status
    raise GRPCError(status, message, details)
grpclib.exceptions.GRPCError: (<Status.UNAUTHENTICATED: 16>, 'Missing or invalid authentication token', None)


pyasic is trying to use gRPC on the backend to handle setting power limit (as opposed to editing the config, which tends to be really buggy on new models), and for some reason is having issues authenticating with it. Have you changed the password of that miner at all?

I'll do some testing (either tonight or tomorrow) to see if I have the same issue, but as far as I remember, the implementation was working last time I tried.

I haven't changed the password for this unit, however I can set one and then see if that changes anything.

My testing locally is working good, but that being said, I only have a BCB100, no miner to pair it with, so I'm a f ew version behind, and only able to test with get_ commands, I'm not able to do the increment_power_target command that you're having the issue with. I would assume the authentication should work the same for all versions and all commands, but I may be wrong.

This may end up being a very complex issue if I'm unable to test on a real miner, but I have asked some friends if they can get me access to some, I'll see if I can get this figured out for you.

So I have set a password on the S19 and still no go. Same error as above.

When i try on an S9 i get the following error

Logger: homeassistant.components.websocket_api.http.connection
Source: components/websocket_api/commands.py:238
Integration: Home Assistant WebSocket API (documentation, issues)
First occurred: 16:57:43 (1 occurrences)
Last logged: 16:57:43

[547794924736] [Errno 111] Connect call failed ('192.168.36.19', 50051)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 238, in handle_call_service
    response = await hass.services.async_call(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2149, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2186, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 272, in handle_service
    return await service.entity_service_call(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 882, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 952, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/components/number/__init__.py", line 111, in async_set_value
    await entity.async_set_native_value(native_value)
  File "/config/custom_components/miner/number.py", line 134, in async_set_native_value
    result = await miner.web.grpc.increment_power_target(
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/pyasic/web/bosminer/__init__.py", line 435, in increment_power_target
    return await self.send_command(
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/pyasic/web/bosminer/__init__.py", line 319, in send_command
    metadata.append(("authorization", await self.auth()))
                                      ^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/pyasic/web/bosminer/__init__.py", line 333, in auth
    await self._get_auth()
  File "/usr/local/lib/python3.11/site-packages/pyasic/web/bosminer/__init__.py", line 345, in _get_auth
    await stream.send_message(req, end=True)
  File "/usr/local/lib/python3.11/site-packages/grpclib/client.py", line 241, in send_message
    await self.send_request()
  File "/usr/local/lib/python3.11/site-packages/grpclib/client.py", line 173, in send_request
    protocol = await self._channel.__connect__()
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/grpclib/client.py", line 748, in __connect__
    self._protocol = await self._create_connection()
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/grpclib/client.py", line 725, in _create_connection
    _, protocol = await self._loop.create_connection(
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 1085, in create_connection
    raise exceptions[0]
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 1069, in create_connection
    sock = await self._connect_sock(
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/base_events.py", line 973, in _connect_sock
    await self.sock_connect(sock, address)
  File "/usr/local/lib/python3.11/asyncio/selector_events.py", line 628, in sock_connect
    return await fut
           ^^^^^^^^^
  File "/usr/local/lib/python3.11/asyncio/selector_events.py", line 668, in _sock_connect_cb
    raise OSError(err, f'Connect call failed {address}')
ConnectionRefusedError: [Errno 111] Connect call failed ('192.168.36.19', 50051)


Ok, that's definitely not supposed to happen. S9s don't even support gRPC, there's no reason that service should even be getting called in the first place. I'll take a look through the code tomorrow and see if I can figure it out, but likely need to add a try/except for that connection error.

@Schnitzel this should be an easy fix, just add ConnectionError to this except line -

except pyasic.APIError:

            except (ConnectionError, pyasic.APIError):```

@UpstreamData & @Schnitzel I can confirm the above code change does work on an S19, I will try with the T17 and S9 later today.

Pretty sure I fixed this in v1.1.0, it was more of a pyasic issue, but now that ive seperated S19 and S9s in the backend I think it should work much better.

I don't beleve the component has been actually updated yet, I just manually made the changes to the component on my environment to confirm it worked.

I don't beleve the component has been actually updated yet, I just manually made the changes to the component on my environment to confirm it worked.

FYI, I actually removed all the code that was causing that issue from hass-miner. It is all handled the way it should have been, with set_power_limit via pyasic, and pyasic seperates between gRPC enabled miners and non gRPC enabled miners.