jeffsf / pyDE1

Controller for the Decent Espresso DE1
GNU General Public License v3.0
77 stars 16 forks source link

[v0.7.0] [Query] Scale described as "disconnected" during remote tare request #6

Closed a112358132134 closed 3 years ago

a112358132134 commented 3 years ago

Below is a command and response from the http server to tare the scale:

$ curl -D - -X PATCH --data '{"tare": true}' http://localhost:1234/scale/tare HTTP/1.0 409 Conflict Server: BaseHTTP/0.6 Python/3.9.6 Date: Tue, 24 Aug 2021 07:43:41 GMT Content-type: text/plain Content-length: 276 Last-Modified: Tue, 24 Aug 2021 17:43:41 +1000

Traceback (most recent call last): File "/home/username/.local/lib/python3.9/site-packages/pyDE1/dispatcher/dispatcher.py", line 168, in _request_queue_processor raise DE1NotConnectedError("Scale not connected") pyDE1.exceptions.DE1NotConnectedError: Scale not connected

Below is a snip from pyDE1's console, showing slightly before and slightly after the command was executed, with clear evidence the scale is happily connected and transmitting:

2021-08-24 17:43:41,082 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x00N') 2021-08-24 17:43:41,161 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x00N') 2021-08-24 17:43:41,282 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x00N') 2021-08-24 17:43:41,402 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x14Z') 2021-08-24 17:43:41,522 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00(f') 2021-08-24 17:43:41,602 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x00N') 2021-08-24 17:43:41,722 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x14Z') 2021-08-24 17:43:41,789 INFO [InboundAPI] InboundAPI: Request: PATCH /scale/tare HTTP/1.1 2021-08-24 17:43:41,791 DEBUG [Controller] Dispatcher: PATCH SCALE_TARE requires {'DE1': False, 'Scale': True} 2021-08-24 17:43:41,793 ERROR [Controller] Dispatcher: Exception in processing HTTPMethod.PATCH Resource.SCALE_TARE DE1NotConnectedError('Scale not connected') 2021-08-24 17:43:41,794 ERROR [Controller] Dispatcher: Traceback (most recent call last): File "/home/username/.local/lib/python3.9/site-packages/pyDE1/dispatcher/dispatcher.py", line 168, in _request_queue_processor raise DE1NotConnectedError("Scale not connected") pyDE1.exceptions.DE1NotConnectedError: Scale not connected 2021-08-24 17:43:41,800 INFO [InboundAPI] InboundAPI: 127.0.0.1 - - [24/Aug/2021 17:43:41] "PATCH /scale/tare HTTP/1.1" 409 - 2021-08-24 17:43:41,803 DEBUG [InboundAPI] InboundAPI: RTT: 14.3 ms PATCH /scale/tare HTTP/1.1 2021-08-24 17:43:41,807 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x14Z') 2021-08-24 17:43:41,922 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x14Z') 2021-08-24 17:43:42,004 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x14Z') 2021-08-24 17:43:42,122 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x14Z') 2021-08-24 17:43:42,245 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x14Z') 2021-08-24 17:43:42,324 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x00N') 2021-08-24 17:43:42,442 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00(f') 2021-08-24 17:43:42,561 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x00N') 2021-08-24 17:43:42,642 DEBUG [Controller] Scale.DecentScale: Got weight data of: 13.1 using bytes bytearray(b'\x00\x83') from message bytearray(b'\x03\xce\x00\x83\x00\x14Z')

As far as I can tell, on dispatcher.py line 161 it's saying the scale isn't connected if any of these three conditions aren't met:

  1. got.resource is Resource.SCALE_ID
  2. len(got.payload.keys()) == 1
  3. 'id' in got.payload or 'first_if_found' in got.payload

At this point, got.resource is Resource.SCALE_TARE and so it raises DE1NotConnectedError("Scale not connected").

Is this expected behaviour? Am I requesting a tare correctly?

jeffsf commented 3 years ago

The primary branch there at https://github.com/jeffsf/pyDE1/blob/alpha/src/pyDE1/dispatcher/dispatcher.py#L155 is that the scale needs to be present and in in the ready state before accepting commands from the external API:

                if (got.connectivity_required['Scale']
                        and (scale_processor.scale is None
                             or not scale_processor.scale.is_ready)):

Since the API needs to support connecting to a scale, there is an exception in place to the "must be present and ready" check to allow either setting the ID directly or initiating setting of the ID indirectly through "find first".

Are you setting .is_ready when initialization of the scale is complete?

https://github.com/jeffsf/pyDE1/blob/alpha/src/pyDE1/scale/atomax_skale_ii.py#L101

There's a little trickiness there with hold_notification=True to allow the "call to super" without having it set the event, for when the specific class needs to do something after that call.

"Ready" vs. "connected" isn't a lot on a scale, but it is very significant on the DE1. You don't want to hammer it with the profile and other settings until it is ready (which may take on the order of a second).

a112358132134 commented 3 years ago

Thank you for the quick and detailed response.

Here is my init function - I was setting the ready state, but looks like not per the current internal API which uses a new definition in scale.py. Great sleuthing!

    async def standard_initialization(self, hold_notification=False):
        await super(DecentScale, self).standard_initialization(
            hold_notification=True)
        if not hold_notification:
            await self._event_connectivity.publish(
                ConnectivityChange(
                    arrival_time=time.time(),
                    state=ConnectivityState.READY
                )
            )

I'll need to walkthrough the new scale.py and atomax_skale_ii.py and make sure I'm up-to-date in the other areas too.