Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add proper support for Orca Slicer #2

Merged
merged 1 commit into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,9 @@ pip install -r requirements.txt
spoolman2slicer uses [Jinja2](https://palletsprojects.com/p/jinja/)
templates for the configuration files it creates. They are stored with
the filaments' material's name in `templates-<slicer>/`.
If the material's template isn't found, `default.template` is used.
If the material's template isn't found, `default.<suffix>.template`
is used, where `suffix` is the config files suffix (`ini` for Super Slicer,
`info` and `json` for Orca Slicer).

The variables available in the templates is the return data from
Spoolman's filament request, described
Expand All @@ -75,12 +77,14 @@ sm2s also adds its own fields under the sm2s field:
* name - the name of the tool's program file.
* version - the version of the tool.
* now - the time when the file is created.
* slicer_suffix - the filename suffix used by the slicer.
* now_int - the time when the file is created as the number of seconds since UNIX' epoch.
* slicer_suffix - the filename's suffix.

To generate your own templates, copy your existing filament settings
from the slicers config dir (on linux: ~/.config/SuperSlicer/filament/)
to the template dir with the material's name plus ".template", then
change the fields' values like the provided template files.
from the slicers config dir (on linux: `~/.config/SuperSlicer/filament/`,
`~/.config/OrcaSlicer/user/default/filament/`) to the template dir with
the material's name plus "<suffix>.template", then change the fields'
values like the provided template files.

The filename used for the filaments is created by
the `filename.template` template.
Expand All @@ -91,5 +95,9 @@ the `filename.template` template.
```sh
./spoolman2slicer.py -U -d ~/.config/SuperSlicer/filament/
```
or
```sh
./spoolman2slicer.py -s orcaslicer -U -d ~/.config/OrcaSlicer/user/default/filament/
```

See the other options above.
85 changes: 60 additions & 25 deletions spoolman2slicer.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
import requests
from websockets.client import connect

DEFAULT_TEMPLATE = "default.template"
DEFAULT_TEMPLATE_PREFIX = "default."
DEFAULT_TEMPLATE_SUFFIX = ".template"
FILENAME_TEMPLATE = "filename.template"

ORCASLICER = "orcaslicer"
Expand All @@ -32,9 +33,7 @@
description="Fetches filaments from Spoolman and creates slicer filament config files.",
)

parser.add_argument(
"--version", action="version", version="%(prog)s " + VERSION
)
parser.add_argument("--version", action="version", version="%(prog)s " + VERSION)
parser.add_argument(
"-d",
"--dir",
Expand Down Expand Up @@ -91,23 +90,24 @@
filename_usage = {}


def add_sm2s_to_filament(filament):
def add_sm2s_to_filament(filament, suffix):
"""Adds the sm2s object to filament"""
sm2s = {
"name": parser.prog,
"version": VERSION,
"now": time.asctime(),
"slicer_suffix": get_config_suffix(),
"now_int": int(time.time()),
"slicer_suffix": suffix,
}
filament["sm2s"] = sm2s


def get_config_suffix():
"""Returns the slicer's config file prefix"""
if args.slicer == SUPERSLICER:
return "ini"
return ["ini"]
if args.slicer == ORCASLICER:
return "json"
return ["json", "info"]

raise ValueError("That slicer is not yet supported")

Expand All @@ -124,9 +124,28 @@ def get_filament_filename(filament):
return args.dir + "/" + template.render(filament)


def get_cached_filename_from_filaments_id(filament):
"""Returns the cached (old) filename for the filament"""
return filament_id_to_filename.get(
f"{filament['id']}-{filament['sm2s']['slicer_suffix']}"
)


def set_cached_filename_from_filaments_id(filament, filename):
"""Stores the filename for the filament in a cache"""
filament_id_to_filename[f"{filament['id']}-{filament['sm2s']['slicer_suffix']}"] = (
filename
)


def get_default_template_for_suffix(suffix):
"""Get the template filename for the given suffix"""
return f"{DEFAULT_TEMPLATE_PREFIX}{suffix}{DEFAULT_TEMPLATE_SUFFIX}"


def delete_filament(filament, is_update=False):
"""Delete the filament's file if no longer in use"""
filename = filament_id_to_filename[filament["id"]]
filename = get_cached_filename_from_filaments_id(filament)

if not filename in filename_usage:
return
Expand All @@ -136,7 +155,6 @@ def delete_filament(filament, is_update=False):

new_filename = None
if is_update:
add_sm2s_to_filament(filament)
new_filename = get_filament_filename(filament)

if filename != new_filename:
Expand All @@ -147,16 +165,16 @@ def delete_filament(filament, is_update=False):
def delete_all_filaments():
"""Delete all config files in the filament dir"""
for filename in os.listdir(args.dir):
if filename.endswith("." + get_config_suffix()):
filename = args.dir + "/" + filename
print(f"Deleting: {filename}")
os.remove(filename)
for suffix in get_config_suffix():
if filename.endswith("." + suffix):
filename = args.dir + "/" + filename
print(f"Deleting: {filename}")
os.remove(filename)


def write_filament(filament):
"""Output the filament to the right file"""

add_sm2s_to_filament(filament)
filename = get_filament_filename(filament)
if filename in filename_usage:
filename_usage[filename] += 1
Expand All @@ -165,21 +183,30 @@ def write_filament(filament):

filament_id = filament["id"]

old_filename = filament_id_to_filename.get(filament_id)
# old_filename = filament_id_to_filename.get(filament_id)
old_filename = get_cached_filename_from_filaments_id(filament)

filament_id_to_filename[filament_id] = filename
# filament_id_to_filename[filament_id] = filename
set_cached_filename_from_filaments_id(filament, filename)

if "material" in filament:
template_name = f"{filament['material']}.template"
template_name = (
f"{filament['material']}.{filament['sm2s']['slicer_suffix']}.template"
)
else:
template_name = DEFAULT_TEMPLATE
template_name = get_default_template_for_suffix(
filament["sm2s"]["slicer_suffix"]
)

try:
template = templates.get_template(template_name)
if args.verbose:
print(f"Using {template_name} as template")
except TemplateNotFound:
template = templates.get_template(DEFAULT_TEMPLATE)
template_name = get_default_template_for_suffix(
filament["sm2s"]["slicer_suffix"]
)
template = templates.get_template(template_name)
if args.verbose:
print("Using the default template")

Expand Down Expand Up @@ -212,13 +239,17 @@ def load_and_update_all_filaments(url: str):

for spool in spools:
filament = spool["filament"]
write_filament(filament)
for suffix in get_config_suffix():
add_sm2s_to_filament(filament, suffix)
write_filament(filament)


def handle_filament_update(filament):
"""Handles update of a filament"""
delete_filament(filament, is_update=True)
write_filament(filament)
for suffix in get_config_suffix():
add_sm2s_to_filament(filament, suffix)
delete_filament(filament, is_update=True)
write_filament(filament)


def handle_spool_update_msg(msg):
Expand All @@ -227,11 +258,15 @@ def handle_spool_update_msg(msg):
spool = msg["payload"]
filament = spool["filament"]
if msg["type"] == "added":
write_filament(filament)
for suffix in get_config_suffix():
add_sm2s_to_filament(filament, suffix)
write_filament(filament)
elif msg["type"] == "updated":
handle_filament_update(filament)
elif msg["type"] == "deleted":
delete_filament(filament)
for suffix in get_config_suffix():
add_sm2s_to_filament(filament, suffix)
delete_filament(filament)
else:
print(f"Got unknown filament update msg: {msg}")

Expand Down
68 changes: 68 additions & 0 deletions templates-orcaslicer/ABS+.json.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"_comment": "Generated by {{sm2s.name}} {{sm2s.version}}",
"default_filament_colour": [
"#{{color_hex}}"
],
"filament_cost": [
"{{price}}"
],
"filament_spool_weight": [
"{{spool_weight}}"
],
"filament_type": [
"{{material}}"
],
"filament_diameter": [
"{{diameter}}"
],
"filament_density": [
"{{density}}"
],
"filament_flow_ratio": [
"0.924"
],
"filament_settings_id": [
"{{id}}"
],
"filament_start_gcode": [
"SET_PRESSURE_ADVANCE ADVANCE={{extra.pressure_advance|default(0)|float}}\nASSERT_ACTIVE_FILAMENT ID={{id}}"
],
"filament_vendor": [
"{{vendor.name}}"
],
"from": "User",
"inherits": "Voron Generic ABS",
"is_custom_defined": "0",
"name": "{{name}}",
"nozzle_temperature": [
"{{settings_extruder_temp|int}}"
],
"nozzle_temperature_initial_layer": [
"{{settings_extruder_temp|int + 5}}"
],
"cool_plate_temp" : [
"{{settings_bed_temp|int}}"
],
"eng_plate_temp" : [
"{{settings_bed_temp|int}}"
],
"hot_plate_temp" : [
"{{settings_bed_temp|int}}"
],
"textured_plate_temp" : [
"{{settings_bed_temp|int}}"
],
"cool_plate_temp_initial_layer" : [
"{{settings_bed_temp|int + 10}}"
],
"eng_plate_temp_initial_layer" : [
"{{settings_bed_temp|int + 10}}"
],
"hot_plate_temp_initial_layer" : [
"{{settings_bed_temp|int + 10}}"
],
"textured_plate_temp_initial_layer" : [
"{{settings_bed_temp|int + 10}}"
],
"version": "2.1.1.0"
}
68 changes: 68 additions & 0 deletions templates-orcaslicer/ASA.json.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"_comment": "Generated by {{sm2s.name}} {{sm2s.version}}",
"default_filament_colour": [
"#{{color_hex}}"
],
"filament_cost": [
"{{price}}"
],
"filament_spool_weight": [
"{{spool_weight}}"
],
"filament_type": [
"{{material}}"
],
"filament_diameter": [
"{{diameter}}"
],
"filament_density": [
"{{density}}"
],
"filament_flow_ratio": [
"0.924"
],
"filament_settings_id": [
"{{id}}"
],
"filament_start_gcode": [
"SET_PRESSURE_ADVANCE ADVANCE={{extra.pressure_advance|default(0)|float}}\nASSERT_ACTIVE_FILAMENT ID={{id}}"
],
"filament_vendor": [
"{{vendor.name}}"
],
"from": "User",
"inherits": "Voron Generic ASA",
"is_custom_defined": "0",
"name": "{{name}}",
"nozzle_temperature": [
"{{settings_extruder_temp|int}}"
],
"nozzle_temperature_initial_layer": [
"{{settings_extruder_temp|int + 5}}"
],
"cool_plate_temp" : [
"{{settings_bed_temp|int}}"
],
"eng_plate_temp" : [
"{{settings_bed_temp|int}}"
],
"hot_plate_temp" : [
"{{settings_bed_temp|int}}"
],
"textured_plate_temp" : [
"{{settings_bed_temp|int}}"
],
"cool_plate_temp_initial_layer" : [
"{{settings_bed_temp|int + 10}}"
],
"eng_plate_temp_initial_layer" : [
"{{settings_bed_temp|int + 10}}"
],
"hot_plate_temp_initial_layer" : [
"{{settings_bed_temp|int + 10}}"
],
"textured_plate_temp_initial_layer" : [
"{{settings_bed_temp|int + 10}}"
],
"version": "2.1.1.0"
}
Loading
Loading