Joshua 38722e54e6
All checks were successful
Dev Build / build-test (pull_request) Successful in 1m29s
CUB-117: Port Moonraker + MQTT printer integrations to Go
- Moonraker REST client with GetPrinterInfo, GetPrintStats, GetPrintHistory
- Moonraker WebSocket client with auto-reconnect + telemetry parsing
- MQTT client via paho.mqtt.golang with TLS support for Bambu Lab
- Moonraker poller worker: background polling, dedup, usage logging to PostgreSQL
- MQTT subscriber worker: Bambu telemetry parsing, print job tracking
- Config: 7 new env vars (MOONRAKER_URL, MQTT_BROKER, etc.)
- main.go: per-printer worker discovery, graceful shutdown
2026-05-12 01:02:49 -04:00
2026-04-25 18:51:05 +00:00
2026-04-27 18:49:26 -04:00

Extrudex

Filament inventory and print tracking system for CubeCraft Creations.

Extrudex replaces Spoolman with a fully custom solution built for Joshua's 7-printer fleet. It tracks spool stock, per-print material consumption, and cost-of-goods — with a touch-optimized kiosk interface on a Raspberry Pi 5.


Tech Stack

Layer Technology
Backend ASP.NET Core Web API (.NET 8)
Database PostgreSQL (snake_case via EF Core)
ORM Entity Framework Core
Real-time SignalR (PrinterHub)
Printer integration Moonraker REST/WebSocket (Elegoo) · MQTTnet + TLS (Bambu Lab)
Frontend Angular 17+, Angular Material
Deployment Docker · Docker Compose

Project Structure

Extrudex/
├── backend/
│   ├── Domain/
│   │   ├── Base/                   # BaseEntity, AuditableEntity
│   │   ├── Entities/               # Spool, Printer, PrintJob, FilamentUsage,
│   │   │                           #   AmsUnit, AmsSlot, MaterialBase,
│   │   │                           #   MaterialFinish, MaterialModifier
│   │   ├── Enums/                  # ConnectionType, DataSource, JobStatus,
│   │   │                           #   PrinterStatus, PrinterType, QrResourceType
│   │   └── Interfaces/             # ICostPerPrintService, IFilamentUsageSyncService,
│   │                               #   IMoonrakerClient, IQrCodeService
│   ├── Infrastructure/
│   │   ├── Configuration/          # FilamentUsageSyncOptions
│   │   ├── Data/
│   │   │   ├── Configurations/     # EF Core fluent configs (snake_case)
│   │   │   ├── Migrations/         # EF migrations
│   │   │   ├── Seed/               # SeedData.cs
│   │   │   └── ExtrudexDbContext.cs
│   │   └── Services/               # CostPerPrintService, FilamentUsageSyncService,
│   │                               #   MoonrakerClient, QrCodeService
│   └── API/
│       ├── Controllers/            # Filaments, Spools, Printers, PrintJobs,
│       │                           #   MaterialBases, MaterialFinishes,
│       │                           #   MaterialModifiers, MaterialLookups,
│       │                           #   CostAnalysis, QR
│       ├── DTOs/                   # Request/response shapes per domain
│       ├── Filters/                # FluentValidationFilter
│       ├── Hubs/                   # PrinterHub, IPrinterClient
│       ├── Jobs/                   # FilamentUsageSyncJob (background)
│       ├── Validators/             # FluentValidation validators
│       ├── Program.cs
│       └── appsettings.json
├── frontend/
│   └── src/app/
│       ├── components/             # DashboardSummary, FilamentFilter, FilamentTable
│       ├── models/                 # Filament, Agent model types
│       └── app.routes.ts
├── design/                         # UX specs and mockups (kiosk + mobile)
├── docker-compose.dev.yml
├── deploy.sh
└── README.md

Domain Model

Materials (normalized taxonomy)

Entity Description
MaterialBase The base material type — PLA, PETG, ABS, ASA, TPU, etc.
MaterialFinish Required. Surface finish — Basic (default), Matte, Silk, Sparkle, etc.
MaterialModifier Optional. Composite fill — Carbon Fiber, Glass Fiber, Wood, etc.

Rules:

  • MaterialFinish is required — every spool must have one. Default is "Basic".
  • MaterialModifier is optional — plain PLA has no modifier.

Consumption calculation

grams_used = mm_extruded × filament_cross_section_area × material_density

Grams are always derived, never assumed from printer telemetry directly.

Printers

Type Integration
Bambu Lab (×5) MQTTnet with TLS
Elegoo Centauri Carbon Moonraker REST + WebSocket
Elegoo Saturn (resin ×2) Manual / future

AMS units and slots are modelled as AmsUnitAmsSlot[]Spool.


Key Design Decisions

  1. Spoolman rejected — Full custom system for data model control and workflow flexibility.
  2. "Basic" not "Standard" — Default MaterialFinish value is Basic.
  3. MaterialFinish is required — No null/optional finish state allowed.
  4. MaterialModifier is optional — Not every spool has a modifier.
  5. Derived consumption — Grams calculated from mm × density, never assumed.
  6. Push over poll — SignalR and MQTT preferred over periodic polling.
  7. Snake_case PostgreSQL — All database identifiers follow this convention via EF Core.

Getting Started

Prerequisites

  • .NET 8 SDK
  • Node.js 20+
  • Docker + Docker Compose
  • PostgreSQL (or use the dev compose stack)

Backend

cd backend

# Restore and build
dotnet restore
dotnet build

# Apply migrations
dotnet ef database update

# Run API (dev)
dotnet run --project API

API runs at http://localhost:5000 · Swagger at http://localhost:5000/swagger

Frontend

cd frontend
npm install
ng serve

Frontend runs at http://localhost:4200

Docker (dev stack)

docker-compose -f docker-compose.dev.yml up

Configuration

backend/appsettings.json — override in appsettings.Development.json or environment variables:

Key Default Description
ConnectionStrings:ExtrudexDb Host=localhost;... PostgreSQL connection string
FilamentUsageSync:PollingInterval 00:05:00 Sync job interval
FilamentUsageSync:RequestTimeout 00:00:30 Moonraker request timeout
FilamentUsageSync:Enabled true Enable/disable background sync

Real-Time Events

SignalR hub endpoint: /hubs/printer

Clients receive PrinterHub events for live printer status, job progress, and spool consumption updates.


API Overview

Route prefix Resource
/api/filaments Filament catalog
/api/spools Spool inventory
/api/printers Printer registry
/api/print-jobs Print job tracking
/api/material-bases Material base types
/api/material-finishes Material finishes
/api/material-modifiers Material modifiers
/api/material-lookups Combined material lookup
/api/cost-analysis Cost-per-print and COGS
/api/qr QR code generation

Full schema available at /swagger when running in dev.


CI

Gitea Actions pipeline (.gitea/workflows/dev.yml) runs on every push to dev:

  • dotnet build
  • Frontend ng build

Branch & PR Rules

  • All feature branches target devnever main
  • Branch naming: agent/<agent>/CUB-N-short-description
  • PR titles: CUB-N: short description
  • PRs require Otto review before Joshua merges

Built by CubeCraft Creations · Orchestrated by Otto

Description
No description provided
Readme 18 MiB
Languages
C# 82.2%
Go 10.1%
TypeScript 4.9%
PLpgSQL 2.3%
JavaScript 0.2%
Other 0.2%