Clon1998 / mobileraker

A Flutter mobile app for Klipper/Moonraker
Other
474 stars 52 forks source link

Parsing of heater_generic config is broken #242

Closed Clon1998 closed 1 year ago

Clon1998 commented 1 year ago

This is still happening to me with 2.5.3-249.

I've added a heater_generic and now I can no longer use the app to control my printer.

Exception:

 type 'Null' is not a subtype of type 'String' in type cast

#0      _$$_ConfigHeaterGenericFromJson (package:mobileraker/data/dto/config/config_heater_generic.g.dart:14)
#1      new _$_ConfigHeaterGeneric.fromJson (package:mobileraker/data/dto/config/config_heater_generic.freezed.dart:196)
#2      _$ConfigHeaterGenericFromJson (package:mobileraker/data/dto/config/config_heater_generic.freezed.dart:18)
#3      new ConfigHeaterGeneric.fromJson (package:mobileraker/data/dto/config/config_heater_generic.dart:45)
#4      new ConfigFile.parse (package:mobileraker/data/dto/config/config_file.dart:102)
#5      PrinterService._updateConfigFile (package:mobileraker/service/moonraker/printer_service.dart:697)
#6      PrinterService._parseObjectType (package:mobileraker/service/moonraker/printer_service.dart:529)
#7      PrinterService._temperatureStore.<anonymous closure> (package:mobileraker/service/moonraker/printer_service.dart:478)
#8      _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:625)
#9      PrinterService._parseQueriedObjects (package:mobileraker/service/moonraker/printer_service.dart:614)
#10     PrinterService._printerObjectsQuery (package:mobileraker/service/moonraker/printer_service.dart:773)
<asynchronous suspension>
#11     PrinterService.refreshPrinter (package:mobileraker/service/moonraker/printer_service.dart:203)
<asynchronous suspension>

Failed-Key: configfile Raw Json:

{
    "configfile": {
        "config": {
            "virtual_sdcard": {
                "path": "/home/bush/sv01_data/gcodes"
            },
            "pause_resume": {},
            "display_status": {},
            "menu __main __octoprint": {
                "type": "disabled"
            },
            "menu __main __sdcard": {
                "type": "disabled"
            },
            "menu __main __macros": {
                "type": "list",
                "name": "Macros"
            },
            "menu __main __macros __resume": {
                "type": "command",
                "enable": "{printer.print_stats.state == \"paused\"}",
                "name": "Resume printing",
                "gcode": "\nRESUME"
            },
            "menu __main __macros __pause": {
                "type": "command",
                "enable": "{printer.print_stats.state == \"printing\"}",
                "name": "Pause printing",
                "gcode": "\nPAUSE"
            },
            "menu __main __macros __cancel": {
                "type": "command",
                "enable": "{(printer.print_stats.state == \"printing\" or printer.print_stats.state == \"paused\")}",
                "name": "Cancel printing",
                "gcode": "\nCANCEL_PRINT"
            },
            "stepper_x": {
                "step_pin": "PF0",
                "dir_pin": "PF1",
                "enable_pin": "!PD7",
                "microsteps": "16",
                "rotation_distance": "40",
                "endstop_pin": "^PE5",
                "position_endstop": "0",
                "position_max": "300",
                "homing_speed": "50"
            },
            "stepper_y": {
                "step_pin": "PF6",
                "dir_pin": "PF7",
                "enable_pin": "!PF2",
                "microsteps": "16",
                "rotation_distance": "40",
                "endstop_pin": "^PJ1",
                "position_endstop": "0",
                "position_max": "255",
                "homing_speed": "50"
            },
            "stepper_z": {
                "step_pin": "PL3",
                "dir_pin": "!PL1",
                "enable_pin": "!PK0",
                "microsteps": "16",
                "rotation_distance": "8",
                "endstop_pin": "probe:z_virtual_endstop",
                "position_max": "300"
            },
            "extruder": {
                "max_extrude_only_distance": "100.0",
                "max_extrude_cross_section": "5.0",
                "step_pin": "PA4",
                "dir_pin": "!PA6",
                "enable_pin": "!PA2",
                "microsteps": "16",
                "rotation_distance": "7.680",
                "nozzle_diameter": "0.400",
                "filament_diameter": "1.750",
                "heater_pin": "PB4",
                "sensor_type": "EPCOS 100K B57560G104F",
                "sensor_pin": "PK5",
                "min_temp": "0",
                "max_temp": "265",
                "control": "pid",
                "pid_kp": "30.170",
                "pid_ki": "3.409",
                "pid_kd": "66.751"
            },
            "heater_bed": {
                "heater_pin": "PH5",
                "sensor_type": "EPCOS 100K B57560G104F",
                "sensor_pin": "PK6",
                "min_temp": "0",
                "max_temp": "110",
                "control": "pid",
                "pid_kp": "72.630",
                "pid_ki": "1.664",
                "pid_kd": "792.579"
            },
            "fan": {
                "pin": "PH6"
            },
            "bltouch": {
                "sensor_pin": "^PD3",
                "control_pin": "PB5",
                "x_offset": "-34.0",
                "y_offset": "-3.5",
                "z_offset": "2.30",
                "samples": "3",
                "samples_result": "median",
                "sample_retract_dist": "5.0",
                "samples_tolerance": "0.01",
                "samples_tolerance_retries": "3"
            },
            "gcode_macro CANCEL_PRINT": {
                "description": "Cancel the actual running print",
                "rename_existing": "CANCEL_PRINT_BASE",
                "gcode": "\nTURN_OFF_HEATERS\nCANCEL_PRINT_BASE"
            },
            "gcode_macro PAUSE": {
                "description": "Pause the actual running print",
                "rename_existing": "PAUSE_BASE",
                "variable_extrude": "1.0",
                "gcode": "\n\n{% set E = printer[\"gcode_macro PAUSE\"].extrude|float %}\n\n\n{% set x_park = printer.toolhead.axis_maximum.x|float - 5.0 %}\n{% set y_park = printer.toolhead.axis_maximum.y|float - 5.0 %}\n\n{% set max_z = printer.toolhead.axis_maximum.z|float %}\n{% set act_z = printer.toolhead.position.z|float %}\n{% if act_z < (max_z - 2.0) %}\n{% set z_safe = 2.0 %}\n{% else %}\n{% set z_safe = max_z - act_z %}\n{% endif %}\n\nPAUSE_BASE\nG91\n{% if printer.extruder.can_extrude|lower == 'true' %}\nG1 E-{E} F2100\n{% else %}\n{action_respond_info(\"Extruder not hot enough\")}\n{% endif %}\n{% if \"xyz\" in printer.toolhead.homed_axes %}\nG1 Z{z_safe} F900\nG90\nG1 X{x_park} Y{y_park} F6000\n{% else %}\n{action_respond_info(\"Printer not homed\")}\n{% endif %}"
            },
            "gcode_macro RESUME": {
                "description": "Resume the actual running print",
                "rename_existing": "RESUME_BASE",
                "gcode": "\n\n{% set E = printer[\"gcode_macro PAUSE\"].extrude|float %}\n\n{% if 'VELOCITY' in params|upper %}\n{% set get_params = ('VELOCITY=' + params.VELOCITY)  %}\n{%else %}\n{% set get_params = \"\" %}\n{% endif %}\n\n{% if printer.extruder.can_extrude|lower == 'true' %}\nG91\nG1 E{E} F2100\n{% else %}\n{action_respond_info(\"Extruder not hot enough\")}\n{% endif %}\nRESUME_BASE {get_params}"
            },
            "gcode_macro M600": {
                "gcode": "\n{% set X = params.X|default(50)|float %}\n{% set Y = params.Y|default(0)|float %}\n{% set Z = params.Z|default(10)|float %}\nSAVE_GCODE_STATE NAME=M600_state\nPAUSE\nG91\nG1 E-.8 F2700\nG1 Z{Z}\nG90\nG1 X{X} Y{Y} F3000\nG91\nG1 E-50 F1000\nRESTORE_GCODE_STATE NAME=M600_state"
            },
            "gcode_macro START_PRINT": {
                "gcode": "\n{% set BED_TEMP = params.BED_TEMP|default(60)|float %}\n{% set EXTRUDER_TEMP = params.EXTRUDER_TEMP|default(190)|float %}\n\nM190 S{BED_TEMP}\n\nG90\n\nG28\n\nBED_MESH_CALIBRATE\n\nSmart_Park\n\nM109 S{EXTRUDER_TEMP}\n\nLINE_PURGE"
            },
            "gcode_macro END_PRINT": {
                "gcode": "\nTURN_OFF_HEATERS\n\nG91\n\nG1 E-18 F800\n\nG1 Z10 F3000\n\nM106 S0\n\nG90\n\nG28 X\n\nM84"
            },
            "gcode_macro POWER_OFF_PRINTER": {
                "gcode": "\n{action_call_remote_method(\n\"set_device_power\", device=\"sv01\", state=\"off\"\n)}"
            },
            "gcode_macro BED_MESH_CALIBRATE": {
                "rename_existing": "_BED_MESH_CALIBRATE",
                "gcode": "\n\n{% set all_points = printer.exclude_object.objects | map(attribute='polygon') | sum(start=[]) %}\n{% set bed_mesh_min = printer.configfile.settings.bed_mesh.mesh_min %}\n{% set bed_mesh_max = printer.configfile.settings.bed_mesh.mesh_max %}\n{% set probe_count = printer.configfile.settings.bed_mesh.probe_count %}\n{% set verbose_enable = printer[\"gcode_macro _KAMP_Settings\"].verbose_enable | abs %}\n{% set probe_dock_enable = printer[\"gcode_macro _KAMP_Settings\"].probe_dock_enable | abs %}\n{% set attach_macro = printer[\"gcode_macro _KAMP_Settings\"].attach_macro | string %}\n{% set detach_macro = printer[\"gcode_macro _KAMP_Settings\"].detach_macro | string %}\n{% set mesh_margin = printer[\"gcode_macro _KAMP_Settings\"].mesh_margin | float %}\n{% set fuzz_amount = printer[\"gcode_macro _KAMP_Settings\"].fuzz_amount | float %}\n{% set probe_count = probe_count if probe_count|length > 1 else probe_count * 2  %}\n{% set max_probe_point_distance_x = ( bed_mesh_max[0] - bed_mesh_min[0] ) / (probe_count[0] - 1)  %}\n{% set max_probe_point_distance_y = ( bed_mesh_max[1] - bed_mesh_min[1] ) / (probe_count[1] - 1)  %}\n{% set x_min = all_points | map(attribute=0) | min | default(bed_mesh_min[0]) %}\n{% set y_min = all_points | map(attribute=1) | min | default(bed_mesh_min[1]) %}\n{% set x_max = all_points | map(attribute=0) | max | default(bed_mesh_max[0]) %}\n{% set y_max = all_points | map(attribute=1) | max | default(bed_mesh_max[1]) %}\n\n{% set fuzz_range = range((0) | int, (fuzz_amount * 100) | int + 1) %}\n{% set adapted_x_min = (bed_mesh_min[0] + fuzz_amount - mesh_margin, x_min) | max - (fuzz_range | random / 100.0) %}\n{% set adapted_y_min = (bed_mesh_min[1] + fuzz_amount - mesh_margin, y_min) | max - (fuzz_range | random / 100.0) %}\n{% set adapted_x_max = (bed_mesh_max[0] - fuzz_amount + mesh_margin, x_max) | min + (fuzz_range | random / 100.0) %}\n{% set adapted_y_max = (bed_mesh_max[1] - fuzz_amount + mesh_margin, y_max) | min + (fuzz_range | random / 100.0) %}\n\n{% set adapted_x_min = [adapted_x_min , bed_mesh_min[0]] | max %}\n{% set adapted_y_min = [adapted_y_min , bed_mesh_min[1]] | max %}\n{% set adapted_x_max = [adapted_x_max , bed_mesh_max[0]] | min %}\n{% set adapted_y_max = [adapted_y_max , bed_mesh_max[1]] | min %}\n\n{% set points_x = (((adapted_x_max - adapted_x_min) / max_probe_point_distance_x) | round(method='ceil') | int) + 1 %}\n{% set points_y = (((adapted_y_max - adapted_y_min) / max_probe_point_distance_y) | round(method='ceil') | int) + 1 %}\n\n{% if (([points_x, points_y]|max) > 6) %}\n{% set algorithm = \"bicubic\" %}\n{% set min_points = 4 %}\n{% else %}\n{% set algorithm = \"lagrange\" %}\n{% set min_points = 3 %}\n{% endif %}\n\n{% set points_x = [points_x , min_points]|max %}\n{% set points_y = [points_y , min_points]|max %}\n{% set points_x = [points_x , probe_count[0]]|min %}\n{% set points_y = [points_y , probe_count[1]]|min %}\n\n{% if verbose_enable == True %}\n\n{ action_respond_info( \"Algorithm: {}.\".format(\n(algorithm),\n)) }\n\n{ action_respond_info(\"Default probe count: {},{}.\".format(\n(probe_count[0]),\n(probe_count[1]),\n)) }\n\n{ action_respond_info(\"Adapted probe count: {},{}.\".format(\n(points_x),\n(points_y),\n)) }\n\n{action_respond_info(\"Default mesh bounds: {}, {}.\".format(\n(bed_mesh_min[0],bed_mesh_min[1]),\n(bed_mesh_max[0],bed_mesh_max[1]),\n)) }\n\n{% if mesh_margin > 0 %}\n{action_respond_info(\"Mesh margin is {}, mesh bounds extended by {}mm.\".format(\n(mesh_margin),\n(mesh_margin),\n)) }\n{% else %}\n{action_respond_info(\"Mesh margin is 0, margin not increased.\")}\n{% endif %}\n\n{% if fuzz_amount > 0 %}\n{action_respond_info(\"Mesh point fuzzing enabled, points fuzzed up to {}mm.\".format(\n(fuzz_amount),\n)) }\n{% else %}\n{action_respond_info(\"Fuzz amount is 0, mesh points not fuzzed.\")}\n{% endif %}\n\n{ action_respond_info(\"Adapted mesh bounds: {}, {}.\".format(\n(adapted_x_min, adapted_y_min),\n(adapted_x_max, adapted_y_max),\n)) }\n\n{action_respond_info(\"KAMP adjustments successful. Happy KAMPing!\")}\n\n{% endif %}\n\n{% if probe_dock_enable == True %}\n{attach_macro}\n{% endif %}\n\n_BED_MESH_CALIBRATE mesh_min={adapted_x_min},{adapted_y_min} mesh_max={adapted_x_max},{adapted_y_max} ALGORITHM={algorithm} PROBE_COUNT={points_x},{points_y}\n\n{% if probe_dock_enable == True %}\n{detach_macro}\n{% endif %}"
            },
            "gcode_macro LINE_PURGE": {
                "description": "A purge macro that adapts to be near your actual printed objects",
                "gcode": "\n\n{% set travel_speed = (printer.toolhead.max_velocity) * 60 | float %}\n{% set cross_section = printer.configfile.settings.extruder.max_extrude_cross_section | float %}\n\n\n{% if printer.firmware_retraction is defined %}\n{% set RETRACT = G10 | string %}\n{% set UNRETRACT = G11 | string %}\n{% else %}\n{% set RETRACT = 'G1 E-.5 F2100' | string %}\n{% set UNRETRACT = 'G1 E.5 F2100' | string %}\n{% endif %}\n\n\n{% set verbose_enable = printer[\"gcode_macro _KAMP_Settings\"].verbose_enable | abs %}\n{% set purge_height = printer[\"gcode_macro _KAMP_Settings\"].purge_height | float %}\n{% set tip_distance = printer[\"gcode_macro _KAMP_Settings\"].tip_distance | float %}\n{% set purge_margin = printer[\"gcode_macro _KAMP_Settings\"].purge_margin | float %}\n{% set purge_amount = printer[\"gcode_macro _KAMP_Settings\"].purge_amount | float %}\n{% set flow_rate = printer[\"gcode_macro _KAMP_Settings\"].flow_rate | float %}\n\n\n\n{% set all_points = printer.exclude_object.objects | map(attribute='polygon') | sum(start=[]) %}\n{% set purge_x_min = (all_points | map(attribute=0) | min | default(0)) %}\n{% set purge_x_max = (all_points | map(attribute=0) | max | default(0)) %}\n{% set purge_y_min = (all_points | map(attribute=1) | min | default(0)) %}\n{% set purge_y_max = (all_points | map(attribute=1) | max | default(0)) %}\n\n{% set purge_x_center = ([((purge_x_max + purge_x_min) / 2) - (purge_amount / 2), 0] | max) %}\n{% set purge_y_center = ([((purge_y_max + purge_y_min) / 2) - (purge_amount / 2), 0] | max) %}\n\n{% set purge_x_origin = ([purge_x_min - purge_margin, 0] | max) %}\n{% set purge_y_origin = ([purge_y_min - purge_margin, 0] | max) %}\n\n\n{% set purge_move_speed = (flow_rate / 5.0) * 60 | float %}\n\n{% if cross_section < 5 %}\n\n{action_respond_info(\"[Extruder] max_extrude_cross_section is insufficient for purge, please set it to 5 or greater. Purge skipped.\")}\n\n{% else %}\n\n{% if verbose_enable == True %}\n\n{action_respond_info(\"Moving filament tip {}mms\".format(\n(tip_distance),\n)) }\n{% endif %}\n\n{% if printer.firmware_retraction is defined %}\n{action_respond_info(\"KAMP purge is using firmware retraction.\")}\n{% else %}\n{action_respond_info(\"KAMP purge is not using firmware retraction, it is recommended to configure it.\")}\n{% endif %}\n\n{% if purge_y_origin > 0 %}\n\n{action_respond_info(\"KAMP purge starting at {}, {} and purging {}mm of filament, requested flow rate is {}mm/s3.\".format(\n(purge_x_center),\n(purge_y_origin),\n(purge_amount),\n(flow_rate),\n)) }\n\n{% else %}\n\n{action_respond_info(\"KAMP purge starting at {}, {} and purging {}mm of filament, requested flow rate is {}mm/s3.\".format(\n(purge_x_origin),\n(purge_y_center),\n(purge_amount),\n(flow_rate),\n)) }\n\n{% endif %}\n\nSAVE_GCODE_STATE NAME=Prepurge_State\n\n{% if purge_y_origin > 0 %}\n\nG92 E0\nG0 F{travel_speed}\nG90\nG0 X{purge_x_center} Y{purge_y_origin}\nG0 Z{purge_height}\nM83\nG1 E{tip_distance} F{purge_move_speed}\nG1 X{purge_x_center + purge_amount} E{purge_amount} F{purge_move_speed}\n{RETRACT}\nG0 X{purge_x_center + purge_amount + 10} F{travel_speed}\nG92 E0\nM82\nG0 Z{purge_height * 2} F{travel_speed}\n\n{% else %}\n\nG92 E0\nG0 F{travel_speed}\nG90\nG0 X{purge_x_origin} Y{purge_y_center}\nG0 Z{purge_height}\nM83\nG1 E{tip_distance} F{purge_move_speed}\nG1 Y{purge_y_center + purge_amount} E{purge_amount} F{purge_move_speed}\n{RETRACT}\nG0 Y{purge_y_center + purge_amount + 10} F{travel_speed}\nG92 E0\nM82\nG0 Z{purge_height * 2} F{travel_speed}\n\n{% endif %}\n\nRESTORE_GCODE_STATE NAME=Prepurge_State\n\n{% endif %}"
            },
            "gcode_macro Smart_Park": {
                "description": "Parks your printhead near the print area for pre-print hotend heating.",
                "gcode": "\n\n{% set kamp_settings = printer[\"gcode_macro _KAMP_Settings\"] %}\n{% set z_height = kamp_settings.smart_park_height | float %}\n{% set purge_margin = kamp_settings.purge_margin | float %}\n{% set verbose_enable = kamp_settings.verbose_enable | abs %}\n{% set center_x = printer.toolhead.axis_maximum.x / 2 | float %}\n{% set center_y = printer.toolhead.axis_maximum.y / 2 | float %}\n{% set all_points = printer.exclude_object.objects | map(attribute='polygon') | sum(start=[]) %}\n{% set x_min = all_points | map(attribute=0) | min | default(center_x) %}\n{% set y_min = all_points | map(attribute=1) | min | default(center_y) %}\n{% set travel_speed = (printer.toolhead.max_velocity) * 60 | float %}\n\n{% if purge_margin > 0 and x_min != center_x and y_min != center_y %}\n{% set x_min = [ x_min - purge_margin , x_min ] | max %}\n{% set y_min = [ y_min - purge_margin , y_min ] | max %}\n{% endif %}\n\n\n{% if verbose_enable == True %}\n\n{ action_respond_info(\"Smart Park location: {},{}.\".format(\n(x_min),\n(y_min),\n)) }\n\n{% endif %}\n\nG0 X{x_min} Y{y_min} F{travel_speed}\nG0 Z{z_height}"
            },
            "gcode_macro _KAMP_Settings": {
                "description": "This macro contains all adjustable settings for KAMP",
                "variable_verbose_enable": "True",
                "variable_mesh_margin": "0",
                "variable_fuzz_amount": "0",
                "variable_probe_dock_enable": "False",
                "variable_attach_macro": "'Attach_Probe'",
                "variable_detach_macro": "'Dock_Probe'",
                "variable_purge_height": "0.8",
                "variable_tip_distance": "15",
                "variable_purge_margin": "40",
                "variable_purge_amount": "40",
                "variable_flow_rate": "8",
                "variable_smart_park_height": ".42",
                "gcode": "\n\n{action_respond_info(\" Running the KAMP_Settings macro does nothing, it is only used for storing KAMP settings. \")}"
            },
            "menu __main __setup": {
                "type": "disabled"
            },
            "mcu": {
                "serial": "/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A10K2RB1-if00-port0",
                "restart_method": "arduino"
            },
            "printer": {
                "kinematics": "cartesian",
                "max_velocity": "300",
                "max_accel": "3000",
                "max_z_velocity": "5",
                "max_z_accel": "100"
            },
            "display": {
                "lcd_type": "st7920",
                "cs_pin": "PH1",
                "sclk_pin": "PA1",
                "sid_pin": "PH0",
                "encoder_pins": "^PC4, ^PC6",
                "click_pin": "^!PC2"
            },
            "exclude_object": {},
            "gcode_arcs": {
                "resolution": "0.1"
            },
            "bed_mesh": {
                "speed": "150",
                "horizontal_move_z": "5",
                "mesh_min": "38, 35",
                "mesh_max": "242, 214",
                "probe_count": "7, 7",
                "algorithm": "bicubic"
            },
            "safe_z_home": {
                "home_xy_position": "150, 127",
                "speed": "100",
                "z_hop": "10",
                "z_hop_speed": "10"
            },
            "delayed_gcode delayed_printer_off": {
                "initial_duration": "0.",
                "gcode": "\n{% if printer.idle_timeout.state == \"Idle\" %}\nPOWER_OFF_PRINTER\n{% endif %}"
            },
            "idle_timeout": {
                "gcode": "\nUPDATE_DELAYED_GCODE ID=delayed_printer_off DURATION=60"
            },
            "bed_screws": {
                "screw1": "38,35",
                "screw2": "242,35",
                "screw3": "242,214",
                "screw4": "38,214"
            },
            "screws_tilt_adjust": {
                "screw1": "69,43",
                "screw1_name": "front left screw",
                "screw2": "276,43",
                "screw2_name": "front right screw",
                "screw3": "276,217",
                "screw3_name": "rear right screw",
                "screw4": "69,217",
                "screw4_name": "rear left screw",
                "horizontal_move_z": "10.",
                "speed": "50.",
                "screw_thread": "CW-M4"
            },
            "mcu pico": {
                "serial": "/dev/serial/by-id/usb-Klipper_rp2040_E6605838836F9A30-if00"
            },
            "multi_pin heater_pin": {
                "pins": "pico:gpio9,pico:gpio26"
            },
            "multi_pin fan_pin": {
                "pins": "pico:gpio5,pico:gpio27"
            },
            "heater_generic my_heater": {
                "sensor_type": "BME280",
                "gcode_id": "ENC",
                "i2c_mcu": "pico",
                "i2c_speed": "400000",
                "heater_pin": "multi_pin:heater_pin",
                "max_power": "1",
                "control": "watermark",
                "min_temp": "0",
                "max_temp": "55"
            },
            "verify_heater my_heater": {
                "check_gain_time": "120"
            },
            "heater_fan my_heater_fan": {
                "pin": "multi_pin:fan_pin",
                "max_power": "1",
                "heater": "my_heater",
                "heater_temp": "30.0",
                "fan_speed": "1.0"
            },
            "bed_mesh default": {
                "version": "1",
                "points": "\n-0.007500, 0.007500, 0.045000\n-0.007500, 0.017500, 0.020000\n-0.007500, 0.007500, 0.007500",
                "x_count": "3",
                "y_count": "3",
                "mesh_x_pps": "0",
                "mesh_y_pps": "0",
                "algo": "direct",
                "tension": "0.2",
                "min_x": "110.0",
                "max_x": "170.0",
                "min_y": "104.5",
                "max_y": "135.5"
            }
        },
        "settings": {
            "mcu": {
                "serial": "/dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A10K2RB1-if00-port0",
                "baud": 250000,
                "restart_method": "arduino",
                "max_stepper_error": 0.000025
            },
            "mcu pico": {
                "serial": "/dev/serial/by-id/usb-Klipper_rp2040_E6605838836F9A30-if00",
                "baud": 250000,
                "max_stepper_error": 0.000025
            },
            "virtual_sdcard": {
                "path": "/home/bush/sv01_data/gcodes",
                "on_error_gcode": ""
            },
            "pause_resume": {
                "recover_velocity": 50.0
            },
            "heater_bed": {
                "sensor_type": "EPCOS 100K B57560G104F",
                "pullup_resistor": 4700.0,
                "inline_resistor": 0.0,
                "sensor_pin": "PK6",
                "min_temp": 0.0,
                "max_temp": 110.0,
                "min_extrude_temp": 170.0,
                "max_power": 1.0,
                "smooth_time": 1.0,
                "control": "pid",
                "pid_kp": 72.63,
                "pid_ki": 1.664,
                "pid_kd": 792.579,
                "heater_pin": "PH5",
                "pwm_cycle_time": 0.1
            },
            "verify_heater heater_bed": {
                "hysteresis": 5.0,
                "max_error": 120.0,
                "heating_gain": 2.0,
                "check_gain_time": 60.0
            },
            "fan": {
                "max_power": 1.0,
                "kick_start_time": 0.1,
                "off_below": 0.0,
                "cycle_time": 0.01,
                "hardware_pwm": false,
                "shutdown_speed": 0.0,
                "pin": "PH6"
            },
            "bltouch": {
                "z_offset": 2.3,
                "stow_on_each_sample": true,
                "probe_with_touch_mode": false,
                "control_pin": "PB5",
                "sensor_pin": "^PD3",
                "pin_up_reports_not_triggered": true,
                "pin_up_touch_mode_reports_triggered": true,
                "pin_move_time": 0.68,
                "speed": 5.0,
                "lift_speed": 5.0,
                "x_offset": -34.0,
                "y_offset": -3.5,
                "samples": 3,
                "sample_retract_dist": 5.0,
                "samples_result": "median",
                "samples_tolerance": 0.01,
                "samples_tolerance_retries": 3
            },
            "gcode_macro cancel_print": {
                "gcode": "\nTURN_OFF_HEATERS\nCANCEL_PRINT_BASE",
                "rename_existing": "CANCEL_PRINT_BASE",
                "description": "Cancel the actual running print"
            },
            "gcode_macro pause": {
                "gcode": "\n\n{% set E = printer[\"gcode_macro PAUSE\"].extrude|float %}\n\n\n{% set x_park = printer.toolhead.axis_maximum.x|float - 5.0 %}\n{% set y_park = printer.toolhead.axis_maximum.y|float - 5.0 %}\n\n{% set max_z = printer.toolhead.axis_maximum.z|float %}\n{% set act_z = printer.toolhead.position.z|float %}\n{% if act_z < (max_z - 2.0) %}\n{% set z_safe = 2.0 %}\n{% else %}\n{% set z_safe = max_z - act_z %}\n{% endif %}\n\nPAUSE_BASE\nG91\n{% if printer.extruder.can_extrude|lower == 'true' %}\nG1 E-{E} F2100\n{% else %}\n{action_respond_info(\"Extruder not hot enough\")}\n{% endif %}\n{% if \"xyz\" in printer.toolhead.homed_axes %}\nG1 Z{z_safe} F900\nG90\nG1 X{x_park} Y{y_park} F6000\n{% else %}\n{action_respond_info(\"Printer not homed\")}\n{% endif %}",
                "rename_existing": "PAUSE_BASE",
                "description": "Pause the actual running print",
                "variable_extrude": "1.0"
            },
            "gcode_macro resume": {
                "gcode": "\n\n{% set E = printer[\"gcode_macro PAUSE\"].extrude|float %}\n\n{% if 'VELOCITY' in params|upper %}\n{% set get_params = ('VELOCITY=' + params.VELOCITY)  %}\n{%else %}\n{% set get_params = \"\" %}\n{% endif %}\n\n{% if printer.extruder.can_extrude|lower == 'true' %}\nG91\nG1 E{E} F2100\n{% else %}\n{action_respond_info(\"Extruder not hot enough\")}\n{% endif %}\nRESUME_BASE {get_params}",
                "rename_existing": "RESUME_BASE",
                "description": "Resume the actual running print"
            },
            "gcode_macro m600": {
                "gcode": "\n{% set X = params.X|default(50)|float %}\n{% set Y = params.Y|default(0)|float %}\n{% set Z = params.Z|default(10)|float %}\nSAVE_GCODE_STATE NAME=M600_state\nPAUSE\nG91\nG1 E-.8 F2700\nG1 Z{Z}\nG90\nG1 X{X} Y{Y} F3000\nG91\nG1 E-50 F1000\nRESTORE_GCODE_STATE NAME=M600_state",
                "description": "G-Code macro"
            },
            "gcode_macro start_print": {
                "gcode": "\n{% set BED_TEMP = params.BED_TEMP|default(60)|float %}\n{% set EXTRUDER_TEMP = params.EXTRUDER_TEMP|default(190)|float %}\n\nM190 S{BED_TEMP}\n\nG90\n\nG28\n\nBED_MESH_CALIBRATE\n\nSmart_Park\n\nM109 S{EXTRUDER_TEMP}\n\nLINE_PURGE",
                "description": "G-Code macro"
            },
            "gcode_macro end_print": {
                "gcode": "\nTURN_OFF_HEATERS\n\nG91\n\nG1 E-18 F800\n\nG1 Z10 F3000\n\nM106 S0\n\nG90\n\nG28 X\n\nM84",
                "description": "G-Code macro"
            },
            "gcode_macro power_off_printer": {
                "gcode": "\n{action_call_remote_method(\n\"set_device_power\", device=\"sv01\", state=\"off\"\n)}",
                "description": "G-Code macro"
            },
            "gcode_macro bed_mesh_calibrate": {
                "gcode": "\n\n{% set all_points = printer.exclude_object.objects | map(attribute='polygon') | sum(start=[]) %}\n{% set bed_mesh_min = printer.configfile.settings.bed_mesh.mesh_min %}\n{% set bed_mesh_max = printer.configfile.settings.bed_mesh.mesh_max %}\n{% set probe_count = printer.configfile.settings.bed_mesh.probe_count %}\n{% set verbose_enable = printer[\"gcode_macro _KAMP_Settings\"].verbose_enable | abs %}\n{% set probe_dock_enable = printer[\"gcode_macro _KAMP_Settings\"].probe_dock_enable | abs %}\n{% set attach_macro = printer[\"gcode_macro _KAMP_Settings\"].attach_macro | string %}\n{% set detach_macro = printer[\"gcode_macro _KAMP_Settings\"].detach_macro | string %}\n{% set mesh_margin = printer[\"gcode_macro _KAMP_Settings\"].mesh_margin | float %}\n{% set fuzz_amount = printer[\"gcode_macro _KAMP_Settings\"].fuzz_amount | float %}\n{% set probe_count = probe_count if probe_count|length > 1 else probe_count * 2  %}\n{% set max_probe_point_distance_x = ( bed_mesh_max[0] - bed_mesh_min[0] ) / (probe_count[0] - 1)  %}\n{% set max_probe_point_distance_y = ( bed_mesh_max[1] - bed_mesh_min[1] ) / (probe_count[1] - 1)  %}\n{% set x_min = all_points | map(attribute=0) | min | default(bed_mesh_min[0]) %}\n{% set y_min = all_points | map(attribute=1) | min | default(bed_mesh_min[1]) %}\n{% set x_max = all_points | map(attribute=0) | max | default(bed_mesh_max[0]) %}\n{% set y_max = all_points | map(attribute=1) | max | default(bed_mesh_max[1]) %}\n\n{% set fuzz_range = range((0) | int, (fuzz_amount * 100) | int + 1) %}\n{% set adapted_x_min = (bed_mesh_min[0] + fuzz_amount - mesh_margin, x_min) | max - (fuzz_range | random / 100.0) %}\n{% set adapted_y_min = (bed_mesh_min[1] + fuzz_amount - mesh_margin, y_min) | max - (fuzz_range | random / 100.0) %}\n{% set adapted_x_max = (bed_mesh_max[0] - fuzz_amount + mesh_margin, x_max) | min + (fuzz_range | random / 100.0) %}\n{% set adapted_y_max = (bed_mesh_max[1] - fuzz_amount + mesh_margin, y_max) | min + (fuzz_range | random / 100.0) %}\n\n{% set adapted_x_min = [adapted_x_min , bed_mesh_min[0]] | max %}\n{% set adapted_y_min = [adapted_y_min , bed_mesh_min[1]] | max %}\n{% set adapted_x_max = [adapted_x_max , bed_mesh_max[0]] | min %}\n{% set adapted_y_max = [adapted_y_max , bed_mesh_max[1]] | min %}\n\n{% set points_x = (((adapted_x_max - adapted_x_min) / max_probe_point_distance_x) | round(method='ceil') | int) + 1 %}\n{% set points_y = (((adapted_y_max - adapted_y_min) / max_probe_point_distance_y) | round(method='ceil') | int) + 1 %}\n\n{% if (([points_x, points_y]|max) > 6) %}\n{% set algorithm = \"bicubic\" %}\n{% set min_points = 4 %}\n{% else %}\n{% set algorithm = \"lagrange\" %}\n{% set min_points = 3 %}\n{% endif %}\n\n{% set points_x = [points_x , min_points]|max %}\n{% set points_y = [points_y , min_points]|max %}\n{% set points_x = [points_x , probe_count[0]]|min %}\n{% set points_y = [points_y , probe_count[1]]|min %}\n\n{% if verbose_enable == True %}\n\n{ action_respond_info( \"Algorithm: {}.\".format(\n(algorithm),\n)) }\n\n{ action_respond_info(\"Default probe count: {},{}.\".format(\n(probe_count[0]),\n(probe_count[1]),\n)) }\n\n{ action_respond_info(\"Adapted probe count: {},{}.\".format(\n(points_x),\n(points_y),\n)) }\n\n{action_respond_info(\"Default mesh bounds: {}, {}.\".format(\n(bed_mesh_min[0],bed_mesh_min[1]),\n(bed_mesh_max[0],bed_mesh_max[1]),\n)) }\n\n{% if mesh_margin > 0 %}\n{action_respond_info(\"Mesh margin is {}, mesh bounds extended by {}mm.\".format(\n(mesh_margin),\n(mesh_margin),\n)) }\n{% else %}\n{action_respond_info(\"Mesh margin is 0, margin not increased.\")}\n{% endif %}\n\n{% if fuzz_amount > 0 %}\n{action_respond_info(\"Mesh point fuzzing enabled, points fuzzed up to {}mm.\".format(\n(fuzz_amount),\n)) }\n{% else %}\n{action_respond_info(\"Fuzz amount is 0, mesh points not fuzzed.\")}\n{% endif %}\n\n{ action_respond_info(\"Adapted mesh bounds: {}, {}.\".format(\n(adapted_x_min, adapted_y_min),\n(adapted_x_max, adapted_y_max),\n)) }\n\n{action_respond_info(\"KAMP adjustments successful. Happy KAMPing!\")}\n\n{% endif %}\n\n{% if probe_dock_enable == True %}\n{attach_macro}\n{% endif %}\n\n_BED_MESH_CALIBRATE mesh_min={adapted_x_min},{adapted_y_min} mesh_max={adapted_x_max},{adapted_y_max} ALGORITHM={algorithm} PROBE_COUNT={points_x},{points_y}\n\n{% if probe_dock_enable == True %}\n{detach_macro}\n{% endif %}",
                "rename_existing": "_BED_MESH_CALIBRATE",
                "description": "G-Code macro"
            },
            "gcode_macro line_purge": {
                "gcode": "\n\n{% set travel_speed = (printer.toolhead.max_velocity) * 60 | float %}\n{% set cross_section = printer.configfile.settings.extruder.max_extrude_cross_section | float %}\n\n\n{% if printer.firmware_retraction is defined %}\n{% set RETRACT = G10 | string %}\n{% set UNRETRACT = G11 | string %}\n{% else %}\n{% set RETRACT = 'G1 E-.5 F2100' | string %}\n{% set UNRETRACT = 'G1 E.5 F2100' | string %}\n{% endif %}\n\n\n{% set verbose_enable = printer[\"gcode_macro _KAMP_Settings\"].verbose_enable | abs %}\n{% set purge_height = printer[\"gcode_macro _KAMP_Settings\"].purge_height | float %}\n{% set tip_distance = printer[\"gcode_macro _KAMP_Settings\"].tip_distance | float %}\n{% set purge_margin = printer[\"gcode_macro _KAMP_Settings\"].purge_margin | float %}\n{% set purge_amount = printer[\"gcode_macro _KAMP_Settings\"].purge_amount | float %}\n{% set flow_rate = printer[\"gcode_macro _KAMP_Settings\"].flow_rate | float %}\n\n\n\n{% set all_points = printer.exclude_object.objects | map(attribute='polygon') | sum(start=[]) %}\n{% set purge_x_min = (all_points | map(attribute=0) | min | default(0)) %}\n{% set purge_x_max = (all_points | map(attribute=0) | max | default(0)) %}\n{% set purge_y_min = (all_points | map(attribute=1) | min | default(0)) %}\n{% set purge_y_max = (all_points | map(attribute=1) | max | default(0)) %}\n\n{% set purge_x_center = ([((purge_x_max + purge_x_min) / 2) - (purge_amount / 2), 0] | max) %}\n{% set purge_y_center = ([((purge_y_max + purge_y_min) / 2) - (purge_amount / 2), 0] | max) %}\n\n{% set purge_x_origin = ([purge_x_min - purge_margin, 0] | max) %}\n{% set purge_y_origin = ([purge_y_min - purge_margin, 0] | max) %}\n\n\n{% set purge_move_speed = (flow_rate / 5.0) * 60 | float %}\n\n{% if cross_section < 5 %}\n\n{action_respond_info(\"[Extruder] max_extrude_cross_section is insufficient for purge, please set it to 5 or greater. Purge skipped.\")}\n\n{% else %}\n\n{% if verbose_enable == True %}\n\n{action_respond_info(\"Moving filament tip {}mms\".format(\n(tip_distance),\n)) }\n{% endif %}\n\n{% if printer.firmware_retraction is defined %}\n{action_respond_info(\"KAMP purge is using firmware retraction.\")}\n{% else %}\n{action_respond_info(\"KAMP purge is not using firmware retraction, it is recommended to configure it.\")}\n{% endif %}\n\n{% if purge_y_origin > 0 %}\n\n{action_respond_info(\"KAMP purge starting at {}, {} and purging {}mm of filament, requested flow rate is {}mm/s3.\".format(\n(purge_x_center),\n(purge_y_origin),\n(purge_amount),\n(flow_rate),\n)) }\n\n{% else %}\n\n{action_respond_info(\"KAMP purge starting at {}, {} and purging {}mm of filament, requested flow rate is {}mm/s3.\".format(\n(purge_x_origin),\n(purge_y_center),\n(purge_amount),\n(flow_rate),\n)) }\n\n{% endif %}\n\nSAVE_GCODE_STATE NAME=Prepurge_State\n\n{% if purge_y_origin > 0 %}\n\nG92 E0\nG0 F{travel_speed}\nG90\nG0 X{purge_x_center} Y{purge_y_origin}\nG0 Z{purge_height}\nM83\nG1 E{tip_distance} F{purge_move_speed}\nG1 X{purge_x_center + purge_amount} E{purge_amount} F{purge_move_speed}\n{RETRACT}\nG0 X{purge_x_center + purge_amount + 10} F{travel_speed}\nG92 E0\nM82\nG0 Z{purge_height * 2} F{travel_speed}\n\n{% else %}\n\nG92 E0\nG0 F{travel_speed}\nG90\nG0 X{purge_x_origin} Y{purge_y_center}\nG0 Z{purge_height}\nM83\nG1 E{tip_distance} F{purge_move_speed}\nG1 Y{purge_y_center + purge_amount} E{purge_amount} F{purge_move_speed}\n{RETRACT}\nG0 Y{purge_y_center + purge_amount + 10} F{travel_speed}\nG92 E0\nM82\nG0 Z{purge_height * 2} F{travel_speed}\n\n{% endif %}\n\nRESTORE_GCODE_STATE NAME=Prepurge_State\n\n{% endif %}",
                "description": "A purge macro that adapts to be near your actual printed objects"
            },
            "gcode_macro smart_park": {
                "gcode": "\n\n{% set kamp_settings = printer[\"gcode_macro _KAMP_Settings\"] %}\n{% set z_height = kamp_settings.smart_park_height | float %}\n{% set purge_margin = kamp_settings.purge_margin | float %}\n{% set verbose_enable = kamp_settings.verbose_enable | abs %}\n{% set center_x = printer.toolhead.axis_maximum.x / 2 | float %}\n{% set center_y = printer.toolhead.axis_maximum.y / 2 | float %}\n{% set all_points = printer.exclude_object.objects | map(attribute='polygon') | sum(start=[]) %}\n{% set x_min = all_points | map(attribute=0) | min | default(center_x) %}\n{% set y_min = all_points | map(attribute=1) | min | default(center_y) %}\n{% set travel_speed = (printer.toolhead.max_velocity) * 60 | float %}\n\n{% if purge_margin > 0 and x_min != center_x and y_min != center_y %}\n{% set x_min = [ x_min - purge_margin , x_min ] | max %}\n{% set y_min = [ y_min - purge_margin , y_min ] | max %}\n{% endif %}\n\n\n{% if verbose_enable == True %}\n\n{ action_respond_info(\"Smart Park location: {},{}.\".format(\n(x_min),\n(y_min),\n)) }\n\n{% endif %}\n\nG0 X{x_min} Y{y_min} F{travel_speed}\nG0 Z{z_height}",
                "description": "Parks your printhead near the print area for pre-print hotend heating."
            },
            "gcode_macro _kamp_settings": {
                "gcode": "\n\n{action_respond_info(\" Running the KAMP_Settings macro does nothing, it is only used for storing KAMP settings. \")}",
                "description": "This macro contains all adjustable settings for KAMP",
                "variable_verbose_enable": "True",
                "variable_mesh_margin": "0",
                "variable_fuzz_amount": "0",
                "variable_probe_dock_enable": "False",
                "variable_attach_macro": "'Attach_Probe'",
                "variable_detach_macro": "'Dock_Probe'",
                "variable_purge_height": "0.8",
                "variable_tip_distance": "15",
                "variable_purge_margin": "40",
                "variable_purge_amount": "40",
                "variable_flow_rate": "8",
                "variable_smart_park_height": ".42"
            },
            "display": {
                "lcd_type": "st7920",
                "cs_pin": "PH1",
                "sclk_pin": "PA1",
                "sid_pin": "PH0",
                "menu_root": "__main",
                "menu_timeout": 0,
                "menu_reverse_navigation": false,
                "encoder_pins": "^PC4, ^PC6",
                "encoder_steps_per_detent": 4,
                "encoder_fast_rate": 0.03,
                "click_pin": "^!PC2",
                "display_group": "_default_16x4"
            },
            "menu __main __octoprint": {
                "type": "disabled",
                "name": "",
                "enable": true
            },
            "menu __main __sdcard": {
                "type": "disabled",
                "name": "",
                "enable": true
            },
            "menu __main __macros": {
                "type": "list",
                "name": "Macros",
                "enable": true
            },
            "menu __main __macros __resume": {
                "type": "command",
                "name": "Resume printing",
                "enable": "{printer.print_stats.state == \"paused\"}",
                "gcode": "\nRESUME"
            },
            "menu __main __macros __pause": {
                "type": "command",
                "name": "Pause printing",
                "enable": "{printer.print_stats.state == \"printing\"}",
                "gcode": "\nPAUSE"
            },
            "menu __main __macros __cancel": {
                "type": "command",
                "name": "Cancel printing",
                "enable": "{(printer.print_stats.state == \"printing\" or printer.print_stats.state == \"paused\")}",
                "gcode": "\nCANCEL_PRINT"
            },
            "menu __main __setup": {
                "type": "disabled",
                "name": "",
                "enable": true
            },
            "gcode_arcs": {
                "resolution": 0.1
            },
            "bed_mesh": {
                "probe_count": [
                    7,
                    7
                ],
                "mesh_min": [
                    38.0,
                    35.0
                ],
                "mesh_max": [
                    242.0,
                    214.0
                ],
                "mesh_pps": [
                    2,
                    2
                ],
                "algorithm": "bicubic",
                "bicubic_tension": 0.2,
                "horizontal_move_z": 5.0,
                "speed": 150.0,
                "fade_start": 1.0,
                "fade_end": 0.0,
                "split_delta_z": 0.025,
                "move_check_distance": 5.0
            },
            "bed_mesh default": {
                "version": 1,
                "points": [
                    [
                        -0.0075,
                        0.0075,
                        0.045
                    ],
                    [
                        -0.0075,
                        0.0175,
                        0.02
                    ],
                    [
                        -0.0075,
                        0.0075,
                        0.0075
                    ]
                ],
                "min_x": 110.0,
                "max_x": 170.0,
                "min_y": 104.5,
                "max_y": 135.5,
                "x_count": 3,
                "y_count": 3,
                "mesh_x_pps": 0,
                "mesh_y_pps": 0,
                "algo": "direct",
                "tension": 0.2
            },
            "safe_z_home": {
                "home_xy_position": [
                    150.0,
                    127.0
                ],
                "z_hop": 10.0,
                "z_hop_speed": 10.0,
                "speed": 100.0,
                "move_to_previous": false
            },
            "delayed_gcode delayed_printer_off": {
                "gcode": "\n{% if printer.idle_timeout.state == \"Idle\" %}\nPOWER_OFF_PRINTER\n{% endif %}",
                "initial_duration": 0.0
            },
            "idle_timeout": {
                "timeout": 600.0,
                "gcode": "\nUPDATE_DELAYED_GCODE ID=delayed_printer_off DURATION=60"
            },
            "bed_screws": {
                "screw1": [
                    38.0,
                    35.0
                ],
                "screw1_name": "screw at 38.000,35.000",
                "screw2": [
                    242.0,
                    35.0
                ],
                "screw2_name": "screw at 242.000,35.000",
                "screw3": [
                    242.0,
                    214.0
                ],
                "screw3_name": "screw at 242.000,214.000",
                "screw4": [
                    38.0,
                    214.0
                ],
                "screw4_name": "screw at 38.000,214.000",
                "speed": 50.0,
                "probe_speed": 5.0,
                "horizontal_move_z": 5.0,
                "probe_height": 0.0
            },
            "screws_tilt_adjust": {
                "screw1": [
                    69.0,
                    43.0
                ],
                "screw1_name": "front left screw",
                "screw2": [
                    276.0,
                    43.0
                ],
                "screw2_name": "front right screw",
                "screw3": [
                    276.0,
                    217.0
                ],
                "screw3_name": "rear right screw",
                "screw4": [
                    69.0,
                    217.0
                ],
                "screw4_name": "rear left screw",
                "screw_thread": "CW-M4",
                "horizontal_move_z": 10.0,
                "speed": 50.0
            },
            "multi_pin heater_pin": {
                "pins": [
                    "pico:gpio9",
                    "pico:gpio26"
                ]
            },
            "multi_pin fan_pin": {
                "pins": [
                    "pico:gpio5",
                    "pico:gpio27"
                ]
            },
            "heater_generic my_heater": {
                "sensor_type": "BME280",
                "i2c_mcu": "pico",
                "i2c_speed": 400000,
                "i2c_address": 118,
                "bme280_iir_filter": 1,
                "bme280_oversample_temp": 2,
                "bme280_oversample_hum": 2,
                "bme280_oversample_pressure": 2,
                "bme280_gas_target_temp": 320,
                "bme280_gas_heat_duration": 150,
                "min_temp": 0.0,
                "max_temp": 55.0,
                "min_extrude_temp": 170.0,
                "max_power": 1.0,
                "smooth_time": 1.0,
                "control": "watermark",
                "max_delta": 2.0,
                "heater_pin": "multi_pin:heater_pin",
                "pwm_cycle_time": 0.1,
                "gcode_id": "ENC"
            },
            "verify_heater my_heater": {
                "hysteresis": 5.0,
                "max_error": 120.0,
                "heating_gain": 2.0,
                "check_gain_time": 120.0
            },
            "heater_fan my_heater_fan": {
                "heater": [
                    "my_heater"
                ],
                "heater_temp": 30.0,
                "max_power": 1.0,
                "kick_start_time": 0.1,
                "off_below": 0.0,
                "cycle_time": 0.01,
                "hardware_pwm": false,
                "shutdown_speed": 1.0,
                "pin": "multi_pin:fan_pin",
                "fan_speed": 1.0
            },
            "printer": {
                "max_velocity": 300.0,
                "max_accel": 3000.0,
                "max_accel_to_decel": 1500.0,
                "square_corner_velocity": 5.0,
                "buffer_time_low": 1.0,
                "buffer_time_high": 2.0,
                "buffer_time_start": 0.25,
                "move_flush_time": 0.05,
                "kinematics": "cartesian",
                "max_z_velocity": 5.0,
                "max_z_accel": 100.0
            },
            "stepper_x": {
                "step_pin": "PF0",
                "dir_pin": "PF1",
                "rotation_distance": 40.0,
                "microsteps": 16,
                "full_steps_per_rotation": 200,
                "gear_ratio": [],
                "enable_pin": "!PD7",
                "endstop_pin": "^PE5",
                "position_endstop": 0.0,
                "position_min": 0.0,
                "position_max": 300.0,
                "homing_speed": 50.0,
                "second_homing_speed": 25.0,
                "homing_retract_speed": 50.0,
                "homing_retract_dist": 5.0,
                "homing_positive_dir": false
            },
            "force_move": {
                "enable_force_move": false
            },
            "stepper_y": {
                "step_pin": "PF6",
                "dir_pin": "PF7",
                "rotation_distance": 40.0,
                "microsteps": 16,
                "full_steps_per_rotation": 200,
                "gear_ratio": [],
                "enable_pin": "!PF2",
                "endstop_pin": "^PJ1",
                "position_endstop": 0.0,
                "position_min": 0.0,
                "position_max": 255.0,
                "homing_speed": 50.0,
                "second_homing_speed": 25.0,
                "homing_retract_speed": 50.0,
                "homing_retract_dist": 5.0,
                "homing_positive_dir": false
            },
            "stepper_z": {
                "step_pin": "PL3",
                "dir_pin": "!PL1",
                "rotation_distance": 8.0,
                "microsteps": 16,
                "full_steps_per_rotation": 200,
                "gear_ratio": [],
                "enable_pin": "!PK0",
                "endstop_pin": "probe:z_virtual_endstop",
                "position_min": 0.0,
                "position_max": 300.0,
                "homing_speed": 5.0,
                "second_homing_speed": 2.5,
                "homing_retract_speed": 5.0,
                "homing_retract_dist": 5.0,
                "homing_positive_dir": false
            },
            "extruder": {
                "sensor_type": "EPCOS 100K B57560G104F",
                "pullup_resistor": 4700.0,
                "inline_resistor": 0.0,
                "sensor_pin": "PK5",
                "min_temp": 0.0,
                "max_temp": 265.0,
                "min_extrude_temp": 170.0,
                "max_power": 1.0,
                "smooth_time": 1.0,
                "control": "pid",
                "pid_kp": 30.17,
                "pid_ki": 3.409,
                "pid_kd": 66.751,
                "heater_pin": "PB4",
                "pwm_cycle_time": 0.1,
                "nozzle_diameter": 0.4,
                "filament_diameter": 1.75,
                "max_extrude_cross_section": 5.0,
                "max_extrude_only_velocity": 79.82432411074329,
                "max_extrude_only_accel": 798.2432411074329,
                "max_extrude_only_distance": 100.0,
                "instantaneous_corner_velocity": 1.0,
                "step_pin": "PA4",
                "pressure_advance": 0.0,
                "pressure_advance_smooth_time": 0.04,
                "dir_pin": "!PA6",
                "rotation_distance": 7.68,
                "microsteps": 16,
                "full_steps_per_rotation": 200,
                "gear_ratio": [],
                "enable_pin": "!PA2"
            },
            "verify_heater extruder": {
                "hysteresis": 5.0,
                "max_error": 120.0,
                "heating_gain": 2.0,
                "check_gain_time": 20.0
            }
        },
        "warnings": [],
        "save_config_pending": false,
        "save_config_pending_items": {}
    },
    "gcode_move": {
        "speed_factor": 1.0,
        "speed": 1500.0,
        "extrude_factor": 1.0,
        "absolute_coordinates": true,
        "absolute_extrude": true,
        "homing_origin": [
            0.0,
            0.0,
            0.0,
            0.0
        ],
        "position": [
            0.0,
            0.0,
            0.0,
            0.0
        ],
        "gcode_position": [
            0.0,
            0.0,
            0.0,
            0.0
        ]
    },
    "print_stats": {
        "filename": "",
        "total_duration": 0.0,
        "print_duration": 0.0,
        "filament_used": 0.0,
        "state": "standby",
        "message": "",
        "info": {
            "total_layer": null,
            "current_layer": null
        }
    },
    "virtual_sdcard": {
        "file_path": null,
        "progress": 0.0,
        "is_active": false,
        "file_position": 0,
        "file_size": 0
    },
    "display_status": {
        "progress": 0.0,
        "message": null
    },
    "heater_bed": {
        "temperature": 22.36,
        "target": 0.0,
        "power": 0.0
    },
    "fan": {
        "speed": 0.0,
        "rpm": null
    },
    "exclude_object": {
        "objects": [],
        "excluded_objects": [],
        "current_object": null
    },
    "bed_screws": {
        "is_active": false,
        "state": null,
        "current_screw": 0,
        "accepted_screws": 0
    },
    "heater_generic my_heater": {
        "temperature": 22.19,
        "target": 0.0,
        "power": 0.0
    },
    "heater_fan my_heater_fan": {
        "speed": 0.0,
        "rpm": null
    },
    "motion_report": {
        "live_position": [
            0.0,
            0.0,
            0.0,
            0.0
        ],
        "live_velocity": 0.0,
        "live_extruder_velocity": 0.0,
        "steppers": [
            "extruder",
            "stepper_x",
            "stepper_y",
            "stepper_z"
        ],
        "trapq": [
            "extruder",
            "toolhead"
        ]
    },
    "manual_probe": {
        "is_active": false,
        "z_position": null,
        "z_position_lower": null,
        "z_position_upper": null
    },
    "toolhead": {
        "homed_axes": "",
        "axis_minimum": [
            0.0,
            0.0,
            0.0,
            0.0
        ],
        "axis_maximum": [
            300.0,
            255.0,
            300.0,
            0.0
        ],
        "print_time": 0.001,
        "stalls": 0,
        "estimated_print_time": 62717.8476845,
        "extruder": "extruder",
        "position": [
            0.0,
            0.0,
            0.0,
            0.0
        ],
        "max_velocity": 300.0,
        "max_accel": 3000.0,
        "max_accel_to_decel": 1500.0,
        "square_corner_velocity": 5.0
    },
    "extruder": {
        "temperature": 22.36,
        "target": 0.0,
        "power": 0.0,
        "can_extrude": false,
        "pressure_advance": 0.0,
        "smooth_time": 0.04,
        "motion_queue": null
    }
}

Originally posted by @busheezy in https://github.com/Clon1998/mobileraker/issues/205#issuecomment-1699846159

Clon1998 commented 1 year ago

@busheezy thanks for bringing that up. Seems like I missed to correctly test that after refactoring it.

I will have a look and fix it as soon as I can.

busheezy commented 1 year ago

Sorry, I wasn't sure if I should make a new issue or not. Let me know if I can help in any way.

Clon1998 commented 1 year ago

No worries at all, I can always just create a new issue based of an comment, just like it did.

However, I am unable to reproduce that issue and parsing of the JSON works just fine.

Could you send me the latest log file of the app (App Settings -> Scroll to The Btoom -> Debug logs)

busheezy commented 1 year ago
💡 Completed FirebaseRemote init
💡 Machine in box is SV01 (49eab63f-8e94-4e41-ad2c-b23212c2b38f)#844025974
💡 Machine in box is Ender 5 (ded88165-3557-4da0-88e5-8e2e9d82f892)#61376534
💡 Completed Hive init
💡 Completed PaymentService init
💡 Selecting machine SV01
💡 Received fetchAll
💡 Got customerInfo: CustomerInfo(entitlements: EntitlementInfos(all: {Supporter: EntitlementInfo(identifier: Supporter, isActive: true, willRenew: true, latestPurchaseDate: 2023-08-13T03:50:45.000Z, originalPurchaseDate: 2023-08-13T03:50:45.000Z, productIdentifier: mobileraker_supporter_v2, isSandbox: false, ownershipType: OwnershipType.unknown, store: Store.playStore, periodType: PeriodType.normal, expirationDate: 2023-09-13T03:43:57.000Z, unsubscribeDetectedAt: null, billingIssueDetectedAt: null), supporter_subscription: EntitlementInfo(identifier: supporter_subscription, isActive: true, willRenew: true, latestPurchaseDate: 2023-08-13T03:50:45.000Z, originalPurchaseDate: 2023-08-13T03:50:45.000Z, productIdentifier: mobileraker_supporter_v2, isSandbox: false, ownershipType: OwnershipType.unknown, store: Store.playStore, periodType: PeriodType.normal, expirationDate: 2023-09-13T03:43:57.000Z, unsubscribeDetectedAt: null, billingIssueDetectedAt: null)}, active: {Supporter: EntitlementInfo(identifier: Supporter, isActive: true, willRenew: true, latestPurchaseDate: 2023-08-13T03:50:45.000Z, originalPurchaseDate: 2023-08-13T03:50:45.000Z, productIdentifier: mobileraker_supporter_v2, isSandbox: false, ownershipType: OwnershipType.unknown, store: Store.playStore, periodType: PeriodType.normal, expirationDate: 2023-09-13T03:43:57.000Z, unsubscribeDetectedAt: null, billingIssueDetectedAt: null), supporter_subscription: EntitlementInfo(identifier: supporter_subscription, isActive: true, willRenew: true, latestPurchaseDate: 2023-08-13T03:50:45.000Z, originalPurchaseDate: 2023-08-13T03:50:45.000Z, productIdentifier: mobileraker_supporter_v2, isSandbox: false, ownershipType: OwnershipType.unknown, store: Store.playStore, periodType: PeriodType.normal, expirationDate: 2023-09-13T03:43:57.000Z, unsubscribeDetectedAt: null, billingIssueDetectedAt: null)}), allPurchaseDates: {mobileraker_supporter_v2:199-1m: 2023-08-13T03:50:45.000Z}, activeSubscriptions: [mobileraker_supporter_v2:199-1m], allPurchasedProductIdentifiers: [mobileraker_supporter_v2:199-1m], nonSubscriptionTransactions: [], firstSeen: 2023-06-04T01:22:03.000Z, originalAppUserId: $RCAnonymousID:e35cfa24e231464cbd0a237f93ba0c65, allExpirationDates: {mobileraker_supporter_v2:199-1m: 2023-09-13T03:43:57.000Z}, requestDate: 2023-08-31T12:11:46.337Z, latestExpirationDate: 2023-09-13T03:43:57.000Z, originalPurchaseDate: null, originalApplicationVersion: null, managementURL: https://play.google.com/store/account/subscriptions)
💡 RCat ID: $RCAnonymousID:e35cfa24e231464cbd0a237f93ba0c65
💡 Received isSupporter true
💡 Max allowed machines for non Supporters is -1
💡 Completed initialRoute init
💡 Started initializeAvailableMachines
💡 Received all machines
💡 machineProvider creation STARTED 49eab63f-8e94-4e41-ad2c-b23212c2b38f
💡 machineProvider creation STARTED ded88165-3557-4da0-88e5-8e2e9d82f892
💡 machineProvider creation DONE 49eab63f-8e94-4e41-ad2c-b23212c2b38f
💡 machineProvider creation DONE ded88165-3557-4da0-88e5-8e2e9d82f892
💡 initialized all machineProviders
💡 Completed initializeAvailableMachines
💡 Notifications are permitted: true
PlatformException(INVALID_ARGUMENTS, Firebase service is not available (check if you have google-services.json file), arguments.invalid.fcm.assertFirebaseServiceEnabled, null)
#0   StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:652)
#1   MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:310)
#2   <asynchronous suspension>
#3   AwesomeNotificationsFcm.requestFirebaseAppToken (package:awesome_notifications_fcm/src/awesome_notifications_fcm_core.dart:127)
#4   <asynchronous suspension>
#5   FutureHandlerProviderElementMixin.handleFuture.<anonymous closure>.<anonymous closure> (package:riverpod/src/async_notifier/base.dart:337)
#6   <asynchronous suspension>
⛔ Error while trying to register supporter status/fcm token in firebase:
💡 Setup notification channels
💡 Setup ReceiverPort!
💡 Completed NotificationService init
💡 Theme selected: 4, available theme len: 5
💡 SV01(ws://192.168.1.225:7126/websocket)  Device's FCM token: f4C6-RFxRmyHfKDRsPQfih:APA91bGIWjEff8i0zHLBrRsg1V6idj7TQJX-M9rD-ytFWXcaXzrQpa33W1nm1WLI8pFC5ODe-P9vQIR1XsifKz-LVThvtlZcnxN-4DR21b-0vpKq0LunJeQTgIFi-pIcujra-vYS4px2
💡 No OE config was found! Will only rely on local client. ref:766235877
💡 JsonRpcClient (ws://192.168.1.225:7126/websocket , ClientType.local) CREATED!!
💡 [523093308]Trying to connect to ws://192.168.1.225:7126/websocket
💡 [523093308-ws://192.168.1.225:7126/websocket] ClientState.disconnected ➝ ClientState.connecting
💡 Using headers {}
💡 Ender 5(ws://192.168.1.225:7125/websocket)  Device's FCM token: f4C6-RFxRmyHfKDRsPQfih:APA91bGIWjEff8i0zHLBrRsg1V6idj7TQJX-M9rD-ytFWXcaXzrQpa33W1nm1WLI8pFC5ODe-P9vQIR1XsifKz-LVThvtlZcnxN-4DR21b-0vpKq0LunJeQTgIFi-pIcujra-vYS4px2
💡 No OE config was found! Will only rely on local client. ref:989472977
💡 JsonRpcClient (ws://192.168.1.225:7125/websocket , ClientType.local) CREATED!!
💡 [46904453]Trying to connect to ws://192.168.1.225:7125/websocket
💡 [46904453-ws://192.168.1.225:7125/websocket] ClientState.disconnected ➝ ClientState.connecting
💡 Using headers {}
💡 Token from FCM f4C6-RFxRmyHfKDRsPQfih:APA91bGIWjEff8i0zHLBrRsg1V6idj7TQJX-M9rD-ytFWXcaXzrQpa33W1nm1WLI8pFC5ODe-P9vQIR1XsifKz-LVThvtlZcnxN-4DR21b-0vpKq0LunJeQTgIFi-pIcujra-vYS4px2
💡 [523093308-ws://192.168.1.225:7126/websocket] ClientState.connecting ➝ ClientState.connected
💡 >>>Fetching Server.Info
💡 >>>Fetching Printer.Info
💡 Printer Service received klippyState: null
💡 Printer Service received klippyState: null
💡 [46904453-ws://192.168.1.225:7125/websocket] ClientState.connecting ➝ ClientState.connected
💡 >>>Fetching Server.Info
💡 >>>Fetching Printer.Info
💡 <<<Received Server.Info
💡 <<<Received Printer.Info
💡 Partial Update STARTED KlipperInstance(klippyConnected: true, klippyState: KlipperState.ready, components: [klippy_connection, application, websockets, internal_transport, dbus_manager, database, file_manager, klippy_apis, secrets, template, shell_command, machine, data_store, proc_stats, job_state, job_queue, http_client, announcements, webcam, extensions, authorization, octoprint_compat, power, update_manager, history], warnings: [], klippyStateMessage: null)
💡 Partial Update Done KlipperInstance(klippyConnected: true, klippyState: KlipperState.ready, components: [klippy_connection, application, websockets, internal_transport, dbus_manager, database, file_manager, klippy_apis, secrets, template, shell_command, machine, data_store, proc_stats, job_state, job_queue, http_client, announcements, webcam, extensions, authorization, octoprint_compat, power, update_manager, history], warnings: [], klippyStateMessage: Printer is ready)
💡 Printer Service received klippyState: KlipperState.ready
💡 Refreshing printer for uuid: 49eab63f-8e94-4e41-ad2c-b23212c2b38f
💡 >>>Querying printers object list
💡 Jrpc Client of SV01(ws://192.168.1.225:7126/websocket) is connected, can Setup FCM on printer now!
💡 Getting fcm
⚠️ watchWhere just forces owner to invalidate! Ref:AutoDisposeAsyncNotifierProviderElement<PrinterCardController, WebcamInfo?>(provider: printerCardControllerProvider:AutoDisposeAsyncNotifierProviderImpl<PrinterCardController, WebcamInfo?>#d94ac, origin: printerCardControllerProvider:AutoDisposeAsyncNotifierProviderImpl<PrinterCardController, WebcamInfo?>#d94ac)
💡 List Webcams request...
💡 Trying to fetch all webcams from moonraker.
💡 <<<Received Server.Info
💡 Printer Service received klippyState: KlipperState.error
💡 <<<Received Printer.Info
💡 Partial Update STARTED KlipperInstance(klippyConnected: true, klippyState: KlipperState.error, components: [klippy_connection, application, websockets, internal_transport, dbus_manager, database, file_manager, klippy_apis, secrets, template, shell_command, machine, data_store, proc_stats, job_state, job_queue, http_client, announcements, webcam, extensions, authorization, octoprint_compat, history, update_manager, power], warnings: [], klippyStateMessage: null)
💡 Partial Update Done KlipperInstance(klippyConnected: true, klippyState: KlipperState.error, components: [klippy_connection, application, websockets, internal_transport, dbus_manager, database, file_manager, klippy_apis, secrets, template, shell_command, machine, data_store, proc_stats, job_state, job_queue, http_client, announcements, webcam, extensions, authorization, octoprint_compat, history, update_manager, power], warnings: [], klippyStateMessage: mcu 'mcu': Unable to connect
💡 Once the underlying issue is corrected, use the
💡 "FIRMWARE_RESTART" command to reset the firmware, reload the
💡 config, and restart the host software.
💡 Error configuring printer
💡 )
💡 Getting fcm.49eab63f-8e94-4e41-ad2c-b23212c2b38f
💡 List Webcams request...
💡 Trying to fetch all webcams from moonraker.
💡 Received 1 webcams from moonraker.
💡 Got 1 webcams
💡 <<<Received printer objects list!
💡 >>>Querying Printer Objects!
💡 Received 1 webcams from moonraker.
💡 Got 1 webcams
💡 Current FCMConfig in MoonrakerDB: DeviceFcmSettings{machineId: f4C6-RFxRmyHfKDRsPQfih:APA91bGIWjEff8i0zHLBrRsg1V6idj7TQJX-M9rD-ytFWXcaXzrQpa33W1nm1WLI8pFC5ODe-P9vQIR1XsifKz-LVThvtlZcnxN-4DR21b-0vpKq0LunJeQTgIFi-pIcujra-vYS4px2, machineName: SV01, language: en, settings: NotificationSettings{progress: 0.25, states: {standby, printing, paused, complete, error, cancelled}}}
💡 Start MJPEG - targFps: 30 - http://192.168.1.225/webcam2?action=snapshot
💡 <<<Received queried printer objects
type 'Null' is not a subtype of type 'String' in type cast
#0   _$$_ConfigHeaterGenericFromJson (package:mobileraker/data/dto/config/config_heater_generic.g.dart:14)
#1   new _$_ConfigHeaterGeneric.fromJson (package:mobileraker/data/dto/config/config_heater_generic.freezed.dart:196)
#2   _$ConfigHeaterGenericFromJson (package:mobileraker/data/dto/config/config_heater_generic.freezed.dart:18)
#3   new ConfigHeaterGeneric.fromJson (package:mobileraker/data/dto/config/config_heater_generic.dart:45)
#4   new ConfigFile.parse (package:mobileraker/data/dto/config/config_file.dart:102)
#5   PrinterService._updateConfigFile (package:mobileraker/service/moonraker/printer_service.dart:697)
#6   PrinterService._parseObjectType (package:mobileraker/service/moonraker/printer_service.dart:529)
#7   PrinterService._temperatureStore.<anonymous closure> (package:mobileraker/service/moonraker/printer_service.dart:478)
#8   _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:625)
#9   PrinterService._parseQueriedObjects (package:mobileraker/service/moonraker/printer_service.dart:614)
#10   PrinterService._printerObjectsQuery (package:mobileraker/service/moonraker/printer_service.dart:773)
#11   <asynchronous suspension>
#12   PrinterService.refreshPrinter (package:mobileraker/service/moonraker/printer_service.dart:203)
#13   <asynchronous suspension>
⛔ Error while parsing configfile object
💡 Fetching cached temperature store data
💡 Received cached temperature store for [heater_bed, heater_generic my_heater, extruder]
MobilerakerException{Missing field: configFile, parentException: null, parentStack: null}
#0   PrinterBuilder.build (package:mobileraker/data/dto/machine/printer.dart:94)
#1   PrinterService.refreshPrinter (package:mobileraker/service/moonraker/printer_service.dart:208)
#2   <asynchronous suspension>
⛔ Unexpected exception thrown during refresh 49eab63f-8e94-4e41-ad2c-b23212c2b38f...
💡 Show Dialog request for DialogType.stacktrace
💡 Stop MJPEG
💡 Start MJPEG - targFps: 30 - http://192.168.1.225/webcam2?action=snapshot
💡 Stop MJPEG
💡 [ws://192.168.1.225:7125/websocket46904453] WS-Stream closed normal! Code: 1002, Reason: null
💡 [46904453-ws://192.168.1.225:7125/websocket] ClientState.connected ➝ ClientState.disconnected
💡 [46904453]Trying to connect to ws://192.168.1.225:7125/websocket
💡 [46904453-ws://192.168.1.225:7125/websocket] ClientState.disconnected ➝ ClientState.connecting
💡 Using headers {}
💡 Printer Service received klippyState: KlipperState.disconnected
💡 [ws://192.168.1.225:7126/websocket523093308] WS-Stream closed normal! Code: 1002, Reason: null
💡 [523093308-ws://192.168.1.225:7126/websocket] ClientState.connected ➝ ClientState.disconnected
💡 [523093308]Trying to connect to ws://192.168.1.225:7126/websocket
💡 [523093308-ws://192.168.1.225:7126/websocket] ClientState.disconnected ➝ ClientState.connecting
💡 Using headers {}
💡 Printer Service received klippyState: KlipperState.disconnected
⚠️ Got channel error SocketException: HTTP connection timed out after 0:00:03.000000, host: 192.168.1.225, port: 7125
⛔ [ws://192.168.1.225:7125/websocket46904453] WS-Stream error: SocketException: HTTP connection timed out after 0:00:03.000000, host: 192.168.1.225, port: 7125
💡 [46904453-ws://192.168.1.225:7125/websocket] ClientState.connecting ➝ ClientState.error
⚠️ Got channel error SocketException: HTTP connection timed out after 0:00:03.000000, host: 192.168.1.225, port: 7126
⛔ [ws://192.168.1.225:7126/websocket523093308] WS-Stream error: SocketException: HTTP connection timed out after 0:00:03.000000, host: 192.168.1.225, port: 7126
💡 [523093308-ws://192.168.1.225:7126/websocket] ClientState.connecting ➝ ClientState.error
💡 Printer Service received klippyState: KlipperState.error
💡 Printer Service received klippyState: KlipperState.error
💡 Start MJPEG - targFps: 30 - http://192.168.1.225/webcam2?action=snapshot
💡 Stop MJPEG
💡 _AdaptiveStreamManager DISPOSED
⚠️ [SV01@ws://192.168.1.225:7126/websocket]Unable to propagate new notification settings because JRPC was not connected!
MobilerakerException{Machine not connected, parentException: null, parentStack: null}
⚠️ Error while trying to fetch CompanionMeta for machine SV01 (49eab63f-8e94-4e41-ad2c-b23212c2b38f)
⚠️ [Ender 5@ws://192.168.1.225:7125/websocket]Unable to propagate new notification settings because JRPC was not connected!
MobilerakerException{Machine not connected, parentException: null, parentStack: null}
⚠️ Error while trying to fetch CompanionMeta for machine Ender 5 (ded88165-3557-4da0-88e5-8e2e9d82f892)
💡 Show Dialog request for DialogType.logging
Clon1998 commented 1 year ago

Sorry I input your JSON into the wrong file I am using for testing <.<

The App is complaining because your heater heater_generic does not use a sensor_pin? Is that expected? As far as I understand the klipper docs the sensor_pin should always be present?

busheezy commented 1 year ago

Oh, I am probably a fun edge-case.

[mcu pico]
serial: /dev/serial/by-id/usb-Klipper_rp2040_E6605838836F9A30-if00

[multi_pin heater_pin]
pins: pico:gpio9,pico:gpio26

[multi_pin fan_pin]
pins: pico:gpio5,pico:gpio27

[heater_generic my_heater]
sensor_type: BME280
gcode_id: ENC
i2c_mcu: pico
i2c_speed: 400000
heater_pin: multi_pin:heater_pin
max_power: 1
control: watermark
min_temp: 0
max_temp: 55

[verify_heater my_heater]
check_gain_time: 120

[heater_fan my_heater_fan]
pin: multi_pin:fan_pin
max_power: 1
heater: my_heater
heater_temp: 30.0
fan_speed: 1.0
Clon1998 commented 1 year ago

Since you are using the BME280 that uses i2c you can not define a sensor_pin (lol)... I will adapt my implementation since I don't really care about most of the config entries I parse. I just used the Klipper config for reference and sometimes it simply is outdated.

busheezy commented 1 year ago

Thanks!

Clon1998 commented 1 year ago

However, I won't trigger a new patch release since going by my reporting, you are the only users affected by that issue.

Clon1998 commented 1 year ago

However, if you are on IOS I can trigger a TestFlight version that resolves the issue.

Clon1998 commented 1 year ago

Or provide an Android APK :)

busheezy commented 1 year ago

I'm an android user. An APK would be perfect. Thanks.

busheezy commented 1 year ago

I added you on Discord.