Files
spoolman2/scripts/parse_temps_api.py
tonym e264d7ed4e
Some checks failed
CI / style (push) Has been cancelled
CI / build-client (push) Has been cancelled
CI / build-amd64 (push) Has been cancelled
CI / build-tester (push) Has been cancelled
CI / test (cockroachdb) (push) Has been cancelled
CI / test (mariadb) (push) Has been cancelled
CI / test (postgres) (push) Has been cancelled
CI / test (sqlite) (push) Has been cancelled
CI / build-arm64 (push) Has been cancelled
CI / build-armv7 (push) Has been cancelled
CI / publish-images (push) Has been cancelled
CI / publish-release (push) Has been cancelled
Add scripts to parse temps from comments
- parse_temps_api.py - Parse temps via API (for remote instances)
- parse_temps_from_comments.py - Parse temps via direct DB access

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 00:00:00 -06:00

179 lines
7.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""Parse temperature values from filament comments using the API."""
import re
import requests
import sys
def parse_temps_from_comment(comment: str) -> dict:
"""Parse extruder and bed temps from a comment string.
Patterns to match:
- "extrude 190-230" or "extruder 190-230" or "nozzle 190-230"
- "bed 50-70"
- "190-230 / 50-70" (extruder / bed)
- "190-230C" or "190-230°C"
- Single values like "extrude 210" → min=max=210
"""
result = {
"extruder_temp_min": None,
"extruder_temp_max": None,
"bed_temp_min": None,
"bed_temp_max": None,
}
if not comment:
return result
comment_lower = comment.lower()
# Pattern for temperature ranges: 190-230 or 190 - 230
temp_range_pattern = r"(\d{2,3})\s*[-]\s*(\d{2,3})"
# Pattern for single temp: 210
single_temp_pattern = r"(\d{2,3})"
# Try to find extruder temp (usually higher values, 150-300 range)
extruder_keywords = ["extrude", "extruder", "nozzle", "hotend", "hot end", "printing temp"]
for keyword in extruder_keywords:
if keyword in comment_lower:
# Find temp after keyword
idx = comment_lower.index(keyword)
search_area = comment[idx:idx+50] # Look in next 50 chars
# Try range first
match = re.search(temp_range_pattern, search_area)
if match:
result["extruder_temp_min"] = int(match.group(1))
result["extruder_temp_max"] = int(match.group(2))
break
# Try single value
match = re.search(single_temp_pattern, search_area[len(keyword):])
if match:
val = int(match.group(1))
if 150 <= val <= 350: # Reasonable extruder temp range
result["extruder_temp_min"] = val
result["extruder_temp_max"] = val
break
# Try to find bed temp (usually lower values, 30-120 range)
bed_keywords = ["bed", "plate", "build plate"]
for keyword in bed_keywords:
if keyword in comment_lower:
# Find temp after keyword
idx = comment_lower.index(keyword)
search_area = comment[idx:idx+40] # Look in next 40 chars
# Try range first
match = re.search(temp_range_pattern, search_area)
if match:
t1, t2 = int(match.group(1)), int(match.group(2))
# Validate: bed temps should be 30-120°C typically
if 30 <= t1 <= 120 and 30 <= t2 <= 120:
result["bed_temp_min"] = t1
result["bed_temp_max"] = t2
break
# Try single value
match = re.search(single_temp_pattern, search_area[len(keyword):])
if match:
val = int(match.group(1))
if 30 <= val <= 120: # Reasonable bed temp range
result["bed_temp_min"] = val
result["bed_temp_max"] = val
break
# If no keywords found, try to find generic temp pattern
# Format: "190-230 / 50-70" (extruder / bed separated by /)
if result["extruder_temp_min"] is None and "/" in comment:
parts = comment.split("/")
if len(parts) >= 2:
# First part might be extruder
match = re.search(temp_range_pattern, parts[0])
if match:
t1, t2 = int(match.group(1)), int(match.group(2))
if t1 > 100: # Likely extruder temp
result["extruder_temp_min"] = t1
result["extruder_temp_max"] = t2
# Second part might be bed
match = re.search(temp_range_pattern, parts[1])
if match:
t1, t2 = int(match.group(1)), int(match.group(2))
if t1 < 150: # Likely bed temp
result["bed_temp_min"] = t1
result["bed_temp_max"] = t2
return result
def main(api_url: str, dry_run: bool = True):
"""Main function to parse temps from comments."""
print(f"Connecting to: {api_url}")
# Get all filaments
response = requests.get(f"{api_url}/filament")
response.raise_for_status()
filaments = response.json()
print(f"\nFound {len(filaments)} filaments total")
updated_count = 0
for fil in filaments:
comment = fil.get("comment")
if not comment:
continue
parsed = parse_temps_from_comment(comment)
# Check if we found any temps
has_extruder = parsed["extruder_temp_min"] is not None
has_bed = parsed["bed_temp_min"] is not None
if has_extruder or has_bed:
print(f"\n--- Filament #{fil['id']}: {fil.get('name', 'unnamed')} ---")
print(f" Comment: {comment}")
print(f" Parsed extruder: {parsed['extruder_temp_min']}-{parsed['extruder_temp_max']} °C" if has_extruder else " No extruder temp found")
print(f" Parsed bed: {parsed['bed_temp_min']}-{parsed['bed_temp_max']} °C" if has_bed else " No bed temp found")
current_extruder_min = fil.get("settings_extruder_temp_min")
current_bed_min = fil.get("settings_bed_temp_min")
print(f" Current extruder: {current_extruder_min}-{fil.get('settings_extruder_temp_max')}" if current_extruder_min else " Current extruder: Not set")
print(f" Current bed: {current_bed_min}-{fil.get('settings_bed_temp_max')}" if current_bed_min else " Current bed: Not set")
if not dry_run:
update_data = {}
# Only update if not already set
if has_extruder and not current_extruder_min:
update_data["settings_extruder_temp_min"] = parsed["extruder_temp_min"]
update_data["settings_extruder_temp_max"] = parsed["extruder_temp_max"]
if has_bed and not current_bed_min:
update_data["settings_bed_temp_min"] = parsed["bed_temp_min"]
update_data["settings_bed_temp_max"] = parsed["bed_temp_max"]
# Clear comment after parsing
update_data["comment"] = ""
if update_data:
response = requests.patch(f"{api_url}/filament/{fil['id']}", json=update_data)
response.raise_for_status()
print(" → Updated and cleared comment")
updated_count += 1
if dry_run:
print(f"\n[DRY RUN] Would update {updated_count} filaments")
print("Run with --apply to actually make changes")
else:
print(f"\n✓ Updated {updated_count} filaments")
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Parse temps from filament comments via API")
parser.add_argument("--url", default="http://192.168.0.11:8000/api/v1", help="API URL (default: http://192.168.0.11:8000/api/v1)")
parser.add_argument("--apply", action="store_true", help="Actually apply changes (default is dry run)")
args = parser.parse_args()
main(api_url=args.url, dry_run=not args.apply)