Skip to content

Feature/u1 filament info#705

Open
FWeinb wants to merge 7 commits intomarcolivierarsenault:mainfrom
FWeinb:feature/u1-filament-info
Open

Feature/u1 filament info#705
FWeinb wants to merge 7 commits intomarcolivierarsenault:mainfrom
FWeinb:feature/u1-filament-info

Conversation

@FWeinb
Copy link

@FWeinb FWeinb commented Feb 17, 2026

This PR adds four extruder filament information sensors specific to the Snapmaker U1. Using the moonraker api to query for print_task_config via printer.objects.query (see API response below)

I mapped the filament color info as a new sensor state value (rgba hex string, prefixed with an #) and added the other bits (vendor, type, sku, etc.) as extra state attributes:

Screenshot of the Extruder 0 filament info sensor visible in the developer tools in homeassistant

And my printer dashboard using this information
image

Sample API Response
{
  "result": {
    "eventtime": 22566.172050677,
    "status": {
      "print_task_config": {
        "filament_vendor": [
          "Snapmaker",
          "Snapmaker",
          "Snapmaker",
          "Snapmaker"
        ],
        "filament_type": [
          "PLA",
          "PLA",
          "PLA",
          "PLA"
        ],
        "filament_sub_type": [
          "SnapSpeed",
          "SnapSpeed",
          "SnapSpeed",
          "SnapSpeed"
        ],
        "filament_color": [4293058267, 4293340957, 4294230066, 4278716941],
        "filament_color_rgba": [
          "E2DEDBFF",
          "E72F1DFF",
          "F4C032FF",
          "080A0DFF"
        ],
        "filament_official": [true, true, true, true],
        "filament_sku": [900000, 900002, 900003, 900001],
        "filament_edit": [false, false, false, false],
        "filament_exist": [true, true, true, true],
        "filament_soft": [false, false, false, false],
        "extruder_map_table": [0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        "extruders_used": [false, false, false, false],
        "extruders_replenished": [0, 1, 2, 3],
        "time_lapse_camera": false,
        "auto_bed_leveling": false,
        "flow_calibrate": false,
        "shaper_calibrate": false,
        "auto_replenish_filament": true,
        "filament_entangle_detect": false,
        "reprint_info": {
          "auto_bed_leveling": false,
          "flow_calibrate": false,
          "flow_calib_extruders": [true, true, true, true],
          "time_lapse_camera": false,
          "extruder_map_table": [0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
          "extruders_used": [true, true, true, true]
        },
        "flow_calib_extruders": [true, true, true, true],
        "filament_entangle_sen": "medium"
      }
    }
  }
}

@marcolivierarsenault
Copy link
Owner

@codex review plz

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fb8476618b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

][field][extruder_index]
for field in U1_FILAMENT_ATTRIBUTES
},
subscriptions=U1_FILAMENT_ATTRIBUTES,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Define U1 subscriptions as object/field tuples

subscriptions is consumed by MoonrakerDataUpdateCoordinator.load_sensor_data, which indexes each entry as (object_name, field_name). Passing U1_FILAMENT_ATTRIBUTES (a list of strings) means each string is treated as a character sequence, so this registers bogus query targets like object 'f' / field 'i' rather than print_task_config fields, causing incorrect polling configuration and potential query failures.

Useful? React with 👍 / 👎.

Comment on lines +1034 to +1037
super()._handle_coordinator_update()
self._attr_extra_state_attributes.update(
self.entity_description.extra_state_fn(self)
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update attributes before calling async_write_ha_state

This override calls super()._handle_coordinator_update() first, and the parent implementation immediately writes entity state. The extra filament attributes are updated only afterwards and there is no second async_write_ha_state(), so Home Assistant publishes stale attributes (typically one update cycle behind, and the final update may never be written).

Useful? React with 👍 / 👎.

@marcolivierarsenault
Copy link
Owner

Can you make sure your patch account for printers that does NOT have the module.

Here is what it looks on mine.

2026-02-28 12:05:32.320 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up moonraker platform for sensor: 'NoneType' object is not subscriptable
Traceback (most recent call last):
  File "/home/vscode/.local/lib/python3.13/site-packages/homeassistant/helpers/entity_platform.py", line 455, in _async_setup_platform
    await asyncio.shield(awaitable)
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 374, in async_setup_entry
    await async_setup_u1_sensors(coordinator, entry, async_add_entities)
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 927, in async_setup_u1_sensors
    [U1ExtruderFilamentSensor(coordinator, entry, desc) for desc in sensors]
     ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 1028, in __init__
    super().__init__(coordinator, entry, description)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 1003, in __init__
    self._attr_native_value = description.value_fn(self)
                              ~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 894, in <lambda>
    value_fn=lambda sensor: f"#{sensor.coordinator.data[U1_PRINT_TASK_CONFIG][
                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        'filament_color_rgba'
        ~~~~~~~~~~~~~~~~~~~~~
    ][extruder_index]}",
    ~^^^^^^^^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable

@FWeinb
Copy link
Author

FWeinb commented Feb 28, 2026

Improved the check and also fixed the other suggestions.

@marcolivierarsenault
Copy link
Owner

I am still getting local error when I run this

2026-03-01 12:44:07.952 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up moonraker platform for sensor: 'NoneType' object is not subscriptable
Traceback (most recent call last):
  File "/home/vscode/.local/lib/python3.13/site-packages/homeassistant/helpers/entity_platform.py", line 455, in _async_setup_platform
    await asyncio.shield(awaitable)
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 374, in async_setup_entry
    await async_setup_u1_sensors(coordinator, entry, async_add_entities)
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 929, in async_setup_u1_sensors
    [U1ExtruderFilamentSensor(coordinator, entry, desc) for desc in sensors]
     ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 1030, in __init__
    super().__init__(coordinator, entry, description)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 1005, in __init__
    self._attr_native_value = description.value_fn(self)
                              ~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 894, in <lambda>
    value_fn=lambda sensor: f"#{sensor.coordinator.data[U1_PRINT_TASK_CONFIG][
                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        'filament_color_rgba'
        ~~~~~~~~~~~~~~~~~~~~~
    ][extruder_index]}",
    ~^^^^^^^^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable

)


async def async_setup_u1_sensors(coordinator, entry, async_add_entities):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please move this with the other setup functions

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved it now to follow this pattern:

  • _X_updater
  • async_setup_X_sensors

e.g. _queue_updater followed by async_setup_queue_sensors
and _spoolman_updater followed by async_setup_spoolman_sensors

I just added it after the async_setup_spoolman_sensors

  • _u1_updater
  • async_setup_u1_sensors

u1_print_task_query is None or
"status" not in u1_print_task_query or
U1_PRINT_TASK_CONFIG not in u1_print_task_query["status"]
or not u1_print_task_query["status"][U1_PRINT_TASK_CONFIG]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest adding adding debuging logs to debug here

@FWeinb
Copy link
Author

FWeinb commented Mar 1, 2026

I am still getting local error when I run this

2026-03-01 12:44:07.952 ERROR (MainThread) [homeassistant.components.sensor] Error while setting up moonraker platform for sensor: 'NoneType' object is not subscriptable
Traceback (most recent call last):
  File "/home/vscode/.local/lib/python3.13/site-packages/homeassistant/helpers/entity_platform.py", line 455, in _async_setup_platform
    await asyncio.shield(awaitable)
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 374, in async_setup_entry
    await async_setup_u1_sensors(coordinator, entry, async_add_entities)
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 929, in async_setup_u1_sensors
    [U1ExtruderFilamentSensor(coordinator, entry, desc) for desc in sensors]
     ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 1030, in __init__
    super().__init__(coordinator, entry, description)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 1005, in __init__
    self._attr_native_value = description.value_fn(self)
                              ~~~~~~~~~~~~~~~~~~~~^^^^^^
  File "/workspaces/moonraker-home-assistant/custom_components/moonraker/sensor.py", line 894, in <lambda>
    value_fn=lambda sensor: f"#{sensor.coordinator.data[U1_PRINT_TASK_CONFIG][
                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        'filament_color_rgba'
        ~~~~~~~~~~~~~~~~~~~~~
    ][extruder_index]}",
    ~^^^^^^^^^^^^^^^^
TypeError: 'NoneType' object is not subscriptable

Could you give me the output of http://<moonraker-host>/printer/objects/query?print_task_config so I can see what the error response looks like? Kinda lost why this verification is not enough.

[Edit]
I suspect it is still responding with:

{"status": {U1_PRINT_TASK_CONFIG: {}}}

@marcolivierarsenault
Copy link
Owner

yes I get
{"result":{"eventtime":4447542.446659984,"status":{"print_task_config":{}}}}

@FWeinb
Copy link
Author

FWeinb commented Mar 23, 2026

I think my latest changes should be compatible with that response.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants