dsf-python 3.4.6.post4__tar.gz → 3.5.0.1rc2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (201) hide show
  1. {dsf-python-3.4.6.post4/src/dsf_python.egg-info → dsf-python-3.5.0.1rc2}/PKG-INFO +5 -1
  2. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/setup.py +5 -1
  3. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/code.py +1 -2
  4. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/code_channel.py +6 -0
  5. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/generic.py +22 -2
  6. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/http_endpoints.py +1 -1
  7. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/user_sessions.py +1 -17
  8. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/connections/__init__.py +2 -2
  9. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/connections/base_command_connection.py +1 -2
  10. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/connections/base_connection.py +1 -3
  11. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/connections/init_messages/client_init_messages.py +4 -4
  12. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/connections/intercept_connection.py +3 -3
  13. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/http.py +1 -1
  14. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/__init__.py +3 -3
  15. dsf-python-3.5.0.1rc2/src/dsf/object_model/boards/__init__.py +10 -0
  16. dsf-python-3.4.6.post4/src/dsf/object_model/boards/closed_loop.py → dsf-python-3.5.0.1rc2/src/dsf/object_model/boards/board_closed_loop.py +2 -2
  17. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/boards/boards.py +43 -16
  18. dsf-python-3.5.0.1rc2/src/dsf/object_model/boards/direct_display/__init__.py +8 -0
  19. dsf-python-3.5.0.1rc2/src/dsf/object_model/boards/direct_display/direct_display.py +23 -0
  20. dsf-python-3.5.0.1rc2/src/dsf/object_model/boards/direct_display/direct_display_controller.py +14 -0
  21. dsf-python-3.5.0.1rc2/src/dsf/object_model/boards/direct_display/direct_display_encoder.py +19 -0
  22. dsf-python-3.5.0.1rc2/src/dsf/object_model/boards/direct_display/direct_display_screen.py +101 -0
  23. dsf-python-3.5.0.1rc2/src/dsf/object_model/boards/direct_display/direct_display_screen_st7567.py +31 -0
  24. dsf-python-3.5.0.1rc2/src/dsf/object_model/boards/driver.py +29 -0
  25. dsf-python-3.5.0.1rc2/src/dsf/object_model/boards/driver_closed_loop.py +77 -0
  26. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/directories/directories.py +0 -11
  27. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/fans/fan_thermostatic_control.py +12 -2
  28. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/fans/fans.py +7 -7
  29. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/heat/heat.py +2 -2
  30. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/heat/heater.py +33 -0
  31. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/heat/heater_model_pid.py +3 -3
  32. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/heat/heater_monitor.py +16 -4
  33. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/inputs/__init__.py +2 -1
  34. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/inputs/input_channel.py +51 -3
  35. dsf-python-3.5.0.1rc2/src/dsf/object_model/inputs/inputs.py +22 -0
  36. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/job/build.py +1 -1
  37. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/job/gcode_fileinfo.py +3 -3
  38. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/job/job.py +34 -23
  39. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/job/layer.py +3 -3
  40. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/job/thumbnail_info.py +4 -4
  41. dsf-python-3.5.0.1rc2/src/dsf/object_model/led_strips/__init__.py +1 -0
  42. dsf-python-3.5.0.1rc2/src/dsf/object_model/led_strips/led_strip.py +74 -0
  43. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/limits/limits.py +24 -2
  44. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/axis.py +36 -20
  45. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/current_move.py +13 -2
  46. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/extruder.py +28 -17
  47. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/extruder_non_linear.py +3 -3
  48. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/input_shaping.py +13 -11
  49. dsf-python-3.5.0.1rc2/src/dsf/object_model/move/keepout_zone.py +58 -0
  50. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/kinematics/delta_kinematics.py +5 -5
  51. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/kinematics/delta_tower.py +5 -5
  52. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/kinematics/hangprinter_kinematics.py +1 -1
  53. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/kinematics/tilt_correction.py +3 -3
  54. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/microstepping.py +1 -1
  55. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/motors_idle_control.py +2 -2
  56. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/move.py +24 -5
  57. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/move_calibration.py +1 -1
  58. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/move_deviations.py +2 -2
  59. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/move_queue_item.py +2 -2
  60. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/move_rotation.py +1 -1
  61. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/move_segmentation.py +2 -2
  62. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/probe_grid.py +1 -1
  63. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/skew.py +3 -3
  64. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/network/network_interface.py +48 -25
  65. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/network/network_state.py +3 -0
  66. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/object_model.py +25 -30
  67. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/plugins/plugin_manifest.py +14 -4
  68. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/plugins/plugins.py +1 -1
  69. dsf-python-3.5.0.1rc2/src/dsf/object_model/sbc/__init__.py +3 -0
  70. dsf-python-3.5.0.1rc2/src/dsf/object_model/sbc/cpu.py +50 -0
  71. dsf-python-3.5.0.1rc2/src/dsf/object_model/sbc/dsf/__init__.py +3 -0
  72. dsf-python-3.5.0.1rc2/src/dsf/object_model/sbc/dsf/dsf.py +66 -0
  73. dsf-python-3.4.6.post4/src/dsf/object_model/http_endpoints/http_endpoints.py → dsf-python-3.5.0.1rc2/src/dsf/object_model/sbc/dsf/http_endpoint.py +4 -4
  74. {dsf-python-3.4.6.post4/src/dsf/object_model → dsf-python-3.5.0.1rc2/src/dsf/object_model/sbc/dsf}/user_sessions/user_sessions.py +3 -3
  75. dsf-python-3.5.0.1rc2/src/dsf/object_model/sbc/memory.py +30 -0
  76. dsf-python-3.5.0.1rc2/src/dsf/object_model/sbc/sbc.py +100 -0
  77. dsf-python-3.5.0.1rc2/src/dsf/object_model/sensors/analog_sensor.py +113 -0
  78. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/analog_sensor_type.py +9 -0
  79. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/endstop.py +14 -4
  80. dsf-python-3.5.0.1rc2/src/dsf/object_model/sensors/filament_monitors/Duet3DFilamentMonitor.py +66 -0
  81. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/filament_monitors/__init__.py +6 -4
  82. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/filament_monitors/filament_monitor.py +23 -1
  83. dsf-python-3.5.0.1rc2/src/dsf/object_model/sensors/filament_monitors/filament_monitor_enable_type.py +14 -0
  84. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/filament_monitors/laser_filament_monitor.py +10 -10
  85. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/filament_monitors/pulsed_filament_monitor.py +8 -8
  86. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/filament_monitors/rotating_magnet_filament_monitor.py +11 -11
  87. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/gp_input_port.py +1 -1
  88. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/probe.py +67 -29
  89. dsf-python-3.5.0.1rc2/src/dsf/object_model/sensors/temperature_error.py +62 -0
  90. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/spindles/spindles.py +33 -0
  91. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/state/__init__.py +1 -0
  92. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/state/beep_request.py +2 -2
  93. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/state/gp_output_port.py +13 -1
  94. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/state/message_box.py +75 -7
  95. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/state/restore_point.py +4 -4
  96. dsf-python-3.5.0.1rc2/src/dsf/object_model/state/startup_error.py +43 -0
  97. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/state/state.py +21 -40
  98. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/tools/tool_retraction.py +5 -5
  99. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/tools/tools.py +7 -7
  100. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/utils.py +6 -9
  101. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2/src/dsf_python.egg-info}/PKG-INFO +5 -1
  102. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf_python.egg-info/SOURCES.txt +28 -14
  103. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/tests/test_object_model.py +21 -15
  104. dsf-python-3.4.6.post4/src/dsf/object_model/boards/__init__.py +0 -10
  105. dsf-python-3.4.6.post4/src/dsf/object_model/boards/direct_display.py +0 -40
  106. dsf-python-3.4.6.post4/src/dsf/object_model/boards/driver.py +0 -15
  107. dsf-python-3.4.6.post4/src/dsf/object_model/boards/driver_settings.py +0 -27
  108. dsf-python-3.4.6.post4/src/dsf/object_model/boards/stall_detect_settings.py +0 -62
  109. dsf-python-3.4.6.post4/src/dsf/object_model/http_endpoints/__init__.py +0 -4
  110. dsf-python-3.4.6.post4/src/dsf/object_model/scanner/__init__.py +0 -4
  111. dsf-python-3.4.6.post4/src/dsf/object_model/scanner/scanner.py +0 -39
  112. dsf-python-3.4.6.post4/src/dsf/object_model/scanner/scanner_status.py +0 -23
  113. dsf-python-3.4.6.post4/src/dsf/object_model/sensors/analog_sensor.py +0 -47
  114. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/LICENSE +0 -0
  115. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/MANIFEST.in +0 -0
  116. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/README.md +0 -0
  117. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/pyproject.toml +0 -0
  118. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/setup.cfg +0 -0
  119. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/__init__.py +0 -0
  120. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/__init__.py +0 -0
  121. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/base_command.py +0 -0
  122. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/code_flags.py +0 -0
  123. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/code_interception.py +0 -0
  124. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/code_parameter.py +0 -0
  125. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/code_type.py +0 -0
  126. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/condition_type.py +0 -0
  127. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/files.py +0 -0
  128. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/model_subscription.py +0 -0
  129. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/object_model.py +0 -0
  130. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/packages.py +0 -0
  131. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/plugins.py +0 -0
  132. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/commands/responses.py +0 -0
  133. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/connections/command_connection.py +0 -0
  134. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/connections/exceptions.py +0 -0
  135. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/connections/init_messages/__init__.py +0 -0
  136. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/connections/init_messages/server_init_message.py +0 -0
  137. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/connections/subscribe_connection.py +0 -0
  138. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/exceptions.py +0 -0
  139. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/boards/accelerometer.py +0 -0
  140. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/boards/min_max_current.py +0 -0
  141. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/directories/__init__.py +0 -0
  142. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/fans/__init__.py +0 -0
  143. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/heat/__init__.py +0 -0
  144. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/heat/heater_model.py +0 -0
  145. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/inputs/compatibility.py +0 -0
  146. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/inputs/distance_unit.py +0 -0
  147. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/inputs/input_channel_state.py +0 -0
  148. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/job/__init__.py +0 -0
  149. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/job/build_object.py +0 -0
  150. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/job/times_left.py +0 -0
  151. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/limits/__init__.py +0 -0
  152. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/messages/__init__.py +0 -0
  153. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/messages/messages.py +0 -0
  154. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/model_collection.py +0 -0
  155. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/model_dictionary.py +0 -0
  156. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/model_object.py +0 -0
  157. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/__init__.py +0 -0
  158. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/driver_id.py +0 -0
  159. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/kinematics/__init__.py +0 -0
  160. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/kinematics/core_kinematics.py +0 -0
  161. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/kinematics/kinematics.py +0 -0
  162. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/kinematics/kinematics_name.py +0 -0
  163. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/kinematics/polar_kinematics.py +0 -0
  164. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/kinematics/scara_kinematics.py +0 -0
  165. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/kinematics/zleadscrew_kinematics.py +0 -0
  166. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/move/move_compensation.py +0 -0
  167. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/network/__init__.py +0 -0
  168. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/network/network.py +0 -0
  169. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/network/network_interface_type.py +0 -0
  170. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/network/network_protocol.py +0 -0
  171. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/plugins/__init__.py +0 -0
  172. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/plugins/sbc_permissions.py +0 -0
  173. {dsf-python-3.4.6.post4/src/dsf/object_model/http_endpoints → dsf-python-3.5.0.1rc2/src/dsf/object_model/sbc/dsf}/http_endpoint_type.py +0 -0
  174. {dsf-python-3.4.6.post4/src/dsf/object_model → dsf-python-3.5.0.1rc2/src/dsf/object_model/sbc/dsf}/user_sessions/__init__.py +0 -0
  175. {dsf-python-3.4.6.post4/src/dsf/object_model → dsf-python-3.5.0.1rc2/src/dsf/object_model/sbc/dsf}/user_sessions/access_level.py +0 -0
  176. {dsf-python-3.4.6.post4/src/dsf/object_model → dsf-python-3.5.0.1rc2/src/dsf/object_model/sbc/dsf}/user_sessions/session_type.py +0 -0
  177. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/__init__.py +0 -0
  178. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/endstop_type.py +0 -0
  179. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/filament_monitors/filament_monitor_status.py +0 -0
  180. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/filament_monitors/filament_monitor_type.py +0 -0
  181. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/probe_type.py +0 -0
  182. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/sensors/sensors.py +0 -0
  183. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/spindles/__init__.py +0 -0
  184. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/spindles/spindle_state.py +0 -0
  185. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/state/log_level.py +0 -0
  186. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/state/machine_mode.py +0 -0
  187. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/state/machine_status.py +0 -0
  188. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/tools/__init__.py +0 -0
  189. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/tools/tool_state.py +0 -0
  190. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/utils.py +0 -0
  191. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/volumes/__init__.py +0 -0
  192. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/object_model/volumes/volumes.py +0 -0
  193. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf/utility/__init__.py +0 -0
  194. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf_python.egg-info/dependency_links.txt +0 -0
  195. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf_python.egg-info/requires.txt +0 -0
  196. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/src/dsf_python.egg-info/top_level.txt +0 -0
  197. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/tests/test_code.py +0 -0
  198. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/tests/test_custom_http_endpoint.py +0 -0
  199. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/tests/test_custom_m_codes.py +0 -0
  200. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/tests/test_send_simple_code.py +0 -0
  201. {dsf-python-3.4.6.post4 → dsf-python-3.5.0.1rc2}/tests/test_subscribe_object_model.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: dsf-python
3
- Version: 3.4.6.post4
3
+ Version: 3.5.0.1rc2
4
4
  Summary: Python interface to access DuetSoftwareFramework
5
5
  Home-page: https://github.com/Duet3D/dsf-python
6
6
  Author: Duet3D Ltd.
@@ -17,6 +17,10 @@ Classifier: Programming Language :: Python :: 3
17
17
  Classifier: Programming Language :: Python :: 3.7
18
18
  Classifier: Programming Language :: Python :: 3.8
19
19
  Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
20
24
  Classifier: Programming Language :: Python :: 3 :: Only
21
25
  Requires-Python: >=3.7, <4
22
26
  Description-Content-Type: text/markdown
@@ -6,7 +6,7 @@ long_description = open("README.md", encoding="utf-8").read()
6
6
 
7
7
  setuptools.setup(
8
8
  name="dsf-python",
9
- version="3.4.6-4",
9
+ version="3.5.0.1rc2",
10
10
  description="Python interface to access DuetSoftwareFramework",
11
11
  long_description=long_description,
12
12
  long_description_content_type="text/markdown",
@@ -22,6 +22,10 @@ setuptools.setup(
22
22
  "Programming Language :: Python :: 3.7",
23
23
  "Programming Language :: Python :: 3.8",
24
24
  "Programming Language :: Python :: 3.9",
25
+ "Programming Language :: Python :: 3.10",
26
+ "Programming Language :: Python :: 3.11",
27
+ "Programming Language :: Python :: 3.12",
28
+ "Programming Language :: Python :: 3.13",
25
29
  "Programming Language :: Python :: 3 :: Only",
26
30
  ],
27
31
  install_requires=[
@@ -1,4 +1,3 @@
1
- from __future__ import annotations
2
1
  from typing import List, Optional
3
2
 
4
3
  from .base_command import BaseCommand
@@ -79,7 +78,7 @@ class Code(BaseCommand):
79
78
  @property
80
79
  def is_from_file_channel(self) -> bool:
81
80
  """Check if this code is from a file channel"""
82
- return self.channel is CodeChannel.File
81
+ return self.channel is CodeChannel.File or self.channel is CodeChannel.File2
83
82
 
84
83
  def parameter(self, letter: str, default=None):
85
84
  """Retrieve the parameter whose letter equals c or generate a default parameter"""
@@ -40,6 +40,12 @@ class CodeChannel(str, Enum):
40
40
  # Code channel that executes macros on power fail, heater faults and filament out
41
41
  Autopause = "Autopause"
42
42
 
43
+ # Code channel for secondary file prints
44
+ File2 = "File2"
45
+
46
+ # Code channel for the code queue that executes a couple of codes in-sync with moves of the primary print file
47
+ Queue2 = "Queue2"
48
+
43
49
  # Unknown code channel
44
50
  Unknown = "Unknown"
45
51
 
@@ -10,7 +10,9 @@ def check_password(password: str):
10
10
  """
11
11
  Check if the given password is correct and matches the previously set value from M551.
12
12
  If no password was configured before or if it was set to "reprap", this will always return true
13
+
13
14
  :param password: Password to check
15
+
14
16
  :returns: true if the password matches or is not set
15
17
  """
16
18
  if not isinstance(password, str) or not password:
@@ -23,6 +25,7 @@ def evaluate_expression(channel: CodeChannel, expression: str):
23
25
  Evaluate an arbitrary expression on the given channel in RepRapFirmware.
24
26
  Do not use this call to evaluate file-based and network-related fields because the
25
27
  DSF and RRF models diverge in this regard.
28
+
26
29
  :param channel: Code channel where the expression is evaluated
27
30
  :param expression: Expression to evaluate
28
31
  """
@@ -33,22 +36,36 @@ def evaluate_expression(channel: CodeChannel, expression: str):
33
36
  return BaseCommand("EvaluateExpression", **{"Channel": channel, "Expression": expression})
34
37
 
35
38
 
36
- def flush(channel: CodeChannel):
39
+ def flush(channel: CodeChannel, sync_file_streams: bool = False, if_executing: bool = True):
37
40
  """
38
41
  Wait for all pending (macro) codes on the given channel to finish.
39
42
  This effectively guarantees that all buffered codes are processed by RRF before this command finishes.
43
+
40
44
  :param channel: Code channel to flush
45
+ :param sync_file_streams: Whether the File and File2 streams are supposed to synchronize if a code is being
46
+ intercepted. This option should be used with care, under certain circumstances this can lead to a deadlock!
47
+ :param if_executing: Check if the corresponding channel is actually executing codes (i.e. if it is active).
48
+ If the input channel is not active, this command returns false.
49
+ This option is ignored if SyncFileStreams is true.
50
+
41
51
  :returns: true if the flush request is successful
42
52
  """
43
53
  if not isinstance(channel, CodeChannel):
44
54
  raise TypeError("channel must be a CodeChannel")
45
- return BaseCommand("Flush", **{"Channel": channel})
55
+ if not isinstance(sync_file_streams, bool):
56
+ raise TypeError("sync_file_streams must be a boolean")
57
+ if not isinstance(if_executing, bool):
58
+ raise TypeError("if_executing must be a boolean")
59
+ return BaseCommand("Flush",
60
+ **{"Channel": channel, "SyncFileStreams": sync_file_streams, "IfExecuting": if_executing})
46
61
 
47
62
 
48
63
  def invalidate_channel(channel: CodeChannel):
49
64
  """
50
65
  Invalidate all pending codes and files on a given channel (including buffered codes from DSF in RepRapFirmware)
66
+
51
67
  :param channel: Code channel to invalidate
68
+
52
69
  :returns: true if the invalidate request is successful
53
70
  """
54
71
  if not isinstance(channel, CodeChannel):
@@ -59,6 +76,7 @@ def invalidate_channel(channel: CodeChannel):
59
76
  def set_update_status(updating: bool):
60
77
  """
61
78
  Override the current status as reported by the object model when performing a software update.
79
+
62
80
  :param updating: Whether an update is now in progress
63
81
  """
64
82
  if not isinstance(updating, bool):
@@ -73,6 +91,7 @@ def simple_code(code: str, channel: CodeChannel = CodeChannel.DEFAULT_CHANNEL, a
73
91
  its Code.Result is transformed back into a basic string. This is useful for minimal
74
92
  extensions that do not require granular control of the code details. Except for certain cases, it
75
93
  is NOT recommended for usage in InterceptionMode because it renders the internal code buffer useless.
94
+
76
95
  :param code: Code to parse and execute
77
96
  :param channel: Destination channel
78
97
  :param async_exec: Whether this code may be executed asynchronously.
@@ -93,6 +112,7 @@ def write_message(
93
112
  ):
94
113
  """
95
114
  Write an arbitrary generic message
115
+
96
116
  :param message_type: Type of the message to write
97
117
  :param content: Content of the message to write
98
118
  :param output_message: Output the message on the console and via the object model
@@ -1,5 +1,5 @@
1
1
  from .base_command import BaseCommand
2
- from ..object_model.http_endpoints import HttpEndpointType
2
+ from ..object_model import HttpEndpointType
3
3
 
4
4
 
5
5
  def add_http_endpoint(endpoint_type: HttpEndpointType, namespace: str, path: str, is_upload_request: bool):
@@ -1,21 +1,5 @@
1
- from enum import Enum
2
-
3
1
  from .base_command import BaseCommand
4
-
5
-
6
- class AccessLevel(str, Enum):
7
- """Defines what a user is allowed to do"""
8
-
9
- ReadOnly = "ReadOnly"
10
- ReadWrite = "ReadWrite"
11
-
12
-
13
- class SessionType(str, Enum):
14
- """Types of user sessions"""
15
-
16
- Local = "Local"
17
- HTTP = "HTTP"
18
- Telnet = "Telnet"
2
+ from ..object_model import AccessLevel, SessionType
19
3
 
20
4
 
21
5
  def add_user_session(access_level: AccessLevel, session_type: SessionType, origin: str):
@@ -24,8 +24,8 @@ class InterceptionMode(str, Enum):
24
24
  # Intercept codes before they are internally processed by the control server
25
25
  PRE = "Pre"
26
26
 
27
- # Intercept codes after the initial processing of the control server but before they are forwarded to
28
- # the RepRapFirmware controller
27
+ # Intercept codes after the initial processing of the control server, but before they are forwarded
28
+ # to the RepRapFirmware controller
29
29
  POST = "Post"
30
30
 
31
31
  # Receive a notification for executed codes. In this state the final result can be still changed
@@ -5,8 +5,7 @@ from .. import commands, DEFAULT_BACKLOG
5
5
  from ..commands import code
6
6
  from ..commands.code_channel import CodeChannel
7
7
  from ..http import HttpEndpointUnixSocket
8
- from ..object_model import ObjectModel
9
- from ..object_model.http_endpoints import HttpEndpointType
8
+ from ..object_model import HttpEndpointType, ObjectModel
10
9
  from ..object_model.job import GCodeFileInfo
11
10
  from ..object_model.messages import Message, MessageType
12
11
  from ..object_model.state import LogLevel
@@ -117,9 +117,7 @@ class BaseConnection:
117
117
  except Exception as e:
118
118
  raise e
119
119
  # either 0 or end of data
120
- if part == b"":
121
- raise IPCSocketBrokenException()
122
- elif len(part) < BUFF_SIZE:
120
+ if len(part) < BUFF_SIZE:
123
121
  break
124
122
 
125
123
  json_string += data.decode("utf8")
@@ -17,7 +17,7 @@ clientinitmessages holds all messages a client can send to the server to initiat
17
17
  You should have received a copy of the GNU Lesser General Public License
18
18
  along with this program. If not, see <https://www.gnu.org/licenses/>.
19
19
  """
20
- from __future__ import annotations
20
+ from typing import List
21
21
  from .server_init_message import ServerInitMessage
22
22
  from .. import ConnectionMode, InterceptionMode, SubscriptionMode
23
23
  from ...commands.code_channel import CodeChannel
@@ -38,8 +38,8 @@ class ClientInitMessage:
38
38
 
39
39
  def intercept_init_message(
40
40
  intercept_mode: InterceptionMode,
41
- channels: list[CodeChannel],
42
- filters: list[str],
41
+ channels: List[CodeChannel],
42
+ filters: List[str],
43
43
  priority_codes: bool,
44
44
  auto_flush: bool = True):
45
45
  """
@@ -70,7 +70,7 @@ def intercept_init_message(
70
70
  "Channels": channels,
71
71
  "AutoFlush": auto_flush,
72
72
  "Filters": filters,
73
- "PriortyCodes": priority_codes,
73
+ "PriorityCodes": priority_codes,
74
74
  },
75
75
  )
76
76
 
@@ -1,4 +1,4 @@
1
- from __future__ import annotations
1
+ from typing import List, Optional
2
2
 
3
3
  from .base_command_connection import BaseCommandConnection
4
4
  from .init_messages import client_init_messages
@@ -28,8 +28,8 @@ class InterceptConnection(BaseCommandConnection):
28
28
  def __init__(
29
29
  self,
30
30
  interception_mode: client_init_messages.InterceptionMode,
31
- channels: list[CodeChannel] = None,
32
- filters: list[str] = None,
31
+ channels: List[CodeChannel] = None,
32
+ filters: List[str] = None,
33
33
  auto_flush: bool = True,
34
34
  priority_codes: bool = False,
35
35
  debug: bool = False,
@@ -5,7 +5,7 @@ from concurrent.futures import ThreadPoolExecutor
5
5
  from enum import Enum
6
6
 
7
7
  from . import DEFAULT_BACKLOG
8
- from .object_model.http_endpoints import HttpEndpointType
8
+ from .object_model import HttpEndpointType
9
9
 
10
10
 
11
11
  class HttpResponseType(str, Enum):
@@ -2,19 +2,19 @@ from .boards import Board, BoardState
2
2
  from .directories import Directories
3
3
  from .fans import Fan
4
4
  from .heat import Heat, Heater, HeaterState
5
- from .http_endpoints import HttpEndpoint, HttpEndpointType
6
5
  from .inputs import InputChannel
7
6
  from .job import Job
7
+ from .led_strips import LedStrip, LedStripType
8
8
  from .limits import Limits
9
9
  from .messages import Message, MessageType
10
10
  from .move import DriverId, Move
11
11
  from .network import Network, NetworkInterface, NetworkInterfaceType, NetworkProtocol, NetworkState
12
12
  from .object_model import ObjectModel
13
13
  from .plugins import Plugin, PluginManifest, SbcPermissions
14
- from .scanner import Scanner, ScannerStatus
14
+ from .sbc import CPU, Memory, SBC
15
+ from .sbc.dsf import AccessLevel, HttpEndpoint, HttpEndpointType, SessionType, UserSession
15
16
  from .sensors import AnalogSensor, AnalogSensorType, Endstop, EndstopType, GpInputPort, Probe, ProbeType, Sensors
16
17
  from .spindles import Spindle, SpindleState
17
18
  from .state import LogLevel, MachineStatus, MessageBox, MessageBoxMode, State
18
19
  from .tools import Tool, ToolState
19
- from .user_sessions import AccessLevel, SessionType, UserSession
20
20
  from .volumes import Volume
@@ -0,0 +1,10 @@
1
+ from .accelerometer import Accelerometer
2
+ from .boards import Board, BoardState
3
+ from .board_closed_loop import BoardClosedLoop
4
+ from .direct_display import DirectDisplay
5
+ from .driver import Driver
6
+ from .driver_closed_loop import DriverClosedLoop, ClosedLoopCurrentFraction, ClosedLoopPositionError
7
+ from .min_max_current import MinMaxCurrent
8
+
9
+ __all__ = ['Accelerometer', 'Board', 'BoardState', 'BoardClosedLoop', 'DirectDisplay', 'Driver', 'DriverClosedLoop',
10
+ 'ClosedLoopCurrentFraction', 'ClosedLoopPositionError', 'MinMaxCurrent']
@@ -1,10 +1,10 @@
1
1
  from ..model_object import ModelObject
2
2
 
3
3
 
4
- class ClosedLoop(ModelObject):
4
+ class BoardClosedLoop(ModelObject):
5
5
  """This represents information about closed-loop tuning"""
6
6
  def __init__(self):
7
- super(ClosedLoop, self).__init__()
7
+ super(BoardClosedLoop, self).__init__()
8
8
  # Number of collected data points in the last run or 0 if it failed
9
9
  self._points = 0
10
10
  # Number of completed sampling runs
@@ -1,12 +1,16 @@
1
1
  from __future__ import annotations
2
2
  from enum import Enum
3
+ from typing import List, Union
3
4
 
4
5
  from .accelerometer import Accelerometer
5
- from .closed_loop import ClosedLoop
6
+ from .board_closed_loop import BoardClosedLoop
6
7
  from .direct_display import DirectDisplay
8
+ from .driver import Driver
7
9
  from .min_max_current import MinMaxCurrent
10
+ from ..model_collection import ModelCollection
8
11
  from ..model_object import ModelObject
9
12
  from ..utils import wrap_model_property
13
+ from ...utils import deprecated
10
14
 
11
15
 
12
16
  class BoardState(str, Enum):
@@ -36,7 +40,7 @@ class Board(ModelObject):
36
40
  # Accelerometer of this board or None if unknown
37
41
  accelerometer = wrap_model_property('accelerometer', Accelerometer)
38
42
  # Closed loop data of this board or None if unknown
39
- closed_loop = wrap_model_property('closed_loop', ClosedLoop)
43
+ closed_loop = wrap_model_property('closed_loop', BoardClosedLoop)
40
44
  # Details about a connected display or None if none is connected
41
45
  direct_display = wrap_model_property('direct_display', DirectDisplay)
42
46
  # Minimum, maximum, and current temperatures of the MCU or None if unknown
@@ -59,6 +63,8 @@ class Board(ModelObject):
59
63
  self._closed_loop = None
60
64
  # Details about a connected display or None if none is connected
61
65
  self._direct_display = None
66
+ # Drivers of this board
67
+ self._drivers = None
62
68
  # Date of the firmware build
63
69
  self._firmware_date = ""
64
70
  # Filename of the firmware binary
@@ -95,9 +101,11 @@ class Board(ModelObject):
95
101
  self._v_12 = None
96
102
  # Minimum, maximum, and current voltages on the input rail or None if unknown
97
103
  self._v_in = None
104
+ # Filename of the on-board WiFi chip or None if not present
105
+ self._wifi_firmware_file_name = None
98
106
 
99
107
  @property
100
- def bootloader_file_name(self) -> str | None:
108
+ def bootloader_file_name(self) -> Union[str, None]:
101
109
  """Filename of the bootloader binary or None if unknown"""
102
110
  return self._bootloader_file_name
103
111
 
@@ -106,7 +114,7 @@ class Board(ModelObject):
106
114
  self._bootloader_file_name = str(value) if value is not None else None
107
115
 
108
116
  @property
109
- def can_address(self) -> int | None:
117
+ def can_address(self) -> Union[int, None]:
110
118
  """CAN address of this board or None if not applicable"""
111
119
  return self._can_address
112
120
 
@@ -114,13 +122,22 @@ class Board(ModelObject):
114
122
  def can_address(self, value: int | None = None):
115
123
  self._can_address = int(value) if value is not None else None
116
124
 
125
+ @property
126
+ def drivers(self) -> Union[List[Driver], None]:
127
+ """Drivers of this board"""
128
+ return self._drivers
129
+
130
+ @drivers.setter
131
+ def drivers(self, value):
132
+ self._drivers = None if value is None else ModelCollection(Driver, value)
133
+
117
134
  @property
118
135
  def firmware_date(self) -> str:
119
136
  """Date of the firmware build"""
120
137
  return self._firmware_date
121
138
 
122
139
  @firmware_date.setter
123
- def firmware_date(self, value: str):
140
+ def firmware_date(self, value):
124
141
  self._firmware_date = str(value)
125
142
 
126
143
  @property
@@ -129,7 +146,7 @@ class Board(ModelObject):
129
146
  return self._firmware_file_name
130
147
 
131
148
  @firmware_file_name.setter
132
- def firmware_file_name(self, value: str):
149
+ def firmware_file_name(self, value):
133
150
  self._firmware_file_name = str(value)
134
151
 
135
152
  @property
@@ -138,7 +155,7 @@ class Board(ModelObject):
138
155
  return self._firmware_name
139
156
 
140
157
  @firmware_name.setter
141
- def firmware_name(self, value: str):
158
+ def firmware_name(self, value):
142
159
  self._firmware_name = str(value)
143
160
 
144
161
  @property
@@ -147,11 +164,11 @@ class Board(ModelObject):
147
164
  return self._firmware_version
148
165
 
149
166
  @firmware_version.setter
150
- def firmware_version(self, value: str):
167
+ def firmware_version(self, value):
151
168
  self._firmware_version = str(value)
152
169
 
153
170
  @property
154
- def iap_file_name_SBC(self) -> str | None:
171
+ def iap_file_name_SBC(self) -> Union[str, None]:
155
172
  """Filename of the IAP binary that is used for updates from the SBC or None if unsupported"""
156
173
  return self._iap_file_name_SBC
157
174
 
@@ -160,7 +177,7 @@ class Board(ModelObject):
160
177
  self._iap_file_name_SBC = str(value) if value is not None else None
161
178
 
162
179
  @property
163
- def iap_file_name_SD(self) -> str | None:
180
+ def iap_file_name_SD(self) -> Union[str, None]:
164
181
  """Filename of the IAP binary that is used for updates from the SD card or None if unsupported
165
182
  This is only available for the mainboard (first board item)"""
166
183
  return self._iap_file_name_SD
@@ -175,7 +192,7 @@ class Board(ModelObject):
175
192
  return self._max_heaters
176
193
 
177
194
  @max_heaters.setter
178
- def max_heaters(self, value: int):
195
+ def max_heaters(self, value):
179
196
  self._max_heaters = int(value)
180
197
 
181
198
  @property
@@ -184,7 +201,7 @@ class Board(ModelObject):
184
201
  return self._max_motors
185
202
 
186
203
  @max_motors.setter
187
- def max_motors(self, value: int):
204
+ def max_motors(self, value):
188
205
  self._max_motors = int(value)
189
206
 
190
207
  @property
@@ -193,7 +210,7 @@ class Board(ModelObject):
193
210
  return self._name
194
211
 
195
212
  @name.setter
196
- def name(self, value: str):
213
+ def name(self, value):
197
214
  self._name = str(value)
198
215
 
199
216
  @property
@@ -202,7 +219,7 @@ class Board(ModelObject):
202
219
  return self._short_name
203
220
 
204
221
  @short_name.setter
205
- def short_name(self, value: str):
222
+ def short_name(self, value):
206
223
  self._short_name = str(value)
207
224
 
208
225
  @property
@@ -221,9 +238,10 @@ class Board(ModelObject):
221
238
  f" Got {type(value)}: {value}")
222
239
 
223
240
  @property
241
+ @deprecated(f"Use {__name__}.supports_direct_display instead")
224
242
  def supports_12864(self) -> bool:
225
243
  """Indicates if this board supports external 12864 displays
226
- Obsolete: Replaced with SupportsDirectDisplay"""
244
+ Deprecated: Use supports_direct_display instead"""
227
245
  return self._supports_12864
228
246
 
229
247
  @supports_12864.setter
@@ -240,10 +258,19 @@ class Board(ModelObject):
240
258
  self._supports_direct_display = bool(value)
241
259
 
242
260
  @property
243
- def unique_id(self) -> str | None:
261
+ def unique_id(self) -> Union[str, None]:
244
262
  """Unique identifier of the board or None if unknown"""
245
263
  return self._unique_id
246
264
 
247
265
  @unique_id.setter
248
266
  def unique_id(self, value: str | None = None):
249
267
  self._unique_id = str(value) if value is not None else None
268
+
269
+ @property
270
+ def wifi_firmware_file_name(self):
271
+ """Filename of the on-board WiFi chip or None if not present"""
272
+ return self._wifi_firmware_file_name
273
+
274
+ @wifi_firmware_file_name.setter
275
+ def wifi_firmware_file_name(self, value):
276
+ self._wifi_firmware_file_name = str(value) if value is not None else None
@@ -0,0 +1,8 @@
1
+ from .direct_display import DirectDisplay
2
+ from .direct_display_controller import DirectDisplayController
3
+ from .direct_display_encoder import DirectDisplayEncoder
4
+ from .direct_display_screen import DirectDisplayScreen
5
+ from .direct_display_screen_st7567 import DirectDisplayScreenST7567
6
+
7
+ __all__ = ['DirectDisplay', 'DirectDisplayController', 'DirectDisplayEncoder',
8
+ 'DirectDisplayScreen', 'DirectDisplayScreenST7567']
@@ -0,0 +1,23 @@
1
+ from .direct_display_encoder import DirectDisplayEncoder
2
+ from .direct_display_screen import DirectDisplayScreen
3
+
4
+ from ...model_object import ModelObject
5
+ from ...utils import wrap_model_property
6
+
7
+
8
+ class DirectDisplay(ModelObject):
9
+ """Class providing information about a connected direct-connect display"""
10
+
11
+ encoder = wrap_model_property('encoder', DirectDisplayEncoder)
12
+
13
+ def __init__(self):
14
+ super(DirectDisplay, self).__init__()
15
+ # Encoder of this screen or null if none
16
+ self._encoder = None
17
+ # Screen information
18
+ self._screen = DirectDisplayScreen()
19
+
20
+ @property
21
+ def screen(self) -> DirectDisplayScreen:
22
+ """Screen information"""
23
+ return self._screen
@@ -0,0 +1,14 @@
1
+ from enum import Enum
2
+
3
+
4
+ class DirectDisplayController(str, Enum):
5
+ """Enumeration of possible direct-connect display controllers"""
6
+
7
+ # ST7920 controller
8
+ ST7920 = "ST7920"
9
+
10
+ # ST7567 controller
11
+ ST7567 = "ST7567"
12
+
13
+ # ILI9488 controller
14
+ ILI9488 = "ILI9488"
@@ -0,0 +1,19 @@
1
+ from ...model_object import ModelObject
2
+
3
+
4
+ class DirectDisplayEncoder(ModelObject):
5
+ """Class providing information about a connected display encoder"""
6
+
7
+ def __init__(self):
8
+ super().__init__()
9
+ # Number of pulses per click of the rotary encoder
10
+ self._pulses_per_click = 1
11
+
12
+ @property
13
+ def pulses_per_click(self) -> int:
14
+ """Number of pulses per click of the rotary encoder"""
15
+ return self._pulses_per_click
16
+
17
+ @pulses_per_click.setter
18
+ def pulses_per_click(self, value: int):
19
+ self._pulses_per_click = int(value)