moggieuk / Happy-Hare

MMU software driver for Klipper (ERCF, Tradrack, Prusa)
GNU General Public License v3.0
448 stars 107 forks source link

Failed to send spoolid to Spoolman #384

Closed FeatureExpert closed 3 weeks ago

FeatureExpert commented 4 weeks ago

Hello. I'm not sure my problem is related to HH or Spoolman or maybe it's a configuration problem but I'm unable to send spoolid to Spoolman. I'm using HH 2.7.0 and Spoolman 0.19.3. spoolman_support is set to 'push'.

10:38:35 $ MMU_SPOOLMAN REFRESH=1 SYNC=1
10:38:35 !! Failed to set spool 25 for printer voron
10:38:35 !! Failed to set spool 4 for printer voron
10:38:35 !! Failed to set spool 19 for printer voron
10:38:35 !! Failed to set spool 3 for printer voron
10:38:35 !! Failed to set spool 20 for printer voron
10:38:35 !! Failed to set spool 22 for printer voron
10:40:04 $ MMU_GATE_MAP GATE=0 SPOOLID=25
10:40:04 // Gates / Filaments:
         // Gate 0: Status: Buffer, SpoolId: 25 --> Material: ABS, Color: 000000, Name: Black
         // Gate 1: Status: Buffer, SpoolId: 4 --> Material: ABS, Color: ff0000, Name: Fire Engine RED
         // Gate 2: Status: Spool, SpoolId: 3 --> Material: ABS, Color: 792fbe, Name: Purple
         // Gate 3: Status: Spool, SpoolId: 19 --> Material: ABS, Color: 1d640b, Name: Pine GREEN
         // Gate 4: Status: Spool, SpoolId: 20 --> Material: ABS, Color: 8f8f8f, Name: Silver
         // Gate 5: Status: Spool, SpoolId: 22 --> Material: ABS, Color: ffffff, Name: Cold WHITE
10:40:05 !! Failed to set spool 25 for printer voron

Moonraker log says:

2024-08-15 10:38:35,461 [mmu_server.py:_build_spool_location_cache()] - Building spool location cache from spoolman db
2024-08-15 10:38:35,532 [mmu_server.py:_set_spool_gate()] - Setting spool 25 for printer voron @ gate 0
2024-08-15 10:38:35,534 [mmu_server.py:_set_spool_gate()] - Setting spool 4 for printer voron @ gate 1
2024-08-15 10:38:35,534 [mmu_server.py:_set_spool_gate()] - Setting spool 3 for printer voron @ gate 2
2024-08-15 10:38:35,535 [mmu_server.py:_set_spool_gate()] - Setting spool 19 for printer voron @ gate 3
2024-08-15 10:38:35,536 [mmu_server.py:_set_spool_gate()] - Setting spool 20 for printer voron @ gate 4
2024-08-15 10:38:35,536 [mmu_server.py:_set_spool_gate()] - Setting spool 22 for printer voron @ gate 5
2024-08-15 10:38:35,580 [mmu_server.py:_set_spool_gate()] - Attempt to set spool failed: HTTP error: 422 HTTP 422: Unprocessable Entity
2024-08-15 10:38:35,581 [mmu_server.py:_log_n_send()] - Failed to set spool 25 for printer voron
2024-08-15 10:38:35,582 [mmu_server.py:_set_spool_gate()] - Attempt to set spool failed: HTTP error: 422 HTTP 422: Unprocessable Entity
2024-08-15 10:38:35,582 [mmu_server.py:_log_n_send()] - Failed to set spool 4 for printer voron
2024-08-15 10:38:35,584 [mmu_server.py:_set_spool_gate()] - Attempt to set spool failed: HTTP error: 422 HTTP 422: Unprocessable Entity
2024-08-15 10:38:35,584 [mmu_server.py:_log_n_send()] - Failed to set spool 19 for printer voron
2024-08-15 10:38:35,585 [mmu_server.py:_set_spool_gate()] - Attempt to set spool failed: HTTP error: 422 HTTP 422: Unprocessable Entity
2024-08-15 10:38:35,585 [mmu_server.py:_log_n_send()] - Failed to set spool 3 for printer voron
2024-08-15 10:38:35,597 [mmu_server.py:_set_spool_gate()] - Attempt to set spool failed: HTTP error: 422 HTTP 422: Unprocessable Entity
2024-08-15 10:38:35,598 [mmu_server.py:_log_n_send()] - Failed to set spool 20 for printer voron
2024-08-15 10:38:35,603 [mmu_server.py:_set_spool_gate()] - Attempt to set spool failed: HTTP error: 422 HTTP 422: Unprocessable Entity
2024-08-15 10:38:35,603 [mmu_server.py:_log_n_send()] - Failed to set spool 22 for printer voron

Here's pcap captured from Spoolman server: https://apackets.com/pcaps?pcap=f1df75dd54002fcecf8fcf48f9de2755.pcap&view=flows

In the response from Spoolman i can see {"detail":[{"type":"string_type","loc":["body","extra","mmu_gate_map"],"msg":"Input should be a valid string","input":0}]}

moggieuk commented 4 weeks ago

Thanks. This has been reported elsewhere. Works fine on my spoolmanDB so it is very strange.. Has something to do with string quoting. But if I add additional quotes, they appear as text in my DB..?

Any ideas?

FeatureExpert commented 4 weeks ago

After this little change it works for me:

klipper@voron:~/klipper/repository/happy-hare/components$ diff -u mmu_server.py mmu_server_fe.py
--- mmu_server.py       2024-08-15 02:21:47.208328325 +0200
+++ mmu_server_fe.py    2024-08-15 12:52:41.641405422 +0200
@@ -324,7 +324,7 @@
         if not silent:
             logging.info(f"Setting spool {spool_id} for printer {printer} @ gate {gate}")
         if self.spoolman_has_extras:
-            data = {'extra': {MMU_NAME_FIELD: f"\"{printer}\"", MMU_GATE_FIELD: gate}}
+            data = {'extra': {MMU_NAME_FIELD: f"\"{printer}\"", MMU_GATE_FIELD: f"{gate}"}}
             if self.update_location:
                 data['location'] = f"{printer} @ MMU Gate:{gate}"
             response = await self.http_client.request(

I'm not a programmer so no idea why integer needs to be written like this in JSON string.

FeatureExpert commented 4 weeks ago

Oh wait. Looking at the spoolman.db now any extra value should be a string because of TEXT type.

CREATE TABLE spool_field (
    spool_id INTEGER NOT NULL,
    "key" VARCHAR(64) NOT NULL,
    value TEXT NOT NULL,
    PRIMARY KEY (spool_id, "key"),
    FOREIGN KEY(spool_id) REFERENCES spool (id)
);

INSERT INTO spool_field VALUES(25,'printer_name','"voron"');
INSERT INTO spool_field VALUES(25,'mmu_gate_map','0');
moggieuk commented 3 weeks ago

The mmu_gate_map field should indeed be an integer. I've pushed a change that uses the correct json.dumps() encoding, rather than back-quoting, so an example piece of code is:

        data = {'extra': {MMU_NAME_FIELD: json.dumps(f"{printer}"), MMU_GATE_FIELD: gate}}
        if self.update_location:
            data['location'] = f"{printer} @ MMU Gate:{gate}"
        response = await self.http_client.request(
            method="PATCH",
            url=f"{self.spoolman.spoolman_url}/v1/spool/{spool_id}",
            body=json.dumps(data)
        )

This works perfectly for me. For some reason spoolman seems to be sticky as to what the field type...

If making the mmu_gate_map a string makes everything work for you if further indicates that spoolman db's are different. Very strange.

PS For a non-programming you are doing very well !!

moggieuk commented 3 weeks ago

I pushed an update to HH. You may need to force update-manger to get it.

Screenshot 2024-08-16 at 12 24 12 AM

Then DELETE the extra fields from your spoolmanDB (see screenshot).

Then RESTART Moonraker .. the extra fields will be added back.

Then see it if starts working. I can't get my system to fail. Lol.

FeatureExpert commented 3 weeks ago

Still the same error. Are you using Spoolman v0.18.1 by any chance? Seems it's working perfecly fine on 0.18.1 but starting from 0.19.0 problem occurs, at least for me.

Spoolman 0.18.1

curl -v -d '{"extra": {"printer_name": "\"voron\"", "mmu_gate_map": 0}}' -H 'Content-Type: application/json' -X PATCH http://spoolman.dom.lan/api/v1/spool/1
*   Trying 10.0.0.254:80...
* Connected to spoolman.dom.lan (10.0.0.254) port 80 (#0)
> PATCH /api/v1/spool/1 HTTP/1.1
> Host: spoolman.dom.lan
> User-Agent: curl/7.81.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 59
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/json
< Date: Thu, 15 Aug 2024 18:06:34 GMT
< Server: uvicorn
< Vary: Accept-Encoding
< Transfer-Encoding: chunked
<
* Connection #0 to host spoolman.dom.lan left intact
{"id":1,"registered":"2024-08-15T18:06:23Z","filament":{"id":1,"registered":"2024-08-15T18:06:23Z","name":"Black","vendor":{"id":1,"registered":"2024-08-15T18:06:23Z","name":"3DJAKE","external_id":"3DJAKE","extra":{}},"material":"PCTG","density":1.24,"diameter":1.75,"weight":1000.0,"spool_weight":231.0,"settings_extruder_temp":260,"settings_bed_temp":100,"color_hex":"000000","external_id":"3djake_pctg_black_1000_175_n","extra":{}},"remaining_weight":1000.0,"initial_weight":1000.0,"spool_weight":231.0,"used_weight":0.0,"remaining_length":335283.6194167644,"used_length":0.0,"archived":false,"extra":{"printer_name":"\"voron\"","mmu_gate_map":"0"}}

Spoolman 0.19.0

curl -v -d '{"extra": {"printer_name": "\"voron\"", "mmu_gate_map": 0}}' -H 'Content-Type: application/json' -X PATCH http://spoolman.dom.lan/api/v1/spool/1
*   Trying 10.0.0.254:80...
* Connected to spoolman.dom.lan (10.0.0.254) port 80 (#0)
> PATCH /api/v1/spool/1 HTTP/1.1
> Host: spoolman.dom.lan
> User-Agent: curl/7.81.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 59
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 422 Unprocessable Entity
< Content-Length: 122
< Content-Type: application/json
< Date: Thu, 15 Aug 2024 18:10:08 GMT
< Server: uvicorn
<
* Connection #0 to host spoolman.dom.lan left intact
{"detail":[{"type":"string_type","loc":["body","extra","mmu_gate_map"],"msg":"Input should be a valid string","input":0}]}
FeatureExpert commented 3 weeks ago

Ah, didnt't noticed your last commit https://github.com/moggieuk/Happy-Hare/commit/62c6416d51a562a595dbe56dcab4f943411cfca6. It's working now!

BOAndy1985 commented 3 weeks ago

Great, thank you, it works now

moggieuk commented 3 weeks ago

Fantastic! I still don't know the root cause because I never had problems, but the current implementation is more "technically" correct in the way strings are encoded.

FeatureExpert commented 3 weeks ago

I guess it was Spoolman's side change since 0.19 (fastapi version bump?), but I don't really care TBH as it's working now. Thanks for resolving this issue and keep up the good work!