Compare commits

..
Author SHA1 Message Date
grabowski 380629e382 Deploy site: publish to the registry only; the s1 steps go
Deploy test site / deploy (push) Successful in 28s
cnxvinyl.lol resolves to bkk01 since Nov 4, 2026 (cnx-network-clan PR #49),
which serves the releases from the B4L package registry. The SSH setup,
rsync and swap on s1 are removed; the URL check now waits up to two
minutes for bkk01 to fetch the new release. The VPS_* secrets are no
longer read, and the job token only reads the repository.
2026-11-04 10:12:46 +07:00
grabowski 9b0c7b42f5 Deploy site: publish to the registry before the s1 steps
Deploy test site / deploy (push) Failing after 1m34s
Run 73 could not reach s1 at all (ssh-keyscan failed three times, the
runner's address is probably banned there), and with the upload last
that held back bkk01's release too. Publishing comes first now; s1 keeps
getting the same build while it answers.
2026-11-04 09:51:10 +07:00
grabowski c8ffe42125 Deploy site: private ~/.ssh files on the runner
Deploy test site / deploy (push) Failing after 1m32s
Run 72 failed with "Bad owner or permissions on /root/.ssh/config" (a
loose umask or a reused HOME on the runner). Same fix as thaiai b59230e:
umask 077, a fresh config, chmod 600 on config and known_hosts.
2026-11-04 09:48:22 +07:00
grabowski 4728a821f2 Deploy site: also publish each build to the package registry for bkk01
Deploy test site / deploy (push) Failing after 20s
cnxvinyl.lol moves from s1 to bkk01 (cnx-network-clan, TODO section 18,
docs/src/s1-migration.md). After the rsync to s1 the job uploads
site/dist as site.tar.gz, generic package B4L/cnxvinyl.lol, version
<UTC time>-<commit>, as b4l-ci (organization secrets REGISTRY_USER and
REGISTRY_TOKEN); the package event makes bkk01 fetch it. s1 stays the
live server until DNS moves; then the SSH steps and VPS_* secrets go.
2026-11-04 09:45:08 +07:00
grabowski f39b175948 Investor deck: rewritten in the house style
Deploy test site / deploy (push) Successful in 26s
All visible English in docs/pitch/ is now literate American English in
whole sentences: slide headlines are plain statements that make the
slide's point (no "X, not Y" taglines such as "Ownership and control,
not a higher modelled return"), argument bullets became sentences,
"Read plainly:"/"unlocks" fragments are gone, and spelling, dates and
percentages follow American conventions ("labeled", "itemized",
"programs", "October 20, 2026", "60%").

Facts are unchanged: the style checker finds no number gone, added or
used fewer times; footers, Plan B/Plan A wording, sources and estimates
labels stay. Quoted doc section titles in the source lines keep their
original wording. Notes 109 to 120 words each.

Both PDFs regenerated (17 pages; dark 1.82 MB, light 2.01 MB).
deck_verify: 0 layout issues on 17 slides x 4 viewports x 2 themes,
charts, theme, navigation and presenter checks pass.
2026-10-28 11:56:59 +07:00
grabowski 22f04ee9a1 Plant assistant mockup: operator, management, sales
Deploy test site / deploy (push) Successful in 24s
docs/plant-assistant.html (test site /demos/plant-assistant/): the
plant assistant on vinyl-ai as three roles see it. Operator at the C1
press kiosk in Thai or English with push to talk (non-fill rejects
explained from cycle rows, lot change and press hall humidity, the
stamper change procedure quoted from the approved version, a lot on
hold, a refused price question, a safety question answered word for
word); management at a desk (output and yield per press against the
plan basis, steam per record against scale.md, orders at risk, the
weekly note, payroll refused); sales on a phone (order status and ship
window, repress feasibility from archived mothers and the standby
calendar, repress leads, a test pressing status, fans' addresses
refused). Each answer carries numbered sources; the side panel shows
the tool calls (ERPNext as the asker's role, the PostgreSQL replica,
VictoriaMetrics, documents, event log) on premises with the internet
not used; action buttons create drafts only. Deep links
#role=<role>&q=<id>, light and dark theme. Invented data; names match
the factory console demo.

plant-assistant.md: mockup link; sales and customer service row in
"Who asks what"; sales drafts (quotation, CRM opportunity, message).
README, site index and site/build.sh link and publish the page.
2026-10-27 09:50:42 +07:00
grabowski 3d9bb9af53 Own catalogue in a second company; models self-hosted on premises
Decisions (Alexander, 26 Oct 2026): a second company, not the plant
company, holds the catalogue; it owns and licenses titles; language
models are self-hosted on premises.

catalogue-intelligence.md reworked: the catalogue company is a customer
of the plant at arm's length (orders through intake and portal, the
plant's price list, standby pressing offered to every customer, no
moved dates, no data either way, metal in the archive on customer
terms; Revenue Code section 71 bis, 200M THB disclosure threshold per
the OECD profile), its own ERPNext site, the run-size rule on the
plant's price instead of its direct cost, its own advisor instance on
hardware it controls, phasing, cost borne by it, risks, open decisions
(shareholders and Poy Records, working capital, standby terms, where its
systems run).

Mirrors: README (planning bullet, project status), roadmap item 28,
digital-factory (tool rule, language-model row in the open-source
table), artist-platform (standby pressing proposal, pre-orders),
production-timeline, revenue-model, plant-assistant (self-hosted on
premises; catalogue data removed; advisor as a separate instance).
2026-10-27 09:38:32 +07:00
grabowski 15d28d2e0b Plant assistant: one agent management and operators can ask
New docs/plant-assistant.md (decision, Alexander, 26 Oct 2026): an
assistant for the whole plant, asked in Thai or English at kiosks, desks
and phones, answering from the knowledge base (SOPs as ERPNext Quality
Procedures, vendor manuals on the Assets, recipes and limits, this
repository, lessons learned) and from ERPNext and the machine-data store,
with sources on every answer. Roles and questions, what it does
(explain, trace, summarise, alert context, plan vs actual, drafts) and
never does (machines, submitting, safety improvisation, seeing more than
the asker, rating operators, needing the internet). Built on Typhoon 2.5
(open weights, Apache-2.0, CPU trial first), Typhoon ASR for optional
voice, pgvector retrieval, MCP tools in cnx-factory through the one
integration layer and the PostgreSQL replica; vinyl-ai GPU server only if
needed (~250k to 300k THB, RTX 5090 Thai retail Oct 2026). Test set per
role, phasing, cost, risks, open decisions.

Mirrors: digital-factory systems and machines tables, rough cost note;
catalogue advisor becomes a role of the assistant; worker-safety
training; roadmap item 18; README bullet and layout.
2026-10-27 09:33:25 +07:00
grabowski d36a6fdd02 Own catalogue: sales map, demand model and market advisor (plan)
New docs/catalogue-intelligence.md for Alexander's idea of a catalogue
the plant presses for itself. Why (idle Classic hours ~60k to 160k
records a year at 60 % specials on the doc basis; two-week represses
from the metal archive; Thai catalogue sells in Japan, EM Records,
ZudRangMa), scope (Poy Records as seed; customers' data and press dates
protected), data sources with access terms (Bandcamp ship-to fields,
distributor sell-through clauses, opt-in record passport registrations,
Spotify for Artists, Discogs CC0 dumps; Discogs API marketplace and
want data restricted), ERPNext touchpoints (Licence, Channel Sales
Report, Catalogue Recommendation, geocoded addresses, CRM), PDPA rules
for the map, dashboard views on an open-source map stack, a staged
demand model with a stocking rule for run size, a propose-only advisor
on an open-weights model, phasing, cost estimates, risks and open
decisions.

Backlinks: README (planning documents, layout), roadmap item 28,
digital-factory tool rule, artist-platform repress pre-orders,
production-timeline repress, revenue-model ResurRec Japan.
2026-10-27 09:28:51 +07:00
grabowski 793ea02c22 ResurRec Japan: demand in Japan and whether it serves all of Asia
Revenue model, ResurRec Japan section: RIAJ 2025 vinyl production
(3.38M records, 8.4bn yen, fifth year of growth), short domestic supply
(6 to 12 month lead times at Toyo Kasei and Sony per P-Vine, orders
placed abroad via brokers), the photographed presses at about a fifth of
Japan's volume on one shift. No published Asia-wide intent; the rest of
Asia has local plants, so Japan-from-Japan and SEA-from-Bangkok is our
reading. Consequence for CNX's ~0.74M regional demand (roadmap item 1).
2026-10-26 16:58:23 +07:00
grabowski 7fca116edb ResurRec Japan vs CNX launch plant: capacity table
Revenue model, ResurRec Japan section: 3 AD12s as photographed against
one Duplex system + one Classic on the scale.md basis (60 to 70 %
effectiveness, 300 days): ~1.6x per hour on black and solid colours,
one Japan shift matches CNX's two; specials comparison waits on the
AD12 splatter-mode rate; steam load about the same.
2026-10-26 16:38:27 +07:00
grabowski 39342f3a7e ResurRec Japan: press capacity of the three AD12s in the photo
Revenue model, ResurRec Japan section: ~2,000 to 2,500 records a day,
~0.6 to 0.76M a year on one shift, ~1.2 to 1.5M on two (Pheenix 24 to
26 s cycle, the table's 60 to 70 % effectiveness, 300 days), about CNX's
launch plant at 60 % specials. Black and solid colours only; splatter
runs semi-automatic on the AD12 with no published cycle time.
2026-10-26 16:35:43 +07:00
grabowski d968ee5b08 ResurRec Japan: photos of the new plant, presses read as new Pheenix AD12s
Four photos of ResurRec's new Japan plant (October 2026) filed in
docs/finance/resurrec-japan/. Revenue model gets a "ResurRec Japan"
section: what the photos show (visitor window, automatic presses in
aluminium cabinets that Alexander identifies as a new red AD12
generation, ceiling services, air-conditioned room, no plating in view),
what it changes (scaling abroad, Japan export wedge narrows, Classic vs
AD12 evidence, collaboration depends on their metal path) and open
questions. Also notes a directory listing naming an M-Tech Allegro II in
Bangkok against the tour's Newbilt Classic.

Mirrors: Pheenix sections in vendor-landscape, exhibitor questions and
supplier map; pressing-line AD12 paragraph; roadmap item 5; visitor
corridor in crane-workshop-tours; README status and layout.
2026-10-26 16:33:18 +07:00
grabowski f6829417a0 Test site: DNS moves to the fleet nameservers, no Cloudflare proxy
Deploy test site / deploy (push) Successful in 1m4s
cnxvinyl.lol's zone now lives in cnx-network-clan (ns1/ns2.cnx.network),
pointing straight at s1; mail is on mx1. Live once the nameservers at
Porkbun are switched.

- site/Caddyfile mirrors what s1 runs (checked 2026-10-23): no
  cloudflare_only or security_headers imports; Caddy gets its own certs.
- deploy-site.yml: drop the Cloudflare cache purge step and its secrets.
- site/README.md and digital-factory.md: DNS and certificate notes.
2026-10-23 11:01:55 +07:00
grabowski 1f532d0c85 All-equity funding: shareholders fund the whole plant
Deploy test site / deploy (push) Successful in 1m0s
User, 20 Oct 2026: the plan is that the shareholders fund the whole
plant and get shares for that (no bank loan).

- total-investment.md "Two plans": Funding paragraph: Plan B's ~217M
  THB paid in as share capital; the lead investor's 60 % at least ~130M,
  the 40 % at most ~87M (~121M / ~81M before the reserve; Plan A ~109M /
  ~73M); capital registered in full and called in instalments against
  the tranches; BOI's 3:1 met with no debt; nothing pledged.
- boi.md, README Project Status and the share-price bullet follow.
- Business plan A and B: the ask, the decisions, section 12.2 (funding
  bullet replaces the 3:1 equity floor), section 14 and the BOI
  requirements paragraph; "not in this plan" now names bank debt; both
  rebuilt (63 pages, checked).
- share-price.md re-based: 2,170,000 shares of 100 THB, the 40 % ~86.8M
  THB; illustrative calls 25/40/20/15 % against the tranches; premium
  rows on 217M; value per share once running with no debt (adverse 11 to
  42 THB, central 80 to 314, favourable 176 to 688 per 100 THB paid);
  VC method and CAPM recomputed; the calculator's ~22 % IRR is now the
  shareholders' pre-tax return (~18 % after tax, rough); missed-call
  rules (CCC 1120 to 1125); the levered case kept as "if a loan were
  added later".
- Deck: slide 12 (all equity, 60/40 bar ~130M / ~87M, none pledged,
  share capital called in instalments), slide 13 (re-based table, chart,
  premium cards, VC line), slide 17 (co-investor card, calls) and notes
  ("lenders" -> "investors"); both PDFs rebuilt; deck verify clean.
2026-10-20 17:17:18 +07:00
grabowski 1829dd2aec Share price for the 40 %: market-based ranges, deck slide 13
Deploy test site / deploy (push) Successful in 1m4s
User, 20 Oct 2026: add a page about possible share prices, do some
calculation on normal market data.

- docs/finance/share-price.md (new): market data with sources and
  dates (Damodaran January 2026 EV/EBITDA, P/E and betas for emerging
  markets and global; Thailand ERP 6.18 % (July 2026); ThaiBMA 10-year
  2.30 % (19 Oct 2026); illiquidity discount 20 to 35 %; venture target
  returns by stage; SET peers SCGP, TPAC, SITHAI, GRAMMY; Thai Civil and
  Commercial Code on par value and premiums).
- Results, all estimates: A founding round at par, pari passu: 542,500
  shares of 100 THB at Plan B's 54.25M equity floor, the 40 % ~21.7M
  THB; B a premium only for documented pre-round costs (102 to 137 THB);
  C value per share once running at ~163M THB debt: adverse ~0, central
  126 to 1,016 THB, favourable 508 to 2,512 THB; D a financial investor
  today 18 to 236 THB (central); E calculator cross-check. Recommendation:
  par for the founding round; pre-emption and information rights for the
  40 %.
- Deck: new slide 13 "Share price: what the 40 % could cost" in both
  themes, with notes; the ask slide points to it; 17 slides, both PDFs
  rebuilt; site slide notes trimmed.
- README bullet, layout line and Project Status link; total-investment
  shareholding paragraph links the page.
2026-10-20 15:13:47 +07:00
grabowski 967e6b1c76 Payap still an option: rezoning route; order example opaque
Deploy test site / deploy (push) Successful in 2m40s
User, 20 Oct 2026: Payap University claims they can rezone the land;
update the deck to show it is still an option. And: do not use a
transparent vinyl as the example in the order tool screenshot.

- land-listings/payap/rezoning-2026-10-20.md (new): what a rezoning is
  under the Town Planning Act B.E. 2562 (section 35 amendment started by
  DPT or the local official, Town Planning Commission, 30-day posting
  with objections, Ministry of Interior notification via Cabinet and the
  Royal Gazette; a landowner can ask, not rezone), the DPT's own work
  plan (~70 weeks without objections, ~82 with: ~16 to 19 months), the
  schedule effect (roughly a year on first production unless the request
  starts now; estimate) and what to ask Payap. DPT procedure PDF filed.
- site-candidates.md: Payap "still an option" in the table, rezoning
  paragraph with an Open action, check 1 and the re-siting rule; zoning
  record, payap-partnership.md and README point to it.
- Business plan 6.1, risk table and critical path: Payap's rezoning
  claim and its ~16 to 19 months; A and B rebuilt (63 pages, checked).
- Deck: site slide names Payap as an option once rezoned, notes and
  source line; risk row updated.
- order.html: the "Splatter 12"" preset now has a white base instead of
  clear; deck platform screenshots re-shot in both themes (numbers
  unchanged: 100 fans, break-even 46, ~480 THB kept). Order checks 96/96,
  fan parity 206/206; deck verify clean in both themes, PDFs rebuilt.
2026-10-20 14:58:40 +07:00
grabowski 744a56d22b Order tool: fan funding; deck: light and dark, 60/40 shareholding
Deploy test site / deploy (push) Successful in 1m2s
User, 20 Oct 2026: can the deck also be made in a light and dark mode;
the new order tool should also offer fan funding, so the platform
screenshots match and use the same calculator; the main investor holds
at least 60 %, so 40 % is for sale.

Order tool (docs/order.html, /demos/order/):
- New step 15 "How to pay": pay the plant directly (deposit) or let
  fans fund it; step 16 becomes "Review & launch" with the campaign
  simulation and its three outcomes.
- Campaign maths ported from make-a-record (fan price, length, cap, own
  copies, VAT; fans needed = max(100, break-even); keep at the goal and
  with more fans; price hint); R gains fee (3.5 %), VAT and campaign
  length with sources; no price changed.
- Quote card shows fan price, fans needed and the artist's keep on the
  fan route; route and campaign in the #q= hash; deep links
  #s=<step>&p=<preset>&route=fans.
- Parity with make-a-record: 206/206 checks over 40 configurations;
  default quotes unchanged (37,836 / 217 / 102,936 THB; partner
  mastering 43,676).

Investor deck (docs/pitch/):
- Light and dark theme like the other site pages (cnx-theme, T key and
  button), presenter and overview follow; charts from CSS variables;
  text pairs at WCAG AA in both themes; tool screenshots in both themes.
- Two PDFs: dark and light (print-friendly), each ~1.5 MB.
- Platform slide: both pictures from the order tool (Splatter 12" order
  step and its fan-funding view: 100 fans at 1,200 THB, break-even 46,
  ~480 THB a copy kept).
- BOI and financing slide: shareholding bar, lead investor at least 60 %,
  at most 40 % for co-investors (~32M / ~22M THB at the ~54M equity
  floor, arithmetic only); the ask offers up to 40 %.

Docs: artist-platform.md (fan funding in the order tool), README and
landing page entries.
2026-10-20 14:31:40 +07:00
grabowski c8307f9d5e Shareholding: main investor holds at least 60 %, 40 % for sale
User, 20 Oct 2026: the main investor W wants to hold at least 60 % of
the company (the BOI-promoted company), so only 40 % is for sale.

- total-investment.md "Two plans": the 60/40 rule; Ploy Printing's
  stake, founders' shares and any further co-investor come out of the
  40 %; at Plan B's ~54M THB equity floor (3:1) and one share price
  that is at least ~32M / at most ~22M THB (arithmetic only; share
  price, valuation and in-kind shares not agreed).
- README Project Status and boi.md (foreign-ownership privilege) point
  to it.
- Business plan: section 12.2 states the split (A: ~28M / ~18M, B:
  ~32M / ~22M at the equity floor, arithmetic), the co-investment bullet
  and the decisions list name the 40 %; A and B rebuilt (63 pages each,
  TOC and em-dash check clean).
2026-10-20 13:52:33 +07:00
grabowski 81de64c8a1 Investor deck rebuilt around Plan B (16 slides)
Deploy test site / deploy (push) Successful in 59s
User, 19 Oct 2026: build the deck again but focus on Plan B, the main
investor wants to go with that.

- Proposes Plan B, ~217M THB at the midpoint (~6.56M USD), labelled
  ~215M; Plan A (~182M) only as the comparison. Every running footer,
  source line and speaker note now presents Plan B.
- New slide 9 "Why Plan B": ownership and control, not a higher
  modelled return (owned roof PV and battery instead of a PPA, full
  metrology from the first release, corridor and tours from day one,
  cassette and CD-R, bought crane, Thai utilities; ~34.5M THB together);
  Plan A has the better modelled return, owning the array earns no BOI
  tax benefit.
- Investment by block for Plan B with low-high ranges, the "what Plan B
  buys" table, no contingency (~30M at 15 %); operating picture, cash
  curve (payback ~4.2, IRR ~22 %, NPV ~4.7M USD) and BOI slide (equity
  at least ~54M THB at 3:1, owned PV and battery as collateral) for B;
  B-specific risks; the ask with the Plan B tranches only.
- Plan B renders replace the Plan A ones; PDF regenerated, 16 pages,
  1.5 MB.
- README and landing page entries say 16 slides and Plan B.
- Checks: every slide at 1920/1440/1280/390 px without overflow,
  navigation and presenter sync, PDF pages and text, no em dashes.
2026-10-20 13:45:30 +07:00
grabowski 995bb4ba60 Plan B chosen; stale mirrors fixed; business plan rebuilt
User, 19 Oct 2026: the main investor wants to go with Plan B; fix the
stale docs the deck build found.

- total-investment.md "Two plans" and README: the main investor wants
  Plan B (~217M THB, labelled ~215M); Plan A stays as the comparison.
- boi.md: duty without BOI on the launch plant's ~2.3M USD of imported
  machinery (~0.11M duty, ~0.17M import VAT), as total-investment states;
  the calculator's ~2.5M includes the water treatment; the old ~2.75M
  was the superseded start fleet.
- roadmap.md item 2: the BOI application stacks automation, R&D and the
  battery if it qualifies; solar lost promotion on 1 July 2025.
- project-timeline.md: October re-read note (launch plant with
  galvanics commissioned first, long lease of raw land, Plan B price;
  calendar not redrawn); galvanics rows no longer "Phase 5".
- revenue-model.md: blended price at 60 % specials ~124 to 174 THB
  (3.76 to 5.27 USD), the Thai gap "three to six times".
- site-candidates.md, scale.md: utility yard with air-cooled chillers,
  no cooling tower; electroplating permission needed from the start.
- Business plan: working capital 4.5M to 9.6M THB (as total-investment);
  A and B docx and PDF rebuilt (63 pages each, TOC checked).
2026-10-20 13:26:28 +07:00
grabowski 40c049ae15 Investor deck: 15 web slides with presenter view, plus PDF
Deploy test site / deploy (push) Successful in 55s
User, 19 Oct 2026: build a high-end investor pitch deck; the whole
plant, web slides on the test site with presenter mode plus a PDF,
12 to 15 slides, both plans, for a BOI / bank / institutional reader.

- docs/pitch/index.html (site /pitch/): title, opportunity, the chain
  under one roof, how a record is made (9 stages, 3 gates, traceability,
  ERPNext), platform, site and building, sustainability and region,
  investment A vs B by block with the six levers (no contingency in
  either price), operating picture with the adverse case, ten-year cash
  and returns (calculator presets), BOI promotion and the 3:1
  debt-to-equity condition (financing structure to be agreed), schedule,
  risks, team and vendors, the ask (phase 0 then tranches).
- Every figure carries a source line (business plans draft 0.3 and the
  owning docs); speaker notes per slide; P opens a synced presenter
  window, O the overview, F fullscreen, #n deep links.
- img/: six WebP pictures (calculator renders, order tool, fan funding,
  record passport); CNX-Vinyl-Investor-Deck.pdf, 15 pages 16:9, images
  re-encoded to 1.5 MB.
- site/build.sh copies docs/pitch/ to /pitch/ (new DIRS list); the
  deploy also triggers on docs/pitch/**; landing page and README entries.
- Checks: 15 slides at 1920/1440/1280/390 px without overflow, navigation,
  presenter sync both ways, PDF pages and text, no em dashes.
2026-10-19 17:35:34 +07:00
grabowski 7d6a47e6d0 Order tool v2: step-by-step configurator after mobineko.com/order
Deploy test site / deploy (push) Successful in 51s
User, 19 Oct 2026: build a new version of the order tool like
mobineko.com/order; it should also offer selectable mastering like
brandenburgmastering.com at 60 USD a track.

- New docs/order.html (site /demos/order/): 15-step rail, step panel,
  large live SVG record (colour per disc, translucent, split, splatter,
  marble, colour-in-colour; label, dead wax, jacket view), floating
  quote card with price, ship window and quantity; phone strip and
  bottom bar. Review lists what is missing, itemised quote with basis
  badges, deposit, lead time, ERPNext touchpoints on the simulated
  order. Disabled-not-hidden options with reasons.
- Mastering choice: none, in-house vinyl mastering (5,000 THB a side,
  default), or partner studio (Brandenburg Mastering, Amsterdam, example,
  not contracted) at 60 USD a track (team figure), replacing the in-house
  line.
- Same R list and quote() as artist-order: defaults reproduce 37,836 THB
  per title and the per-copy figures; new lines (repress stamper,
  colour effects, printed inner, finish, obi, bag, shipping) are
  estimates.
- artist-platform.md: the page and the mastering choice; README, landing
  page and site/build.sh entries.
- Checks: pw_order.py 96 checks (parity, partner mastering, 15 steps at
  1440/1024/768/390 dark and light, disabled force-clicks, render sizes
  and fills, uploads, audio readers, share link, place order).
2026-10-19 14:21:11 +07:00
grabowski 69f8392a23 Optical QC: plate every 5 records, how plates avoid scratching
User, 19 Oct 2026: one plate every 5 records; how do we make sure the
plates don't scratch the records.

- Plate every 5 (10 per 50-record stack, ~15 kg a stack).
- Scratch rules: groove-guard profile keeps grooves off the plate (QRP);
  plate flat, larger than the record (306 to 310 mm), deburred; clear
  anodised (cost estimate, CNY 16 to 28/m2 China reference); vertical
  handling only; no grit (trimmer extraction, ionised blow-off and wipe
  on return, covered carts and racks); numbered plates, monthly check;
  station compares scratches on plate faces vs record faces.
- About 700 plates for a 24 h queue (25 sheets, THB 245k to 315k cut,
  + 35k to 105k anodising, estimates); 200 to 260 for 8 h.
- Plate trial adds bare vs anodised and the scratch comparison.
2026-10-19 12:37:28 +07:00
grabowski 5bdb013449 Optical QC: stacks of 50, aluminium cooling plates cut locally
User, 19 Oct 2026: stack records with spacers; the plates are aluminium
and should be cut locally.

- Where it sits: 50 records a stack (Cascade), a flat aluminium plate
  every 10 records to start (MY45; Mobineko uses one per record; the
  Classic handles plates itself), full discs not ring spacers.
- Plates: 5052 (5083 if anodised), 3 mm, diameter and hole to Newbilt's
  drawing; 28 per 1220 x 2440 sheet, sheet about THB 8,300 ex VAT
  (OneStockHome, 3003), THB 350 to 450 a plate cut and deburred
  (estimate); fibre laser or waterjet, Chiang Mai shops listed; deburred,
  flatness check, kept clean. About 350 plates for a 24 h queue
  (THB 120k to 160k), 100 to 130 for 8 h.
- Spiral cooling tower considered and not taken (full queue USD 75k to
  120k for 8 h, dust, no stack weight); a 30 to 60 min spiral stays a
  later option.
- Next steps: Newbilt plate drawing; new plate and settling trial
  (plate every 5/10/25, warp at 1 h and 24 h).
2026-10-19 12:35:48 +07:00
grabowski c939ba1fbb Optical QC control: QiTech Control library and shop
User, 19 Oct 2026: check github.com/qitechgmbh/control and
shop.qitech.de/collections/ethercat.

- QiTech Control (LGPL-3.0, Rust on an EtherCrab fork, NixOS, runs
  QiTech's own machines): plan now uses its EtherCAT library qitech_lib,
  pinned, as the layer under our station service; not the full Electron
  app. It has DC SYNC0, SDO/PDO handling, EK1100/EL2809/EL3021/EL3024
  drivers and a CiA402 MINAS A6 servo driver to copy for the A6-EC.
  Drivers to write: EK1101, EL1809, EL3152, EL5101, A6-EC (upstream).
  Kernel: start from QiTech's tested settings (6.18, preempt=full,
  isolcpus 2,3); 6.12 PREEMPT_RT stays the fallback for IgH.
- QiTech shop (new Beckhoff stock from an insolvency, ships worldwide):
  EK1101 EUR 85.13, EL1809 EUR 16.53, EL2809 EUR 41.03, EL9011 EUR 1.76
  replace the geizhals offers, EUR 207.57 less. TwinSAFE and Beckhoff
  STO servo terminals noted, not taken.
- EtherCAT parts EUR 1,684 to 1,897 + 2 servo kits (THB 72k to 80k);
  bench parts about THB 56k; spare coupler/DI/DO now stocked.
- BOM total USD 16,671 to 32,681 (THB 0.55M to 1.08M).
2026-10-19 10:54:31 +07:00
grabowski face699a28 Optical QC: EtherCAT control plan with geizhals.de prices
Deploy test site / deploy (push) Successful in 57s
User, 19 Oct 2026: plan the current EtherCAT setup, keep the 100 W servo,
check prices on geizhals.de.

- New docs/equipment/inline-qc-control-plan.md: decisions, bus layout
  (drives at the end of the line because the A6-200EC takes control
  power from the main supply), I/O list for EL1809/EL2809/EL3152/EL5101
  and the drive touch probe, PDO and DC notes from the A6-EC manual,
  geizhals.de price table (EUR 1,891.60 to 2,104.39 + USD 246.58 for the
  servo kits, THB 80k to 88k), NixOS/EtherCrab software, safety circuit
  (PNOZ s3, two contactors, dump valve), bench test with pass marks
  (parts about THB 64k, all reused), build order, spares, open points.
- EL3102 replaced by EL3152: the optoNCDT 1420 output is 4 to 20 mA.
- Spindle encoder index goes to an EL5101 instead of the drive touch
  probe; encoder 2,000 to 2,500 pulses.
- BOM: control lines split per part with geizhals.de prices (+30% high
  end for shipping and Thai duty/VAT, estimate); total USD 16,912 to
  33,061 (THB 0.56M to 1.09M). Doc, render caption and fleet calculator
  text now say USD 17k to 33k.
- README links the plan.
2026-10-19 10:43:59 +07:00
grabowski d26ed7ab3c Optical QC: STO servo version looked at, stay with 100 W
User, 18 Oct 2026, asked about the A6-EC400H2B1-M17-STO (400 W, STO,
brake, USD 157.91). STO comes only from 400 W; its manual gives no SIL
or PL and no certificate, so it cannot replace the contactor; the brake
holds nothing on a horizontal axis. Recommendation recorded: keep the
100 W kit; if a rated STO is confirmed in writing, take the brake-less
A6-EC400H2A1-M17-STO (USD 129.60) on both axes, 1:2 to 1:3 belt, no
contactor.
2026-10-19 10:24:54 +07:00
grabowski ba1f5fc3a9 Optical QC: EtherCAT control
User, 18 Oct 2026: use an EtherCAT based system.

- Spindle and conveyor on the StepperOnline A6-EC100L2A1-M17 kit
  (100 W, A6-200EC drive, USD 123.29), spindle through a 1:6 belt in
  cyclic synchronous position, conveyor in cyclic synchronous velocity.
- The A6-EC drive has no divided encoder output, so an RS-422
  incremental encoder on the spindle shaft clocks both line-scans; its
  index goes to the drive touch probe for one angle reference.
- Station controller: fanless N100 mini PC with 2x Intel i226, NixOS
  PREEMPT_RT, EtherCAT master EtherCrab (Rust, MIT/Apache) first, IgH
  (nixpkgs, igc native driver on 6.12 LTS) as fallback; no PLC.
- EtherCAT I/O: EK1100, EL1809, EL2809, EL3102 (warp lasers sampled with
  the spindle position, ~1,000 points a turn at 1 ms).
- Safety stays hardwired (safety relay, contactor; no STO at 100 W).
- Edge PC with the GPU stays off the real-time loop.
- BOM: drives, encoder, controller and I/O lines with sources; total
  USD 16,112 to 32,938 (THB 0.53M to 1.09M). Next step: EtherCAT bench.
- Investor render: cabinet and outfeed labels.
2026-10-19 10:15:54 +07:00
grabowski cf900cf3a4 Optical QC: spindle servo, 100 W StepperOnline A6-RS kit
User, 18 Oct 2026, asked about the StepperOnline A6-EC100L2A1-M17
(100 W EtherCAT kit).

- The motor fits: torque about 0.02 N m needed at the motor through a
  1:6 belt (0.32 rated); the belt brings the load inertia (about 25 to
  35 kg cm2, estimate; record 20.5) to about 28x the 0.03 kg cm2 rotor.
- Take the pulse/RS-485 twin A6-RS100L2A1-M17 (USD 108.78): its drive
  outputs the encoder as divided A/B/Z pulses for the line-scans and
  takes pulse/direction from the planned PLC. The EtherCAT drive has no
  divided output (A6-EC manual, CN1: 5 DI, 3 DO) and needs an EtherCAT
  master.
- inline-optical-qc.md: spindle servo paragraph, sensor table, BOM
  group; BOM line 109 to 250 (was 300 to 700). Total USD 16,073 to
  32,734, THB 0.53M to 1.08M.
2026-10-19 10:01:40 +07:00
grabowski 9d8a1a1fb8 Optical QC: sensor list
User, 18 Oct 2026: list the sensors the optical QC station uses.

- inline-optical-qc.md: sensor table in the station setup (4 cameras,
  2 warp lasers, spindle encoder, 3 presence sensors and a through-beam,
  6 cylinder position switches, door switch; thermal camera option and
  laser line profiler alternative), with where each sits, what it
  measures and the price signal.
- BOM: cylinder position switches were missing (6, SMC D-M9 class,
  USD 25 to 60 each, estimate). Total now USD 16,264 to 33,184, still
  16k to 33k; THB 0.54M to 1.10M.
2026-10-19 09:46:10 +07:00
grabowski 8c2143630c Optical QC: one station for both presses, after the cooling racks
Deploy test site / deploy (push) Successful in 55s
User, 18 Oct 2026: for now one QC station for both machines; let the
records cool in a queue before testing them.

- inline-optical-qc.md "Where it sits": launch setup. Spindle stacks
  from the Duplex system and the Classic, labelled at the press (press,
  stamper set, first and last cycle), cool in FIFO racks (24 h accepted
  practice, 8 h at the shortest, Stamper Discs; about one day of output,
  2,800 to 3,100 records); the finishing operator feeds the station from
  the cooled stacks. Gains: warp and centring measured on settled records
  (the release value), one station instead of two, no Classic unloader
  change, no warm-record sag or thermal camera. Cost: defects found hours
  later, covered by the Duplex operator, per-cycle telemetry and an early
  lane for the first records of each run and after stamper changes.
  Record key from the stack label and stack position, checked against the
  run-out stamper number. Capacity 10 to 12 a minute against 5 to 6:
  one station to about two Duplex systems and two Classics. A station at
  each press stays the later option. Cost table, open points, infeed row,
  thermal camera note and the Newbilt question follow.
- Fleet calculator: the per-press stations and the release station are
  gone; the finishing block shows the cooling racks with record stacks
  and the one optical station by the corridor glass; tooltips, corridor
  and conveyor texts; machine park back to its legend, finishing box
  "cooling, QC, packing".
- quality-automation.md layer 1, digital-factory.md QC row,
  process-flow.md stage 6, site-candidates.md block ground floor,
  crane-workshop-tours.md tour stop 6.
- Investor render: infeed label "the operator sets each cooled record
  down".

Checks: node --check; pw_bp_calc.py 0 fails; pw_iso_view_check.py OK;
info for every data-id at all presets, levels and rotations; GF nodes
2,414 at the full preset; zoomed shots in two rotations.
2026-10-18 15:18:00 +07:00
grabowski 9ffcfe62f1 Plant view: inline optical QC station at every press
Deploy test site / deploy (push) Successful in 58s
User, 18 Oct 2026: add the new inline inspection machine to the factory.

- Fleet calculator, isometric plant view: qcStation() draws the concept
  station (1.9 x 0.65 x 1.5 m: aluminium conveyor table with the two rim
  belts, light-tight tunnel, stack light, record on the infeed, reject
  bin) in front of the operator in every Duplex cell (after the trimmer)
  and at the unload side of every Classic, in the hall and in phase 2;
  own ids qc-duplex-n / qc-classic-n with tooltips from
  inline-optical-qc.md (Classic hand-off open with Newbilt). Cell floor
  extended to take the bin.
- The finishing block's end-of-line optical station becomes the release
  inspection: the same station measuring cooled samples (records settle
  ~24 h); corridor, block and conveyor tooltips reworded.
- Machine park schematic: a QC bar in every Duplex cell and Classic, an
  "inline QC" legend entry; the legend moved to the bottom of the hall
  box (it collided with the hall heading).
- Docs: inline-optical-qc.md (release station location, plant view),
  site-candidates.md block ground floor, crane-workshop-tours.md tour
  stop 6.

Checks: node --check on all scripts; pw_bp_calc.py 0 fails;
pw_iso_view_check.py OK; every data-id has info at all presets, levels
and rotations; legend clear of cells and heading up to 30M records;
zoomed shots in both themes and two rotations. GF node count at the full
preset 2,523 (was 2,388), 8M records ~2,980; rebuild under 60 ms.
2026-10-18 14:56:08 +07:00
grabowski 705690eb99 Fleet calculator: plant view starts from the front, drag pans at any zoom
Deploy test site / deploy (push) Successful in 55s
User, 18 Oct 2026: show the factory from the front at start, and make the
view movable always, not only after the first zoom.

- CNXIso default rotation 1 (from the south-west: office, car park and
  gate face the viewer) instead of 3; documented setRotation in the
  header. The business plan renders pin setRotation(1) already.
- Drag pans at fit as well (was only when zoomed in); grab cursor at
  every zoom, grabbing while dragging. On touch screens the fitted view
  keeps vertical swipes for page scrolling (touch-action pan-y), so a
  horizontal drag pans; once zoomed in every direction pans, as before.
2026-10-18 14:24:54 +07:00
grabowski e8674795f5 Inline QC station: real 40x40 profiles, labelled investor render
User, 18 Oct 2026: use real 40x40 profiles, make a render with text
pointing out the parts to show the investor; the ring lights looked
like they were floating.

- build_station.py: frame drawn from the real 8-slot 40 series section
  (profile_shape: slots, centre bore, corner cavities; 40x80 with centre
  cavity) and 24 cast angle brackets; top beams now butt between the
  uprights; label-camera posts moved beside the cameras so both ring
  lights clamp straight to them; top line-scan on a side post with
  visible camera plate and light hangers; slide strips on carrier angles,
  pulley axles, end-stop posts, presence-sensor brackets, backlight post,
  cabinet on base crosses, chute on two supports and clear of the rail,
  pneumatics rail, stack light on the back upright, touch screen on the
  front end upright. A connectivity check at the end lists any part that
  does not reach the floor through touching parts: none.
- render_annotated.py (FreeCAD): front three-quarter view, camera backed
  off so nothing is clipped, no navigation cube or preselection, label
  positions projected from the camera and checked with marker renders.
- annotate_render.py (Pillow): title, 16 labels in two columns, leaders
  assigned so none cross -> inline-qc-station-annotated.png.
- render_station.py: same camera and preselection fixes; all six views
  re-rendered.
- BOM: 32 m of 40x40 in 45 pieces; total still USD 16k to 33k.
- inline-optical-qc.md and README updated; .gitignore for the render
  intermediates.
2026-10-18 14:07:41 +07:00
grabowski 609424b598 Inline QC station: concept setup on an aluminium profile frame
User, 18 Oct 2026: create a setup for the inline optical QC, an
aluminium extrusion frame with all sensors and a conveyor mounted to it.

- docs/equipment/inline-qc-station/: FreeCAD script (build_station.py)
  and model (.FCStd) of one station, 1.9 x 0.65 x 1.5 m on 27 m of
  40x40 and 3.8 m of 40x80 profile: rim-belt conveyor (two 6 mm PU round
  belts under the unrecorded rim, open centre), label gate with top and
  bottom colour cameras on the fly, inspection position with a lift and
  rotate chuck (75 mm lift, expanding mandrel, belt-driven servo), top and
  bottom 4k line-scans on opposite radii with coaxial, dark-field and
  backlights, two warp lasers, optional thermal camera, light-tight black
  tunnel with door switch, rodless-cylinder reject pusher with chute and
  bin, outfeed stop, cabinet, PLC, NixOS edge PC, HMI, stack light.
- render_station.py renders six views (open and closed iso, front, plan,
  inspection detail and elevation via clipped temporary documents).
- inline-qc-station-bom.csv: 32 lines with sources; USD 16k to 33k per
  station without the thermal camera.
- inline-optical-qc.md: new section "The station setup" (flow table,
  inspection zone, cycle ~5 to 6 s, control, BOM by group, open points);
  cost table updated (two launch stations ~USD 50k to 105k, still inside
  the metrology launch tier); Duplex/Classic flow now via the conveyor.
- README bullet and tree.
2026-10-18 13:29:55 +07:00
grabowski 5207808b57 Inline optical QC: devices for the record inspection station
User, 17 Oct 2026: research on the inline QC equipment, which devices
can be used for the optical check.

- New docs/equipment/inline-optical-qc.md: defect-by-defect table with
  the optical signature, device and limit (IEC 98 / DIN 45547 hole and
  eccentricity, Stamper Discs targets, Mobineko warp limits), precedents
  (no vinyl product; Dr. Schenk ISM CD scanner as template; Basler/Xiris;
  PRP AQA 2023; CTU thesis), a station design (centring turntable, 4k
  line-scan per side with dark-field, bright-field and transmitted light,
  colour label camera, two laser warp sensors or a line profiler,
  optional thermal camera) with sourced price signals, resolution and
  eccentricity math, throughput, placement at the Duplex cell and the
  Classic, smart-camera vs open GenICam/Aravis/OpenCV/anomalib on NixOS,
  specials, Thai channels, next steps.
- Estimate USD 12k-30k hardware per station, ~USD 40k-100k for the two
  launch stations; inside the existing metrology launch tier, no plan
  price change.
- Backlinks: quality-automation.md layer 1, digital-factory.md QC
  integration row, README bullet and tree.
2026-10-17 23:47:12 +07:00
grabowski 984ced2485 Biomass steam in both plans, PV on the factory roof only
Deploy test site / deploy (push) Successful in 49s
User, 17 Oct 2026: "only put solar on the factory, prepare the other
buildings for solar, option a and b should operate on biomass".

- Steam: two 500 kg/h biomass modules (Getabec class, 6M to 10M THB) plus
  a fuel store and handling block (1M to 2M, estimate) in both plans; the
  electric bank becomes the alternative. ~0.67M THB of fuel a year against
  ~4.9M for electric steam; grid demand ~264 kW instead of ~980 kW.
- Solar: ~520 kWp on the factory roof (the biomass-case optimum is ~500 to
  550 kWp, hourly sketch in sustainability.md "PV size with biomass
  steam"); office roof and parking canopies built PV-ready (~120 kWp
  later). ~87 % used on site, ~61 % of the plant's electricity.
- Calculator: biomass default, bFuel row, pvKWp 520, pvSelf 87, iso fills
  the factory roof first and shows the other roofs as PV-ready.
- Numbers: launch plant ~168M / 232M / 296M with contingency; Plan A
  ~182M (~2M above 180M: the Chinese-route lever priced only electric
  boilers; a Chinese biomass quote is the way back), Plan B ~217M (label
  ~215M), ~35M more. Calculator EBITDA A 2.17M, B 2.23M USD.
- CSV, total-investment, revenue-model, sustainability, scale, biomass,
  site-candidates, boi, steam-cooling, construction RFQ (canopies
  PV-ready), README, roadmap; business plan draft 0.3 rebuilt (A and B
  63 pages) with new renders.
2026-10-17 20:24:55 +07:00
grabowski 9ff5feef11 Solar on every roof, BOI solar correction, open source section
Deploy test site / deploy (push) Successful in 54s
Solar (user, 17 Oct 2026: "use as much roof space as possible")
- PV on every roof and canopy: ~640 kWp on the Payap scenario plot
  (factory roof ~523, canopies ~54, flat office roof ~65 kWp around the
  AC units); ~300 kWp on the Mueang Chi hall. Calculator: pvKWp 640,
  new pvSelf 85 % (zero export, hourly sketch), PV cost per kWp times the
  array, office-roof PV in the iso view, roofs drawn full.
- 12.8M to 16.6M THB at 20 to 26 THB/W; CSV baseline 34.37M to 56.34M;
  launch plant ~168M / 231M / 294M THB with contingency; Plan B ~216M
  (label ~215M), ~39M above Plan A; Plan A unchanged (it leases the
  array), its solar lever ~17.5M. PV payback ~4.2 to 5.9 years.
- Permits (rooftop solar no factory licence since 28 Dec 2024, ERC
  exemption under 1,000 kVA, PEA zero export) and PPA discounts sourced
  in sustainability.md.

BOI correction
- Announcement 3/2568 (in force 1 July 2025) ended BOI promotion for
  solar installations; only the battery may qualify (12M THB per MW cap).
  Removed the "BOI solar measure" from boi.md, total-investment,
  revenue-model, sustainability, site-candidates and both plan versions;
  Plan B's case for owning the array is the PPA bill it avoids
  (~0.07M USD a year).

Open source (user, 17 Oct 2026)
- digital-factory.md "Open source throughout, and working with other
  plants": everything we run and build is open source on NixOS, our code
  published (licence to decide), vendor firmware the stated exception;
  later the stack and factory-automation services for other pressing
  plants, not in the revenue.
- Business plan section 5.6 plus an executive-summary bullet, reading
  guide and not-modelled mentions; draft 0.3 rebuilt (A 60, B 61 pages),
  renders re-made with the roofs full.
2026-10-17 17:22:57 +07:00
grabowski ab303618d8 Solar and battery re-priced from Thai market data (October 2026)
Deploy test site / deploy (push) Successful in 46s
- Rooftop PV, 300 kWp (size still illustrative): 20 to 26 THB/W installed
  with the Deye hybrid inverters, 6.0M to 7.8M THB (was 25 to 35 THB/W,
  7.5M to 10.5M). Sources in the utilities CSV: DEDE Thailand PV Status
  report (Mahidol survey: 22 to 25 THB/W for factory systems of 10 kW to
  1 MW, 2023), CapSolar 2026 (20 to 25 under 1 MWp), Saimai Solar's list
  (300 kW for 5.4M THB), Deye hybrid inverter retail (160,500 THB per
  50 kW).
- Battery 271 kWh, now installed: 2.0M to 3.5M THB (was the bare Gobel
  list price, 1.4M to 2.0M, which matches DEDE's 5,000 to 7,000 THB/kWh
  for LiFePO4); adds enclosure, fire protection, controls and installation,
  below CapSolar's 12,000 to 15,000 THB/kWh for a fully installed factory
  BESS because the hybrid inverters do the conversion (estimate).
- Utilities baseline 27.57M to 47.50M THB; launch plant ~160M / 222M /
  283M THB with contingency; Plan B ~208M (~149M to 266M), ~31M more than
  Plan A; Plan A's total unchanged, its solar lever ~9.7M. PV payback
  ~3.8 to 5.4 years (sustainability.md). Calculator, README, roadmap,
  revenue model and both business plan versions (renders included)
  updated.
2026-10-17 16:41:14 +07:00
grabowski 3f33babdaa Plan B re-defined: the launch plant with everything in (~210M THB); front view on the cover
Deploy test site / deploy (push) Successful in 52s
- Plan B now starts like Plan A with one Duplex system and one Classic,
  but takes none of the six levers: owned solar and battery (with the BOI
  solar measure), the full metrology stack, the visitor corridor, cassette
  and CD-R, the bought crane and Thai-supplied utilities (user, 17 October
  2026). ~193.8M THB before the reserve, ~209M with it (~150M to 268M),
  ~32M (~18 %) more than Plan A; the second Duplex is a growth step from
  revenue in both (~15.4M THB, estimate).
- total-investment.md "Two plans" re-based (heading and anchor now
  "B at ~210M THB", README and roadmap links updated); revenue-model.md
  operating pictures: same volume and EBITDA as Plan A, depreciation on
  Plan B's capital (operating profit 1.26M USD central, payback ~3.7 yr);
  the extra earns nothing in the modelled table, which the docs say.
- Calculator: Plan B preset = the launch plant with contingency kept out
  (EBITDA 2.07M USD, cash payback year ~4.3, IRR ~21 %); budget card marks
  180M and 180M plus 25 %; preset label "Plan B (~210M, all in)".
- Business plan draft 0.3, both versions rebuilt: every Plan B branch of
  the three content files rewritten; renders regenerated with the
  isometric view turned to the front of the site (road, car park, office,
  corridor facade) for the cover and Figures 8 to 10.
2026-10-17 16:33:18 +07:00
grabowski ffc6cedbca Business plan: isometric calculator views instead of FreeCAD, software section with screenshots
- Cover and section 6.2 now use the isometric plant view of the plant and
  business plan calculator, drawn with each version's own preset: the
  cover (roofs, no labels), Figure 8 the site from above, Figure 9 the
  ground floor cut open, Figure 10 the press hall close up. The FreeCAD
  aerial render, the Mueang Chi site plan and the hall layout sketch are
  no longer in the plan; the captions say the calculator draws the Payap
  scenario model while the 6.2 text and zone table are the Mueang Chi
  hall.
- New section 5.5 "The software: plant overview, factory console and
  artist platform" with six screenshots of the demos: the plant overview
  (simulated SCADA), the factory console press floor and its ERPNext
  link, the artist ordering offer, fan funding and the record passport.
  Simulated data is marked as such; the platform name stays undecided.
- Figures renumbered (budget card 11, cash 12) and named in the
  section 15 source table. Renders in docs/renders/calculator/ and
  docs/renders/demos/; README bullet updated.
2026-10-17 16:06:04 +07:00
grabowski bd357ab03f Business plan draft 0.3 in two versions: Plan A ~180M and Plan B ~225M THB
Deploy test site / deploy (push) Successful in 52s
- One build makes both documents: plan_variant.py switches the
  plan-specific text (pick / is_a / label); build_plan.py writes
  CNX-Vinyl-Business-Plan-A and -B (docx), export_pdf.py exports both PDFs
  with the table of contents filled in. Draft 0.2 (single launch-plant
  plan with contingency) is removed; it stays in the history.
- Plan A: the launch plant with every machine and six cost levers, ~177M
  THB with the ramp-up reserve, no contingency. Plan B: the second Duplex
  at launch, five presses, ~224M THB on the same basis. Each version reads
  as a complete plan with one table comparing it with the other; the
  216M investor-question text is gone, Pheenix is priced at OMS's
  reference plus 20 %.
- Calculator renders in both documents, each from its own preset: the
  plant at a glance (Figure 4), the budget check (Figure 5) and ten years
  of cash (Figure 6), in docs/renders/calculator/.
- Calculator budget card: the verdict and third KPI now name the tightest
  budget the midpoint fits (Plan A: 3.3M to spare under 180M; Plan B:
  0.8M under 225M) instead of always 225M.
- Fixes: CD replication cross-references point to section 4.10; the
  blended price in section 3.3 and roadmap item 1 is 3.76 to 5.27 USD at
  60 % specials (3.50 to 4.60 at a standard-heavy mix).
2026-10-17 15:42:35 +07:00
grabowski f2ff1eac1f Two plans for the investor: Plan A ~180M, Plan B ~225M THB; Pheenix at OMS +20 %
Deploy test site / deploy (push) Successful in 53s
User (October 2026): price the Pheenix galvanics line at OMS's reference
plus 20 %, and work on a new business plan in two versions, one at
roughly 180M THB and one at +25 %; the plans do not include contingency;
Plan A keeps every machine and uses cost levers only.

- total-investment.md: Pheenix block 324k to 445k USD (OMS 4-cell wet
  room with know-how transfer, EUR 234k to 321k, plus 20 %; was 320k to
  650k estimate); launch plant now ~161M to 285M THB with contingency,
  midpoint ~223M. New section "Two plans": Plan A = launch plant with
  solar PPA, metrology launch tier, corridor later, cassette and CD-R
  later, rented crane, Chinese boilers and compressor: subtotal ~161.7M
  + ramp-up reserve 10 to 20M = ~177M THB (127M to 226M). Plan B = second
  Duplex at launch (five presses), everything in: subtotal ~209.2M +
  reserve = ~224M THB (162M to 286M). Contingency listed as not in
  either price (~24M / ~31M at 15 %). The 180M / 216M answer marked
  superseded.
- revenue-model.md: operating pictures of both plans at 60 % specials.
  Plan A central EBITDA 1.73M USD, operating profit 1.34M, payback ~3.1
  yr on the plan price; adverse loses money. Plan B (1.0 / 1.25 / 1.5M
  records) central EBITDA 3.14M, operating profit 2.63M, payback ~2.2 yr;
  adverse just covers depreciation; needs ~1.25M records sold.
- Calculator: Pheenix price basis "OMS +20 %" and "OMS directly"; new
  contingency switch (in the total / shown separately); presets Plan A
  and Plan B (replace "investor levers" and "five-press"); budget card
  against 180M and 225M.
- galvanics.md price note, README, roadmap.

Checks: calculator regression updated and passing (0 fails, no page
errors), node --check on all scripts, site build (no dead links), no em
dashes added.
2026-10-17 14:47:43 +07:00
grabowski f7e20e1015 Make a record: USD / THB / EUR selector and English / Thai language switch
Deploy test site / deploy (push) Successful in 1m45s
User (October 2026): currency selector on the first page (USD / THB /
EUR) and a language selector for Thai on the make-a-record demo.

- Top bar: one currency control (replaces the THB/USD switch on the
  price step) and an EN / Thai control, visible from step 1; both persist
  (localStorage, #cur= / #lang= in the URL, hash wins). Prices stay
  computed in THB: USD = THB / 33, EUR = THB / 38.115 (1 EUR = 1.155
  USD); the fan price is entered in the chosen currency and stored in
  THB, the campaign rule max(100, break-even) unchanged.
- Thai: every visible string, tooltip, aria label, file check, quote
  line, production update, passport, investor note and tour caption
  (dictionary T = {en, th}, t(key, vars), data-i18n attributes; 636
  keys), system Thai fonts, Thai dates with Gregorian years, and a footer
  note that the Thai is a draft translation for review. Template PDFs
  stay English (Helvetica has no Thai glyphs).
- Top bar wraps to two rows below 1000 px (steps were cut off between 761
  and 990 px before).
- README and landing entries mention the currencies and Thai.

Checks (headless Edge): doc example unchanged in THB (37,836 per title,
232 per copy at 100, break-even 41, goal 100, ~548 kept, 640 hint);
conversions exact; 390 / 768 / 1024 / 1440 px, light and dark, EN and
TH, all currencies, steps 1 to 5: no page errors, overflow or untranslated
leftovers; tour in Thai; node --check; no em dashes.
2026-10-16 22:03:50 +07:00
grabowski 3f1e4452b8 Press hall: five Duplex bays and four Classic positions (balanced at 60 % specials)
Deploy test site / deploy (push) Successful in 44s
User (October 2026): "change the hall layout" after the finding that the
60/40 floor split leaves the Classics about half loaded at 60 %+
specials (specials run only on the Duplex systems).

- Press hall now keeps five Duplex bays (four along the visitor
  corridor, the fifth at the head of the second row) and four Classic
  positions: 550 + 200 = ~750 m2 of ~870 m2, ~73/27 by floor, 10 to 4 by
  presses; launch plant fills one of each, growth adds Duplex first.
- Full hall: ~2.9 to 4.4M records a year at 60 % specials, Classics ~80
  to 100 % loaded (60/40 gave ~2.3 to 3.6M); ~3.2 to 4.4M at ~20 %;
  fourteen presses as before: ~2.1 to 2.5 t/h steam, up to ~1.8 MW
  cooling, a utility phase of its own.
- pressing-line.md, scale.md, site-candidates.md, crane-workshop-tours.md,
  roadmap.md, README (FreeCAD model still the earlier layout, not
  redrawn); calculator preset "Full hall (5 D + 4 C)" and ladder; plant
  view reserves 5 Duplex bays and 4 Classic positions; business plan
  draft 0.2 rebuilt.

Checks: renderer 720 checks and functional checks pass, calculator
regression 0 fails, level checks clean; PDF 47 pages, TOC filled.
2026-10-16 20:57:51 +07:00
grabowski b3e8e4272b Specials share 60 %+: revenue model, calculator and business plan re-based
Deploy test site / deploy (push) Successful in 52s
User (October 2026): "lets say 60+% special prints" (the plant focuses on
special prints, not mono colours).

- Specials (splatter, marble, colour effects) run only on the Duplex
  systems, so at 60 % the Duplex sets the launch plant's output: ~0.58 /
  0.74 / 0.90M records a year (was 0.71 / 0.84 / 0.97 at ~20 %), the
  Classic at about two thirds load. Full 60/40 hall: ~2.3 to 3.6M (Duplex
  -limited, Classics about half loaded); five-press fleet unchanged. A
  hall balanced by output at 60 % would give Duplex ~70 to 75 % of the
  floor (estimate; noted, not applied).
- Blended price 3.76 / 4.49 / 5.27 USD (standard 3.40 / 3.80 / 4.25 plus
  the 0.60 / 1.15 / 1.70 specials premium on 60 %). Launch operating
  picture: revenue 2.28 / 3.65 / 5.41M USD, EBITDA 0.23 / 1.73 / 3.79M,
  operating profit -0.66 / 1.21 / 3.46M, payback ~3.8 yr central,
  break-even ~0.25M records; adverse needs ~1.1M records to cover
  depreciation. Specials' extra direct cost (coloured compound, purge,
  trim only into black) is not in the cost table yet: flagged as an
  upper bound until compound quotes.
- Calculator default specials share 20 -> 60 % (planning rates keep the
  launch plant balanced at 850k: revenue 4.14M, EBITDA 2.07M, payback
  3.3 yr, cash payback year ~4.8, IRR ~18 %).
- revenue-model.md, scale.md, pressing-line.md, README; business plan
  draft 0.2 rebuilt (sections 1, 4, 9, risks).

Checks: calculator regression 0 fails, no page errors, node --check on
all scripts; PDF 47 pages, table of contents filled; no em dashes added.
2026-10-16 20:45:39 +07:00
grabowski d8b2c1e2db Press hall laid out 60/40 for Duplex systems (special pressings first)
Deploy test site / deploy (push) Successful in 46s
User (October 2026): "the factory should have more space for duplex
setups than classic, we will mainly focus on special prints and not mono
colours plan it to be 60/40 duplex classic".

- Press hall (~870 m2) planned 60/40 by floor: four Duplex bays along the
  visitor corridor and six Classic positions in the second row (440 + 300
  = ~740 m2 at 110 / 50 m2), the rest open for mould carts and staging;
  the launch plant fills one of each, growth adds Duplex systems first.
  Replaces "room for ten more Classics".
- Full hall: 8 semi-automatic presses + 6 Classics, 57/43 by press count,
  ~1,250 to 1,410 records/h gross, ~3.6 to 4.7M a year on the scale.md
  basis (was 4.7 to 5.8M for 2 Duplex + 11 Classics); ~2.1 to 2.5 t/h
  steam and up to ~1.8 MW cooling, still a utility phase of its own.
  By hourly output the six automatic Classics still press more than the
  eight semi-automatic presses (estimate).
- pressing-line.md, scale.md (capacity table, utilities), site-candidates
  .md, crane-workshop-tours.md, roadmap.md, README (the FreeCAD Payap
  model still draws the earlier layout; noted, not redrawn).
- Calculator: preset "Full hall 60/40 (4 D + 6 C)", fleet ladder Duplex
  first (1+1, 2+1, 3+2, 4+3, 4+6) plus the same floor Classic-led (2+11)
  and Duplex-only (7+0) for comparison; plant view reserves 4 Duplex
  bays and 6 Classic positions.
- Business plan draft 0.2 rebuilt (capacity table row, plot fit, layout).

Checks: renderer 720 checks pass (node budget 2,700 for the Duplex-heavy
stress preset, 60 fps), calculator regression 0 fails, level selector and
page checks clean at 390 / 1024 / 1440 px dark and light; PDF 47 pages
with a filled table of contents.
2026-10-16 20:09:56 +07:00
grabowski 4beda7f27a Plant view: toilets in the factory, link lands on doors, no separate trimmer
Deploy test site / deploy (push) Successful in 45s
User feedback on the isometric view (October 2026):
- "the production hall is missing toilets": two sets. At the staff
  entry: women 2 WC, men 1 WC and 1 urinal, an accessible WC, basins.
  At the east end of the back aisle in the finishing block: women 2 WC,
  men 1 WC and 1 urinal, basins (proposed, not yet in the parametric
  plans). site-candidates.md gets a Toilets bullet with the Thai minimum
  (Ministerial Regulation No. 39 B.E. 2537, table 2; separate toilets for
  men, women and disabled staff under the welfare regulation B.E. 2548).
- "the door and the corridor is not aligned": the covered link now lands
  on doors at both ends, centred on it (factory entrance at the start of
  the visitor corridor, office lobby door on the north face, windows
  cleared); the corridor glass starts after the door; the stray staff
  door with no path is gone; the link deck ramps up to the factory floor.
- "we also dont need a extra trimmer with the optical, this is included
  in the duplex and the classics": the finishing block keeps only the
  optical inspection station; site-candidates.md, the tour route and the
  process flow say the presses trim inline.

Checks: renderer 720 checks and functional checks pass (max 2,485 SVG
nodes); calculator regression 0 fails; level selector works in the page;
no page errors or overflow at 390 / 1024 / 1440 px, dark and light.
2026-10-16 19:40:05 +07:00
grabowski 8e4559ee36 Plant view: GF / 1F / Roof levels, lamps off the drive areas, pipe bridges land on walls
Deploy test site / deploy (push) Successful in 48s
User feedback on the isometric view (October 2026):
- "a light pole in the middle of the truck apron": a PAVED list of the
  drive areas (gate road, aprons, east road, lane, access road, car
  park, yard); every lamp now stands on a kerb or verge (the apron lamp
  to the south kerb, three more moved off drive areas, one added on the
  east road); one LAMPS list feeds poles and light pools.
- "the office building also has 2 levels, can we make a selector for GF
  1 2": the Roof / Inside toggle becomes GF | 1F | Roof. 1F shows the
  office first floor (+4.0 m: offices, meeting and training, meeting
  room, IT and server, toilets, pantry, flexible room, stair and lift)
  and the finishing and print block's upper floor (+3.8 m: print room in
  reserve, print stock, packaging materials, stair and goods lift), the
  rest ghosted. Office ground floor re-split after the floor plans
  (site-candidates.md). setMode('inside'/'roof') still works; new
  setLevel / getLevel / onLevel; the level survives calculator updates.
- "the pipe bridge to the pump and HX room also stops mid air": both
  pipe bridges now drop down the wall faces at the factory and at the
  yard building to low-level wall sleeves, with a second support post.

Checks: renderer 720 checks (presets x GF/1F/Roof x 390/1024/1440 x
dark/light) and functional checks pass; calculator regression 0 fails;
level selector works in the page; screenshots reviewed in all rotations.
2026-10-16 18:52:17 +07:00
grabowski 073f20a132 Plant view: cars under the canopies, PV on the car park, yard lamps, silo order
Deploy test site / deploy (push) Successful in 47s
User feedback on the isometric view (October 2026):
- "the cars are above the car park roof": cars and scooters were their
  own sprites and the depth sort put some above the canopy; they are now
  drawn inside the canopy sprite before the posts and the roof, so the
  roof always covers them in every rotation.
- "a light pole in the middle of the yard": the two yard lamps at the
  service-lane edge (one in front of the boiler hall) move to the yard's
  back fence; one LAMPS list feeds both the poles and the light pools.
- "add solar panels to the car park": the car and scooter canopies now
  take PV first (107 modules, ~48 kWp; construction RFQ has canopy PV),
  the factory roof the rest (560 of 667 modules at 300 kWp); canopy
  tooltips give their kWp.
- "arrange the pvc storage outside to be black, red, yellow": the silos
  read black, black, red, yellow from the default north-east view.

Renderer checks rerun (288 + functional, no failures); calculator
regression 62 checks pass; 390 / 1024 / 1440 px, dark and light, no page
errors or overflow.
2026-10-16 18:10:53 +07:00
grabowski d7380919e4 Steam and cooling, plant operation: show the launch plant (1 Duplex + 1 Classic)
Deploy test site / deploy (push) Successful in 43s
User (October 2026): "launch plant should be 1x duplex system and 1x
classic". The calculator already did; these two pages did not.

- steam-cooling.html: default case is now "Launch plant" (D1-A, D1-B,
  Classic; B-1 and B-2; CH-1 and CH-2: 450 to 540 kg/h on 1,000 kg/h,
  391.5 kW on 500 kW). Other cases: Duplex first (commissioning), Second
  Duplex (growth option, five presses), One module down (launch plant
  with B-2 and CH-2 out). Idle boxes say "reserved position" / "growth
  option". Phasing table: launch plant, second Duplex, options;
  galvanics cooling is launch scope. Five-press figures labelled as the
  growth case or backbone sizing; chiller cost per the CSV 2-module row.
- plant-operation.html: the launch plant: Classic C2 removed everywhere
  (press, trimmer, routes, conveyor, lamps, texts), Classic re-centred;
  one PDPU (2 cells) as in total-investment; boilers 2 x 500 kg/h,
  chillers 2 x 250 kW; title arrivals scaled to three presses; phone
  legend in one column.
- Landing entries and README bullets for both pages.

Verified headless (Edge): skill checks pw_sc_check and pw_plant_check
with launch-plant expectations, 90-day runs, perf unchanged; 390 / 1024
/ 1440 px dark and light without page errors or overflow.
2026-10-16 16:58:37 +07:00
grabowski 71e30b0633 Plant view: isometric tile-game render of the configured plant
Deploy test site / deploy (push) Successful in 45s
User request (October 2026): a SimCity / Factorio style render in the
calculator for an overview of the factory, solar and utilities.

New card "The plant at a glance" at the top of the plant and business
plan calculator: an isometric SVG scene (CNXIso, inlined with its iso-
prefixed CSS) of the Payap-scenario site driven by the calculator state:
Duplex systems and Classics (r.D, r.C; overflow into the phase 2
building), galvanics in-house or "stampers bought in", cutting in-house
or "cut abroad", metrology tier, cassette and CD-R benches, solar buy /
PPA / none (300 kWp, 271 kWh battery), electric or biomass steam (fuel
store, chip pile, smoking stack), boiler and chiller modules out of the
four positions each (r.nb, r.nc), crane, visitor corridor.

Roof / Inside cutaway, four rotations with a north arrow, zoom, pan,
pinch, tap for figures from the docs; dusk in the dark theme, day in the
light theme; CSS-only animation that pauses off-screen and respects
reduced motion. The scene only rebuilds when its config changes.

Verified headless on Edge: 390 / 1024 / 1440 px, dark and light, no page
errors, no overflow, presets map to the scene (lean, five-press, full
hall); the calculator's 62-check regression still passes; node --check
on all scripts. Renderer built and tested separately (288 checks).
2026-10-16 16:55:34 +07:00
grabowski 485b3b630a Plant and business plan calculator: configuration, investment, budget, ten-year cash
Deploy test site / deploy (push) Successful in 44s
User request (October 2026): an interactive business plan calculator
where the plant configuration is chosen and everything follows. Built
into the fleet calculator (same page and URL, one model):

- Plant configuration card: galvanics in-house or bought stampers (and
  Pheenix estimate vs OMS reference), mastering and cutting in-house or
  outsourced, metrology full or launch tier, cassette and CD-R, solar
  buy / PPA / none, electric or biomass steam, Thai or Chinese utilities,
  crane buy or rent, visitor corridor now or later, ramp-up reserve;
  stamper supply to other plants; disabled-not-hidden controls.
- Investment built from the total-investment blocks (low / mid / high,
  sources and kind badges); boiler and chiller modules sized from the
  fleet and flagged past the four positions; phase 2 building past the
  870 m2 press hall. Default reproduces 160.9 / 226.7 / 292.5M THB.
- Budget card against 180M and 216M THB; "Investor levers" preset gives
  193.6M mid, 203.6 to 213.6M with the reserve.
- Money follows the configuration: outsourced title steps passed through
  at cost (fee split 51.1 / 37.0 / 11.9 %), electric steam energy and
  demand charge, PPA power price, optional cassette/CD-R revenue.
- Ten-year cash view: editable ramp and discount rate, payback, NPV, IRR,
  chart and table; pre-tax, pre-financing sketch.
- Presets: launch plant, investor levers, lean, five-press, full hall.
- Verified headless on Edge: 62 checks, 390 / 1024 / 1440 px, dark and
  light, no overflow, no page errors.

Business plan 9.4 cross-check updated to the calculator's figures
(EBITDA 1.68M, payback 4.1 yr; cash payback year ~5.7, IRR ~13 %);
docx and pdf rebuilt. README and landing entry renamed.
2026-10-16 16:15:22 +07:00
grabowski d42e99389b Business plan draft 0.2: re-based on the launch plant
The investor business plan (docx + pdf) rebuilt for the launch plant
decided in October 2026: one Duplex system and one Classic, Pheenix
galvanics with zero discharge, the Sibert line, a Sillitoe cutting room,
modular steam and cooling (rooms for four), cassette and CD-R; no bridge
stampers, no outsourced cutting; second Duplex as a growth option.

- Part A: executive summary (what changed since 0.1, the numbers, the
  180M / 216M answer, first release marked open), reading guide, two
  price points (ResurRec and Record Industry), anatomy rewritten for
  Sillitoe, Pheenix, Sibert, Duplex + Classic, lead times without bridge
  stampers, new 4.8 artist platform, cassette 4.9, CD 4.10.
- Part B: traceability with ERPNext as system of record, metrology launch
  tier as the investor's choice, QC, efficiency (PEA tariff, utility
  modules, fuel open, Chinese boilers and DIW rules), site (Mueang Chi,
  Payap zoning result), building blocks, safety, BOI and licences with
  galvanics in the first factory licence.
- Part C: launch-plant investment table, the investor's question and
  levers, tranches, currency, operating picture of the launch plant,
  timeline with the metal path on the critical path, commissioning
  sequence and why the whole chain at launch, team, 22 risks, 17 phase 0
  actions, the ask.
- plan_lib: grid column widths so LibreOffice keeps table widths.
- export_pdf.py: LibreOffice UNO export that fills the table of
  contents (47 pages).
- README: total investment, revenue model and business plan bullets.
2026-10-16 16:01:25 +07:00
grabowski 794cde228c Re-base scale, pressing line, roadmap, revenue model and calculator on the launch plant
Deploy test site / deploy (push) Successful in 48s
Launch plant (user, October 2026): one Duplex system and one Classic,
with cutting and galvanics in-house, everything in one capital round.

- scale.md: capacity table now launch plant 0.71-0.97M records/yr, the
  second Duplex as a growth option; launch utilities (450-540 kg/h on
  B-1/B-2, ~390 kW on 2 x 250 kW); calculator figure ~0.94M.
- pressing-line.md: launch plant section on top; five-press fleet kept as
  the layout fleet the hall and backbone are built for.
- roadmap.md: long-lead orders for the launch plant, no bridge stampers
  or outsourced cutting, commissioning order, what stays revenue-gated.
- revenue-model.md: operating picture of the launch plant: central
  revenue ~3.75M USD, EBITDA ~1.6M, operating profit ~1.1M, payback ~4
  yr on 216M THB, break-even ~0.3M records; adverse corner cannot cover
  depreciation. Five-press table kept and labelled.
- fleet-calculator.html: start fleet 1 Duplex + 1 Classic, target 850k,
  capex base 6.55M (cases 8.9 / 6.55 / 4.9M), Duplex beyond one, chiller
  500 kW, imported machinery 2.3M, ladder from the launch plant.
- total-investment.md: superseded note updated.
2026-10-16 15:34:19 +07:00
grabowski 7344f12dc8 Chinese suppliers for boilers, compressed air and hydraulics
Checked October 2026 on the investor's budget question. New
docs/suppliers/china-utilities.md: boiler makers (ZOZEN, Sitong,
Fangkuai, Taiguo, Yuanda, Yongxing, Taishan, Nobeth) with fit for 500
kg/h at 1.25 MPa, claimed certificates, Thai references and listing
prices; the Thai rules for an imported boiler (MR and MOI notification
B.E. 2549: ASME/JIS/EN or equivalent, certification-body verification,
once-through relief does not reach 10.5 bar, licensed controller, annual
inspection); compressor makers with Thai offices (Kaishan, Denair) and
sizing; hydraulic pump sets and accumulators (Huade, Yuci, Hengli, WMD,
Renowell, Inovance, NXQ makers), the shared-ring-main risks and Thai HPU
builders; duty and freight; open RFQs.

Result: about 2M THB at the midpoint (~2.5M with contingency), ~1 % of
the 216M target, mostly the boilers; Newbilt aggregates stay Newbilt's.
total-investment notes it and lists the uncosted central hydraulic
plant; utilities CSV gets the Chinese candidates and route estimates;
backlinks from equipment-suppliers, pressing-line, README.
2026-10-16 15:21:38 +07:00
grabowski 553b4a93d1 Launch plant roll-up and the investor's 180M THB question
Decided (user, October 2026): the plant launches with everything in one
capital round, commissioned in sequence: one Newbilt Duplex system, one
Classic, a Pheenix galvanics line with ZLD water, the Sibert line, a
Sillitoe cutting room, and the modular steam and cooling plant (2 x 500
kg/h boilers, 2 x 250 kW chillers, rooms for four each). No bridge
stampers, no outsourced cutting; cassette and CD-R stay; the second
Duplex and further Classics are growth options, not in the investment.

total-investment.md: new 'Launch plant' roll-up, 4.9M to 8.9M USD,
161M to 292M THB incl. 15 % contingency (midpoint ~227M), with what is
left out (ramp-up reserve ~10-20M THB, CD replication, financing, FX,
archive shelving) and the BOI assumption. The investor's question (180M
THB, maybe +20 % = 216M): fits at the low end only; at the midpoint four
levers that keep every machine (solar via PPA, metrology launch tier,
galvanics near OMS's reference, visitor corridor later) give ~193M, plus
reserve ~203-213M, inside 216M; 180M needs low quotes. The quotes that
decide it: Newbilt (Duplex, Classic), Pheenix galvanics, building with
soil test, metrology. Old full vision and phased entry marked superseded
until the mirrors are re-based.

Utilities CSV: chiller bank two modules (4.9-7.9M THB), boiler note for
B-1 and B-2 at launch, ZLD and DI rows now launch scope (carried with
galvanics); baseline 28.47M-48.73M THB. README project status.
2026-10-16 14:53:19 +07:00
grabowski 07ef9c0b9a Order demos: spine choice, artwork templates, PDF and AI uploads
Deploy test site / deploy (push) Successful in 50s
User request (October 2026): the order tool needs a thin / thick spine
selection, templates for the jacket and label upload, and must accept AI
and PDF files.

Both artist demos (artist-order, make-a-record):
- Spine: thin 3 mm (one record) or thick 5 mm (two records, or a thick
  insert); a double album in a single jacket takes 5 mm, thin is then
  disabled; 7", gatefold (7 or 9 mm) and own jacket disable the row with
  the reason. Quote line 'Thick 5 mm spine' (R.spine 12 / 10 THB per
  copy, estimate from QRP 0.90 vs 0.55 USD and Kudos 137.50 GBP/order).
  Mock-up draws the spine edge to scale; caption names it.
- Templates: vector PDFs written in the browser for the current choice:
  jacket spread (back, spine, front; 633/635 x 315 mm for 12" from
  Mighty Media Discs), gatefold with an inside page, labels with a page
  per side and the dinked hole; trim and bleed boxes set, 3 mm bleed,
  5 mm safe area, folds, crop marks, guidance notes.
- Uploads accept PDF, AI (PDF-compatible) and images. PDFs are read in
  the browser (object streams inflated with DecompressionStream): page
  boxes, pages, PDF/X, creator, colour spaces, font embedding; checks
  against the chosen spine (a 5 mm spread on a 3 mm order is flagged),
  bleed, CMYK, fonts; old PostScript-only AI files are refused with the
  fix. Image spreads are measured the same way. Preview via pdf.js
  (jsDelivr, loaded only when a PDF arrives); the front panel goes into
  the mock-up.

artist-platform.md: new section 'Artwork templates and files' with the
sources; preflight step links it; RI 'left out' list updated. README
demo bullet. Checked headless on Edge: fixtures (3/5 mm spreads, no
bleed, AI, legacy AI, front only, labels, 150 dpi PNG), downloaded
templates parsed with PyMuPDF, 390/1024/1280 px no overflow, dark and
light, no page errors; pw_mr_check --tour and pw_ri unchanged
(37,836 / 232).
2026-10-16 12:34:58 +07:00
grabowski 5c303dfc61 ERPNext is the only system of record; we build tools on it
Deploy test site / deploy (push) Successful in 46s
User (October 2026): we only build tools and interfaces that interact
with ERPNext; invoices, stock and the rest are kept there, except
telemetry and other machine data.

digital-factory.md: standing decision, decisions 2, 3, 6, 7 and 10
rewritten (ERPNext holds every record of the business and of production,
including artist gates, metal-part genealogy as serial numbers with
parents, and quality inspections; the machine-data store keeps only
cycle and record rows, the hash chain and time series, keyed to ERPNext
names; ERPNext first, then custom fields or document types in cnx_erp,
then a tool, never a second business database). Systems table,
architecture labels, factory application section (modules as a table:
records in ERPNext, what we build, machine data outside; our only tables
are the machine-data ones), ownership table, integration rules 4 and 8,
phasing and estimates (cnx_erp app 2 to 3 person-months; total 3.5 to 6).
artist-platform.md: campaigns are an ERPNext document from launch, pledges
post as advance payment entries; traceability, README, facility security
(archive location on the serial number), production timeline (sets per
mother on the mother's serial number), crane-workshop spares store,
total-investment.

Factory console: KPI row no longer touches the postings card (user
screenshot); ERPNext page, order card, sidenote and ledger say every
record lives in ERPNext and only machine data stays outside; new
postings for artist gates, stamper metrology inspections, stamper set
serial numbers (grown, retired with play count). Checked headless:
Edge dark and light, 1440/1024/390, no overflow or page errors, rows
aligned, pw_fc, pw_wo, pw_feed and pw_erp pass.
2026-10-16 12:14:52 +07:00
grabowski a101c9f7db Factory console: ERPNext link page and ERPNext documents on orders
Deploy test site / deploy (push) Successful in 45s
Follows the decision that the whole plant runs ERPNext and every tool
we build interacts with it (e12ad2e).

- New page #erp (nav: ERPNext): every posting the floor makes, derived
  from the same event log: sales orders in by webhook, work orders,
  job cards per station, serial numbers for lacquers, fathers and
  mothers (warehouse Archive), purchase receipts, quality inspections
  and stock entries per compound batch, manufacture entries per run,
  downtime entries per stop, delivery notes and invoices. Outbox status
  per row (sent within a minute, held during the nightly backup
  01:00 to 01:15), KPIs, who-owns-what table, counts by document type.
  Rows use fixed ch grid columns; on phones a two-line row.
- Order page: ERPNext card (customer, sales order, work order with
  produced quantity, job cards completed, batches, delivery note and
  invoice). Work order page: its job card, quality inspection or asset
  maintenance log.
- Names follow ERPNext's default naming series and are simulated;
  nothing uses the simulation's random stream, so the seed is unchanged.
- Phones: the nav strip scrolls the current tab into view. Work order
  IDs on the order page no longer wrap (wider fixed column).

digital-factory.md demo paragraph. Checked: node --check, Edge dark and
light at 1440/1024/390 (no overflow, no page errors, rows aligned), and
the pw_fc, pw_wo and pw_feed regressions.
2026-10-16 11:37:10 +07:00
grabowski e12ad2ed7b ERPNext runs the whole plant; every tool we build integrates with it
Decided by the user (October 2026): the whole plant runs ERPNext, and
all tooling we develop has to interact with it.

digital-factory.md: standing decision in the summary; decision 10
(ERPNext owns the business documents, the factory application owns the
floor; ERPNext names are the shared keys); new section 'ERPNext: the
plant's ERP' with the ownership table (customers, prices, sales orders,
items and BOMs, work orders and job cards per station, batches and
quality inspections per compound lot, serial numbers for metal parts,
downtime entries, delivery notes, assets, accounting, payroll vs. cycles,
per-record inspection, genealogy and the hash-chained log staying in the
factory application), the integration rules (one typed Frappe REST
client in cnx-factory, an integration user per tool, webhooks in,
transactional outbox with idempotent postings so the floor never waits
on the ERP, business-sized postings, customisation as a Frappe app in
Gitea, nightly reconciliation, no public ERPNext endpoint, new tools use
the same client), hosting on NixOS (no nixpkgs module, NixOS/nixpkgs
#241921; Avunu frappe-nix as the start, frappe_docker as
oci-containers fallback; MariaDB + Redis; vinyl-erp on site behind the
gateway proxy; OIDC sign-on; upgrades on a restored copy), Thai
localisation (Ecosoft erpnext_thailand: VAT, WHT, PND, billing notes;
Ecosoft as partner to quote; payroll and BOI reporting to check),
phasing (dev ERPNext now; accounting and assets from the first capex
invoice; manufacturing at commissioning) and estimates. ERPNext added
to the architecture diagram, services, machines (vinyl-erp), module
list, backup, cost, build order and open decisions; the old 'ERP out of
scope, decide after launch' line replaced.

artist-platform.md: price list, customers, sales orders, campaign
pledges as payment entries, through the plant's outbox. traceability.md:
one ERP, one set of keys. README summary. total-investment.md added
scope: ERPNext (to quote, not in the sum, no licence fee).
2026-10-16 11:29:26 +07:00
grabowski 655d5705c4 Supplier: LPI Rack Range (Thailand), racking and mobile shelving
Added at the user's request (October 2026): LPI Rack Range (Thailand)
Corp., Ltd., Bangkok head office, plants in Bangplee Industrial Estate
and Bangpla (Samut Prakan); office mobile shelving for documents, pallet
racking (selective, drive-in, mobile, shuttle, pallet flow), picking
shelves and mezzanines, mould-and-die racking, mini-load AS/RS; no specs
or prices published (lpi.co.th, checked October 2026).

equipment-suppliers.md section 8 entry; the Thai supplier the archive
shelving is quoted against (facility-security.md open points, supplier
map archive line); racking candidate in the utilities CSV.
2026-10-16 11:25:15 +07:00
grabowski 4f02d9a7a9 Archive room: mobile shelving for the father and mother archive
Deploy test site / deploy (push) Successful in 43s
Planned (October 2026, user): the archive in the office gets mobile
archive shelving, A-Z Solutions (Vienna) as the reference
(a-z-solutions.eu, checked October 2026: hand wheel or electric drive,
lockable, rails need early floor planning; no published prices).

facility-security.md, new section under Protecting the irreplaceable:
what it holds (fathers and mothers, ~1,200 to 2,400 parts a year; a
reference pressing per title only as a proposal), sizing estimates (about
0.2 kg per part, ~3 mm and ~75 kg per shelf metre; in the Payap office's
~4 x 5.75 m room two fixed runs, four double carriages and one aisle hold
~150 shelf metres, ~50,000 parts, 20+ years), what it asks of the
building (ground slab at full rating, ~11 kN/m2 under the block; rails in
the screed fixed before the floor finish; geared hand wheel; gas,
climate, leak sensor, access control; barcoded box addresses), open
points (quotes from A-Z and a Thai supplier, storage format from the
galvanics vendors, fathers in a second compartment or off site).

Mirrors: site-candidates.md (office ground floor), phase 1 RFQ (archive
keeps the full slab rating if the slab is zoned), digital-factory.md
(archive location as box and shelf position, sets per mother),
equipment-suppliers.md (section 8 entry), total-investment.md added scope
(to quote, not in the sum).
2026-10-16 11:18:09 +07:00
grabowski 475623e9f2 Archive the father as well as the mother; how many represses a mother carries
Decided (October 2026): the plant keeps the father and the mother of every
side. production-timeline.md (repress section) records the decision and the
rule of thumb with sources: about 10 stamper sets per mother before it
degrades (Third Man Pressing FAQ, a Nashville plater via WPLN), fewer in
quality-minded sources (5 VinyLab, 6 to 8 Stereo Review 1962); a father
grows about 5 to 10 mothers. So a mother covers roughly ten represses
(10,000 to 20,000 records a side) and a worn one is replaced from the
archived father without a new cut. galvanics.md: 4 archived parts per
title, ~1,200 to 2,400 a year; new open question to all galvanics
candidates (sets per mother, mothers per father, storage).
artist-platform.md repress paragraph.

Demos: make-a-record and artist-order say father and mother are archived;
factory console archives the father on represses too, counts stamper sets
per mother (shown in the genealogy and the customer's metal card), and the
metal archive counts fathers and mothers.
2026-10-16 11:17:13 +07:00
grabowski 1cceedc8a4 Factory console: inspection feeds in fixed columns
Deploy test site / deploy (push) Successful in 45s
The live inspection feeds (floor, quality, press, customer's latest
copies) were one run-on string, so a shorter press ID (C1 vs D1-A)
shifted everything after it and the cycle time showed twice. Each row
is now a grid of fixed columns sized in characters of the mono font:
time, stamper, press, order, result, with a header row (the row keeps
the mono font so its columns match; only the labels change font). On
phones the order column (factory) or press column (customer) drops.
The full record key stays in the stamper cell's tooltip.

Work order cards: station chip left, work order ID right-aligned in the
header, the assignee moves to the time line, so card headers no longer
shift with the ID length.
2026-10-16 10:58:35 +07:00
grabowski f9b8407561 Factory console: work orders for the operators
Deploy test site / deploy (push) Successful in 51s
New "Work orders" section in the factory console (#work), derived from
the same simulated records as the rest of the page, one work order per
station and job:
- order stages: mastering, lacquer cutting, electroforming, stamper prep,
  test pressings, press run, packing, dispatch
- stamper changes (planned when a set nears its life, in progress during
  the change), fault clearing on a stopped press (maintenance)
- material lab: lab gate per compound lot, release test pressing, and the
  held lot's re-dry and retest (button starts it)
- audio QC: each sampled copy's listening check

Board: In progress (press floor first) / Next up (planned press runs and
stamper changes with time and press, jobs arriving at the next station)
/ Done today, filter per station, KPIs. Each work order opens a kiosk
view: the steps an operator follows (badge in, scan what the step asks
for, with the IDs to scan, confirm), confirmation times and who did it,
the order, lot or press it belongs to, and what it writes to the log.
Order detail lists the order's work orders by station. Mastering and
cutting are booked to the engineers, the lab, QC and maintenance to
technicians, the rest to numbered operators; jobs finishing at night are
booked to the late shift.

README, digital-factory.md demo paragraph and the landing page mention
the work orders.
2026-10-16 10:41:29 +07:00
grabowski dd7b749af9 Factory console: demo fleet of one Duplex system and one Classic
Deploy test site / deploy (push) Successful in 51s
Three presses for now (D1-A, D1-B on one Newbilt Duplex system, C1
Classic) instead of the plan's two Duplex systems. Order arrivals scaled
to the smaller fleet (about 3,000 to 4,600 good records a day); press
row fills the width; landing page text updated.
2026-10-16 10:29:39 +07:00
grabowski 9ed51f4b22 Factory console and customer order status: investor demo
Deploy test site / deploy (push) Successful in 51s
New page docs/factory-console.html (site /demos/factory/): the factory
application of digital-factory.md on a simulated plant day, with a
switch to the customer portal of the same orders.

Factory console (sidebar: Floor, Orders, Quality, Lab, Metal, Ledger):
- floor: five presses of the launch fleet (two Newbilt Duplex systems,
  one Classic) with the mounted order, live good / rejected counters,
  stamper plays against life, cycle time and steam; KPIs for the day;
  live optical inspection stream with record keys; alerts (stops, lab
  holds, stampers near end of life, listening reviews, long gate waits);
  stations (cutting, galvanics, stamper prep, lab, packing); orders by
  stage; good records per day
- orders list with stage filters and search; order detail with stage
  track, approvals, metal genealogy and stamper metrology, press run
  telemetry, compound lot certificate, rejects by reason, audio samples,
  packing and shipping, and the order's events
- press detail with telemetry sparklines; quality (rejects by reason,
  yield per press, audio comparison); lab (compound lots with results
  against illustrative limits, one lot on hold with re-dry and retest,
  regrind batches, hoppers); metal (baths, mounted stampers, metrology,
  archive); hash-chained event log

Customer portal (four demo customers: pressing now, waiting to approve
the test pressing, in plating, delivered): progress through every step
and the three gates, copies pressed so far with the latest copies and
their record keys, approving the test pressing books the press slot
(greedy plan of the queue gives the start time and press), and a quality
report that fills in step by step: files, lacquers, metal parts with
metrology, test pressings, the compound lot's lab results, pressing and
inspection, listening checks, packing.

Simulation: 60 days warmed up at load (about 0.7 s), then 1x to 3600x.
Stages and durations from the production timeline, Newbilt cycle times,
two shifts 06:00 to 22:00, unplanned stops, stamper life 1,000 to 2,000
plays, audio sampling first-off plus about 1 in 50 (1 in 25 near end of
life), compound lots through the lab gate and release test pressing.
All orders, values and IDs are simulated; limits are illustrative.

Linked from digital-factory.md (the factory application), traceability.md
(customer-facing view), the README and the landing page.
2026-10-16 10:17:19 +07:00
grabowski 5090609df3 Calculators: options from Record Industry's calculator; its prices as a benchmark
Deploy test site / deploy (push) Successful in 45s
Reviewed Record Industry's (Haarlem, NL) public vinyl calculator: a
seven-step wizard with a live itemised cost list priced on its server.
Read its prices for a reference 12" LP at 200 / 300 / 500 / 1,000 copies
and for each option worth copying (checked October 2026).

Both artist demos (make-a-record and artist-order):
- audio arrives as digital files, analog tape (+ tape transfer) or a cut
  lacquer (no blanks, cutting or mastering; mastering choice disabled with
  the reason; cutting and mastering stages skipped in the timeline; the
  passport starts at "Lacquer received")
- labels printed, plain white or plain black (credit line; the label
  artwork drop is disabled for plain labels; the mock-up shows the plain
  label)
- press cleaning before a colour run, on by default, disabled for black
- 7" dinked (large centre hole), 7" only, drawn in the mock-up
- download card and barcode sticker extras
- run-out inscription (A-Z, 0-9, up to 15), scribed along the dead wax in
  the mock-up and named in the passport
- new rates (tape 3,800, cleaning 2,300 per title; plain labels -12 per
  disc; download card 43, barcode 6 per copy) are estimates with Record
  Industry's prices as the basis, each listed in the detailed demo
- make-a-record investor notes: Record Industry's 9 to 11 week quote after
  test-pressing approval against the 7 to 9 week CNX quote, and its 2 %
  reject allowance against 100 % optical inspection

Defaults unchanged (37,836 THB per title, 232 per copy at 100, break-even
41, goal 100, 548 kept).

Docs: artist-platform.md (choices table, benchmark section: what was
taken, what was left out, commercial terms worth deciding);
revenue-model.md (second Western data point: 219 THB a copy at 300
ex-works, per-title and per-copy reading against the assumptions, not a
re-base); production-timeline.md (its published lead times).
2026-10-16 09:42:57 +07:00
grabowski 83f1aa94dc Make a record: launching a campaign no longer starts the simulation
Deploy test site / deploy (push) Successful in 52s
After Launch the campaign page opens at day 0 with Play ready; the
artist (or presenter) starts it. The quick "Run the demo campaign" path
behaves the same; only the guided tour presses play itself.
2026-10-16 09:36:53 +07:00
grabowski e36d7b00a0 Fan funding: the price sets the fans needed; limited edition as a switch
Deploy test site / deploy (push) Successful in 1m4s
The artist sets only the fan price; the number of fans needed follows from
it: the plant's 100-copy minimum, or the break-even if that is higher. The
goal selector of 6a62505 is removed from both demos.

make-a-record.html:
- step 4 leads with "Your price to fans" (input, slider from 300 THB,
  presets 800 to 2,000) and a live "You need N fans to press it, X THB in
  pre-orders", plus the price below which the minimum no longer covers
  the costs (about 640 THB at the defaults)
- limited edition is now a switch, off by default; the edition size stays
  visible but disabled until it is on, and switching it on adds the
  numbered edition to the record
- "per title" renamed for end users: "One-off, for this release", "once +
  per copy", "One-off setup", with a note that one-off costs count sides,
  not songs (a double LP has four)
- the tour lowers the price to 500 THB and back to show the fans needed
  rising from 100 to 152
artist-order.html: goal field removed, "Fans needed" label and hint.
artist-platform.md: the price-sets-the-goal decision (October 2026).
2026-10-16 08:54:15 +07:00
grabowski 6a62505aa6 Fan funding: the artist chooses the campaign goal in fans
Deploy test site / deploy (push) Successful in 1m9s
The goal is no longer fixed at the larger of the plant minimum and the
break-even; that is now the floor, and the artist sets any goal above it.

- make-a-record.html: "Goal: how many fans you need" with number input,
  slider and chips (Lowest, 150, 200, 300, 500, 1,000); chips below the
  floor or above the edition cap stay visible but disabled with the
  reason; the goal also shows as the pre-order amount (fans x fan price);
  typing below the floor snaps back with a note; the campaign, the
  outcome and the stage run against the chosen goal; the tour shows the
  goal being raised to 150
- artist-order.html: goal field in the campaign card, same floor rule
- artist-platform.md: the floor rule and that a higher goal is all or
  nothing as well

Defaults unchanged (goal 100 = the plant minimum at 1,200 THB, break-even
41, 548 THB kept a copy).
2026-10-15 16:40:49 +07:00
grabowski 4b20ca4f48 Side length per format: team table with songs a side; palette control
Deploy test site / deploy (push) Successful in 47s
Side length "at most" per format is now the table the team supplied
(October 2026, from recordplayerexpert.com, songs counted at an average
4:32): 12" 22 / 15 min, 10" 15 / 12 min, 7" 7 / 5 min at 33 1/3 / 45 rpm.
Changes against the earlier microcut.studio figures: 10" 33 1/3 16 -> 15,
10" 45 11 -> 12, 7" 45 6 -> 5. The comfortable column stays the lower end
of microcut.studio's ranges.

- artist-platform.md: table with a songs column, both sources, and the
  three formats where cutting rooms disagree (10" 45 is now more generous
  than microcut.studio and Diggers Factory) as re-check points for the
  cutting engineer
- artist-order.html: LIM and the side-length table (songs column, sources)
- make-a-record.html: LIM; format cards show the at-most time and about
  how many songs a side; step 2 hint adds the songs; the last control in
  each colour row is now a labelled "Palette" pill with a colour wheel,
  showing the chosen colour and "Your colour" when a custom colour is set
2026-10-15 16:36:11 +07:00
grabowski 607f6631a7 Make a record: investor demo of the artist platform, end-user flow
Deploy test site / deploy (push) Successful in 53s
New static page docs/make-a-record.html (test site /demos/make-a-record/):
the artist platform as a customer would see it, polished for presenting.

- five steps (design, music and art, price, fan funding, track) with a
  sticky stage: to-scale mock-up (record spins at 33 1/3 or 45 rpm on
  hover), spec chips, price per copy, ship month and the next action
- design as option cards and swatches; options that do not apply stay
  visible and disabled (weight and gatefold off 12", colour pickers for
  black vinyl)
- masters and artwork read in the browser as in the detailed demo, side
  bars per side, checks in plain words, approval 1 of 3
- price with the curve, itemised lines folded under one summary, lead time
  as two bars (approvals, then the 7 to 9 week quote)
- fan funding: goal, break-even and what the artist keeps, money rules;
  the campaign on a phone with a pre-order ticker, funded or missed ends,
  production timeline with the artist's approvals, updates feed
- record passport for one delivered copy (stamper, press, cycle time and
  side; stage dates; optical inspection and sampled audio), per
  traceability.md and quality-automation.md, IDs simulated; repress card
- "Investor notes" switch with the business case per step (market
  research, vault, short-run economics and the Thai price gap, plant-owned
  vs broker and the Qrates lesson, traceability and represses); guided
  tour of about a minute (#tour, #notes in the URL)
- light/dark theme shared with the other pages; phone layout with a
  bottom bar

Same price list (demo-0.1) and stage table as artist-order.html, so the
defaults reproduce the artist platform example: 37,836 THB per title,
232 THB per copy at 100, break-even 41, goal 100, 548 THB kept a copy.

artist-platform.md: investor demo paragraph. traceability.md: the record
passport as the per-copy customer view. README bullet and layout line,
site DEMOS line and landing-page entry.
2026-10-15 16:13:29 +07:00
grabowski 5daf54a90b Payap parts model: saved view (camera on the utility yard)
Model content unchanged; only the save timestamp and camera differ.
2026-10-14 21:14:25 +07:00
grabowski e49abf89d3 Utilities: build the backbone once, add modules with the presses; four-module boiler hall and chiller compound
Deploy test site / deploy (push) Successful in 57s
Phased build list for steam, cooling and hydraulics (launch, Duplex 1,
Duplex 2, Classic, options): everything cheap to oversize and costly to
retrofit (rooms, pads, headers and ring mains with a valved branch per
press position, tanks, HX frame, feeders, one sequencer) is built for the
five-press fleet at launch; boilers, chillers and hydraulic pump sets come
in identical modules as presses arrive. The Single 2.1 aggregate is
proposed as the first central pump set; per-branch isolation and filters.

Rooms sized for four modules each (user decision, estimates until vendor
footprints): boiler hall ~18 x 9 m for four 500 kg/h positions (fired case,
AIX DZL0.5 body), open screened chiller compound ~12.5 x 10.8 m with four
pads (250 kW at 40 C ~ Carrier 30RB 080-090), ~40 m2 pump and HX room; the
cooling tower pad of the water-cooled concept is dropped. Yard 178 -> ~379
m2. Four boilers carry ~8 presses with N+1; four 250 kW chillers carry the
five presses with CH-4 as reserve and no growth position unless the pads
take the ~350 kW frame (RFQ option).

- scale.md: yard table and basis, utility phasing section
- pressing-line.md: hydraulics phasing and re-quote questions
- steam-cooling.html: B-4 position, phasing and rooms card, details, RFQ
  questions (pw_sc_check clean)
- construction RFQ: yard table, sealed area 6,549 m2 (68 %)
- total-investment: added-scope row +73k to +122k USD (building rate on
  the ~200 m2 the yard grows by)
- Payap parts model: yard rebuilt from Params (blr_n, blr_inst, ch_*,
  bh_*, cy_*, pr_*), renders updated
2026-10-14 21:02:30 +07:00
grabowski 7688d03be6 Payap scenario: Part/Draft model with roof, rooftop PV and PV parking canopies
New FreeCAD model docs/cnx_vinyl_parametric_payap_parts.FCStd: the Payap
scenario rebuilt from plain Part solids and Draft (arrays, labels,
dimensions) on the same Params sheet, no BIM objects, plus:

- monopitch roof 10 deg, low eave 7.0 m south, high side 11.4 m north
  (phase 1 RFQ geometry); gables and the fire wall follow the roof
- rooftop PV: 901 x 580 W placeholder modules, ~523 kWp, 17 rows in
  blocks of four with walkways, 1 m edge strip, 2.5 m clear over the
  fire wall (estimate)
- car canopy (10 bays, 72 modules) and scooter canopy (30 spaces,
  22 modules), ~54 kWp, RFQ footprints and heights
- module counts and kWp as sheet expressions; ~577 kWp in all

FreeCAD 26.3 RC1 does not propagate spreadsheet edits: CNX_apply_Params
macro touches the dependents and recomputes; parametric test (factory
length, pitch, car bays, walkway) matches the sheet counts.

site-candidates.md: roof/PV/canopy section with the export, battery and
BOI questions a 577 kWp array raises; mirrors in sustainability.md and
scale.md; README layout lines.
2026-10-14 20:32:43 +07:00
grabowski 1946553dd1 Artist ordering demo: colour pickers disabled for black vinyl
Deploy test site / deploy (push) Successful in 43s
With black vinyl the colour pickers are greyed out and cannot be used;
with solid colour only the first is active, marbled and splatter use
both. The weight buttons are disabled for 10" and 7" (140 or 180 g is a
12" option). Both rows were meant to hide, but .row display:flex
overrode the hidden attribute; a [hidden] rule now guards that too.
2026-10-14 19:41:45 +07:00
grabowski 2a3da0778f Artist ordering demo: mock-up drawn to scale for 12", 10" and 7"
Deploy test site / deploy (push) Successful in 46s
The record and jacket in the mock-up (sidebar and fan campaign page) now
scale with the chosen format: record diameters 302 / 250 / 175 mm
(IEC 60098), jackets 314 / 260 / 184 mm, labels 100 / 100 / 90 mm, so a
7" label is relatively larger as on the real disc. Smaller formats show
a dashed 12" jacket outline for scale and a caption with the sizes.
2026-10-14 19:33:36 +07:00
grabowski a07faf6ef0 Artist ordering demo: configure, check, offer, fan-funded campaign
Deploy test site / deploy (push) Successful in 53s
New static page docs/artist-order.html (test site /demos/artist-order/)
walking the artist platform flow end to end:

- record configurator (format, speed, discs, weight, colour, packaging,
  extras, mastering, test pressings) with a live mock-up
- track list or dropped masters read in the browser (WAV/FLAC/AIFF
  headers, sample peak and clipping), side length against the format,
  jacket and label preflight (size, dpi, CMYK), rights and gate 1
- itemised offer (per title / per copy, pass-through jacket), price per
  copy against quantity, lead time from the production timeline
- direct order or fan-funded campaign: goal = max(minimum run,
  break-even), what the artist keeps, the money rules, a simulated
  campaign (sells out / just makes it / falls short) with refund or
  go-ahead-at-minimum, and the production tracker with the three gates
  and the fan update feed

Price list demo-0.1 splits the doc's 38,000 THB per title and 132 THB per
copy into lines (estimates, each listed with its basis); defaults
reproduce the artist platform example (break-even 41, goal 100, ~548 THB
kept per copy at 100).

artist-platform.md: demo paragraph, side length per format table with
sources, VAT note on the campaign example. README bullet and layout line,
site DEMOS line and landing-page entry.
2026-10-14 19:24:49 +07:00
grabowski b650503ea1 Payap zoning record: type 72 condition verbatim
The annex row for type 72 in the very high density residential zone
carries the orange "permitted with conditions" mark; the condition as
printed is "ให้ดำเนินการหรือประกอบกิจการได้เฉพาะดัดแปลงหรือซ่อมแซม"
(may operate only for modification or repair). Added verbatim to the
source record.
2026-10-14 12:05:16 +07:00
grabowski 3984d0c93b Payap: the point given fails zoning (DPT, checked 14 October 2026)
Point 18.797678 N, 99.038272 E, queried on the DPT land-use plan map:
Chiang Mai comprehensive city plan in force from 25 May 2026, zone
ย.7-1, very high density residential. The zone prohibits every factory
under the Factory Act except the types in the plan's annex, and
prohibits warehouse and silo businesses.

Annex for this zone: type 107 (CD production, whose definition names
gramophone records and recorded tapes) is not permitted here, only in
the low density residential, special industrial, agricultural land
reform and rural and agricultural zones; type 72 (sound recording,
record players, gramophone records) only for modification or repair;
plastics products and metal plating are not on the list. A record
pressing plant cannot get a factory licence at that point.

Caveats recorded: point, not parcel; DPT data is preliminary, the
provincial office confirms; the pharmaceutical neighbour may be in
another zone or type. Since type 107 is permitted in the plan's low
density residential and rural zones, other Payap land is worth checking
before the lead is dropped.

- docs/land-listings/payap/: source record (zone rules, annex rows,
  the 51 types permitted in the zone) and the Thai panel text.
- site-candidates.md: plot point, zoning row, status, the result with
  caveats, check 1 marked failed for this point.
- README: project status line, layout line for land-listings/.
2026-10-14 11:58:23 +07:00
grabowski cb5809e73c Feedwater heat recovery: economizer, condensate, then HP-1
Deploy test site / deploy (push) Successful in 48s
The order to investigate for a fired boiler (biomass such as rice
husk, or LPG): first a flue-gas economizer, second as much clean, hot
condensate back to T-1 as possible, third the heat pump HP-1 where the
press return has enough heat and the combined heating and cooling
economics justify it.

- Diagram: new ECON-1 (option, fired boilers only) between the feed
  pumps and the boiler manifold, with a bypass for an electric bank and
  the flue-gas path from the boilers; feed in 90 to 95 C, outlet and
  stack temperature are vendor figures. HP-1 is now drawn as an option
  and labelled the third measure. AT conductivity on the condensate
  return to T-1; off-spec condensate goes to the warm tank.
- Found in Newbilt's offer 240620-04: steam and cooling water share the
  mould channels, with one steam/water outlet valve and steam trap per
  mould, so the condensate is only as clean as the cooling loop. Noted
  in the T-1 detail, sustainability.md and as a Newbilt RFQ question.
- With most condensate returned (about 15 % flashes at atmospheric
  pressure, estimate) the feed tank needs only a fraction of the ~70 kW
  that heating all make-up takes, so HP-1 may not pay.
- RFQ: economizer outlet feed and stack temperature, corrosion limit,
  pressure drop; rice husk ash is high in silica and abrasive, so
  fouling, cleaning, wear protection and a bypass.
- sustainability.md: the order, before the exclusions. biomass.md: new
  "Recovering heat at the boiler".

Checked headless (scripts/pw_sc_check.py): 33 boxes, 20 tags, no
overlap or overflow, no unstyled pipes, no card or page overflow at
1600, 1258 and 390 px in all four cases, every box opens its detail, no
errors.
2026-10-14 11:03:34 +07:00
grabowski b1c18cb040 Steam and cooling: water and steam temperatures on the diagram
Deploy test site / deploy (push) Successful in 47s
Twenty temperature tags on the pipes, each styled by its basis: green
border for a Newbilt figure, amber for a design target or estimate,
dashed for a value the vendor or a measurement still has to set.

- Newbilt: steam main 10 bar ~180 C, header to the presses ~180 C,
  press outlets ~60 C (one per press, dimmed with the press when it is
  not installed in the selected case), supply header 20 to 25 C, oil
  cooler return <= 35 C (supply plus max. 10 K).
- Design target or estimate: raw water ~28 to 30 C (ground
  temperature), feed to the boilers 90 to 95 C, heat pump feed loop
  <= 95 C, condensate after the traps <= 100 C (atmospheric return),
  extruder returns <= 35 C (2 to 3 kW at 4 l/min), heat pump source in
  <= 60 C, return header up to ~60 C mixed, chiller loop to HX-1 ~18
  to 23 C (~2 K approach).
- To be set: heat pump source out, warm tank mixed temperature, chiller
  loop return.

The clicked details say where each figure comes from, including that
Newbilt's 180 C is saturation at 10 bar absolute (~184 C at 10 bar
gauge, to confirm). Legend explains the three tag styles.

Checked headless (scripts/pw_sc_check.py, now also tag overflow and tag
overlap with boxes, labels, symbols and each other): 20 tags, none
overlapping or overflowing; no SVG or HTML overflow at 1600, 1258 and
390 px in all four cases; 32 boxes open their detail; no unstyled pipes;
no errors.
2026-10-14 10:33:38 +07:00
grabowski eb0039179b Steam and cooling: visible heat-recovery loop, tables inside their cards
Deploy test site / deploy (push) Successful in 52s
- The feedwater loop between HP-1 and T-1 was drawn with class "hr",
  which had no stroke rule, so it was invisible. It now has its amber
  stroke, flow arrows both ways and a "feed loop" label.
- Number cells were white-space:nowrap, so the operating-case table ran
  up to 33 px past its card, the design basis table up to 312 px, and a
  phone page was 842 px wide. Numbers may wrap now (only the coverage
  percentages stay on one line), the side column and grid tracks may
  shrink, and units moved into the case table's row labels. Only the
  diagram scrolls sideways on a phone.

Checked headless (scripts/pw_sc_check.py, now also HTML card/table
overflow, document width and unstyled pipes): before, 'p hr' unstyled
and card overflow at 1600, 1258 and 390 px in every case; after, no
unstyled pipes, no card or table overflow and document width equal to
the viewport at all three sizes and four cases, no SVG overlap or
overflow, 32 boxes open their detail, no errors.
2026-10-14 10:14:31 +07:00
grabowski 7af5d89dd0 Steam and cooling plant for the five-press fleet; utilities re-based
Deploy test site / deploy (push) Successful in 44s
New page docs/steam-cooling.html (site /demos/steam-cooling/): the
utility plant as a clickable process diagram. Steam side: raw water,
softener and dosing, feed tank with heat-pump feedwater recovery, feed
pumps, a bank of two 500 kg/h boilers (third for N+1 as an option),
separator and metering, optional accumulator, blowdown, the 10 bar
header with a valved, metered branch and trap per press, drip legs and
condensate return. Cooling side: Newbilt's press outlets are open (max.
2 bar), so returns drain to a warm tank, pass the heat pump, an optional
dry cooler and a plate heat exchanger to a cold buffer tank, and VFD
pumps feed the 20 to 25 C header at ~10 bar to every press, the
extruders and the central hydraulic oil cooler; the chiller loop
(three 250 kW air-cooled modules at 40 C ambient, fourth as option) stays
closed and clean. Galvanics cooling (12 to 20 C) is a separate circuit.
Operating cases (launch, Duplex system 1, five presses, one module down)
show demand against installed capacity; design basis with sources,
equipment schedule, RFQ questions. Static SVG, no per-frame work.

Design basis at Newbilt's per-machine figures: steam 750 to 900 kg/h,
cooling 652.5 kW (625 presses, 15 extruders, 12.5 hydraulics), 305 to
540 l/min circulating. Also found: Newbilt's 53 l/min at ~60 C out is
~140 kW, above its 125 kW peak; listed as a re-quote question.

Re-based in the same commit:
- scale.md: electrical table (chiller bank ~210 to 325 kW electrical,
  plant peak ~430 to 700 kW, ~950 to 1,330 kW with electric steam),
  grid 800 to 1,000 kVA (1,250 to 1,600 with electric steam, Schedule
  4 past 1,000 kW), tariff 4.5M to 6.8M THB/yr, battery ~1 h of chiller
  peak, boiler and chiller banks, biomass up to ~550 t/yr at 1.5 M
  records, utilities money line.
- sustainability.md, biomass.md: same figures; electric steam 5.2M to
  6.0M THB/yr mature, 1.6M to 1.8M early; fuel saving 4.0M to 5.4M.
- utilities CSV: boiler bank, chiller bank with HX and tanks, softener
  and loop treatment re-sized; baseline 23.98M-41.63M -> 30.07M-51.33M.
- total-investment.md: re-size as an added-scope row (+185k / +294k
  USD); headline 4.7M to 8.9M unchanged until the investment re-base.
- pressing-line, equipment-suppliers, facility-security, fleet
  calculator (boiler 1000 kg/h, chiller 750 kW), plant page detail
  texts; README, landing page, build.sh.
2026-10-14 09:58:27 +07:00
grabowski 9b03e4de07 Plant overview: header bands follow the rounded box corners
Deploy test site / deploy (push) Successful in 44s
Every machine box has rounded corners (rx 4), but its header band was
a square rect inset by 1, painted over the box. At both top corners the
band's square corner covered the inside of the curved border, so the
border looked thin and squared off there, most visibly on a selected
box. The band is now a path with top corners of radius 3, concentric
with the box.

Measured on zoomed crops in headless Edge (light theme, selected
border): border thickness along the 45-degree diagonal against the
straight edge was 0.26 to 0.42 on the Traceability box, Classic C1 and
the VEX 50; now 0.9 to 1.13. Full UI check unchanged: all press states,
47 stations, demo buttons, no overflow, canvas alignment, no errors.
2026-10-14 09:27:49 +07:00
grabowski f776025b58 Plant overview: motion on canvas, no more lag
Deploy test site / deploy (push) Successful in 53s
The page spent most of each second laying out the SVG, not simulating:
the simulation itself costs ~26 ms per simulated hour. Profiled headless
on Edge (CDP metrics and a timeline trace with invalidation tracking):

- tokens asked the DOM for getPointAtLength right after writing a
  transform, which forced a layout of the whole SVG for every token,
  every frame (540 to 630 ms/s);
- ~55 CSS stroke-dashoffset animations repainted the drawing all the
  time;
- the press platens were SVG rects moved every frame, and any geometry
  write re-lays-out the whole SVG with its 275 text labels.

Now the SVG holds only the machines and labels. Pipes, flow dashes and
the conveyor are drawn on a canvas under it; tokens, records, platens,
cakes, the extruder screw and plating bubbles on a canvas over it, both
with the SVG's own viewBox transform, so pan and zoom need nothing extra.
Routes are measured polylines (ptAt) instead of DOM path queries, and
the 5 Hz tag, lamp and KPI writes only touch the DOM when the value
changes.

Headless Edge, 1600 x 900, before -> after:
  1x     26 -> 60 fps, layout 842 -> 26 ms/s, long tasks 19 -> 0
  60x    19 -> 59 fps, layout 858 -> 29 ms/s
  600x   18 -> 60 fps, layout 855 -> 30 ms/s
  3600x  33 -> 60 fps, layout 726 -> 29 ms/s

Behaviour unchanged: all press states seen at 3600x, 47 stations open
their detail, steam dip holds and recovers, lot and repress log, no text
overflow at 1600 x 900 and 1258 x 800, canvas and SVG agree within
0.2 px at fit, zoomed, 1258 x 800 and phone size, both themes, no
errors.
2026-10-14 09:16:38 +07:00
grabowski 53f3a07a45 Unified Engelbert Strauss workwear for all staff
Deploy test site / deploy (push) Successful in 43s
User, October 2026: we want unified Engelbert Strauss work clothes.

- worker-safety.md: decision recorded; everyone, office included, in the
  same Strauss workwear with the company logo, process PPE on top. Kit at
  Strauss catalogue prices checked October 2026 (incl. 19 % German VAT,
  which drops out on export): production 3 trousers e.s.motion 2020, 3
  polo shirts, 2 T-shirts, a sweatshirt, S1 safety shoes e.s. Vasegus II
  low, ~293 EUR before VAT, ~338 with embroidered logos (embroidery price
  an estimate); office 4 polos and a softshell jacket, ~127 EUR. Ordering:
  Strauss ships outside Germany where customs law allows, shipping quoted
  with the order, prepayment, duty and taxes charged to the recipient;
  Thai duty on work trousers 13.8 %, BOI does not cover clothing. About
  9k USD (~0.3M THB) a year at the start fleet. Check lighter lines for
  the press hall heat with samples.
- revenue-model.md: workwear noted on top of the x1.3.
- Fleet calculator: workwear line under labour (production and office
  kits a year, shipping and Thai duty), six new assumptions; 8,573 USD a
  year at the defaults.
2026-10-10 20:46:27 +07:00
grabowski 8032e0ea47 BOI: machinery import duty and import VAT, PVC duty relief
Deploy test site / deploy (push) Successful in 35s
User, October 2026: take the BOI duty-free import and VAT exemption into
consideration.

- boi.md: import VAT goes with the BOI duty exemption (Revenue Department
  answer on the BOI OSOS FAQ, checked October 2026); what it is worth:
  ~2.75M USD of imported machinery at the start fleet (block midpoints)
  would otherwise carry ~5 % duty (Thai MFN averages 4.1 % on HS 8477,
  0 to 10 % across HS 84; estimate until the HS codes are set), ~0.14M
  USD, and 7 % import VAT, ~0.2M paid at the border and recovered later
  as input tax, mostly as a refund claim since exports are zero-rated.
- total-investment.md: the blocks are vendor prices without duty or
  import VAT, so the headline already assumes promotion.
- Fleet calculator: BOI promoted / not promoted switch and export share.
  Not promoted adds the machinery duty to capex and depreciation, shows the
  import VAT as cash at the border, and charges duty on imported PVC
  compound; promoted exempts both, with no compound duty on exported
  records and 90 % off for domestic sales (sections 36(1) and 30). A note
  under the KPIs shows what promotion saves either way. Defaults: payback
  3.1 years with BOI, 3.2 without; adverse case operating result -31k
  with BOI, -68k without. CIT and BOI CIT exemptions still not modelled.
2026-10-10 20:29:32 +07:00
grabowski 1a368287f8 Labour from base salaries; health care with check-ups for all staff
Deploy test site / deploy (push) Successful in 34s
User, October 2026: option to enter base salaries; the company should
provide proper extra health care with check-ups for all staff.

- worker-safety.md: new "Health care for all staff" policy (decided
  October 2026): group health insurance (inpatient and outpatient) and a
  yearly check-up for everyone, office included, on top of social
  security; the occupational checks Thai law requires for risk-factor
  work (Ministerial Regulation B.E. 2547: within 30 days, then yearly, by
  an occupational physician, records kept 2 years after the job ends) for
  the press floor, galvanics and maintenance; planning costs with sources
  checked October 2026 (group insurance ~8,000 to 18,006 THB a head a
  year, plan ~15,000; Rajavej Chiang Mai check-ups 1,290 to 5,990 THB,
  plan ~2,500 plus ~1,500 risk-factor tests, estimates); social security
  5 % up to the 17,500 THB ceiling since 1 January 2026.
- revenue-model.md: cutting engineer 50,000 THB is base salary; health
  care on top of the x1.3 (~0.35M THB a year at the start fleet); what the
  x1.3 is made of.
- Fleet calculator: base salaries per role (the revenue model loaded
  rates / 1.3; cutting engineer 50,000), employer social security 5 %
  capped at 17,500, 25 % overtime, bonus and PPE, health insurance and
  check-ups for all staff incl. 4 office staff (scale.md 3 to 5), risk-
  factor tests for the press floor, galvanics and maintenance; all as
  editable assumptions; people table gains office and all-staff rows.
  Defaults: labour 5.25M THB (was 4.67M loaded), direct cost 1.90 USD a
  record, EBITDA 2.19M USD.
2026-10-10 20:17:39 +07:00
grabowski eac45eb234 Lacquer blank 70 EUR and cutting engineer 50,000 THB a month
Deploy test site / deploy (push) Successful in 39s
Team figures, October 2026:
- revenue-model.md: a lacquer blank costs about 70 EUR, one per side, so
  ~160 USD a two-sided title before recuts; a cutting engineer costs about
  50,000 THB a month;
- fleet calculator: the lacquer assumption is now in EUR (70, one per
  side, converted at 1.155 USD per EUR; styli and recuts not included)
  and the cutting engineer 50,000 THB a month, both marked as team
  figures instead of estimates. At the defaults lacquers come to ~54k USD
  a year and direct cost to 1.88 USD a record (was 1.86).
2026-10-10 20:12:26 +07:00
grabowski ce1d71e0b5 Fleet calculator: material, energy and labour cost, revenue and P&L
Deploy test site / deploy (push) Successful in 36s
User, October 2026: add calculation for material cost, PVC, carton,
chemicals, labour etc. and revenue from sales.

New "Money a year" card (and a "Prices and money" input card):
- revenue: standard records at the standard price, specials with the
  premium, title services per title (revenue-model.md 3.50 to 4.60
  blended, +0.60 to 1.70, 580 to 1,730 USD a title);
- materials and packaging: PVC from the compound tonnage (rejects in,
  trim back as regrind), labels per pressed record, inner sleeves,
  printed jackets, shrink wrap, shipping cartons (estimate), maintenance;
- stamper making: lacquer blanks and styli per side (estimate), nickel,
  silver and chemistry per electroformed part (revenue model: 60 to 150
  USD a three-generation set);
- energy from the fleet: machines, chiller and compressors at the hours
  run plus an estimated base load, roof PV off, PEA 3.2.2 blended rate and
  demand charge; steam from the presses running time at the biomass heat
  price (biomass.md); the start fleet lands in scale.md 4.3 to 6.4M THB;
- loaded labour per role (revenue-model.md wages; cutting engineer an
  estimate), headcount now also counts QC, maintenance and cutting;
- overheads, EBITDA, depreciation of capex (total-investment.md start
  fleet plan plus or minus each Duplex system and Classic), operating
  profit, payback; per-record cost bar;
- Adverse / Central / Favourable presets from the revenue model ranges,
  USD / THB / EUR display; ladder gains revenue and EBITDA columns.
At the defaults (1 M records, 20 % specials): revenue 4.42M USD, direct
cost 1.86 USD a record (revenue model central 1.94), EBITDA 2.23M.

README bullet; revenue-model.md links the calculator from its operating
picture.
2026-10-10 19:41:08 +07:00
grabowski 7d7a378c8b Fleet calculator: machine park schematic with the stamper line feeding it
Deploy test site / deploy (push) Successful in 34s
User, October 2026: add a visualization of the machine park and the
connected stamper production to the tool.

- New card "Machine park and stamper production": one live SVG that
  follows every input. Top: the stamper line, lathe, Pheenix PASU, PPPU,
  PDPU (2 cells), PMPB, Sibert VSF, VSP, VSC, each with its count, flow a
  day and how busy it is. Middle: the press hall, each Duplex cell drawn as
  in the cell sketch (presses either side of the operator, EX 50 and EX 35
  behind, trimmer in front) and each Classic with its built-in extruder,
  wrapping into rows and scaling down for big fleets; compound in on the
  left, stamper rack in and finishing out on the right. Bottom: central
  hydraulics, boiler, cooling, air and electrical piped up into the hall,
  amber where they exceed the plant as planned today.
- Stamper production is now counted per station from the cycle times in
  galvanics.md (silvering, pre-plate four at a time, father, mother,
  stamper plus handling per PDPU cell, PMPB, Sibert steps; usable share of
  the hours 80 %, estimate) instead of a flat 20 to 32 parts per PDPU.
  At the defaults: 1 PDPU at ~43 % busy, as galvanics.md concludes.
  New assumptions with sources; the lathe rate (8 sides a day) is an
  estimate.
- Requirements table: per-station counts and load; the URL hash now also
  reloads in an open tab (hashchange).

Checked headless in Edge, both themes: no JS errors, no text overlap or
overflow in the schematic at the default, 8 M and 30 M records, no
horizontal overflow at 390 px.
2026-10-10 19:30:05 +07:00
grabowski 6df1301fb9 Site: light and dark mode for the landing page, plant overview and fleet calculator
Deploy test site / deploy (push) Successful in 36s
User, October 2026: add bright/dark mode to the site for both tools.

- Each page sets data-theme on <html> before first paint: the saved choice
  (localStorage "cnx-theme", shared by all cnxvinyl.lol pages) or, without
  one, the system setting (prefers-color-scheme), which it keeps following
  until the user picks a mode. Toggle: header button (sun / moon).
- Plant overview: light overrides for every SVG class; pipe colours are
  now CSS variables (--p-*), used by the pipes and the legend, darkened in
  light mode where the dark-mode tints were too pale (DI water, granulate,
  stamper sets, cooling return); press state text and the VEX zone fills
  use variables instead of inline hex, so they flip with the theme.
- Fleet calculator and landing page: light palettes; input, flag, badge
  and ladder-highlight colours moved to variables.

Checked headless in Edge: both system schemes pick the right mode, the
toggle persists across pages, computed colours flip (press text, zones,
pipes, legend), no text overflow in either mode, no JS errors.
2026-10-10 18:27:58 +07:00
grabowski c6bec71442 Press fleet calculator: target output and specials share to fleet mix and needs
Deploy test site / deploy (push) Successful in 37s
User, October 2026: calculations for the later business plan, starting
from 2 Duplex + 1 Classic at 3 records a minute per Duplex and 2 per
Classic, as an interactive tool on the website: pick the yearly output
and the share of splatter/specials, get the machine mix and all the
requirements (people, hydraulics, power, ...).

docs/fleet-calculator.html (single static page, no dependencies):
- target mode sizes the fleet (specials only on Duplex with its EX 35;
  grow with Classics or with Duplex systems; start fleet as the floor);
  fleet mode takes a fleet and gives its output at the specials share;
- output, capacity, utilisation and the mix bar per machine type;
- needs: people per shift and in total, galvanics operators, machines,
  connected kVA and average kW, MWh/yr, central hydraulics (flow, motor,
  oil, accumulator), steam, cooling and cooling water, compressed air,
  press floor, room climate, compound, trim, titles, electroformed parts
  and plating units; checks against the 400 kg/h boiler, 250 kW chiller
  and the 870 m2 Payap press hall;
- ladder from the start fleet to a full Payap press hall, click to load;
- every assumption editable with its source (Newbilt Duplex site
  requirements V14 and offer 240620-04, scale.md, galvanics.md, revenue
  model, Payap model; estimates labelled), shareable link via the hash.
The Classic counts as one HRP 12 press plus one extruder until Newbilt
states figures (Toolex Alpha leaflet as a cross-check).

Site: DEMOS entry (/demos/fleet-calculator/) and landing-page entry.
README bullet and layout line; backlinks from scale.md (capacity) and
pressing-line.md (current plan).
2026-10-10 18:21:47 +07:00
grabowski 68539d563c Payap model: main gate, guard house, boom barrier; truck paving cut down
User, October 2026: add the guard house and the gate; the truck apron is
far too big.

Model (changed live in FreeCAD 26.3):
- main gate as in the phase 1 RFQ: piers and two 5 m sliding leaves (shown
  open, parked inside the wall), 10 m clear (gate_width 8 -> 10 m);
- guard house as in the RFQ: 4 x 3 m (guard room 8.4 m2 + WC 3.6 m2),
  window wall to the gate, guard desk, on the gate's north-west side;
- boom barrier just inside the gate (cars and trucks both pass it);
- truck paving: the 42 x 101 m apron (~4,240 m2) replaced by an 8 m gate
  road (550 m2) and a 32 m deep apron and dock face (1,600 m2) that joins
  the east service road; new params apron_depth, road_w.

Docs: site-candidates Access bullet (~2,150 m2 heavy-duty paving against
1,608 m2 in the Mueang Chi RFQ).
2026-10-10 17:58:18 +07:00
grabowski 90697c8cac Payap model: Duplex cells at Newbilt sizes; fire water per facility-security
User, October 2026: the Duplex sketch is not to scale, check it against
the documents; the fire water tank is too small.

Model (changed live in the open FreeCAD 26.3 document):
- both Duplex cells rebuilt in the sketched arrangement at the documented
  sizes: presses 0.95 m square (0.9 m2) turned 45 deg, EX 50 0.5 x 1.0 m
  (0.5 m2), EX 35 0.4 x 0.8 m and trimmer 0.6 x 0.6 m (estimates),
  operator position marked; 0.6 to 0.8 m between machines;
- fire water: the ~25 m3 yard tank replaced by the facility-security
  planning tank, 9 m x 4 m (254 m3 gross, ~200 m3 usable), new params
  fw_dia, fw_h, fw_x, fw_y, at the front by the access road, outside the
  production yard, on a ring foundation, with a pump house (duty electric,
  standby diesel, jockey); the yard process water tank is now the 5 x 3 m
  raw water tank of the phase 1 RFQ.

Docs: site-candidates (cell, raw water, fire water bullet),
facility-security (the Payap model draws the tank; 6 m racking and twice
the floor area make ~200 m3 a floor there).
2026-10-10 17:43:09 +07:00
grabowski 7da64088ce Duplex cell layout: one operator, presses turned towards him
User sketch, October 2026 (filed as docs/equipment/
duplex-cell-layout-sketch.png; arrangement only, the user notes it is not
to scale): operator in the middle, the two presses either side turned 45
degrees towards him, EX 50 and EX 35 side by side behind him, one trimmer
per cell in front on the left.

Sized from the Newbilt site requirements p. 10 (press ~0.9 m2, extruder
~0.5 m2, hydraulic aggregate ~1.0 m2, walk-around space, >= 60 cm to
walls, room height >= 2.5 m): cell ~5 x 3 m, 0.6 to 0.8 m between
machines; EX 35 and trimmer footprints are estimates. The layout drawing
the site requirements refer to on p. 11 is missing from our copy: ask
for it with the re-quote. README layout line for the sketch.
2026-10-10 17:43:00 +07:00
grabowski 83840d45dc Payap model v4: colour store, silos, two-storey finishing and print block
User, October 2026: ground-floor colour store plus outdoor silos; a
two-storey block at the east end with packaging below and printing plus
print and packaging stock above; in-house printing not decided, so the
print room is reserved only.

Model (rebuilt live in FreeCAD 26.3 after checking a copy of the saved
file for user edits; parametric check plot 150->160 m and upper floor
3.8->4.2 m passed):
- factory 128 x 25 m, plot 150 m (14.1 rai), corridor 98 m, fire wall
  at 106 m, new params crane_x (runway end = press hall end, 92 m) and
  mezz_z (+3.8 m);
- galvanics open to stamper prep (wall kept only on the material area
  and electrical side);
- colour store 10 m bay (~180 m2): two racking rows, ~100 pallet
  positions on 4 levels (estimate), weighing and mixing, vacuum
  conveying station; indoor silos replaced by regrind bins;
- 4 outdoor PVC silos (2 black, 2 standard colours, ~50 m3 each,
  estimate), big-bag filling station, buried conveying lines;
- finishing and print block 14 x 25 m: ground floor trim, optical
  inspection, QC, packaging (tables, shrink wrap, pallet wrapper), stair
  (Arch Stairs) and goods lift; upper floor print room (reserved), print
  stock, packaging materials.
New docs/cnx_vinyl_parametric_payap-block.png with both block levels.

Docs: site-candidates Payap section rewritten (areas ~3,800 m2 under
roof, ~4,630 m2 of floor), crane doc (98 m corridor, runway ends at the
press hall), README bullet and layout line.
2026-10-10 17:21:44 +07:00
grabowski d9f3a4b88e Compound storage for tens of colours; stamper prep open to galvanics
User, October 2026: special designs will need tens of colours, so the
compound store needs far more space, with maybe a few silos for black and
the standard colours; and the wall between stamper prep and galvanics is
to go.

- pressing-line: "Compound storage" bullet (colour store with pallet
  racking, ~100 positions in the Payap model, estimate; outdoor silos
  proposed; compound stays on the ground floor, ~160 to 270 t a year at
  the mature fleet; sacks vs big bags decides the silo filling).
- galvanics: stamper prep open to galvanics, one clean zone.
2026-10-10 17:21:33 +07:00
grabowski 0700c14b5c Payap model: two-storey office building with canteen, changing and showers
User, October 2026: the office building also houses several showers, a
changing room, toilets and a canteen; the office area itself about
150 m2; the building can be multi-storey.

Model (office rebuilt live in FreeCAD 26.3; factory and site untouched):
- 32 x 15 m on two storeys (off_storey 3.6 m), ~960 m2 of floor, Arch
  Stairs plus a lift, first floor slab with the stair and lift void;
- ground floor: reception and lobby (entrance and link door), canteen
  ~40 seats with kitchen and servery, changing rooms women and men with
  4 showers each and lockers, toilets, mastering and cutting (acoustic
  lining), listening room, archive;
- first floor: offices 147 m2 (16 desks), training room (Payap
  programmes), meeting room, IT and server, toilets, pantry, flexible
  room;
- factory staff entry relabelled "PPE, WC" (changing is in the office).
New docs/cnx_vinyl_parametric_payap-office.png with both floor plans.

Docs: site-candidates Payap section (office bullet, staff entry, area
~3,400 m2 footprint / ~3,880 m2 floor), README bullet and layout line.
2026-10-10 17:01:40 +07:00
grabowski 4263fbbd9b Payap model v2: bigger factory, shared plant room, separate water treatment
User, October 2026: the factory is too small and needs room to grow
(possibly ten more Classics), one shared hydraulic and air supply, water
treatment perhaps in a separate building connected to the galvanics lab,
and a fully equipped workshop (maintenance tools, 3D printers, maybe a
lathe and a small CNC mill).

Model (rebuilt live in FreeCAD 26.3, BIM objects, Params-driven,
parametric check plot 135->145 m and factory 112->120 m passed):
- plot 135 m (11.4 rai) with a reserve; factory 112 x 25 m, 16 bays,
  82 m visitor corridor, fire wall at 90 m;
- press hall ~870 m2: two Duplex systems (EX 50 + EX 35), the Classic,
  ten future Classic positions in two rows on a service trench;
- central hydraulics and compressed-air plant room (~62 m2);
- water treatment building 12 x 10 m behind galvanics: buried duct
  (gravity from the +1.2 m floor), covered crossing 6 m clear;
- workshop ~200 m2 with benches, tool cabinets, 3D printers, lathe,
  small CNC mill, drill, saw, welding bay, press, washer, measuring table.

Docs: galvanics (water treatment building, proposed), crane doc (workshop
fit-out; lathe and CNC mill not yet priced; corridor now 82 m),
site-candidates Payap section rewritten, README bullet.
2026-10-10 16:47:44 +07:00
grabowski 9e0c5d4045 Fleet: one shared hydraulic and air supply; room for ten more Classics
User, October 2026: the presses run from one shared hydraulic supply
and one compressed-air supply, and the plant may add up to ten more
Newbilt Classics at some point.

- pressing-line: fleet table and intro (shared central supply), new
  bullets on the shared supply and the expansion option, re-quote point
  (central supply for the whole fleet, extendable, can the Classic run
  from it), Hydraulics bullet now the plan.
- scale: "Expansion (option)" capacity row, ~4.7 to 5.8M records/yr on
  the same basis, explicitly outside revenue model and investment;
  utilities note: fifteen presses would need ~2.3 to 2.7 t/h steam and
  up to ~1.9 MW cooling, a utility phase of its own.
2026-10-10 16:47:34 +07:00
grabowski f2bb7f3d85 Payap scenario: parametric BIM model of the whole plant on a square plot
A separate FreeCAD 26.3 model (the Mueang Chi model is untouched) sites
the plant on a 110 m square placeholder plot of Payap land, built from
BIM objects (Arch Site, Buildings and Levels, walls, slabs, columns,
beams, a ramp, Spaces with computed areas, Equipment). Every object sits
on an expression-driven base, so the Params sheet drives plot, setbacks,
floor level, building sizes, fire wall line and office gap (checked:
plot 110 to 120 m and factory 84 to 90 m, everything followed).

- Factory 84 x 25 m, production only, in process order along a 54 m
  glazed corridor; press hall 465 m2 with the October fleet (two Duplex
  systems, each EX 50 + EX 35, and the Classic); crane to the fire wall;
  machine door and 12 m ramp at the north-west corner.
- Office building 24 x 15 m, 12 m away on its own slab with a covered
  link: reception, offices, meeting/training, mastering and cutting,
  listening, IT, archive. Resolves the crane-zone conflict of the old
  sketch.
- Utility yard behind the press hall (boiler and chiller flagged for
  re-sizing), gate, truck apron, car park, service road.
- site-candidates: new section and plot-fit note; crane doc: conflict
  resolved, 54 m corridor; README bullet and layout lines; the old
  sketch is labelled as Mueang Chi with the earlier fleet.
2026-10-10 16:31:46 +07:00
grabowski 3a758fcffb Fleet: each Duplex has an EX 50 main and an EX 35 colour extruder
Correction from the user: the two Duplex systems are not in the
two-extruder configuration. Each runs two HRP 12 presses from an EX 50
main extruder with an EX 35 auxiliary extruder beside it for a second
colour; the Classic stays. Fleet still five presses. Updated in
pressing-line (table, phasing, re-quote: EX 50 vs the VEX 50 of the 2024
quote, and whether one EX 50 keeps both presses at full rate), scale,
total investment (wording; estimates unchanged), roadmap item 4, README.
2026-10-10 16:11:46 +07:00
grabowski c50417668b Press fleet: two Newbilt Duplex systems with an extruder per press, plus a Classic
The current plan (user decision, October 2026) replaces the 50/50 target
(two semi-automatic presses and two Pheenix AD12s) with an all-Newbilt
fleet of five presses: two Duplex systems in Newbilt's two-extruder
configuration (two HRP 12 presses, an extruder each, one hydraulic unit)
and one Classic fully automatic press.

- pressing-line.md: new "Current plan" section (fleet table, what it
  means, phasing from the Single 2.1 as the first half of system 1,
  re-quote questions); site requirements per Duplex system.
- scale.md: capacity table and basis (368 to 448 records/h, ~1.06 to 1.5M
  a year on two shifts, same range as before); pressing electrical row;
  steam and cooling flagged, not re-based: five presses draw ~750 to 900
  kg/h of steam and up to ~625 kW of cooling at Newbilt's per-press
  figures, against the 400 kg/h / 250 kW sized for one Duplex.
- total-investment.md: fleet change as an added-scope row (system 2
  ~230k-300k and the Classic ~290k-460k, estimates; -60k / -160k against
  the two blocks it replaces); headline unchanged until the re-base.
- roadmap items 4, 5 and 24, revenue model mature row, crane doc (the
  Classic's weight now decides 5 t or 3.2 t), vendor landscape (AD12 is
  the comparison for the Classic), README.

The business plan docx is not regenerated.
2026-10-10 16:05:27 +07:00
grabowski f1334f4756 OMS introduction letter and links, Sibert's answer (9 October 2026)
OMS (Lou Wullms) sent its introduction letter, filed in
docs/equipment/oms/: wet-room units with reference prices, two 4-cell
configurations (EUR 224,000 basic with two EFS2-200, EUR 311,000 advanced
with one AEFS4-250 and PLC; installation days extra), capacities of 24
and 32 shells in an 8-hour day, utilities, rooms, staffing, used
equipment, and five contacts for buying a cutting lathe. Recorded in
galvanics.md (tables, our reading: the advanced units add up to EUR
314,000, know-how transfer is left out of both totals although CNX has no
plating know-how, the basic set has no passivation unit), the exhibitor
follow-ups, vendor landscape (new section on used lathes and cutting-room
contacts, plus Lou's three websites), supplier map, roadmap items 6 and
13, total investment (basis note only, block unchanged) and the scale
people estimate. Open: forward the letter to Simona, as Lou asked.

Sibert (Ian Locke, 9 October): footprints and formal quotations when we
are ready; settle the pressing side first, hopefully with Pheenix, and
mention his recommendation if we do; impressed by the green-factory
plans (supplier feedback). Open: pass on the recommendation if Pheenix is
chosen.

CNX-01 in proplan: OMS basic and advanced added as options to D-002 with
their reference prices in THB; budget line 3 notes the OMS range.
2026-10-10 15:52:23 +07:00
grabowski 90d8a3778a Record the replies to Sibert and OMS
- Sibert: back in Thailand, investor meeting in preparation, his OMS/Pheenix
  advice noted; itemised quotation not yet requested.
- OMS: met in Haarlem; role split given to Lou (Simona management and audio,
  Alexander technical); waiting for his calculation material.
- README: team roles, investor meeting in the status list.
2026-10-09 12:14:59 +07:00
grabowski 21419145f8 Replies sent to Sibert (Ian Locke) and OMS (Lou Wullms)
OMS confirmation is done; next is the calculation material from Lou
Wullms. Sibert itemised quotation still open.
2026-10-09 12:08:07 +07:00
grabowski 4fec258f15 After Haarlem: Pheenix CEO follow-up, OMS first contact, SST
- Pheenix Alpha (Robert Gunnarsson, 5 Oct; Simona's reply 9 Oct): offers
  a Teams call, reference clients and a factory visit near Stockholm;
  300+ presses (vendor figure); we call once questions are concrete,
  next Europe trip planned for February 2027. CEO contact and Marsta
  address added.
- OMS (Lou Wullms, 7 Oct): first email contact, company data, contacts
  (Lou Wullms technical, Wilma Peeters accounting/logistics); open: reply
  to confirm, then OMS sends material to calculate from.
- SST Frankfurt (Daniel Krieger, 7 Oct): cut the lacquers for POY003,
  005, 006 and 013; on good terms with ResurRec; offered help. New cutting
  service entry in the supplier map and vendor landscape; corrected the
  briefing, which had SST as DMM (its site lists lacquer and dubplates).
- Roadmap items 5, 6 and 14 and the production timeline launch basis
  updated accordingly.
2026-10-09 06:38:52 +02:00
grabowski 47e5f9e458 Biomass: reported northern fuel prices (October 2026)
No public price index exists; DEDE lists buyers, not prices. Reported
market prices: fresh chips 1,350-1,800 THB/t (LH Bank, Mar 2026),
rubberwood firewood >1 THB/kg farm gate (OIE RIU 2026, doubled since late
2025), corn residue 2 THB/kg (Sunsweet, Mae Chaem), rice husk ~1.5 THB/kg,
pellets 3,000-5,000 THB/t. Planning price 1.35-2 THB/kg delivered, so the
mature fuel bill is ~0.6M-1.2M THB/yr (was 0.35M-0.8M): still a quarter
to a tenth of electric steam. Prices follow diesel; Ratch Pathana's Pa Sak
(Lamphun) buying centre is the local price-setter. Sources filed under
docs/finance/biomass/; sustainability.md and README follow.
2026-10-07 10:08:54 +02:00
grabowski 9640a4f075 Energy: PEA tariff, electric vs biomass steam, PV vs solar thermal
PEA tariff schedule (May 2023 onward, still current) filed under
docs/finance/pea/; Ft 0.1623 THB/kWh for Sep-Dec 2026 from the PEA Ft page.
The plant falls under Schedule 3.2.2 (Medium General Service, TOU, 22 kV).

New section in sustainability.md: blended ~3.81 THB/kWh for two-shift
production plus 132.93 THB/kW demand charge; electric steam ~4.7M-5.5M
THB/yr at maturity against ~0.35M-0.8M of biomass fuel; self-consumed PV
worth ~3.7 THB/kWh (~4.5-7 yr payback); solar thermal not recommended;
the battery earns little from TOU arbitrage or peak shaving. biomass.md,
scale.md, the utilities CSV note and the README follow.
2026-10-07 09:54:31 +02:00
grabowski 79e8cddcff Production hall: rough BIM layout sketch
FreeCAD BIM (Arch) sketch of the 60 x 25 m phase 1 hall:
Building > Ground floor with Spaces for every zone (areas computed),
room-in-room partitions, the fire wall at 48 m, the 5 t crane runway,
and the main equipment as BIM Equipment (Pheenix line, Sibert row,
Newbilt Duplex and two Classic presses, silos, racking). Zones run in
process order along the visitor corridor. Top-view PNG alongside.
Linked from the README and from the crane doc, with the one conflict it
shows: reception and cutting room under the crane travel.
2026-10-07 09:40:13 +02:00
grabowski 856e0a2ccf Add the Poy Records logo
docs/brand/poyrecord-logo-1536x1536.png (1536 px PNG), shown at the top
of the README and listed in the repository layout.
2026-10-07 09:24:35 +02:00
grabowski 6888abe602 Sibert follow-up: USD 250k budget, current VS specs, OMS as galvanics option
Deploy test site / deploy (push) Successful in 41s
Ian Locke's email of 5 October 2026 after Making Vinyl Europe:

- Budget of USD 250k for VSP, VSF and VSC confirmed; his time, spares,
  shipping and travel extra; itemised quotation on request. The
  total-investment block keeps its estimate until the re-base, the
  difference (+190k low case / +80k high case) goes into the
  not-yet-rolled-up table.
- Current specifications filed (VSF and VSC 2022, VSP 2023) plus the
  VSF/VSP/VSC line-up drawing (4958 x 833 mm); the 2021 issues move to
  sibert/specs-2021/. VSC is now 1000 kg with split OD hydraulic / ID
  pneumatic forming; VSF 0-30 psi, 4-station head. Crane table, supplier
  map, vendor landscape and the plant page details updated.
- Fully automatic VSPa exists; Sibert offers to move features to the VSP.
- Electroforming: OMS (Optical Media Services, Lou Wullms) named next to
  Pheenix; added as a third galvanics candidate with open questions.
- Sequencing advice (presses, boilers, operators and live feedback loops
  first) recorded in the exhibitor briefing, roadmap item 23, and as
  digital-factory design decision 9 (operators see the data first).
2026-10-07 09:24:11 +02:00
grabowski b672c58e34 Plant page: mature fleet at real cycle times
Deploy test site / deploy (push) Successful in 34s
Rebuild docs/plant-operation.html from the single P1 press into the mature
plant: Newbilt Duplex (two HRP 12 on a VEX 50, EX 35 for splatter), two
Newbilt Classic automatic presses with edge trimmers, label punch and
Granulator 400; Pheenix Alpha PASU, PPPU, two PDPU and PMPB; Sibert VSF,
VSP and VSC in that order; father and mother archive and the stamper rack.

Time runs at 1x real time with speeds up to 3600x. Press cycles are
Newbilt's (Classic 28 s, Duplex ~30 s), plating follows Faraday's law at
the PDPU current, and the operator steps use the galvanics.md table, with
unpublished times marked as estimates. Titles flow through the three artist
gates in days; test pressings unmount and the presses run approved work
meanwhile; worn stampers and represses come from the archived mothers.
Two shifts, unplanned press stops sized to scale.md's 60 to 70 %
effectiveness, and demos for a steam dip, a new PVC lot and a repress.

The boiler and chiller are shown at 800 kg/h and 500 kW (estimates) and
the detail panels flag that scale.md's 400 kg/h and 250 kW are Duplex
figures; scale.md itself is unchanged.

Also commits the galvanics.md cycle-time table the page runs on (one PDPU
covers demand, the second is redundancy) and updates the README and the
test-site descriptions.
2026-10-03 22:47:57 +02:00
grabowski 9b26cfbf7c PVC lab: instrument list with estimates, and cost it
quality-automation.md: the day-one per-lot tier becomes a table with an
instrument class and a rough price per check (moisture analyzer, strip
oven, density balance, spectrophotometer, gloss, sieves, muffle furnace,
stereo microscope), plus what was missing: a lab plaque press or two-roll
mill so speck, color and DSC tests do not tie up a production press;
sample conditioning as part of the method at 60 to 90 % ambient humidity;
magnets for metal in lots and regrind. Day-one tier ~USD 55k to 150k
(estimate); Karl Fischer and the ISO 182 Thermomat as options. Mature tier
priced (~120k to 240k), handheld XRF as an option, and partner labs (Payap
pharmacy, CMU science) to defer it.

total-investment.md: the day-one tier goes into "Added scope, not yet in
the roll-up" (55k to 150k USD, 1.8M to 5.0M THB); added total now ~290k
to 690k USD, about 7 to 9 % on the subtotal. Headline total unchanged.
2026-10-03 21:51:00 +02:00
grabowski c56d403da0 Record the Making Vinyl feedback on traceability
Most people the team talked to in Haarlem were strongly interested in the
full-traceability approach. For Sibert it was one of the reasons to talk to
us at all; without it their representative would strongly advise against
the plan, and seeing buildfor.life's development and data work convinced
him the project comes from the right direction.

Exhibitor briefing gets an "After the show" section (feedback, what has
been filed since); traceability.md opens with the market signal; roadmap
item 1 notes it as supply-side evidence, with buyer prices still missing;
README project status updated (show attended, Payap lead).
2026-10-03 21:39:45 +02:00
grabowski ffbc46782a Add the Payap University partnership: joint student programmes
Payap also wants to work closely with the project on new student
programmes: audio engineering (mastering, lathe cutting), IT, business
administration and more.

New docs/payap-partnership.md: why it fits (mastering/cutting engineers
are the hardest hires; Payap has music, IT, business, communication arts,
an English-language International College and pharmacy labs; the plant has
a lathe, production data and a real factory application), programme areas
mapped to the docs they draw on, and what it changes: a reason to bring
the cutting room (roadmap item 27) forward, a cutting engineer before the
students, lacquer and stylus cost of teaching, pre-release security for
customer audio, student access and safety, IT work on staging only, the
link to the Payap land, BOI R&D merit. Suggested form: MOU, internships,
short certificate courses first, degree tracks later; what to settle in
writing and questions for the next meeting.

Links from README (bullet, layout), site-candidates, roadmap item 27, the
supplier map's open training item and the BOI open items.
2026-10-03 21:36:17 +02:00
grabowski 31d89faf03 Add Payap University land as a site candidate
Payap University (Chiang Mai) is interested in leasing land to the
project; a pharmaceutical facility is under construction on the same land.

New docs/site-candidates.md puts the three options side by side (Mueang
Chi lease, Northern Region Industrial Estate, Payap) with the public facts
on Payap (Mae Khao campus on the Chiang Mai-Lampang superhighway, bought
as low-lying land, ~275 acres; Faculty of Pharmacy cosmetics production
facility tendered July 2024; RPAH cannabis/herbal bioreactor centre), why
it is attractive (5 km from the old city, a university partner with music,
pharmacy and labs, production already being built there) and the checks
that could rule it out, in order: zoning for pressing, boiler and later
electroplating; whether the university can lease to a company; the GMP
neighbour's sensitivity to our emissions (argues against biomass steam
there); flooding; plot fit; galvanics consent. Questions for the next
meeting listed. Nothing re-sited: model, RFQ and site code stay on
Mueang Chi until a plot is known.

README (intro, bullet, layout), roadmap item 9 and the lease fork in
project-timeline link to it.
2026-10-03 21:31:25 +02:00
grabowski 81f3279efd Add Pheenix galvanics flyers and Sibert stamper prep specs
Deploy test site / deploy (push) Successful in 45s
docs/equipment/pheenix-alpha/: the four Pheenix Alpha electroforming flyers
(2024: PASU silvering, PPPU pre-plating, PDPU dual-cell plating, PMPB
passivation bench), renamed from their download hashes.
docs/equipment/sibert/: the VSP, VSF and VSC technical specifications
(2021), plus Sibert's 2008-09 optical-disc SPS literature and the 2008
Blu-ray stamper characteristics paper in sps-optical-disc-2009/. Two
byte-identical duplicates in the download were dropped.

New docs/equipment/galvanics.md, the metal-path counterpart to
pressing-line.md: datasheet tables for both ranges and what they change.
Pheenix is a second turnkey galvanics vendor next to Digital Matrix and
can quote lacquer-to-record as one vendor; neither range includes water
treatment. Utilities from the sheets (~27 kVA connected per line, DI water,
12-20 C cooling water, extraction sizes), ~5.6 m2 of footprint, and a cell
count estimate (one PDPU at the low end, two at the high end). The Sibert
machines are single-phase, 200/250/600 kg on castors, centre manually and
list no data interface; the VSC locates on the punched hole; the finisher's
water carries nickel. Weights, cycle times, prices and mould fit are listed
as quote questions.

Backlinks and small updates: README (bullet, layout tree, vendor list),
roadmap items 6 and 23, vendor landscape, supplier map, exhibitor briefing
(on-file notes, Sibert three-phase question answered), digital factory
(Pheenix PLC data, Sibert data question, RFQ clause 5), quality automation
(hardness on the centre slug, BD paper as the acceptance-spec model),
sustainability (finisher water), total investment block label (numbers
unchanged), scale (galvanics feeder note), crane weight table, process
flow, pressing-line stamper-fit question, plant page detail lines.
2026-10-03 21:05:00 +02:00
grabowski 293979bef8 Supplier list: drop the last em dash 2026-10-02 21:54:25 +02:00
grabowski 88220bcd1f Supplier list: drop the two remaining em dashes 2026-10-02 21:54:14 +02:00
grabowski 725f0cc9d1 Add the Newbilt flyers from Making Vinyl Europe 2026
Deploy test site / deploy (push) Successful in 35s
docs/equipment/newbilt/flyers-2026/: the six 2026 product flyers
(Classic, Duplex, EX 35, Edge Trimmer, Granulator 400, Label Punch) and
the 2024 Classic print flyer, collected at the booth in Haarlem.

pressing-line.md gets a range table with the flyer figures and what they
change: Classic and Duplex share inserts (one mould family for a
Newbilt-only fleet, Classic now named as automated candidate next to the
Pheenix AD12), edge trim of 20 to 40 g per 12" 180 g record brackets the
~20 % regrind share, the Granulator 400 runs in batches, central
hydraulics is an option, and the EX 35 is not in the 2024 quote.

Sources disagree on the Classic's panel (two 21" vs one 10"), extruder
power (7.5 kW drive in the 2024 flyer vs 15 kW noted earlier) and 10"
support; recorded as re-quote points instead of picking one. Supplier
table and exhibitor briefing corrected to match and given Erwin Neubauer
as a second contact; plant page grinder detail cites the flyer figures.
2026-10-02 21:53:45 +02:00
grabowski e23be20b13 Plant operation page: work on phones and tablets held sideways
Deploy test site / deploy (push) Successful in 37s
The header no longer forces a 1,600 px layout: it wraps on tablets and
narrow desktops (all nine KPIs now fit at 1,600 px, one was clipped
before), and on short screens (max-height 560 px, i.e. phones in
landscape) it collapses to one row with a scrolling KPI strip. There the
detail, event log and legend move into a side sheet (Info button, opens
by itself when a station is tapped), so the drawing gets the full height.

The drawing pans and zooms by viewBox, so the sim coordinates are
untouched: pinch and drag on touch, wheel and drag with a mouse, plus
zoom buttons and +/-/0 keys. A drag or pinch never selects the station
under the finger. Uses 100dvh and disables iOS landscape text inflation.
Upright phones get a hint to turn sideways.

Checked in Chrome device emulation at 667x375, 740x360, 844x390,
932x430, 1024x768, 1180x820, 1366x1024, 1258x800, 1600x900, 1920x1080
(no horizontal overflow, zoom controls clear of every station) with real
touch input (tap, tab switching, pinch, drag) and a 10x sim run without
errors.
2026-10-02 21:33:04 +02:00
grabowski 52bf35f183 Deploy workflow: check the SSH key and log its fingerprint
Deploy test site / deploy (push) Successful in 36s
A first run failed with "Permission denied (publickey)": s1 accepts only
the blog key (deploy@s1.b4l.co.th, SHA256:o4w7HL...) for the deploy user,
and the secret held a different key. The SSH step now strips CR, refuses
a secret that is not an unencrypted private key, and logs the key's
fingerprint for comparison with authorized_keys. The ssh host alias is
renamed so the masked VPS_USER value no longer hides it in the log.
2026-10-02 21:14:33 +02:00
grabowski 560d073019 Add the cnxvinyl.lol test site with a Gitea deploy workflow
Deploy test site / deploy (push) Canceled after 0s
site/ builds the internal test site: public/ served as is (landing page,
robots.txt, static sites) plus demo pages copied out of docs/ (the plant
operation page at /demos/plant-operation/). build.sh fails on dead
internal links and stamps version.txt.

.gitea/workflows/deploy-site.yml rsyncs site/dist to the buildfor.life
web server with the blog's two-directory rename swap, checks version.txt
on the server, purges Cloudflare when a token is set, and checks the
public URL. Secret names match the blog's workflow.

site/Caddyfile is the virtual host to append on s1 (noindex everywhere,
Cloudflare-only like the blog apex, www redirect). site/README.md has the
one-time setup: DNS, Caddy, web root, secrets, runner.
2026-10-02 20:59:38 +02:00
grabowski 0e033784a2 Note the internal testing domain cnxvinyl.lol 2026-10-02 20:44:10 +02:00
grabowski 4607a4da58 Plan the artist platform: price calculator and fan-funded pressing
New docs/artist-platform.md: upload master and artwork with automatic
audio, artwork and rights checks; an itemised price calculator for every
customer (per-title vs per-copy lines, price-per-copy curve, lead time
from the production-timeline quote table, versioned price list); and
fan-funded campaigns that press and dropship per fan once the goal is
reached, refund otherwise. Covers goal maths, payments (charge into a
ring-fenced account, CNX as seller of record, legal opinion first; the
Qrates failure as the design rule), repress pre-orders, architecture on
the cnx-factory stack with the public side on a fleet machine, PDPA,
phasing (calculator public early as a run-size probe, campaigns only
after first releases ship), cost and open decisions.

Backlinks from README, process flow, production timeline, revenue model,
digital factory and roadmap items 1 and 20; total investment added-scope
table gains the platform line.
2026-10-02 17:37:32 +02:00
grabowski 917a3eb933 Plan the overhead crane, maintenance workshop and visitor corridor
New docs/crane-workshop-tours.md: a 5 t single-girder EOT crane over the
whole production compartment (stops at the warehouse fire wall), a
machine door and crane-served workshop/machine bay at the ramp end, and
a glazed ground-level visitor corridor along the car-park elevation with
stations in process order, its own air and acoustic glazing so tours
need no PPE. Covers what each changes in the shell (crane-ready frame,
hook height under the 7.0 m eave, no full-height cross walls in the
crane zone, room lids and crane hatches), safety, costs and open
decisions.

Propagated: construction RFQ (crane-ready frame, new section 1c, machine
door, accessible 1:12 entrance now required), scale zone table (+210 to
280 m2, total ~1,400 to 2,000 m2), facility security, worker safety,
roadmap items 9 and 15, total investment added-scope table, README.
2026-10-02 17:34:24 +02:00
grabowski 81185d8013 Add the Sillitoe SDMS as a second mastering lathe candidate
Sillitoe Audio Technology (Australia) sells a complete cutting system:
lathe, MMFB feedback cutterhead, cutting amplifier, Space / Time Control
automation with a virtual groove, vacuum and microscope, at a published
USD 125,000 ex tax and shipping. Vendor landscape gets the narrative and
an Agnew-or-Sillitoe comparison; supplier map, total investment basis,
roadmap item 13 and the digital factory's no-telemetry section (STC cue
sheet, Open Groove export, stylus hours) follow.
2026-10-02 17:31:36 +02:00
grabowski ffcce42a51 Digital factory plan: build on the existing cnx-network clan
Rewrite docs/digital-factory.md against the fleet that already exists at
git.b4l.co.th/B4L/cnx-network-clan instead of a plant-only clan:

- The plant is one more site: gw-lpn-1 from the cnx.router module, plant
  machines in the same inventory, reached over the existing ZeroTier mesh
  (no VPS, no moon, no port forwards).
- Fleet pieces reused as-is: control for host metrics, journals and host
  alerts; ns1/ns2 for the gateway wildcard cert; web01 as the public
  proxy for the customer portal; clan borgbackup with a plant server.
- Process time series move from TimescaleDB to a plant-local
  VictoriaMetrics (same modules and rules as control); PostgreSQL keeps
  everything with identity. Object storage dropped for ZFS datasets.
- VLAN table on the fleet addressing convention (siteId 3 assumed, ids
  above 40); OT segments as dual-homed islands behind the collectors;
  stations reach the app only through the gateway Caddy proxy.
- New section listing every file that changes in the clan repo, the
  modules/vinyl/* to write, and three router-module extensions (NTP
  serving, static VLANs, second WAN).
- Gaps the plant closes for the fleet: Alertmanager delivery, off-site
  backup destination, TSDB backup.
- Repository layout decided: infra in cnx-network-clan, app in
  cnx-factory as a flake input, this repo stays documents.

README bullet updated to match.
2026-09-21 21:41:49 +02:00
grabowski 0fb60bcbb5 Add digital factory systems plan (NixOS fleet as one Clan)
New docs/digital-factory.md: every system needed for environmental,
machine, QC and genealogy data to land in one database keyed to one
record identity. Standing decision: all services run on NixOS machines
declared and deployed as a single clan.lol inventory (mesh, backups,
host monitoring, secrets from clan services).

Covers machine list and roles, VLAN zoning, Telegraf/MQTT acquisition
source by source with the RFQ clause for each, environment sensor zones,
QC instrument integration paths, the factory application modules and
entities, alerting tiers, backup and retention, security, procurement
clauses, build order aligned with the roadmap phases, rough cost and
open questions.

README index and layout tree updated; roadmap item 17 and the
traceability spec link to the new document.
2026-09-21 21:06:42 +02:00
grabowski 122d908862 Labels are pressed into the record, not applied at finishing
The docs and the plant page had labelling as a finishing step after the
press. On a record press the bottom label, the cake and the top label go
in between the stampers every cycle and the mold bonds the paper into the
vinyl; the oven only pre-dries them. Corrected everywhere the process is
described:

- process-flow.md: labels are a parallel input to pressing with their own
  row (print inspection, oven, lot per cycle); stage 6 loads label, cake,
  label; stage 7 is trim, sleeve, shrink
- process-flow.drawio (+ regenerated png/pdf): label input now feeds
  stage 6, not stage 7
- README vision list and the business plan source (regenerated docx/pdf):
  pressing paragraph explains the pressed-in label, finishing no longer
  claims to label
- plant-operation.html: label dry oven station feeds two label discs
  into the press with every cake, the cake in the mold shows its labels,
  the cycle log records the label lot, finishing is sleeve + shrink
2026-09-21 16:16:18 +02:00
grabowski c8482b7a76 Add animated plant operation page (simulated SCADA overview)
docs/plant-operation.html: one self-contained static page showing the
whole plant running, from PVC intake and the material lab gate through
extruder, press cycle (load/close/steam/cool/open/eject), trimmer, 100%
optical inspection, sampled audio comparison, finishing, packaging
(matrix code vs barcode) and fulfillment. The metal path (audio intake,
mastering, cutting, silvering, father/mother/stamper, stamper prep) runs
above with the three artist gates; utilities (steam, cooling, air,
hydraulics, grinder/regrind, energy, traceability, HVAC) below with
live-looking tags.

Numbers are taken from the repo (Newbilt site requirements, scale.md,
quality-automation.md, process-flow.md). Every station is clickable for
what happens there and the checks that gate it. Two demo buttons show a
steam pressure dip holding the press and a new PVC lot held by the lab
until a test pressing releases it. README links the page.
2026-09-21 16:01:41 +02:00
grabowski ed0260d476 Add Making Vinyl Europe 2026 exhibitor briefing and booth questions 2026-09-19 19:24:58 +02:00
grabowski fbe6a97e39 business plan pdf 2026-09-10 10:28:03 +02:00
grabowski 3934dc1dc4 Add investor business plan (draft 0.1) with its Python builder
Leased land instead of purchase, in-house cassette duplication, CD-R
duplication with CD replication shown as a separate investor decision,
Ploy Printing as packaging partner and intended co-investor, and a
dedicated section on traceability, metrology, QC and efficiency.
2026-09-10 10:20:05 +02:00
grabowski 1bbef055c4 Remove em dashes where the replacement is unambiguous
The project has a standing style rule against em dashes that was missed
when these docs were written. This removes the 42 occurrences where the
substitution is mechanical and cannot change meaning:

- table cells using an em dash as a placeholder, now a hyphen
- em dashes immediately followed by a conjunction or subordinator
  (but, and, or, so, though, while, which, where, because, since),
  where a comma is simply correct

115 remain. Those join independent clauses, where a comma would create a
splice and a colon often reads wrong, so each needs a judgement call
rather than a pattern. A blanket regex over them was attempted and
reverted: it produced double colons and broken sentences.
2026-08-06 15:31:09 +07:00
grabowski 8c8e1be451 Rewrap an over-long line left by an earlier edit 2026-08-06 12:54:52 +07:00
grabowski caa38dcd0b Rebuild the operating roll-up and labour cost from components
Both were flagged in the review and deferred; fixing them properly
changes what the model says.

Labour
- The 0.23-0.40 USD/record line implied 44,000-63,000 THB per head per
  month, far above northern Thai production rates.
- Rebuilt from headcount and wages: 13-19 direct production staff
  (operators, galvanics, QC, maintenance) at loaded northern Thai rates
  gives 3.7M-5.4M THB/yr, or 0.08-0.16 USD per record. Build-up shown.
- Mastering and cutting engineers excluded as title-services labour;
  admin and sales moved to overheads where they belong.
- Stamper amortisation widened to 0.03-0.12 to match the in-house
  marginal cost assumed elsewhere on the page.
- Direct cost total is now 1.30-2.58 USD (43-85 THB).

Operating roll-up
- The old EBITDA and operating-profit figures did not reconcile with
  their own components and showed no loss case anywhere. Replaced with
  a three-scenario table built from the components, each column
  internally consistent, with cash overheads and depreciation separated.
- The adverse case is EBITDA-positive but does NOT cover depreciation:
  operating profit -0.32M USD at 1.0M records on the low price and high
  cost. The previous figures quoted 0.6-1.2M and hid this entirely.
  Utilisation and price realisation decide solvency, not just upside.
- The favourable case is not credible and that is a finding about the
  cost table rather than the business: 69% EBITDA margin against
  industry norms of 15-25%, and 47% even at the centre. The direct cost
  table counts only per-record consumables and direct payroll. Named
  what is missing (indirect labour, scrap above the reject allowance,
  water and effluent, inbound freight, inventory carrying, sales
  commission) and marked the adverse column as the honest one until
  those lines exist.
- Payback restated per scenario: never / 2.3-4.4 yr / 1.0-1.8 yr. The
  old "5 to 8 years" came from the pre-correction margin.
- FX sensitivity and the utilisation bullet updated to match.

The table is a sensitivity, not a forecast, and now says so.
2026-08-06 12:52:14 +07:00
grabowski 4deaa2c57c Correct errors found by review; hedge unmarked inferences
A four-agent review audited arithmetic, cross-document consistency,
epistemic honesty and style. It found substantially more than the
manual pass in the previous commit. Errors that changed conclusions,
not decimals:

Arithmetic
- production-timeline: the headline lead times did not reconcile with
  the stage table on the same page. Launch is 22-49 days (was 21-39),
  mature 11.5-22 (was 14-20), repress 6.5-11.5. Including gates,
  launch is 6-17 weeks, not 8-14.
- Consequence: at 17 weeks the launch configuration is at parity with
  EU/US plants, not ahead of them. The page now compares quote to
  quote rather than a stage sum to a quoted lead time, and says so.
- The galvanics turnaround saving is 1.5-5 weeks, not 3-5.
- scale.md Duplex capacity 300-600k/yr did not reproduce from its own
  stated basis; corrected to 175-540k. production-timeline disagreed
  with scale.md on the same fleet; both now agree.
- "300 units is under an hour of pressing" was out by an order of
  magnitude on the semi-auto line: 5-8 hours.
- project-timeline carried two totals for the same quantity. Now
  27-33 months throughout, with the Gantt's two ordering breaks fixed.
- scale.md: 300 kWp covers 28-45% of consumption, not 20-35%; roof PV
  stated as both 150-200 and 247 kWp for the same roof; parking canopy
  dimensions and PV disagreed with the RFQ.
- RFQ: fire tank stated 200 m3 where both its geometry (254 m3) and
  its own mass (250 t) say 250. Drainage now gives total sealed area
  66%, not the 46% paving figure, since that is what attenuation needs.
- Galvanics payback used only the top of the saving range: 1-5 years,
  not 1-4.

Inference marked as inference
- The 22,000 THB stamper figure is an invoice RESIDUAL. It carries
  lacquer cutting, test pressings, setup and margin, so it is an upper
  bound on the stamper component, not a measurement. Everything derived
  from it now says so, and a line-itemised invoice is the top question.
- The saving was also benchmarked against the wrong supplier: CNX buys
  from Stamper Discs, not a Thai reseller. Stated as 175-665 USD until
  that quote exists.
- The stamper-bottleneck hypothesis now names its alternatives. Jacket
  print runs would produce the same symptom and would constrain CNX
  equally, which would remove the competitive read entirely.
- Competitor capacity relabelled as nameplate times an assumed OEE,
  with the assumed shift pattern stated; all rows on one 300-day basis.
- The fixed/variable decomposition keeps the shape and drops the point
  estimates: the solve point inside the flat 1000-3000 tier is
  arbitrary and moves the fixed component by nearly half.
- "Nobody in Thailand plates" reduced to "we have found no evidence",
  with a desk check named as the action.
- Cut the USD 450-700k valuation of a competitor's presses entirely.
  It extrapolated a semi-auto quote onto a different machine, ignored
  the used market, and supported no decision.
- The collaboration payback divided capex by revenue where the same
  page uses contribution elsewhere: 5-10 years, not 1-3.

Missing caveats added
- No financing is committed or modelled anywhere in this repo;
  project-timeline previously asserted money was not a constraint.
- Leasing cannot pull the launch forward on its own, since the press
  chain governs and construction has float against it.
- The whole competitive analysis is one buyer, one plant, one
  afternoon, and the primary evidence is not archived in the repo.
- ResurRec is a competitor and may decline to buy from a new entrant.
2026-08-06 12:35:37 +07:00
grabowski 20c8d283d5 Rebase costs on USD/THB; add timelines and first market data
Currency
- Base currency moves from EUR to USD and THB throughout. Rates at
  5 Aug 2026: 1 USD = 33 THB, 1 EUR = 1.155 USD, 1 GBP = 1.35 USD.
  EUR/THB lands at ~38, so existing THB research needed no change.
- Vendor quotes keep their original currency with a USD/THB equivalent
  alongside, so they stay checkable against the source PDFs.
- Full vision ~4.7-8.9M USD; phased entry ~1.7-2.9M USD.

New documents
- production-timeline.md: order turnaround stage by stage. Launch
  8-14 weeks, mature 5-10, repress 2-3. Quantifies the in-house
  galvanics turnaround claim the repo had asserted without a number,
  and flags artwork as an unmodelled fourth approval gate.
- project-timeline.md: calendar to first paying release, ~Q4 2028.
  Critical path is BOI certificate to press order to build to
  commissioning. Two findings: Newbilt build time is absent from the
  repo yet carries ~40% of the schedule, and the BOI rule may be
  over-serialised since duty exemption attaches at importation rather
  than at contract signature.

First market data (ResurRec, Bangkok)
- Invoice-derived prices, a factory tour, and a confirmed fleet of one
  Newbilt Classic 12" automatic plus one semi-automatic.
- Price ladder recorded at 300/500/1000-3000/3000+ units. Decomposes
  to roughly 34-50k THB fixed per title and 535-780 THB variable per
  unit, which is 4-7x the price this model assumes.
- The incumbent presses 230-350k records/yr but buys every stamper as
  an import. That single constraint plausibly explains their 150-unit
  floor, their flat discount ladder and their large-run lead time, and
  it is what an in-house galvanics line attacks. Logged as an open
  question on whether galvanics should move from phase 5 to phase 1.
- Inferences are marked as inferences; the whole set is one buyer and
  one plant, and the model is deliberately left unrebased until a
  second data point exists.

Corrections
- Gross margin arithmetic did not follow from its own inputs. Restated
  as ~1.95 USD at the midpoint with the 0.75-3.15 spread shown; the
  previous "40 to 55%" was not supported.
- Direct cost low total 1.50 to 1.45 USD; contingency THB high 40M
  to 38M.
- README indexes the construction RFQ, which was missing.
2026-08-06 12:22:40 +07:00
grabowski 9d5d695855 Add parametric BIM model; rework site works, envelope and phase 2
The parametric model (docs/cnx_vinyl_parametric.FCStd) is now tracked. It
is the spreadsheet-driven Arch/BIM rebuild that supersedes the hard-coded
massing in factory_building_rough.FCStd, which is kept because the current
renders still come from it.

Site works. The two gates are consolidated into a single 10.0 m bi-parting
opening, with the wall plugged where the second one stood. The guard house
sits beside it clear of the entry corridor, and was raised out of the
ground - it had been modelled sunk half a storey. The fire water tank moved
to the north-west corner of the plot, taking utility-yard clearance from
5.6 m to 18.6 m; the fire pump house follows it. The site is now paved
continuously from the frontage through to phase 2: 4,387 m², split 1,608
heavy-duty and 2,779 general so the two can be priced apart.

Phase 1 envelope. The walls stopped flat at 8.2 m while the roof rose to
12.6 m, leaving the entire high-side wall and both gable triangles open -
about 366 m². Walls now follow the roof underside exactly. The rebuild also
starts the sandwich panel on top of the masonry dado, clearing a 31.9 m³
overlap that had been double-counting 425 m² of envelope. A vehicle ramp
(10.5 m at 1:10) and three stair flights are added, since with FFL at
+1.2 m the building had no means of access at grade.

Phase 2. Built from the design already documented in scale.md: 45 x 38 m,
two-bay sawtooth at 10.35/7.0 m with a 3.35 m glazed riser, bays falling
ESE. A three-storey office cube - canteen, office, office plus sleeping -
stands at the yard end of the west tooth, 1.65 m proud of the ridge. Its
walls and the hall walls are Arch Walls, and the yard glazing is Arch
Windows, so both carry IFC types and cut their own openings.

RFQ updated against the model throughout, with a new section on where
mineral-wool core is required instead of PIR, for compartmentation and for
acoustics.
2026-08-05 16:38:24 +07:00
grabowski bbeaed7e87 Add loading dock, second gate, and phase 1 construction RFQ
Site model: two sealed dock positions on the north gable (depressed
12 m pit + 12 m ramp cut into ground and paving), water treatment
moved clear of the cooling tower, second car/staff gate on the NE
edge with access road to parking, guard house relocated between the
gates, perimeter wall rebuilt continuous on its 0.4 m inset line,
leftover door recesses filled on both envelopes, loading-apron
marking removed. Renders re-exported.

Docs: phase 1 contractor pricing request (PEB spec, PIR envelope,
dock, site works, exclusions, soil caveats).
2026-07-30 18:11:30 +07:00
172 changed files with 30743 additions and 350 deletions

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
# Shell scripts run on the Linux CI runner and in git-bash: keep LF.
*.sh text eol=lf
+76
View File
@@ -0,0 +1,76 @@
name: Deploy test site
# Builds site/dist (site/public/ plus demo pages copied out of docs/, see
# site/build.sh) and publishes it to the B4L package registry as the generic
# package B4L/cnxvinyl.lol. bkk01 serves https://cnxvinyl.lol/ from those
# releases (cnx-network-clan, docs/src/s1-migration.md): the registry's
# package event makes it fetch a new version within seconds, and a timer
# there fetches every 15 minutes as a backstop.
#
# Secrets (organization level): REGISTRY_USER, REGISTRY_TOKEN, an account with
# a write:package token in a B4L team that may write packages (b4l-ci). The
# job's own token only reads the repository: the registry refuses it.
on:
push:
branches: [master]
paths:
- "site/**"
- "docs/**/*.html"
- "docs/pitch/**"
- ".gitea/workflows/deploy-site.yml"
workflow_dispatch:
# A newer push supersedes a running deploy; bkk01 serves whichever version
# the registry lists as the latest.
concurrency:
group: deploy-cnxvinyl-lol
cancel-in-progress: true
permissions:
contents: read
jobs:
deploy:
runs-on: ubuntu-latest
env:
SITE_URL: https://cnxvinyl.lol
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build site/dist
run: bash site/build.sh
- name: Publish to the package registry
# The version joins the UTC time and the commit, so versions never
# collide. The archive holds the site's root itself.
env:
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
run: |
if [ -z "$REGISTRY_USER" ] || [ -z "$REGISTRY_TOKEN" ]; then
echo "::error::REGISTRY_USER and REGISTRY_TOKEN must be set as organization secrets"
exit 1
fi
version="$(date -u +%Y%m%dT%H%M%S)-${GITHUB_SHA::12}"
tar -czf site.tar.gz -C site/dist .
curl -fsS --user "$REGISTRY_USER:$REGISTRY_TOKEN" --upload-file site.tar.gz \
"${{ github.server_url }}/api/packages/${{ github.repository_owner }}/generic/cnxvinyl.lol/$version/site.tar.gz"
echo "published cnxvinyl.lol $version ($(du -h site.tar.gz | cut -f1))"
- name: Check the public URL
# bkk01 fetches the release a few seconds after the upload; give it up
# to two minutes. Warning only: the release is in the registry either
# way, and the timer on bkk01 picks it up.
run: |
expected=$(cat site/dist/version.txt)
for i in $(seq 1 24); do
got=$(curl -sS --max-time 20 "$SITE_URL/version.txt?nocache=$expected" || true)
if [ "$got" = "$expected" ]; then
echo "$SITE_URL serves $expected"
exit 0
fi
sleep 5
done
echo "::warning::$SITE_URL/version.txt returned '${got:0:80}', expected $expected"
+3
View File
@@ -23,3 +23,6 @@ node_modules/
# Playwright MCP session output # Playwright MCP session output
.playwright-mcp/ .playwright-mcp/
# Test site build output (site/build.sh)
site/dist/
+385 -34
View File
@@ -1,15 +1,18 @@
# CNX Vinyl / Poy Records # CNX Vinyl / Poy Records
<img src="docs/brand/poyrecord-logo-1536x1536.png" alt="Poy Records logo" width="160">
A vinyl record factory in planning for the Chiang Mai area of northern A vinyl record factory in planning for the Chiang Mai area of northern
Thailand (site candidates include Lamphun and Lampang provinces). This Thailand (site candidates include Lamphun and Lampang provinces and, since
repository is the source of truth for the project: planning documents and October 2026, Payap University land in Chiang Mai). This repository is
cost data today. As the factory takes shape it will also hold the data and the source of truth for the project: planning documents and cost data
software used to run it. today. As the factory takes shape it will also hold the data and software
used to run it.
## Team ## Team
- **Simona Meesaiyati**, Project Lead - **Simona Meesaiyati**, Project Lead: management and the audio side
- **Alexander Grabowski**, Technical Consultant - **Alexander Grabowski**, Technical Consultant: the technical side
[buildfor.life](https://buildfor.life) supports the project in a consulting [buildfor.life](https://buildfor.life) supports the project in a consulting
capacity. capacity.
@@ -23,8 +26,9 @@ file to delivered record:
2. **Lathe cutting**: cutting the master disc 2. **Lathe cutting**: cutting the master disc
3. **Silvering**: metallizing the cut master 3. **Silvering**: metallizing the cut master
4. **Stamper production**: electroforming nickel stampers in-house 4. **Stamper production**: electroforming nickel stampers in-house
5. **Pressing**: extrusion and pressing of the finished records 5. **Pressing**: extrusion and pressing of the records, with the labels
6. **Finishing**: trimming, labels, shrink wrapping pressed in
6. **Finishing**: trimming, sleeving, shrink wrapping
7. **Packaging**: folded paper cartons (jackets and sleeves), produced in 7. **Packaging**: folded paper cartons (jackets and sleeves), produced in
collaboration with local packaging manufacturers collaboration with local packaging manufacturers
8. **Fulfillment**: dropshipping directly to end customers on behalf of 8. **Fulfillment**: dropshipping directly to end customers on behalf of
@@ -34,20 +38,70 @@ In-house galvanics (steps 3 and 4) removes the dependency on overseas stamper
suppliers, a common bottleneck for pressing plants, and shortens turnaround suppliers, a common bottleneck for pressing plants, and shortens turnaround
for clients. Partnering with local carton manufacturers keeps packaging for clients. Partnering with local carton manufacturers keeps packaging
sourcing close to the plant, in line with the local-sourcing preference for sourcing close to the plant, in line with the local-sourcing preference for
materials. The pressing line is documented in detail; equipment, partners, materials. The pressing line is documented in detail, galvanics and stamper
and budgets for the other steps are open planning items. prep from vendor datasheets; equipment, partners, and budgets for the other
steps are open planning items.
## Project Status ## Project Status
**Planning stage** (as of mid-2026). **Planning stage** (as of October 2026).
- Industry outreach has been ongoing for several years: equipment vendors, - Industry outreach has been ongoing for several years: equipment vendors,
material suppliers, and independent consultants. material suppliers, and independent consultants.
- Alexander and Simona will soon travel to - Alexander and Simona attended
[Making Vinyl](https://makingvinyl.com/) in Haarlem, Netherlands, to gather [Making Vinyl Europe 2026](https://makingvinyl.com/) in Haarlem (30
further insights from the pressing industry. September to 2 October). Most people they talked to were strongly
- A collaboration with [Resurrec](https://www.resurrec.com/) is under interested in the full-traceability approach, and for Sibert it was a
discussion. reason to engage at all (notes in the
[exhibitor briefing](docs/suppliers/making-vinyl-europe-2026-exhibitors.md#after-the-show)).
- Payap University (Chiang Mai) has offered land on lease and wants to
build joint student programmes with the plant. The point it gave for the
land is zoned very high density residential in the Chiang Mai city plan,
where record pressing is not permitted (checked October 2026). Payap
says the land can be rezoned (20 October 2026), so it stays an option;
a rezoning is a city-plan amendment the planning department schedules
at ~16 to 19 months
([what it takes](docs/land-listings/payap/rezoning-2026-10-20.md)); other
Payap land would need checking
([site candidates](docs/site-candidates.md),
[Payap partnership](docs/payap-partnership.md)).
- A second company, separate from the plant company, is to hold a record
catalogue (owned and licensed titles) and have it pressed at the plant
as a customer; language models in the project are self-hosted on
premises (decided October 2026;
[own catalogue](docs/catalogue-intelligence.md)).
- A collaboration with [ResurRec](https://www.resurrec.com/) is under
discussion. ResurRec has since opened a plant in Japan with automatic
presses, identified from photos as new Pheenix AD12s (October 2026;
[revenue model](docs/finance/revenue-model.md#resurrec-japan-october-2026)).
- Back from Haarlem, the team is preparing a meeting with the project's
investor (October 2026). Post-show follow-ups with Pheenix, Sibert, OMS
and SST are in the
[exhibitor briefing](docs/suppliers/making-vinyl-europe-2026-exhibitors.md#after-the-show).
- The plant now launches with everything in one capital round (October
2026): one Newbilt Duplex system and one Classic, a Pheenix galvanics
line, the Sibert stamper-prep line, a Sillitoe cutting room and the
modular boiler and chiller plant: ~168M to 296M THB with contingency
(midpoint ~232M; biomass steam, PV on the factory roof), the Pheenix line priced at OMS's reference plus 20 %
([total investment](docs/finance/total-investment.md#launch-plant-october-2026)).
For the investor the business plan comes in two versions, priced
without contingency and with the ramp-up reserve
([two plans](docs/finance/total-investment.md#two-plans-a-at-180m-thb-and-b-at-215m-thb-october-2026)):
**Plan A, ~182M THB** (~2M above 180M since steam went biomass), the
launch plant with six cost levers, and **Plan B, ~217M THB**, the same
launch plant with everything in. **The main investor wants to go with
Plan B** (19 October 2026); the investor deck leads with it. The
shareholders fund the whole plant as share capital, no bank loan
planned (20 October 2026). The main
investor holds **at least 60 % of the company** (~130M THB of Plan B's
~217M), so at most 40 % (~87M) is for
sale to co-investors (Ploy Printing, the founders, others;
[possible share prices](docs/finance/share-price.md);
[shareholding](docs/finance/total-investment.md#two-plans-a-at-180m-thb-and-b-at-215m-thb-october-2026),
20 October 2026).
Chinese boilers, compressor and hydraulics save about 2M THB of that
([Chinese suppliers](docs/suppliers/china-utilities.md)).
The business plan is re-based on it (draft 0.2).
## Planning Documents ## Planning Documents
@@ -57,23 +111,44 @@ The detail lives in dedicated documents:
three current gates (market validation, BOI, land title check) through three current gates (market validation, BOI, land title check) through
quotes, commitment, build, launch, and expansion quotes, commitment, build, launch, and expansion
- [Pressing line equipment plan](docs/equipment/pressing-line.md): the - [Pressing line equipment plan](docs/equipment/pressing-line.md): the
50/50 automated/semi-automatic fleet strategy, the Newbilt system under current all-Newbilt fleet (two Duplex systems, each with an EX 50 main
evaluation (≈ €200,500 quoted scope), and site requirements and an EX 35 colour extruder, plus one Classic automatic press), the 2024
Newbilt quote (~USD 232k,
expired), the 2026 product flyers, and site requirements
- [Galvanics and stamper prep equipment plan](docs/equipment/galvanics.md):
the metal path from lacquer to press-ready stamper, from vendor
datasheets: Pheenix Alpha's electroforming range as a second turnkey
vendor next to Digital Matrix, OMS as a third named by Sibert (reference
prices for a 4-cell wet room, EUR 224k to 311k), Sibert's
VSP/VSF/VSC stamper prep line (USD 250k budget for the three confirmed),
the utilities they need, a first cell-count estimate, and Sibert's
optical-disc reference material
- [Vendor landscape](docs/suppliers/vendor-landscape.md): researched - [Vendor landscape](docs/suppliers/vendor-landscape.md): researched
candidates for mastering and cutting (Agnew Analog), galvanics equipment candidates for mastering and cutting (Agnew Analog, and the Sillitoe
(Plating Power / Digital Matrix), stamper preparation (Sibert), bridge SDMS with integrated cutting automation at a published USD 125k),
stamper service (Stamper Discs), and automated presses (Pheenix Alpha) galvanics equipment
(Plating Power / Digital Matrix, Pheenix Alpha, Optical Media Services),
used lathes and cutting-room contacts (via OMS),
stamper preparation
(Sibert), bridge stamper service (Stamper Discs), and automated presses
(Pheenix Alpha, the comparison for the Classic)
- [Equipment needs and supplier map](docs/suppliers/equipment-suppliers.md): - [Equipment needs and supplier map](docs/suppliers/equipment-suppliers.md):
the full needs list per production step with supplier tables and contacts the full needs list per production step with supplier tables and contacts
- [Chinese suppliers](docs/suppliers/china-utilities.md): boilers,
compressed air and hydraulics from China (makers, published prices,
Thai offices, Thai boiler rules for imports); saves about 2M THB, ~1 %
of the budget
- [Sustainability](docs/sustainability.md): the solar installation (Deye - [Sustainability](docs/sustainability.md): the solar installation (Deye
inverters, 271 kWh Gobel Power battery stack), the zero contaminated water inverters, 271 kWh Gobel Power battery stack), the PEA grid tariff and
commitment, and the materials strategy what it decides (biomass steam at a quarter to a tenth of the cost of
electric, PV rather than solar thermal), the zero contaminated water commitment,
and the materials strategy
- [Worker safety](docs/worker-safety.md): safety training, galvanics clean - [Worker safety](docs/worker-safety.md): safety training, galvanics clean
rooms and decontamination, PPE rooms and decontamination, PPE
- [Biomass fuel strategy](docs/biomass.md): the 60 rai own-grown coppice - [Biomass fuel strategy](docs/biomass.md): the 60 rai own-grown coppice
idea (with the forestry-classification check that comes first), northern idea (with the forestry-classification check that comes first), northern
agricultural waste as the main supply, and the staged electric-to-biomass agricultural waste as the main supply, reported northern fuel prices
path (October 2026) and who sets them, and the staged electric-to-biomass path
- [BOI investment promotion](docs/boi.md): the promotion strategy (Group B - [BOI investment promotion](docs/boi.md): the promotion strategy (Group B
base activity plus solar, automation, and R&D measures for the tax value), base activity plus solar, automation, and R&D measures for the tax value),
requirements, Northern-region angle, and why BOI approval precedes requirements, Northern-region angle, and why BOI approval precedes
@@ -82,9 +157,67 @@ The detail lives in dedicated documents:
control, CCTV, whole-factory HVAC (temperature, humidity, PM), archive and control, CCTV, whole-factory HVAC (temperature, humidity, PM), archive and
audio protection, fire and life safety, plant monitoring, Thai compliance audio protection, fire and life safety, plant monitoring, Thai compliance
anchors anchors
- [Overhead crane, workshop and visitor corridor](docs/crane-workshop-tours.md):
a 5 t crane over the whole production floor to move machines in and
out, a crane-served maintenance workshop and machine bay at the ramp
end, and a glazed ground-level corridor for guided tours without noise,
dust or plating chemistry; what each changes in the building and what
it costs
- [Production hall layout sketch](docs/production-hall-layout-sketch.png):
a rough BIM sketch in FreeCAD (`docs/production-hall-layout-sketch.FCStd`)
of the 60 x 25 m phase 1 hall at Mueang Chi, with the fleet before
October 2026: zones in process order along the visitor corridor, the
crane zone, room-in-room boxes and the main equipment; every position is
an estimate
- [Payap scenario model](docs/cnx_vinyl_parametric_payap.png): a parametric
BIM model in FreeCAD 26.3 (`docs/cnx_vinyl_parametric_payap.FCStd`,
[isometric](docs/cnx_vinyl_parametric_payap-iso.png)) of the whole plant
on a square placeholder plot of Payap land: a 128 x 25 m production-only
factory with the five-press fleet, room for ten more Classics (drawn
before the October 2026 decision to lay the hall out for Duplex
systems: five Duplex bays and four Classic positions), one
shared hydraulic and air plant, a colour store with outdoor silos and a
two-storey finishing and print block
([plans](docs/cnx_vinyl_parametric_payap-block.png)), a separate
two-storey office building
([floor plans](docs/cnx_vinyl_parametric_payap-office.png): canteen,
changing rooms and showers, mastering and listening below; ~150 m² of
offices, training room and IT above), a separate water treatment
building next to galvanics, the utility yard and site access, all
driven by one parameter sheet
- [Process logging and traceability](docs/traceability.md): end-to-end - [Process logging and traceability](docs/traceability.md): end-to-end
per-order traceability for customers, batch genealogy from audio file to per-order traceability for customers, batch genealogy from audio file to
shipment, and the requirements this sets for the factory software shipment, and the requirements this sets for the factory software
- [Digital factory systems plan](docs/digital-factory.md): every system
that has to exist for environment, machine, QC and genealogy data to land
in one place keyed to one record identity, with ERPNext as the plant's
only system of record (every tool we build reads and writes it; only
machine data stays outside), everything open source with our own code
published and, later, the stack and automation services offered to
other pressing plants: the plant as one more site in B4L's
existing NixOS fleet (the cnx-network clan: mesh, DNS, fleet
monitoring, site gateway module, public proxy), what changes in that
repo, VLAN zoning, Telegraf/MQTT acquisition source by source, QC
instrument integration, the factory application, alerting, backup,
security, the data clauses for every RFQ, build order and rough cost
- [Plant assistant](docs/plant-assistant.md): an agent management and
operators ask in Thai or English, at a press kiosk, a desk or a phone;
it answers from the procedures, vendor manuals and this repository and
from ERPNext and the machine data, with sources on every answer, sees
only what the asker may see, drafts but never submits, never touches a
machine, and runs on site on an open-weights model
- [Inline optical QC](docs/equipment/inline-optical-qc.md): devices for
the 100% record inspection station (line-scan cameras with dark-field
and transmitted light, label camera, laser warp sensors, centring
turntable), CD-scanner and PRP precedents, smart-camera versus open
NixOS software, specials, prices and a two-station cost estimate, and
a FreeCAD concept model of the station (aluminium profile frame,
rim-belt conveyor, chuck, sensors) with a sourced bill of materials
- [QC station control plan](docs/equipment/inline-qc-control-plan.md):
EtherCAT with two 100 W servo kits, Beckhoff I/O and an N100 mini PC
running QiTech's open-source EtherCAT library on NixOS; bus layout, I/O
list, geizhals.de and QiTech shop prices, safety circuit, bench test and
build order
- [Quality automation](docs/quality-automation.md): stamper metrology - [Quality automation](docs/quality-automation.md): stamper metrology
(Keyence-class confocal, profiler, XRF), layered pressed-record QC (100% (Keyence-class confocal, profiler, XRF), layered pressed-record QC (100%
optical inspection, per-cycle press telemetry, sampled automated audio optical inspection, per-cycle press telemetry, sampled automated audio
@@ -92,37 +225,255 @@ The detail lives in dedicated documents:
- [Process flow](docs/process-flow.md): the whole chain from audio file to - [Process flow](docs/process-flow.md): the whole chain from audio file to
delivered record as a chart and stage table, with every check and the delivered record as a chart and stage table, with every check and the
three artist approval gates (printable diagram alongside) three artist approval gates (printable diagram alongside)
- [Artist platform](docs/artist-platform.md): upload a master and
artwork, get a transparent itemised offer from the price calculator
(for artists, labels and any other customer), and optionally launch a
fan-funded campaign that the plant presses and ships to each fan once
enough have pre-ordered, with refunds if not
- [Own catalogue](docs/catalogue-intelligence.md): a second company, not
the plant company, owns and licenses a record catalogue and has it
pressed at the plant as a customer at arm's length (standby runs in
idle press time); its catalogue dashboard, map of where the records
sell, demand model for what to repress and how many, and an advisor
agent on a self-hosted, on-premises model; not in the plant's
business plan
- [Order a record](docs/order.html): the order tool as a step-by-step
configurator after the Mobineko pattern (step rail, choices, a large live
record picture, running price and ship date, a "how to pay" step with
direct payment or a fan-funded campaign on make-a-record's calculator,
review with what is missing); same price list as the artist demos
- [Artist ordering demo](docs/artist-order.html): the artist platform as a
clickable single page: configure a record (jacket with a 3 or 5 mm
spine), type the track list or drop the master files and artwork
(checked in the browser, never uploaded: format, sample rate, bit
depth, clipping, side length against the format; artwork as PDF, AI or
image against the downloadable jacket and label templates: size and
spine, bleed, resolution, colour, fonts), approve gate 1, get the itemised offer with
its price curve and lead time, then order directly or run a fan-funded
campaign to a funded or missed end (refund, or go ahead at the
minimum) and follow the production through the three artist gates
- [Make a record](docs/make-a-record.html): the investor demo of the same
platform as a customer sees it, in one polished flow: design the record
against a to-scale mock-up, check the music and artwork, see the price,
let fans fund it, follow the production and open the record passport
(the traceability record of one copy); investor notes on every step, a
one-minute guided tour (`#tour`), prices in THB, USD or EUR and the whole
page in English or Thai (draft translation, `#cur=EUR&lang=th`)
- [Factory console and order status](docs/factory-console.html): the
factory application of the [digital factory](docs/digital-factory.md)
plan as a demo on a simulated plant day: the press floor with live
counters, work orders per station (kiosk steps: badge in, scan,
confirm), the inspection stream, audio samples, the material lab gate,
stamper metrology, the hash-chained event log, and the customer portal
for the same orders (steps, copies pressed so far, lab and inspection
results, approving a test pressing)
- [Plant assistant mockup](docs/plant-assistant.html): the
[plant assistant](docs/plant-assistant.md) on `vinyl-ai` as an operator
at the press kiosk (Thai, push to talk), management at a desk and sales
on a phone see it: answers with their sources, the tool calls beside
each answer, drafts that a person submits, safety steps quoted word for
word and the questions it refuses
- [Steam and cooling](docs/steam-cooling.html): the utility plant for the
launch plant (one Duplex system and one Classic; rooms built for four
modules, the five-press growth case one click away) as a clickable
process diagram: water treatment, feed tank and heat recovery, a bank of
two 500 kg/h boilers, the steam header and condensate return, and
process cooling with two 250 kW chillers (a third with the second Duplex),
a plate heat exchanger, warm and cold tanks and a branch to every press,
extruder and the hydraulic oil cooler; operating cases from the launch plant
and its commissioning to one module down, the design basis, an equipment schedule and
the open questions for the boiler and chiller RFQs
- [Plant operation page](docs/plant-operation.html): a single static page
animating the launch plant as a simulated SCADA overview at real cycle
times: the Newbilt Duplex system and the Classic, the Pheenix Alpha
electroforming line and Sibert stamper prep, from PVC intake and the
material lab through pressing, inspection, packaging and fulfillment,
with the three artist gates, the mother archive, utilities and energy;
1× is real time, up to 3600× (a day in 24 s); every station is
clickable and names the source of its figures; on phones and tablets
held sideways it pinch-zooms and opens station details in a side sheet
- [Plant and business plan calculator](docs/fleet-calculator.html): a
single static page for the business plan: choose the plant
configuration (presses, galvanics in-house or bought stampers, cutting
in-house or outsourced, metrology tier, cassette and CD-R, solar bought,
PPA or none, steam fuel, Thai or Chinese utilities, crane, visitor
corridor) and it builds the investment from the cost blocks of the
total investment, checks it against the investor's 180M and 216M THB,
and runs the money a year and a ten-year cash view (payback, NPV, IRR,
pre-tax sketch), with presets from the launch plant to a full hall. Set
the records a year and the share of splatter and specials, and it sizes
the mix of Duplex systems (3 records a minute each) and Classics (2 a
minute) from the launch plant of one Duplex and one Classic up to a
full press hall, with the people,
power, central hydraulics, steam, cooling, air, floor, compound and
stampers that fleet needs, drawn as a live schematic of the machine
park with the stamper line (lathe, Pheenix galvanics, Sibert prep)
feeding it, each station counted from the galvanics cycle times;
plus the money a year: revenue (standard, specials, title services),
PVC, labels, sleeves, jackets, cartons, lacquers, plating chemistry,
electricity and steam, labour from base salaries with social security,
on-costs and health care for all staff, overheads, EBITDA, depreciation
and payback, with the revenue model's adverse, central and favourable
cases, BOI promotion on or off (machinery import duty and import VAT,
PVC duty relief) and USD, THB or EUR; every assumption is editable, with its
source, and a scenario can be shared by link
- [Test site](site/README.md): `site/` builds https://cnxvinyl.lol/, the
internal test site with demo pages from `docs/` (the plant operation
page first) and any static site we want to share by link; Gitea Actions
deploys it to the buildfor.life web server on every push that touches it
- [Production timeline](docs/production-timeline.md): how long an order
takes stage by stage, launch vs mature configuration, the repress fast
path, and what lead time can honestly be quoted to a customer
- [Project timeline](docs/project-timeline.md): the calendar from today to
first paying release, the BOI-to-machinery critical path, and where the
float actually sits
- [Site candidates](docs/site-candidates.md): the land options side by
side (the Mueang Chi lease, the Northern Region Industrial Estate, and
Payap University's offer of land next to a pharmaceutical facility under
construction) and what has to be checked before any of them is chosen
- [Payap University partnership](docs/payap-partnership.md): joint student
programmes in audio engineering (mastering, lathe cutting), IT and
business built around the plant, what they change in the plan (cutting
room earlier, pre-release security, student access) and what to agree
- [Project scale](docs/scale.md): rough numbers for everything on one page: - [Project scale](docs/scale.md): rough numbers for everything on one page:
output capacity, building area, land, electrical demand, solar and output capacity, building area, land, electrical demand, solar and
storage, steam and fuel, headcount, and money cross-references storage, steam and fuel, headcount, and money cross-references
- [Total investment](docs/finance/total-investment.md): the full-vision - [Total investment](docs/finance/total-investment.md): the launch plant
roll-up (~4M to 7.7M EUR) and the ~1.5M to 2.5M EUR phased entry, with decided in October 2026 (~168M to 296M THB, ~5.1M to 9.0M USD, midpoint
the basis of every block ~232M THB) with the basis of every block, the two plans for the investor
- [Revenue model](docs/finance/revenue-model.md): rough full-capacity (Plan A ~180M, Plan B ~215M THB, without contingency), and the earlier
revenue (~3.2M to 5.9M EUR/yr), direct cost and margin per record, and answer to the 180M / 216M question; the earlier full vision and phased
the levers and caveats behind the numbers entry are kept as superseded
- [Phase 1 construction RFQ](docs/finance/phase1-construction-rfq.md):
the spec sheet for asking a contractor to price the phase 1 buildings
and site works, with quantities taken from the parametric BIM model
- [Revenue model](docs/finance/revenue-model.md): pricing, direct cost
and margin per record, the launch plant's operating picture at the
planned 60 % specials (central revenue ~3.65M USD a year on ~0.74M
records, EBITDA ~1.7M; the adverse case loses money), the operating
pictures of Plan A (payback ~3.2 years on ~182M THB) and Plan B (the
same output, payback ~3.8 years on ~217M THB: its extra pays back
through what the table leaves out), the five-press table, and the levers and
caveats behind the numbers
- [Share price](docs/finance/share-price.md): possible prices for the 40 %
of the company open to co-investors (the lead investor holds at least
60 %), from market data (Damodaran industry multiples, the Thai risk
premium and bond yield, illiquidity discounts, venture target returns,
Thai listed peers), on the decision that the shareholders fund the
whole plant as share capital: the founding round at par (Plan B's ~217M
as 2,170,000 shares of 100 THB, the 40 % ~86.8M THB, called in
instalments against the tranches), a premium only for documented
pre-round costs, and what a share could be worth once the plant runs
(adverse 11 to 42 THB per 100 THB paid, central 80 to 314 THB)
- [Investor deck](docs/pitch/index.html) (October 2026): the plant in 17
web slides for BOI, bank and institutional readers, proposing Plan B
(~215M THB) with Plan A as the comparison, in a light and a dark theme
(press T), with a presenter view (press P) and a PDF of each theme
([dark](docs/pitch/CNX-Vinyl-Investor-Deck.pdf),
[light](docs/pitch/CNX-Vinyl-Investor-Deck-light.pdf)); every figure carries its
source in the business plan or the owning doc
- Business plan, draft 0.3 (October 2026), in two versions:
[Plan A, ~180M THB](docs/business-plan/CNX-Vinyl-Business-Plan-A.pdf)
([docx](docs/business-plan/CNX-Vinyl-Business-Plan-A.docx)) and
[Plan B, ~215M THB](docs/business-plan/CNX-Vinyl-Business-Plan-B.pdf)
([docx](docs/business-plan/CNX-Vinyl-Business-Plan-B.docx)): the
investor-facing roll-up of everything above, each a complete plan with
one table comparing it with the other, both priced without contingency
and with the ramp-up reserve. Each carries renders of the
[plant and business plan calculator](docs/fleet-calculator.html) with
its own preset (the isometric plant view on the cover and in section 6,
the budget check, ten years of cash; in `docs/renders/calculator/`) and
a software section (5.5) with screenshots of the plant overview, the
factory console with its ERPNext link, the artist ordering demo, fan
funding and the record passport (`docs/renders/demos/`). Built from `docs/business-plan/build/`
(`python build_plan.py` makes both versions; the PDFs are exported with
LibreOffice so the table of contents is filled in). Draft 0.2, a single
launch-plant plan with contingency, is in the git history
## Repository Layout ## Repository Layout
``` ```
docs/ docs/
├── brand/ Poy Records logo (1536 px PNG)
├── business-plan/
│ ├── CNX-Vinyl-Business-Plan-A.docx / .pdf Investor business plan, Plan A (generated)
│ ├── CNX-Vinyl-Business-Plan-B.docx / .pdf Investor business plan, Plan B (generated)
│ └── build/ Python source of the plan; regenerate with
│ build_plan.py
├── pitch/ Investor deck: web slides (index.html, presenter
│ view), images in img/, PDF export
├── consulting/ Consultancy proposals and overviews ├── consulting/ Consultancy proposals and overviews
├── equipment/ ├── equipment/
│ ├── newbilt/ Offers, site requirements, process schematic, │ ├── newbilt/ Offers, site requirements, process schematic,
│ │ service rates (vendor PDFs) │ │ service rates, 2026 product flyers (vendor PDFs)
│ ├── oms/ OMS introduction letter: wet-room units, reference
│ │ prices, capacities, lathe contacts (vendor docx)
│ ├── pheenix-alpha/ Electroforming range flyers (vendor PDFs)
│ ├── sibert/ Stamper prep specifications and line-up drawing
│ │ (2021 issues in specs-2021/), 2008-09
│ │ optical-disc literature (vendor PDFs)
│ ├── duplex-cell-layout-sketch.png Duplex cell arrangement (sketch, not to scale)
│ ├── galvanics.md Electroforming and stamper prep equipment plan
│ ├── inline-optical-qc.md Devices for the record inspection station
│ ├── inline-qc-control-plan.md EtherCAT control plan for the station
│ ├── inline-qc-station/ Concept model of the station (FreeCAD script,
│ │ .FCStd, renders, labelled investor view,
│ │ bill of materials)
│ └── pressing-line.md Press fleet strategy and equipment plan │ └── pressing-line.md Press fleet strategy and equipment plan
├── finance/ Project cost overviews ├── finance/ Project cost overviews, revenue model,
├── suppliers/ Supplier contacts, vendor landscape, supplier map │ share price, construction RFQ, PEA electricity tariff
│ schedule (pea/), biomass fuel market
│ reports (biomass/), photos of ResurRec's
│ Japan plant (resurrec-japan/)
├── suppliers/ Supplier contacts, vendor landscape, supplier map,
│ Chinese utility suppliers (china-utilities.md)
├── order.html Step-by-step order configurator demo page
├── artist-order.html Artist ordering and fan-funding demo page
├── artist-platform.md Upload, price calculator, fan-funded pressing
├── biomass.md Biomass fuel strategy and the 60 rai coppice idea ├── biomass.md Biomass fuel strategy and the 60 rai coppice idea
├── boi.md BOI promotion strategy and requirements ├── boi.md BOI promotion strategy and requirements
├── catalogue-intelligence.md Own catalogue: sales map, demand model, advisor
├── cnx_vinyl_parametric_payap.FCStd Payap scenario parametric BIM model
├── cnx_vinyl_parametric_payap.png Top view of the Payap model
├── cnx_vinyl_parametric_payap-iso.png Isometric view of the Payap model
├── cnx_vinyl_parametric_payap-office.png Office building floor plans
├── cnx_vinyl_parametric_payap-block.png Finishing and print block plans
├── cnx_vinyl_parametric_payap_parts.FCStd Payap model in Part/Draft: roof, PV, parking canopies
├── cnx_vinyl_parametric_payap_parts.png Isometric view of the parts model
├── cnx_vinyl_parametric_payap_parts-top.png Top view of the parts model
├── CNX_apply_Params.FCMacro Pushes Params edits to the model (FreeCAD 26.3 RC1)
├── crane-workshop-tours.md Overhead crane, workshop, visitor corridor
├── digital-factory.md Data platform, NixOS/Clan fleet, acquisition, app
├── facility-security.md Security, HVAC, fire and life safety, compliance ├── facility-security.md Security, HVAC, fire and life safety, compliance
├── factory-console.html Factory application and customer portal demo
├── fleet-calculator.html Press fleet calculator: output, mix, requirements
├── land-listings/ Land offers and zoning records (Mueang Chi, Payap,
│ Payap rezoning route)
├── make-a-record.html Artist platform investor demo (end-user flow)
├── payap-partnership.md Joint student programmes with Payap University
├── plant-assistant.html Plant assistant (vinyl-ai) mockup: operator, management, sales
├── plant-assistant.md Ask the plant: assistant on knowledge base and data
├── plant-operation.html Animated plant overview (simulated SCADA)
├── process-flow.md Audio file to delivered record, with all checks ├── process-flow.md Audio file to delivered record, with all checks
├── production-hall-layout-sketch.FCStd Rough BIM sketch, Mueang Chi hall (earlier fleet)
├── production-hall-layout-sketch.png Top view of the sketch
├── production-timeline.md Order turnaround, stage by stage
├── project-timeline.md Calendar to first paying release, critical path
├── quality-automation.md Stamper metrology and layered record QC ├── quality-automation.md Stamper metrology and layered record QC
├── roadmap.md Next steps in dependency order ├── roadmap.md Next steps in dependency order
├── scale.md Rough project sizing on one page ├── scale.md Rough project sizing on one page
├── site-candidates.md Land options and the checks before choosing
├── steam-cooling.html Steam and cooling plant diagram, launch plant
├── sustainability.md Energy, water, materials commitments ├── sustainability.md Energy, water, materials commitments
├── traceability.md Process logging and per-order traceability ├── traceability.md Process logging and per-order traceability
└── worker-safety.md Training, clean rooms, PPE └── worker-safety.md Training, clean rooms, PPE
site/ Internal test site https://cnxvinyl.lol/
├── public/ Served as is: landing page, static sites
├── build.sh Builds site/dist: public/ plus demo pages from docs/
├── Caddyfile Virtual host for the web server (applied by hand)
└── README.md Build, deploy and one-time setup
.gitea/workflows/
└── deploy-site.yml Builds site/ and deploys it on push to master
``` ```
Vendor PDFs and spreadsheets are primary sources and reflect the state of Vendor PDFs and spreadsheets are primary sources and reflect the state of
+19
View File
@@ -0,0 +1,19 @@
# CNX: apply Params
# FreeCAD 26.3 RC1 does not pass spreadsheet edits on to the objects that read them
# (a normal recompute only recomputes the sheet). Run this macro after editing Params:
# it touches every object whose expressions read the sheet, then recomputes; anything
# further down the chain (arrays, dimensions) follows normally.
import FreeCAD as App
doc = App.ActiveDocument
sheet = doc.getObject("Params") if doc else None
if sheet is None:
App.Console.PrintError("CNX apply Params: the active document has no Params sheet\n")
else:
sheet.recompute()
deps = [o for o in sheet.InList if o is not sheet]
for o in deps:
o.touch()
n = doc.recompute()
bad = [o.Label for o in doc.Objects if "Invalid" in o.State or "Error" in o.State]
App.Console.PrintMessage(f"CNX apply Params: {len(deps)} objects read Params, {n} recomputed, errors: {bad[:10]}\n")
File diff suppressed because it is too large. Load diff
+595
View File
@@ -0,0 +1,595 @@
# Artist Platform: Upload, Price Calculator and Fan-Funded Pressing
A web platform where anyone who wants records made, from a bedroom
artist to a label, can:
1. **Configure a record in a calculator** and get a transparent,
itemised offer: what every line costs, which costs are per title and
which per copy, how the price per copy falls with quantity, and when
it ships.
2. **Upload the master and the artwork**, and have both checked before
anyone pays for anything.
3. **Either order directly**, as any label would, **or launch a
fan-funded campaign**: a page the artist shares with fans, who
pre-order their copy. If enough fans commit before the deadline, the
plant presses and ships each fan's copy. If not, every fan is
refunded and nobody is left with a garage full of records.
The calculator is for every customer. The campaign is the part that
opens vinyl to artists who could never front the cost of a run. Both sit
on top of what the plan already has: the stages and the three artist
gates in [process flow](process-flow.md), the lead times in
[production timeline](production-timeline.md), the order intake, client
vault and customer portal in [digital factory](digital-factory.md), and
the dropshipping already in the fulfillment step. Every figure on this
page without a source is an estimate.
**Demo.** The [artist ordering demo](artist-order.html) (test site
`/demos/artist-order/`) walks this whole flow on one static page:
configure a record, type the track list or drop the master files and
artwork (read in the browser and never uploaded: format, sample rate, bit
depth, sample peak and clipping, side length against the format, print
resolution and colour space), approve gate 1, get the itemised offer with
its price curve and lead time, then order directly or set up a campaign
and run it to a funded or a missed end, with the production steps and the
three gates after it. Its price list (version `demo-0.1`) splits the
illustration rates below into lines; every split is an estimate and the
page lists each rate with its basis.
**Investor demo.** [Make a record](make-a-record.html) (test site
`/demos/make-a-record/`) is the same flow as a customer would see it,
built for presenting: a to-scale mock-up with a record that spins at the
chosen speed, the checks in plain words, one price with the itemised
lines folded under it, the fan campaign on a phone, the production
timeline, and a **record passport** for one delivered copy (stamper,
press, cycle time and side, per [traceability](traceability.md) and
[quality automation](quality-automation.md)). An "Investor notes" switch
adds the business case to each step, sourced from this page, the
[revenue model](finance/revenue-model.md) and the
[production timeline](production-timeline.md); a guided tour (`#tour`
after the URL, `#notes` for the notes) walks the whole flow in about a
minute. It uses the same price list and stage table as the detailed
demo, so a rate change goes into both pages.
**Step-by-step order tool.** [Order a record](order.html) (test site
`/demos/order/`, October 2026, after the configurator at
[mobineko.com/order](https://mobineko.com/order)) is the order flow as a
plant's online order form: a rail of numbered steps (order type, size,
discs, vinyl colour and effects, labels, inner sleeves, jacket and
finish, extras, mastering and cutting, test pressings, shipping, track
list, artwork, how to pay, review), each step's choices beside a large
live picture of the record, and a running price and ship date. The review
lists what is still missing before an order can be placed. It carries the
same price list, so a rate change goes into all three pages.
**Fan funding in the order tool** (user, 20 October 2026: the new tool
offers fan funding too, so the investor deck's platform pictures come
from one tool and one calculator). Step 15 "How to pay" chooses between
paying the plant directly (the deposit, the rest before dispatch) and a
fan-funded campaign with the same inputs and the same campaign maths as
[make-a-record](make-a-record.html): the artist sets the fan price
(default 1,200 THB) and the campaign length, the fans needed are the
larger of break-even and the 100-copy minimum run, and the tool shows
what the artist keeps at the goal and with more fans, after the payment
fees (~3.5 %, to confirm with the provider), the one-off setup and the
pressing. Step 16 becomes "Review & launch" and simulates the campaign's
outcome. For the same record both pages give the same numbers (checked
headless over 40 combinations, October 2026): the default record at
1,200 THB needs 100 fans (break-even 41) and keeps ~548 THB a copy; the
Splatter 12" preset needs 100 fans (break-even 46) and keeps ~480 THB a
copy. Indicative demo prices.
**Mastering as a choice** (user, October 2026): the order tool lets the
customer pick the mastering: none (the master is final and only prepared
for the lathe), CNX vinyl mastering in-house per side, or full mastering
by a partner studio at **60 USD a track** (team figure, about 1,980 THB).
The example partner is [Brandenburg Mastering](https://www.brandenburgmastering.com)
in Amsterdam, which quotes on request and publishes no price list
(checked October 2026); it is not contracted. Partner mastering replaces
the in-house line rather than adding to it, and keeps gate 2: the artist
approves the master before cutting.
## Why it fits this plant
- **The bottom of the Thai market is unserved.** The one Thai plant we
have seen quotes a 150-unit minimum that is "rarely accepted because
the cost is way too high", so runs under 300 are effectively
unavailable ([revenue model](finance/revenue-model.md)). The reason is
a per-title cost (imported stampers, outsourced cutting) that does not
shrink with the run. In-house cutting and plating collapses it, which
makes short runs viable for CNX in a way they are not for an importer
of metalwork. Short runs need a channel; this is it.
- **Fan funding removes the artist's risk.** What stops an indie artist
ordering 200 records is not the price per copy, it is paying for all
200 up front without knowing whether they sell. A campaign turns that
around: the fans pay first, the run is exactly as big as the demand.
- **CNX owns the presses.** The known platforms of this kind are brokers
over a network of other people's plants. A plant-owned platform
controls its own price, schedule and quality, and keeps the margin on
manufacturing instead of a commission.
- **Transparency is already the brand.** The plan is built on
traceability that customers can see. The same event log can tell a fan
"cut on 12 March, plated, test pressing approved by the artist,
pressing now, ships next week", automatically and truthfully.
## Who else does this, and the lesson
| | Model | Notes |
|---|---|---|
| **Qrates** (Japan, global) | Crowdfunding plus pressing through partner plants, with a profit calculator for the artist | Its site carries a notice (October 2026) that the service is suspended "due to unforeseen financial difficulties"; artists report funded projects caught in the wind-down |
| **Diggers Factory** (France) | Upload tracks and artwork, set a sales goal; if missed, the project is cancelled and everyone refunded, or the artist funds the rest; about 8 weeks of manufacturing after success (2023 description); also sells direct pressing paid up front | An on-demand network rather than a single plant |
| **elasticStage** (UK) | Each record made when it is ordered, no minimum, no campaign | Its own on-demand production technology; a different answer to the same problem |
**The Qrates lesson is the design rule for the money**: fan payments are
held apart from the company's own money and are never working capital,
so that if anything goes wrong, fans can be refunded and artists keep
their projects. See "Payments" below.
## The calculator
### What the customer chooses
| Choice | Options |
|---|---|
| Format | 12" LP, 10", 7"; single or double disc; 33⅓ or 45 rpm; 7" with a small or a large (dinked) centre hole |
| Weight | 140 g, 180 g |
| Colour | Black, solid colour, marbled or splatter (the semi-automatic line's speciality); for colour, whether the press is cleaned first |
| Quantity | Free entry, with the price-per-copy curve shown live |
| Labels | Paper labels pressed into the record: printed, or plain white or black (white labels for promos and DJ copies) |
| Run-out inscription | The customer's catalogue number or text, scribed next to the run-out groove of every side (letters and numbers, up to 15) |
| Inner sleeve | Paper, poly-lined |
| Jacket | None (customer supplies), plain, printed single, printed gatefold; printed by the local packaging partner |
| Extras | Insert, hype sticker, shrink wrap, numbered edition, download card, barcode sticker |
| Audio source | Digital files, analog tape (transferred in-house), or a lacquer cut by the customer's studio (straight to plating; must arrive within days of cutting) |
| Audio services | Customer supplies a vinyl-ready master, or CNX vinyl mastering per side, or full mastering by a partner studio per track |
| Metal | Lacquer cutting and stampers (in-house; bridge stampers from Stamper Discs until the galvanics line exists) |
| Test pressings | Number of copies for the artist |
| Delivery | Bulk to one address, dropship to each buyer, or collect at the plant |
### Benchmark: Record Industry's calculator (October 2026)
Record Industry (Haarlem, NL; host plant of Making Vinyl Europe 2026)
runs a public calculator
(https://www.recordindustry.com/calculator/, checked October 2026): seven
steps (pre-production, vinyl, labels, inner sleeve, outer sleeve, extras,
quote or order) with an itemised cost list beside the form that updates
on every choice, an info box under each question, and a draft order
that the plant confirms by hand before the pre-payment invoice. Prices
are computed on its server. What it shows that this plan had not
covered, and what the demos took from it:
- **Taken into both demos:** audio arriving as tape or as a supplied
lacquer (it charges 470 EUR for cutting plus stampers from a digital
master, 570 from tape, 240 for plating a supplied lacquer), plain white
or black labels, press cleaning before a colour run (60 EUR, with the
warning that without it records can carry the previous colour), the
dinked 7", download cards and barcode stickers, and a catalogue number
scribed in the run-out (letters and numbers, up to 15). The new rates
are estimates with its prices as the basis, listed in the detailed
demo.
- **Left out for now:** label print modes (CMYK, Pantone, one colour),
board grades and finishes (kraft, Hansaboard, matt or gloss varnish,
laminates), die-cut holes, spines other than 3 and 5 mm, booklets, foil numbering,
sticker position, protective outer sleeves, BIO PVC and a recycled
colour mix, and multi-address shipping. Each is a price-list line once
the packaging partner and the compound suppliers quote.
- **Commercial terms worth deciding for CNX:** a flat order set-up fee
(60 EUR) and a small-run surcharge (60 EUR under 300, 40 under 500);
20 copies over the order invoiced to cover under- or over-production,
credited if fewer are delivered; customers asked to accept about 2 %
rejects; full pre-payment for new customers; minimum 200 copies.
Its prices and lead times are recorded as a benchmark in the
[revenue model](finance/revenue-model.md) and the
[production timeline](production-timeline.md).
### What the customer gets back
- **Every line itemised**, grouped into **per title** (mastering,
cutting, stampers, test pressings, setup) and **per copy** (pressing,
labels, sleeve, jacket, extras), with pass-through items such as the
printed jacket marked as such.
- **The price per copy against quantity** as a curve, so it is obvious
why 100 copies cost more each than 500, and where the steps are.
- **A lead time in weeks** from the quote table in
[production timeline](production-timeline.md): counted from
test-pressing approval, with the stages before it shown separately as
"typically X weeks, subject to your approvals", exactly as that page
says a quote should be made.
- **An offer** with a validity date and the price-list version it was
computed from.
### How it computes
Price = sum of the per-title lines + quantity × sum of the per-copy lines,
with quantity tiers where a supplier's price steps (jacket print runs).
All rates come from **one versioned price list** in the factory
application, and every offer records the version it used, so any old
offer can be reproduced to the baht. That follows the append-only rule
the factory application already applies to everything else.
Transparency rules, so the word means something:
- every line visible, no fees that appear later;
- pass-through costs (the jacket) shown at what the partner charges plus
a stated handling margin;
- quoted in THB for Thai customers and in USD for export customers, the
currency choice the [revenue model](finance/revenue-model.md) already
recommends deciding early.
### Side length per format
The audio check compares each side with the format's limit. Until the
cutting engineer sets CNX's own figures, the demos use these (October
2026):
| Format | Comfortable | At most | Songs a side, at most |
|---|---|---|---|
| 12", 33⅓ rpm | 18 min | 22 min | ~4.9 |
| 12", 45 rpm | 12 min | 15 min | ~3.3 |
| 10", 33⅓ rpm | 12 min | 15 min | ~3.3 |
| 10", 45 rpm | 8 min | 12 min | ~2.6 |
| 7", 33⅓ rpm | 5 min | 7 min | ~1.5 |
| 7", 45 rpm | 4.5 min | 5 min | ~1.1 |
**At most** and **songs** are the table the team supplied in October
2026, from recordplayerexpert.com ("How much can a vinyl record hold",
https://recordplayerexpert.com/vinyl-record-capacity, checked October
2026), which counts songs at an average length of 4:32. **Comfortable**
is the lower end of each range in the microcut.studio format guide
(https://microcut.studio/guides/vinyl-format-guide-12-10-7/).
The published cutting-room figures disagree with the at-most column in
three places, so treat those as re-check points for the cutting engineer:
10" at 33⅓ rpm (15 min here; microcut.studio up to 16, Diggers Factory
17), 10" at 45 rpm (12 min here; microcut.studio 11, Diggers Factory 10,
so this table is the most generous) and 7" at 45 rpm (5 min here, as
Diggers Factory; microcut.studio 6). Diggers Factory lists hard maxima of
22, 12, 17, 10, 6 and 5 minutes for the six formats (stricter on 12" at
45 rpm), and A to Z Media 14 to 18 minutes as ideal on a 12" LP. Loud or bass-heavy music needs
shorter sides: Diggers Factory's dance-music figures are about 60 % of its
standard ones (11:27 against 19:23 on a 12" LP), which the demo applies as
a factor of 0.6. The engineer check, not this table, decides whether a
side is cuttable.
### What it looks like with numbers
An illustration of the **shape**, using the midpoints of the working
assumptions in the revenue model: **38,000 THB per title** (mastering,
cutting, stampers, test pressings; range 19,000 to 57,000), **132 THB per
copy** for pressing, labels, inner sleeve and assembly (range 115 to 150),
plus **~100 THB per copy for a printed jacket and shrink** at short run
(estimate, until the packaging partner quotes). Black 12", 140 g:
| Copies | Per-title share per copy | Per copy | Per copy, all in | Order total |
|---|---|---|---|---|
| 100 | 380 | 232 | **~612 THB** | ~61,200 THB |
| 200 | 190 | 232 | **~422 THB** | ~84,400 THB |
| 300 | 127 | 232 | **~359 THB** | ~107,600 THB |
| 500 | 76 | 232 | **~308 THB** | ~154,000 THB |
| 1,000 | 38 | 232 | **~270 THB** | ~270,000 THB |
**Do not read the level off this table.** At these Western-benchmark
rates the 300-copy price lands near 360 THB, while the Thai market pays
650 to 950 THB for 300 today. That is the very gap the revenue model
flags as its biggest open question. The real price list is set after
market validation ([roadmap](roadmap.md) item 1); the calculator only
makes whatever prices are chosen legible.
## Artwork templates and files
Decided for the demos (user, October 2026): the order tool offers a
**spine choice** and **templates to download**, and accepts the files
designers actually deliver, **PDF and Illustrator (AI)** as well as
images.
- **Spine.** Thin, 3 mm, holds one record in its inner sleeve; thick,
5 mm, holds two, or one with a thick insert or a poster. Plants publish
templates for both, and for 7 or 9 mm on a gatefold (Mighty Media Discs:
12" sleeve 633 x 315 mm with a 3 mm spine, 635 x 315 mm with 5 mm;
Implant: 5 mm for two records; RPM Records: gatefold with a 7 mm spine;
XVinylX: 9 mm gatefold; all checked October 2026). A double album in a
single jacket takes the 5 mm spine without asking. The thick spine is
an extra line on the quote, an estimate until the packaging partner
quotes: Quality Record Pressings (US) lists a generic wide-spine jacket
at 0.90 USD against 0.55 for a standard one, and Kudos (UK) charges
137.50 GBP per order for an extra wide spine (price lists, checked
October 2026). A 7" jacket keeps the 3 mm spine.
- **Templates** follow the format, the jacket type and the spine chosen:
the jacket spread (back, spine, front) with 3 mm bleed, a 5 mm safe
area and the folds marked, a second page for the inside of a gatefold,
and a label template with one page per side (centre hole, and the
large hole of a dinked 7"). They are vector PDFs with trim and bleed
boxes set, so they open in Illustrator, InDesign and Affinity. Until
the packaging partner supplies its dielines the sizes come from the
published templates above; 10" and 7" panels are the mock-up's sizes.
- **Files accepted:** PDF (PDF/X-4 preferred), Illustrator files saved
with PDF compatibility (an AI file without it is refused with
instructions), and 300 dpi images. Plants ask for the same: Mobineko
publishes PSD, AI and PDF templates, New Orleans Record Press takes
print PDFs and refuses flattened images (checked October 2026). The
preflight reads the page boxes, colour spaces and fonts from the file,
checks the trim against the chosen spine (a spread made for a 5 mm
spine is flagged on a 3 mm order), the bleed, CMYK against RGB, and
whether fonts are embedded or outlined, and renders the front panel
into the mock-up.
## Fan-funded campaigns
### Before the campaign goes live
Nothing goes in front of fans that the plant cannot make:
1. **Upload**: master files (WAV/FLAC/AIFF) with checksums at both ends,
resumable for album-size uploads, straight into the encrypted client
vault (module 2 of the factory application).
2. **Automatic audio checks**, reported to the artist within minutes:
format, sample rate and bit depth, clipping and true peak, **side
length against the chosen format**, and low-frequency phase problems
that make a groove hard to cut.
3. **Automatic artwork preflight**: label and jacket files against the
templates (size, centre hole and safe area for the pressed-in label,
bleed, resolution, colour space), with a rendered mock-up of the
jacket and the vinyl colour; templates and accepted files in
[Artwork templates and files](#artwork-templates-and-files).
4. **Engineer check**: a cutting engineer confirms side length and level
are cuttable. On a Sillitoe lathe this is a number from the software's
virtual groove (disk capacity in percent) without a test cut; see
[vendor landscape](suppliers/vendor-landscape.md).
5. **Rights**: the artist confirms they own or have licensed the
recordings and the compositions (covers need a mechanical licence),
and an automatic audio fingerprint check (open tools such as
Chromaprint/AcoustID) catches obvious bootlegs before a person looks.
6. **Gate 1, master plan approved**, recorded as the event the
[process flow](process-flow.md) already defines, plus the approved
artwork proof that packaging QC later checks print against.
### The campaign page
- Artwork mock-up, story, track list, **short audio previews** (a few
seconds to a minute per track at reduced quality, rendered by the plant
from the master; the full master never leaves the vault, which matters
because pre-release audio is a leak target per
[facility security](facility-security.md))
- Price per copy, shipping by destination, goal, progress, deadline,
**estimated ship month** (campaign close plus the quoted lead time),
and what happens if the goal is missed
- Sharing built for where the fans are: a link, a QR code for gigs and
merch tables, and **LINE** alongside the international networks; Thai
and English
- Duration chosen by the artist, **14 to 45 days** (estimate)
### The goal
The artist sets only the fan price; the goal, the number of fans
needed, follows from it (decided October 2026). It is the larger of two
numbers:
- **the plant's minimum campaign run**, set by setup and stamper
economics on the semi-automatic line (**100 copies** as a planning
figure, to be decided), and
- **the artist's break-even**: the copies at which the fan price covers
the per-title costs, the per-copy costs and the payment fees.
Both demos show it in fans and as the pre-order amount (fans × fan
price); the investor demo also says from which fan price the 100-copy
minimum is enough (about 640 THB in the illustration; below it the
break-even sets the goal).
With the illustration above and a fan price of 1,200 THB (an example,
not a recommendation) and payment fees of about 3.5%: break-even is
38,000 / (1,200 − 42 − 232) ≈ **41 copies**, so the goal is the 100-copy
minimum. At 100 copies the artist keeps about **546 THB a copy**, at 300
about **799 THB**, because the per-title cost spreads. The calculator
shows the artist this before launch, for any price they type in. Shipping
is charged to the fan separately at checkout, at cost.
VAT is not in this example. With CNX as seller of record (open decision
1), a 1,200 THB fan price includes about 79 THB of VAT (7/107), which
comes out of the artist's margin; the demo can show the numbers with and
without it.
Over-subscription is good news: the run is pressed at the final number
plus the artist's own copies and the spares the reject allowance already
covers. An artist can cap a campaign for a limited, numbered edition.
### Payments
The decision that matters most, and the one Qrates got wrong.
| | A. Charge at pledge, refund on failure | B. Save card, charge at success |
|---|---|---|
| How | Fan pays when pledging; money held in a ring-fenced account; automatic refund if the goal is missed | Card stored by the payment provider; charged only when the campaign succeeds |
| Thai fit | Works with **PromptPay QR**, cards and wallets, which is how Thai fans pay | Cards only; excludes PromptPay |
| Risk | CNX holds fan money for the campaign's length: must be ring-fenced and legally clean | Some charges fail at the end, so a campaign that "succeeded" can come up short |
| Note | Refund paths differ by payment method; confirm each with the provider | A card authorisation cannot simply be held: Opn (Omise) allows an authorise-and-capture pause of up to 7 days, far short of a campaign |
**Recommended: A**, with three rules. Fan money sits in a **separate
account** and is never used for operations until the campaign succeeds.
**CNX is the seller of record** to the fan (CNX makes and sells the
record, the artist licenses the music and receives the margin), which
keeps VAT, consumer protection and refunds in one place. And before the
first campaign, **a Thai legal opinion** on whether holding pre-order
money for a third party's project needs anything beyond that, for
example under the Bank of Thailand's payment-service rules. Card data
never touches CNX servers: the provider's hosted payment page or fields
keep it out of scope.
### When the campaign succeeds
The campaign becomes a production order and runs the normal chain:
vinyl mastering if ordered and **gate 2** (master approved by the
artist), cutting (only now, because a lacquer has to be plated within
one to three days), stampers, test pressings and **gate 3** (artist
approves the test pressing; a photo or short video of it to the fans is
cheap marketing), the run, packaging, and **dropshipping one parcel per
fan** with tracking, which is fulfillment step 9 as already planned.
Fans follow it on the campaign page, fed from the order's records in
ERPNext and the plant's event log: the progress is the plant's own record, not a status someone
remembers to update. If a stage slips, the estimated ship month moves
and every fan is told.
An optional **"test pressing first"** campaign does mastering, cutting and
test pressings before launch, so fans hear and see the real record. The
artist pays the per-title services up front for it; it suits artists
with an audience but no track record.
### When it does not succeed
Automatic refunds to every fan, or, if the artist chooses, the artist
pays the shortfall and the run goes ahead at the minimum (the Diggers
Factory option). The artist's uploaded master and artwork stay in the
vault for a second attempt.
### After the first run: repress on demand
Once a title exists, its father and mother sit in the archive (a mother
gives about ten stamper sets, and a worn one is replaced from the father
without a new cut) and a repress takes
**1.5 to 2.5 weeks** of plant time
([production timeline](production-timeline.md)). The campaign page can
reopen as "pre-order the repress, pressed when 100 more are in", which
turns one release into a recurring one. This is the part a plant with
in-house plating can offer and a broker cannot. The planned catalogue
company can use the same pre-order as the market test for its titles, on
the same terms as any label ([own catalogue](catalogue-intelligence.md)).
## For labels and regular customers
The same calculator and upload path, with an account:
- negotiated rates as a customer-specific price-list version;
- direct orders with a deposit instead of a campaign;
- the three gates approved in the customer portal
([digital factory](digital-factory.md), modules 1 to 3 and 10);
- bulk delivery, dropshipping, or both;
- standby pressing (proposal, October 2026): a flexible date scheduled
into idle press time at a lower price, on the same terms for every
customer, the related catalogue company included
([own catalogue](catalogue-intelligence.md#arms-length-between-the-two-companies)).
## How it is built
Same stack and same rules as the factory application in
[digital factory](digital-factory.md): Rust (axum, SQLx, minijinja,
HTMX) on PostgreSQL, in the `cnx-factory` repository, packaged as a
flake, deployed by the clan. The platform extends modules 1 (orders and
releases), 2 (audio intake and the client vault), 3 (the gates) and 10
(customer portal) with a price list and calculator, campaigns, pledges,
payments and per-fan shipments.
**Where the public side runs.** The digital factory plan accepts that a
WAN outage at the plant stops the customer portal. That is acceptable for
a label checking an order, not for a campaign page in the hour an artist
posts it, or for payment-provider webhooks. Proposal:
- the **public process** (calculator, campaign pages, checkout, payment
webhooks, upload staging) runs on a fleet machine with a public
address, `web01` or a sibling declared in the clan the same way, with
its own small PostgreSQL for campaigns and pledges;
- the **plant core stays the authority** for everything with a
production identity: when a campaign succeeds it becomes an order on
`vinyl-core`, and from then on the fan-facing progress is read through
the plant, as the portal is. Design decision 7 ("the portal is a view,
not a copy") still holds for production data; campaigns and pledges are
new data that start life in public;
- **uploads** land encrypted in a staging area on the public machine, are
pulled over the mesh into the client vault, checksum-verified on both
sides, and deleted from staging; **previews** are rendered on the plant
and published outwards, so a full master never rests outside the
vault.
No SaaS beyond the payment provider (Opn/Omise, 2C2P or a bank gateway,
to be chosen), in line with the plan's standing rule that every plant
service runs on the NixOS fleet.
**ERPNext** (decided October 2026: the plant runs ERPNext as its only
system of record, and what we build are tools and interfaces on it;
[digital factory](digital-factory.md#erpnext-the-plants-erp)). The
platform keeps no business records of its own. For the platform that
means:
- the **price list** behind the calculator is an ERPNext price list
(the demos' `R` list is its prototype), synced out to the public
process, so the calculator and the invoice never disagree;
- an artist or label account is linked to one ERPNext **customer**; a
direct order becomes a **sales order** when it is confirmed;
- a **campaign** is a custom Campaign document in ERPNext from launch;
each pledge is posted as an advance **payment entry** into the
ring-fenced account as it arrives, with the fan as a customer; when the
campaign succeeds it becomes a sales order the advances are allocated
to, and fan shipments become delivery notes; the refunds of a missed
campaign are posted as payment entries too. The public process holds
sessions and a cache of what it shows, nothing else;
- every posting goes through the plant's integration layer and its
outbox over the mesh; the public side never talks to ERPNext directly.
**Personal data.** Fans' names and addresses are personal data under
PDPA, with CNX as controller as the seller of record. An artist gets
fan contact details only where the fan ticked a consent box; that list
is worth a lot to an artist, and consent is what makes it legal to hand
over.
## The calculator is also a research instrument
Every configuration anyone builds, anonymously logged, is a data point on
what people actually want to order: run size, colour, weight, packaging,
how many walk away at which price. The revenue model's open **run-size**
question ([roadmap](roadmap.md) item 1) is exactly that distribution. So
the calculator should go public **long before the plant exists**, with
indicative prices and a "tell me when it opens" list, and no payments.
## Phasing
| Roadmap phase | Platform step |
|---|---|
| 0 to 1, validate | Public calculator with indicative prices and an interest list; configuration logging feeds market validation |
| 3, build | Direct orders, uploads, automatic checks and gates, as part of factory application v1 |
| 4, launch | Campaigns go live **after** the first paying releases have shipped and lead times have been measured. No fan money is taken against a plant that has not yet delivered |
| 5, expand | Repress pre-orders, numbered editions, international shipping at scale, cassette and CD formats from the business plan's scope |
## Rough cost (estimate)
| Item | THB | USD |
|---|---|---|
| Public side on top of the factory application: calculator, campaigns, payments, uploads and previews, preflight, fan accounts | 1.3M – 3.0M | 40k – 90k |
| Hosting | on the existing fleet | negligible |
| Payment fees | per transaction, inside the fan price | about 3 to 4% on cards, less on PromptPay (to be confirmed with the provider) |
Not yet in the roll-up in
[total investment](finance/total-investment.md); listed there as added
scope.
## Risks
- **Most crowdfunding campaigns fail**, and each failed one still costs
CNX checking and setup time. A small non-refundable setup fee, credited
against the order if the campaign succeeds, is one answer; decide it
before launch.
- **Lumpy demand.** Campaigns end on dates nobody controls. The scheduler
in the factory application should see live campaigns, weighted by how
close they are to their goal, and cap how many can close in the same
week.
- **Fans are not labels.** They expect a perfect record and a date.
Clear wording on what vinyl sounds like, the artist's test-pressing
approval, and honest ship months carry most of this.
- **Rights.** Someone will upload music that is not theirs. Warranty,
fingerprint check, a human look, and a takedown route.
- **Money.** Covered by the payment rules above; the legal opinion comes
before the first campaign, not after.
## Open decisions
1. **Seller of record**: CNX (recommended) or the artist.
2. **Payment model**: charge-and-refund into a ring-fenced account
(recommended) or save-card-and-charge; legal opinion either way.
3. **Fee model**: margin inside the published price list only
(recommended, it is what "transparent" means) or a separate platform
commission.
4. **Minimum campaign run**: 100 copies as the planning figure.
5. **Public price list**: fully public rates, or public list prices with
account-specific rates for labels.
6. **Hosting split**: public process on a fleet machine as proposed, or
everything on the plant core at launch volumes.
7. **Name**: under CNX Vinyl, Poy Records, or its own brand.
+110 -14
View File
@@ -1,23 +1,52 @@
# Biomass Fuel Strategy # Biomass Fuel Strategy
If the steam boiler goes the biomass route (see the options in **Decided 17 October 2026 (user): both business plan versions run on
[sustainability](sustainability.md) and the Getabec candidate in the biomass steam** ("option a and b should operate on biomass"): two 500 kg/h
[utilities CSV](finance/utilities-investment.csv)), the fuel comes from two biomass modules (or one ~1 t/h package, Getabec class, 6M to 10M THB
sources: the team's own 60 rai of currently unused land, and northern installed with fuel feed, grate and dust control) plus a fuel store and
handling block (1M to 2M THB, estimate) in the
[utilities CSV](finance/utilities-investment.csv). The launch plant at
~850k records burns ~954 MWh of heat a year, about 300 t of air-dry wood
or ~460 t of fresh chips, ~0.67M THB at 0.7 THB/kWh, against ~4.9M THB a
year for electric steam with its demand charge (calculator, estimates).
The electric-first staged path under Decision framing is dropped; the
electric bank stays the alternative.
The fuel comes from two sources: the team's own 60 rai of currently unused land, and northern
Thailand's agricultural waste market. Figures below are planning estimates, Thailand's agricultural waste market. Figures below are planning estimates,
plus or minus a wide margin, to be refined against the actual boiler choice plus or minus a wide margin, to be refined against the actual boiler choice
and duty cycle. and duty cycle.
## Demand: what the boiler would burn ## Demand: what the boiler would burn
The 400 kg/h boiler is roughly 300 kW thermal at full fire. With the heat The five-press fleet draws 750 to 900 kg/h of steam at full demand, ~510
recovery architecture trimming the load and realistic duty cycles: to 610 kW thermal, from a proposed bank of two 500 kg/h boilers
([steam and cooling](steam-cooling.html)). Fuel follows records pressed,
not presses installed. With the heat recovery architecture trimming the
load and realistic duty cycles:
- Mature plant (semi-auto plus automated lines, two shifts, ~300 days/yr): - Mature plant (two shifts, ~300 days/yr, about 1.0 to 1.1 million
roughly **350 to 400 tonnes of air-dry wood per year** (at ~80% boiler records): roughly **350 to 400 tonnes of air-dry wood per year** (at
efficiency and ~4 kWh/kg air-dry wood) ~80% boiler efficiency and ~4 kWh/kg air-dry wood); the start fleet at
its full ~1.5 million records needs up to **~550 t/yr**
- Early operations (one press line, single shift): roughly a quarter of - Early operations (one press line, single shift): roughly a quarter of
that, **~90 to 100 t/yr** that, **~90 to 100 t/yr**
- Bought as fresh wood chips (~45 % moisture, ~2.6 kWh/kg) the same heat
is **~540 to 620 t/yr**, up to ~840 t/yr at 1.5 million records, which
is what the fuel store and the monsoon
stock have to be sized for (estimate)
### Recovering heat at the boiler
A fired boiler loses heat up its stack, so an economizer that preheats the
boiler feedwater with the flue gas is the first heat-recovery measure to
investigate, ahead of condensate return and the feedwater heat pump
([sustainability](sustainability.md#energy-efficiency-architecture-recover-before-generating)).
How far the flue gas can be cooled is the vendor's figure: it depends on
the flue-gas temperature, the corrosion limit and the fuel. Rice husk ash
is high in silica and abrasive, so the RFQ asks for fouling and cleaning
provisions, wear protection and a bypass rather than a clean-gas
economizer ([steam and cooling](steam-cooling.html)).
## The 60 rai: own-grown fuelwood ## The 60 rai: own-grown fuelwood
@@ -28,11 +57,14 @@ proven in Thailand (eucalyptus, acacia, leucaena, bamboo) yield roughly 8 to
about **80 to 135 t/yr**: about **80 to 135 t/yr**:
- Enough to cover **most or all of early operations** - Enough to cover **most or all of early operations**
- About **a quarter to a third of mature two-shift demand** - About **a fifth to a third of mature two-shift demand** at ~1.0 million
records, a seventh to a quarter at the start fleet's full 1.5 million
That makes the land a meaningful supplement and a strong brand story That makes the land a meaningful supplement and a strong brand story
("records pressed with steam from our own trees"), not a complete fuel ("records pressed with steam from our own trees"), not a complete fuel
supply. supply. At the market prices below, 80 to 135 t of air-dry wood is worth
only ~0.1M to 0.25M THB a year (estimate): the land's value is supply
security and the story, not the fuel bill.
### The classification check comes first ### The classification check comes first
@@ -62,6 +94,60 @@ The region fills the remainder easily and cheaply:
- Buying from local farmers also strengthens the local-sourcing story that - Buying from local farmers also strengthens the local-sourcing story that
already runs through packaging and PVC already runs through packaging and PVC
## Fuel prices (market check, October 2026)
There is no public price index for biomass fuel in northern Thailand. DEDE
publishes lists of buyers and sellers (February 2026: 42 registered buyers
wanting 2.09M t a year), not prices, so the figures below are reported
market prices from bank research, a government industry unit and the
press, all checked 7 October 2026. None is a quote to this plant.
| Fuel | Reported price | Source | Heat cost (estimate) |
|---|---|---|---|
| Wood chips, fresh (45 to 50 % moisture) | 1,350 to 1,800 THB/t delivered | [LH Bank Research, wood pellet outlook](finance/biomass/LHBank_Wood_Pellets_Industry_Outlook_2026-03.pdf), 9 March 2026: 1,700 to 1,800 THB per fresh tonne for export; a power-plant chip quota in Nakhon Ratchasima at 1,350 THB/t, at most 45 % moisture (undated trader post) | ~0.65 to 0.85 THB/kWh |
| Firewood and rubberwood offcuts, air-dry | over 1 THB/kg at the farm gate, up from 0.55 to 0.70 before late 2025 | [OIE Rubber Intelligence Unit](https://rubber.oie.go.th/Article.aspx?id=66365), 2026; southern rubber belt, so chipping and haulage to Lamphun come on top | ~0.3 to 0.5 THB/kWh before chipping and haulage |
| Corn cobs and stalk residue | 2 THB/kg, bought from farmers in Mae Chaem (Chiang Mai) | Sunsweet's "no burning, we buy" programme, [Prachachat](https://www.prachachat.net/economic/local-economy/news-1498508), February 2024; an incentive price set to stop field burning | ~0.6 THB/kWh |
| Rice husk | ~1.5 THB/kg at past demand peaks | [FTI renewable energy group](https://re-fti.org/%E0%B9%84%E0%B8%9F%E0%B8%9F%E0%B9%89%E0%B8%B2%E0%B8%8A%E0%B8%B5%E0%B8%A7%E0%B8%A1%E0%B8%A7%E0%B8%A5%E0%B8%A3%E0%B8%B0%E0%B8%AA%E0%B9%88%E0%B8%B3%E0%B8%A3%E0%B8%B2%E0%B8%84%E0%B8%B2%E0%B9%81%E0%B8%81%E0%B8%A5%E0%B8%9A%E0%B8%9E%E0%B8%B8%E0%B9%88%E0%B8%87/) (undated); power plants compete for it and northern milling volumes are small | ~0.5 THB/kWh |
| Wood pellets, domestic | 3,000 to 5,000 THB/t | LH Bank Research, March 2026; export FOB averaged 4,482 THB/t in 2025 | ~0.75 to 1.25 THB/kWh |
Heat cost assumes an 80 % boiler (85 % on pellets) and ~2.6 kWh/kg for
fresh chips, ~4 for air-dry wood, ~4.2 for corn cobs, ~3.75 for rice husk
and ~4.7 for pellets (estimates).
What it means for the plan:
- **Planning price: 1.35 to 2 THB/kg delivered**, which is ~0.5 to 0.9 THB
per kWh of heat. The earlier assumption of 1 to 2 THB/kg of air-dry wood
(~0.3 to 0.6 THB/kWh) was too low at the bottom: the cheap end is
farm-gate wood, not chipped fuel at the plant gate. At maturity the fuel
bill is **~0.6M to 1.2M THB a year** (~0.15M to 0.3M early), still a
quarter to a tenth of electric steam (see
[grid tariff](sustainability.md#grid-tariff-pea-and-what-it-decides))
- **Prices are rising and follow diesel.** With diesel near 40 THB/L in
2026, chip traders feeding power plants parked trucks and cut purchases
([Thai Post](https://www.thaipost.net/district-news/971839/), 30 March
2026), and rubberwood firewood roughly doubled since late 2025. Haulage
is a large share of a delivered tonne, so source within ~50 km and write
a diesel clause into the fuel contract rather than a fixed price
- **Supply is not the constraint.** Lamphun alone produces more than
900,000 t of farm residues a year (Maejo University, via
[ThaiPublica](https://thaipublica.org/2026/08/lamphun-reduce-pm2-5-agricultural-waste-biomass-fuel/),
August 2026) against the plant's ~600 t. Buying them also counts against
the burning season, which is part of the story
- **The local price-setter is in Mueang Lamphun.** Ratch Pathana's
[biomass buying centre](https://www.ratchpathana.com/th/our-businesses/related-and-other-businesses/biomass-business)
at Pa Sak, Mueang Lamphun, buys wood waste, sawdust and corn cobs from
farmers for Saha Cogen Green's 9.6 MW, 25 t/h steam cogeneration plant
in the Saha Group Lamphun industrial park. It is the reference price to
ask for and the main competitor for the same fuel. Further out, Clover
Power at Wang Chin (Phrae) buys chips, corn husks and cobs, and bamboo
([DEDE buyer list](finance/biomass/DEDE_biomass_buyers_2026-02.pdf),
February 2026)
- **Next step:** written quotes from the Pa Sak centre and two or three
chip suppliers within 50 km, priced by moisture content (an oven-dry
tonne carries roughly twice the heat of a fresh one), before the boiler
decision
## Logistics on site ## Logistics on site
To reflect in the facility planning: a fuel storage shed (biomass To reflect in the facility planning: a fuel storage shed (biomass
@@ -80,8 +166,18 @@ storage are additional.
- The 60 rai tilts the economics and the story further toward biomass, but - The 60 rai tilts the economics and the story further toward biomass, but
only after the land-title check clears only after the land-title check clears
- The electric boiler remains the alternative: cleanest permitting, no fuel - The electric boiler remains the alternative: cleanest permitting, no fuel
logistics, but effectively grid-powered steam at a ~300 kW draw logistics, but effectively grid-powered steam at a ~520 to 625 kW draw
- A staged path is possible: start electric (fast, clean permitting), plant for the five presses. On PEA's time-of-use tariff that costs ~5.2M to
6.0M THB a year at mature load against ~0.6M to 1.2M of fuel for
biomass, and ~1.6M to 1.8M (one 500 kg/h module) against ~0.15M to 0.3M at early load, because the demand charge follows
the boiler's full-power draw (estimates; see the
[grid tariff](sustainability.md#grid-tariff-pea-and-what-it-decides)).
The electric boiler is the more efficient machine; biomass is the far
cheaper heat
- (Superseded 17 October 2026: biomass from the launch.) A staged path is possible: start electric (fast, clean permitting), plant
the coppice now (first harvest in 2 to 4 years), and add the biomass the coppice now (first harvest in 2 to 4 years), and add the biomass
boiler at the automated-line expansion when demand and the fuel supply boiler at the automated-line expansion when demand and the fuel supply
have both matured have both matured. At the tariff above that is a permitting and logistics
choice, not a cost one: every year on electric steam costs roughly 1.4M
to 5.4M THB more than biomass, so the switch should come as soon as the
permit and a fuel contract are in place
+57 -16
View File
@@ -15,13 +15,25 @@ no corporate income tax holiday on the core pressing activity, but the full
non-tax package and machinery duty exemption. The tax value is engineered on non-tax package and machinery duty exemption. The tax value is engineered on
top through the upgrade measures, where this project happens to be strong: top through the upgrade measures, where this project happens to be strong:
- **Solar and battery**: the alternative-energy measure (Announcement - **Solar: no longer promoted; the battery may be.** The alternative-energy
2/2568, April 2025, under the Smart and Sustainable Industry framework) measure (Announcement 2/2568, April 2025, under the Smart and Sustainable
grants CIT exemption based on the solar investment. Eligible spend Industry framework) granted a CIT exemption on the solar investment,
explicitly includes PV modules, inverters, BESS and BESS inverters, and capped at THB 12M/30M/40M per MW. **Announcement 3/2568** (5 June 2025,
mounting structures, capped at THB 12M/30M/40M of investment value per MW in force 1 July 2025) ended promotion for installing solar power
depending on investment type. The planned Deye + Gobel installation generation under that measure for applications from 1 July 2025; what
converts directly into CIT-exemption headroom. remains is machinery modified to use other renewable energy, and battery
storage (BESS) with its inverters, the eligible investment capped at
THB 12M per MW
([B Global Law](https://bgloballaw.com/2026/01/18/boi-announcement-no-3-2568-amendment-to-renewable-energy-efficiency-enhancement-measures),
[Smarter Energy Solution](https://smarterenergysolution.com/blog/boi-solar-thailand-2026),
checked October 2026). So owning the ~520 kWp factory-roof array earns no BOI
benefit; its case is the bill (see [sustainability](sustainability.md)).
Whether the 271 kWh battery qualifies is for the BOI consultant. A PPA
developer selling solar power (200 kW or more per distribution point)
can still be promoted under activity 7.1.2 (8-year CIT exemption); that
benefit is the developer's, and how much of it reaches the PPA price is
a negotiation
([CapSolar](https://capsolar.co.th/en/knowledge/boi-solar-incentives-2026)).
- **Automation and metrology**: the Smart and Sustainable Industry upgrade - **Automation and metrology**: the Smart and Sustainable Industry upgrade
measure (Announcement 15/2565, refreshed July 2025) rewards automation, measure (Announcement 15/2565, refreshed July 2025) rewards automation,
smart machinery, and energy efficiency, typically 3 years of CIT smart machinery, and energy efficiency, typically 3 years of CIT
@@ -33,15 +45,37 @@ top through the upgrade measures, where this project happens to be strong:
galvanics process development, and recycled-PVC work could be framed as galvanics process development, and recycled-PVC work could be framed as
qualifying development. qualifying development.
So the application is pitched on solar, automation, and technology content, So the application is pitched on automation and technology content (and
not on "we press plastic discs." the battery, if it qualifies), not on "we press plastic discs."
## What Group B still delivers (the core value) ## What Group B still delivers (the core value)
- **Machinery import duty exemption**: significant with the entire equipment - **Machinery import duty exemption**: significant with the entire equipment
list imported (Germany, Sweden, USA, Japan) list imported (Germany, Sweden, USA, Japan). **Import VAT goes with it:**
machinery or raw material imported with the duty exemption is exempt
from VAT at import as well (Revenue Department answer on the
[BOI OSOS FAQ](https://osos.boi.go.th/One-Stop/faq-group/205/FAQ-about-VAT--BOI),
checked October 2026); otherwise a BOI company is treated like any other
for VAT. What it is worth: the capex blocks in
[total investment](finance/total-investment.md) are vendor prices
without duty or VAT, so they already assume promotion. Without it, the
~2.3M USD of imported machinery in the launch plant (presses, galvanics
line, Sibert, cutting room, metrology; block midpoints, as
[total investment](finance/total-investment.md#launch-plant-october-2026)
states it) would carry import duty, roughly 5 % (Thailand's MFN averages
4.1 % on HS 8477 plastics machinery, 0 to 10 % across HS 84; estimate
until the HS codes are set), ~0.11M USD, and 7 % import VAT, ~0.17M USD
paid at the border and only recovered later as input tax, mostly as a
refund claim because exports are zero-rated. The
[plant and business plan calculator](fleet-calculator.html) shows both
cases; its BOI switch also counts the water treatment (ZLD/DI) as
imported, ~2.5M USD at the midpoint (figures re-based October 2026; the
earlier ~2.75M was the superseded start fleet).
- **100% foreign ownership** of the promoted manufacturing company, - **100% foreign ownership** of the promoted manufacturing company,
overriding Foreign Business Act restrictions for the promoted activity overriding Foreign Business Act restrictions for the promoted activity.
The intended split: the main investor holds at least 60 %, at most
40 % goes to co-investors (user, October 2026;
[total investment](finance/total-investment.md#two-plans-a-at-180m-thb-and-b-at-215m-thb-october-2026))
- **Land ownership** for the promoted operation despite foreign - **Land ownership** for the promoted operation despite foreign
shareholding, plus a small allowance for office/residential use; note the shareholding, plus a small allowance for office/residential use; note the
privilege is tied to the promotion, which matters for the buy-vs-lease privilege is tied to the promotion, which matters for the buy-vs-lease
@@ -57,8 +91,10 @@ not on "we press plastic discs."
- Minimum investment THB 1,000,000 excluding land and working capital - Minimum investment THB 1,000,000 excluding land and working capital
(comfortably cleared by the first pressing line alone) (comfortably cleared by the first pressing line alone)
- Debt-to-equity ratio no higher than 3:1, maintained for the life of the - Debt-to-equity ratio no higher than 3:1, maintained for the life of the
privileges; plan the equity/loan mix for the machinery and solar capex privileges. Met with room to spare: the shareholders fund the whole
accordingly plant as share capital and no bank loan is planned (user, October 2026;
[total investment](finance/total-investment.md#two-plans-a-at-180m-thb-and-b-at-215m-thb-october-2026)),
so any later loan keeps the same ceiling
- Modern machinery and process expected; ISO/environmental compliance for - Modern machinery and process expected; ISO/environmental compliance for
larger projects larger projects
- BOI promotion does not replace the factory license (Ror.Ngor. 4), - BOI promotion does not replace the factory license (Ror.Ngor. 4),
@@ -104,11 +140,16 @@ project timeline, ahead of equipment contracts.
- Confirm the exact activity sub-code and tier for vinyl/PVC consumer-goods - Confirm the exact activity sub-code and tier for vinyl/PVC consumer-goods
pressing (Group B assumption is well supported but not code-verified) pressing (Group B assumption is well supported but not code-verified)
- Confirm the live versions and per-MW caps of the solar and - Confirm the live version of the smart-and-sustainable measures at
smart-and-sustainable measures at filing time filing time, and whether the battery qualifies under the BESS part of
the alternative-energy measure (THB 12M per MW cap); solar itself is out
since 1 July 2025 (Announcement 3/2568)
- Confirm current NEC/Lamphun area add-ons - Confirm current NEC/Lamphun area add-ons
- Engage a BOI-registered consultant to structure the application so the - Engage a BOI-registered consultant to structure the application so the
solar, automation, and R&D measures stack on the base promotion automation and R&D measures (and the battery) stack on the base promotion
- Check whether R&D contracted with Payap University and the joint student
programmes ([Payap partnership](payap-partnership.md)) count toward the
R&D merit or a skills-development measure
- Keep any future label/content/retail arm in a separate entity: media and - Keep any future label/content/retail arm in a separate entity: media and
service activities carry different (and sometimes Thai-ownership) service activities carry different (and sometimes Thai-ownership)
conditions, and mixing them muddies a clean manufacturing application conditions, and mixing them muddies a clean manufacturing application
Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+46
View File
@@ -0,0 +1,46 @@
"""Build the CNX Vinyl business plan .docx, in its two versions (October 2026).
python build_plan.py -> ../CNX-Vinyl-Business-Plan-A.docx and -B.docx
python build_plan.py A -> ../CNX-Vinyl-Business-Plan-A.docx
python build_plan.py B out.docx -> Plan B to a custom path
Plan A (~180M THB) and Plan B (~215M THB) share every chapter; the content modules
switch the plan-specific text with plan_variant.pick(). Images are resolved relative
to docs/ (the parent of business-plan/).
"""
from __future__ import annotations
import sys
from pathlib import Path
HERE = Path(__file__).resolve().parent
sys.path.insert(0, str(HERE))
from plan_lib import Renderer # noqa: E402
import plan_variant # noqa: E402
import content_a, content_b, content_c # noqa: E402
DOCS = HERE.parent.parent # .../docs
VERSION = "draft 0.3, October 2026"
def out_path(plan: str) -> Path:
return HERE.parent / f"CNX-Vinyl-Business-Plan-{plan}.docx"
def main(plan: str = "A", out: Path | None = None) -> Path:
plan_variant.PLAN = plan
out = out or out_path(plan)
r = Renderer(DOCS, header_text=f"CNX Vinyl / Poy Records: Business plan, {plan_variant.label()}, {VERSION}",
footer_text="Confidential")
r.render(content_a.blocks() + content_b.blocks() + content_c.blocks())
r.save(out)
return out
if __name__ == "__main__":
args = sys.argv[1:]
plans = [args.pop(0).upper()] if args and args[0].upper() in ("A", "B") else ["A", "B"]
target = Path(args[0]) if args else None
for p in plans:
print(main(p, target if len(plans) == 1 else None))
+973
View File
@@ -0,0 +1,973 @@
"""Part A: cover, reading guide, executive summary, opportunity, anatomy of the plant.
Builds Plan A (~180M THB) or Plan B (~215M THB): plan-specific text is switched with
plan_variant.pick() inside blocks(), never at import time.
"""
from plan_lib import H1, H2, H3, P, B, N, T, KV, IMG, CALL, PB, TOC, COVER
from plan_variant import pick, is_a, is_b, label, name
def blocks():
out = []
LP = pick("Launch plant", "At launch") # 'When' column of the 4.0 checklist
# ------------------------------------------------------------ cover
out.append(COVER(
kicker="CNX VINYL / POY RECORDS",
title="What It Takes to Build a Top-Notch Vinyl Plant",
subtitle="Business plan for a full-service vinyl, cassette and CD manufacturing plant "
"in the Chiang Mai region, Northern Thailand",
image=pick("renders/calculator/plan-a-cover.png", "renders/calculator/plan-b-cover.png"),
lines=[
"**Prepared for:** the project's lead investor",
"**Prepared by:** Simona Meesaiyati (Project Lead) and Alexander Grabowski (Technical Consultant), "
"supported by buildfor.life, with Ploy Printing (Chiang Mai) as packaging partner and "
"strategic co-investor",
f"**Version:** Draft 0.3, October 2026: **{name()}, {pick('~180M THB', '~215M THB')}**",
],
note="Confidential. All figures in USD and THB at 1 USD = 33 THB (August 2026). Vendor quotes are "
"snapshots at their file dates, not commitments. Every number in this plan is labelled as quoted, "
"researched, or estimated; see section 2. " + pick(
"This version is Plan A: the launch plant with the whole chain, cutting and galvanics "
"included, three presses, with six cost levers taken: labelled ~180M THB, it comes to "
"~182M at the midpoint, about 2M above 180M. A second version, Plan B (~215M THB), builds "
"the same plant and takes none of the levers. ",
"This version is Plan B: the launch plant with the whole chain, cutting and galvanics "
"included, three presses, with everything in and none of the cost levers taken, at ~215M "
"THB (~217M). A second version, Plan A (~180M THB), builds the same plant with six cost "
"levers. ")
+ "The plan price includes the ramp-up reserve and carries no contingency. Cover picture: the "
"plant as the plant and business plan calculator draws this plan (schematic, Payap scenario "
"layout, section 6.2). Draft 0.3 replaces "
"draft 0.2 (October 2026), which described a single launch plant priced with a contingency.",
))
out.append(TOC())
# ------------------------------------------------ 1 executive summary
out += [
H1("1. Executive summary"),
P("CNX Vinyl (label name Poy Records) is a planned record manufacturing plant for the Chiang Mai "
"region of Northern Thailand. Its premise is simple: a label or artist in Asia-Pacific should be "
"able to send an audio file to one place and receive finished, packaged, fully traceable records at "
"their door, without shipping a fragile lacquer disc across the world and without waiting for metal "
"stampers to come back from Europe. Today that customer presses in Europe, the United States or "
"Japan. The one Thai pressing shop we have seen presses only: it buys its stampers abroad, runs "
"without climate control, and cannot economically serve runs under 300 units."),
P("This document explains, for a reader who is not a vinyl specialist, what a top-notch plant "
"consists of, why each part matters, what it costs, what it can earn, how long it takes, and what "
"could go wrong. It is built from the project's planning repository and vendor documents, and it "
"keeps the honest parts: where a number is an estimate, it says so; where the evidence is thin, it "
"says that too."),
P("**What changed since the earlier drafts.** In October 2026 the plan moved from a phased entry (one "
"press at launch, stampers bought in from the UK, cutting bought in from Europe) to a **launch plant** "
"that has the whole chain from the first day, bought in one capital round and commissioned in "
"sequence. There are no bridge stampers and no outsourced cutting in the plan any more. Draft 0.3 "
"prices that plant in **two versions**, both including the ramp-up reserve and neither carrying a "
"contingency: **Plan A (~180M THB)**, the launch plant's three presses with six cost levers, and "
"**Plan B (~215M THB)**, the same three presses with everything in. " + pick(
"**This document is Plan A**, and every section below is written for it; a short table after "
"the numbers compares the two versions.",
"**This document is Plan B**, and every section below is written for it; a short table after "
"the numbers compares the two versions.")),
H2("What we will build"),
B([
"**The complete vinyl chain under one roof:** mastering, lacquer cutting, galvanics (growing the "
"nickel stampers), stamper preparation, pressing, finishing, packaging with our Chiang Mai print "
"partner Ploy Printing, and fulfilment including direct-to-fan dropshipping.",
"**Three presses at launch:** one Newbilt Duplex system (two semi-automatic presses with a main "
"and a colour extruder, for colour, splatter and short runs) and one Newbilt Classic fully "
"automatic press for long standard runs. Special prints are the focus (60 % and more of the "
"records), and specials run only on the Duplex, so together they make about 0.58 to 0.90 "
"million records a year on two shifts (0.71 to 0.97 million at a standard-heavy mix; "
"estimates). A second Duplex system is a growth step from revenue, with its floor, utility "
"positions and pipe connections reserved, not part of the investment.",
"**The metal path in-house:** a Sillitoe SDMS cutting room, a Pheenix Alpha galvanics line with "
"zero-discharge water treatment, and the Sibert stamper-prep line. The father and the mother of "
"every side are archived, so represses start from our own metal.",
"**A modular utility plant:** a boiler hall and a chiller compound built once for four modules "
"each, with two 500 kg/h biomass boiler modules (B-1, B-2) and two 250 kW chiller modules "
"(CH-1, CH-2) installed at launch; further presses add modules, not rooms. **Steam is biomass "
"from launch in both versions of this plan**, fired with wood chips from a covered fuel "
"store: ~0.67M THB of fuel a year against ~4.9M THB for electric steam (estimates). Electric "
"boilers are the alternative, not the plan.",
pick("**Cassette duplication and CD-R duplication as a growth step** after launch, not in the "
"plan price; both fit inside the building programme. ",
"**Cassette duplication and CD-R duplication in-house** from launch. ")
+ "Full CD replication "
"(injection-moulded discs) is a separate, much larger decision, outside the totals; both CD "
"routes are set out in section 4.10 for the investor to decide.",
"**A purpose-built ~1,500 m² plant on long-term leased land**, with a detached utility yard, "
+ pick("solar on the factory roof (~520 kWp, estimate) through a solar power purchase "
"agreement (PPA)",
"owned solar on the factory roof (~520 kWp, estimate) with a battery")
+ ", the office roof and the car and scooter canopies built PV-ready for later panels, and "
"room for a second building.",
"**Open source throughout:** every plant server runs NixOS, declared in one repository in the "
"fleet B4L already operates, so any machine is rebuilt from it; ERPNext (no licence fee) is the "
"only system of record; and our own code (the factory console, the plant overview, the artist "
"platform, the calculator) is published as open source, licence to be chosen. The exception is "
"the vendors' own firmware and control software in the machines, instruments and inverters, "
"kept as appliances that export data into our systems and run none of our services. Once the "
"plant has run this stack in production for at least a year, it and our factory-automation "
"services can be offered to other pressing plants; that is not in the revenue (section 5.6).",
"**Commissioned in sequence:** the cutting room and galvanics first (the presses need their "
"stampers), then " + pick("the Duplex system, then the Classic",
"the Duplex system, then the Classic, with cassette and CD-R "
"duplication alongside")
+ ". That puts galvanics, the hardest skill to "
"hire, on the path to the first paying release. Sibert, the stamper-prep supplier in the plan, "
"advised after the Haarlem trade show to get presses, boilers, operators and feedback loops "
"right first; " + pick("the launch plant", "the whole chain at launch")
+ " was decided anyway, and that advice is carried as a risk (sections 11.2 and 13).",
pick(
"**Six cost levers bring the plant to ~182M THB: labelled ~180M, it is about 2M above 180M "
"at the midpoint** (177M with the low end of the ramp-up reserve), from ~201.6M to ~167.1M "
"THB at the midpoint before the reserve (estimates, section 8): solar on the factory roof "
"(~520 kWp) and the battery through a solar PPA (the installer owns and finances the array, "
"the plant buys the power); metrology in two steps (XRF, inline vision and the audio "
"station at launch, the laser confocal and the "
"wide-area profiler bought from revenue); the visitor corridor built later, so no public tours "
"at first; cassette and CD-R duplication later; a mobile crane rented for the installations, "
"with frame, runway and machine door kept crane-ready; the compressor through the Chinese "
"route. Every press, the cutting room, the galvanics line, the stamper-prep line and the "
"biomass boilers stay in. The Chinese route priced only electric boilers; a Chinese biomass "
"boiler is not yet quoted, and one ~2M THB or more below the Thai package would bring the "
"midpoint back to 180M.",
"**Everything in, none of the cost levers: ~215M THB** (~217M at the midpoint with the "
"ramp-up reserve, ~201.6M THB before it) and ~35M THB more than Plan A (estimates, section "
"8): owned solar on the factory roof (~520 kWp) and the battery, so no PPA power bill (~1.9M "
"THB a year in Plan A, estimate); the full metrology stack from launch (XRF, "
"laser confocal, wide-area profiler, inline vision, audio station); the visitor corridor and "
"accessible entrance, so public tours and the Payap student programmes are possible from the "
"start; cassette and CD-R duplication; a bought 5 t overhead crane; the compressor from a "
"Thai supplier, with local service. Every press, the cutting room, the galvanics line, the "
"stamper-prep line and the biomass boilers are the same as in Plan A."),
]),
H2("What makes it top-notch"),
P("Four things separate this plant from a pressing shop, and they are the reason it can charge "
"export-grade prices in a region that currently has none:"),
N([
"**Traceability from audio file to shipment.** Every lacquer, father, mother, stamper, press "
"cycle, compound lot and carton lot gets an identity that knows its parents; a pressed record is "
"identified by its stamper, press, cycle time and side. The plant runs **ERPNext as its only "
"system of record** (orders, invoices, stock, job cards, batches, inspections, metal-part "
"genealogy); machine data (press cycles, instrument files, audio captures) sits beside it, keyed "
"to the same ERPNext names. A customer sees their order's full chain; a complaint resolves to one "
"stamper, one press, one shift and one material lot. The **father and the mother of every side "
"are archived**: a mother gives about ten stamper sets and a father five to ten mothers "
"(industry rules of thumb), so a repress starts from the archived mother and a worn mother is "
"regrown from the father without a new cut. At Making Vinyl Europe in Haarlem this was what the "
"industry responded to most.",
"**Metrology and layered quality control.** The nickel parts are measured without contact "
+ pick("and logged per serial, which is ahead of current industry practice: XRF thickness from "
"launch, the laser confocal and the wide-area profiler bought from revenue. ",
"(laser confocal, wide-area profiler, XRF thickness) and logged per serial, which is ahead "
"of current industry practice. ")
+ "Every pressed record passes 100% inline optical inspection, every "
"press cycle is logged, and sampled records are compared automatically against the source "
"master.",
"**Efficiency designed in.** Heat is recovered before energy is generated: in order, a flue-gas "
"economiser on the biomass boilers, as much condensate back to the feed tank as possible, then "
"a heat pump that lifts the presses' ~60 °C cooling return into boiler feedwater. Solar goes on "
"the factory roof: **~520 kWp** on the Payap scenario layout, about 730 to 780 MWh a year, of "
"which ~87 % is used on site (~633 MWh, ~61 % of the launch plant's ~1,036 MWh a year of "
"electricity); the rest is curtailed, because a factory on PEA's grid runs zero export and is "
"not paid for surplus. With biomass steam the running load is ~230 kW, and an hourly sketch "
"puts the best array for it at ~500 to 550 kWp, so the factory roof sits at that optimum "
"(estimates). The office roof (~65 kWp) and the car and scooter canopies (~54 kWp) are built "
"PV-ready (structure rated for panels, conduit to the main board) and take panels when the "
"load rises with the second Duplex system: ~120 kWp for ~2.4M to 3.1M THB (estimate). On the "
"Mueang Chi hall the factory roof takes ~247 kWp and its canopies are PV-ready too. A 271 kWh "
"battery gives ride-through"
+ pick(
"; array and battery come through the solar PPA: the installer owns and finances them, the "
"plant buys the power. ",
"; array and battery are owned by the plant. ")
+ "Cooling runs as a closed loop, no process water is discharged, "
"galvanics rinse water goes through a zero-discharge evaporator, and 20% of the feedstock is "
"in-house regrind. Boilers and chillers come in identical modules, so spares and service are one "
"routine. At reported northern fuel prices biomass heat costs a quarter to a tenth of electric "
"steam, which is why steam is biomass from launch: it saves ~4.2M THB (~USD 0.13M) a year "
"against electric boilers and keeps the grid demand at ~264 kW instead of ~980 kW (estimates).",
"**Climate control as product quality.** The whole plant runs at 20 to 26 °C, 35 to 60% "
"relative humidity, with particulate filtration sized for Northern Thailand's burning season. "
"Moisture and dust are the two classic causes of noisy records; the plant we visited has "
"neither control.",
]),
H2("The numbers"),
KV([
["Capacity", pick(
"~0.58M to 0.90M records/yr at 60 % specials (2 semi-automatic presses + 1 Classic, 2 shifts; "
"the Duplex sets the pace; estimate; the press fleet calculator gives ~0.94M at our planning "
"rates). Second Duplex as a growth step from revenue: ~1.0M to 1.5M",
"~0.58M to 0.90M records/yr at 60 % specials, central 0.74M (2 semi-automatic presses + 1 "
"Classic, 2 shifts; the Duplex sets the pace; estimate; the press fleet calculator gives ~0.94M "
"at our planning rates). Second Duplex as a growth step from revenue (section 4.4); full hall "
"as a later option: ~2.9M to 4.4M")],
["Site", "~1,500 m² main building plus a ~379 m² utility yard built for four boiler and four "
"chiller modules and a covered biomass fuel store, on leased land (~4 rai minimum, "
"6 to 8 rai with expansion); second "
"building as expansion"],
[pick("Investment, Plan A", "Investment, Plan B"), pick(
"**~THB 182M (~USD 5.52M), labelled ~180M THB**: the plan investment, ~THB 167.1M (~USD "
"5.06M) at the midpoint with the six levers taken, plus a ramp-up reserve of ~THB 10M to 20M "
"(staff and overheads before volume covers them). **At the midpoint that is about 2M above "
"180M**; with the low end of the reserve (~177M) it fits. From the low to the high end of "
"every block: ~THB 132M to 233M. Estimates: no quote yet for the Classic, the galvanics line "
"(priced at OMS's reference plus 20 %) or the building",
"**~THB 217M (~USD 6.56M), labelled ~215M THB**: the plan investment, ~THB 201.6M (~USD "
"6.11M) at the midpoint with everything in, plus a ramp-up reserve of ~THB 10M to 20M (staff "
"and overheads before volume covers them); at the midpoint ~0.6M above the investor's 180M "
"THB plus 20 % (216M), inside 225M. From the low to the high end of every block: ~THB 156M "
"to 277M. "
"Estimates: no "
"quote yet for the Classic, the galvanics line (priced at OMS's reference plus 20 %) or the "
"building")],
["Not in the plan price", "**No contingency** (at the 15 % used in the cost documents, ~THB "
+ pick("25M", "30M") + " at the midpoint): quotes that land high are "
"funded outside the plan or by scope steps (section 8). Also not in "
"it: the central hydraulic plant (not yet costed), the archive's mobile "
"shelving (to quote), CD replication, financing costs, currency moves, "
"and Thai duty and import VAT (the blocks assume BOI promotion)"],
["Land lease", "Not negotiated; the plan carries an estimated THB 0.3M to 1.0M per year "
"(USD 9k to 30k), section 6.1"],
["Operating result, mature year", pick(
"Central case at 60 % specials: revenue ~USD 3.65M (~THB 120M), EBITDA ~USD 1.73M (~THB "
"57M), operating profit ~USD 1.33M (~THB 44M); break-even on operating profit at ~0.2M "
"records a year. **The adverse case loses money:** EBITDA ~USD 0.23M, operating loss ~USD "
"0.41M (~THB 14M); it would need ~1.0M records a year to cover depreciation and the three "
"presses make 0.58M at that rate. The solar PPA's power price (~USD 0.06M a year in the "
"calculator) is not in these figures. Utilisation and price decide the outcome, not upside "
"(section 9)",
"Central case at 60 % specials: revenue ~USD 3.65M (~THB 120M), EBITDA ~USD 1.73M (~THB "
"57M), operating profit ~USD 1.24M (~THB 41M); break-even on operating profit at ~0.24M "
"records a year. **The adverse case loses money:** EBITDA ~USD 0.23M, operating loss ~USD "
"0.55M (~THB 18M); it would need ~1.1M records a year to cover depreciation and the three "
"presses make 0.58M at that rate. Cassette, CD-R and tour revenue are not in these figures. "
"Utilisation and price decide the outcome, not upside (section 9)")],
["Payback", pick(
"~3.2 years on the plan price in the central case (2.3 to 4.1 from the low to the high end of "
"the price); ~1.1 years in the favourable case, ~31 years in the adverse case (EBITDA, mature "
"year, ramp-up reserve included; estimates)",
"~3.8 years on the plan price in the central case (2.7 to 4.9 from the low to the high end of "
"the price); ~1.2 years in the favourable case, ~37 years in the adverse case (EBITDA, mature "
"year, ramp-up reserve included; estimates)")],
["First paying release", "**Open.** The August 2026 calendar gives Q4 2028 to mid-2029 (27 to 33 "
"months from the start of phase 0), but it was drawn for a one-press "
"launch. Commissioning the cutting room and galvanics before the presses "
"is not yet in it, and the lathe, galvanics line and stamper-prep build "
"times are not on file, so the date stays open until those vendors "
"quote. Ordering machinery before the BOI certificate, if allowed, could "
"still pull it forward by 6 to 9 months (section 10)"],
["People", "~15 to 25 across shifts at volume (estimate); the launch plant needs most of that "
"crew, because two shifts still need press, finishing, galvanics, QC and maintenance "
"staff (13 to 19 direct production staff in the revenue model)"],
["The ask", pick(
"~THB 182M (~USD 5.52M), the plan labelled ~180M THB (about 2M above 180M at the midpoint), "
"released in tranches against milestones (section 8), starting with phase 0 (~THB 1.3M to "
"2.6M). Funded entirely by the shareholders as share capital, no bank loan planned: the "
"lead investor's 60 % is at least ~THB 109M, the 40 % open to co-investors at most ~THB 73M "
"(arithmetic at one share price)",
"~THB 217M (~USD 6.56M), the ~215M THB plan, released in tranches against milestones "
"(section 8), starting with phase 0 (~THB 1.3M to 2.6M). Funded entirely by the shareholders as "
"share capital, no bank loan planned: the lead investor's 60 % is at least ~THB 130M, the 40 % "
"open to co-investors at most ~THB 87M (arithmetic at one share price)")],
]),
H2("Two versions of this plan"),
P("This plan comes in two versions, built from the same documents and the same machine choices. " + pick(
"This document is **Plan A**. The other version, **Plan B (~215M THB)**, builds the same three "
"presses and takes none of the six levers. ",
"This document is **Plan B**. The other version, **Plan A (~180M THB)**, builds the same three "
"presses (one Duplex system and the Classic) and takes six cost levers. ")
+ "Both carry the ramp-up reserve and neither carries a contingency, and in both the second Duplex "
"system is a growth step from revenue. What decides between them is no longer demand, because both "
"make the same records: it is whether the investor funds ~THB 35M (~19 %) more at launch for what "
"Plan A leases or buys from revenue. Plan B owns its solar array (no PPA power bill), measures "
"every stamper fully from the first release, makes tours and the Payap "
"programmes possible from the start, sells cassette and CD-R from launch, owns its crane and buys "
"its compressor with local service; both run on biomass steam. On the modelled numbers that extra "
"earns little (the same EBITDA in the revenue model, ~USD 0.06M a year more in the calculator for "
"the PPA power bill the "
"owned array avoids; more depreciation, a longer payback, a deeper adverse case), so Plan A has "
"the better modelled return and Plan B the more complete plant. Most of Plan B's items can be added to Plan A "
"later from revenue; the corridor is cheaper to build in from the start, and owning the array "
"saves the PPA bill from the first year. BOI no longer promotes solar installations (since 1 July "
"2025, section 7.1), so neither plan earns a tax benefit on the array. "
"Section 8 sets the two side by side."),
T(["", "Plan A", "Plan B"], [
["Plan price (ramp-up reserve in, no contingency)", "~THB 182M (~USD 5.52M), ~2M above 180M at "
"the midpoint; ~132M to 233M from the low to the high end", "~THB 217M (~USD 6.56M); ~156M to "
"277M from the low to the high end"],
["Presses", "3: one Duplex system (2 semi-automatic) and one Classic", "The same 3"],
["Records a year at 60 % specials", "~0.58M to 0.90M (central 0.74M)", "The same"],
["Steam", "Biomass from launch: two 500 kg/h modules and a covered fuel store", "The same"],
["EBITDA, central case", "~USD 1.73M (~THB 57M)", "~USD 1.73M (~THB 57M); cassette and CD-R "
"not modelled"],
["Operating profit, central case", "~USD 1.33M (~THB 44M)", "~USD 1.24M (~THB 41M)"],
["Payback on the plan price, central case", "~3.2 years (2.3 to 4.1)", "~3.8 years (2.7 to 4.9)"],
["Adverse case", "Loses money: EBITDA ~USD 0.23M, operating loss ~USD 0.41M",
"Loses money: EBITDA ~USD 0.23M, operating loss ~USD 0.55M"],
["What Plan A gives up, what Plan B buys", "At launch: solar through a PPA (a power bill of "
"~USD 0.06M a year instead of owning the array), no confocal or profiler, no visitor corridor "
"or tours, no cassette or CD-R, a rented crane; a Chinese-made compressor",
"~THB 35M more at launch: owned solar (~520 kWp on the factory roof) and battery, "
"so no PPA bill, the full "
"metrology stack, the visitor corridor and tours, cassette and CD-R, a bought crane; "
"a Thai-supplied compressor"],
], widths_mm=[42, 64, 64], font_pt=8.5,
caption="Estimates: mature year at 60 % specials, from the revenue model; payback counted on the "
"whole plan price including the reserve. A central EBITDA margin of ~47 % (both plans) is "
"far above the 15 to 25 % pressing plants earn; read the adverse case as the honest one. "
"The revenue model does not split energy cost by plan or fuel, so the PPA bill and the "
"biomass saving show only in the calculator."),
H2("Where we are, and what we ask"),
P("The project is at the planning stage. Industry outreach has run for several years. Alexander and "
"Simona attended **Making Vinyl Europe in Haarlem** (30 September to 2 October 2026): most people "
"they talked to were strongly interested in the full-traceability approach, and for Sibert it was "
"the reason to engage at all. Since the show Sibert has confirmed a **USD 250k budget** for its "
"three stamper-prep machines; Pheenix Alpha's CEO has offered a call, reference clients and a "
"factory visit (the next Europe trip is planned for February 2027); OMS has sent reference prices "
"for a galvanics wet room; and SST in Frankfurt, which already cuts Poy Records' lacquers, has "
"offered help. This is supplier-side evidence, not buyer price validation."),
P("Vendor quotes exist for the pressing line (2024, expired), utilities have been costed with Thai "
"suppliers, and a parametric building model has produced quantities for a construction price "
"request. **Site:** a leased parcel in Mueang Chi, Lamphun, is the working candidate the design is "
"tested against; Payap University in Chiang Mai has offered land on lease and joint student "
"programmes, but the point it gave fails zoning (zoned very high density residential, where "
"record pressing is not permitted; checked October 2026), and its other plots are not yet "
"checked. Nothing has been re-sited and **nothing has been ordered**."),
P("Three gates run now and in parallel: **market validation** (buyer prices from regional labels; "
"none yet); the **BOI investment promotion** track with a registered consultant; and **land**: "
"zoning, lease terms and a soil test. Nothing large is spent until its gate clears."),
CALL("What the investor is asked to fund now", [
"**Phase 0 (next 3 to 6 months): ~USD 40k to 80k (~THB 1.3M to 2.6M)** for the BOI consultant, "
"Thai legal work on the lease and zoning, a soil boring test, and the requests that settle most "
"of the investment band: " + pick(
"the Newbilt re-quote for the Duplex system (with an EX 35 price) and the Classic, a Pheenix "
"quote for the galvanics line, the building price request with the soil test, metrology "
"distributor quotes, a solar PPA offer and a Chinese biomass-boiler quote (one ~2M THB or "
"more below the Thai package brings Plan A's midpoint back to 180M).",
"the Newbilt re-quote for the Duplex system (with an EX 35 price) and the Classic, a Pheenix "
"quote for the galvanics line, the building price request with the soil test, and metrology "
"distributor quotes."),
pick(
"**Then the Plan A round, ~THB 182M (~USD 5.52M), labelled ~180M THB**, about 2M above 180M "
"at the midpoint, including the "
"ramp-up reserve and without contingency, released in tranches against milestones: BOI "
"certificate and lease signed, long-lead orders (lathe, galvanics, stamper prep, presses, "
"boiler and chiller modules), building contract, fit-out, commissioning in sequence "
"(section 8). From the low to the high end of every block the plan runs from ~THB 132M to "
"233M; quotes that land high are funded outside the plan or by scope steps.",
"**Then the Plan B round, ~THB 217M (~USD 6.56M), labelled ~215M THB**, including the "
"ramp-up reserve and without contingency, at the midpoint ~0.6M above the investor's 180M "
"THB plus 20 % (216M) and inside 225M, released in tranches against milestones: BOI "
"certificate and lease signed, "
"long-lead orders (lathe, galvanics, stamper prep, presses, boiler and chiller modules), "
"building contract, fit-out, commissioning in sequence (section 8). From the low to the high "
"end of every block the plan runs from ~THB 156M to 277M; quotes that land high are funded "
"outside the plan or by scope steps."),
"**Decisions needed from the investor:** which version to fund, Plan A or Plan B (both make the "
"same records, so the choice is ~THB 35M more at launch for what Plan A leases or defers; the "
"Classic, Pheenix and EX 35 quotes, the solar PPA offer and the building quote settle the "
"numbers); the share capital's call schedule against the tranches (the shareholders fund the whole "
"plant, no bank loan planned, so BOI's 3:1 debt-to-equity ceiling is met with no debt); and CD "
"replication, yes or no (it must be in the BOI application from the start). The steam fuel is "
"no longer open: both versions run on biomass steam from launch.",
"**Co-investment:** Ploy Printing, the Chiang Mai print and packaging house that will produce "
"the plant's jackets and sleeves, has expressed the intention to invest alongside the lead "
"investor. The lead investor holds at least 60 % of the company, so at most 40 % is open to "
"Ploy Printing, the founders and any further co-investor. Terms are not yet discussed; the "
"intended structure is described in section 12.2.",
]),
# ----------------------------------------------- 2 reading guide
H1("2. How to read the numbers"),
P("**Two versions.** This business plan comes in two versions, built from the same documents: "
"**Plan A (~180M THB)**, the launch plant's three presses with six cost levers, and **Plan B "
"(~215M THB)**, the same three presses with everything in. Both plan prices include the ramp-up "
"reserve and neither carries a contingency. This document is **" + label() + "**. Chapters that "
"do not depend on the choice read the same in both; where the plans differ, this version gives "
"its own figures, and sections 1 and 8 compare the two."),
P("Every figure in this plan carries one of three confidence levels. Where a table does not say, "
"the basis column or caption does."),
T(["Label", "Meaning", "Examples"], [
["Quoted", "A vendor document exists, in its original currency: a quote, a budget confirmation "
"or a published list price. Quotes may have expired and need re-confirmation.",
"Newbilt pressing line (EUR 200,500, June 2024, expired); Sibert's USD 250k budget confirmation "
"for the stamper-prep line (October 2026); Sillitoe SDMS list price USD 125k (ex tax and "
"shipping); OMS reference prices for a galvanics wet room; Newbilt service rates"],
["Researched", "Published or market data gathered by the team, including one set of real Thai "
"invoices.", "Record Industry's online price calculator (October 2026); Thai "
"pressing invoices (August 2026); the PEA electricity tariff; vendor "
"flyers and datasheets; reported biomass fuel prices; BOI measures"],
["Estimate", "Engineering ratio or industry norm with no vendor confirmation. Treat as "
"plus or minus 30 to 50%.", "Building cost per m²; the Pheenix galvanics line (no "
"Pheenix price on file; priced at OMS's reference plus "
"20 %) and the Newbilt Classic (no price on file); the "
"cutting room beyond the lathe; metrology stack; land "
"lease; the solar yield and the share used on "
"site; " + pick("the solar PPA power price; ", "")
+ "all cassette and CD figures"],
], widths_mm=[22, 70, 78]),
P("Currency: USD and THB at 1 USD = 33 THB (5 August 2026). Vendor quotes issued in EUR or GBP are "
"kept in their currency next to their source and converted at 1 EUR = 1.155 USD and "
"1 GBP = 1.35 USD. Currency exposure is real and is discussed in section 8.5."),
P("Deliberately **not** in this plan: a contingency in the plan price (section 8); bank debt (the "
"shareholders fund the whole plant as share capital; the share price and call schedule are to be "
"agreed, section 12.2); "
"a signed customer; a signed lease; firm quotes for the Classic, the galvanics line, the metrology "
"stack or the building; a price for the central hydraulic plant; and a year-by-year cash model. "
"Each of these is a named next step in section 14. The revenue also leaves out two upsides that "
"have no price or volume yet: supplying stampers to other plants (section 3.3), and services to "
"other pressing plants built on the plant's open-source software and factory automation "
"(section 5.6)."),
# ------------------------------------------------- 3 opportunity
H1("3. The opportunity"),
H2("3.1 The product"),
P("A vinyl record is made by cutting the audio into a soft lacquer disc, growing a set of nickel "
"metal parts from that lacquer by electroplating (the 'stampers'), and pressing hot PVC between two "
"stampers under about 150 tonnes of force with steam heating and water cooling. The record is then "
"trimmed, sleeved, put into a printed jacket, shrink-wrapped and shipped. Each of these "
"steps has its own equipment, skills and failure modes, and most plants in the world do only some "
"of them, sending the rest out to specialists, often on other continents."),
P("Demand for vinyl has grown for well over a decade from a small base. The 2021 to 2022 boom "
"pushed lead times at European and US plants to six to nine months; they have since normalised to "
"roughly 10 to 16 weeks for a standard black LP, and global capacity has been added. Demand is "
"cyclical and this plan does not assume it only rises; it assumes the plant can sell what it "
"presses, which is the single assumption most worth testing (section 3.3)."),
H2("3.2 Where regional labels press today"),
P("Labels and artists in Southeast Asia, Australia and much of East Asia ship their masters to "
"Europe, the United States or Japan, wait in those plants' queues, and pay freight and time zones "
"on top. We know of no industrial-grade, climate-controlled, full-service plant in the region. That "
"is the gap. It is also the plan's biggest assumption: that enough regional customers will pay for "
"a closer, faster, more accountable plant at a price that works. That pricing power is unproven. "
"The Haarlem trade show produced strong supplier interest but no buyer prices, and the market "
"validation gate exists to test it before capital is committed."),
H2("3.3 What the market shows: two price points"),
P("Two sets of real prices now exist: invoices from the one Thai pressing shop we have seen, and the "
"published calculator of a European plant. Neither is used to re-base the financial model, which "
"keeps its assumed price until buyers have been asked. Together they bracket that assumption."),
H3("The Thai market: one buyer, one plant"),
P("In August 2026 the team compared real invoices from ResurRec in Bangkok (with whom a "
"collaboration is also under discussion), and toured its plant. This is one buyer, one plant, one "
"afternoon, but it is the only domestic market evidence so far."),
T(["Item", "THB", "USD", "Note"], [
["Audio mastering", "5,000 to 20,000 per song", "150 to 605", "Market range from several engineers"],
["Stamper set (father, mother, silvering)", "up to 22,000 per title", "up to 665",
"Residual between a full-service and a pressing-only invoice; an upper bound that also carries "
"cutting, test pressings and margin"],
["All-in per 12-inch record at 300 units", "650 to 950", "19.70 to 28.80",
"Includes a printed jacket; discounts of 5% at 500, 15% at 1,000 to 3,000, 30% above 3,000, "
"with 2 to 4 weeks added lead time above 3,000"],
["Minimum run", "150 units, 'rarely accepted'", "", "Sub-300 runs are effectively unavailable "
"in Thailand"],
], widths_mm=[42, 36, 24, 68],
caption="Researched: buy-side invoices and published discount ladder, August 2026."),
P("What the tour showed: the shop operates from a small non-industrial premises; it does not plate "
"(stampers are bought in from abroad and resold); there is no temperature, humidity or particulate "
"control on the pressing floor; and it runs two Newbilt presses, a Classic fully automatic and one "
"semi-automatic, about 190 to 210 records an hour at nameplate. That is a real capital fleet. "
"Our launch plant's three presses (248 to 288 records an hour at nameplate, planned for two "
"shifts) out-press it on paper, which the one-press launch of draft 0.1 did not. Neither figure is "
"measured output: their shifts and order book were not observed."),
H3("A European plant: Record Industry's calculator"),
P("Record Industry (Haarlem, Netherlands) publishes an online calculator. For a 12-inch 140 g black "
"LP cut from a digital master, with stampers, five test pressings, printed labels, a white paper "
"inner sleeve, a printed 3 mm jacket and shrink wrap, ex Dutch VAT and ex freight (checked "
"October 2026):"),
T(["Copies", "Order total", "Per copy", "Per copy, USD", "Per copy, THB"], [
["200", "EUR 1,494.68", "EUR 7.47", "8.63", "~285"],
["300", "EUR 1,721.22", "EUR 5.74", "6.63", "~219"],
["500", "EUR 2,098.12", "EUR 4.20", "4.85", "~160"],
["1,000", "EUR 3,169.78", "EUR 3.17", "3.66", "~121"],
], widths_mm=[22, 38, 30, 40, 40],
caption="Researched: Record Industry online calculator, October 2026; converted at 1 EUR = 1.155 USD "
"and 1 USD = 33 THB."),
P("Its per-title items (set-up, small-run charge, cutting, stampers, test pressings) come to about "
"EUR 580 to 600 (~THB 22,000 to 23,000), at the low end of our per-title assumption. Black "
"pressing with labels and a paper inner sleeve comes to about USD 2.43 a copy at 300 (2.09 at "
"1,000). The Thai price at 300 copies is about 3 to 4.3 times this plant's ex-works price, before "
"the freight, Thai import duty and VAT a Thai buyer pays on an import. Our own artist ordering "
"demo's price list comes to about 343 THB a copy at 300 with vinyl mastering: above the European "
"ex-works price and well below the Thai market. These price levels stay open until buyers have "
"been asked (roadmap item 1)."),
P("Four readings follow, each with its caveat:"),
B([
"**Our assumed price sits between the two markets.** The plan prices a record at USD 3.76 to 5.27 "
"blended at 60 % specials (124 to 174 THB; 3.50 to 4.60 at a standard-heavy mix). The Thai market pays 535 to 780 THB on a comparable scope, several "
"times more, even after allowing 100 to 150 THB for the jacket. A European plant's published "
"price for black pressing with labels and an inner sleeve (~USD 2.43 at 300) is below our "
"assumption, though our blend also carries colour work and assembly. Two caveats: a sole "
"domestic supplier can hold an import-parity price that a second entrant compresses, and against "
"Europe our assumption is not conservative. We keep it until buyer prices exist.",
"**The floor of the market is unserved.** Runs under 300 are uneconomic for a shop whose "
"per-title cost is an imported stamper plus outsourced mastering. In-house cutting and plating "
"collapse that fixed cost, which makes short runs viable for CNX in a way they structurally are "
"not for the incumbent. The artist platform (section 4.8) is the channel for them.",
"**Lead time degrades with run size, probably because of metalwork.** Three thousand units is "
"about two days of pressing on their fleet, yet they add two to four weeks. A stamper lasts "
"1,000 to 2,000 pressings, so a 3,000-unit run needs two or three sets, each an overseas order. "
"Jacket printing or floor space could produce the same symptom, and the cause should be "
"confirmed before it is treated as a structural weakness.",
"**The gap we close is capability, not only capacity.** No plating, no climate control, no "
"metrology, no traceability. The incumbent sells commercially from that room today, which bounds "
"how much the Thai market currently pays for the difference. Our bet is on export-grade customers "
"and on regional labels who currently ship to Europe.",
]),
CALL("Investor takeaway", "CNX should not fight a price war at 200-unit runs against an operator "
"with low rent and no climate-control load. It competes on what a non-plating, unconditioned "
"shop cannot offer at any run size: export-grade quality control and traceability, titles that "
"need plating, consistent output through the burning season, a repress in two to three weeks "
"from an archived mother, and short runs. A collaboration with the incumbent is under "
"discussion; supplying stampers into its presses is one plausible shape for it, and is not in "
"the revenue model."),
H2("3.4 Cassettes and CDs"),
P("The investor has asked for cassette and CD capability on the site. Both fit the same customer: "
"the independent label that presses 300 to 2,000 records also orders 100 to 500 cassettes and a "
"short run of CDs for the same release, and prefers one supplier, one artwork approval and one "
"shipment. Cassette sales have grown from a very low base in the US and UK over the last decade; "
"volumes are small and the equipment market is mostly refurbished, but the format is a natural "
"add-on with modest capital. CDs remain a large format in Asia (Japan and Korea in particular), "
"but industrial CD replication is an established, price-competitive business with existing "
"capacity across the region. Sections 4.9 and 4.10 lay out both formats and the two very "
"different CD routes; " + pick(
"Plan A adds cassette and CD-R duplication after launch, as a growth step outside its price.",
"cassette and CD-R duplication are in Plan B from launch.")),
# ------------------------------------------ 4 anatomy of the plant
H1("4. Anatomy of a top-notch plant: the full chain"),
P("The chain from audio file to delivered record has nine stages and three points where the artist or "
"label must approve before work continues. Every stage records its events in ERPNext and its "
"machine data in the plant's data store, and the instruments behind every check are specified in "
"section 5. The chart on the next page shows the whole chain; the table after it is the checklist "
"of what a top-notch plant needs and where this plan puts each item."),
PB(),
IMG("process-flow.png", 138, "Figure 1. Process flow from audio file to delivered product, with every "
"check and the three artist approval gates. Source: project repository."),
PB(),
H2("4.0 The checklist"),
T(["What a top-notch plant needs", "Why it matters", "This plan", "When"], [
["A quiet, vibration-free cutting room with a modern lathe", "The groove is born here; every "
"defect propagates to every record", "Sillitoe SDMS complete cutting system in-house; Agnew "
"Type 612 as the other candidate", LP + ", commissioned first"],
["In-house galvanics with zero-discharge water", "The regional bottleneck; enables represses in "
"days and short runs", "Pheenix Alpha line (PASU, PPPU, one PDPU, PMPB); evaporator-based "
"zero discharge and DI water in a treatment building next to it",
LP + ", commissioned first"],
["Stamper preparation machines", "Turns a raw nickel shell into a press-ready part",
"Sibert back-finisher, punch, coiner (USD 250k budget confirmed)", LP + ", with galvanics"],
["A mixed press fleet", "Semi-automatic for colour and short runs, automatic for long runs",
"Newbilt Duplex system (2 presses, main + colour extruder) and one Newbilt Classic",
pick("Launch plant; second Duplex as growth option", "At launch; second Duplex as growth option")],
["Steam, cooling and compressed air engineered locally", "The largest energy loads; efficiency "
"lives here", "Boiler hall and chiller compound for four modules each; 2 x 500 kg/h biomass "
"boilers with a covered fuel store and 2 x 250 kW chillers; heat recovery designed in",
LP + "; modules added with presses"],
["Whole-plant climate and particulate control", "Moisture and dust are the two classic record "
"defects", "20 to 26 °C, 35 to 60% RH, filtration for the burning season, tighter in clean "
"zones", LP],
["Metrology for the metal parts", "Data-backed accept/reject before a stamper is mounted",
pick("XRF thickness and inline vision at launch; laser confocal and wide-area profiler from "
"revenue",
"Laser confocal, wide-area profiler, XRF thickness, inline vision"),
pick("Launch plant (confocal and profiler from revenue)", "At launch, full stack")],
["Layered QC for every record", "Catch defects at line speed without playing every record",
"100% optical inspection, per-cycle telemetry, sampled audio comparison", LP],
["Traceability from file to shipment", "Complaints resolve backwards; customers see their "
"order; machine data access is a purchasing condition", "ERPNext as the only system of record, "
"machine data keyed to it, customer "
"portal", LP + " (v1 before the "
"machines arrive)"],
["A materials lab", "PVC lots differ; a bad lot is a noisy run", "Per-lot gate: moisture, heat "
"stability, colour, density, granulate; release by test pressing", LP + " (day-one tier)"],
["A packaging partner and packaging QC", "Jackets are the path that slips; the wrong "
"record in the right jacket is the classic error", "Ploy Printing (Chiang Mai) for jackets, "
"sleeves, J-cards; matrix code scanned "
"against jacket barcode", LP],
["An archive for fathers and mothers", "Irreplaceable metal; repress economics",
"Father and mother of every side; fire-rated, climate-controlled room, clean-agent suppression, "
"mobile shelving (to quote)", LP],
["Renewable energy and closed-loop water", "Cost, resilience, brand" + pick(
"", "; the owned battery may qualify for BOI as storage"),
pick("PV on the factory roof (~520 kWp; office roof and canopies PV-ready) and a 271 kWh "
"battery through a solar PPA (installer-owned), biomass steam, closed cooling loop, zero "
"process discharge",
"PV on the factory roof (~520 kWp; office roof and canopies PV-ready) and a 271 kWh "
"battery (owned), biomass steam, closed cooling loop, zero process discharge"),
pick("Launch plant (PV and battery through a solar PPA)", "At launch")],
["Trained people and a safety program", "Steam at 10 bar, hydraulics at 180 bar, plating "
"chemistry", "Vendor commissioning training, in-house program, PPE, clean rooms",
LP + "; galvanics hiring first"],
["An ordering platform for every customer", "Short runs need a channel; transparency is the "
"brand", "Itemised price calculator, upload checks, fan-funded campaigns (section 4.8)",
"Calculator early; campaigns after first releases ship"],
["Cassette and CD lines", "Same customers, one order, one shipment", "In-house cassette "
"duplication; CD-R duplication; CD replication as a separate option",
pick("Growth step after launch, not in the plan price (replication only if chosen)",
"At launch (replication only if chosen)")],
], widths_mm=[40, 45, 55, 30], font_pt=8.5),
H2("4.1 Mastering and lacquer cutting"),
P("**What happens.** A mastering engineer prepares the audio for vinyl (levels, side length, "
"low-frequency handling), then a cutting lathe drives a heated stylus into a lacquer-coated "
"aluminium disc, cutting the groove in real time. The lacquer is soft nitrocellulose: heat- and "
"shock-sensitive, and it wants plating within one to three days. Lacquers do not travel well, "
"which is the reason to cut and plate under the same roof."),
P("**What it needs.** A disk mastering lathe and stereo cutter head, matched cutting amplifiers, a "
"mastering console and chain, monitoring, pitch and depth automation, vacuum for platter hold-down "
"and chip suction, a groove inspection microscope, and a low-vibration, temperature-controlled "
"room away from the presses and compressor. Consumables are lacquer blanks and styli."),
P("**Who supplies it.** The plan is a **Sillitoe Disk Mastering System (SDMS)** from Sillitoe Audio "
"Technology (Australia), a complete cutting system rather than a bare lathe: direct-drive "
"turntable with a vacuum platter for 7- to 14-inch disks, a feedback cutterhead, a 350 W per "
"channel cutting amplifier, vacuum and a groove microscope in the box. Its Space / Time Control "
"software computes a virtual groove from the audio before anything is cut and drives pitch, depth "
"and head lift automatically (vendor claim: no capacity tests or dry runs). It also exports a cue "
"sheet, an open-format groove file and stylus hours, which the cutting record in ERPNext can "
"attach instead of manual entry. The weaknesses: it is a closed system (the head works only with "
"Sillitoe's amplifier and is factory calibrated), the install base is small, and service depends "
"on one small company, so a spare cutterhead and support terms belong in the quote. **Agnew "
"Analog** (Greece) and its Type 612 lathe, billed as the first all-new lacquer lathe since the "
"1960s, is the other candidate: bespoke, unpublished price, long build times, with amplifiers and "
"automation sourced around it. Used lathes and complete used studios exist too, through contacts "
"OMS passed on; any of them is compared as a whole room."),
P("**Cost and people.** The cutting-room block is an estimated USD 200k to 350k (THB 6.6M to "
"11.6M): the SDMS at its published list price of USD 125k (ex tax and shipping, built to order), "
"plus a spare cutterhead and support, the mastering console and chain, monitoring and the room "
"build-out, all estimates. A cutting engineer earns about 50,000 THB a month base (team figure). "
"Mastering is labour-bound: an engineer masters perhaps two to four songs a day, which caps the "
"title-services line (section 9). Payap University wants joint student programmes in mastering "
"and lathe cutting, a possible future source of trained people. SST in Frankfurt, which already "
"cuts Poy Records' lacquers, stays a contact for overflow or a slipping commissioning, not part "
"of the plan."),
H2("4.2 Galvanics: silvering and electroforming"),
P("**What happens.** The lacquer is cleaned and sprayed with a conductive silver layer, then "
"electroplated with nickel to grow a negative metal copy, the 'father'. From the father a positive "
"'mother' is grown (playable), and from the mother the working 'stampers' that go into the press. "
"This three-step process means a fresh stamper can be grown from an archived mother in a day or "
"two; a cheaper one-step stamper is single-use and a repress restarts at cutting. The plant keeps "
"the father **and** the mother of every side in its archive, so a worn mother is regrown from the "
"father without a recut."),
P("**Why it is the key to the region.** We have found no plating capability in Thailand; the one "
"plant we have seen buys its stampers abroad (a desk check of Thai electroforming capacity is "
"still to be done). Every title it presses therefore waits on an overseas order, which is the most "
"plausible cause of its lead-time penalty on larger runs and its inability to take small ones. "
"Bringing cutting and plating in-house takes an estimated 1.5 to 5 weeks out of the lead time and "
"USD 175 to 665 per title out of the cost."),
P("**What it needs.** A lacquer cleaning and silvering station, a low-stress nickel pre-plate, "
"production electroforming cells for the three generations, a passivation and cleaning bench, a "
"clean room with controlled access, fume extraction, DI water, and a closed-loop rinse-water "
"treatment and metal recovery system. The chemistry (silver nitrate, nickel salts) sets the safety "
"and permitting requirements: decontamination procedures, PPE, locked chemical storage, eyewash "
"and emergency shower, and hazardous-substance registration. Because galvanics is now in the "
+ pick("launch plant", "plant from launch")
+ ", the site's zoning and the first factory licence have to allow electroplating from "
"the start."),
P("**Who supplies it.** The plan is a **Pheenix Alpha** line (Sweden): the PASU automatic silvering "
"unit, the PPPU pre-plating unit (four masters at once), one PDPU dual plating unit (two cells, up "
"to 200 A each) and the PMPB passivation and cleaning bench. The plating units are PLC-controlled "
"with recipes and a network connection (the protocol is not stated; data access is a purchasing "
"condition). **Digital Matrix / Plating Power** (New York), the long-standing US turnkey vendor, "
"is the second turnkey candidate. **OMS** (Optical Media Services, Baarlo, Netherlands), named by "
"Sibert, is the third candidate and the price reference: EUR 224,000 for a basic and EUR 311,000 "
"for an advanced 4-cell wet room (installation and water treatment extra), 24 and 32 shells in an "
"8-hour day. No vendor supplies the water treatment: the zero-discharge evaporator and DI water "
"come from an industrial water vendor (an imported core unit with Thai integration), in a small "
"treatment building next to the galvanics room (proposed)."),
P("**How much line the plant needs.** Pheenix publishes no cycle times. Published plating practice "
"gives about 15 to 30 minutes for pre-plate, ~75 minutes for a father, about an hour for a mother "
"and ~45 minutes for a stamper (silvering and bench times are estimates). With loading and rinsing, "
"a cell turns a part in about 1 to 1.5 hours, so one PDPU makes 20 to 32 parts in a two-shift day "
"against 8 to 20 parts a working day "
+ pick("even for the larger five-press fleet", "even with the second Duplex system added from revenue")
+ ". **One PDPU covers the "
"demand; a second would buy redundancy, not capacity.** By OMS's rule of thumb (one person runs "
"about 20 stampers a day) that is one galvanics operator per shift."),
P("**Cost and risk.** Pheenix has not quoted, so the plan prices its line at **OMS's reference plus "
"20 %**: OMS's 4-cell wet room with the EUR 10,000 know-how transfer (nobody on the team has run a "
"plating room), EUR 234,000 to 321,000, times 1.2 gives EUR 280,800 to 385,200, ~USD 324k to 445k "
"(THB 10.7M to 14.7M; an estimate, replacing the earlier estimate of USD 320k to 650k). The "
"zero-discharge and DI water plant adds an estimated USD 97k to 258k "
"and its building USD 52k to 87k. Galvanics is the hardest skill to hire and it is now on the "
"path to the first release, because the presses need its stampers. Sibert advised getting each "
"main step right and earning some return before every manufacturing step is in place; that advice "
"and the plan's answer to it are in sections 11.2 and 13. Stamper Discs (UK), a trade stamper "
"service, stays a contact for overflow or a slipping commissioning, not part of the plan."),
H2("4.3 Stamper preparation"),
P("A raw electroformed shell is not yet a stamper. It is back-finished flat, centre-punched to the "
"groove, and formed ('coined') to the mould. Sibert Instruments (UK, in this niche since the early "
"1970s) makes the three machines, run in that order: the **VSF** back-finisher, the **VSP** punch "
"and the **VSC** coiner, which forms the centre hole and the edge and punches the outer diameter "
"to size. Sibert confirmed in October 2026 that **USD 250k covers all three** (a budget "
"confirmation, with an itemised quotation to follow when we go ahead); its engineer's time, spare "
"parts, shipping and travel are extra and sit in the freight and spares lines. The machines run "
"on single-phase power and compressed air, weigh 200, 250 and 1,000 kg, and stand in a row about "
"5.0 x 0.8 m. They list no data interface, and centring on the punch is manual under x100 optics, "
"so the concentricity check after it stays and feeds the traceability record. Sibert also builds "
"a fully automatic punch (VSPa) and has offered to carry some of its features across to the VSP; "
"which ones is a question for the quotation. The coiner needs tooling per mould type, which the "
"press vendor has to specify. The back-finisher's water carries nickel fines and goes to the "
"galvanics treatment, never the drain. Stamper prep is planned in one clean zone with galvanics."),
H2("4.4 Pressing"),
P("**What happens.** An extruder melts PVC compound into a 'patty', which is placed with two labels "
"between two stampers in a steam-heated mould. The press closes at about 150 tonnes, the mould is "
"then water-cooled, and the record is ejected and trimmed. A cycle takes about 28 seconds on the "
"automatic Classic; on a semi-automatic press an operator handles the patty and the record, which "
"is slower but is exactly what colour, splatter and special editions need. The labels are pressed "
"into the record, not glued on afterwards: they are pre-dried in an oven (moisture in a label "
"causes bubbles) and loaded with the patty every cycle, and the label lot is logged per cycle."),
P("**The fleet: all Newbilt, semi-automatic first.** The semi-automatic side carries most of the "
"volume: splatter, marble and other colour effects, special editions and small runs are where an "
"operator working the mould is an advantage rather than a cost, and the colour extruder on the "
"Duplex adds the second colour strand. The Classic takes the long standard runs. Classic and "
"Duplex share mould inserts, so the plant runs one mould family, one set of spares and one service "
"relationship; the cost is a single-vendor dependency."),
T(["Machine", "Role", "Basis", "Cost"], [
["Newbilt Duplex system (Alsdorf, Germany)",
"Two HRP 12 hydraulic presses (~150 t), EX 50 main "
"extruder and EX 35 colour extruder, 12-inch book moulds for 140/180 g, trimmer, label dry oven, "
"shrink wrapper, PVC grinder, label punch, spindles and plates; one operator's cell",
"Quoted: EUR 200,500 (~USD 232k) for the Single 2.1 system incl. sea freight, June 2024, plus "
"the quoted second press and extruder (~USD 115k); expired, re-quote required with build time",
"USD 350k to 370k (THB 11.6M to 12.2M)"],
["Newbilt Classic", "Fully automatic press with built-in extruder, automatic patty, label and "
"record handling; 28 s cycle, ~128 records/h at 180 g; Siemens safety PLC with OPC UA; "
"vendor-claimed 95% yield and uptime", "Estimate: placeholder band; **no Newbilt price on "
"file**", "USD 290k to 460k (THB 9.6M to 15.2M)"],
["Second Duplex system (growth option)", "Two more semi-automatic presses on the same central "
"hydraulics; floor, utility positions and ring-main tees reserved", "Estimate; not in the "
"investment",
"~USD 230k to 300k"],
], widths_mm=[34, 66, 42, 28], font_pt=8.5),
P("The Pheenix Alpha AD12 automatic press left the plan in October 2026 and stays the comparison if "
"the Classic re-quote disappoints."),
P("**What Newbilt deliberately excludes**, and what is engineered and sourced locally: steam and "
"cooling. At Newbilt's per-machine figures the three presses draw about 450 to 540 kg/h of steam "
"at 10 bar / 180 °C and up to ~390 kW of cooling on a hot afternoon (estimates; the Classic is "
"counted as one press and extruder until Newbilt states its own figures). They are met by **two "
"500 kg/h biomass boiler modules (B-1, B-2) and two 250 kW chiller modules (CH-1, CH-2)**, in a "
"boiler hall and an open chiller compound built for four modules each; a second Duplex adds a "
"third chiller module, and the fourth positions are reserve and growth. The boilers burn wood "
"chips from a covered fuel store, in both versions of the plan: ~6M to 10M THB installed with "
"fuel feed, grate and dust control, plus ~1M to 2M THB for the fuel store and handling, and "
"~0.67M THB of fuel a year (estimates). " + pick(
"Plan A buys the compressor through the Chinese route. That route priced only electric "
"boilers; Chinese makers also build biomass boilers but none is priced yet, and a quote ~2M "
"THB or more below the Thai package would bring Plan A's midpoint back to 180M (section 5.4). ",
"Plan B buys the compressor from a Thai supplier, with local service. ")
+ "The presses share one central hydraulic plant and one "
"compressed-air plant through ring mains with a valved tee at every press position, so a new press "
"is connected without stopping the others; the standby pump set, accumulators and ring main are "
"not yet costed. These are the largest energy systems in the plant and the reason the efficiency "
"architecture in section 5.4 is ours to design."),
P("**Site requirements.** Roughly 200 m² of production floor per Duplex system and an estimated 50 "
"to 75 m² for the Classic, saturated steam, compressed air and cooling circuits, and side rooms for "
"materials and finished goods. A press weighs 1,350 kg on under one square metre, so the floor slab "
"must carry several tonnes per square metre and is a building-selection criterion; the floor must "
"be flat, non-slip and solvent-resistant."),
T(["Stage", "Fleet", "Rough output per year"], [
["Launch plant", "1 Duplex system (2 semi-automatic) + 1 Classic, 2 shifts",
"~0.58 to 0.90 million records at 60 % specials (0.71 to 0.97 at ~20 %)"],
["Growth option: second Duplex", "4 semi-automatic + 1 Classic, 2 shifts; room reserved, not in "
"the investment",
"~1.0 to 1.5 million records"],
["Full hall (option)", "5 Duplex systems + 4 Classics, the press hall laid out for Duplex "
"(special pressings first, ~73/27 by floor); a utility phase of its own",
"~2.9 to 4.4 million records at 60 % specials (estimate)"],
], widths_mm=[40, 80, 50],
caption="Basis: semi-automatic 60 to 80 records/h assumed; Classic ~128/h (vendor flyer); 16 h/day, "
"300 days/yr, 60 to 70% overall equipment effectiveness; specials (60 % and more) only on the "
"Duplex. The launch plant is 248 to 288 records/h at nameplate, but at 60 % specials the "
"Duplex caps it at 200 to 267/h, ~120 to 187/h after effectiveness; the press fleet "
"calculator at the team's planning rates gives ~0.94 million. Neither option is in the "
"revenue model or the investment."),
P("**On the 60 to 70% effectiveness figure.** Newbilt publishes 95% yield and 95% uptime for the "
"Classic. We have not adjusted the plan on that basis, deliberately: a vendor's machine uptime "
"excludes stamper and mould changes, colour changeovers, compound lot changes, first-article QC "
"and breaks, which are exactly the losses that dominate a short-run boutique plant. It would also "
"apply only to the Classic, because the semi-automatic rate already includes operator handling. "
"Newbilt is being asked for the basis of its figures as part of the re-quote; if they hold, they "
"argue for a higher effectiveness on the Classic only."),
H2("4.5 Finishing, packaging and fulfilment"),
P("After pressing, records are trimmed inline, sleeved, assembled into jackets, shrink-wrapped and "
"packed; edge trim and rejected records go back through the label punch and grinder as regrind. "
"Jackets, sleeves, inserts, J-cards and CD packaging come from **Ploy Printing** (Ploy Karnpim "
"Limited Partnership, Pa Daet, Mueang Chiang Mai), an established print house with offset, "
"digital, risograph, UV inkjet and latex inkjet presses and vinyl packaging production. That "
"keeps a labour-intensive, freight-heavy item within the province, gives the plant a partner who "
"already knows record packaging, and, because Ploy Printing intends to co-invest (section 12), "
"aligns the two businesses on the same schedule and quality. Risograph and UV print also open "
"boutique packaging options (spot colours, special stocks, printed shells and J-cards) that suit "
"the short-run and colour-vinyl market the semi-automatic line serves. Two points matter "
"commercially:"),
B([
"**Packaging is the path that slips.** Printed jackets need 10 to 20 working days from approved "
"artwork. The metal path and the packaging path run in parallel and converge at assembly; when "
"a label delivers artwork late, jackets become the critical path and every day saved on "
"metalwork is wasted. Artwork deadline is therefore contracted as a fourth approval gate, and "
"the ordering platform checks artwork against our templates at upload (section 4.8).",
"**The wrong record in the right jacket is the classic error**, and a misprinted barcode is a "
"rejected delivery at the distributor. Each jacket is scanned against the runout matrix code of "
"the record going into it, and every unit's barcode is verified.",
]),
P("**Fulfilment** covers bulk pallet delivery to labels and distributors, and dropshipping single "
"parcels directly to end customers on behalf of labels and artists (one parcel per fan for a "
"fan-funded campaign), with carrier tracking recorded per shipment. Dropshipping fees are charged "
"per parcel and are not in the revenue model."),
H2("4.6 Materials: PVC compound"),
P("Records are pressed from a vinyl chloride / vinyl acetate copolymer compound, about 150 to 160 g "
"per 12-inch record. The plant runs an 80% virgin / 20% regrind feed: trimmings and rejects go "
"through an in-house grinder and back to the extruder, so scrap is feedstock, not landfill. The "
"current supplier list is European (Netherlands, UK, Italy, France, Germany) with one US option; "
"the preference is a qualified Thai or regional compound if it meets record specifications, "
"which cuts freight, cost and footprint. The incumbent's floor was stacked with sacks marked "
"'Made in Thailand', a lead worth following. Special designs will run in tens of colours, so the "
"plan keeps a racked colour store, with outdoor silos proposed for black and the standard colours. "
"Every incoming lot passes the material lab gate in section 5.3 before it is released to a press."),
H2("4.7 The order, end to end: what a customer is promised"),
P("A defensible lead time is not the sum of process steps: it carries queue and buffer, and it is "
"quoted from the last customer approval, because a plant cannot be held to a clock the customer "
"keeps stopping. With cutting and plating in-house from the start, there is no external metal "
"block in any of these quotes. The plan's quotable lead times, from test-pressing approval:"),
T(["Order type", "Quoted lead time", "Basis"], [
["New title, full service (cutting, plating and pressing in-house)", "7 to 9 weeks",
"Stage sum of 11.5 to 22 plant days plus queue and buffer; Record Industry (NL) quotes 9 to 11 "
"weeks after test-pressing and artwork approval; EU/US plants are reported at 10 to 16 weeks"],
["Customer supplies jackets", "1 to 2 weeks less", "Removes the print path"],
["Repress from an archived mother, no changes", "2 to 3 weeks", "Grow a stamper from the mother "
"(1 to 2 days), prep, press, finish: about 7 to 11 working days in the plant; the highest-margin "
"order the plant will take"],
["Rush slot", "Premium, capped per month", "Only credible with reserved capacity"],
], widths_mm=[62, 28, 80],
caption="Estimate: planning figures from the stage table; no order has run through this plant."),
P("Draft 0.1 quoted 10 to 14 weeks for the launch, when stampers were to come from the UK; that row "
"is gone. The figures above are still planning numbers: the first months will run slower while "
"the reject rate settles, which is why fan-funded campaigns open only after the first releases "
"have shipped and lead times are measured."),
P("Lead time is a capacity decision, not a process decision. A plant running at 90% quotes 16 weeks "
"with the same equipment that quotes 6 weeks at 50%. Any turnaround promise to the market is a "
"promise to hold spare capacity, and the revenue model in section 9 is built on that basis."),
H2("4.8 The artist platform: ordering and fan-funded pressing"),
P("Short runs need a channel, and the plant's transparency needs a front door. The artist platform is "
"a web service where anyone who wants records made, from a bedroom artist to a label, configures a "
"record and gets a **transparent, itemised offer**: what every line costs, which costs are per "
"title and which per copy, how the price per copy falls with quantity, and when it ships. Two "
"clickable demos of it exist, one detailed and one built for investors."),
B([
"**Calculator and uploads.** Format, weight, colour, labels, jacket with a 3 or 5 mm spine, "
"extras, mastering and test pressings, priced from one price list that also drives the invoice "
"in ERPNext. The master files are checked within minutes (format, sample rate, clipping, side "
"length against the format); artwork is checked against downloadable jacket and label templates "
"(size, spine, bleed, resolution, colour) and can be delivered as PDF, Illustrator (AI) or image "
"files.",
"**Fan-funded campaigns.** The artist sets a fan price and shares a campaign page; fans pre-order "
"their copy. The goal is the larger of a minimum campaign run (100 copies as the planning figure) "
"and the artist's break-even. Fans pay into a **ring-fenced account** that is never working "
"capital, and are refunded automatically if the goal is missed; CNX is the seller of record. The "
"rule comes from Qrates, a crowdfunded pressing platform whose service was suspended with funded "
"projects caught in the wind-down. A Thai legal opinion comes before the first campaign.",
"**Timing.** The calculator goes public early with indicative prices and an interest list but no "
"payments: every configuration is a data point on the run sizes people actually want, which is "
"the open question in market validation. Campaigns open **only after the first paying releases "
"have shipped** and lead times are measured; no fan money is taken against a plant that has not "
"yet delivered.",
]),
P("In the platform's illustration, a fan price of 1,200 THB breaks even at about 41 copies, so the "
"100-copy minimum sets the goal (an example, not a recommendation). The public side is an estimated "
"USD 40k to 90k, inside the software block of the investment; it runs on the plant's own server "
"fleet, with a payment provider as the only outside service. Its name is undecided (under CNX "
"Vinyl, Poy Records or a brand of its own)."),
H2("4.9 Cassette duplication"),
P("**What happens.** A studio master is duplicated onto tape either in real time on a bank of decks, "
"or at high speed on a loop-bin duplicator that copies a running master loop onto reels of blank "
"tape ('pancakes') many times faster than real time. The tape is then loaded into empty cassette "
"shells ('C-0s') by a loader that cuts to length and splices, shells are printed or labelled, "
"J-cards are printed and folded, and the cassette is boxed and shrink-wrapped."),
T(["", "Tier A: real-time bank", "Tier B: professional high-speed line"], [
["Equipment", "10 to 20 duplicating decks, a cassette loader, shell printer or label printer, "
"shrink wrapper", "Loop-bin high-speed duplicator (typically refurbished 1980s to 1990s "
"Lyrec, Gauss or similar, or a current Chinese-built unit), 2 to 3 loaders, "
"pad printer for on-shell print, imprinter, shrink wrapper"],
["Throughput", "~100 to 300 cassettes per day", "~1,000 to 3,000 cassettes per day"],
["Space", "~30 to 40 m²", "~60 to 80 m², climate-controlled (tape and PVC are both "
"humidity-sensitive)"],
["Staff", "1, part time", "1 to 2"],
["Capital", "USD 15k to 40k", "USD 40k to 150k"],
["Quality", "Adequate for short runs; audio quality is master-limited", "Industry standard; "
"chrome or ferric tape"],
], widths_mm=[24, 68, 78],
caption="Estimate. The professional cassette equipment market is largely refurbished; new "
"high-speed lines are rare. Prices to be confirmed with two or three vendors."),
P("**Supply chain.** Blank tape pancakes and C-0 shells come from a handful of suppliers worldwide "
"(National Audio Company in the US is the largest tape source; shell moulders exist in China and "
"should be sought in Thailand). Supply risk is real and the plan is to hold stock. **Positioning:** "
"cassettes are a boutique add-on for the same indie customers, with shells in colours that match "
"the record. **Effect on the plan:** " + pick(
"Plan A adds cassette and CD-R duplication after launch, as a growth step from revenue, "
"starting at tier A or a small tier B. Together they are one estimated block of USD 55k to "
"190k (~THB 4.0M at the midpoint), not in Plan A's price: moving them later is one of its six "
"cost levers. They fit inside the building programme, and the activity can still go into the "
"BOI application from the start (to confirm with the BOI consultant).",
"in Plan B from launch, starting at tier A or a small tier B; cassette and CD-R together are "
"one estimated block of USD 55k to 190k in the investment; schedule-neutral; fits inside the "
"building programme; the activity goes into the BOI application. Plan A, the other version, "
"moves both to after launch as one of its cost levers.")),
H2("4.10 CD: two very different routes (investor decision)"),
P("'CD manufacturing' can mean two things that differ by two orders of magnitude in capital, and the "
"investor is asked to choose."),
T(["", "Route 1: CD-R duplication", "Route 2: CD replication"], [
["What it is", "Blank recordable discs are burned and printed by robotic duplicators. The "
"result is a CD-R, playable in almost all players, with full-colour on-disc print.",
"Discs are injection-moulded from polycarbonate against a nickel stamper (made by glass "
"mastering and electroforming), metallised, lacquered, and printed. The result is a 'pressed' "
"CD identical to major-label product."],
["Equipment", "2 to 4 robotic autoloader duplicators with inkjet or thermal print (Rimage, "
"Microboards, Primera or Epson class); packaging printed by Ploy Printing; "
"shrink wrapper", "Laser beam recorder for glass mastering (or outsourced glass masters), "
"electroforming line, one or two injection-moulding lines with inline "
"metalliser, lacquer coater and scanner, screen or offset disc printer, "
"packaging automation, ISO 7/8 clean room"],
["Throughput", "~200 to 800 discs per day per unit", "~10,000 to 30,000 discs per day per line"],
["Space", "~20 to 40 m²", "~300 to 600 m² plus clean room; realistically the second building"],
["Capital", "USD 15k to 40k", "USD 1.5M to 4.0M (new-build lines); used lines from closed "
"plants can halve that at higher risk"],
["Staff", "Shared with cassette line", "6 to 10 across shifts, including a process engineer"],
["Market fit", "Short runs of 50 to 500 for indie releases, merch and promo; same customers as "
"vinyl and cassette", "Volume runs of 1,000+; competes with established replicators in "
"Japan, Taiwan, Malaysia and elsewhere on thin margins"],
["Regulatory", "No separate BOI activity expected (confirm)", "Separate BOI activity code, "
"must be in the application from "
"the start; larger factory "
"licence scope"],
["Effect on timeline", "None", "Substantial: a second commissioning programme and a bigger "
"building; would push first CD output well past first vinyl"],
["Synergy", "Shares packaging, fulfilment, artwork approval, traceability", "Shares the "
"electroforming skill set and the clean-room discipline of the vinyl galvanics room, but not "
"the equipment"],
], widths_mm=[24, 68, 78], font_pt=8.5,
caption="Estimate throughout. Route 2 figures are order-of-magnitude and would need a dedicated "
"feasibility study."),
P("**Recommendation.** " + pick(
"Route 1 is the CD route for this plant: it is cheap, schedule-neutral, and serves the plant's "
"customers; Plan A adds it after launch together with the cassette line. ",
"Route 1 is in Plan B from launch: it is cheap, schedule-neutral, and serves the plant's "
"customers. ")
+ "Treat Route 2 as a separate project with its own market study, because CD "
"replication is a mature, competitive, declining business outside Asia's strongholds and would "
"add USD 1.5M to 4.0M and a second building to a plan whose vinyl economics do not depend on it. "
"If the investor wants Route 2, the decision must be taken before the BOI application is filed "
"(section 7), and the second building should be designed for it. " + pick(
"Plan A's price includes neither route; Route 1 is a growth step and Route 2 a separate line.",
"This plan's totals include Route 1 only; Route 2 is shown as a separate line.")),
]
return out
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+49
View File
@@ -0,0 +1,49 @@
"""Export CNX-Vinyl-Business-Plan-A.docx and -B.docx to PDF with LibreOffice, filling in the table of contents.
Run with LibreOffice's own Python (it ships the uno module):
"C:/Program Files/LibreOffice/program/python.exe" export_pdf.py
A plain `soffice --convert-to pdf` leaves the Word TOC field unfilled.
"""
import uno, sys, time, subprocess, os
from pathlib import Path
HERE = Path(__file__).resolve().parent
DOCXS = [HERE.parent / f"CNX-Vinyl-Business-Plan-{p}.docx" for p in ("A", "B")]
DOCXS = [d for d in DOCXS if d.exists()]
from com.sun.star.beans import PropertyValue
def pv(n, v):
p = PropertyValue(); p.Name = n; p.Value = v; return p
soffice = r"C:\Program Files\LibreOffice\program\soffice.exe"
proc = subprocess.Popen([soffice, "--headless", "--invisible", "--norestore", "--accept=socket,host=localhost,port=2083;urp;"])
local = uno.getComponentContext()
resolver = local.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", local)
for i in range(60):
try:
ctx = resolver.resolve("uno:socket,host=localhost,port=2083;urp;StarOffice.ComponentContext"); break
except Exception:
time.sleep(0.5)
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
for DOCX in DOCXS:
PDF = DOCX.with_suffix(".pdf")
src = uno.systemPathToFileUrl(str(DOCX))
doc = desktop.loadComponentFromURL(src, "_blank", 0, (pv("Hidden", True),))
idx = doc.getDocumentIndexes()
print(DOCX.name, "indexes", idx.getCount())
for i in range(idx.getCount()):
idx.getByIndex(i).update()
doc.refresh()
# update fields (page numbers)
doc.getTextFields().refresh()
for i in range(idx.getCount()):
idx.getByIndex(i).update()
out = uno.systemPathToFileUrl(str(PDF))
doc.storeToURL(out, (pv("FilterName", "writer_pdf_Export"),))
doc.close(True)
try:
desktop.terminate()
except Exception:
pass
time.sleep(1)
proc.kill() if proc.poll() is None else None
print("done")
+326
View File
@@ -0,0 +1,326 @@
"""Tiny document DSL and renderer for the CNX Vinyl business plan.
Blocks are plain tuples so the content files stay readable:
H1("text") / H2 / H3 headings
P("text with **bold** runs") paragraph
B([...]) bullet list
N([...]) numbered list (manual numbers, restart per list)
T(header, rows, widths_mm=None, caption=None, font_pt=9)
KV([[k, v], ...], widths_mm) two-column table without header
IMG(path, width_mm, caption) picture
CALL(title, body) shaded call-out box; body is str or list
PB() page break
TOC() table-of-contents field
"""
from __future__ import annotations
import re
from pathlib import Path
from docx import Document
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.enum.text import WD_ALIGN_PARAGRAPH, WD_BREAK
from docx.oxml import OxmlElement
from docx.oxml.ns import qn
from docx.shared import Mm, Pt, RGBColor
NAVY = RGBColor(0x1F, 0x38, 0x64)
BLUE = RGBColor(0x2E, 0x55, 0x97)
GREY = RGBColor(0x59, 0x59, 0x59)
HEADER_FILL = "1F3864"
CALLOUT_FILL = "DEEAF6"
ALT_FILL = "F2F5FA"
BODY_FONT = "Calibri"
# ----------------------------------------------------------------- DSL ---
def H1(t): return ("h", 1, t)
def H2(t): return ("h", 2, t)
def H3(t): return ("h", 3, t)
def P(t, style=None): return ("p", t, style)
def B(items): return ("bullets", items)
def N(items): return ("numbers", items)
def T(header, rows, widths_mm=None, caption=None, font_pt=9):
return ("table", header, rows, widths_mm, caption, font_pt)
def KV(rows, widths_mm=(50, 115), font_pt=9.5): return ("kv", rows, widths_mm, font_pt)
def IMG(path, width_mm, caption=None): return ("img", path, width_mm, caption)
def CALL(title, body): return ("callout", title, body)
def PB(): return ("pb",)
def TOC(): return ("toc",)
def COVER(**kw): return ("cover", kw)
# ------------------------------------------------------------ helpers ---
def _shade(cell, fill):
tcPr = cell._tc.get_or_add_tcPr()
shd = OxmlElement("w:shd")
shd.set(qn("w:val"), "clear")
shd.set(qn("w:color"), "auto")
shd.set(qn("w:fill"), fill)
tcPr.append(shd)
def _field(paragraph, instr, placeholder):
run = paragraph.add_run()
b = OxmlElement("w:fldChar"); b.set(qn("w:fldCharType"), "begin")
i = OxmlElement("w:instrText"); i.set(qn("xml:space"), "preserve"); i.text = instr
s = OxmlElement("w:fldChar"); s.set(qn("w:fldCharType"), "separate")
t = OxmlElement("w:t"); t.text = placeholder
e = OxmlElement("w:fldChar"); e.set(qn("w:fldCharType"), "end")
for el in (b, i, s, t, e):
run._r.append(el)
return run
def _set_font(style, name, size=None, bold=None, color=None, italic=None):
f = style.font
f.name = name
rpr = style.element.get_or_add_rPr()
rfonts = rpr.find(qn("w:rFonts"))
if rfonts is None:
rfonts = OxmlElement("w:rFonts"); rpr.append(rfonts)
for k in ("w:ascii", "w:hAnsi", "w:eastAsia", "w:cs"):
rfonts.set(qn(k), name)
if size is not None: f.size = Pt(size)
if bold is not None: f.bold = bold
if italic is not None: f.italic = italic
if color is not None: f.color.rgb = color
_INLINE = re.compile(r"(\*\*.+?\*\*)")
def _runs(paragraph, text, size=None, color=None):
for part in _INLINE.split(text):
if not part:
continue
bold = part.startswith("**") and part.endswith("**")
run = paragraph.add_run(part[2:-2] if bold else part)
run.bold = bold or None
if size is not None: run.font.size = Pt(size)
if color is not None: run.font.color.rgb = color
return paragraph
def _cell_text(cell, text, size, bold=False, color=None, align=None):
cell.text = ""
para = cell.paragraphs[0]
para.paragraph_format.space_after = Pt(1)
para.paragraph_format.space_before = Pt(1)
if align: para.alignment = align
for j, line in enumerate(str(text).split("\n")):
if j:
para = cell.add_paragraph()
para.paragraph_format.space_after = Pt(1)
_runs(para, line, size=size, color=color)
if bold:
for r in para.runs: r.bold = True
def _caption(doc, text):
p = doc.add_paragraph()
p.paragraph_format.space_before = Pt(2)
p.paragraph_format.space_after = Pt(8)
r = p.add_run(text)
r.italic = True
r.font.size = Pt(8.5)
r.font.color.rgb = GREY
return p
def _keep_rows_together(table):
for row in table.rows:
trPr = row._tr.get_or_add_trPr()
cs = OxmlElement("w:cantSplit"); trPr.append(cs)
# ----------------------------------------------------------- renderer ---
class Renderer:
def __init__(self, base_dir: Path, header_text: str, footer_text: str):
self.base = Path(base_dir)
self.doc = Document()
self._setup_page()
self._setup_styles()
self._setup_header_footer(header_text, footer_text)
self._update_fields_on_open()
# -- setup
def _setup_page(self):
s = self.doc.sections[0]
s.page_width, s.page_height = Mm(210), Mm(297)
s.top_margin = s.bottom_margin = Mm(22)
s.left_margin = s.right_margin = Mm(20)
s.header_distance = s.footer_distance = Mm(10)
def _setup_styles(self):
st = self.doc.styles
_set_font(st["Normal"], BODY_FONT, 10.5)
pf = st["Normal"].paragraph_format
pf.space_after = Pt(6); pf.line_spacing = 1.08
_set_font(st["Heading 1"], BODY_FONT, 17, True, NAVY)
st["Heading 1"].paragraph_format.space_before = Pt(18)
st["Heading 1"].paragraph_format.space_after = Pt(8)
_set_font(st["Heading 2"], BODY_FONT, 13, True, BLUE)
st["Heading 2"].paragraph_format.space_before = Pt(12)
st["Heading 2"].paragraph_format.space_after = Pt(4)
_set_font(st["Heading 3"], BODY_FONT, 11, True, RGBColor(0x40, 0x40, 0x40))
st["Heading 3"].paragraph_format.space_before = Pt(8)
st["Heading 3"].paragraph_format.space_after = Pt(3)
for name in ("List Bullet", "List Number"):
_set_font(st[name], BODY_FONT, 10.5)
st[name].paragraph_format.space_after = Pt(3)
def _setup_header_footer(self, header_text, footer_text):
s = self.doc.sections[0]
hp = s.header.paragraphs[0]
hp.alignment = WD_ALIGN_PARAGRAPH.RIGHT
r = hp.add_run(header_text); r.font.size = Pt(8.5); r.font.color.rgb = GREY
fp = s.footer.paragraphs[0]
fp.alignment = WD_ALIGN_PARAGRAPH.CENTER
r = fp.add_run(footer_text + " | Page "); r.font.size = Pt(8.5); r.font.color.rgb = GREY
r = _field(fp, "PAGE", "1"); r.font.size = Pt(8.5); r.font.color.rgb = GREY
r = fp.add_run(" of "); r.font.size = Pt(8.5); r.font.color.rgb = GREY
r = _field(fp, "NUMPAGES", "1"); r.font.size = Pt(8.5); r.font.color.rgb = GREY
def _update_fields_on_open(self):
el = OxmlElement("w:updateFields"); el.set(qn("w:val"), "true")
self.doc.settings.element.append(el)
# -- blocks
def render(self, blocks):
for blk in blocks:
kind = blk[0]
getattr(self, "_b_" + kind)(*blk[1:])
return self.doc
def _b_cover(self, kw):
d = self.doc
for _ in range(3): d.add_paragraph()
p = d.add_paragraph(); p.alignment = WD_ALIGN_PARAGRAPH.LEFT
r = p.add_run(kw["kicker"]); r.font.size = Pt(12); r.font.color.rgb = BLUE; r.bold = True
p = d.add_paragraph()
r = p.add_run(kw["title"]); r.font.size = Pt(30); r.font.color.rgb = NAVY; r.bold = True
p.paragraph_format.space_after = Pt(6)
p = d.add_paragraph()
r = p.add_run(kw["subtitle"]); r.font.size = Pt(13); r.font.color.rgb = GREY
p.paragraph_format.space_after = Pt(14)
if kw.get("image"):
d.add_picture(str(self.base / kw["image"]), width=Mm(170))
p = d.add_paragraph(); p.paragraph_format.space_before = Pt(10)
for line in kw["lines"]:
_runs(p, line, size=10.5); p.add_run().add_break()
p = d.add_paragraph()
r = p.add_run(kw["note"]); r.font.size = Pt(8.5); r.italic = True; r.font.color.rgb = GREY
d.add_paragraph().add_run().add_break(WD_BREAK.PAGE)
def _b_toc(self):
d = self.doc
p = d.add_paragraph(); r = p.add_run("Contents"); r.font.size = Pt(17); r.bold = True; r.font.color.rgb = NAVY
p = d.add_paragraph()
_field(p, 'TOC \\o "1-2" \\h \\z \\u',
"Table of contents: open in Word and press F9 (or accept the update prompt) to populate.")
d.add_paragraph().add_run().add_break(WD_BREAK.PAGE)
def _b_h(self, level, text):
self.doc.add_heading(text, level=level)
def _b_p(self, text, style):
p = self.doc.add_paragraph(style=style) if style else self.doc.add_paragraph()
_runs(p, text)
def _b_bullets(self, items):
for it in items:
_runs(self.doc.add_paragraph(style="List Bullet"), it)
def _b_numbers(self, items):
for i, it in enumerate(items, 1):
p = self.doc.add_paragraph()
p.paragraph_format.left_indent = Mm(8)
p.paragraph_format.first_line_indent = Mm(-6)
p.paragraph_format.space_after = Pt(3)
_runs(p, f"{i}. {it}")
def _b_table(self, header, rows, widths, caption, font_pt):
d = self.doc
n = len(header)
t = d.add_table(rows=1, cols=n)
t.style = d.styles["Table Grid"]
t.alignment = WD_TABLE_ALIGNMENT.CENTER
for j, h in enumerate(header):
c = t.rows[0].cells[j]
_shade(c, HEADER_FILL)
_cell_text(c, h, font_pt, bold=True, color=RGBColor(0xFF, 0xFF, 0xFF))
for i, row in enumerate(rows):
cells = t.add_row().cells
for j in range(n):
val = row[j] if j < len(row) else ""
_cell_text(cells[j], val, font_pt)
if i % 2 == 1: _shade(cells[j], ALT_FILL)
if widths:
t.autofit = False
for j, w in enumerate(widths):
t.columns[j].width = Mm(w) # grid columns: LibreOffice reads these
for row in t.rows:
for j, w in enumerate(widths):
row.cells[j].width = Mm(w)
# repeat header row
trPr = t.rows[0]._tr.get_or_add_trPr()
th = OxmlElement("w:tblHeader"); th.set(qn("w:val"), "true"); trPr.append(th)
_keep_rows_together(t)
if caption: _caption(d, caption)
else: d.add_paragraph().paragraph_format.space_after = Pt(2)
def _b_kv(self, rows, widths, font_pt):
d = self.doc
t = d.add_table(rows=0, cols=2)
t.style = d.styles["Table Grid"]
t.alignment = WD_TABLE_ALIGNMENT.CENTER
for k, v in rows:
cells = t.add_row().cells
_shade(cells[0], ALT_FILL)
_cell_text(cells[0], k, font_pt, bold=True)
_cell_text(cells[1], v, font_pt)
t.autofit = False
for j, w in enumerate(widths):
t.columns[j].width = Mm(w)
for row in t.rows:
for j, w in enumerate(widths):
row.cells[j].width = Mm(w)
_keep_rows_together(t)
d.add_paragraph().paragraph_format.space_after = Pt(2)
def _b_img(self, path, width_mm, caption):
self.doc.add_picture(str(self.base / path), width=Mm(width_mm))
self.doc.paragraphs[-1].alignment = WD_ALIGN_PARAGRAPH.CENTER
if caption: _caption(self.doc, caption)
def _b_callout(self, title, body):
d = self.doc
t = d.add_table(rows=1, cols=1)
t.style = d.styles["Table Grid"]
t.alignment = WD_TABLE_ALIGNMENT.CENTER
c = t.rows[0].cells[0]
_shade(c, CALLOUT_FILL)
c.width = Mm(170)
c.text = ""
p = c.paragraphs[0]
p.paragraph_format.space_before = Pt(3); p.paragraph_format.space_after = Pt(3)
r = p.add_run(title); r.bold = True; r.font.color.rgb = NAVY; r.font.size = Pt(10.5)
items = body if isinstance(body, list) else [body]
for it in items:
q = c.add_paragraph()
q.paragraph_format.space_after = Pt(3)
if isinstance(body, list):
q.paragraph_format.left_indent = Mm(4)
_runs(q, "\u2022 " + it, size=10)
else:
_runs(q, it, size=10)
_keep_rows_together(t)
d.add_paragraph().paragraph_format.space_after = Pt(2)
def _b_pb(self):
self.doc.add_paragraph().add_run().add_break(WD_BREAK.PAGE)
def save(self, path):
self.doc.save(str(path))
+36
View File
@@ -0,0 +1,36 @@
"""Which version of the business plan is being built (October 2026).
Plan A, ~180M THB: the launch plant (1 Duplex system + 1 Classic, every machine) with six cost levers.
Plan B, ~215M THB: the same launch plant with everything in (none of the six levers).
Both are priced without contingency and with the ramp-up reserve
(docs/finance/total-investment.md, "Two plans").
build_plan.py sets PLAN before it calls the content modules' blocks(); call pick() and the
helpers inside blocks(), never at import time.
"""
PLAN = "A"
NAME = {"A": "Plan A", "B": "Plan B"}
PRICE = {"A": "~180M THB", "B": "~215M THB"}
def is_a() -> bool:
return PLAN == "A"
def is_b() -> bool:
return PLAN == "B"
def pick(a, b):
"""The Plan A or the Plan B variant of a value, text or list of blocks."""
return a if PLAN == "A" else b
def name() -> str:
return NAME[PLAN]
def label() -> str:
"""e.g. 'Plan A (~180M THB)'."""
return f"{NAME[PLAN]} ({PRICE[PLAN]})"
+495
View File
@@ -0,0 +1,495 @@
# Own Catalogue: Sales Map, Demand Forecast and Market Advisor
The idea (Alexander, 26 October 2026): with a catalogue of its own to
press, sales by shop, region and location can drive a model that says
what to press next. That needs three things: a **catalogue dashboard**
with a **map of where the records sell**, a **demand model** that turns
those sales into press decisions, and an **advisor agent** that points at
market opportunities.
**Decided the same day (Alexander):**
- **A second company holds the catalogue, not the plant company.** It
owns titles and licenses titles, and has its records pressed at the
plant as a customer.
- **It owns and licenses**: owned masters and licensed reissues are both
in scope.
- **Language models are self-hosted, on premises**, for the catalogue
company's advisor as for the [plant assistant](plant-assistant.md); no
hosted AI service.
This document plans the catalogue company's tools on the same open-source
stack the plant runs, and the line between the two companies. It is a
planning position: every figure without a source is an estimate. Nothing
here is in the plant's business plan: the catalogue company's orders
would reach the plant as ordinary customer orders, and its capital is its
own.
## Why a catalogue company next to the plant
- **It can fill press time the plan does not sell.** At the planned 60 %
specials, specials run only on the Duplex system, and the Classic runs
at about two thirds of its ~128 records an hour
([revenue model](finance/revenue-model.md#operating-picture-of-the-launch-plant-october-2026)).
The spare third is 21 to 48 records an hour; at the plan's 60 to 70 %
effectiveness, 16 hours and 300 days that is **~60,000 to 160,000
records a year** (estimate), black and solid colours only. At the
calculator's planning rate the launch plant is balanced and that spare
time disappears, so the catalogue company's runs are fillers for idle
hours, not a reason to buy presses.
- **A repress at the plant is short.** The father and mother of every
side are archived, so a repress skips cutting and the three artist
gates and takes **~7 to 11 working days**; a mother gives about ten
stamper sets and a father 5 to 10 mothers
([production timeline](production-timeline.md#repress-the-shortest-path-in-the-plant)).
A label that orders from a plant abroad presses big runs months ahead
and carries the stock. A label next to a plant with its metal in the
archive can press **small runs often, against measured demand**. That
is what makes a demand model worth having: it is asked every few weeks,
for a few hundred records, not once a year for thousands.
- **There is a market for Thai catalogue abroad, and it runs through
Japan.** EM Records (Osaka) reissues luk thung and molam compiled by
Soi48, many of them first official reissues
([EM1185LP](https://www.discogs.com/release/14467921-Various-Classic-Productions-by-Surin-Phaksiri-Luk-Thung-Gems-from-the-1960s-80s),
[EM1198DLP](https://emrecords.ocnk.net/product/244)); Bangkok's
ZudRangMa Records co-released an Angkanang Kunchai compilation with EM
Records and Soi48 that launched in Japan with the singer present
([Bangkok Post](https://www.bangkokpost.com/life/arts-and-entertainment/419399/legendary-molam-star-unleashed-again)).
Japanese labels shipped 3.38 million records in 2025, and Japan is short
of pressing capacity ([revenue model](finance/revenue-model.md#resurrec-japan-october-2026)).
Contract pressing for Japanese labels now competes with ResurRec's new
Japan plant; selling Thai catalogue into Japan does not.
- **The reverse has been done.** P-Vine, a Japanese label, built its own
plant (VGAP, 2024) because domestic plants took six months to a year
and pressing abroad about six months, too slow for new releases. P-Vine
also said that, having made records themselves, it found the ~¥4,000 a
new record sells for "tight"
([Phile-web, 15 October 2024](https://www.phileweb.com/news/audio/202410/15/25744.html),
[BRUTUS, 2025](https://brutus.jp/en/post-430468/)). A catalogue earns the
retail or wholesale price, and carries stock, rights and marketing in
exchange.
**What the split does (our reading).** Stock, licence advances, royalty
accounting and the risk of a title that does not sell sit in the
catalogue company, not in the plant company, its BOI promotion or the
capital plan its shareholders fund
([total investment](finance/total-investment.md)). The plant stays a
neutral supplier to every label, including this one.
## What the catalogue company holds
| Kind | What it is |
|---|---|
| Owned titles | Masters the company owns. Poy Records' releases are the obvious first ones (SST in Frankfurt cut lacquers for POY003, 005, 006 and 013, [equipment suppliers](suppliers/equipment-suppliers.md)); whether they move into the new company, or Poy Records becomes that company, is open |
| Licensed titles | Masters licensed for vinyl: territories, term, sell-off period, royalty per unit, advance and recoupment |
Which titles, in which territories and until when, is the first list to
write; nothing below can be tested without it.
## Arm's length between the two companies
The catalogue company is **a customer of the plant like any label**, and
both sides keep it that way:
- **Orders** go through the plant's order intake and customer portal
with a customer account and the same gates
([artist platform](artist-platform.md#for-labels-and-regular-customers)).
A purchase order in the catalogue company's books becomes a sales order
and a work order in the plant's ERPNext; the plant's invoice becomes a
purchase invoice on the other side.
- **Prices** come from the plant's price list. Runs that fill idle slots
can be sold as **standby pressing** (a flexible date, scheduled into
idle press time, at a lower price), offered on the same terms to every
customer, so the related company gets nothing another label could not
(proposal; price and terms open). Thai law lets the Revenue Department
adjust prices between related companies to arm's length (Revenue Code
section 71 bis), and related companies with more than 200 million THB
of revenue a year file a disclosure form
([OECD transfer pricing profile, Thailand](https://www.oecd.org/content/dam/oecd/en/topics/policy-sub-issues/transfer-pricing/transfer-pricing-country-profile-thailand.pdf)).
Whether the two companies are related in that sense depends on who
holds the shares, which is open.
- **Press dates.** The plant never moves another customer's date for the
catalogue company. A label that suspects its plant favours a related
label goes elsewhere.
- **Data.** The plant's customers' orders, sizes and addresses never
reach the catalogue company, and the catalogue company's sales never
reach the plant. In the portal it sees what any customer sees: its own
orders, its metal parts in the archive and the standby calendar.
- **Metal.** Its fathers and mothers sit in the plant's archive under the
same storage and retention terms as every customer's, which the
customer contract still has to state
([production timeline](production-timeline.md#repress-the-shortest-path-in-the-plant)).
## The questions the system answers
1. **What to press next**: which title, before it runs out where it
sells.
2. **How many**: a run sized to the demand of the next few months, since
the next repress is two weeks away.
3. **Which variant**: black or a colour, within what the plant can make
(specials compete with every customer's specials on the Duplex; black
and solid colours suit standby runs on the Classic's idle hours).
4. **Where the stock goes**: its own store room, a distributor, or a shop
on consignment.
5. **Which titles to add**: licensing leads for a person to research.
## Data sources
| Source | What it gives | Location detail | Access and terms | Lands in |
|---|---|---|---|---|
| Own web shop, direct shop accounts, event sales (Poy Festival merch table) | Every sale with its ship-to or the event's place | postcode or city; the event venue | the company's own | its ERPNext: Sales Invoice, POS Invoice, Delivery Note |
| Distributor statements | Units per account (shop) and territory per month, returns | shop or territory | the distribution agreement must require monthly sell-through by account, not only sell-in | its ERPNext: Channel Sales Report (new, below) |
| Consignment shops | Monthly stock count, so sell-through per shop | the shop | the consignment agreement | its ERPNext: Channel Sales Report, consignment warehouse per shop |
| Bandcamp | Raw sales report with the buyer's ship-to city, state, postcode and country for physical items; also as JSON through the Sales API ([help](https://get.bandcamp.help/en/articles/15263368-reading-your-raw-data-sales-report), [API](https://bandcamp.com/developer/sales)) | postcode or city | the label's own account | its ERPNext: Sales Invoice per Bandcamp payout with lines, or Channel Sales Report |
| Record passport registrations | A buyer scans the sleeve code and, opting in, gives country and city: the end listener's place even when the record went through a shop or distributor | city | consent on the form; no IP address stored; the plant runs the passport for every customer and passes a customer's registrations on to it as its processor ([traceability](traceability.md)) | its analytics store, per-record rows keyed to the record key |
| Streaming of its own artists | Top countries and cities per artist and per song in Spotify for Artists ([Spotify](https://artists.spotify.com/en/blog/how-to-read-your-spotify-for-artists-data)); country totals in the distributor's streaming statements | country, top cities | only for artists it releases | its analytics store, weekly series |
| Interest list and pre-orders | "Tell me when it is pressed" sign-ups and pre-orders in its own shop, or through the plant's campaign service on the [artist platform](artist-platform.md) on the same terms as any label | country, city | consent on sign-up | its ERPNext: Lead, Sales Order with advance payments |
| Discogs monthly data dumps | Every release, version and pressing in the Discogs database: labels, countries, formats, identifiers ([data.discogs.com](https://data.discogs.com), CC0) | country of release | free to use (CC0) | a local index on its own server, refreshed monthly |
| Discogs API: have/want counts, lowest price and copies for sale ([API](https://www.discogs.com/developers)) | The collectors' view of a title | none useful | **Restricted Data** (marketplace data by name; the have/want counts come from users' collections and wantlists, which the terms also restrict): no commercial use, no storage longer than needed, never shown more than six hours old, no marketing analytics without Discogs' written permission ([API Terms of Use](https://support.discogs.com/hc/en-us/articles/360009334593-API-Terms-of-Use), checked October 2026); 60 requests a minute | not stored; live look-ups by a person only, unless Discogs agrees in writing |
| Market totals | Country production and sales series, e.g. RIAJ for Japan ([revenue model](finance/revenue-model.md#resurrec-japan-october-2026)) | country | public | a context layer on the map |
| Events | Tours, festival slots, film or ad syncs, anniversaries, Record Store Day | city, date | entered by the team | its ERPNext (a dated note on the Release) |
**Sell-in is not sell-through.** A distributor buying 300 copies says
nothing about fans until the shops sell them; returns can come months
later. The model uses sell-through wherever an agreement provides it and
treats sell-in as a weaker signal.
**Stockouts hide demand.** Weeks in which a title was out of stock at a
shop record zero sales, not zero demand. Those weeks are marked censored,
and the interest list and passport registrations carry the demand the
till could not.
## Where the data lives (ERPNext touchpoints)
The catalogue company follows the rule the plant set for itself: ERPNext
is its only system of record, its tools read and write it, and only
machine-speed and signal data stays outside
([digital factory](digital-factory.md#erpnext-the-plants-erp)). It runs
**its own ERPNext site**, not a second company inside the plant's
ERPNext: separate books, a separate database and no shared users, so
neither company can see the other's records. The packaging the plant
plans to use runs several sites from one installation (frappe-nix with
per-site systemd units, [hosting on NixOS](digital-factory.md#hosting-on-nixos)).
| Object | In its ERPNext | Outside (its analytics store) |
|---|---|---|
| Release, side, item per format and variant | custom Release and Side documents from the same `cnx_erp` app; Item per release, format and variant | none |
| Rights | **new** Licence document: licensor, territories, term, sell-off end, royalty basis and rate, advance and recoupment; Release links to it; "owned" or "licensed" on the Release | none |
| Royalties | royalty accrual per unit sold, posted as journal entries; a royalty statement print format per licensor | none |
| Places | Address gains latitude and longitude of its **postcode or city centroid** (custom fields, filled by the geocoder); shops are Customers in a "Shop" group with their exact location; regions are ERPNext Territories | none |
| Sales | Sales Invoice, POS Invoice, Delivery Note | none |
| Third-party sales | **new** Channel Sales Report: source (distributor, Bandcamp, consignment count), period, lines of item, place (shop, territory or city), units sold, returned, on hand | none |
| Stock | Warehouses: its own store room, each distributor, one per consignment shop | none |
| Pressing | Purchase Order to the plant, Purchase Invoice from it; repress-ready status (archived father and mother, stamper sets left) read from the plant's customer portal | none |
| Recommendations | **new** Catalogue Recommendation: title and variant, quantity, the forecast quantiles it rests on, the reason, status (proposed, accepted, rejected), link to the Purchase Order it became | the full forecast rows per title, place and month |
| Market opportunities | CRM Opportunity and Lead (new shop, distributor, territory, licensing lead) | none |
| External signals | none | weekly streams per country and city, passport registrations, Discogs dump index, map aggregates |
The forecast rows and map aggregates are derived and can be rebuilt from
ERPNext and the signal series at any time; nobody types into them.
Decisions and their outcomes are ERPNext documents, which is what lets
the model and the advisor be scored later.
```mermaid
flowchart LR
subgraph S[Sources]
SHOP[Web shop, shop accounts,<br/>event POS]
DIST[Distributor and<br/>consignment statements]
BC[Bandcamp sales report]
INT[Interest list,<br/>pre-orders]
PP[Record passport<br/>registrations, opt-in]
STR[Streaming by country<br/>and city, own artists]
DG[Discogs CC0 dump]
end
subgraph C[Catalogue company, on premises]
ERP[(Its ERPNext<br/>releases, licences, sales,<br/>stock, channel reports)]
MD[(Analytics store<br/>signal series, forecast rows)]
FC[Forecast job]
DASH[Catalogue dashboard<br/>and sales map]
AG[Market advisor,<br/>self-hosted model]
TEAM[Team decides]
end
subgraph P[Plant company]
PORTAL[Order intake and<br/>customer portal]
end
SHOP --> ERP
DIST --> ERP
BC --> ERP
INT --> ERP
PP --> MD
STR --> MD
DG --> MD
ERP --> FC
MD --> FC
FC --> MD
FC -->|recommendations| ERP
ERP --> DASH
MD --> DASH
DASH --> AG
AG -->|drafts: recommendations,<br/>opportunities| ERP
ERP --> TEAM
TEAM -->|purchase order| PORTAL
PORTAL -->|order status, archive,<br/>standby calendar, invoice| ERP
```
## Personal data
Buyers' names and addresses are personal data under Thailand's PDPA
(B.E. 2562, fully in force since 1 June 2022;
[overview](https://pacmap.dev/regulation/th-pdpa-2019)), and so is a sales
location fine enough to point at one buyer. The catalogue company is the
controller of its buyers' data; the plant handles passport registrations
for it as a processor, under a processing agreement. The map is built so
that it never needs a person:
- addresses are geocoded to the **postcode or city centroid**, never to
the house;
- a map cell shows a count only when it holds at least five buyers;
smaller cells merge into the surrounding region;
- only shops and venues, which are businesses, appear as points;
- passport registrations ask for country and city, with consent, and
store no name, e-mail or IP address unless the fan asks to be told
about represses;
- the advisor sees aggregates only; no personal data goes into a prompt.
## The catalogue dashboard
One internal tool for the catalogue company's team, with five views.
1. **Catalogue.** Every title and variant: owned or licensed, licence
territories and expiry, stock by place (store room, distributors, each
consignment shop), sell-through over 4, 13 and 52 weeks, weeks of
cover at the current rate, repress-ready (from the plant's portal),
last pressing, royalties accrued, and a flag when a recommendation is
open.
2. **Sales map.** Sales density by city or hexagon over time, with a
time slider and filters by title, genre, variant and channel. Layers:
own sales; shops with its stock (pins sized by stock, coloured by
weeks of cover); distributor territories; streaming listeners of its
artists; passport registrations; interest-list sign-ups; country
totals (RIAJ and others) as context. A **white-space layer** marks
places where listeners, sign-ups or registrations are high and sales
or stock are low: the map's version of a market opportunity.
3. **Title page.** The sales curve with out-of-stock weeks shaded, the
forecast fan for the next months, the title's own map, its archived
metal and its licence clock.
4. **Repress planner.** Proposed runs against the plant's standby
calendar (the idle slots the plant publishes to every customer) and
normal lead times, with the Classic's idle hours as the default for
black and solid colours.
5. **Advisor inbox.** The advisor's notes, each with its numbers linked
to the rows they came from, and accept or reject buttons that create
or close the ERPNext document.
**How it is built.** The same open-source stack as the plant's tools
([digital factory](digital-factory.md#the-factory-application)): Rust
(axum, minijinja, HTMX), its own ERPNext integration user, NixOS, managed
like the plant's machines but on the catalogue company's own server and
disks; internal only, not public. The map is open source and
self-hosted, in line with the plant's open-source decision
([digital factory](digital-factory.md#open-source-throughout-and-working-with-other-plants)):
- **MapLibre GL JS** (BSD-3-Clause) in the browser;
- **vector tiles from OpenStreetMap data** (ODbL, attribution on the map)
as one Protomaps PMTiles file (BSD-3-Clause tooling) served from its
own server, so no Google Maps or Mapbox account;
- **H3** hexagons (Apache-2.0) for binning;
- **geocoding offline**: postcode and city centroids from GeoNames
(CC BY 4.0), with a self-hosted Nominatim only if centroids prove too
coarse.
## The demand model
The model grows with the data. Each stage has to beat the simpler one
before it is allowed to decide anything.
**Stage 0: no sales history (a new title or a reissue candidate).**
Demand is borrowed from comparable titles (genre, era, the artist's
streaming, how many pressings already exist per the Discogs dump) and
tested cheaply with a **pre-order**: in the company's own shop, or
through the plant's campaign service on the
[artist platform](artist-platform.md#fan-funded-campaigns) on the same
terms as any label. If the pre-orders reach the minimum run, press; if
not, refund and learn.
**Stage 1: the first months of sales.** A reorder rule, not a model:
sell-through per title and place per week, with out-of-stock weeks left
out of the rate. Repress when the stock that will be left at the end of
the repress lead time (~7 to 11 working days at the plant, plus transport
to where it sells) falls below a safety stock. Dashboard view 1 shows
this from the first sale.
**Stage 2: a year of data and a few dozen titles (thresholds are
estimates).** A hierarchical count model of weekly sales per title and
place (negative binomial, with partial pooling across titles of the same
genre and across nearby places), so a title with three months of history
borrows strength from its neighbours. Inputs: past sales with censoring
for stockouts, the artist's streaming in that place with a lag, price,
variant, season (year-end, Record Store Day), events, age since release,
passport registrations and sign-ups. Output: a forecast **distribution**
(quantiles), never a single number. Runs as a nightly batch job on its
server (Python with statsmodels or PyMC from nixpkgs, as a systemd
timer).
**How many to press.** With a two-week repress the run only has to cover
the next few months, so it is sized by the classic stocking rule: press
the quantile of next-period demand at which the margin lost on a missed
sale balances the cost of a record left unsold.
- Missed-sale cost: net selling price after the channel's margin, minus
what the record costs the catalogue company (the plant's price, 3.40
to 4.25 USD a standard record in the
[revenue model](finance/revenue-model.md#operating-picture-of-the-launch-plant-october-2026)
before any standby discount, plus jacket, sleeve and freight), minus
royalty.
- Unsold-record cost: that cost plus storage and the money tied up,
minus any salvage value (an unsold record can be label-punched and
granulated into regrind,
[pressing line](equipment/pressing-line.md#newbilt-range-making-vinyl-europe-2026-flyers),
if the plant takes it back; terms open).
- Floor: the plant's minimum run and setup terms, and within one
stamper's life (1,000 to 2,000 pressings,
[production timeline](production-timeline.md#repress-the-shortest-path-in-the-plant)).
The catalogue company's wholesale and retail prices, the standby price
and the packaging cost are not in any document yet; they are inputs to
fill before the rule produces a number.
**How it is checked.** Rolling back-tests on its own history: do the
80 % intervals contain about 80 % of outcomes, and does following the
model give fewer out-of-stock weeks and less stock unsold after a year
than the Stage 1 rule did? Accepted and rejected recommendations, with
what then sold, are ERPNext records, so this is a report, not a project.
## The market advisor
An agent that reads the dashboard's data and writes a **weekly note**
plus answers to questions ("where does molam sell outside Thailand?",
"which shops stock out fastest?"). It **proposes and never acts**: it
places no order with the plant, sends no e-mail to a shop or licensor and
changes no price. An accepted proposal becomes an ERPNext document
created by a person.
What it looks for:
- **Repress now**: weeks of cover below the repress lead time plus
safety, with the run size from the model.
- **Move stock**: a shop out of stock while another sits on months of
cover.
- **White space**: places with listeners, sign-ups or registrations and
no shop or distributor; proposed as a CRM Lead for a shop or
distributor to approach.
- **Variants**: colours that sell faster in a region than black, within
what the plant's standby calendar offers.
- **Events**: an artist's tour or festival date in a city where stock is
thin.
- **Licensing leads**: titles in genres that sell for the company that,
per the Discogs dump, were never reissued or not for decades, with the
original label named. A lead for a person to research; the advisor
never says that rights are available.
How it is kept honest:
- the numbers come from the model and the database, the words from the
agent; every figure in a note links to its row and date;
- it separates the company's own data from outside signals and says how
sure it is;
- it has read-only tools: the dashboard API, the forecast rows, ERPNext
reports through a read-only integration user, the local Discogs dump
index, market notes, and web search through a self-hosted SearXNG for
news (tours, syncs, competing reissues); it has no access to the
plant's systems beyond the customer portal;
- every suggestion and its outcome is logged, and after six months it is
scored against the plain reorder rule; if it does not beat it, it
becomes a report instead of an agent.
**Which model runs it** (decided: self-hosted, on premises). The same
software as the [plant assistant](plant-assistant.md), as the catalogue
company's own instance with its own data and permissions, and an
open-weights model on hardware it controls. The forecasting is ordinary
statistics, so the language model only reads, searches and writes; a
mixture-of-experts model such as Typhoon 2.5 may run on a CPU server
(to be measured, as for the plant). Running it on the plant's `vinyl-ai`
instead would put the catalogue company's sales data into prompts on the
plant company's hardware; that needs a written hosting agreement and is
an open decision, not the default.
## How it works with the plant
- **Scheduling.** Its orders enter the plant's schedule like any
customer's; standby runs go into idle slots, the Classic's first, and
never move another customer's date.
- **Metal archive.** Its fathers and mothers sit in the archive room with
every customer's ([facility security](facility-security.md)); the
portal shows it what is archived and how many stamper sets are left.
- **Traceability.** Its sleeves carry the record passport code like every
other record, which is what makes the registration layer of the map
possible ([traceability](traceability.md)).
- **Artist platform.** It can use the plant's campaign service on the
same terms as any label; its own web shop is its own.
- **Money.** The plant's [revenue model](finance/revenue-model.md) does
not count on its orders. Its working capital (stock, licence advances)
and its systems are its own, outside the plant's
[total investment](finance/total-investment.md).
## Phasing
| Roadmap phase | Step |
|---|---|
| 0, validate (now) | List the titles to own and to license, with rights and territories; collect Poy Records' existing sales (Bandcamp report, shops, festival) into one sheet and draw the first map by hand; decide whether to ask Discogs for written permission |
| 1 to 2, quotes and commit | Found the catalogue company (shareholders, name, whether Poy Records is it or moves into it); the plant's customer terms with standby pressing, data and archive clauses |
| 3, build | Its ERPNext site with Licence, Channel Sales Report, Catalogue Recommendation, geocode fields, consignment warehouses; dashboard views 1 and 2; geocoder and tiles on its own server |
| 4, launch | First standby runs at the plant on the Stage 1 rule; passport registrations live; advisor version 0 (rule-based notes written up by the self-hosted model) |
| 5, expand | Stage 2 model once there is a year of data; licensing leads; the software offered to other labels, open source like the plant stack |
## Rough cost (estimates)
All of it borne by the catalogue company.
| Item | Effort or cost |
|---|---|
| Company setup, its ERPNext site with Thai tax, the catalogue documents and royalty statement | 1 to 2 person-months, or a partner quote for the ERPNext configuration |
| Importers (Bandcamp, distributor and consignment statements, streaming exports) | 0.5 to 1 person-month |
| Dashboard and sales map | 1.5 to 3 person-months, less where the plant's open-source code is reused |
| Forecast job: Stage 1 rule, then the Stage 2 model | 0.5, then 1 to 2 person-months |
| Advisor: tools, prompts, logging, scoring on the plant assistant's software | 0.5 to 1 person-month |
| On-premises server for ERPNext, dashboard, forecast and model (CPU first) | a few thousand USD; a GPU only if the CPU trial is too slow ([plant assistant](plant-assistant.md#rough-cost-estimates) for the GPU figure) |
## Risks
- **Stock is the risk a pressing plant normally avoids.** It now sits in
the catalogue company; small, frequent represses keep it small, and the
model's job is to keep it smaller.
- **Related-party pricing.** Prices between the two companies must be the
plant's published terms, documented, or the Revenue Department can
adjust them.
- **Neutrality.** Other labels must be able to trust that the plant does
not favour its neighbour; the arm's-length rules above go into the
customer terms, not only into this document.
- **Small data.** A few dozen titles is little to learn from; the stages
above exist so that no complex model decides before it has beaten a
simple rule.
- **Data access.** Distributors and shops report sell-through only if the
contract says so; that clause goes into every agreement from the
first.
- **Platform terms.** Discogs' marketplace and wantlist data are
restricted; the plan uses its CC0 dumps and live look-ups by a person
unless Discogs agrees in writing.
- **Distraction.** A label is a second business for the same people. Its
runs stay fillers for idle press time until the plant's own order book
is validated ([roadmap](roadmap.md) item 1).
## Open decisions
1. **The catalogue company**: who holds its shares, its name, and whether
Poy Records is that company or its titles move into it.
2. **Working capital** for stock and licence advances: how much and from
whom.
3. **Standby pressing**: price, terms and the minimum run, offered to
every customer of the plant.
4. **Discogs**: ask for written permission to use have/want and
marketplace data commercially, or work from the CC0 dumps alone.
5. **Where its systems run**: its own on-premises server (the default
here) or hardware at the plant under a written hosting agreement.
6. **Other labels**: whether the software is offered to them, and on
what terms (it is open source either way).
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 455 KiB

+452
View File
@@ -0,0 +1,452 @@
# Overhead Crane, Maintenance Workshop and Visitor Corridor
Three additions to the building program, decided in October 2026:
1. **An overhead crane over the whole factory floor**, so machines can be
moved in, out and around without hiring a mobile crane or dragging
them on skates.
2. **A maintenance workshop** with a crane-served service bay, so a
machine can be lifted out of the line and serviced properly instead of
in place.
3. **A glazed visitor corridor at ground level through the factory**, so
guided tours see the whole process without being exposed to noise,
dust or plating chemistry, and without production having to stop or
escort people across the floor.
They are planned together because they collide with each other and with
the building: the crane decides where walls may go, the workshop sits
where the crane parks, and the corridor runs under the crane runway.
This page states what each one needs, what it changes in the
[construction RFQ](finance/phase1-construction-rfq.md), the
[zone table](scale.md) and [facility security](facility-security.md), and
what is still open. Every figure without a vendor or contractor behind it
is an estimate.
## 1. Overhead crane
### What it has to lift
| Item | Weight | Source |
|---|---|---|
| Newbilt press (HRP 12) | 1,350 kg | [Newbilt Duplex site requirements](equipment/newbilt/) |
| Newbilt extruder | 660 kg | same |
| Newbilt hydraulic aggregate (250 L tank, 50 L accumulator) | 600 kg | same, plus the [budgetary offer](equipment/newbilt/) |
| Newbilt Classic automatic press | **unknown**, ask Newbilt with the re-quote | not in any document yet (it replaced the Pheenix AD12 in the fleet plan, October 2026) |
| Sibert VSP punch / VSF finisher / VSC coiner | 200 / 250 / 1,000 kg; VSP and VSF on castors, the VSC sheet lists none, so it is a lift | [Sibert specifications](equipment/sibert/) (2022 and 2023) |
| Pheenix plating units (PPPU, PDPU), silvering unit, prep bench | unknown: dimensions published, weights not; each plating unit carries a 385 L tank, lifted empty | [Pheenix flyers](equipment/pheenix-alpha/), [galvanics and stamper prep](equipment/galvanics.md); ask with the quote |
| Water-treatment evaporator | unknown, lifted empty | to be asked with the quote |
**Planning capacity: 5 t safe working load** (estimate). It covers the
heaviest known lift with its lifting beam and slings at a wide margin and
leaves room for the automatic press until Newbilt states the Classic's
weight. If the Classic turns out under about 2.5 t, price a **3.2 t** crane as the
alternative: lighter runway and frame, and possibly a lighter inspection
regime. Thai cranes fall under the Ministry of Labour's 2021 Ministerial
Regulation on machinery, cranes and boilers (the same regulation that
covers the boiler); a crane-industry summary puts cranes above 3 t on an
engineer inspection every three months. Confirm the intervals against the
regulation text before choosing the capacity.
The crane does **not** serve the outdoor plant. Boiler, chiller, cooling
tower, transformer and the BESS enclosure sit outside the main building
and are set by mobile crane as normal.
### What kind of crane
- **Single-girder electric overhead travelling (EOT) crane** spanning the
building's full 25 m width (about 24 m between rail centres), with an
electric wire-rope hoist. This is the default factory crane in the Thai
market, where most bridge cranes are imported from China and installed
by local firms.
- **Inverter drives on hoist and travel** with a slow creep speed, because
the job is setting precision machines on levelling pads, not moving
steel. Radio remote control, so the operator walks beside the load.
- Overload limiter, hoist limit switches, warning horn and light, and
**protected zones** (a standard option on modern crane controls) so the
hook cannot carry a load over the visitor corridor or over enclosed
rooms.
- **Light duty class.** Machine moves are a few a year plus occasional
maintenance lifts, so a light class (around ISO 4301 M3 to M4, estimate)
is enough.
- **Clean running.** The crane travels over a press hall where dust in a
groove is an audible defect: enclosed gearboxes, lubrication-free wheels
and an enclosed conductor rail, and the crane **parks over the
workshop**, not over the presses.
### What "the whole factory" means in practice
The runway runs the full length of the **production compartment**, wall
to wall and end to end: press hall, material area, stamper prep,
finishing, the workshop and the machine bay. It stops at the fire wall
that separates production from the finished-goods warehouse
([RFQ §1a](finance/phase1-construction-rfq.md) requires that wall to be
rated EI 60 or EI 120, and a crane cannot run through a fire wall). The
warehouse is forklift territory with no heavy lifts, so nothing is lost.
With a 300 to 500 m² warehouse at the dock end, the runway is roughly 40
to 48 m of the 60 m building (estimate, set by the warehouse depth). If
the fire strategy ends up without that wall, the runway can run the full
60 m.
### What it changes in the building
This is where the cost is, and it has to go into the shell price before
the contractor quotes. The RFQ currently says **"no crane"**.
1. **Frame designed for crane loads.** Crane brackets or stepped columns,
runway beams and rails along both long walls, end stops, and a frame
sized for the wheel loads and braking forces. In a PEB this is a known
option, but it is a different frame from the one priced so far.
2. **Hook height under the 7.0 m low eave.** The roof falls across the
25 m width, so the low side governs. With a single-girder hoist the
rail would sit somewhere around 5.5 to 6 m and the hook around 5 m
(estimate; it depends on the haunch depth at the low eave). That is
enough to lift a press and carry it low along a clear aisle, which is
the right way to move a machine anyway, but not to carry it over other
machines or rooms. Ask the contractor for the achievable hook height at
7.0 m and price **+1.0 m on the low eave as an option**. The option
costs wall cladding and about 10% more conditioned volume, so take it
only if the quoted hook height falls short.
3. **No full-height cross walls inside the crane zone.** A wall across
the building would stop the bridge. Partitions inside the zone stop
below the bridge, and where a load has to pass (press hall to
workshop), the partition has a **full-height opening closed by a
high-speed door**, because the hoist rope comes down from above and
needs a slot all the way up. Separation between zones is then by air
pressure, not by a sealed wall (see the workshop below).
4. **Rooms inside the crane zone are boxes with lids.** Galvanics, stamper
prep and any other enclosed room in the zone are built room-in-room
with their own ceilings below the bridge. Where heavy kit has to go in
(electroforming cells, the water-treatment evaporator), the ceiling
gets a **removable crane hatch**. The bridge passes over the lids;
loads do not (protected zones).
5. **The roof space belongs to the crane first.** HVAC ducts, sprinkler
mains, cable trays and lighting run above the crane envelope or along
the walls, never through the band the bridge travels in. Sprinkler
coverage under the bridge is an item for the fire designer.
6. **Vibration and the cutting room.** The crane runs on the building
frame. Keep the mastering and cutting room outside the crane zone (it
belongs at the quiet front of the building with the offices and
archive anyway), on a slab isolated from the frame columns, and do not
run the crane during a cutting session.
### Machine door: how machines get in and out
The vehicle ramp in the RFQ (10.5 m at 1:10, 4.5 m wide) already sits at
the far end of the building, opposite the loading docks. That end gets
the **machine door** and the **machine bay**:
- An insulated sectional door of about **4.5 m wide × 5.0 m high**
(estimate) with full seals. It opens only for machine moves, a few
times a year, so it does not undermine the airtight envelope the HVAC
and the burning-season PM design depend on; schedule moves outside
February to April where possible.
- The crane runway runs right up to the inside face of the door.
- **Method:** a rigid truck reverses up the ramp and through the door
into the machine bay, and the crane lifts the machine off the bed
inside the building. Three checks for the contractor: the ramp
transitions against the truck's ground clearance, door headroom for the
truck, and the machine-bay slab rated for **truck wheel loads**, which
are point loads and not covered by the 30 kN/m² distributed rating.
- **Fallback:** a truck-mounted crane sets the machine on skates at the
door threshold and the overhead crane takes it from there.
### Rough cost (estimate)
| Item | THB | USD |
|---|---|---|
| 5 t × ~24 m single-girder EOT crane, supplied and installed | 1.0M – 2.5M | 30k – 76k |
| Runway beams, rails, end stops, conductor rail, ~2 × 45 m | 0.8M – 1.6M | 24k – 48k |
| Frame premium for crane loads (brackets, heavier columns) | 1.0M – 2.5M | 30k – 76k |
| Machine door and truck-rated slab in the machine bay | 0.4M – 0.9M | 12k – 27k |
| **Crane total** | **~3.2M – 7.5M** | **~97k – 227k** |
## 2. Maintenance workshop and machine bay
### Where
At the ramp end, inside the crane zone, between the machine door and the
press hall. One space does two jobs:
- **Machine bay**: new machines land here, are unpacked, inspected and
documented before they go to the floor; machines leaving for vendor
repair are crated here.
- **Workshop**: a machine is disconnected, lifted out of the line with
the crane, set down on the service bay and worked on properly, with
tools, light and space around it.
The crane's parking position is above it, which keeps the idle crane off
the press hall.
### What is in it
| Area | Contents | Size (estimate) |
|---|---|---|
| Service bay | Clear crane-served floor for one press-sized machine with about 1.5 m working space all round (a Newbilt press stands on under 1 m², an AD12 on about 3.25 m²); bunded drip-tray floor; 400 V three-phase and 230 V outlets; compressed air drop; task lighting | ~60 m² |
| Bench area | Workbenches and vices, pillar drill, hydraulic hose crimper (the press hydraulics run at 180 to 200 bar and hoses are a routine spare), closed-loop parts washer, mould and platen bench, optionally a small lathe and mill for brackets and one-off parts | ~40 m² |
| Spares store | Lockable, shelved; every part tracked in ERPNext (stock, reorder level, which machine it fits) | ~20 – 30 m² |
| Hot-work corner | Welding screen and fume extractor; hot-work permit, because paper, cartons and hydraulic oil share the building | ~10 m² |
| **Total** | | **~100 – 150 m²** |
**Spares are the uptime lever.** Newbilt service comes from Germany and
Pheenix from Sweden; the northern-dispatch service question in the
[supplier map](suppliers/equipment-suppliers.md) only partly closes that
gap. A press down for a seal or a heater should be back the same day from
the shelf, not after a courier.
### Keeping the workshop's dirt out of the press hall
Grinding dust, welding fume and oil mist must not reach the presses. Since
the crane zone rules out a sealed full-height wall (section 1), the
workshop is held at **negative pressure** to the press hall: local
extraction at the welding and grinding positions, an exhaust that keeps
air flowing from the hall into the workshop over the top of the partition
and through the high-speed door, never the other way. The HVAC zoning in
[facility security](facility-security.md) gains the workshop as a zone
below the press hall in the pressure cascade.
### Oil, waste and water
- Hydraulic oil drums on spill pallets, spill kits at the service bay,
used oil and oily rags collected by a licensed waste contractor under
DIW manifests.
- **No floor drain.** A dry workshop keeps the zero contaminated water
commitment in [sustainability](sustainability.md) simple: spills are
absorbed and collected, never washed down.
### Safety
- **Isolation before lifting.** Before a machine is disconnected:
electrical lockout, steam isolated and vented, and the hydraulics
depressurised, including the aggregate's 50 L gas-loaded accumulator,
which holds pressure after the pump stops. Written lockout/tagout per
machine.
- **A lift plan for every machine move**, a trained crane operator and a
trained slinger, and nobody under the load.
- **Warranty.** Newbilt's offer requires every installation to be
commissioned by an engineer trained on Newbilt machinery, the first one
by Newbilt itself, and ties warranty claims to that. Ask Newbilt in
writing whether lifting a press into the workshop and back counts as a
re-installation during the warranty period.
### Fit-out (October 2026)
The workshop is to be fully equipped for maintenance:
- workbenches and the mould service bench, tool cabinets, hand and power
tools;
- a workshop press, parts washer, pillar drill and band saw;
- a screened welding bay and a measuring table;
- **3D printers** for jigs, guards and small parts;
- possibly a **lathe** and a **small CNC mill** to make and repair parts
in house.
The [Payap scenario model](site-candidates.md#payap-scenario-model-october-2026) draws this set in a ~200 m²
workshop next to the machine door.
### Rough cost (estimate)
Workshop fit-out (benches, hand and power tools, hose crimper, parts
washer, welding set and fume extractor, shelving, spill equipment, 3D
printers): **1.0M to 2.5M THB (~30k to 76k USD)**. The lathe and the
small CNC mill are not yet priced and come on top. The
first spares stock sits in the existing working-capital line in
[total investment](finance/total-investment.md).
## 3. Visitor corridor
### What it is for
Guided tours for artists, labels, investors, schools and the public that
show the whole chain from lacquer to packed record, while visitors:
- hear nothing louder than conversation, so no hearing protection;
- breathe the corridor's own filtered air, never press hall or galvanics
air;
- need **no PPE** at all, which turns a tour from an escorted, kitted-out
floor walk into something that can run several times a day;
- cannot touch anything, distract an operator or bring dust onto the
floor. The glass protects production as much as it protects visitors.
ResurRec's new Japan plant shows its press floor the same way, through a
window wall beside the brand sign
([photo](finance/resurrec-japan/resurrec-japan_visitor-window.jpeg),
October 2026; [revenue model](finance/revenue-model.md#resurrec-japan-october-2026)).
### Route
At ground level along **one long wall, the car-park elevation**, which is
where the RFQ already places the main entrance and a second exit at the
far end of the same wall ([RFQ §1b](finance/phase1-construction-rfq.md)).
The tour starts at reception and leaves by the far exit, or loops back.
Along a wall rather than down the middle, for three reasons:
- it does not cut the production floor in two, so forklift routes and
crane moves never cross it;
- the strip under the crane runway is where the hook reaches least well
anyway, so the corridor uses the least valuable floor;
- both ends already have exits.
**Stations follow the process order**, which means the process layout has
to run along the corridor:
1. Mastering and cutting (window into the cutting room)
2. Galvanics (fixed, sealed window in the clean room wall; no opening, no
shared air)
3. Stamper prep
4. Material lab and PVC handling
5. **Press hall**, the long glazed stretch and the centre of the tour
6. Cooling racks and 100% optical inspection of the cooled records (the
presses trim inline)
7. QC and listening, with a headphone listening point
8. Finishing and packaging, where the records leave production
Finished goods sit behind the fire wall and are shown from a fire-rated
window or not at all. The concept drawing
[facility-layout.drawio](facility-layout.drawio) predates this corridor
and the detached utility yard and does not yet follow this order; it
needs redrawing at the next layout pass.
A first rough pass that does follow it is the BIM sketch
[production-hall-layout-sketch.FCStd](production-hall-layout-sketch.FCStd)
(top view: [PNG](production-hall-layout-sketch.png), October 2026): ramp
end with machine door, workshop and spares; then mastering, galvanics,
stamper prep, PVC lab and material area, the press hall, inspection, QC
and packaging along the corridor; the fire wall at 48 m and the warehouse
and dispatch at the dock end, with a 4.5 m crane and forklift aisle along
the back wall from the machine door to the fire wall. It shows one
conflict to resolve: with the workshop at the ramp end, reception and the
cutting room sit under the bridge's travel too, against point 6 above
(cutting room outside the crane zone).
The Payap scenario model
([cnx_vinyl_parametric_payap.FCStd](cnx_vinyl_parametric_payap.FCStd),
[top view](cnx_vinyl_parametric_payap.png); see
[site candidates](site-candidates.md#payap-scenario-model-october-2026))
resolves that conflict. Mastering and cutting, the offices and IT move
into a separate office building, so only production sits under the
crane. The tour then starts in the office building, at the cutting-room
window and the listening room, and crosses a covered link into a 98 m
corridor. That is longer than the 45 to 55 m assumed below, because the
press hall keeps room for five Duplex systems and four Classics and a
colour store sits before it. In that model the crane runway ends at the press hall:
finishing and packaging sit beyond it in a two-storey block with the
print room and stocks upstairs, which the crane cannot serve, so loads
there move by forklift and goods lift. The model also draws the
five-press fleet of October 2026; the sketch above still shows the
earlier fleet (one Duplex and two Classics).
### How it is built
- **Room-in-room**: a glazed wall on the production side, a solid roof at
about 3.0 m (an acoustic lid and protection from anything dropped),
floor on the slab.
- **Clear width about 2.4 m** (estimate): a group of about 15 with a guide,
and room for a wheelchair to pass.
- **Length about 45 to 55 m**, so roughly **110 to 130 m²** of floor and
**~150 m²** of glazing (estimate).
- **Acoustics.** Press halls typically run 80 to 90 dB(A) near the
presses (to be measured on this plant). Laminated acoustic double
glazing in the Rw 40 to 45 dB class (estimate) brings that down to
roughly 40 to 50 dB(A), so a guide can talk without a headset system.
Seals, penetrations and door gaskets decide whether that is achieved,
more than the glass does.
- **Air.** Its own HVAC zone with filtered supply at slight positive
pressure to the press hall, so any leak runs from the corridor into the
hall. It is the cleanest-air space a visitor enters, which matters in
burning season.
- **Glass safety.** Toughened laminated glass; a kerb or steel barrier on
the production side wherever forklifts run; the crane's protected zone
over the whole corridor.
- **Fire and escape.** The corridor is an escape route with exits at both
ends. Where it runs along a fire compartment wall or the galvanics room,
that stretch of glazing must be fire-rated (EI), which costs several
times standard glazing, so keep those stretches short.
- **Viewing.** Light the production side brighter than the corridor and
use low-reflection glass, or the visitors mostly see themselves.
### Step-free access is now required
The building floor sits at **+1.2 m** and the RFQ's only ramp is the 1:10
vehicle ramp, which it notes is not an accessible gradient and asked to
be told now if a step-free entrance is wanted. Public tours make it a
requirement: a **1:12 ramp at the main entrance**, about 14.4 m of run
for the 1.2 m rise plus intermediate landings, with handrails both sides.
### Running tours
- **Visitor screens** at the stations showing live, non-confidential
plant data: a read-only visitor view of the factory application in the
style of the [plant operation page](plant-operation.html), on kiosk
displays wired like the station kiosks. The visitors' own phones stay
on the guest Wi-Fi, which reaches the internet only (VLAN plan in
[digital factory](digital-factory.md)).
- **Confidentiality.** Unreleased artwork and labels are visible on the
floor, and some clients will not want that. Options: schedule tours
around confidential runs, a no-photography rule, or switchable privacy
glass at the label and packaging stations (extra cost, estimate on
request).
- **CCTV notice** at the corridor entrance; footage of visitors falls
under PDPA like staff footage.
- **The tour ends where people can buy records.** A small shop or
pick-up counter at the exit fits the
[artist platform](artist-platform.md) idea of fans collecting their
copy at the plant.
- **Access control.** The corridor is its own zone. No door leads from it
onto the production floor except, if the fire strategy needs one, an
access-controlled staff door.
### Rough cost (estimate)
| Item | THB | USD |
|---|---|---|
| Acoustic laminated glazing, ~150 m² at 6,000 – 15,000 THB/m² | 0.9M – 2.3M | 27k – 70k |
| Structure, roof, finishes, HVAC zone, lighting, screens | 1.0M – 2.0M | 30k – 61k |
| 1:12 accessible entrance ramp with landings and handrails | 0.3M – 0.6M | 9k – 18k |
| **Corridor total** | **~2.2M – 4.9M** | **~67k – 148k** |
## What the three add up to
| | Area | THB | USD |
|---|---|---|---|
| Overhead crane and machine door | (in the shell) | 3.2M – 7.5M | 97k – 227k |
| Workshop and machine bay | 100 – 150 m² | 1.0M – 2.5M | 30k – 76k |
| Visitor corridor and accessible entrance | 110 – 130 m² | 2.2M – 4.9M | 67k – 148k |
| **Total** | **~210 – 280 m²** | **~6.4M – 14.9M** | **~195k – 450k** |
All estimates, not yet in the roll-up in
[total investment](finance/total-investment.md); that page lists them as
added scope until the next re-base.
**On area**: the 1,500 m² phase 1 footprint was already tight for the
zone table in [scale](scale.md). Moving the boiler and chiller into the
detached utility yard freed about 126 m² there, and scale.md left open
whether to shrink the building or grow the program into it. These
additions answer that: the program grows into it. At the lower half of
the zone table everything still fits; at the upper half it does not, and
the release valve is the one scale.md already names, moving finished
goods into the phase 2 building.
## Changes made elsewhere
- [Construction RFQ](finance/phase1-construction-rfq.md): frame type
changed from "no crane" to crane-ready, a new section for the crane and
the machine door, the accessible entrance ramp made a requirement.
- [Scale](scale.md): workshop and corridor added to the zone table.
- [Facility security](facility-security.md): visitor management and
access zones updated for corridor tours.
- [Worker safety](worker-safety.md): lifting operations and the workshop.
- [Roadmap](roadmap.md): item 15 (building fit-out).
## Open decisions
1. **Crane capacity**: 5 t or 3.2 t, once Newbilt states the Classic's weight
and the inspection intervals are confirmed.
2. **Low eave**: keep 7.0 m or raise to 8.0 m, once the contractor states
the achievable hook height.
3. **Runway length**: stop at the warehouse fire wall (recommended) or run
the full 60 m if the fire strategy drops the wall.
4. **Process layout along the corridor**: the stations above need the
layout redrawn in process order along the car-park elevation.
5. **Fire-rated glazing extent**, from the fire strategy.
6. **Tour policy**: who tours, how often, and the confidentiality rule
for client work on the floor.
File diff suppressed because it is too large. Load diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

+528
View File
@@ -0,0 +1,528 @@
# Galvanics and Stamper Prep: Equipment Plan
The metal path turns a cut lacquer into press-ready nickel stampers:
silvering, electroforming of father, mother and stampers, passivation
between generations, then punching, back-finishing and coining (stages 4
and 5 in the [process flow](../process-flow.md)). It is Phase 5 item 23 in
the [roadmap](../roadmap.md), with an open case for pulling it forward;
until it runs, bridge stampers come from Stamper Discs. This page holds the
equipment data for it, the way [pressing-line.md](pressing-line.md) does for
the presses.
Sources are vendor datasheets filed with the Making Vinyl Europe 2026
material in October 2026: Pheenix Alpha's electroforming range (four flyers
dated September 2024, in [`pheenix-alpha/`](pheenix-alpha/)) and Sibert's
vinyl stamper prep line (the current technical specifications and a
line-up drawing, sent by Sibert's Ian Locke on 5 October 2026, in
[`sibert/`](sibert/); the April 2021 issues they replace are in
[`sibert/specs-2021/`](sibert/specs-2021/)), plus Sibert's 2008 to 2009
optical-disc literature (below). Every figure here is vendor-published, not
quoted; the only prices are Sibert's budget confirmation by email and
OMS's reference prices in its introduction letter (both below).
Digital Matrix / Plating Power stays the comparison; its datasheets are not
in the repo yet (see the
[vendor landscape](../suppliers/vendor-landscape.md)).
## Electroforming: the Pheenix Alpha range
Pheenix Alpha, the AD12 press maker, also builds the galvanics line. The
four flyers:
| Unit | What it does | Datasheet figures |
|---|---|---|
| **PASU** Automatic Silvering Unit | Cleaning station plus silver spray unit: the lacquer is cleaned, then silvered by an automatic spray sequence; foot-controlled spray faucet, overspill collection; the silver unit mounts left or right of the cleaning bench | W 2188 × D 715 × H 1835 mm, working height 900 mm; cleaning station up to 120 rpm, spray unit 45 rpm, four nozzles; 100 to 230 VAC single-phase, 10 A; water Ø20 hose, 2 × G3/4"; compressed air G1/2" at 6 bar; exhaust Ø125 mm at 150 m³/h; drain Ø32 mm |
| **PPPU** Pre-Plating Unit | First nickel layer on the silvered master: up to four masters at once, each position controlled on its own with its own cathode movement; integrated dummy plating; PID temperature control | W 1062 × D 1245 × H 1750 mm; 400/480 VAC three-phase, 16 A; tank 385 L, pump 10 m³/h, heater 4.5 kW, 2 × 20" filters; up to 15 VDC and 30 A per position; exhaust Ø63 mm; 500 mm service access behind the tank |
| **PDPU** Dual Plating Unit | Production electroforming: two cells, each with its own rotating cathode shaft and digitally controlled rectifier; titanium anode baskets; adjustable anode-to-cathode distance; options for a flow meter, automatic lid and selective cleaning | W 1070 × D 1350 × H 1800 mm; 400/480 VAC three-phase, 16 A; tank 385 L, 40 L per cell, pump 10 m³/h, heater 4.5 kW, titanium cooling coil; filters 10 µm pre and 2.5 µm fine; 45 rpm; anode baskets 30 kg each; parts up to Ø355 mm; up to 15 VDC and 200 A per cell; cooling water 12 to 20 °C, 5 bar, 10 L/min; exhaust Ø63 mm; 500 mm service access behind the tank |
| **PMPB** Modular Preparation Bench | Passivation, cleaning and drying between generations: removes lacquer residue, anodic passivation and cathodic cleaning for nickel and DMM parts, integrated pump, filtration and temperature control, sink with foot-controlled spray, spin table | W 1588 × D 775 × H 1700 mm, working height 920 mm; spin table up to 120 rpm; 100 to 230 VAC single-phase, 10 A; DI water G3/4"; drain Ø32 mm; exhaust ready |
All four are built in stainless steel and polypropylene, the bench and
plating units with titanium in the wetted parts. The two plating
units are PLC-controlled with a 7" touch screen, user-programmable recipes
and a network connection for remote access; the range advertises alerts for
filter cartridge changes, nickel pellet top-up and anode basket cleaning.
What this changes in the plan:
- **A second turnkey galvanics vendor.** Until now Digital Matrix was the
only one in the plan ([roadmap](../roadmap.md) item 6, the galvanics block
in [total investment](../finance/total-investment.md)). The Pheenix range
covers the same four steps: silvering (PASU against Digital Matrix's
VLSS), pre-plate (PPPU against VLPP), production electroforming (PDPU
against the VLFP 2/4/6-cell system) and passivation (PMPB against the
EC-1000). Pheenix calls itself the only manufacturer of both
electroforming and pressing systems (vendor claim), so it can quote the
whole chain from lacquer to pressed record: AD12 and AD12 Manual for the
presses, this range for the metal. One conversation covers roadmap items
5 and 6, and the single-vendor risk is the same as for the presses.
- **Lacquer and DMM.** The PMPB passivates and cleans DMM parts as well as
nickel, and Pheenix describes the range as built for lacquer and DMM
families, so a DMM lathe (the open Sillitoe question in the
[vendor landscape](../suppliers/vendor-landscape.md)) would not need
different galvanics equipment, by the vendor's description.
- **No water treatment in the flyers.** None of the four covers rinse-water
treatment or metal recovery, the same gap as Digital Matrix. The
zero-discharge plant stays a separate vendor
([sustainability](../sustainability.md)); ask Pheenix which treatment
partner its customers use.
- **Utilities the galvanics room needs** (from the datasheets):
- Electrical: two 16 A three-phase units (~11 kVA each at 400 V) and two
10 A single-phase units (~2.3 kVA each), so **~27 kVA connected** for
one line by the rated currents (estimate). Actual draw is lower: at
most 6 kW DC in the PDPU (2 cells × 15 V × 200 A) and 1.8 kW in the
PPPU (4 × 15 V × 30 A), plus a 4.5 kW heater in each. Thai 400 V / 50
Hz three-phase fits. Not in the [scale](../scale.md) electrical table
yet, because galvanics is Phase 5.
- **DI water** at the PMPB: a deionised (RO plus polishing) water supply
belongs in the galvanics utility list. The RO skid in the
[utilities CSV](../finance/utilities-investment.csv) is an option row
sized for boiler feed, not for this.
- **Cooling water** at the PDPU: 12 to 20 °C at 5 bar and 10 L/min
through its titanium coil, either a branch of the process chiller loop
or a small dedicated chiller. 10 L/min is small next to the press
moulds' ~220 L/min peak.
- **Extraction**: Ø63 mm on each plating unit, Ø125 mm at 150 m³/h on the
silvering unit. The fume-extraction interlock in
[facility security](../facility-security.md) (no extraction, no
plating) applies to every one.
- Compressed air at 6 bar for the PASU; drains Ø32 mm.
- **Water treatment in its own building (proposed, October 2026).** The
zero-discharge effluent treatment, the DI water plant and the chemical
store move out of the factory into a small building next to the
galvanics room. A buried service duct carries the effluent by gravity
from the galvanics floor at +1.2 m and brings DI water back, and a
covered crossing joins the two doors. The galvanics room keeps only a
chemical day store at the duct head. The
[Payap scenario model](../site-candidates.md#payap-scenario-model-october-2026) draws it as a 12 × 10 m building
(estimate).
- **Stamper prep open to galvanics (October 2026).** No wall between the
galvanics room and stamper prep: stampers go from the last bath straight
to the Sibert line inside one clean zone, as the
[Payap scenario model](../site-candidates.md#payap-scenario-model-october-2026) draws it.
- **Space.** One of each unit is ~5.6 m² of footprint (PASU 1.56, PMPB
1.23, PPPU 1.32, PDPU 1.44 m²), plus 500 mm service access behind the two
tank units and working space around them: comfortably inside the 80 to
150 m² the [zone table](../scale.md) holds for clean room, water
treatment and chemical store. At 1.70 to 1.84 m tall they fit under the
room-in-room ceilings in the crane zone
([crane, workshop and tours](../crane-workshop-tours.md)), and by their
published dimensions all four pass through a 1.2 m double door, so the
crane hatch in the clean-room lid is for the water-treatment evaporator
rather than the plating units (check against crated sizes).
- **Weight.** Not published. Each tank unit holds 385 L of electrolyte,
roughly half a tonne filled (estimate), plus 60 kg of nickel in the
PDPU's anode baskets. Ask for empty and filled weights with the quote,
for the slab design and the crane table.
- **Data.** PLC, recipes, network connection and maintenance alerts are on
the datasheets; the protocol is not. Per the
[digital factory](../digital-factory.md) RFQ clauses: read access over
Modbus TCP or OPC UA with the tag list, remote support through our mesh,
no vendor cloud. The maintenance alerts are the bath events the
galvanics record in [traceability](../traceability.md) needs anyway.
### A third candidate: Optical Media Services (OMS)
Asked after the show which electroforming route he would take, Sibert's
Ian Locke named two (email, 5 October 2026): **OMS through Lou Wullms**, "a
long-standing industry colleague who makes good equipment" and very
familiar with the Asian market, or **Pheenix** for a full turnkey package
with long international experience, electroforming systems and presses
together (he calls Pheenix the de facto standard for vinyl presses
worldwide; his view, not a market figure).
OMS is Optical Media Services B.V. in Baarlo, Netherlands, established
1996 (vinyl-pressing-plants.com directory and Lou Wullms' own profile): an
independent vinyl stamper service from lacquers and DMMs that also builds
and refurbishes vinyl electroforming equipment, including conversions of
CD/DVD electroforming lines to 14" vinyl. The same directory gives
Newbilt's equipment page as OMS's website, and that page announces new
Newbilt electroplating equipment with the portfolio "presented here soon";
whether OMS builds it is not confirmed, so ask both. OMS's introduction
letter (below) presents the units as its own designs (EFS2-200, AEFS4-250)
and does not mention Newbilt.
What it adds: a third galvanics vendor next to Digital Matrix and Pheenix,
named by a supplier who knows Lou Wullms and has installed equipment at
Pheenix; a stamper service that could
also serve as a European bridge supplier next to Stamper Discs; and, if
the Newbilt link holds, a galvanics route that pairs with the Newbilt
presses the way the Pheenix range pairs with the AD12.
**First email** (to Alexander in German, 7 October 2026, after meeting in
Haarlem). Lou Wullms introduces himself as the Dutchman who works with nickel
sulfamate (the electroforming electrolyte), asks Alexander to confirm he
received the email, and will then send material so that we can start
calculating and see what the line involves. He also asks whether Simona
will work on the project. Company details as OMS gives them:
| | |
|---|---|
| Company | Optical Media Services B.V., Tangweg 16, 5991 PE Baarlo, Netherlands |
| Technical | Lou Wullms, lou.wullms@gmail.com, mobile +31 6 5490 3443 |
| Accounting and logistics | Wilma Peeters, wilmapeeters6@gmail.com |
| Office phone | +31 77 477 8054 |
| Registration | KvK 12037670 (Venlo), VAT NL806459335B01, EORI NL806459335 |
Alexander has replied to confirm (October 2026), with the split Lou asked
about: Simona covers management and the audio side, Alexander the
technical side, so galvanics questions go to Alexander.
#### OMS introduction letter (9 October 2026)
Lou Wullms sent his material two days later: an introduction letter to
Alexander and Simona, filed as
[`oms/OMS_Introduction_letter_2026-10-09.docx`](oms/OMS_Introduction_letter_2026-10-09.docx).
He asks Alexander to give Simona a copy so that she can work through the
figures. **Open:** forward the letter to Simona. It is an introduction,
not an offer: the prices are "for reference only", final pricing comes
with an official quote, and a dedicated offer needs our plans first. Lou
would rather explain the options in Baarlo, where the equipment can be
seen.
Background, as Lou gives it: from 1986 to 1994 at Philips' optical-disc
equipment business (ODM, then OD&ME and ODME, the company later called
Toolex Alpha); two years setting up a CD plant with mastering and
electroforming at WPME in Kaarst, Germany; then OMS, for service to the
optical-disc industry; involved in setting up Mimeos, a CD and later DVD
stamper service that closed in 2012; in vinyl stamper production since
2015. OMS runs an independent stamper service for vinyl plants and builds
the wet-room equipment to its own designs.
The wet room for a turnkey line, with the letter's reference prices:
| # | Unit | What it does | EUR, reference |
|---|---|---|---|
| 1 | Wet bench | Cleaning, rinsing, soaking, wetting and pre-treating the lacquer | 20,000 |
| 2a | Silvering booth, manual (\*) | Silvering the lacquer | 16,000 |
| 2b | Silvering booth, automatic/manual (\*) | The same, automatic | 22,000 |
| 3 | Pre-plate, 4 positions (\*) | First plating of the silvered lacquer at lower temperature and current | 45,000 |
| 4a | Electroforming unit EFS2-200, 2 cells | Fast plating; the basic unit | 55,000 each |
| 4b | Electroforming unit AEFS4-250, 4 cells with PLC | The advanced unit | 155,000 |
| 5 | Cleaning / passivation | Extra cleaning of the stamper at high temperature and current; passivation | 25,000 |
| 6 | Spin dryer | Spin-drying DMMs, lacquers and stampers; scuffing (pre-treatment) of DMMs and lacquers | 14,000 each |
| 7 | Know-how transfer, including training at OMS | | 10,000 |
| 8 | Silvering recipe | | 5,000 |
(\*) Not needed for stampers made only from DMMs: these are the lacquer
path. The model names of the electroforming units come from the
letter's expansion lines.
The letter totals two configurations:
| | Basic | Advanced |
|---|---|---|
| Units | 1, 2a, 3, 2 × 4a, 2 × 6, 8 | 1, 2b, 3, 1 × 4b, 5, 3 × 6, 8 |
| Cells | 4 (two EFS2-200) | 4 (one AEFS4-250, PLC) |
| Total in the letter | **EUR 224,000** (~USD 259k) | **EUR 311,000** (~USD 359k) |
| One 8-hour day (30 min lunch included) | "7 runs should be possible", then counted with 6: 6 × 4 = **24 shells** | 8 × 4 = **32 shells** |
| Doubling | 2 more EFS2-200, EUR 110,000, "over 50 stampers a day" | 1 more AEFS4-250, EUR 155,000, "over 68 stampers a day" |
USD at the [total investment](../finance/total-investment.md) rate of
1 EUR = 1.155 USD. Reading the letter:
- **The sums.** The basic total adds up; the advanced units add up to EUR
314,000, not the 311,000 stated. A re-quote point.
- **Know-how transfer is left out of both totals**, with the note that
electroplating know-how "is already present at your facility". That is
not the case for CNX: nobody on the team has run a plating room. With
the EUR 10,000 item (training at OMS included) the totals are EUR
234,000 and 321,000, ~USD 270k and 371k (our reading).
- **The basic set has no cleaning/passivation unit** (item 5). Ask how
parts are passivated between generations without it.
- **Installation is extra**: training and start-up on site at EUR 1,200 a
day each, travel days at EUR 600, all other costs invoiced on top.
- **Used equipment** is also on offer ("good used/pre-owned equipment").
- **Finishing is not OMS's scope.** For back-polishing, centre punching and
forming/trimming the letter points to Sibert and Ian Locke as the
reference, as Sibert pointed to OMS for electroforming.
What it changes in the plan:
- **Price.** A complete 4-cell wet room at ~USD 259k to 371k, depending
on the configuration and the know-how item, is at or below the low end
of the USD 320k to 650k galvanics block in
[total investment](../finance/total-investment.md). Neither includes
water treatment (its own block) or installation days. Since October
2026 the plan prices the Pheenix line at **OMS's reference plus 20 %**
(user decision): EUR 280.8k to 385.2k, ~USD 324k to 445k, replacing the
320k to 650k estimate until Pheenix quotes.
- **Capacity.** 6 to 8 runs in a 7.5-hour working day is roughly an hour a
run, which matches the 1 to 1.5 hours per part the cell count below
assumes. Full capacity needs 8 to 20 parts a working day, so either
4-cell configuration covers it on one shift, and the doubling options
buy headroom only. This is the first vendor figure on cycle times.
- **Staff.** One person runs about 20 stampers a day; from about 30 a day
it takes two. Lou asks for people who work accurately and precisely,
attentively, and like clean work. At the plant's 8 to 20 parts a day that
is one operator per shift ([scale](../scale.md) people estimate).
- **Utilities and rooms.** Compressed air, a demineralised-water system,
waste-water collection or treatment, and cooling water, which Lou says
can be passive, with no active chiller (he expects this needs more
discussion). The Pheenix PDPU asks for 12 to 20 °C cooling water, so
whether passive cooling holds at 30 °C and more ambient is a question for
Lou. Space beyond the wet room: an acid cabinet with fume extraction for
mixing chemicals, storage for stampers, lacquers and DMMs, a quality
room with turntable, speakers and inspection microscope, spare parts and
consumables. Smaller items: a drill stand for removing lacquer from the
back of lacquers, lab ware (glass and PP ware, temperature sensor,
density meter, pH meter), and a laundry washing machine and a concrete
mixer for cleaning the anode baskets and anode bags.
- **Data.** The AEFS4-250 has a PLC: programs of up to 20 steps, each step
setting time, voltage, current, flow and rotation; an automatic wake-up
function and pump-curve calibration; a modified cell flow that allows
higher current "without stretching the bath solution". Lou calls it very
energy-efficient with extremely low maintenance (vendor claims). The
protocol is not stated, so the [digital factory](../digital-factory.md)
RFQ clauses apply. The letter mentions no PLC for the basic EFS2-200,
which would keep galvanics a manual check-in station.
- **DMM.** The lacquer-path units (2a or 2b, and 3) are EUR 61,000 to
67,000 of either configuration; a plant cutting only DMM would not need
them, which bears on the Sillitoe DMM question in the
[vendor landscape](../suppliers/vendor-landscape.md).
- **Cutting lathes.** The letter ends with five contacts for buying a
lathe, second-hand included; they are in the
[vendor landscape](../suppliers/vendor-landscape.md#used-lathes-and-cutting-room-contacts-via-oms).
### Cycle times and cell count
Pheenix publishes no cycle times. Published practice from other plating
rooms agrees with Faraday's law at the PDPU's 200 A ceiling (1.095 g of
nickel per ampere-hour), and these are the times the
[plant operation page](../plant-operation.html) runs on:
| Step | Time | Source |
|---|---|---|
| Silvering (clean, sensitise, spray, rinse) | ~15 min | estimate; no published figure |
| Pre-plate | 15 to 30 min at 10 to 20 A | ~15 min at 35 °C (flight 13 duplication, Freiburg, in Leuze Verlag's Galvanotechnik report "Of fathers, mothers and sons"); ~20 min at ~20 A (Welcome to 1979, Nashville, on a Digital Matrix line, in Finishing and Coating); 30 min at 10 to 20 A (US patent 4,363,705) |
| Father | ~1 h 15 min | ~0.2 mm and ~200 g at 150 A and 11 V (flight 13); 1¼ h with the current raised from 20 to 200 A (US 4,363,705) |
| Mother | ~1 to 1¼ h | 1¼ h at 200 A (US 4,363,705); "as little as one hour" (Wikipedia, Production of phonograph records) |
| Stamper | ~45 min | a 145 g stamper in 45 min (Wikipedia, same article) |
| Separation, passivation, cleaning and drying (PMPB) | ~10 to 15 min | estimate |
| Back-finish (VSF), centre punch (VSP), coin (VSC) | ~5 to 10, 3 to 5 and 1 to 2 min | estimate; Sibert publishes none |
The count, from this repo's own demand figures:
- At full capacity the [revenue model](../finance/revenue-model.md) assumes
300 to 600 titles a year across 1.0 to 1.5 million records, so 2,500 to
3,300 records per title.
- Each title needs, per side, a father, a mother and two to three stampers
(at 1,000 to 2,000 pressings per stamper): 8 to 10 electroformed parts per
title, **~2,400 to 6,000 parts a year**, 8 to 20 per working day at 300
days, before remakes.
- The father and the mother of every side go into the archive (decided
October 2026): 4 parts per title, **~1,200 to 2,400 parts a year** at 300
to 600 titles. A mother carries about 10 stamper sets and a father about
5 to 10 mothers by the industry rule of thumb (sources and the repress
arithmetic in the
[production timeline](../production-timeline.md#repress-the-shortest-path-in-the-plant)),
so a repress normally grows stampers from the archived mother, and a
worn mother is replaced from the father without a new cut. The room
that holds them is planned in
[facility security](../facility-security.md#protecting-the-irreplaceable).
- With ~15 minutes of loading, rinsing and unloading on top of 45 to 75
minutes of deposition, a cell turns a part in ~1 to 1.5 hours: 10 to 16
parts per cell per two-shift day, **20 to 32 per PDPU**.
So **one PDPU covers full-capacity demand** with headroom for remakes, and
a second PDPU buys redundancy rather than capacity, which is how Pheenix
itself sells it ("more capacity as well as enhanced redundancy"). The
first version of this page assumed 2 to 3 hours per part and concluded
that the high end needed two. One PASU, one PPPU (pre-plate is for the
masters, 2 to 4 a day at full capacity, and the unit takes four at once)
and one PMPB cover the rest. Ask Pheenix for measured cycles at the
plant's thickness before this goes into a budget. OMS's letter (above) is
the first vendor figure: 6 to 8 runs on 4 cells in a 7.5-hour working day,
roughly an hour a run, which fits these times.
## Stamper prep: the Sibert VS line
Sibert's three vinyl machines, from the current technical specifications
(VSF and VSC dated May 2022, VSP June 2023, by their file dates), sent by
Ian Locke on 5 October 2026 together with a line-up drawing of the three
(July 2023):
| Machine | What it does | Specification figures |
|---|---|---|
| **VSP** Vinyl Stamper Punch | Punches the centre hole after optical centring on the groove | Punch and die M2 high-speed steel, Ø25.4 mm standard (other sizes available), ±0.002 mm; turntable Ø360 mm, 6 mm centring travel, ±0.0015 mm rotational accuracy; pneumatic automatic pre-centring, then manual fine centring; optics ×100, graticule 15 divisions at 0.10 mm, viewing diameter Ø90 to 110 mm (centres on the lead-out groove); pneumatic punch cylinder 100 mm bore, 50 mm stroke; 115 to 230 VAC single-phase, 250 VA; air 6 to 8 bar, 4.5 L/s during the punch stroke; 200 kg; spare punch and die on request |
| **VSF** Vinyl Stamper Finisher | Automatic wet back-finishing with automatic stamper cleaning | Turntable up to Ø362 mm, sized to the customer's stamper, vacuum plus mechanical quick-release clamping on moulded rubber mats, 150 to 1500 rpm; head pressure 0 to 30 psi, brushless DC head drive and traverse, 150 to 1500 rpm; 4-station quick-change disc head including a cleaning pad; abrasive grades P120 to P2500 (nine grades); closed water loop, 0.6 µm absolute or 5 µm nominal filtration plus a 10 µm bag in the tank; 115 to 230 VAC single-phase, 1200 VA; air 6 to 8 bar, 3.1 L/s; 250 kg |
| **VSC** Vinyl Stamper Coiner | Fully automatic forming of the centre hole (ID) and the edge (OD), with the outer diameter punched to a preset size, so no trimming | Press of 40 mm structural steel plate and pillar box section on four hardened pillars and eight linear ball races; independent twin hydraulic OD forming and adjustable pneumatic ID forming; automatically interchangeable 7", 10" and 12" tooling carriages, up to three stations in the machine, loaded by ball rollers and a brushless DC lead screw; D2 and M2 high-speed steel tools, vacuum hardened three times, tempered and precision ground; removable precision-ground ID spigot with height and pressure adjustment; OD insert made to the customer's mould profile ("quick change tooling to suit all vinyl moulds"); 115 to 230 VAC single-phase, 1 kVA; air 6 to 8 bar, 4.5 L/s during forming; 1000 kg; about 2.0 × 0.8 × 1.6 m (width with the tool carriages × depth × height, from the sheet's render) |
All three have aluminium frames and 5 mm cast acrylic guarding and ship
with a pressure regulator and filter. The VSP and VSF sheets list castors
and levelling feet; the current VSC sheet does not.
Against the 2021 sheets, the VSC is a heavier machine (1000 kg, was 600;
40 mm plate, four pillars and eight ball races) with forming split into
hydraulic OD and pneumatic ID; the VSF turntable is now sized to the
stamper (up to 362 mm, was 365), its head pressure range is 0 to 30 psi
(was 0 to 50), its drives are brushless and its disc head has four stations
(was five); the VSP sheet changed only a typo.
What this changes in the plan:
- **Budget: USD 250k for all three.** Sibert confirmed by email (5 October
2026) that a budget of USD 250k covers "all 3 auto-machines"; Ian
Locke's own time, spare parts, shipping and travel come on top. This is a
budget confirmation, not a quote: Sibert offers a fully itemised
quotation once we go ahead. Ian Locke repeated on 9 October 2026 that
equipment footprints and formal quotations follow when we are ready, and
advised settling the pressing side first. It sits above the 60k to 170k estimate in
[total investment](../finance/total-investment.md), which carries the
difference in its not-yet-rolled-up table until the next re-base.
- **Single-phase power.** All three run on 115 to 230 VAC, 50/60 Hz, ~2.5
kVA together, so the three-phase question from the
[Haarlem briefing](../suppliers/making-vinyl-europe-2026-exhibitors.md)
falls away. Each needs 6 to 8 bar compressed air at ½" BSP minimum, so
the air network has to reach the stamper prep room.
- **Weights 200, 250 and 1000 kg.** The VSP and VSF stand on castors:
pallet-truck moves. The VSC weighs a tonne and its sheet lists no
castors, so it is a crane or forklift lift; stamper prep is under the
crane runway ([crane table](../crane-workshop-tours.md) updated).
- **Line-up: 4958 × 833 mm.** Sibert's drawing sets the machines in a row,
VSF, VSP, VSC, 500 mm apart: 4.96 m long overall and 0.83 m deep. With an
operator aisle in front and access at the ends, the line needs a strip of
roughly 6 × 2.5 m (estimate) in the stamper prep room, before stamper
racks and the inspection bench.
- **Order of operations: finish, punch, coin.** Gotta Groove's
Electromastering Lab in Cleveland, which runs a Sibert VSF and VSP,
back-sands first, then centres and punches on the VSP, then trims and
coins the edge and forms the centre hole for the press type
(recordplating.com). The VSC locates on the punched hole, which fits the
same order, and Sibert's line-up drawing places the machines in it. The
[process flow](../process-flow.md)'s "punch, back-finish, coin" names
the operations, not their sequence.
- **Centring is manual.** The VSP pre-centres pneumatically, then the
operator centres the lead-out groove under ×100 optics against the
graticule. Concentricity depends on the operator, so the stage 5 check
stays, and it is the measurement most worth automating. Sibert's 2009
optical-disc punch offered automatic centring with a measured centring
value, a barcode reader for the stamper card and a LAN connection as
options; the VS sheets list none of these. Sibert also builds a fully
automatic punch, the **VSPa**; Ian Locke thinks it may not be right for
this application and offered to discuss it, or to carry some of its
features across to the VSP as a special exception. Which features
(automatic centring, a measured centring value written out against a
stamper serial) is the question to settle before the quotation: the
answer decides whether stamper prep stays a manual check-in station in
the [digital factory](../digital-factory.md).
- **Mould fit.** The standard punch is Ø25.4 mm, other sizes on request,
and the VSC makes its OD insert to each customer mould profile, with
interchangeable ID spigots. Gotta Groove keeps nine
centre-hole forming tools to fit the presses its customers run, which
shows the scale of the question. Which centre hole and
edge form each mould needs (Newbilt book mould, Pheenix/Toolex, M-Tech)
has to come from the press vendors, and the tooling sets per mould type
are a quote line. Whether the VSC duplicates anything a press vendor
supplies is still open.
- **The finisher's water carries nickel.** The VSF's closed loop collects
nickel fines and abrasive in its filters and bag. Spent water and filters
go to the galvanics treatment and hazardous-waste route, never the drain
([sustainability](../sustainability.md)). Consumables: abrasive discs in
up to nine grades, filter cartridges and bags, turntable mats.
- **Service model** (from the 2009 optical-disc literature; confirm for the
VS line). Sibert services punch-and-die sets at its own works: resharpen,
check alignment and vacuum, test-punch the customer's own stampers and
issue a certificate (measured ID, ID-to-data concentricity, roundness,
surface finish, front and back hardness HV0.3). It advises against local
resharpening and sets shot-count warnings in the machine. For a plant in
Thailand that means a spare punch and die in rotation (the VSP lists one
on request) and a UK freight leg per service. In 2009 Sibert also had a
Singapore branch; ask whether regional service still exists. The
certificate's fields are a ready list for the stamper prep record in
[traceability](../traceability.md). Installation and training are not in
the budget: Ian Locke's time and travel are charged on top, so they are
a quote line of their own.
## Optical-disc reference material
[`sibert/sps-optical-disc-2009/`](sibert/sps-optical-disc-2009/) holds
Sibert's SPS (Stamper Preparation System) literature from 2008 and 2009,
punching and finishing modules with their workflows, maintenance lists and
upgrade options, and the August 2008 Blu-ray stamper characteristics paper
by Sony DADC, Singulus, Sibert and technotrans. These are optical-disc
documents and their limits are not vinyl specifications. What carries over:
- **The structure of a stamper acceptance spec**: thickness, flatness,
hardness, back roughness before and after finishing, outer diameter,
centre hole, eccentricity, burr and visual defect counts, each with a
measurement method. CNX has the instruments
([quality automation](../quality-automation.md)) but no written limits
yet; this paper is the model to write them against.
- **Hardness on the centre slug.** Hardness is measured on the disc punched
out of the centre, never on the part, and a fresh nickel bath plates soft
at first, which changes how stampers punch and finish. Taken into
[quality automation](../quality-automation.md).
- **Back-finish pattern.** Random crossing scratches, uniform over the
surface, worked best for Blu-ray; concentric scratches were not
recommended. The SPS finisher reached Ra 0.03 µm. No vinyl figure is on
file: ask Sibert what the VSF reaches and what vinyl plants specify.
- **Tool wear shows in the hole.** Hole size shrinks by a few microns as
the punch and die wear, so a shot count per punch-and-die set belongs in
the genealogy record next to each stamper's concentricity.
The SPS material is directly relevant only if CD replication, the
investor's request in the [project timeline](../project-timeline.md), ever
goes ahead.
## Open questions for the quotes
- **Pheenix Alpha**: price and lead time for one line (PASU, PPPU, PDPU,
PMPB) and for a second PDPU, quoted alongside the AD12; empty and filled
weights; measured cycle per part per cell at stamper, mother and father
thickness; PLC protocol and tag list; DI water quality; which
water-treatment partner its customers use; reference plants running the
range. CEO Robert Gunnarsson offered a Teams call, reference clients and
a factory visit near Stockholm (email, 5 October 2026); the call
follows once these questions are ready, and a visit could fit the
February 2027 Europe trip
([exhibitor briefing](../suppliers/making-vinyl-europe-2026-exhibitors.md#after-the-show)).
- **Sibert**: the itemised quotation against the confirmed USD 250k
budget, with Ian Locke's time, spare parts, shipping and travel priced,
and lead time; tooling sets per mould type and their cost; which VSPa
features can move to the VSP (automatic centring, a measured centring
value, barcode and network); punch-and-die service from Thailand (UK
works or a regional partner); the roughness the VSF reaches; crated
sizes and weights (the VSC is now 1 t); what it installed at Pheenix in
January 2025, and whether Pheenix sells Sibert machines with its line.
- **OMS (Optical Media Services)**: a dedicated offer once we send our
plans (lacquer, DMM or both; parts per day; shifts), ideally after seeing
the equipment in Baarlo (the February 2027 Europe trip could fit);
datasheets for the EFS2-200 and AEFS4-250 (dimensions, empty and filled
weights, power, cooling water); how parts are passivated in the basic set
without the cleaning/passivation unit; the advanced total (the units add
up to EUR 314,000, the letter says 311,000); whether passive cooling holds
at Thai ambient; the AEFS4-250's PLC protocol and tag list; the used
equipment on offer; installations and service in Asia; stamper service
prices and turnaround; which water-treatment partner his customers use;
and whether OMS builds the electroplating equipment Newbilt announces.
- **All galvanics candidates** (Pheenix, Digital Matrix, OMS): how many
stamper sets a mother gives and how many mothers a father gives with
their process before quality drops, how they check it (mother playback,
metrology), and how they recommend storing archived fathers and mothers
(passivation, sleeves, humidity) for years.
- **Press vendors** (Newbilt, Pheenix, M-Tech): the stamper centre hole and
edge form each mould expects, so the punch size and coiner tooling can be
ordered to match ([pressing line](pressing-line.md)).
## Source documents
- [`pheenix-alpha/`](pheenix-alpha/): PASU, PPPU, PDPU and PMPB flyers
(September 2024; renamed from their download names). The flyers give
Pheenix Alpha AB's address as Skepptuna, Märsta, Sweden;
info@pheenixalpha.com, helpdesk@pheenixalpha.com.
- [`sibert/`](sibert/): VSF and VSC technical specifications (May 2022),
VSP technical specification (June 2023) and the VSF/VSP/VSC line-up
drawing (July 2023), attached to Ian Locke's email of 5 October 2026;
the April 2021 issues they replace are in
[`sibert/specs-2021/`](sibert/specs-2021/). Sibert Instruments Ltd,
Medstead, Hampshire, UK, by the email signature (the specification
sheets still carry the older Alton address); sales@sibert.co.uk,
ian.locke@sibert.co.uk.
- [`oms/`](oms/): OMS's introduction letter of 9 October 2026 (Word;
sent as "Introduction letter BUILDFOR.LIFE.docx", attached to Lou
Wullms' email of the same day): wet-room units with reference prices,
two configurations, capacities, utilities, staffing, used equipment and
lathe contacts. Optical Media Services B.V., Tangweg 16, Baarlo,
Netherlands.
- [`sibert/sps-optical-disc-2009/`](sibert/sps-optical-disc-2009/): SPS
punching and finishing literature (2008 to 2009), the punch-and-die
return form, and the Blu-ray stamper characteristics paper (2008).
+659
View File
@@ -0,0 +1,659 @@
# Inline optical QC: devices for the record inspection station
Research note, October 2026. This note works out which devices can do
layer 1 of [quality automation](../quality-automation.md#layer-1-100-optical-inspection-inline),
the optical check of every pressed record. Prices come from vendor shops,
vendor pages or third-party listings, and the source is named each time.
Anything without a source is marked as an estimate. Nothing here is a
quote.
**Short answer.** Nobody sells a vinyl inspection machine. The template
is the CD and DVD in-line scanner: spin the disc once under a line-scan
camera that looks along the radius, with angled lights, and measure the
height with lasers during the same turn. That can be built from standard
parts:
- a 4k line-scan camera per side, with dark-field and bright-field lights;
- a colour area camera per side for the label;
- two laser distance sensors for warp;
- a servo turntable with a centring chuck;
- an edge PC running open-source vision software on NixOS.
The hardware costs about USD 17k to 33k per station (bill of materials,
partly estimates). At launch one station serves both presses, the Duplex
system and the Classic, and it checks the records after they have cooled
(decided October 2026; see [where it sits](#where-it-sits)). A concept model of the station, an aluminium
profile frame with a rim-belt conveyor and all sensors mounted to it, is
in [the station setup](#the-station-setup-frame-conveyor-and-sensors).
## What the station has to catch
| Defect | How it shows optically | Device | Limit or source |
|---|---|---|---|
| Non-fill (PVC did not fill the stamper) | dull, matte patches in the groove band, most often at the outer edge of 180 g records ([AnalogPlanet](https://analogplanet.com/content/what-non-fill-looks)) | line-scan camera, low-angle (dark-field) light | any patch; correlates with audible defects |
| Stitching and flow lines | lines or streaks in the groove sheen | same | any visible line |
| Bubbles, inclusions, black specks | dark or bright points; in clear and translucent colours seen best in transmitted light | line-scan with a back light | size threshold set in trials |
| Debris, scratches, scuffs | bright points or lines in dark-field, dark in bright-field | both lights | size threshold set in trials |
| Edge trim (burr, wrong diameter) | the record edge in the line-scan image | line-scan | trim drawing |
| Label wrong, on the wrong side, off-centre, wrinkled, bubbled, misprinted | colour image of the label against the approved artwork from the order | colour area camera, ring or dome light | artwork in ERPNext |
| Off-centre hole (eccentricity) | the groove band edges trace a sine wave in the unwrapped image when the hole sits off the spiral centre | line-scan, fit of the lead-in and the finishing groove | 0.2 mm hole to groove spiral (IEC 98-1987, DIN 45547-1981, as [tabulated here](http://www7a.biglobe.ne.jp/~yosh/standards_table.htm)); Stamper Discs aims below 0.1 mm on the record and 0.05 mm on the stamper ([Stamper Discs, 2025](https://www.stamperdiscs.com/the-physical-attributes-of-a-stamper-eccentricity/)) |
| Centre hole size | hole diameter in a backlit image, or a go/no-go mandrel | area camera (optional) | 7.24 mm, -0/+0.09 mm (same table) |
| Warp: edge run-out and dish | height change over one turn | two laser distance sensors, or one laser line profiler | Mobineko rejects above 0.5 mm (black), 1.0 mm (colour) or 1.5 mm (special effects) edge run-out per turn, or above 2 mm (black) or 3 mm (colour) between edge and centre ([Mobineko](https://mobineko.com/vinyl-quality-standards)) |
| Colour off the approved test pressing | colour values against the first approved records of the job | calibrated colour camera | tolerance set per job |
| Record temperature at unload (process signal, optional) | temperature map | thermal camera | trend against warp |
No camera can see a wrong master cut into good-looking grooves, or clicks
from defects smaller than its resolution. Those stay with the sampled
audio comparison (layer 3). Optical and audio checks complement each other.
## Who does this already
- **No vinyl product.** A search in October 2026 found no inline
inspection machine for vinyl records on sale. The presses do not offer
one either. The Newbilt Classic's feature list stops at automatic
unloading, the spindle stack, cycle recording and OPC UA
([Newbilt Classic](https://vinyl-pressing-plants.com/blog/newbilt-classic-12-inch-vinyl-record-press)).
- **CD and DVD lines had it, and that is the template.** Dr. Schenk's ISM
in-line scanner ([brochure, 2007](https://www.drschenk.com/fileadmin/user_files/brochures/13-other_applications/optical_media_inspection/ism_inline_scanner.pdf)):
- a 2048-pixel, 12-bit line-scan camera with LED lights;
- one turn in 600 ms or less, 20 µm radial resolution;
- radial and tangential disc deformation measured at 1,000 points;
- a defect classifier, on embedded Linux.
Basler began in this market in 1990 for PolyGram in Hanover
([IMVE](https://imveurope.com/feature/caught-camera)) and sold the
optical-media business to Xiris in 2009
([Vision Systems Design](https://vision-systems.com/cameras-accessories/article/16747762/basler-sells-optical-media-business-continues-focus-on-camera-markets)).
A vinyl record is a bigger, black, grooved disc, but the method carries
over.
- **Precision Record Pressing (Ontario), 2023.** Their in-house AQA system
takes the first and second record of each order. Surface-scanning
cameras built into the lids of modified turntables scan both records,
then both are played in sync and compared with the master
([PRP](https://www.precisionpressing.com/blog/news-prp-announces-new-automated-quality-assurance-system)).
It works on samples and is not for sale, but it is the closest vinyl
precedent.
- **Czech Technical University, Prague.** A bachelor thesis built an
automated optical defect check for LPs in LabVIEW and ran lighting
experiments ([CTU thesis](https://dspace.cvut.cz/entities/publication/11505711-6ce1-4b87-904d-a1421d91cf9f)).
A 2018 paper from the same faculty identified defects with a wavelet
method and classified them with KNN, and got 57 % of records right
([CTU, 2018](https://starfos.tacr.cz/en/vysledky-vyzkumu/RIV%2F68407700%3A21230%2F18%3A00321872)).
- **Plants check by hand today.** Mobineko measures flatness with a
micrometer gauge and a laser level on a modified turntable
([Mobineko](https://mobineko.com/vinyl-quality-standards)). Third Man
checks flatness and label orientation by eye as records leave the press
([WIRED](https://www.wired.com/video/watch/how-vinyl-records-are-made-with-third-man-records)).
## The station
**How it works.** The record goes onto a centring chuck: a mandrel
expands in the 7.24 mm hole and a ring supports the label area. A servo
turntable with an encoder turns it once in about 1 s. Both sides are
imaged during that one turn, one camera set above and one below. The
lights are strobed on alternate lines, so the same turn gives a
dark-field, a bright-field and a transmitted-light image. Stacking line
images from one turn into one picture is standard multi-light line-scan
practice (estimate for this application; to prove in trials). The PC
unwraps each image into a strip of radius against angle, which makes
rings straight lines and an off-centre hole a sine wave.
| Function | Device, per side unless noted | Examples | Price signal |
|---|---|---|---|
| Surface | 4k monochrome line-scan camera along the radius, with a lens, plus a dark-field and a bright-field line light | Basler racer 2 r2L4096 (GigE, 14 to 29 kHz); Hikrobot MV-CL042-91GM (GigE, 4096 × 7 µm pixels, 28 kHz, 80 kHz in high-bandwidth mode, GenICam, Linux; [datasheet](https://www.innosmart.bg/en/catalog/product/by-id/MV-CL042-91GM)); Cognex In-Sight 3800 Line Scan (smart camera, 4K at 84 kHz, encoder inputs, AI tools on board; [specs](https://www.cognex.com/products/machine-vision/2d-machine-vision-systems/in-sight-3800-line-scan/specifications)) | Basler 4k GigE line-scan from USD 857 to 1,088 in Basler's web shop ([price listing](https://cards.keenable.ai/w/01a14ab8-9648-7191-8286-bc5956857428)); lens USD 300 to 800 and line lights USD 500 to 1,500 each (estimates) |
| Transmitted light | a diffuse line light under the record for the top camera | any line-light maker | USD 500 to 1,500 (estimate) |
| Label | 5 to 8 MP colour area camera with a ring or dome light | Basler ace 2 a2A2840-14gcPRO | USD 1,119 (Basler web shop, same listing) |
| Warp, simple | two laser distance sensors under the record, at the outer edge and at mid radius | Micro-Epsilon optoNCDT 1420 | from EUR 470 list ([Micro-Epsilon](https://www.micro-epsilon.com/insights/optoncdt-1220-1320-1420/)); ILD1420-25 about USD 1,600 at a reseller ([Radwell](https://www.radwell.ca/Buy/MICRO%20EPSILON/MICRO%20EPSILON/ILD1420-25)) |
| Warp and thickness, full map (alternative) | laser line profiler across the radius, giving a full height map | Keyence LJ-X8000 (warpage and flatness tools, compensates eccentricity; [Keyence](https://keyence.com/products/measure/laser-2d/lj-x8000)); LMI Gocator 2500 (up to 10 kHz, blue laser; [LMI](https://lmi3d.com/2500-high-speed-3d-laser-profile-sensors/)); Micro-Epsilon scanCONTROL | no list price found; USD 8k to 20k (estimate) |
| Thermal (optional) | infrared camera over the unload position | Optris Xi 400 (80 Hz, line-scan mode) | from EUR 1,950 ([Optris](https://optris.com/products/thermal-cameras/compact-line/xi-400/)); USD 2,995 at a US reseller ([moviTHERM](https://movitherm.com/product/optris-xi-400-infrared-camera/)) |
| Compute | edge PC with a GPU, NixOS | any industrial PC | USD 2k to 4k (estimate) |
| Mechanics | servo turntable, centring chuck, encoder, frame, light shield, reject gate, stack light | local machine builder | USD 4k to 10k (estimate) |
**Resolution.** These are worked figures for a 160 mm field and a 4,096-pixel line:
- **Radial:** about 39 µm per pixel.
- **Along the groove, at 14 kHz and one turn per second:** about 66 µm per line at the outer edge (146 mm radius) and 22 µm at the label edge. At 28 kHz these halve.
- **What that sees:** millimetre-sized non-fill, flow lines and specks of about 0.1 mm and up. It does not resolve single grooves.
- **How defects show:** the camera sees how the groove field scatters light, so a defect has to change that scatter. That is why lighting trials come first, as in the CTU thesis.
**Eccentricity.** At the 0.1 mm target, the sine wave in the unwrapped
image is about 2.6 pixels high. A sub-pixel fit along the lead-in edge
and the finishing groove (106.4 ± 0.8 mm diameter in IEC 98) over about
14,000 lines should repeat within 10 to 20 µm. That figure is an estimate
and has to be shown in trials. The chuck has to centre on the hole
exactly, because the station measures the groove spiral against the
chuck.
**Throughput.**
| | Duplex cell | Classic |
|---|---|---|
| Output | a record every 15 to 20 s from its two presses (at 30 to 40 s per press; Newbilt quotes about 30 s, and the [fleet calculator](../fleet-calculator.html) takes 3 records a minute as 40 s) | a 180 g record every 28 s (Newbilt) |
| Station time per record | about 1 s of scan plus 2 to 3 s to load and unload (estimate) | same |
That leaves slack at both stations. One central station takes the
launch plant's 5 to 6 records a minute with room to spare, and that is
the launch setup ([where it sits](#where-it-sits)). A station at each
cell would catch a non-fill streak within a cycle or two; that stays the
option for a larger fleet.
## The station setup: frame, conveyor and sensors
A concept model of one station, drawn in FreeCAD from the script
[`build_station.py`](inline-qc-station/build_station.py) (views from
[`render_station.py`](inline-qc-station/render_station.py); model file
[`inline-qc-station.FCStd`](inline-qc-station/inline-qc-station.FCStd)).
It is a layout to take to a machine builder, not a fabrication drawing.
The frame uses the real 8-slot 40 series section (slots, centre bore,
corner cavities) with cast angle brackets in the corners; bought parts
are drawn as their outline boxes. The script checks that every part
reaches the floor through parts it touches, so nothing floats.
![Inline QC station with the parts named, for presentations](inline-qc-station/inline-qc-station-annotated.png)
*The labelled view for presentations, made with
[`render_annotated.py`](inline-qc-station/render_annotated.py) (FreeCAD
view and label positions) and
[`annotate_render.py`](inline-qc-station/annotate_render.py) (labels,
Pillow).*
![Inline QC station, open: front panels and lid removed](inline-qc-station/inline-qc-station-iso.png)
*Records run from the infeed (back left, a translucent red special on
the belts) through the light-tight tunnel to the reject pusher and the
outfeed stop (front right). The cabinet sits under the outfeed, the
reject bin behind it.*
**Frame.** The frame is built from 40 × 40 mm 8-slot aluminium profile
(32 m in 45 pieces) on two 40 × 80 mm base beams, with 24 cast angle
brackets in the corners and eight levelling feet. It is 1.9 m long, 0.65 m wide and 1.5 m high, plus the stack
light. The reject bin adds 0.4 m behind it. Records travel at 900 mm,
a normal working height.
The middle 0.8 m is a tunnel closed with black panels on all sides
(4.3 m²), because the line-scans need their own light only. The front
panel is a door with a safety switch. The records enter and leave
through low slots in the end walls. The reject zone has a clear polycarbonate guard.
All camera and light brackets clamp into the slots, so heights and angles
can be moved during the lighting trials.
**Conveyor.** Two 6 mm PU round belts run under the record's rim, 148.5 mm
from the centre line. That is outside the recorded area: a 12" record is
301.6 mm across and its grooves end at 292.6 mm at most (IEC 98, as
[tabulated here](http://www7a.biglobe.ne.jp/~yosh/standards_table.htm)).
The belt therefore touches only the raised edge that records are made to
stand on, never a groove. The centre stays open, so cameras and the chuck
can reach the record from below.
The belts run on UHMW slide strips and are driven by one shaft at the
outfeed end. Side guides with a flared mouth centre the record at the
infeed. Supported on two rim lines, a warm 180 g record sags about 1 mm
in the middle (beam estimate). The launch setup feeds cooled records,
which are stiffer; the trials should confirm that the sag does no harm. For 10" and 7" records the belt spacing moves in on a slide;
the model shows the 12" setting.
| Station | Position from the infeed end | What happens |
|---|---|---|
| Infeed | 200 mm | the finishing operator puts each cooled record down (at a press-side station: the press operator or the Classic's unloader); a presence sensor starts the cycle |
| Label gate | 520 mm | both colour cameras flash the labels on the fly through the open centre (exposure about 20 µs, under 10 µm blur at 0.5 m/s); the top camera also reads the dead-wax code that ties the record to its stamper, and so to its press and cycle (readability to test, as in [digital factory](../digital-factory.md)) |
| Inspection | 880 mm | a through-beam on the leading edge stops the belts; the chuck lifts the record 75 mm off them (the pad waits below the belt plane), expands the mandrel in the 7.24 mm hole and turns it once in about 1 s |
| Reject | 1,320 mm | a pneumatic rodless cylinder on a bridge pushes a reject sideways by its edge onto a felt-lined chute at the back and into the bin |
| Outfeed | 1,715 mm | good records wait at a soft end stop; the station holds the next one while the outfeed is full |
![Inspection zone: chuck, line-scan cameras, lights and lasers](inline-qc-station/inline-qc-station-detail.png)
![Inspection zone in elevation, the front part cut away](inline-qc-station/inline-qc-station-detail-front.png)
**Inspection zone.** The record is shown lifted on the chuck. The two
line-scans look at opposite radii along the conveyor axis, because no
belt crosses that line:
- **Top camera:** reads the downstream radius, from 50 to 155 mm, from
330 mm above. A coaxial line light sits under it, two dark-field line
lights sit at 20° either side, and a diffuse backlight below the
record gives transmitted light for clear colours.
- **Bottom camera:** reads the upstream radius from below with the same
set of lights.
- **Bottom dark-field lights:** these sit outside the record's footprint,
above the rails, so the conveyed record passes them. They light the
underside at about 8°, true dark-field.
- **Warp lasers:** two lasers under the record trace circles at 90 and
130 mm radius during the turn.
- **Spindle drive:** an encoder on the spindle shaft clocks both
line-scans; the lasers are sampled with the servo position (see the
spindle servo below).
- **Lift drive:** the lift is a guided pneumatic cylinder, and the
spindle is belt-driven from a servo set to the side. That keeps the
bottom camera's view cone clear, which the elevation shows.
- **Thermal camera (option):** hangs at the tunnel entry. It only makes
sense at a press-side station; cooled records show no temperature
pattern, so the launch setup leaves it out.
**Spindle servo and camera clock.** The spindle runs on a 100 W EtherCAT
servo kit, StepperOnline A6-EC100L2A1-M17: a 40 mm motor (0.32 N·m rated,
1.12 N·m peak, 17-bit magnetic encoder, 0.03 kg·cm² rotor) with the
A6-200EC drive. It costs USD 123.29 from the China warehouse
([StepperOnline](https://www.omc-stepperonline.com/a6-series-100w-ethercat-ac-servo-motor-kit-3000rpm-0-32nm-17-bit-absolute-encoder-ip67-a6-ec100l2a1-m17),
October 2026). The conveyor uses the same kit, so one spare covers both.
- **Belt ratio 1:6** (for example 15 to 90 teeth). The record alone is
about 20.5 kg·cm² (180 g at 150.8 mm radius); with the spindle head the
load is about 25 to 35 kg·cm² (estimate). That is about 1,000 times the
rotor direct; through 1:6 the ratio comes down to about 28, inside the
drive's tuning range. The motor then runs at 360 rpm for one turn a
second.
- **Torque is no limit.** Reaching one turn a second in 0.15 s takes
about 0.13 N·m at the spindle and 0.02 N·m at the motor (our
arithmetic), well under the rating.
- **Camera clock from a spindle encoder.** The A6-EC drive has no
divided encoder output: its CN1 port carries five inputs, two of them
touch probes, and three outputs
([A6-EC manual](https://www.omc-stepperonline.com/download/A6-EC_series_servo_drive_manual.pdf)).
So an incremental encoder (RS-422 line driver, 2,000 to 2,500 pulses a
turn) sits on the spindle shaft. Its A/B signals clock both line-scans
directly (Basler racer 2 encoder control,
[Basler](https://docs.baslerweb.com/encoder-control)), so line timing
never passes through software, and it measures the spindle itself
rather than the motor behind the belt. The same line also runs to an
EtherCAT encoder terminal (EL5101), which counts A/B and latches the
index once a turn. The scan, the laser traces and the servo then share
one angle reference.
- **STO version, looked at in October 2026.** StepperOnline sells the
A6-EC drive with Safe Torque Off only from 400 W: A6-EC400H2B1-M17-STO
with a brake (USD 157.91,
[StepperOnline](https://www.omc-stepperonline.com/a6-series-400w-sto-safe-torque-off-ethercat-ac-servo-motor-kit-3000rpm-1-27nm-w-brake-17-bit-absolute-encoder-ip67-a6-ec400h2b1-m17-sto))
or the same without a brake, A6-EC400H2A1-M17-STO (USD 129.60). The STO
is two 24 V inputs, STO1 and STO2, on CN5, but its manual names no
safety rating: no SIL or PL figure and no certificate
([A6-EC-STO manual](https://files.omc-stepperonline.com/A6-EC-STO_manual.pdf)).
On that document alone it cannot replace the contactor in the safety
circuit. The brake holds nothing on a horizontal spindle or conveyor.
Recommendation: stay with the 100 W kit. If StepperOnline confirms a
rated STO in writing, switch both axes to the version without a brake
and drop the contactor; its 0.60 kg·cm² rotor then needs only a 1:2 to
1:3 belt.
**Sensor list.** Everything that measures the record, and everything the
station controller needs to run the station. Lights, drives and cylinders are in the
[bill of materials](inline-qc-station/inline-qc-station-bom.csv).
| Sensor | Qty | Example | Where | What it measures | USD each |
|---|---|---|---|---|---|
| 4k monochrome line-scan camera, GigE, 50 mm lens | 2: top and bottom | Basler racer 2 r2L4096, Hikrobot MV-CL042-91GM | inspection zone, on opposite radii (top 330 mm above the record) | surface: non-fill, stitching, flow lines, specks, bubbles, under dark-field, bright-field and transmitted light on alternate lines; eccentricity from the groove spiral | 857 to 1,088 (Basler web shop); lens 300 to 800 (estimate) |
| 8 MP colour area camera, GigE, 16 mm lens, ring light | 2: top and bottom | Basler ace 2 a2A2840-14gcPRO | label gate, 520 mm from the infeed | right label on the right side, print, label centring; the top camera also reads the stamper number in the run-out | 1,119 (Basler web shop); lens and ring light 300 to 800 (estimate) |
| Laser distance sensor | 2 | Micro-Epsilon optoNCDT 1420 | under the record, at 90 and 130 mm radius; analog output to the EtherCAT analog input | warp: height traced round two circles during the turn | from EUR 470 list; ILD1420-25 about 1,600 at a reseller |
| Servo encoder, 17-bit | 2: spindle and conveyor | StepperOnline A6-EC100L2A1-M17 kit | in each motor; position over EtherCAT | spindle angle for the sequence and the warp traces; conveyor travel | in the kit, 123.29 |
| Incremental encoder, RS-422 line driver, 2,000 to 2,500 pulses a turn | 1 | Omron E6B2-CWZ1X class | on the spindle shaft | A/B clock both line-scans; A/B and the index go to the EL5101 encoder terminal, which counts the spindle angle | 53 to 282 (geizhals.de, October 2026) |
| Diffuse photoelectric sensor | 3 | any industrial make | looking up through the open centre: infeed, label trigger, outfeed | a record at the infeed starts the cycle; the trigger fires the label cameras; a full outfeed holds the next record | 50 to 150 (estimate) |
| Through-beam photoelectric sensor | 1 pair | any industrial make | across the conveyor at the inspection position | the record's leading edge; stops the belts over the chuck | 50 to 150 (estimate) |
| Cylinder position switch | 6 | SMC D-M9 class | lift (up, down), reject pusher (home, out), mandrel (open, clamped) | confirms each move before the next step | 25 to 60 (estimate) |
| Safety door switch | 1 | any safety-rated make | tunnel door | stops the station when the door opens, through the safety relay with the e-stop | in the door lot, 120 to 350 (estimate) |
| Thermal camera (option, not in the launch setup) | 0 or 1 | Optris Xi 400 | over the unload position, at a press-side station only | temperature map of a warm record, trended against warp | from EUR 1,950 |
| Laser line profiler (alternative to the two lasers) | 0 or 1 | Keyence LJ-X8000, LMI Gocator 2500, Micro-Epsilon scanCONTROL | across the radius | full height and thickness map | 8k to 20k (estimate) |
So the launch station carries four cameras, two lasers, two servo
encoders and the spindle encoder, four photoelectric sensors, six
cylinder switches and the door switch. The cameras go to the edge PC,
the spindle encoder straight to the line-scans, and everything else onto
EtherCAT.
**Cycle per record (estimate).**
| Step | Time |
|---|---|
| Convey to the inspection position | 1.5 to 2.5 s |
| Lift and clamp | 0.5 s |
| One turn, with run-up and stop | 1.3 s |
| Lower | 0.3 s |
| Convey out, with a push if rejected | 1 to 2 s |
| **Total** | **about 5 to 6 s** |
A Duplex cell delivers a record every 15 to 20 s and the Classic one
every 28 s; together that is 5 to 6 records a minute, against the 10 to
12 the station can take. The PC finishes the verdict while the record is lowered and
carried to the pusher.
**Control: EtherCAT** (decided October 2026; it replaces the small PLC
of the first draft). The full plan, with the I/O list, geizhals.de
prices, safety circuit, bench test and build order, is in
[inline-qc-control-plan.md](inline-qc-control-plan.md).
- **Station controller:** a fanless mini PC, Intel N100 with Intel
i226-V ports, EUR 394 to 456 on
[geizhals.de](https://geizhals.de/mini-pc-barebone-netzwerk-pc-intel-n100-a2926989.html)
(October 2026). It runs NixOS with the PREEMPT_RT
kernel, declared in the plant's clan like the edge PC. It is the
EtherCAT master and runs the station sequence, which we write
ourselves; there is no PLC.
- **Master software,** open source either way:
- **QiTech's EtherCAT library on EtherCrab:**
[qitech_lib](https://github.com/qitechgmbh/qitech_lib) (LGPL-3.0),
the layer under [QiTech Control](https://github.com/qitechgmbh/control),
which runs QiTech's own extrusion and winding machines on NixOS. It
brings distributed clocks, SDO and PDO handling, Beckhoff drivers and
a CiA402 servo driver to copy for the A6-EC; EtherCrab
([GitHub](https://github.com/ethercrab-rs/ethercrab), MIT or
Apache-2.0) is the pure Rust master underneath. It fits the Rust stack
of the factory application, and is the first choice.
- **IgH EtherCAT Master:** the mature fallback (GPL-2.0, its library
LGPL-2.1), packaged in nixpkgs
([MyNixOS](https://mynixos.com/nixpkgs/package/linuxKernel.packages.linux_6_18.ethercat)).
Its native igc driver for the i226 is listed for the 6.12 kernel, so
with IgH, pin the 6.12 LTS kernel
([IgH device drivers](https://docs.etherlab.org/ethercat/1.6/doxygen/devicedrivers.html)).
- **On the bus, in one line:** an EK1101 coupler with EL1809 (16
inputs: photoelectric sensors, cylinder switches, door and e-stop
status), EL2809 (16 outputs: valves, stack light), EL3152 (two 4 to
20 mA inputs for the warp lasers) and EL5101 (spindle encoder), then
the spindle drive and the conveyor drive at the end of the line. The
small A6-200EC takes its control power from the main supply, so it
leaves the bus when the safety contactors open; at the end it cuts
nothing else off. The cycle is 1 ms with distributed clocks. The
spindle runs in cyclic synchronous position mode, the conveyor in
cyclic synchronous velocity.
- **Warp traces:** the lasers are sampled in the same cycle as the
spindle encoder count, so each trace comes with its angles: about
1,000 points a turn at 1 ms (our arithmetic). The optoNCDT 1420 has a
4 to 20 mA output, hence the EL3152 rather than a voltage terminal.
- **Safety stays hardwired:** the e-stop and the door switch sit on a
safety relay that drops a contactor in the drive supply. The 100 W kit
has no STO input; in the A6-EC list, STO versions start at 400 W.
- **Edge PC:** the NixOS edge PC with the GPU, under the outfeed, takes
the four GigE cameras on PoE and the light controllers. It talks to the
station controller over plain Ethernet (record in place, turn done,
verdict with the reason) and sends the result string and images to the
factory system (see [digital factory](../digital-factory.md)). Keeping
the master off this PC keeps the GPU load away from the real-time loop.
- **HMI:** a browser page from the station controller on the 10 inch
touch panel.
Utilities are 230 V single phase at about 1 kW and 6 bar compressed air
(estimates).
![Front elevation, front panels removed](inline-qc-station/inline-qc-station-front.png)
![Plan view, lid and top bridge removed](inline-qc-station/inline-qc-station-top.png)
![The station closed, as it stands in the hall](inline-qc-station/inline-qc-station-closed.png)
**Bill of materials.** The line-by-line list with sources is in
[`inline-qc-station-bom.csv`](inline-qc-station/inline-qc-station-bom.csv).
By group, per station:
| Group | USD | Main parts |
|---|---|---|
| Frame | 0.8k to 1.6k | 32 m of 40 × 40, 3.8 m of 40 × 80, angle brackets, feet |
| Enclosure and guards | 0.3k to 0.7k | black panels, polycarbonate, door switch |
| Conveyor | 0.4k to 1.1k | round belts, pulleys, slide strips, 100 W EtherCAT servo drive |
| Handling | 1.9k to 4.5k | guided lift cylinder, 100 W EtherCAT spindle servo, spindle head with mandrel, rodless cylinder, pneumatics |
| Vision | 7.7k to 12.5k | 2 line-scans, 2 colour cameras, lenses, 2 coaxial, 4 dark-field and 2 backlights, 2 ring lights, controllers |
| Sensors | 1.5k to 4.6k | 2 laser distance sensors, presence and stop sensors, cylinder switches, spindle encoder |
| Control | 4.2k to 7.7k | EtherCAT controller and I/O, edge PC with GPU, HMI, safety, cabinet and wiring |
| **Total** | **17k to 33k (0.55M to 1.08M THB)** | thermal camera (USD 2.1k to 3.0k) not included |
**Open points for the machine builder.**
1. **Sag:** confirm that the rim-only support does not mark or bend the
records: cooled ones at launch, warm ones at a press-side station.
2. **Static:** fresh PVC attracts dust, so an ionising bar at the infeed
may be needed. Otherwise the station counts dust it attracted itself.
3. **Classic hand-off:** only for a press-side station later; at launch
the Classic stacks on its spindle as built.
4. **Belt width:** a quick-change spacing for 10" and 7" records.
5. **Space:** at launch the station and the cooling racks stand at the
start of the finishing block; a press-side station later has to fit the
5 × 3 m Duplex cell next to the trimmer.
## Where it sits
**Launch setup: one station for both presses, after cooling** (decided
October 2026).
- **To the cooling racks.** The records leave both presses on spindle
stacks as they do today: the Classic stacks by itself, with its cooling
plates ([pressing line](pressing-line.md)), and the Duplex operator
stacks the trimmed records. Each full stack gets a label, scanned at the
press, with the press, the stamper set and the first and last cycle. The
stacks go into the cooling racks first in, first out.
- **The queue.** 24 hours of cooling before sleeving is accepted practice,
and some plants cut it to 8 hours
([Stamper Discs](https://stamperdiscs.com/horns-and-quality-issues-in-vinyl-record-pressing)).
The station takes the stacks at the end of that time. A single record
would reach room temperature within minutes in still air (our estimate
for a 1.8 mm disc), but records keep settling for hours, so the queue is
measured in hours. The racks hold about one day of output: 2,800 to
3,100 records at the launch plant (the 850k target to the ~0.94M
capacity in the [calculator](../fleet-calculator.html), over 300 days).
- **Stacks and cooling plates** (decided October 2026).
- **50 records a stack,** about 15 to 25 minutes of one press. Cascade
Record Pressing pulls the spindle at 50
([VRTX](https://vrtxmag.com/articles/how-to-press-vinyl-locally)).
Fifty 180 g records weigh 9 kg; a day of output is about 58 stacks.
- **A flat aluminium cooling plate every 5 records** (decided October
2026), so 10 plates in a stack of 50. MY45 lays one every ten
([oberflaeche.de](https://oberflaeche.de/en/knowledge/topics/electro-plating/a-vinyl-renaissance/the-great-comeback-of-the-record-3)),
Mobineko one under every record
([Mobineko](https://mobineko.com/vinyl-quality-standards)). The
Classic places the plates itself ("automatic cooling plate handling",
[Newbilt](https://vinyl-pressing-plants.com/blog/newbilt-classic-12-inch-vinyl-record-press));
at the Duplex the operator lays one by hand. Full flat discs, not ring
spacers: a warm record held only round the label sags into a dish.
A stack then weighs about 15 kg: 9 kg of records and 10 plates of
0.6 kg at 3 mm (0.4 kg at 2 mm).
- **Plates cut locally.** 5052 aluminium, 3 mm thick, with the centre
hole of Newbilt's plate so the Classic's magazine takes them;
thickness and alloy are our estimate until Newbilt's drawing arrives.
A 1220 × 2440 mm sheet nests 28 discs of up to about 310 mm, and a
3 mm sheet costs about THB 8,300 before VAT
([OneStockHome](https://www.onestockhome.com/th/product_categories/aluminum-sheet-thickness-3-mm),
grade 3003, October 2026): about THB 300 of metal a plate, THB 350 to
450 with cutting and deburring (estimate). Cut on a fibre laser or a
waterjet. Chiang Mai has several laser shops (SK Laser Cut and Laser
CNX on Rattanakosin Road, among others), but many cut only acrylic and
wood, so ask for 3 mm aluminium.
- **Keeping the plates from scratching the records:**
1. **The grooves never touch the plate.** Record dies have a thick
label area matched by a thick outer edge, so pressed records stack
without the groove area touching while they cool
([Quality Record Pressings](http://qualityrecordpressings.com/index.cfm?go=Record-Weights)).
A flat plate rests on the same two rings. That holds as long as the
plate is flat (checked on a surface plate, no gap over 0.1 mm, our
target) and the Newbilt dies have this profile (to confirm).
2. **The plate is larger than the record,** about 306 to 310 mm
against 302 mm, so the record's rim sits on the flat face and never
on the plate's edge. All edges and the centre hole are deburred and
rounded; the centre hole sits under the label.
3. **Clear anodised** (about 10 to 15 µm): a hard, closed surface
that does not smear grey aluminium onto the record and keeps its
finish longer. Roughly CNY 16 to 28 a square metre in bulk in China
([YF CNC](https://yfcncmachining.com/reference-price-for-domestic-surface-treatment-in-china/));
THB 50 to 150 a plate for a small Thai batch (estimate). The first
two sheets test bare against anodised.
4. **Straight up and down only.** Records and plates go onto the
spindle and come off it vertically; nothing slides across a
record. Lint-free gloves, plates lifted by the rim that stands out
past the record.
5. **No grit between them.** Grit trapped under 15 kg is what
scratches. Flash from the edge trimmer goes into the trimmer's
extraction, not onto the stack. Each plate passes an ionised-air
blow-off and a wipe on its way back to the presses, plates travel
on a covered spindle cart, and the racks are covered.
6. **Plates are numbered** (laser mark on the band outside the
record) and looked at under a raking light every month; a dented
or scratched plate is taken out.
7. **The station proves it.** It knows each record's place in the
stack, so it can compare scratch counts on faces that lay on a
plate with faces that lay on another record. If the plate faces
come out worse, the plates are the cause.
- **How many:** one plate per 5 records over the full 24-hour queue
needs about 700 plates (25 sheets): THB 245,000 to 315,000 cut, plus
THB 35,000 to 105,000 for anodising (estimates). An 8-hour queue
needs about 200 to 260. Ask Newbilt how many plates come with the
Classic. Two sheets come first, for the plate trial (next steps).
- **At the station.** The finishing operator takes each record off the
cooled stack and puts it on the infeed, and lifts each cooling plate
onto the plate cart that goes back to the presses. Good records leave the outfeed
into sleeving; a reject goes into the bin, and the HMI shows the reason.
Finishing handles every record anyway, so the station adds no handling
step.
- **What it gains.**
- Warp and centring are measured on settled records, so the reading is
the release value; no separate sampling of cooled records is needed.
- One station instead of two: USD 17k to 33k instead of 50k to 105k
(estimates).
- The Classic needs no change to its unloader.
- The questions about warm records drop out: sag on the rim belts and
the thermal camera.
- **What it costs.** A defect is found hours after pressing instead of
within a cycle or two. Three things cover that gap:
1. The Duplex operator still sees every record.
2. Press telemetry flags process drift every cycle
([layer 2](../quality-automation.md#layer-2-press-telemetry-every-cycle)).
3. An early lane: the first records of every run, and the first after
each stamper change, go to the station warm, straight from the press.
Their surface and label verdicts count; their warp is only an early
warning. The station runs at about half its capacity at launch, so
there is room for this lane.
- **Record key.** Away from the press, the station takes the key from the
stack label and the record's place in the stack (the top record is the
last one pressed). It checks that against the stamper number read in the
run-out; the readability of that code is still to test. Where the check
fails, the result stays tied to the stack: press, stamper set and time
window ([traceability](../traceability.md)).
- **Capacity.** The launch plant makes 5 to 6 records a minute and the
station takes 10 to 12. One station covers about two Duplex systems and
two Classics at the calculator's planning rates (3 + 3 + 2 + 2 = 10 a
minute). Past that, add a second station or move to stations at the
presses.
**Considered, not taken: a spiral cooling tower.** Holding the whole
queue on a spiral is out of proportion. Eight hours of output lying
single is about 2,900 records, some 300 m of 1 m belt three records
across, roughly USD 75k to 120k at USD 250 to 300 per metre for Chinese
spiral coolers
([listing](https://www.sourcingai.com/smart-products/acebakebreadmachine/flexible-screw-cooling-spiral-tower-conveyor-tower-with-advanced-cooling-technology-for-bakery-BUWkKSqORktM);
our arithmetic), for a job the racks do for a few thousand. Bakery
spirals are built for 30 to 60 minutes
([I.J. White](https://www.ijwhite.com/blog/ultra-series-spiral-cooler-at-klosterman-baking/)).
Open on a belt for hours, fresh records also collect dust on both faces,
and a record lying alone has no stack weight holding it flat. A short
spiral of 30 to 60 minutes (20 to 40 m of belt, about USD 5k to 16k
ex-works, estimate) stays a later option: it would hand cooled records
to the station one by one and give each its exact pressing time, but
warp would then be read after an hour instead of on settled records.
The plate trial checks whether the early reading predicts the settled
one.
**Later option: a station at each press.** It finds a defect streak
within a cycle or two, at the price of one station per cell, and it reads
warm records, so release on warp still needs cooled samples.
- **Duplex cell.** After the edge trimmer, in front of the operator,
before the spindle. The operator puts each trimmed record on the infeed;
a stack light and the HMI show green or red; a good record waits at the
outfeed for the spindle.
- **Classic.** Ask Newbilt whether the unload handling can set the record
down on the station's infeed instead of the spindle. If not, a fixed
area camera over the unload position covers surface and label, and
leaves warp and eccentricity to samples.
**Plant view.** The [plant and business plan calculator](../fleet-calculator.html)
draws the station with the cooling racks in the room at the start of the
finishing block.
## Two software routes
| | Smart camera or vendor controller | Open, PC-based |
|---|---|---|
| Examples | Cognex In-Sight 3800 with edge learning (about USD 8,500 a unit in a [third-party listing](https://robotomated.com/explore/manufacturing/cognex-insight-3800)); Keyence CV-X or XG-X with LumiTrax, which separates shape from surface pattern on shiny parts ([Keyence](https://www.keyence.com/landing/vision/lumitrax-lighting.jsp)); CV-X controllers listed at about USD 5,400 to 5,500 on resale sites ([BigGo](https://biggo.com/s/cv-x%20keyence)); Keyence quotes only locally | GenICam cameras (Basler, Hikrobot, or Keyence's VJ series) with:<br>- Aravis for acquisition (LGPL-2.1, GigE Vision and USB3 Vision, packaged in nixpkgs as 0.8.35; [GitHub](https://github.com/AravisProject/aravis), [MyNixOS](https://mynixos.com/nixpkgs/package/aravis)), or Harvester (Apache-2.0, needs the camera maker's GenTL producer; [GitHub](https://github.com/genicam/harvesters));<br>- OpenCV;<br>- anomalib for learned defect detection (Apache-2.0, PatchCore and others; [PyPI](https://pypi.org/project/anomalib/)) |
| For | fast set-up, vendor support, tested tools | we own the code and the data, no licence per unit, fits the NixOS stack and the service offer to other plants ([digital factory](../digital-factory.md)) |
| Against | closed, Windows set-up tools; the polar unwrap, eccentricity fit and per-job learning still have to be built on top | we build and maintain it; the first station takes longer |
Keyence's VJ series sits between the two. It sells Keyence GigE cameras
and LumiTrax lights for PC-based software, with GenICam, OpenCV and
HALCON listed as supported
([Keyence VJ](https://keyence.com/ss/products/vision/vj)).
Recommendation: take the open route for the station itself. Before that,
ask Keyence Thailand for its free demo and test report on sample records
with LumiTrax. It costs nothing, teaches us the lighting, and gives a
benchmark for our own result.
## Colour and special records
Specials are planned at 60 % or more of output, and they are the hard
part:
- **Marbled and splatter:** the pattern is random, so a fixed golden image
cannot work. The model learns each job from its first approved records
and flags what differs. That is few-shot anomaly detection, for example
PatchCore in anomalib, with the operator confirming the first flags.
- **Clear and translucent colours:** transmitted light shows bubbles and
specks well.
- **Picture discs:** they need the label-style print comparison over the
whole face.
- **Black:** the easiest.
Expect more false rejects on specials in the first months (estimate). The
reject rates in the [factory console](../factory-console.html) demo are
simulated.
## Cost
| Item | Estimate |
|---|---|
| Hardware per station, from the [bill of materials](inline-qc-station/inline-qc-station-bom.csv) | USD 17k to 33k (0.55M to 1.08M THB) |
| First station: frame build and machined parts, lighting trials, software, training data | 2 to 4 person-months, USD 15k to 40k (our own team with a local machine builder) |
| Launch plant: one station for both presses, after cooling | the hardware above, USD 17k to 33k, plus the first-station work (about USD 32k to 73k in all, 1.0M to 2.4M THB) |
All three figures are estimates; the bill of materials names a source for each priced line. They fit inside the existing metrology
launch-tier line, USD 170k to 460k for XRF, inline vision and the audio
station ([total investment](../finance/total-investment.md)). The plan
prices therefore do not change. That line has no published split, so the
vision share is not yet confirmed.
## Where to buy in Thailand
| Brand | Channel | Status |
|---|---|---|
| Keyence | Keyence (Thailand), direct sales | free demos and test reports, as Keyence offers in other markets ([Keyence](https://www.keyence.eu/landing/lpc/surface-defect-detection.jsp)); confirm locally |
| Basler | LINX KK (Thailand), Basler's only official distributor in Thailand ([LINX](https://linx.co.th/en)) | |
| Cognex | local distributor | still to name |
| Hikrobot | local distributor or the Chinese route | still to name |
| Micro-Epsilon, LMI, Optris | local distributor | still to name |
## Next steps
1. **Lighting trials.** Get a dozen records with known defects from a
partner plant: non-fill, stitching, bubbles, an off-centre one, and a
splatter colour. Test them with a borrowed line-scan camera and two
lights.
2. **Keyence test.** Ask Keyence Thailand for a test report on the same
records.
3. **Newbilt.** Ask how the Classic hands over its spindle stacks and
cooling plates (records per stack, records per plate), and for the
drawing of its plate (diameter, thickness, alloy, centre hole) so the
locally cut plates fit its magazine. Also ask for the cycle counter over
OPC UA, so every stack label carries the record key (stamper, press,
cycle, side; see [digital factory](../digital-factory.md)).
4. **Warp sensors.** Choose between two point lasers and a line profiler
once the trials show whether a thickness map is worth the extra cost.
5. **Plate and settling trial.** Cut two sheets of plates (56), half of
them anodised. Press one job with a plate every 5, 10 and 25 records,
and read edge run-out and dish on the station after 1 hour and after
24 hours, plus the scratch counts on plate faces against record faces.
That confirms 5 records per plate or shows that 10 is enough (black,
colour and specials apart), and shows whether a 1-hour reading
predicts the settled one.
6. **EtherCAT bench.** Before the frame is built, run one A6-EC kit, the
EK1101 with its terminals and the spindle encoder from the mini PC
with qitech_lib on EtherCrab: eight tests and pass marks are in the
[control plan](inline-qc-control-plan.md#7-bench-test-before-the-frame-is-built)
(about THB 56,000 of parts, all reused in the station). If the
EtherCrab stack falls short on the drive, repeat the test with the
IgH master.
7. **Acceptance test.** Write it before ordering. It should cover the
detection rate per defect class on the trial set, the false-reject
rate on good records (black and specials apart), and every result
matched to its record key.
+349
View File
@@ -0,0 +1,349 @@
# Optical QC station: EtherCAT control plan
How the [inline optical QC station](inline-optical-qc.md) is controlled,
wired, priced, built and tested. Decided in October 2026: EtherCAT, no
PLC, and the 100 W StepperOnline servo kit on both axes. Prices for the
EtherCAT parts were checked on [geizhals.de](https://geizhals.de/) and in
the [QiTech shop](https://shop.qitech.de/collections/ethercat) on
19 October 2026; the station software builds on QiTech's open-source
EtherCAT library (section 5). The station hardware itself (frame, cameras, lights,
lasers) is in the station doc and its
[bill of materials](inline-qc-station/inline-qc-station-bom.csv).
## 1. What is decided
| Part | Choice | Why |
|---|---|---|
| Fieldbus | EtherCAT, 1 ms cycle, distributed clocks | one cable for drives and I/O; the laser samples and the spindle position come from the same cycle |
| Spindle drive | StepperOnline A6-EC100L2A1-M17 (100 W, A6-200EC drive), cyclic synchronous position, 1:6 timing belt | torque need about 0.02 N·m at the motor against 0.32 N·m rated; the belt brings the load inertia to about 28 times the rotor (station doc) |
| Conveyor drive | the same kit, cyclic synchronous velocity | one spare covers both axes |
| Controller | fanless Intel N100 mini PC with Intel i226-V ports, NixOS with a real-time kernel | open source stack, declared in the plant's clan like every other machine |
| Master software | QiTech's EtherCAT library (qitech_lib, LGPL-3.0) on EtherCrab; IgH EtherCAT Master as the fallback | Rust like the factory application, already running QiTech's own production machines, with distributed clocks and a servo driver to copy; IgH is older and proven |
| Camera clock | separate RS-422 encoder on the spindle shaft | the A6-EC drive has no divided encoder output |
| Safety | hardwired: safety relay, two contactors in the drive supply | the 100 W kit has no STO; the 400 W STO kit's manual names no safety rating (station doc) |
## 2. Bus layout
```
Station controller (N100, NixOS, real-time kernel)
|
|-- port 1 (i226-V) == EtherCAT ==> EK1101 coupler
| |-- EL1809 16 digital inputs
| |-- EL2809 16 digital outputs
| |-- EL3152 2 analog inputs (warp lasers, 4 to 20 mA)
| |-- EL5101 spindle encoder (A, B, index)
| |-- EL9011 end cap
| |
| X2 out ==> A6-200EC spindle (CSP)
| ==> A6-200EC conveyor (CSV)
|
|-- port 2 (i226-V) -- plain Ethernet --> edge PC, plant OT network
Spindle encoder (RS-422, 5 V from the EL5101)
A, B ---> racer 2 line-scan 1 ---> racer 2 line-scan 2 ---> EL5101 (A, B, index)
```
- **The drives sit at the end of the line.** On the small A6-200EC the
control electronics share the main supply; there are no separate
control-power terminals ([A6-EC manual](https://www.omc-stepperonline.com/download/A6-EC_series_servo_drive_manual.pdf),
specification table). So when the safety contactors open, both drives
leave the bus. At the end of the line that cuts nothing else off: the
coupler, the I/O and the encoder count stay up, and the master can read
the e-stop and door status and bring the drives back after the reset.
The distributed-clock reference also sits on the I/O side for the same
reason.
- **One RS-422 line, three receivers.** The encoder's line driver feeds
both cameras and the EL5101 in a chain (RS-422 allows up to ten
receivers). The racer 2 inputs take RS-422 with a switchable 120 Ω
terminator ([Basler](https://docs.baslerweb.com/io-control-racer-2-l-xl)).
Only the last receiver on the line is terminated; check on the bench
whether the EL5101 input already is.
- **Port 2 is ordinary Ethernet** to the edge PC and the plant's OT
network (VLAN as in [digital factory](../digital-factory.md)). The
EtherCAT port is a point-to-point cable to the EK1101, never a switch.
## 3. Signals
**EL1809, 16 inputs (24 V):**
| Ch | Signal | Device |
|---|---|---|
| 1 | record at the infeed | diffuse photoelectric sensor |
| 2 | label trigger (also wired straight to the two colour cameras' trigger inputs) | diffuse photoelectric sensor |
| 3 | record at the inspection position (also to the conveyor drive's touch probe 1, CN1 DI5) | through-beam pair |
| 4 | outfeed full | diffuse photoelectric sensor |
| 5, 6 | lift up, lift down | cylinder switches |
| 7, 8 | mandrel open, mandrel clamped | cylinder switches |
| 9, 10 | pusher home, pusher out | cylinder switches |
| 11 | safety relay status | PNOZ s3 semiconductor output |
| 12 | door closed (status contact) | safety door switch |
| 13 | contactors closed | contactor auxiliary contact |
| 14 | reset pressed | second contact on the reset button |
| 15 | air pressure ok | pressure switch on the FRL |
| 16 | spare | |
**EL2809, 16 outputs (24 V, 0.5 A):** lift up, lift down, mandrel clamp,
pusher out, pusher back, stack light green, amber and red, buzzer, light
controllers on (lights only during the turn), reset-button lamp; five
spare (an ionising bar at the infeed is one candidate).
**EL3152, 2 analog inputs:** the two optoNCDT 1420 lasers at 90 and 130 mm
radius. Their analog output is 4 to 20 mA; voltage only comes through a
load resistor in the cable
([Micro-Epsilon manual](https://micro-epsilon.com/download/manuals/man--optoNCDT-1420--en.pdf)),
so the current-input EL3152 replaces the ±10 V EL3102 of the first draft.
**EL5101:** spindle encoder A, B and index. It counts the spindle angle
directly (not the motor behind the belt) and latches the count at the
index once a turn.
**Drive inputs:** only the conveyor drive's touch probe 1 is used: the
through-beam latches the conveyor position at the record's leading edge,
so the stop over the chuck does not depend on the 1 ms cycle or the
input filter.
**Process data per drive.** The A6-EC has one freely mapped RPDO and
TPDO plus fixed sets; the fixed 1702h set carries control word, target
position, target velocity and mode together (manual, PDO section), so
both drives can share one mapping and differ only in the mode (8 for
CSP, 9 for CSV). The drive runs only in DC sync mode; its SYNC0 period
range depends on the mode, so the 1 ms cycle is the first bench check.
## 4. Prices from geizhals.de and the QiTech shop
Lowest price on 19 October 2026, in EUR including 19% German VAT; THB at
38.115 per EUR. Four terminals come from the QiTech shop (section 5),
the rest from the lowest geizhals.de offer.
| Part | Qty | Example | EUR | THB | Source |
|---|---|---|---|---|---|
| Station controller | 1 | ANDAQI RS55 (6 × i226-V) / MNBOXCONET P2-N100 (2 × i226-V, fanless) | 393.99 to 455.99 | 15,017 to 17,380 | [geizhals](https://geizhals.de/mini-pc-barebone-netzwerk-pc-intel-n100-a2926989.html) |
| EtherCAT coupler | 1 | Beckhoff EK1101 (EK1100 with an ID switch) | 85.13 | 3,245 | [QiTech shop](https://shop.qitech.de/products/beckhoff-ek1101), 148 in stock |
| 16 digital inputs | 1 | Beckhoff EL1809 | 16.53 | 630 | [QiTech shop](https://shop.qitech.de/products/beckhoff-el1809), 157 in stock |
| 16 digital outputs | 1 | Beckhoff EL2809 | 41.03 | 1,564 | [QiTech shop](https://shop.qitech.de/products/beckhoff-el2809), 104 in stock |
| 2 analog inputs, 4 to 20 mA | 1 | Beckhoff EL3152 | 208.90 | 7,962 | [geizhals](https://geizhals.de/185886294) |
| Encoder interface, RS-422 | 1 | Beckhoff EL5101 | 291.04 | 11,093 | [geizhals](https://geizhals.de/2974477757) |
| End cap | 1 | Beckhoff EL9011 | 1.76 | 67 | [QiTech shop](https://shop.qitech.de/products/beckhoff-el9011), 131 in stock |
| Spindle encoder | 1 | E6B2-CWZ1X 2000 P/R (marketplace) / GHH60 2500 P/R line driver | 45.52 to 187.83 | 1,735 to 7,159 | [geizhals](https://geizhals.de/6925000400) |
| Safety relay | 1 | Pilz PNOZ s3 750103 | 148.38 | 5,656 | [geizhals](https://geizhals.de/pilz-pnoz-s3-24vdc-2-n-o-750103-a3204143.html) |
| Contactor, 24 V DC coil | 2 | Siemens 3RT2015 | 27.95 each | 2,131 | [geizhals](https://geizhals.de/siemens-leistungsschuetz-3rt2015-1bb41-a3269085.html) |
| E-stop button | 1 | Schneider Harmony, 40 mm head | 45.08 | 1,718 | [geizhals](https://geizhals.de/208045150) |
| HMI touch monitor 10.1 inch | 1 | iiyama ProLite TF1015MC-B3 | 311.90 | 11,888 | [geizhals](https://geizhals.de/iiyama-prolite-tf1015mc-b3-a3228748.html) |
| 24 V supply, 120 W | 1 | Mean Well SDR-120-24 | 38.87 to 47.35 | 1,482 to 1,805 | [geizhals](https://geizhals.de/980542712) |
| Servo kit 100 W, EtherCAT | 2 | StepperOnline A6-EC100L2A1-M17 | USD 123.29 each | 8,137 | not on geizhals; [StepperOnline](https://www.omc-stepperonline.com/a6-series-100w-ethercat-ac-servo-motor-kit-3000rpm-0-32nm-17-bit-absolute-encoder-ip67-a6-ec100l2a1-m17), China warehouse |
| **Total** | | | **1,684.03 to 1,896.82 + USD 246.58** | **72,324 to 80,434** | |
Notes on the prices:
- **German VAT comes off, Thai duty and VAT go on.** For an order
shipped to Thailand the 19% German VAT is not charged; Thai import VAT
(7%) and duty are added. The listed gross price is therefore used as
the landed low end; the bill of materials adds 30% for shipping and a
Thai distributor as the high end (estimate).
- **QiTech shop:** Beckhoff terminals new in the original box, bought
out of an insolvency, at a fraction of the usual price: EL1809
EUR 16.53 against EUR 93.97 on geizhals, EL2809 EUR 41.03 against
EUR 102.97, EK1101 EUR 85.13 against EUR 150.75 for an EK1100 (no
current geizhals offer). Together EUR 207.57 (THB 7,912) less. The shop
ships worldwide by DHL from Darmstadt in 7 to 14 working days; the
postage to Thailand only shows at checkout (not checked). It has no
EL3152 or EL5101, so those two stay with geizhals.
- **Mini PCs** on geizhals are marketplace brands (ANDAQI, MNBOXCONET,
AIOPCWA). Before ordering, check that the ports are i226-V (not the
older i225) and that the BIOS lets C-states be switched off.
- **Encoder:** the EUR 45.52 E6B2-CWZ1X listings come from marketplace
sellers and may be copies; the bench test decides whether one is good
enough. A genuine Omron or a 2,500-pulse line-driver encoder (GHH60,
EUR 187.83) is the fallback.
- **Contactors:** the price is for 3RT2015-1BB41 (one NO auxiliary
contact). The feedback loop needs the NC version, 3RT2015-1BB42
(price not checked; same class).
- **Not on geizhals:** the servo kits (StepperOnline direct), the optoNCDT
lasers and the Basler cameras (both in the station bill of materials).
Bill of materials effect: the control group comes to USD 4.2k to 7.7k
(edge PC with GPU and the cabinet lot included) and the station to
**USD 16.7k to 32.7k (THB 0.55M to 1.08M)**.
## 5. Software on the station controller
**QiTech Control, checked 19 October 2026.** QiTech, a machine builder in
Darmstadt (filament extrusion and winding), publishes the control
software of its own machines:
[QiTech Control](https://github.com/qitechgmbh/control), LGPL-3.0, 359
stars, 2,855 commits since January 2025, last push 16 October 2026,
running more than ten of their production machines (their README). It is
a Rust server on EtherCrab (their fork `ethercrab-dc`) with axum and
Socket.IO, an Electron and React front end, and a NixOS image with a
tuned kernel. The EtherCAT layer is a separate library,
[qitech_lib](https://github.com/qitechgmbh/qitech_lib), also LGPL-3.0.
What fits:
- The same choices as this plan: Rust, EtherCrab, NixOS, Beckhoff
terminals, no PLC.
- Distributed clocks are built in (SYNC0 at 1 ms with a 500 µs shift by
default), with SDO access, PDO mapping and the EtherCAT state changes.
- Drivers exist for the EK1100 and the EL2809 of our list, and for 4 to
20 mA inputs (EL3021, EL3024).
- A CiA402 servo driver for the Panasonic MINAS A6 over CoE (169 lines)
is the template for the A6-EC: the same profile and the same PDO and
SDO steps.
- Their NixOS settings run in production: `isolcpus=2,3` (core 2 for the
EtherCAT thread, core 3 for the control loop), `nohz_full`,
`rcu_nocbs`, `pcie_aspm=off`, `preempt=full` on kernel 6.18, and a
realtime group with rtprio and memlock.
What is missing:
- Drivers for the EK1101, the EL1809 (the 16-channel twin of the
supported EL1008), the EL3152, the EL5101 and the A6-EC drive. A
Beckhoff driver is a short file (their EL2809: 138 lines). We write
them and send them upstream.
- The library's README warns that its API "may change drastically"
before a stable release, so we pin one commit.
- The full QiTech Control app (Electron front end, a GNOME desktop on the
machine PC, their machine catalogue) is built around their machines.
**Decision:** qitech_lib, pinned, is the EtherCAT layer; the station
service on top of it is ours; the full app is not used. The HMI stays a
web page from the station service, which keeps the controller image
small and the station inside the factory application's stack. Adding the
station as a machine in a fork of their app stays open if their front
end proves worth it. LGPL-3.0 leaves our own code under our own licence;
changes to the library are shared under the LGPL, which we want anyway
for the drivers. The obligations only apply if we hand the software to
someone else.
**Also in their shop, not taken:** TwinSAFE terminals (EL1918
EUR 140.89, EL2904 EUR 105.85, EL6910 EUR 106.12) need Beckhoff's
TwinCAT tools to set up the safety logic and a master that passes the
safety frames between terminals, which qitech_lib does not offer; the
PNOZ relay is simpler. Beckhoff servo terminals with STO (EL7211-9014
EUR 215.99 with an AM8122 motor at EUR 285.33) cost about EUR 500 an
axis and need a 48 V supply; the 100 W kit stays.
**Operating system (NixOS module in the plant's clan):**
- Start from QiTech's tested kernel settings above. If the bench jitter
test fails, move to 6.12 LTS with PREEMPT_RT (in the mainline kernel
since 6.12), which the IgH fallback needs anyway: its native i226 (igc)
driver is listed for 6.12
([IgH device drivers](https://docs.etherlab.org/ethercat/1.6/doxygen/devicedrivers.html)).
- The EtherCAT port's interrupts pinned to the EtherCAT core, deep
C-states and Energy Efficient Ethernet off on that port.
- The station service runs under systemd with real-time priority,
locked memory and raw-socket rights, and restarts on failure; logs go
to the plant's log store.
**Station service (Rust, one program, written by us):**
1. **Bus loop:** the qitech_lib EtherCAT thread every 1 ms with
distributed clocks; brings all slaves to OP, maps the drive PDOs,
runs the CiA402 state machine of both drives, and re-adds a drive
that left the bus after an e-stop.
2. **Sequence:** one state machine per record: wait at the infeed,
convey, stop on the latched leading edge, lift, clamp, one turn,
unclamp, lower, convey out, push if rejected. Every step has a
timeout and a fault text (for example "lift up not reached in 0.8 s").
3. **Measurement:** during the turn, each cycle stores the EL5101 count
and both laser values, about 1,000 points a turn at one turn a
second. The laser output lags 750 µs at 4 kHz (Micro-Epsilon), a fixed
offset of about 0.3° at that speed, corrected in software. Edge
run-out and dish are computed at the end of the turn.
4. **Edge PC link** over port 2: record in place, turn started, turn
done with the warp values; the edge PC answers with the verdict and
the reason. No answer in time means reject and an alarm.
5. **HMI:** a web page served by the same program and shown on the touch
monitor in a kiosk browser: state, last results, alarms, counters, and
a setup mode (jog, single steps) that works only with the door shut.
The cameras keep their clock in hardware: the encoder pulses go straight
into the racer 2 encoder input, and the camera's frequency converter
scales them to the line count the optics need
([Basler](https://docs.baslerweb.com/frequency-converter)). No software
sits between the spindle and the line timing.
## 6. Safety
- **Circuit:** e-stop (two channels) and the tunnel door switch (two
channels) on a Pilz PNOZ s3 with a monitored manual reset. Its two
safety contacts switch two contactors in series in the 230 V supply of
both drives; the contactors' NC mirror contacts sit in the relay's
feedback loop. A dump valve on the FRL, wired with the contactor
coils, vents the cylinders at the same time.
- **Stop category 0:** power off at once. Both axes carry a few
kg·cm², so they coast to a stop in well under a second (estimate). If
the risk assessment asks for a controlled stop first (category 1), a
relay with delayed outputs (Pilz PNOZ s5 class) lets the master brake
the axes before the power goes.
- **Target:** PL d (estimate). A risk assessment to ISO 12100 and
ISO 13849-1 by the machine builder decides; it is part of the
acceptance test.
- **After a stop:** reset, the drives power up and rejoin the bus, the
master takes them back to OP, and the spindle angle comes from the
EL5101 count, which never lost power.
## 7. Bench test, before the frame is built
**Parts:** one servo kit, the mini PC, the EK1101 with the four I/O
terminals and the end cap, the spindle encoder, the PNOZ s3, two
contactors, the e-stop and the 24 V supply: EUR 1,372.13 (geizhals.de
and the QiTech shop) plus USD 123.29, about **THB 56,000 (USD 1,710)**. Every part goes into
the station afterwards. One laser and one line-scan camera, ordered
early from the station list, make the test complete. A reject record on
a test mandrel is the load.
| # | Test | Pass (our targets) |
|---|---|---|
| 1 | qitech_lib (EtherCrab) brings coupler, terminals and drive to OP with distributed clocks at 1 ms | all slaves in OP, no lost frames over 24 h |
| 2 | Cycle timing under load: images streaming on port 2, HMI open, CPU stress on the other cores | worst-case jitter under 50 µs over 24 h |
| 3 | Spindle in CSP: one turn a second, 0.15 s run-up | stop repeatable within ±0.1° at the spindle |
| 4 | EL5101 count against the servo position | exactly 6 motor turns per spindle turn over 1,000 turns, index latched every turn |
| 5 | Laser through the EL3152 on the reject record | the warp trace repeats turn to turn within 0.05 mm, a tenth of the smallest edge run-out limit (0.5 mm, Mobineko) |
| 6 | Camera clock: racer 2 on the encoder chain | the set number of lines every turn, none missed over 100 turns |
| 7 | Conveyor (same drive in CSV): through-beam on touch probe 1 | position latched on every pass |
| 8 | E-stop and door | contactors open, drive leaves the bus, I/O stays in OP; drive back in OP within 10 s of the reset |
If the EtherCrab stack fails tests 1, 2, 3 or 8 and a week of work does
not fix it, repeat them with the IgH master on the 6.12 real-time
kernel. The station
service keeps the bus loop behind one interface, so only that part
changes.
## 8. Build order and timing (estimates)
| Weeks | Step | Who |
|---|---|---|
| 1 to 3 | order the bench parts; servo kits from StepperOnline's China warehouse, Beckhoff and the rest from Germany or a Thai distributor | us |
| 3 to 6 | drivers for EK1101, EL1809, EL3152, EL5101 and the A6-EC in qitech_lib, sent upstream; bench test (section 7) | us |
| 5 to 9 | cabinet schematic (QElectroTech, open source) and cabinet build; station service and HMI | us, with a panel builder in Chiang Mai if needed |
| 7 to 11 | frame, conveyor, spindle head and pneumatics | machine builder |
| 10 to 12 | cabinet on the frame, wiring, drive tuning on the real spindle, first records | us and the machine builder |
| 12 to 14 | risk assessment, acceptance test, then into production behind the cooling racks | us and the machine builder |
So the control work should start about four months before the first
records need checking (estimate).
## 9. Spares
One servo kit (covers both axes), one spindle encoder and one contactor:
about USD 210 at the prices above. At the QiTech shop's prices a spare
coupler, EL1809 and EL2809 add only EUR 142.69 (USD 165), so they are
stocked too. The EL3152 and EL5101 are not; a failed one is a few days by
courier from Europe (estimate).
## 10. Open points
1. **The A6-EC drive on qitech_lib** is untested; the driver is ours to
write from their MINAS A6 one. The bench answers it, with IgH as the
fallback. Pin the qitech_lib commit; its API is not stable yet.
2. **SYNC0 range of the A6-EC** at 1 ms in CSP and CSV: not in the
material read so far; the bench checks it.
3. **EL5101 termination** and the RS-422 chain with three receivers.
4. **Shipping:** the QiTech shop's postage to Thailand (shown at
checkout) and a Thai Beckhoff quote for the EL3152 and EL5101.
5. **Risk assessment** by the machine builder: confirms PL d and stop
category 0, or asks for the delayed relay.
6. Still open from the station doc: 7"/10" quick change, anti-static at
the infeed, belt tension against the motor's 78 N radial load.
@@ -0,0 +1,5 @@
# intermediate files of render_annotated.py / annotate_render.py
_*.png
_anchors.json
*-annotated-base.png
*.FCBak
@@ -0,0 +1,111 @@
# Draw the part labels onto the investor render of the inline QC station.
# uv run --with pillow python docs/equipment/inline-qc-station/annotate_render.py
# Reads inline-qc-station-annotated-base.png and _anchors.json from render_annotated.py
# (FreeCAD) and writes inline-qc-station-annotated.png.
import json
import os
from PIL import Image, ImageChops, ImageDraw, ImageFont
D = os.path.dirname(os.path.abspath(__file__))
FONTS = "C:/Windows/Fonts/"
SCALE = 0.75 # 4000 px render, drawn at 3/4 size (anti-aliased)
TITLE = "Inline optical QC station"
SUBTITLE = ("Every record checked on both faces in one turn: surface, label, warp and centring. "
"Failed records leave the line automatically.")
FOOTER = ("CNX Vinyl, concept model (FreeCAD); bought parts drawn as outlines. 1.9 × 0.65 × 1.5 m, "
"front panels and lid removed for the view. Hardware about USD 17k to 33k per station (estimate).")
NAVY, GREY, LINE = (18, 53, 91), (85, 95, 105), (60, 74, 90)
def font(name, size):
return ImageFont.truetype(FONTS + name, size)
F_TITLE, F_SUB = font("seguisb.ttf", 76), font("segoeui.ttf", 36)
F_LAB, F_DESC, F_FOOT = font("seguisb.ttf", 40), font("segoeui.ttf", 31), font("segoeui.ttf", 27)
meta = json.load(open(os.path.join(D, "_anchors.json"), encoding="utf-8"))
img = Image.open(os.path.join(D, "inline-qc-station-annotated-base.png")).convert("RGB")
img = img.resize((round(img.width * SCALE), round(img.height * SCALE)), Image.LANCZOS)
bb = ImageChops.difference(img, Image.new("RGB", img.size, (255, 255, 255))).getbbox()
pad = 30
crop = (max(0, bb[0] - pad), max(0, bb[1] - pad), min(img.width, bb[2] + pad), min(img.height, bb[3] + pad))
img = img.crop(crop)
anchors = [dict(a, xy=(a["xy"][0] * SCALE - crop[0], a["xy"][1] * SCALE - crop[1])) for a in meta["anchors"]]
COL_W, GAP, TOP, BOTTOM, MX = 760, 90, 280, 140, 90
W = img.width + 2 * (MX + COL_W + GAP)
H = img.height + TOP + BOTTOM
canvas = Image.new("RGB", (W, H), (255, 255, 255))
ox, oy = MX + COL_W + GAP, TOP
canvas.paste(img, (ox, oy))
d = ImageDraw.Draw(canvas)
d.text((MX, 60), TITLE, font=F_TITLE, fill=NAVY)
d.text((MX + 4, 165), SUBTITLE, font=F_SUB, fill=GREY)
d.line([(MX, 238), (W - MX, 238)], fill=(215, 220, 226), width=2)
d.text((MX, H - 90), FOOTER, font=F_FOOT, fill=GREY)
# split: the left-most half of the anchors on the left, the rest on the right
order = sorted(anchors, key=lambda a: a["xy"][0])
half = (len(order) + 1) // 2
cols = {"L": order[:half], "R": order[half:]}
BLOCK = 108 # label height incl. spacing
def _cross(p1, p2, p3, p4):
def o(a, b, c):
return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0])
return (o(p1, p2, p3) > 0) != (o(p1, p2, p4) > 0) and (o(p3, p4, p1) > 0) != (o(p3, p4, p2) > 0)
def place(items, edge_x):
"""Label slots kept near each anchor's height without overlapping, then the anchor-to-slot
assignment that makes no two leader lines cross (fewest crossings, then least drift)."""
import itertools
items = sorted(items, key=lambda a: a["xy"][1])
lo, hi = oy - 20, oy + img.height - BLOCK + 20
ys = [min(max(a["xy"][1] + oy - 26, lo), hi) for a in items]
for i in range(1, len(ys)):
ys[i] = max(ys[i], ys[i - 1] + BLOCK)
over = ys[-1] - hi
if over > 0:
ys = [y - over for y in ys]
for i in range(len(ys) - 2, -1, -1):
ys[i] = min(ys[i], ys[i + 1] - BLOCK)
best = None
for perm in itertools.permutations(range(len(items))):
segs = [((edge_x, ys[k] + 26), (items[i]["xy"][0] + ox, items[i]["xy"][1] + oy)) for k, i in enumerate(perm)]
n = sum(_cross(*segs[a], *segs[b]) for a in range(len(segs)) for b in range(a + 1, len(segs)))
drift = sum(abs(ys[k] + 26 - items[i]["xy"][1] - oy) for k, i in enumerate(perm))
score = n * 1e6 + drift
if best is None or score < best[0]:
best = (score, perm)
print("crossings", int(best[0] // 1e6))
return [(items[i], ys[k]) for k, i in enumerate(best[1])]
for side, items in cols.items():
edge = MX + COL_W + GAP - 20 if side == "L" else ox + img.width + 20
for a, y in place(items, edge):
ax, ay = a["xy"][0] + ox, a["xy"][1] + oy
# text in a fixed column, left-aligned; the leader leaves from the end of the title line,
# runs level to the column edge, then straight to the part
tl = d.textlength(a["title"], font=F_LAB)
ly = y + 26
if side == "L":
tx = MX
pts = [(tx + tl + 16, ly), (MX + COL_W + GAP - 20, ly), (ax, ay)]
else:
tx = ox + img.width + GAP
pts = [(tx - 16, ly), (ox + img.width + 20, ly), (ax, ay)]
d.line(pts, fill=LINE, width=3, joint="curve")
d.ellipse([ax - 10, ay - 10, ax + 10, ay + 10], fill=(255, 255, 255))
d.ellipse([ax - 7, ay - 7, ax + 7, ay + 7], fill=NAVY)
d.text((tx, y), a["title"], font=F_LAB, fill=NAVY)
d.text((tx, y + 52), a["desc"], font=F_DESC, fill=GREY)
out = os.path.join(D, "inline-qc-station-annotated.png")
canvas.save(out, optimize=True)
print("saved", out, canvas.size)
@@ -0,0 +1,480 @@
# Build the CNX Vinyl inline optical QC station (concept) in FreeCAD.
#
# Run inside the FreeCAD GUI (26.3):
# exec(open(r"C:/dev/cnx_vinyl/docs/equipment/inline-qc-station/build_station.py", encoding="utf-8").read())
# It creates the document "InlineQCStation", saves inline-qc-station.FCStd next
# to this script and leaves the view open for rendering (render_station.py).
#
# Concept, not a fabrication drawing: the frame uses the real 8-slot 40 series
# section (profile_shape), bought parts are drawn as their envelope boxes. Sizes
# follow ../inline-optical-qc.md. At the end the script lists any part that does
# not reach the floor through parts it touches (panels not counted).
#
# Axes: x = record flow (infeed at x = 0, outfeed at x = L), y = across
# (operator front at -y), z = up from the floor. All values in mm.
import os
import FreeCAD as App
import Part
try:
import FreeCADGui as Gui
HAVE_GUI = App.GuiUp
except Exception:
HAVE_GUI = False
HERE = os.path.dirname(os.path.abspath(__file__)) if "__file__" in dir() else r"C:/dev/cnx_vinyl/docs/equipment/inline-qc-station"
OUT = os.path.join(HERE, "inline-qc-station.FCStd")
V = App.Vector
# ---------------------------------------------------------------- parameters
L = 1900 # frame length along the flow
YF = 300 # centre of the outer frame profiles, +/- y
P = 40 # profile size (40 x 40 slot profile; 40 x 80 for the base)
ZB = 900 # top of the rim belts = record underside while conveyed
R_REC = 150.8 # 12" record radius (IEC 98: 301.6 mm diameter)
T_REC = 2.0 # record thickness (approx.)
R_LABEL = 50.0 # label radius
R_HOLE = 3.62 # centre hole 7.24 mm
R_REC_AREA = 146.3 # recorded outer radius (292.6 mm max): the rim outside it carries no grooves
Y_BELT = 148.5 # round belts run under the unrecorded rim
ZL = 960 # record underside when the chuck has lifted it
LIFT = 75 # chuck stroke: pad top 885 (below the belts) -> 960
X_IN = 200 # infeed: operator or Classic unloader puts the record here
X_LB = 520 # label gate: both label cameras, on the fly with strobe
X_IS = 880 # inspection: lift, clamp, one turn under the line-scans
X_RJ = 1320 # reject pusher
X_OUT = L - 30 - R_REC - 4 # outfeed end stop: good records wait here
XT0, XT1 = 320, 1100 # light-tight tunnel uprights (inner faces 360 / 1100)
TOP_LINE = (X_IS + 50, X_IS + 155) # top line-scan sees the +x radius, r 50..155
BOT_LINE = (X_IS - 155, X_IS - 50) # bottom line-scan sees the -x radius
WD_LINE = 330 # 4k x 7 um sensor, 160 mm field, f = 50 mm -> ~330 mm working distance
WD_LABEL = 303 # 2840 px x 2.74 um sensor, 140 mm field, f = 16 mm
# ---------------------------------------------------------------- colours
ALU = (0.78, 0.80, 0.83)
DARK = (0.18, 0.19, 0.21)
BLACK = (0.04, 0.04, 0.05)
CAM = (0.36, 0.52, 0.70) # camera bodies
LENS = (0.08, 0.08, 0.09)
LIGHT = (0.97, 0.95, 0.80) # emitting faces
LIGHTBODY = (0.25, 0.25, 0.27)
BELT = (0.20, 0.62, 0.34) # green PU round belt
UHMW = (0.95, 0.95, 0.93)
PNEU = (0.70, 0.72, 0.75)
SERVO = (0.12, 0.12, 0.14)
RED = (0.85, 0.10, 0.10)
YELLOW = (0.95, 0.80, 0.10)
GREEN = (0.15, 0.70, 0.25)
AMBER = (0.98, 0.60, 0.10)
PANEL = (0.06, 0.06, 0.07)
CLEAR = (0.75, 0.85, 0.95)
CABINET = (0.72, 0.73, 0.70)
LASER = (1.0, 0.05, 0.05)
for _d in list(App.listDocuments().values()):
if _d.Name.startswith("InlineQCStation") or _d.FileName.replace("\\", "/").endswith("inline-qc-station.FCStd"):
App.closeDocument(_d.Name)
doc = App.newDocument("InlineQCStation")
doc.Label = "CNX inline optical QC station (concept)"
groups = {}
def grp(name):
if name not in groups:
g = doc.addObject("App::DocumentObjectGroup", name)
groups[name] = g
return groups[name]
def add(group, name, shape, color=ALU, transp=0):
o = doc.addObject("Part::Feature", name)
o.Shape = shape
grp(group).addObject(o)
if HAVE_GUI:
vo = o.ViewObject
vo.ShapeColor = color
vo.Transparency = transp
vo.LineColor = (0.25, 0.25, 0.25)
return o
def box(x0, y0, z0, x1, y1, z1):
return Part.makeBox(x1 - x0, y1 - y0, z1 - z0, V(x0, y0, z0))
def cyl(r, h, base, d=V(0, 0, 1)):
return Part.makeCylinder(r, h, base, d)
# ---------------------------------------------------------------- real slot profiles
# 8-slot 40 series (item / Misumi HFS8 class): 8.2 mm slot opening, 4.3 mm lip,
# undercut chamber 16 mm wide, slot depth 12 mm, centre bore 6.8 mm (M8 tap),
# corner cavities, 0.8 mm corner chamfer. 40 x 80 adds a centre cavity.
ALU_BRACKET = (0.60, 0.62, 0.65)
_FACES = {}
def _slot(cx, cy, nx, ny):
td = [(-4.1, -1), (-4.1, 4.3), (-8.0, 4.3), (-8.0, 7.5), (-4.1, 12.0),
(4.1, 12.0), (8.0, 7.5), (8.0, 4.3), (4.1, 4.3), (4.1, -1)]
tx, ty = -ny, nx
pts = [V(cx + t * tx + d * nx, cy + t * ty + d * ny, 0) for t, d in td]
return Part.Face(Part.makePolygon(pts + [pts[0]]))
def profile_face(a, b):
"""Cross-section a (local X) by b (local Y), both multiples of 40, corner at the origin."""
if (a, b) in _FACES:
return _FACES[(a, b)]
c = 0.8
o = [V(c, 0, 0), V(a - c, 0, 0), V(a, c, 0), V(a, b - c, 0), V(a - c, b, 0), V(c, b, 0), V(0, b - c, 0), V(0, c, 0)]
f = Part.Face(Part.makePolygon(o + [o[0]]))
cuts = []
for i in range(int(a // 40)):
cuts += [_slot(20 + 40 * i, 0, 0, 1), _slot(20 + 40 * i, b, 0, -1)]
for j in range(int(b // 40)):
cuts += [_slot(0, 20 + 40 * j, 1, 0), _slot(a, 20 + 40 * j, -1, 0)]
for i in range(int(a // 40)):
for j in range(int(b // 40)):
cuts.append(Part.Face(Part.Wire(Part.makeCircle(3.4, V(20 + 40 * i, 20 + 40 * j, 0)))))
for cx, cy in [(5.4, 5.4), (a - 5.4, 5.4), (a - 5.4, b - 5.4), (5.4, b - 5.4)]:
cuts.append(Part.Face(Part.Wire(Part.makeCircle(2.2, V(cx, cy, 0)))))
if a == 40 and b == 80:
cuts.append(Part.Face(Part.makePolygon([V(14, 33, 0), V(26, 33, 0), V(26, 47, 0), V(14, 47, 0), V(14, 33, 0)])))
if a == 80 and b == 40:
cuts.append(Part.Face(Part.makePolygon([V(33, 14, 0), V(47, 14, 0), V(47, 26, 0), V(33, 26, 0), V(33, 14, 0)])))
for k in cuts:
f = f.cut(k)
_FACES[(a, b)] = f
return f
def profile_shape(x0, y0, z0, x1, y1, z1):
"""A real slot profile filling the axis-aligned bar x0..x1, y0..y1, z0..z1."""
dx, dy, dz = x1 - x0, y1 - y0, z1 - z0
long_axis = max((dx, "x"), (dy, "y"), (dz, "z"))[1]
if long_axis == "x": # local X -> Y, local Y -> Z, extrusion -> X
a, b, n = dy, dz, dx
m = App.Matrix(0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1)
elif long_axis == "y": # local X -> Z, local Y -> X, extrusion -> Y
a, b, n = dz, dx, dy
m = App.Matrix(0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1)
else:
a, b, n = dx, dy, dz
m = App.Matrix()
a, b = round(a), round(b)
if a % 40 or b % 40:
return box(x0, y0, z0, x1, y1, z1)
sol = profile_face(a, b).extrude(V(0, 0, n))
if long_axis != "z":
sol.transformShape(m)
sol.translate(V(x0, y0, z0))
return sol
def prof(group, name, x0, y0, z0, x1, y1, z1):
return add(group, name, profile_shape(x0, y0, z0, x1, y1, z1), ALU)
def gusset(group, name, corner, d1, d2, w):
"""Cast angle bracket in the inside corner: legs 32 mm along d1 and d2, 34 mm wide along w."""
p0 = corner - w * 17
pts = [p0, p0 + d1 * 32, p0 + d2 * 32, p0]
tri = Part.Face(Part.makePolygon(pts))
return add(group, name, tri.extrude(w * 34), ALU_BRACKET)
def rot(shape, center, axis, deg):
s = shape.copy()
s.rotate(center, axis, deg)
return s
def ring(r_out, r_in, h, base):
return cyl(r_out, h, base).cut(cyl(r_in, h + 2, base - V(0, 0, 1)))
# ---------------------------------------------------------------- frame
G = "Frame"
for i, (x, y) in enumerate([(20, -YF), (20, YF), (XT0 + 20, -YF), (XT0 + 20, YF),
(XT1 + 20, -YF), (XT1 + 20, YF), (L - 20, -YF), (L - 20, YF)]):
add(G, f"Foot{i}", cyl(30, 12, V(x, y, 0)).fuse(cyl(8, 50, V(x, y, 12))), DARK)
for s in (-1, 1):
prof(G, f"BaseBeam{'F' if s < 0 else 'B'}", 0, s * YF - 20, 60, L, s * YF + 20, 140) # 40 x 80
for x0, z1, nm in [(0, 870, "End0"), (XT0, 1500, "Tunnel0"), (XT1, 1500, "Tunnel1"),
(L - P, 1340 if s < 0 else 1080, "End1")]: # front end upright carries the touch screen
prof(G, f"Upright{nm}{'F' if s < 0 else 'B'}", x0, s * YF - 20, 140, x0 + P, s * YF + 20, z1)
prof(G, f"TopBeam{'F' if s < 0 else 'B'}", XT0 + P, s * YF - 20, 1460, XT1, s * YF + 20, 1500)
prof(G, f"LowBeam{'F' if s < 0 else 'B'}", XT0 + P, s * YF - 20, 420, XT1, s * YF + 20, 460)
prof(G, f"RejectBeam{'F' if s < 0 else 'B'}", XT1 + P, s * YF - 20, 1040, L - P, s * YF + 20, 1080)
for x0, nm in [(0, "End0"), (XT0, "Tunnel0"), (XT1, "Tunnel1"), (L - P, "End1")]:
prof(G, f"BaseCross{nm}", x0, -YF + 20, 100, x0 + P, YF - 20, 140)
prof(G, f"ConvCross{nm}", x0, -YF + 20, 790, x0 + P, YF - 20, 830)
# top bridge: label camera and top line-scan
prof(G, "TopCrossLabel", X_LB + 70, -YF + 20, 1460, X_LB + 110, YF - 20, 1500)
xt = sum(TOP_LINE) / 2
prof(G, "TopCrossLineScan", xt + 48, -YF + 20, 1460, xt + 88, YF - 20, 1500)
prof(G, "TopCrossThermal", XT0 + P, -YF + 20, 1460, XT0 + P + 40, YF - 20, 1500)
prof(G, "TopCrossBacklight", sum(BOT_LINE) / 2 - 38, -YF + 20, 1460, sum(BOT_LINE) / 2 + 2, YF - 20, 1500)
# lower bridge: bottom label camera, bottom line-scan, chuck lift
xb = sum(BOT_LINE) / 2
prof(G, "LowCrossLabel", X_LB + 70, -YF + 20, 420, X_LB + 110, YF - 20, 460)
prof(G, "LowCrossLineScan", xb - 20, -YF + 20, 420, xb + 20, YF - 20, 460)
prof(G, "LowCrossChuck", X_IS - 20, -YF + 20, 420, X_IS + 20, YF - 20, 460)
prof(G, "LowCrossBacklight", xt - 20, -YF + 20, 420, xt + 20, YF - 20, 460)
prof(G, "BaseCrossCabinet0", 1200, -YF + 20, 100, 1240, YF - 20, 140)
prof(G, "BaseCrossCabinet1", 1580, -YF + 20, 100, 1620, YF - 20, 140)
prof(G, "RejectBridgeCross", X_RJ - 20, -YF + 20, 1040, X_RJ + 20, YF - 20, 1080)
# cast angle brackets in the visible frame corners
EX, EZ, EY = V(1, 0, 0), V(0, 0, 1), V(0, 1, 0)
_k = 0
for s in (-1, 1):
y = s * YF
for x, dirs in [(P, (1,)), (XT0, (-1,)), (XT0 + P, (1,)), (XT1, (-1,)), (XT1 + P, (1,)), (L - P, (-1,))]:
for d in dirs:
gusset(G, f"Bracket{_k}", V(x, y, 140), EX * d, EZ, EY); _k += 1
for x, d, z in [(XT0 + P, 1, 1460), (XT1, -1, 1460), (XT0 + P, 1, 420), (XT1, -1, 420),
(XT1 + P, 1, 1040), (L - P, -1, 1040)]:
gusset(G, f"Bracket{_k}", V(x, y, z), EX * d, EZ * -1, EY); _k += 1
# ---------------------------------------------------------------- conveyor
G = "Conveyor"
for s in (-1, 1):
side = "F" if s < 0 else "B"
prof(G, f"Rail{side}", 0, s * 180 - 20, 830, L, s * 180 + 20, 870)
add(G, f"BeltSlideCarrier{side}", box(45, min(s * 140, s * 200), 870, L - 45, max(s * 140, s * 200), 880), DARK)
add(G, f"BeltSlide{side}", box(45, s * Y_BELT - 5, 880, L - 45, s * Y_BELT + 5, 894), UHMW)
add(G, f"BeltTop{side}", cyl(3, L - 40, V(20, s * Y_BELT, ZB - 3), V(1, 0, 0)), BELT)
add(G, f"BeltReturn{side}", cyl(3, L - 40, V(20, s * Y_BELT, ZB - 49), V(1, 0, 0)), BELT)
for x, nm in [(20, "Idler"), (L - 20, "Drive")]:
add(G, f"Pulley{nm}{side}", cyl(23, 14, V(x, s * Y_BELT - 7, ZB - 26), V(0, 1, 0)), DARK)
add(G, f"PulleyAxle{nm}{side}", cyl(6, 6, V(x, min(s * (Y_BELT + 6), s * 160), ZB - 26), V(0, 1, 0)), PNEU)
# infeed side guides with a flared mouth, PU strip on the rim height
add(G, f"SideGuide{side}", box(110, s * 157 - 3, ZB + 2, XT0 - 10, s * 157 + 3, ZB + 14), UHMW)
add(G, f"SideGuideFlare{side}", rot(box(40, s * 157 - 3, ZB + 2, 112, s * 157 + 3, ZB + 14),
V(110, s * 157, ZB), V(0, 0, 1), s * 25), UHMW)
add(G, f"GuidePost{side}", box(150, min(s * 160, s * 172), 870, 170, max(s * 160, s * 172), ZB + 14), DARK)
add(G, "DriveShaft", cyl(6, 2 * Y_BELT + 60, V(L - 20, -Y_BELT - 30, ZB - 26), V(0, 1, 0)), DARK)
add(G, "DriveGearmotor", cyl(35, 150, V(L - 20, 210, ZB - 26), V(0, 1, 0))
.fuse(box(L - 60, 200, ZB - 70, L + 15, 230, ZB + 15)), SERVO)
add(G, "EndStopBar", box(L - 30, -200, ZB + 30, L - 12, 200, ZB + 48), DARK)
for s in (-1, 1):
add(G, f"EndStopPost{'F' if s < 0 else 'B'}", box(L - 30, min(s * 170, s * 190), 870, L - 12, max(s * 170, s * 190), ZB + 30), DARK)
add(G, "EndStopBumper", box(L - 32, -40, ZB + 4, L - 26, 40, ZB + 30), (0.9, 0.5, 0.1))
# presence sensors (diffuse, looking up through the open centre) and the stop beam
G = "Sensors"
for x, nm in [(X_IN, "Infeed"), (X_LB - 120, "LabelTrigger"), (L - 120, "Outfeed")]:
add(G, f"Presence{nm}", box(x - 15, -120, 850, x + 15, -100, 885), (0.15, 0.35, 0.75))
add(G, f"PresenceBracket{nm}", box(x - 10, -160, 840, x + 10, -100, 850), DARK)
xs = X_IS + R_REC
for s in (-1, 1):
add(G, f"StopBeam{'Tx' if s < 0 else 'Rx'}", box(xs - 10, min(s * 200, s * 222), 870, xs + 10, max(s * 200, s * 222), ZB + 25),
(0.15, 0.35, 0.75))
add(G, "StopBeamRay", cyl(0.8, 400, V(xs, -200, ZB + 8), V(0, 1, 0)), LASER, 40)
# ---------------------------------------------------------------- label gate
G = "LabelGate"
add(G, "LabelCamTop", box(X_LB - 15, -15, ZB + WD_LABEL + 50, X_LB + 15, 15, ZB + WD_LABEL + 92), CAM)
add(G, "LabelLensTop", cyl(17, 50, V(X_LB, 0, ZB + WD_LABEL)), LENS)
add(G, "LabelRingTop", ring(70, 42, 22, V(X_LB, 0, ZB + 170)), LIGHTBODY)
add(G, "LabelRingTopFace", ring(62, 48, 1, V(X_LB, 0, ZB + 169)), LIGHT)
prof(G, "LabelCamTopPost", X_LB + 70, -20, ZB + 160, X_LB + 110, 20, 1460)
add(G, "LabelCamTopPlate", box(X_LB + 15, -12, ZB + WD_LABEL + 55, X_LB + 70, 12, ZB + WD_LABEL + 87), DARK)
add(G, "LabelRingTopClamp", box(X_LB + 58, -14, ZB + 166, X_LB + 70, 14, ZB + 196), DARK)
zl = ZB - WD_LABEL
add(G, "LabelCamBottom", box(X_LB - 15, -15, zl - 92, X_LB + 15, 15, zl - 50), CAM)
add(G, "LabelLensBottom", cyl(17, 50, V(X_LB, 0, zl - 50)), LENS)
add(G, "LabelRingBottom", ring(70, 42, 22, V(X_LB, 0, ZB - 80)), LIGHTBODY)
add(G, "LabelRingBottomFace", ring(62, 48, 1, V(X_LB, 0, ZB - 58)), LIGHT)
prof(G, "LabelCamBottomPost", X_LB + 70, -20, 460, X_LB + 110, 20, ZB - 48)
add(G, "LabelCamBottomPlate", box(X_LB + 15, -12, zl - 87, X_LB + 70, 12, zl - 55), DARK)
add(G, "LabelRingBottomClamp", box(X_LB + 58, -14, ZB - 84, X_LB + 70, 14, ZB - 54), DARK)
# ---------------------------------------------------------------- inspection: lift, clamp, one turn
G = "Chuck"
zp = ZL # pad top, lifted (shown lifted)
add(G, "ChuckPad", cyl(40, 10, V(X_IS, 0, zp - 10)), (0.85, 0.45, 0.10))
add(G, "ChuckMandrel", cyl(3.5, 9, V(X_IS, 0, zp)).fuse(Part.makeCone(3.5, 1.2, 4, V(X_IS, 0, zp + 9))), DARK)
add(G, "SpindleHousing", cyl(25, 110, V(X_IS, 0, zp - 120)), PNEU)
add(G, "LiftPlate", box(X_IS - 40, -40, zp - 132, X_IS + 40, 150, zp - 120), DARK)
add(G, "SpindleServo", cyl(30, 110, V(X_IS, 110, zp - 242)), SERVO)
add(G, "SpindleBeltCover", box(X_IS - 32, -32, zp - 120, X_IS + 32, 142, zp - 100), (0.3, 0.3, 0.32))
add(G, "LiftCylinderRods", cyl(6, 100, V(X_IS - 30, 0, zp - 232)).fuse(cyl(6, 100, V(X_IS + 30, 0, zp - 232))), PNEU)
add(G, "LiftCylinder", box(X_IS - 50, -25, zp - 322, X_IS + 50, 25, zp - 232), PNEU)
prof(G, "LiftPost", X_IS - 20, -20, 460, X_IS + 20, 20, zp - 322)
G = "LineScanTop"
zr = ZL + T_REC # top face of the lifted record
add(G, "LineCamTop", box(xt - 31, -31, zr + WD_LINE + 60, xt + 31, 31, zr + WD_LINE + 105), CAM)
add(G, "LineLensTop", cyl(25, 60, V(xt, 0, zr + WD_LINE)), LENS)
prof(G, "LineCamTopPost", xt + 48, -20, zr + 150, xt + 88, 20, 1460)
add(G, "LightHangerTop", box(xt + 58, -112, zr + 130, xt + 78, 112, zr + 150), DARK)
add(G, "CoaxHangerTop", box(xt + 58, -10, zr + 80, xt + 78, 10, zr + 130), DARK)
add(G, "LineCamTopPlate", box(xt + 31, -20, zr + WD_LINE + 62, xt + 48, 20, zr + WD_LINE + 103), DARK)
x0, x1 = TOP_LINE[0] - 5, TOP_LINE[1] + 5
add(G, "CoaxLightTop", box(x0, -30, zr + 50, x1, 30, zr + 110), LIGHTBODY)
add(G, "CoaxLightTopFace", box(x0 + 3, -26, zr + 49, x1 - 3, 26, zr + 50), LIGHT)
for s in (-1, 1):
b = box(x0, -15, 0, x1, 15, 30)
b.translate(V(0, s * 100, zr + 15))
add(G, f"DarkFieldTop{'F' if s < 0 else 'B'}", rot(b, V(0, s * 100, zr + 30), V(1, 0, 0), s * 20), LIGHTBODY)
add(G, f"DarkFieldTopBracket{'F' if s < 0 else 'B'}", box(xt + 58, s * 100 - 5, zr + 48, xt + 78, s * 100 + 5, zr + 130), DARK)
bx0, bx1 = BOT_LINE[0] - 5, BOT_LINE[1] + 5
add(G, "BacklightForBottomCam", box(bx0, -20, zr + 30, bx1, 20, zr + 52), LIGHTBODY)
add(G, "BacklightForBottomCamFace", box(bx0 + 3, -17, zr + 29, bx1 - 3, 17, zr + 30), LIGHT)
add(G, "BacklightBracketTop", box(xb - 30, -5, zr + 52, xb - 10, 5, 1460), DARK)
add(G, "ScanLineTop", box(TOP_LINE[0], -0.6, zr + 0.05, TOP_LINE[1], 0.6, zr + 0.5), LASER)
add(G, "ThermalPost", box(XT0 + 60, -240, 1400, XT0 + 80, -220, 1460), DARK)
add(G, "ThermalCam", rot(box(XT0 + 70, -260, 1380, XT0 + 130, -200, 1440), V(XT0 + 100, -230, 1410), V(1, 0, 0), -30), (0.95, 0.45, 0.10))
G = "LineScanBottom"
zu = ZL # underside of the lifted record
add(G, "LineCamBottom", box(xb - 31, -31, zu - WD_LINE - 105, xb + 31, 31, zu - WD_LINE - 60), CAM)
add(G, "LineLensBottom", cyl(25, 60, V(xb, 0, zu - WD_LINE - 60)), LENS)
prof(G, "LineCamBottomPost", xb - 20, 40, 460, xb + 20, 80, ZB - 20)
add(G, "CoaxHangerBottom", box(xb - 10, 30, ZB - 70, xb + 10, 40, ZB - 30), DARK)
add(G, "LineCamBottomPlate", box(xb - 20, 31, zu - WD_LINE - 105, xb + 20, 40, zu - WD_LINE - 60), DARK)
add(G, "CoaxLightBottom", box(bx0, -30, ZB - 80, bx1, 30, ZB - 20), LIGHTBODY)
add(G, "CoaxLightBottomFace", box(bx0 + 3, -26, ZB - 20, bx1 - 3, 26, ZB - 19), LIGHT)
for s in (-1, 1):
b = box(bx0, -15, 0, bx1, 15, 30)
b.translate(V(0, s * 175, zu - 40))
add(G, f"DarkFieldBottom{'F' if s < 0 else 'B'}", rot(b, V(0, s * 175, zu - 25), V(1, 0, 0), -s * 8), LIGHTBODY)
add(G, f"DarkFieldBottomBracket{'F' if s < 0 else 'B'}", box(bx0 + 40, s * 192 - 5, 870, bx0 + 60, s * 192 + 5, zu - 35), DARK)
add(G, "BacklightForTopCam", box(x0, -20, ZB - 40, x1, 20, ZB - 15), LIGHTBODY)
prof(G, "BacklightPost", xt - 20, -20, 460, xt + 20, 20, ZB - 40)
add(G, "BacklightForTopCamFace", box(x0 + 3, -17, ZB - 15, x1 - 3, 17, ZB - 14), LIGHT)
add(G, "ScanLineBottom", box(BOT_LINE[0], -0.6, zu - 0.5, BOT_LINE[1], 0.6, zu - 0.05), LASER)
G = "WarpLasers"
for r in (90, 130):
add(G, f"Laser_r{r}", box(X_IS - 23, -r - 10, ZB - 55, X_IS + 23, -r + 10, ZB - 15), (0.15, 0.35, 0.75))
add(G, f"LaserBeam_r{r}", cyl(0.8, zu - (ZB - 15), V(X_IS, -r, ZB - 15)), LASER, 30)
add(G, f"LaserBracket_r{r}", box(X_IS - 10, -r - 10, 830, X_IS + 10, -r + 10, ZB - 55), DARK)
prof(G, "LaserRail", X_IS - 20, -200, 790, X_IS + 20, -70, 830)
# ---------------------------------------------------------------- reject
G = "Reject"
add(G, "RodlessCylinder", box(X_RJ - 30, -300, 1000, X_RJ + 30, 300, 1040), PNEU)
yc = -205 # carriage retracted at the front
add(G, "PusherCarriage", box(X_RJ - 35, yc - 30, 960, X_RJ + 35, yc + 30, 1000), DARK)
add(G, "PusherArm", box(X_RJ - 10, yc - 10, ZB + 26, X_RJ + 10, yc + 10, 960), DARK)
add(G, "PusherPaddle", box(X_RJ - 100, yc + 10, ZB + 4, X_RJ + 100, yc + 22, ZB + 26), (0.9, 0.5, 0.1))
CX0, CX1 = X_RJ - 170, X_RJ + 170
Y_CH, Z_CH = 205, ZB - 7 # chute top edge: just outside the back rail, below the belt plane
chute = box(CX0, 0, 0, CX1, 360, 6)
chute = rot(chute, V(0, 0, 0), V(1, 0, 0), -42)
chute.translate(V(0, Y_CH, Z_CH))
add(G, "RejectChute", chute, (0.55, 0.57, 0.60))
for xw in (CX0 - 6, CX1):
w = box(xw, 0, 0, xw + 6, 360, 80)
w = rot(w, V(0, 0, 0), V(1, 0, 0), -42)
w.translate(V(0, Y_CH, Z_CH))
add(G, f"ChuteWall{xw}", w, (0.55, 0.57, 0.60))
import math
_zc = Z_CH - math.tan(math.radians(42)) * (YF + 20 - Y_CH) # chute underside above the back frame line
for i, xs_ in enumerate((CX0 + 10, CX1 - 50)):
prof(G, f"ChuteSupport{i}", xs_, YF - 20, 140, xs_ + 40, YF + 20, math.floor(_zc))
binb = box(CX0 - 20, 380, 0, CX1 + 20, 720, 560).cut(box(CX0 - 8, 392, 12, CX1 + 8, 708, 600))
add(G, "RejectBin", binb, (0.85, 0.20, 0.15), 20)
# ---------------------------------------------------------------- enclosure (black, light-tight tunnel)
G = "Enclosure"
slot = box(XT0 - 10, -205, 860, XT1 + P + 10, 205, ZB + 30)
for x, nm in [(XT0 - 3, "Infeed"), (XT1 + P, "Outfeed")]:
up = box(x, -YF - 22, 870, x + 3, YF + 22, 1500).cut(slot)
add(G, f"EndWallUpper{nm}", up, PANEL, 55)
lo = box(x, -YF - 22, 140, x + 3, YF + 22, 870).cut(box(x - 1, -205, 815, x + 4, 205, 880))
add(G, f"EndWallLower{nm}", lo, PANEL, 55)
for s in (-1, 1):
side = "Front" if s < 0 else "Back"
y0 = s * (YF + 20) if s > 0 else -YF - 23
add(G, f"Panel{side}Upper", box(XT0, y0, 870, XT1 + P, y0 + 3, 1500), PANEL, 55)
add(G, f"Panel{side}Lower", box(XT0, y0, 140, XT1 + P, y0 + 3, 870), PANEL, 55)
add(G, "PanelTop", box(XT0, -YF - 23, 1500, XT1 + P, YF + 23, 1503), PANEL, 55)
add(G, "PanelBottom", box(XT0, -YF - 20, 140, XT1 + P, YF + 20, 143), PANEL, 55)
add(G, "DoorHandle", box(700, -YF - 45, 1150, 860, -YF - 23, 1175), DARK)
add(G, "GuardRejectFront", box(XT1 + P, -YF - 23, 870, L, -YF - 20, 1100), CLEAR, 75)
add(G, "GuardRejectTop", box(XT1 + P, -YF - 23, 1100, L, YF + 23, 1103), CLEAR, 75)
# ---------------------------------------------------------------- electrical and operator
G = "Electrical"
add(G, "Cabinet", box(1180, -200, 140, 1640, 170, 750), CABINET)
add(G, "CabinetHandle", box(1600, -215, 400, 1615, -200, 520), DARK)
add(G, "StackLightPole", cyl(10, 123, V(XT1 + 20, YF, 1500)), DARK)
for i, c in enumerate([GREEN, AMBER, RED]):
add(G, f"StackLight{i}", cyl(25, 57, V(XT1 + 20, YF, 1623 + i * 57)), c)
add(G, "HMIArm", box(L - 40, -YF - 80, 1225, L, -YF - 20, 1245), DARK)
add(G, "HMI", rot(box(L - 260, -YF - 100, 1150, L, -YF - 80, 1320), V(L - 130, -YF - 90, 1235), V(1, 0, 0), -15), (0.10, 0.10, 0.12))
add(G, "EStopBox", box(XT1, -YF - 60, 930, XT1 + 80, -YF - 20, 1010), YELLOW)
add(G, "EStop", cyl(22, 25, V(XT1 + 40, -YF - 60, 970), V(0, -1, 0)), RED)
add(G, "ValveTerminal", box(XT0 + 80, YF + 20, 300, XT0 + 330, YF + 70, 380), PNEU)
add(G, "FRL", box(XT0 + 360, YF + 20, 280, XT0 + 440, YF + 80, 420), (0.2, 0.4, 0.8))
prof(G, "PneumaticsRail", XT0 + P, YF - 20, 260, XT1, YF + 20, 300)
# ---------------------------------------------------------------- records
G = "Records"
def record(name, x, y, z, label_color, body=BLACK, transp=0, tilt=None):
disc = cyl(R_REC, T_REC, V(x, y, z)).cut(cyl(R_HOLE, T_REC + 2, V(x, y, z - 1)))
lab = cyl(R_LABEL, 0.3, V(x, y, z + T_REC)).cut(cyl(R_HOLE, 2, V(x, y, z + T_REC - 0.5)))
labb = cyl(R_LABEL, 0.3, V(x, y, z - 0.3)).cut(cyl(R_HOLE, 2, V(x, y, z - 1)))
if tilt:
c, ax, deg = tilt
disc, lab, labb = rot(disc, c, ax, deg), rot(lab, c, ax, deg), rot(labb, c, ax, deg)
add(G, name, disc, body, transp)
add(G, name + "LabelA", lab, label_color)
add(G, name + "LabelB", labb, label_color)
record("RecordInfeed", X_IN, 0, ZB, (0.95, 0.85, 0.75), body=(0.80, 0.12, 0.16), transp=25) # translucent red special
record("RecordInspection", X_IS, 0, ZL, (0.20, 0.45, 0.80))
record("RecordOutfeed", X_OUT, 0, ZB, (0.95, 0.60, 0.15))
import math
sc, a = 200, math.radians(42)
yr = Y_CH + math.cos(a) * sc + 6 * math.sin(a)
zr2 = Z_CH - math.sin(a) * sc + 6 * math.cos(a)
record("RecordReject", X_RJ, yr, zr2, (0.6, 0.6, 0.6), tilt=(V(X_RJ, yr, zr2), V(1, 0, 0), -42))
doc.recompute()
doc.saveAs(OUT)
n = len([o for o in doc.Objects if o.TypeId == "Part::Feature"])
bb = None
for o in doc.Objects:
if o.TypeId == "Part::Feature":
bb = o.Shape.BoundBox if bb is None else bb.united(o.Shape.BoundBox)
print("objects", n, "bbox", round(bb.XMin), round(bb.XMax), round(bb.YMin), round(bb.YMax), round(bb.ZMin), round(bb.ZMax))
print("saved", OUT)
# every part should touch another one, without counting the panels (hidden in the open views);
# list the ones that do not (gap > 1 mm)
_panels = set(o.Name for o in groups["Enclosure"].Group)
_parts = [o for o in doc.Objects if o.TypeId == "Part::Feature" and o.Name not in _panels]
# connectivity: every part must reach the floor through touching parts (gap <= 1 mm)
_adj = {o.Name: set() for o in _parts}
for ia, oa in enumerate(_parts):
ba = oa.Shape.BoundBox
for ob in _parts[ia + 1:]:
bq = ob.Shape.BoundBox
if (bq.XMin > ba.XMax + 2 or bq.XMax < ba.XMin - 2 or bq.YMin > ba.YMax + 2 or bq.YMax < ba.YMin - 2
or bq.ZMin > ba.ZMax + 2 or bq.ZMax < ba.ZMin - 2):
continue
if oa.Shape.distToShape(ob.Shape)[0] <= 1.0:
_adj[oa.Name].add(ob.Name)
_adj[ob.Name].add(oa.Name)
_seen = [o.Name for o in _parts if o.Shape.BoundBox.ZMin < 1]
_todo = list(_seen)
_seen = set(_seen)
while _todo:
for nb in _adj[_todo.pop()]:
if nb not in _seen:
_seen.add(nb)
_todo.append(nb)
_floating = sorted(n for n in _adj if n not in _seen)
print("parts not connected to the floor:", _floating if _floating else "none")
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

@@ -0,0 +1,42 @@
group,item,qty,example,unit_usd_low,unit_usd_high,line_usd_low,line_usd_high,source
Frame,"40x40 slot profile, cut to length",32 m (45 pieces),"8-slot 4040 (Misumi HFS8-4040 class, or Thai/Chinese generic)",11,21,354,676,per m; Shopee Thailand listing from THB 356; aluxprofile EUR 19 to 24 per m
Frame,"40x80 slot profile, base beams",3.8 m (2 pieces),8-slot 4080,22,42,84,160,"per m; estimate, about twice the 4040 price"
Frame,"Cast angle brackets (24 drawn), T-nuts, screws, end caps",1 lot,,250,600,250,600,estimate
Frame,Levelling feet M16,8,,8,25,64,200,each; estimate
Enclosure,"Black panels, 4 mm ACM or PP, light-tight tunnel",4.3 m2,,25,60,108,258,per m2; estimate
Enclosure,"Clear polycarbonate guard, reject zone",1.4 m2,,30,70,42,98,per m2; estimate
Enclosure,"Door hinges, handle, safety door switch",1 lot,,120,350,120,350,estimate
Conveyor,"PU round belt 6 mm, welded endless",2 x 3.8 m,,15,40,30,80,"each; PU round belt listings (RS, Amazon) plus welding"
Conveyor,"Round-belt pulleys, shaft, bearings, UHMW slide strips, side guides",1 lot,,250,700,250,700,"pulleys USD 5 to 11 each (ServoCity, REV); rest estimate"
Conveyor,"Conveyor drive: 100 W EtherCAT servo kit (same as the spindle), cyclic synchronous velocity",1,StepperOnline A6-EC100L2A1-M17,123,300,123,300,"USD 123.29 kit, China warehouse (StepperOnline, Oct 2026); high end allows for shipping, duty and a small belt reduction (estimate)"
Handling,"Guided lift cylinder, 20 mm bore, 75 mm stroke",1,SMC MGPM20-75,330,450,330,450,SMC MGPM20-30 USD 322 (Misumi US) to 390 (Motion); 75 mm stroke a little more
Handling,"Spindle servo kit 100 W, EtherCAT (A6-200EC drive), cyclic synchronous position; 1:6 timing belt to the spindle",1,StepperOnline A6-EC100L2A1-M17,123,300,123,300,"USD 123.29 kit, China warehouse (StepperOnline, Oct 2026); high end allows for shipping and duty (estimate)"
Handling,"Spindle head: bearing housing, timing belt, label pad, pneumatic expanding mandrel",1,machined parts,600,1800,600,1800,estimate
Handling,"Rodless cylinder 25 mm, 350 mm stroke, with paddle",1,SMC MY1B / CY3B class,400,900,400,900,estimate
Handling,"Valve terminal, FRL with a dump valve switched by the safety relay, pressure switch, tubing, fittings",1 lot,,400,1000,400,1000,estimate
Vision,"4k monochrome line-scan camera, GigE",2,Basler racer 2 r2L4096 / Hikrobot MV-CL042-91GM,857,1088,1714,2176,Basler web shop via price listing
Vision,"Line-scan lens, 50 mm",2,,300,800,600,1600,estimate
Vision,Coaxial line light,2,,295,446,590,892,made-in-china listing USD 295 to 349; Vision Datum USD 420; light186 from USD 446
Vision,"Dark-field line light, about 150 mm",4,Vision Datum LiN+ class,250,400,1000,1600,Vision Datum LiN+ USD 380
Vision,Diffuse line backlight,2,,200,400,400,800,estimate
Vision,"Colour area camera, 8 MP, GigE",2,Basler ace 2 a2A2840-14gcPRO,1119,1119,2238,2238,Basler web shop via price listing
Vision,Lens 16 mm,2,,150,400,300,800,estimate
Vision,Ring light,2,,150,400,300,800,estimate
Vision,Strobe and light controllers,2,,300,800,600,1600,estimate
Sensors,"Laser distance sensor, 50 mm range",2,Micro-Epsilon optoNCDT 1420,520,1600,1040,3200,"list from EUR 470 (Micro-Epsilon); ILD1420-25 about USD 1,600 (Radwell)"
Sensors,Photoelectric presence sensors and one through-beam (the through-beam also to the conveyor drive's touch probe),5,,50,150,250,750,each; estimate
Sensors,"Cylinder position switches (lift up/down, pusher home/out, mandrel open/clamped)",6,SMC D-M9 class,25,60,150,360,each; estimate
Sensors,"Spindle incremental encoder, RS-422 line driver, 5 V, 2,000 to 2,500 pulses a turn: A/B clock both line-scans, A/B/Z to the EL5101",1,Omron E6B2-CWZ1X 2000 P/R class,53,282,53,282,"E6B2-CWZ1X 2000 P/R listing EUR 45.52 to GHH60 2500 P/R line driver EUR 187.83 (geizhals.de, 19 Oct 2026, lowest listed price incl. 19% German VAT; marketplace sellers, test on the bench); high end +30% for shipping, Thai duty and VAT or a Thai distributor (estimate)"
Sensors,"Thermal camera (option, not in the total)",0 (1 optional),Optris Xi 400,2100,3000,0,0,"from EUR 1,950 (Optris); USD 2,995 (moviTHERM)"
Control,"EtherCAT station controller: fanless mini PC, Intel N100, 2 or more Intel i226-V ports, NixOS real-time tuned, station service on QiTech's open-source EtherCAT library (EtherCrab based; IgH fallback)",1,ANDAQI RS55 / MNBOXCONET P2-N100 / AIOPCWA AI201-TF,455,685,455,685,"EUR 393.99 to 455.99 (geizhals.de, 19 Oct 2026, lowest listed price incl. 19% German VAT: geizhals.de/mini-pc-barebone-netzwerk-pc-intel-n100-a2926989.html); high end +30% for shipping, Thai duty and VAT or a Thai distributor (estimate)"
Control,EtherCAT coupler (the EK1101 adds an ID switch),1,Beckhoff EK1101,98,128,98,128,"EUR 85.13, 148 in stock (QiTech community shop (shop.qitech.de, new in original box from an insolvency, 19 Oct 2026, incl. 19% German VAT: shop.qitech.de/products/beckhoff-ek1101); high end +30% for shipping from Darmstadt and Thai duty and VAT (estimate)"
Control,"16 digital inputs, 24 V: photoelectric sensors, cylinder switches, safety status",1,Beckhoff EL1809,19,25,19,25,"EUR 16.53, 157 in stock (QiTech community shop (shop.qitech.de, new in original box from an insolvency, 19 Oct 2026, incl. 19% German VAT: shop.qitech.de/products/beckhoff-el1809); high end +30% for shipping from Darmstadt and Thai duty and VAT (estimate)"
Control,"16 digital outputs, 24 V, 0.5 A: valves, stack light, light enable",1,Beckhoff EL2809,47,62,47,62,"EUR 41.03, 104 in stock (QiTech community shop (shop.qitech.de, new in original box from an insolvency, 19 Oct 2026, incl. 19% German VAT: shop.qitech.de/products/beckhoff-el2809); high end +30% for shipping from Darmstadt and Thai duty and VAT (estimate)"
Control,"2 analog inputs, 4 to 20 mA: the two warp lasers",1,Beckhoff EL3152,241,314,241,314,"EUR 208.90 (geizhals.de, 19 Oct 2026, lowest listed price incl. 19% German VAT: geizhals.de/185886294); high end +30% for shipping, Thai duty and VAT or a Thai distributor (estimate)"
Control,"Incremental encoder interface, RS-422, 5 V encoder supply: spindle encoder count and index latch",1,Beckhoff EL5101,336,437,336,437,"EUR 291.04 (geizhals.de, 19 Oct 2026, lowest listed price incl. 19% German VAT: geizhals.de/2974477757); high end +30% for shipping, Thai duty and VAT or a Thai distributor (estimate)"
Control,End cap,1,Beckhoff EL9011,2,3,2,3,"EUR 1.76, 131 in stock (QiTech community shop (shop.qitech.de, new in original box from an insolvency, 19 Oct 2026, incl. 19% German VAT: shop.qitech.de/products/beckhoff-el9011); high end +30% for shipping from Darmstadt and Thai duty and VAT (estimate)"
Control,"Edge PC with GPU, 4 GigE PoE ports, NixOS",1,,1500,3200,1500,3200,"qscompute buying guides 2026: USD 1,490 to 3,200"
Control,"HMI: 10.1 inch PCAP touch monitor, 7H glass, showing the station's browser page",1,iiyama ProLite TF1015MC-B3,360,468,360,468,"EUR 311.90 (geizhals.de, 19 Oct 2026, lowest listed price incl. 19% German VAT: geizhals.de/iiyama-prolite-tf1015mc-b3-a3228748.html); high end +30% for shipping, Thai duty and VAT or a Thai distributor (estimate)"
Control,"Safety: relay for e-stop and door switch, 2 contactors in series in the drive supply (the 100 W kit has no STO), e-stop button, reset button",1 lot,"Pilz PNOZ s3 750103, Siemens 3RT2015 24 V DC coil, Schneider Harmony e-stop",300,389,300,389,"PNOZ s3 EUR 148.38, 3RT2015-1BB41 EUR 27.95 each, e-stop EUR 45.08 (geizhals.de, 19 Oct 2026, lowest listed price incl. 19% German VAT); reset button EUR 10 (estimate); high end +30% for shipping, Thai duty and VAT or a Thai distributor (estimate)"
Control,"Cabinet, 24 V 120 W supply, breakers, terminals, wiring, shielded EtherCAT patch cables, stack light",1 lot,Mean Well SDR-120-24 supply,800,2000,800,2000,"estimate; Mean Well SDR-120-24 from EUR 38.87 and shielded Cat5e patch cables from EUR 0.62 (geizhals.de, 19 Oct 2026)"
Total,"Hardware per station, thermal camera excluded",,,,,16671,32681,sum of the lines above
1 group item qty example unit_usd_low unit_usd_high line_usd_low line_usd_high source
2 Frame 40x40 slot profile, cut to length 32 m (45 pieces) 8-slot 4040 (Misumi HFS8-4040 class, or Thai/Chinese generic) 11 21 354 676 per m; Shopee Thailand listing from THB 356; aluxprofile EUR 19 to 24 per m
3 Frame 40x80 slot profile, base beams 3.8 m (2 pieces) 8-slot 4080 22 42 84 160 per m; estimate, about twice the 4040 price
4 Frame Cast angle brackets (24 drawn), T-nuts, screws, end caps 1 lot 250 600 250 600 estimate
5 Frame Levelling feet M16 8 8 25 64 200 each; estimate
6 Enclosure Black panels, 4 mm ACM or PP, light-tight tunnel 4.3 m2 25 60 108 258 per m2; estimate
7 Enclosure Clear polycarbonate guard, reject zone 1.4 m2 30 70 42 98 per m2; estimate
8 Enclosure Door hinges, handle, safety door switch 1 lot 120 350 120 350 estimate
9 Conveyor PU round belt 6 mm, welded endless 2 x 3.8 m 15 40 30 80 each; PU round belt listings (RS, Amazon) plus welding
10 Conveyor Round-belt pulleys, shaft, bearings, UHMW slide strips, side guides 1 lot 250 700 250 700 pulleys USD 5 to 11 each (ServoCity, REV); rest estimate
11 Conveyor Conveyor drive: 100 W EtherCAT servo kit (same as the spindle), cyclic synchronous velocity 1 StepperOnline A6-EC100L2A1-M17 123 300 123 300 USD 123.29 kit, China warehouse (StepperOnline, Oct 2026); high end allows for shipping, duty and a small belt reduction (estimate)
12 Handling Guided lift cylinder, 20 mm bore, 75 mm stroke 1 SMC MGPM20-75 330 450 330 450 SMC MGPM20-30 USD 322 (Misumi US) to 390 (Motion); 75 mm stroke a little more
13 Handling Spindle servo kit 100 W, EtherCAT (A6-200EC drive), cyclic synchronous position; 1:6 timing belt to the spindle 1 StepperOnline A6-EC100L2A1-M17 123 300 123 300 USD 123.29 kit, China warehouse (StepperOnline, Oct 2026); high end allows for shipping and duty (estimate)
14 Handling Spindle head: bearing housing, timing belt, label pad, pneumatic expanding mandrel 1 machined parts 600 1800 600 1800 estimate
15 Handling Rodless cylinder 25 mm, 350 mm stroke, with paddle 1 SMC MY1B / CY3B class 400 900 400 900 estimate
16 Handling Valve terminal, FRL with a dump valve switched by the safety relay, pressure switch, tubing, fittings 1 lot 400 1000 400 1000 estimate
17 Vision 4k monochrome line-scan camera, GigE 2 Basler racer 2 r2L4096 / Hikrobot MV-CL042-91GM 857 1088 1714 2176 Basler web shop via price listing
18 Vision Line-scan lens, 50 mm 2 300 800 600 1600 estimate
19 Vision Coaxial line light 2 295 446 590 892 made-in-china listing USD 295 to 349; Vision Datum USD 420; light186 from USD 446
20 Vision Dark-field line light, about 150 mm 4 Vision Datum LiN+ class 250 400 1000 1600 Vision Datum LiN+ USD 380
21 Vision Diffuse line backlight 2 200 400 400 800 estimate
22 Vision Colour area camera, 8 MP, GigE 2 Basler ace 2 a2A2840-14gcPRO 1119 1119 2238 2238 Basler web shop via price listing
23 Vision Lens 16 mm 2 150 400 300 800 estimate
24 Vision Ring light 2 150 400 300 800 estimate
25 Vision Strobe and light controllers 2 300 800 600 1600 estimate
26 Sensors Laser distance sensor, 50 mm range 2 Micro-Epsilon optoNCDT 1420 520 1600 1040 3200 list from EUR 470 (Micro-Epsilon); ILD1420-25 about USD 1,600 (Radwell)
27 Sensors Photoelectric presence sensors and one through-beam (the through-beam also to the conveyor drive's touch probe) 5 50 150 250 750 each; estimate
28 Sensors Cylinder position switches (lift up/down, pusher home/out, mandrel open/clamped) 6 SMC D-M9 class 25 60 150 360 each; estimate
29 Sensors Spindle incremental encoder, RS-422 line driver, 5 V, 2,000 to 2,500 pulses a turn: A/B clock both line-scans, A/B/Z to the EL5101 1 Omron E6B2-CWZ1X 2000 P/R class 53 282 53 282 E6B2-CWZ1X 2000 P/R listing EUR 45.52 to GHH60 2500 P/R line driver EUR 187.83 (geizhals.de, 19 Oct 2026, lowest listed price incl. 19% German VAT; marketplace sellers, test on the bench); high end +30% for shipping, Thai duty and VAT or a Thai distributor (estimate)
30 Sensors Thermal camera (option, not in the total) 0 (1 optional) Optris Xi 400 2100 3000 0 0 from EUR 1,950 (Optris); USD 2,995 (moviTHERM)
31 Control EtherCAT station controller: fanless mini PC, Intel N100, 2 or more Intel i226-V ports, NixOS real-time tuned, station service on QiTech's open-source EtherCAT library (EtherCrab based; IgH fallback) 1 ANDAQI RS55 / MNBOXCONET P2-N100 / AIOPCWA AI201-TF 455 685 455 685 EUR 393.99 to 455.99 (geizhals.de, 19 Oct 2026, lowest listed price incl. 19% German VAT: geizhals.de/mini-pc-barebone-netzwerk-pc-intel-n100-a2926989.html); high end +30% for shipping, Thai duty and VAT or a Thai distributor (estimate)
32 Control EtherCAT coupler (the EK1101 adds an ID switch) 1 Beckhoff EK1101 98 128 98 128 EUR 85.13, 148 in stock (QiTech community shop (shop.qitech.de, new in original box from an insolvency, 19 Oct 2026, incl. 19% German VAT: shop.qitech.de/products/beckhoff-ek1101); high end +30% for shipping from Darmstadt and Thai duty and VAT (estimate)
33 Control 16 digital inputs, 24 V: photoelectric sensors, cylinder switches, safety status 1 Beckhoff EL1809 19 25 19 25 EUR 16.53, 157 in stock (QiTech community shop (shop.qitech.de, new in original box from an insolvency, 19 Oct 2026, incl. 19% German VAT: shop.qitech.de/products/beckhoff-el1809); high end +30% for shipping from Darmstadt and Thai duty and VAT (estimate)
34 Control 16 digital outputs, 24 V, 0.5 A: valves, stack light, light enable 1 Beckhoff EL2809 47 62 47 62 EUR 41.03, 104 in stock (QiTech community shop (shop.qitech.de, new in original box from an insolvency, 19 Oct 2026, incl. 19% German VAT: shop.qitech.de/products/beckhoff-el2809); high end +30% for shipping from Darmstadt and Thai duty and VAT (estimate)
35 Control 2 analog inputs, 4 to 20 mA: the two warp lasers 1 Beckhoff EL3152 241 314 241 314 EUR 208.90 (geizhals.de, 19 Oct 2026, lowest listed price incl. 19% German VAT: geizhals.de/185886294); high end +30% for shipping, Thai duty and VAT or a Thai distributor (estimate)
36 Control Incremental encoder interface, RS-422, 5 V encoder supply: spindle encoder count and index latch 1 Beckhoff EL5101 336 437 336 437 EUR 291.04 (geizhals.de, 19 Oct 2026, lowest listed price incl. 19% German VAT: geizhals.de/2974477757); high end +30% for shipping, Thai duty and VAT or a Thai distributor (estimate)
37 Control End cap 1 Beckhoff EL9011 2 3 2 3 EUR 1.76, 131 in stock (QiTech community shop (shop.qitech.de, new in original box from an insolvency, 19 Oct 2026, incl. 19% German VAT: shop.qitech.de/products/beckhoff-el9011); high end +30% for shipping from Darmstadt and Thai duty and VAT (estimate)
38 Control Edge PC with GPU, 4 GigE PoE ports, NixOS 1 1500 3200 1500 3200 qscompute buying guides 2026: USD 1,490 to 3,200
39 Control HMI: 10.1 inch PCAP touch monitor, 7H glass, showing the station's browser page 1 iiyama ProLite TF1015MC-B3 360 468 360 468 EUR 311.90 (geizhals.de, 19 Oct 2026, lowest listed price incl. 19% German VAT: geizhals.de/iiyama-prolite-tf1015mc-b3-a3228748.html); high end +30% for shipping, Thai duty and VAT or a Thai distributor (estimate)
40 Control Safety: relay for e-stop and door switch, 2 contactors in series in the drive supply (the 100 W kit has no STO), e-stop button, reset button 1 lot Pilz PNOZ s3 750103, Siemens 3RT2015 24 V DC coil, Schneider Harmony e-stop 300 389 300 389 PNOZ s3 EUR 148.38, 3RT2015-1BB41 EUR 27.95 each, e-stop EUR 45.08 (geizhals.de, 19 Oct 2026, lowest listed price incl. 19% German VAT); reset button EUR 10 (estimate); high end +30% for shipping, Thai duty and VAT or a Thai distributor (estimate)
41 Control Cabinet, 24 V 120 W supply, breakers, terminals, wiring, shielded EtherCAT patch cables, stack light 1 lot Mean Well SDR-120-24 supply 800 2000 800 2000 estimate; Mean Well SDR-120-24 from EUR 38.87 and shielded Cat5e patch cables from EUR 0.62 (geizhals.de, 19 Oct 2026)
42 Total Hardware per station, thermal camera excluded 16671 32681 sum of the lines above
Binary file not shown.

After

Width:  |  Height:  |  Size: 443 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

@@ -0,0 +1,160 @@
# Render the investor view of the inline QC station and the screen positions of
# the parts to call out (run in the FreeCAD GUI after build_station.py):
# exec(open(r"C:/dev/cnx_vinyl/docs/equipment/inline-qc-station/render_annotated.py", encoding="utf-8").read())
# Writes inline-qc-station-annotated-base.png, a check image with magenta markers,
# and anchors.json; annotate_render.py (Pillow) then draws the labels.
import json
import os
import FreeCAD as App
import FreeCADGui as Gui
import Part
from pivy import coin
OUTDIR = r"C:/dev/cnx_vinyl/docs/equipment/inline-qc-station"
W, H = 4000, 3000
V = App.Vector
# (key, 3D point on a face turned to the camera, title, one-line description)
ANCHORS = [
("frame", V(340, -320, 1150), "Aluminium profile frame", "40 × 40 mm slot profile, 1.9 × 0.65 × 1.5 m"),
("belts", V(70, -151.5, 897), "Rim-belt conveyor", "touches only the record's edge, never a groove"),
("infeed", V(200, -80, 902.5), "Infeed", "the operator sets each cooled record down"),
("label", V(520, -15, 1275), "Label cameras, top and bottom", "right label, right side, centred"),
("tunnel", V(820, 319, 1100), "Light-tight tunnel", "black panels keep factory light out"),
("lscan_top", V(975, -31, 1385), "Line-scan camera, top", "images a full radius while the record turns once"),
("lights", V(935, -30, 1042), "Inspection lights", "coaxial, low-angle dark-field and backlight"),
("chuck", V(880, -25, 690), "Lift-and-turn chuck", "lifts the record 75 mm, one turn in about 1 s"),
("lscan_bot", V(778, -31, 547), "Line-scan camera, bottom", "the underside, in the same turn"),
("lasers", V(880, -130, 925), "Laser warp sensors", "edge run-out and dish, to 0.1 mm"),
("pusher", V(1320, -300, 1020), "Reject pusher", "pushes a failed record down a chute into the bin behind"),
("outfeed", V(1715, -140, 902), "Outfeed", "good records wait for sleeving"),
("cabinet", V(1420, -200, 450), "Control cabinet", "EtherCAT controller, drives and the NixOS edge PC"),
("hmi", V(1770, -404, 1235), "Touch screen", "every verdict with its reason"),
("estop", V(1140, -386, 970), "Emergency stop", "and a safety switch on the tunnel door"),
("stack", V(1120, 274, 1720), "Stack light", "green: pass, red: reject"),
]
AZ, EL = 12.0, 28.0 # camera from the front, 12 deg to the right, 28 deg above
doc = App.getDocument("InlineQCStation")
Gui.setActiveDocument(doc.Name)
view = Gui.getDocument(doc.Name).ActiveView
try:
view.setCameraType("Orthographic")
except Exception:
pass
_vp = App.ParamGet("User parameter:BaseApp/Preferences/View")
_navi_before = _vp.GetBool("ShowNaviCube", True)
_vp.SetBool("ShowNaviCube", False)
_anim_before = _vp.GetBool("UseNavigationAnimations", True)
_vp.SetBool("UseNavigationAnimations", False)
_presel_before = _vp.GetBool("EnablePreselection", True)
_vp.SetBool("EnablePreselection", False) # no hover highlight in the pictures
Gui.Selection.clearPreselection()
Gui.Selection.clearSelection()
def back_off(v, dist=8000):
"""Move the orthographic camera back along its axis so nothing sits behind the near plane."""
c = v.getCameraNode()
d = c.orientation.getValue().multVec(coin.SbVec3f(0, 0, -1))
c.position.setValue(c.position.getValue() - d * dist)
c.nearDistance.setValue(100)
c.farDistance.setValue(dist * 4)
Gui.updateGui()
open_view_hidden = ["PanelTop", "PanelFrontUpper", "PanelFrontLower", "GuardRejectFront", "GuardRejectTop",
"DoorHandle", "ThermalCam", "ThermalPost"]
for o in doc.Objects:
if o.TypeId == "Part::Feature":
o.ViewObject.Visibility = o.Name not in open_view_hidden
for o in doc.getObject("Enclosure").Group:
o.ViewObject.Transparency = 45
import math
def set_camera(az, el, margin=1.04):
"""Orthographic camera looking at the whole model from the front, az to the right, el above."""
a, e = math.radians(az), math.radians(el)
tv = V(math.sin(a) * math.cos(e), -math.cos(a) * math.cos(e), math.sin(e)) # towards the viewer
d = tv * -1
right = d.cross(V(0, 0, 1)).normalize()
up = right.cross(d).normalize()
m = App.Matrix(right.x, up.x, -d.x, 0, right.y, up.y, -d.y, 0, right.z, up.z, -d.z, 0, 0, 0, 0, 1)
rot = App.Rotation(m)
bb = None
for o in doc.Objects:
if o.TypeId == "Part::Feature" and o.ViewObject.Visibility:
bb = o.Shape.BoundBox if bb is None else bb.united(o.Shape.BoundBox)
corners = [V(x, y, z) for x in (bb.XMin, bb.XMax) for y in (bb.YMin, bb.YMax) for z in (bb.ZMin, bb.ZMax)]
us = [c.dot(right) for c in corners]
vs = [c.dot(up) for c in corners]
cu, cv = (min(us) + max(us)) / 2, (min(vs) + max(vs)) / 2
centre = right * cu + up * cv + d * (bb.Center.dot(d))
hgt = max(max(vs) - min(vs), (max(us) - min(us)) * H / W) * margin
cam = view.getCameraNode()
cam.orientation.setValue(*rot.Q)
pos = centre + tv * 8000
cam.position.setValue(pos.x, pos.y, pos.z)
cam.height.setValue(hgt)
cam.focalDistance.setValue(8000)
cam.nearDistance.setValue(100)
cam.farDistance.setValue(32000)
Gui.updateGui()
set_camera(AZ, EL)
base = os.path.join(OUTDIR, "inline-qc-station-annotated-base.png")
view.saveImage(base, W, H, "White")
cam = view.getCameraNode()
pos = cam.position.getValue()
inv = cam.orientation.getValue().inverse()
hgt = cam.height.getValue()
def project(p):
c = inv.multVec(coin.SbVec3f(p.x - pos[0], p.y - pos[1], p.z - pos[2]))
s = H / hgt if W >= H else W / hgt
return [W / 2 + c[0] * s, H / 2 - c[1] * s]
out = {"size": [W, H], "anchors": []}
for key, p, title, desc in ANCHORS:
out["anchors"].append({"key": key, "xy": project(p), "title": title, "desc": desc})
# check image: the same view with a magenta ball on every anchor (shows position and occlusion)
balls = []
for key, p, *_ in ANCHORS:
b = doc.addObject("Part::Feature", "Marker_" + key)
b.Shape = Part.makeSphere(9, p)
b.ViewObject.ShapeColor = (1.0, 0.0, 1.0)
b.ViewObject.LineColor = (1.0, 0.0, 1.0)
balls.append(b)
Gui.updateGui()
view.saveImage(os.path.join(OUTDIR, "_markers-check.png"), W, H, "White")
# markers alone, nothing in front of them: exact screen positions (camera unchanged)
_vis = {o.Name: o.ViewObject.Visibility for o in doc.Objects if o.TypeId == "Part::Feature"}
for o in doc.Objects:
if o.TypeId == "Part::Feature" and not o.Name.startswith("Marker_"):
o.ViewObject.Visibility = False
for b in balls:
b.ViewObject.Visibility = True
Gui.updateGui()
view.saveImage(os.path.join(OUTDIR, "_markers-only.png"), W, H, "White")
for n, v in _vis.items():
if not n.startswith("Marker_"):
doc.getObject(n).ViewObject.Visibility = v
for b in balls:
doc.removeObject(b.Name)
for o in doc.getObject("Enclosure").Group:
o.ViewObject.Transparency = 55 if o.Name not in ("GuardRejectFront", "GuardRejectTop") else 75
for o in doc.Objects:
if o.TypeId == "Part::Feature":
o.ViewObject.Visibility = True
_vp.SetBool("ShowNaviCube", _navi_before)
_vp.SetBool("UseNavigationAnimations", _anim_before)
_vp.SetBool("EnablePreselection", _presel_before)
json.dump(out, open(os.path.join(OUTDIR, "_anchors.json"), "w", encoding="utf-8"), ensure_ascii=False, indent=1)
print("saved", base)
@@ -0,0 +1,152 @@
# Render the inline QC station views (run in the FreeCAD GUI after build_station.py).
# exec(open(r"C:/dev/cnx_vinyl/docs/equipment/inline-qc-station/render_station.py", encoding="utf-8").read())
# Detail views are rendered from a temporary document holding the model clipped
# to a box (Part common), because coin clip planes did not reach the render here.
import os
import FreeCAD as App
import FreeCADGui as Gui
import Part
OUTDIR = r"C:/dev/cnx_vinyl/docs/equipment/inline-qc-station"
doc = App.getDocument("InlineQCStation")
_vp = App.ParamGet("User parameter:BaseApp/Preferences/View")
_navi_before = _vp.GetBool("ShowNaviCube", True)
_vp.SetBool("ShowNaviCube", False)
_anim_before = _vp.GetBool("UseNavigationAnimations", True)
_vp.SetBool("UseNavigationAnimations", False)
_presel_before = _vp.GetBool("EnablePreselection", True)
_vp.SetBool("EnablePreselection", False)
Gui.Selection.clearPreselection()
Gui.Selection.clearSelection()
from pivy import coin
def prep(d):
Gui.setActiveDocument(d.Name)
v = Gui.getDocument(d.Name).ActiveView
try:
v.setCameraType("Orthographic")
except Exception:
pass
for m in ("setNavigationCubeVisible", "setCornerCrossVisible"):
if hasattr(v, m):
getattr(v, m)(False)
return v
def members(group):
g = doc.getObject(group)
return list(g.Group) if g else []
def show_all():
for o in doc.Objects:
if o.TypeId == "Part::Feature":
o.ViewObject.Visibility = True
def hide(groups=(), names=()):
for gname in groups:
for o in members(gname):
o.ViewObject.Visibility = False
for n in names:
o = doc.getObject(n)
if o:
o.ViewObject.Visibility = False
def shoot(v, fname, orient, w=3200, h=2400):
getattr(v, orient)()
Gui.updateGui()
v.fitAll()
Gui.updateGui()
# move the orthographic camera well back so no part sits behind the near plane
c = v.getCameraNode()
d = c.orientation.getValue().multVec(coin.SbVec3f(0, 0, -1))
c.position.setValue(c.position.getValue() - d * 8000)
c.nearDistance.setValue(100)
c.farDistance.setValue(32000)
Gui.updateGui()
path = os.path.join(OUTDIR, fname)
v.saveImage(path, w, h, "White")
print("saved", path)
def clipped_doc(name, clipbox, skip_groups=()):
skip = set()
for gname in skip_groups:
skip.update(o.Name for o in members(gname))
d = App.newDocument(name)
for o in doc.Objects:
if o.TypeId != "Part::Feature" or o.Name in skip:
continue
s = o.Shape.common(clipbox)
if s.isNull() or s.Volume < 1e-3:
continue
n = d.addObject("Part::Feature", o.Name)
n.Shape = s
n.ViewObject.ShapeColor = o.ViewObject.ShapeColor
n.ViewObject.Transparency = o.ViewObject.Transparency
n.ViewObject.LineColor = o.ViewObject.LineColor
d.recompute()
return d
view = prep(doc)
enclosure_tops = ["PanelTop", "PanelFrontUpper", "PanelFrontLower", "GuardRejectFront", "GuardRejectTop", "DoorHandle"]
# 1 open iso: front panels and lid off, the rest of the enclosure translucent
show_all()
hide(names=enclosure_tops)
shoot(view, "inline-qc-station-iso.png", "viewIsometric")
# 2 closed iso: as it stands in the hall
show_all()
for o in members("Enclosure"):
o.ViewObject.Transparency = 15 if o.Name not in ("GuardRejectFront", "GuardRejectTop") else 70
shoot(view, "inline-qc-station-closed.png", "viewIsometric")
for o in members("Enclosure"):
o.ViewObject.Transparency = 55 if o.Name not in ("GuardRejectFront", "GuardRejectTop") else 75
# 3 front elevation without the front panels
show_all()
hide(names=enclosure_tops)
shoot(view, "inline-qc-station-front.png", "viewFront")
# 4 plan view without the lid and the top bridge
show_all()
hide(names=enclosure_tops + ["TopBeamF", "TopBeamB", "TopCrossLabel", "TopCrossLineScan", "TopCrossThermal",
"TopCrossBacklight", "RejectBridgeCross", "RodlessCylinder", "PusherCarriage",
"LabelCamTop", "LabelCamTopPost", "LabelCamTopPlate", "LineCamTop", "LineCamTopPost",
"LineCamTopPlate", "LightHangerTop", "CoaxHangerTop", "CoaxLightTop", "CoaxLightTopFace",
"BacklightForBottomCam", "BacklightForBottomCamFace", "BacklightBracketTop",
"LabelRingTop", "LabelRingTopFace", "ThermalCam", "ThermalPost",
"DarkFieldTopF", "DarkFieldTopB", "DarkFieldTopBracketF", "DarkFieldTopBracketB",
"StackLight0", "StackLight1", "StackLight2", "StackLightPole", "HMI", "HMIArm"])
shoot(view, "inline-qc-station-top.png", "viewTop")
show_all()
hide(names=enclosure_tops)
view.viewIsometric()
view.fitAll()
doc.save()
# 5 inspection elevation: x 600..1120, everything in front of y = -150 cut away
d5 = clipped_doc("QCDetailFront", Part.makeBox(520, 500, 1100, App.Vector(600, -150, 400)),
skip_groups=("Enclosure", "Electrical", "Reject"))
v5 = prep(d5)
shoot(v5, "inline-qc-station-detail-front.png", "viewFront", w=2400, h=2400)
App.closeDocument(d5.Name)
# 6 inspection zone, 3/4 view: x 600..1120, z 400..1500
d6 = clipped_doc("QCDetailIso", Part.makeBox(520, 700, 1100, App.Vector(600, -350, 400)),
skip_groups=("Enclosure", "Electrical", "Reject"))
v6 = prep(d6)
shoot(v6, "inline-qc-station-detail.png", "viewIsometric", w=2400, h=2400)
App.closeDocument(d6.Name)
Gui.setActiveDocument(doc.Name)
_vp.SetBool("ShowNaviCube", _navi_before)
_vp.SetBool("UseNavigationAnimations", _anim_before)
_vp.SetBool("EnablePreselection", _presel_before)
print("done")
+239 -11
View File
@@ -1,13 +1,169 @@
# Pressing Line: Equipment Plan # Pressing Line: Equipment Plan
The target press fleet is a **50/50 split between fully automated and ## Launch plant: one Duplex system and one Classic (October 2026)
semi-automatic presses**: automated presses for standard production volume,
and semi-automatic presses for splatter and other color effects, special Decided (user, October 2026): the plant launches with **one Newbilt Duplex
editions, and small runs, where an operator working the mold directly is an system** (two HRP 12 presses, EX 50 main and EX 35 colour extruder) and
advantage rather than a cost. The semi-automatic side is covered by the **one Newbilt Classic**, bought in one capital round with the galvanics,
Newbilt evaluation below; a fully automated press line is an open stamper-prep and cutting room and commissioned in sequence
procurement item (see the [vendor landscape](../suppliers/vendor-landscape.md) ([total investment](../finance/total-investment.md#launch-plant-october-2026)).
for the Pheenix Alpha candidate). That is ~0.71 to 0.97 million records a year on two shifts
([scale](../scale.md#production-capacity)). The second Duplex system below
is a growth option with its room, utility modules and ring-main tees
reserved, not part of the investment. The five-press fleet stays the
layout the hall and the utility backbone are built for.
## Layout fleet: an all-Newbilt fleet of five presses (October 2026)
Two **Newbilt Duplex** systems, each with two HRP 12 presses fed by an
**EX 50** main extruder with an **EX 35** auxiliary extruder beside it for
a second colour, plus one **Newbilt Classic** fully automatic press. The
whole fleet runs from **one shared hydraulic supply and one shared
compressed-air supply** (October 2026):
| | Presses | Extruders | Hydraulics and air |
|---|---|---|---|
| Duplex system 1 | 2 semi-automatic | EX 50 main + EX 35 colour | shared central supply |
| Duplex system 2 | 2 semi-automatic | EX 50 main + EX 35 colour | shared central supply |
| Classic | 1 fully automatic | built in | shared central supply (to confirm with Newbilt) |
| **Fleet** | **5: 4 semi-automatic, 1 automatic** | **2 EX 50, 2 EX 35, 1 built in** | **one hydraulic plant, one air plant** |
This replaces the earlier target of a 50/50 split between automated and
semi-automatic presses (two of each, with the Pheenix AD12 as the
automated candidate). What it means:
- **The semi-automatic side carries most of the volume.** Splatter and
other colour effects, special editions and small runs are where an
operator working the mould is an advantage rather than a cost, and
Newbilt itself recommends the Duplex for splatter, and the EX 35 on
each system adds the second colour strand for splatter, marble and
half-and-half work, which is what the flyer offers it for. The Classic
takes the long standard runs.
- **One vendor, one mould family.** Classic and Duplex share insert sets
(below), so the whole fleet runs one family of moulds and spares and one
service relationship. The single-vendor risk is the same one the Pheenix
path would have carried.
- **Phasing.** The Newbilt Single 2.1 system of the 2024 quote (one press,
one extruder) is the first half of Duplex system 1: its hydraulic
aggregate is already sized for the second press. Since October 2026 the
launch plant buys the whole of system 1 (second press and EX 35) and the
Classic at once; system 2 is the growth step ([scale](../scale.md) capacity table,
[roadmap](../roadmap.md) item 24). The
[press fleet calculator](../fleet-calculator.html) works out the mix of
Duplex systems and Classics for a target output and specials share,
with the utilities from Newbilt's site requirements; the Classic counts
there as one HRP 12 press plus one extruder until Newbilt states its
figures.
- **One shared hydraulic and air supply.** A central hydraulic plant
(pumps, tank, accumulators) and one compressed-air plant feed every
press through ring mains, instead of a hydraulic unit per system. It
means one plant room to maintain and one place for noise and heat, and
it makes adding presses a matter of tapping the ring main. In the
[Payap scenario model](../site-candidates.md#payap-scenario-model-october-2026)
it is a plant room at the west end of the press hall, with a service
trench along the press rows. Open for the re-quote (below): whether the
Single 2.1's own aggregate becomes part of the central plant or a
standby, and whether the Classic can run from it.
Built to grow from one press (October 2026): the plant room is built at
full size, and the hydraulic and air ring mains are sized for the whole
fleet from the start, with a valved, capped tee at every press position,
the empty ones included, so a new press is connected without stopping
the others. The proposal for the Single 2.1's own aggregate, already
sized for the second press, is to set it in the plant room as the first
pump set on the ring main instead of beside the press; system 2 and the
Classic add pump sets in parallel on one manifold with the accumulators,
and a standby set follows. Each branch gets its own isolation valves and
filter: with one shared oil system, a contamination event otherwise
reaches every press. Chinese pump sets and accumulators for the
standby set were checked in October 2026; the press aggregates stay
Newbilt's ([Chinese suppliers](../suppliers/china-utilities.md#hydraulics)).
Steam and cooling follow the same pattern; the phased list for all
three is in
[scale](../scale.md#utility-phasing-backbone-once-modules-with-the-presses).
- **Cell layout (October 2026).** Each Duplex system is one operator's
cell, as sketched in [duplex-cell-layout-sketch.png](duplex-cell-layout-sketch.png)
(arrangement only, not to scale):
- the operator stands in the middle, with the two presses either side
turned 45° towards him;
- the EX 50 and the EX 35 stand side by side behind him, between the
presses;
- one trimmer per cell stands in front of him on the left.
At Newbilt's sizes (site requirements p. 10: press footprint about
0.9 m², extruder about 0.5 m², room to walk around every machine, at
least 60 cm to walls) the cell is about 5 × 3 m, with 0.6 to 0.8 m
between machines. The EX 35 and trimmer footprints are not published,
so those are estimates. The [Payap scenario model](../site-candidates.md#payap-scenario-model-october-2026) draws
both systems this way.
- **Room to grow: a hall laid out for Duplex systems (October 2026).**
The plant will mainly press special editions (splatter, marble, colour
effects), not mono colours: the specials share is planned at 60 % and
more ([revenue model](../finance/revenue-model.md)), and specials run
only on the Duplex systems. The press hall therefore keeps five Duplex
bays (the launch system and four more) and four Classic positions (the
launch Classic and three more). At the calculator's floor figures (110
m² per Duplex bay, 50 m² per Classic) that is 550 + 200 = ~750 m² of the
~870 m² hall, ~73/27 by floor and 10 to 4 by presses; the rest stays
open for mould carts and staging. Growth adds Duplex systems first.
This split balances the hall by output at 60 % specials: ten
semi-automatic presses (600 to 800 records an hour, estimate) carry the
specials and the four Classics (~512 an hour) the standard records. A
60/40 floor split (four Duplex bays, six Classics), planned first the
same month, left the Classics about half loaded at that share. This is
an option, not part of the plan or the investment: the layout keeps the
floor, and the central hydraulic and air plant should be sized or
extendable for it. At Newbilt's per-press figures, the fourteen presses
would draw ~2.1 to 2.5 t/h of steam and up to ~1.8 MW of cooling, so
boiler, chiller and grid connection would be a phase of their own
([scale](../scale.md#production-capacity)). The Payap scenario model in
FreeCAD still draws the earlier layout (two Duplex bays and eleven
Classic positions).
- **Capacity** at maturity stays at ~1.0 to 1.5 million records a year on
two shifts, the range the [revenue model](../finance/revenue-model.md)
uses: four semi-automatic presses at 60 to 80 records an hour (estimate)
and the Classic at ~128 an hour (28 s cycle, vendor figure).
- **Utilities, re-based for this fleet (October 2026).** At Newbilt's
per-machine figures (steam 150 to 180 kg/h, cooling up to 125 kW per
press) the five presses draw ~750 to 900 kg/h of steam and up to ~650 kW
of cooling with extruders and hydraulics, against the ~400 kg/h steam
generator and ~250 kW cooling system that the 2024 quote's exclusions
describe for one Duplex. The proposal is a bank of two 500 kg/h boilers
and three 250 kW chillers, one module per press stage, in a boiler hall
and a chiller compound built for four modules each
([scale](../scale.md#detached-utility-yard-parking-and-what-that-moves));
the layout, the
operating cases and the open RFQ questions are in
[steam and cooling](../steam-cooling.html), the electrical consequences in
[scale](../scale.md) and the costs in the
[utilities CSV](../finance/utilities-investment.csv).
- **Investment**: the fleet change is carried in the added-scope table of
[total investment](../finance/total-investment.md) until the next
re-base.
- **For the re-quote** ([roadmap](../roadmap.md) item 4): the Duplex with
an EX 50 and an EX 35 as an upgrade of the Single 2.1 and as a second
complete system, and whether the EX 50 is the VEX 50 of the 2024 quote;
whether one EX 50 keeps both presses of a system at full rate (the
flyer's Duplex main configuration runs two presses on one extruder); the
Classic's price, weight, power, steam and cooling figures; and the
central hydraulic supply (an option the flyer offers) for the whole
fleet, extendable to the full hall (five Duplex systems, four Classics),
including whether the Classic
can run from it, whether the presses hold their pressure from it over
the ring-main lengths of the hall, the filtration and isolation each
branch needs, and whether the Single 2.1's aggregate can be its first
pump set.
The Pheenix AD12 leaves the plan; it stays in the
[vendor landscape](../suppliers/vendor-landscape.md) as the comparison if
the Classic re-quote disappoints, and Pheenix stays a galvanics candidate
([galvanics and stamper prep](galvanics.md)). ResurRec, which the August
2026 tour found running a Newbilt Classic in Bangkok (a directory listing
names an M-Tech Allegro II instead), appears to have
equipped its new Japan plant with AD12s (Alexander's identification
from photos, October 2026, [revenue model](../finance/revenue-model.md#resurrec-japan-october-2026)).
Why they chose the AD12 there is a question for the Classic re-quote, the
Pheenix call and the ResurRec talks.
## Semi-automatic line: Newbilt ## Semi-automatic line: Newbilt
@@ -25,20 +181,91 @@ The core semi-automatic machinery under evaluation comes from
(scrap feeds back as the ~20% recycled share of the feedstock), 7" center (scrap feeds back as the ~20% recycled share of the feedstock), 7" center
label punch, buffer spindles and separator plates. label punch, buffer spindles and separator plates.
The June 2024 Newbilt quotation totals **≈ €200,500** including freight from The June 2024 Newbilt quotation totals **EUR 200,500** (about **USD 232k
/ 7.7M THB** at August 2026 rates), including freight from
Alsdorf to Thailand and seaworthy packaging. Two major utility systems are Alsdorf to Thailand and seaworthy packaging. Two major utility systems are
deliberately excluded and will be **sourced and installed locally in deliberately excluded and will be **sourced and installed locally in
Thailand**: a ~400 kg/h steam generator (with water treatment) and a ~250 kW Thailand**: a ~400 kg/h steam generator (with water treatment) and a ~250 kW
cooling water system. The quotation has passed its validity date and will need cooling water system. The quotation has passed its validity date and will need
re-confirmation before ordering. re-confirmation before ordering.
## Newbilt range: Making Vinyl Europe 2026 flyers
Collected at the Newbilt booth in Haarlem (30 September to 2 October 2026);
the PDFs are in [`newbilt/flyers-2026/`](newbilt/flyers-2026/). Figures are
vendor-published, not quoted.
| Machine | What it is | Flyer figures |
|---|---|---|
| **Classic** | Fully automatic press: hydraulic 3-column frame based on the Toolex Alpha, built-in extruder, automatic cake loading, label feed, record loading and unloading, cooling-plate handling and spindle stacking | 12" at 110, 140, 160 and 180 g, 7" in development; 28 s cycle at 180 g, claimed ≥95 % yield and ≥95 % uptime (2024 flyer); steam temperature, cooling-water temperature and flow monitored; cooling by time or by delivered water volume, adjusted automatically as the cooling water warms up; Siemens safety PLC, cycle and trend recording, SCADA interface with OPC UA (2024 flyer) |
| **Duplex** | Semi-automatic system in three configurations: Single (1 press, 1 extruder), Duplex main (2 presses, 1 extruder), Duplex with two extruders (2 presses, 2 extruders run as one system with shared control and one hydraulic unit) | 12", 10" and 7"; solid colours, splatter, marble, half and half, picture discs; hydraulic unit normally supplied, or an external central supply shared by several systems |
| **EX 35** | Auxiliary extruder beside the main one, for a second or third colour | 35 mm PVC screw, 3 heating zones, 2 fans, frequency-controlled screw speed, PVC strand output, touchscreen HMI, prepared for Newbilt online support |
| **Edge Trimmer** | Trims the pressed record to its final diameter | Hardened heated blade with adjustable temperature; 7", 10" and 12" with one trimming plate per size (sold separately); standalone, or wired and piped to the Newbilt extruder and then part of the Duplex/Single emergency-stop circuit |
| **Granulator 400** | Grinds edge trim and label-free records into regrind | 200 to 250 kg/h, 7.5 kW, crushing chamber 410 × 270 mm, 12 rotor knives, 8 mm screen, 800 kg; cyclone collection with stainless contact surfaces, dust bags and outlet magnet, about 100 kg storage |
| **Label Punch** | Removes the label area so rejected records can be granulated | 106 mm punch for 7", 10" and 12"; manual loading, then automatic transport, punching and collection; optional dinker for 7" |
What this changes in the plan:
- **Classic and Duplex share inserts.** Insert sets move between the two
machines, so the current all-Newbilt fleet (Duplex systems for the
semi-automatic side, the Classic for the automated press) runs one mould
family. Newbilt itself recommends the Duplex for splatter, which is why
the semi-automatic side carries most of the fleet. The Pheenix AD12
stays the comparison for the Classic.
- **Regrind loop.** The granulator flyer puts edge trim at about 20 to 40 g
per 12" 180 g record, 11 to 22 % of the record's mass, which brackets the
~20 % recycled share in the process schematic. Rejected records go
through the Label Punch first; trim goes into the granulator directly. A
Classic at 28 s makes about 128 records/h, so roughly 2.5 to 5 kg/h of
trim per press (estimate): one Granulator 400 at 200 to 250 kg/h runs in
short batches, not continuously.
- **Compound storage (October 2026).** Special designs will run in tens
of colours, so the compound store is sized for them:
- a colour store with pallet racking next to the regrind and conveying
room: about 100 pallet positions on four levels in the
[Payap scenario model](../site-candidates.md#payap-scenario-model-october-2026) (estimate);
- a few outdoor silos (proposed) for black and the standard colours,
filled from big bags or by bulk truck and conveyed to the extruders.
Compound is the heaviest material in the plant (~160 to 270 t a year at
the mature fleet: 1.0 to 1.5 million records at roughly 160 to 180 g
each with trim), so it
stays on the ground floor. The compound suppliers' answer on 25 kg sacks
versus big bags
([Making Vinyl briefing](../suppliers/making-vinyl-europe-2026-exhibitors.md))
decides how the silos are filled.
- **Hydraulics.** One central hydraulic supply for several systems is an
option on the flyer and is now the plan, together with one shared
compressed-air supply (see "Current plan" above); it changes the
machine-floor layout and the utility list in [scale.md](../scale.md).
- **Colour effects.** The EX 35 is the add-on for multi-colour work on the
semi-automatic side. It is not in the 2024 quote; the current plan has
one per Duplex system.
- **For the re-quote**, where sources disagree: the Classic's operator panel
(two 21" touchscreens in the 2024 flyer, one 10" on the Newbilt website);
its built-in extruder power (7.5 kW, 400 V drive motor in the 2024 flyer,
15 kW in this repo's earlier notes, source not recorded); 10" on the
Classic (in the 2024 flyer and on the website, not in the 2026 flyer);
and whether the Edge Trimmer is the Vario trimmer of the 2024 quote.
- **Stamper fit.** Ask both press vendors which stamper centre hole and
edge form their moulds expect: the Sibert VSP punches Ø25.4 mm as
standard and the VSC coiner needs tooling per mould type (see
[galvanics and stamper prep](galvanics.md)).
## Site requirements ## Site requirements
Site planning for the semi-automatic line works from Newbilt's Duplex Site planning for the semi-automatic line works from Newbilt's Duplex
requirements: roughly 200 m² of production floor, 32 kVA connected requirements: roughly 200 m² of production floor, 32 kVA connected
electrical load, saturated steam at 10 bar, and compressed air and cooling electrical load, saturated steam at 10 bar, and compressed air and cooling
water circuits, plus side rooms for materials, compressor, chiller, and water circuits, plus side rooms for materials, compressor, chiller, and
finished goods. finished goods. These are per Duplex system: the current fleet needs two,
plus floor for the Classic (~400 m², plus ~50 to 75 m² for the Classic,
estimate). The machines themselves are small: a press is about 0.9 m², an
extruder about 0.5 m², and the hydraulic aggregate about 1.0 m², which
Newbilt prefers outside the pressing room; the minimum room height is
2.5 m. Most of the 200 m² is walking, handling and side-room space. The
layout drawing that page 11 of the site requirements refers to is not in
our copy; ask for it with the re-quote.
**Floor loading is a building-selection criterion**: the slab must carry **Floor loading is a building-selection criterion**: the slab must carry
multiple tons per m² in the machine areas. A Newbilt press weighs 1,350 kg multiple tons per m² in the machine areas. A Newbilt press weighs 1,350 kg
@@ -50,4 +277,5 @@ from press cycles come on top of the static figures, so the structural
engineer gets the vendor data sheets, not just the totals. engineer gets the vendor data sheets, not just the totals.
Source documents live in [`newbilt/`](newbilt/): the budgetary offer, the Source documents live in [`newbilt/`](newbilt/): the budgetary offer, the
Duplex site requirements, the process schematic, and the service rate card. Duplex site requirements, the process schematic, the service rate card, and
the 2026 product flyers in [`newbilt/flyers-2026/`](newbilt/flyers-2026/).
Binary file not shown.
+91 -5
View File
@@ -28,7 +28,8 @@ option per room.
sensors logging in every zone, with alarms on excursions, tied into the sensors logging in every zone, with alarms on excursions, tied into the
plant monitoring below. plant monitoring below.
- **Energy design**: conditioning a whole factory in a tropical climate is - **Energy design**: conditioning a whole factory in a tropical climate is
a major electrical load on top of the 250 kW process cooling, and it must a major electrical load on top of the process cooling (up to ~650 kW for
the five presses), and it must
be included in the solar PV and battery sizing from the start. Heat be included in the solar PV and battery sizing from the start. Heat
recovery from the press hall (steam, hydraulics, and hot PVC all reject recovery from the press hall (steam, hydraulics, and hot PVC all reject
heat) and from compressors should feed the design rather than fight it. heat) and from compressors should feed the design rather than fight it.
@@ -38,15 +39,20 @@ option per room.
- **Access control**: zoned, not just at the gate. Minimum zones: general - **Access control**: zoned, not just at the gate. Minimum zones: general
production, galvanics clean room (controlled access is already a safety production, galvanics clean room (controlled access is already a safety
requirement), chemical storage, master/stamper archive, server/IT room, requirement), chemical storage, master/stamper archive, server/IT room,
finished goods and shipping. Badge or biometric, with logs. finished goods and shipping, and the visitor corridor. Badge or
biometric, with logs.
- **CCTV**: entrances, perimeter, loading dock, production floor, chemical - **CCTV**: entrances, perimeter, loading dock, production floor, chemical
storage, archive. Retention policy to be defined; Thai PDPA (personal data storage, archive. Retention policy to be defined; Thai PDPA (personal data
protection) applies to camera footage of staff and visitors. protection) applies to camera footage of staff and visitors.
- **Intrusion alarm** with monitoring, covering off-hours. - **Intrusion alarm** with monitoring, covering off-hours.
- **Perimeter and lighting**: fencing appropriate to the site, lit - **Perimeter and lighting**: fencing appropriate to the site, lit
approaches and parking. approaches and parking.
- **Visitor management**: sign-in, escort rules, PPE issue at entry, no - **Visitor management**: sign-in, escort rules, no unaccompanied access to
unaccompanied access to production or galvanics. production or galvanics. Tours run through the glazed visitor corridor
([crane, workshop and tours](crane-workshop-tours.md)), which keeps
visitors out of noise, dust and plating air and so needs no PPE; anyone
who goes onto the floor itself is escorted and issued PPE at entry as
before.
## Protecting the irreplaceable ## Protecting the irreplaceable
@@ -62,6 +68,81 @@ option per room.
salts are hazardous. Locked storage, inventory tracking, and controlled salts are hazardous. Locked storage, inventory tracking, and controlled
issue to the galvanics team. issue to the galvanics team.
### Archive room: mobile shelving
Planned (October 2026): the archive in the office is fitted with **mobile
archive shelving**, carriages on floor rails that close up into one block
and open a single aisle where it is needed. The reference is A-Z
Solutions' archive shelving (Vienna; fahrbare Archivregale,
https://www.a-z-solutions.eu/buero-archiv/archivregale, checked October
2026): hand wheel or electric push-button drive, optional front panels,
lockable, and the vendor asks to be involved early because the rails set
requirements on the floor and the room layout. Prices are not published.
**What it holds.** The father and the mother of every side (decided
October 2026, [galvanics](equipment/galvanics.md)): 4 parts per title,
about 1,200 to 2,400 a year at full capacity, in protective sleeves,
standing in labelled boxes. Also paper records that have to be kept as
originals. A reference pressing of every title could go here too; that is
a proposal, not decided.
**Size, estimates.** A 12" father or mother grows on a 14" lacquer: about
35 cm across, 0.25 mm thick, ~9.6 dm² ([plant
operation](plant-operation.html) and galvanics figures), so about 0.2 kg of
nickel. In a sleeve with a separator, assume ~3 mm of shelf per part:
~330 parts and ~75 kg per shelf metre, on 400 mm deep shelves with ~400 mm
clear height, five levels to ~2.2 m. In the Payap scenario's office the
archive is a ground-floor room of about 4 × 5.75 m
([site candidates](site-candidates.md)). With the rails along the long
side it takes two fixed single-sided runs, four double-sided carriages
about 3 m long and one ~0.9 m working aisle: ~150 shelf metres, roughly
50,000 parts, which is 20 years or more of fathers and mothers at full
capacity. Static shelving with an aisle between every pair of runs
would hold about 60 % of that.
**What it asks of the building.**
- **Floor load.** Fully loaded, a double carriage carries about a tonne
per metre of length: ~11 kN/m² under the shelving block and ~6 kN/m²
averaged over the room (estimates), above an office floor. The archive stays on the ground slab, and
that slab keeps the full rating if the slab is zoned lighter under
offices ([phase 1 RFQ](finance/phase1-construction-rfq.md)).
- **Rails.** Set into the floor screed during fit-out, or on a raised
floor ramped at the door, so the shelving layout and the rail positions
are fixed before the floor finish. Rail type, depth and floor flatness
tolerance come from the shelving supplier.
- **Drive.** A geared hand wheel with an aisle lock is enough for a room
one or two people use and has nothing to fail; electric drive is an
option, not a need.
- **The room around it** stays as above: clean-agent gas suppression
(the suppression designer confirms the agent reaches into the closed
carriage block), climate control with the archive in the tightest
monitoring tier ([digital factory](digital-factory.md)), a water-leak
sensor along the rails, lockable carriages behind the room's access
control.
- **Locations.** Every box carries a barcode and every position an
address (carriage, face, level, slot); each part's serial number in
ERPNext carries its archive location, so a repress order says which box
to pull.
**Open points.**
- **Quotes:** A-Z Solutions and LPI Rack Range (Thailand), a Bangkok
manufacturer of office mobile shelving and industrial racking
([supplier map](suppliers/equipment-suppliers.md)), against the same spec (carriages ~3 m, five levels, 400 mm
shelves, at least ~100 kg per shelf level per metre, geared hand wheel
with aisle lock, central lock, rail embedding detail, delivery and
installation in Chiang Mai). Steel shelving shipped from Austria is
heavy, so the A-Z system is the reference spec rather than the default
buy.
- **Storage format:** sleeves, boxes, passivation and humidity for
archived nickel parts, from the galvanics vendors
([open questions](equipment/galvanics.md#open-questions-for-the-quotes)).
- **Two compartments:** with fathers and mothers in one room, one event
can take both. Keeping the fathers (rarely pulled) in a second fire
compartment or off site, and the mothers (pulled for every repress) in
this room, would meet the off-site point above.
## Fire and life safety ## Fire and life safety
- **Fire detection and alarm** throughout; suppression matched to each zone - **Fire detection and alarm** throughout; suppression matched to each zone
@@ -131,7 +212,12 @@ sprinkler demand, so the site carries its own reserve and pumps.
**Warehouse racking height drives the real number.** If finished-goods **Warehouse racking height drives the real number.** If finished-goods
storage goes above roughly 3.7 m, the commodity classification and sprinkler storage goes above roughly 3.7 m, the commodity classification and sprinkler
design change, and the stored volume grows with them. Fix the racking height design change, and the stored volume grows with them. Fix the racking height
before the fire design is frozen, not after. before the fire design is frozen, not after. The
[Payap scenario model](site-candidates.md#payap-scenario-model-october-2026)
draws the 9 m × 4 m tank with its pump house at the front. It also draws
6 m warehouse racking and about twice the floor area this figure was
based on, a paper store among it, so treat ~200 m³ as a floor there,
not as the answer.
The property insurer will drive much of the final specification, so involve The property insurer will drive much of the final specification, so involve
them before the design is fixed. The archive gas system and the BESS them before the design is fixed. The archive gas system and the BESS
File diff suppressed because it is too large. Load diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
+240
View File
@@ -0,0 +1,240 @@
# Phase 1 Construction: Rough Pricing Request
Spec sheet for asking a contractor for a budget-level price on the phase 1
buildings and site works. Quantities come from the parametric model
(`docs/cnx_vinyl_parametric.FCStd`) sited on the candidate Mueang Chi
parcel; everything here is planning-stage, not construction documents. In
Thailand this scope is typically quoted as a PEB (pre-engineered steel
building) per m² plus civil works, and the sheet is structured that way.
Context to give the contractor up front: the land is not yet purchased and
zoning is unverified, so this is a budget number, not a bid.
## 1. Main production building
| Item | Spec |
|---|---|
| Type | Single-storey steel portal frame (PEB), no mezzanine, **crane-ready: one 5 t EOT crane runway over the production compartment** (see §1c) |
| Footprint | **60 × 25 m = 1,500 m²** |
| Roof | Monopitch, **10° pitch**, roof plane **1,523 m²**, low eave **7.0 m**, high side **~11.4 m** (both above finished floor) |
| Roof load | Carries a rooftop PV array (~425 modules, ~247 kWp): add **~20 kg/m²** dead load plus wind uplift on racking; PV mounts on the purlins |
| Envelope | **Insulated sandwich panels, walls and roof, PIR core — EPS core excluded** (fire and insurability), fire-rated class stated (FM-approved or B-s1,d0). **Roof 100 mm PIR** with light-colored top skin, **walls 75 mm PIR**. Taped/gasketed joints throughout — the building is air-conditioned (20–26 °C, 35–60 % RH) and must be airtight against smoke-season PM2.5. No skylights. Not bare metal sheet with blanket insulation. **See §1a for where mineral-wool core is required instead** |
| Wall quantities | Masonry/precast dado **170 m perimeter × 2.5 m = 425 m²** (impact, security, washdown), internally insulated so the envelope stays continuous; **sandwich panel above dado ~1,140 m²** |
| Floor | **200 mm** ground-bearing slab rated **30 kN/m² UDL**, provision for machine plinths, power-floated finish |
| Finished floor level | **+1.2 m above surrounding ground** — see §1b |
| Doors | 2 loading doors (insulated sectional) as **sealed dock positions**: dock shelters/seals plus dock levelers, so the docked trailer acts as the airlock and doors never open to outside air. **1 machine door** (~4.5 × 5.0 m insulated sectional, fully sealed) at the ramp end, see §1c. Personnel entrances with vestibule; fire exits per code |
| Interior | **Shell only — no internal fit-out** in this price (clean room, offices etc. priced later) |
On the slab spec: 30 kN/m² (3 t/m²) is the standard industrial warehouse
class, not a premium — it is what the presses and pallet racking need, and
stepping up from a light-duty slab adds only on the order of 100–200 THB/m².
The real cost variable is the ground underneath (see soil, below). A later
value-engineering option is to zone the slab — 30 kN/m² under press hall and
warehouse only, lighter under offices, but for rough pricing the whole
floor is specified at 30 so the number is conservative. If it is zoned,
the archive room keeps the full rating: it gets mobile shelving loaded
with nickel parts, about 11 kN/m² under the shelving when full (estimate), and
its rails go into the floor screed at fit-out
([facility security](../facility-security.md#archive-room-mobile-shelving)).
### 1a. Panel core: where PIR is not enough
PIR is specified for the general envelope because it gives the best thermal
performance per millimetre (λ ≈ 0.022 W/mK, so roughly U 0.28 W/m²K walls
and 0.21 W/m²K roof), which is what the conditioned interior needs. Two
places it should **not** be used, and the contractor should price
**mineral-wool core** panels instead:
- **Fire compartmentation.** A panel's reaction-to-fire class is not a fire
resistance rating. Any wall required to compartment — production hall to
warehouse, and anything separating the boiler hall — needs rated
construction achieving **EI 60 or EI 120**, which in panel form means
mineral wool, not PIR.
- **Acoustics.** PIR performs poorly for sound, typically **Rw 25–30 dB**;
it is a stiff closed-cell foam and behaves as a mass-spring-mass system
with coincidence dips. Presses, compressors, chillers and the boiler are
all significant sources and the site is agricultural land, so a neighbour
complaint is a permitting risk. Mineral-wool core reaches roughly
**Rw 32–40 dB**.
Ask the contractor to price the general envelope in PIR and to quote
mineral-wool core as a **separate rate per m²** for nominated compartment
and acoustic walls, stating the panel thickness needed to hold the same
U-value (mineral wool at λ ≈ 0.038 needs roughly 130 mm walls / 180 mm roof
to match, and is heavier — it may affect purlin and frame sizing).
**Open decision:** which elevations are acoustically governed. That depends
on the neighbour to be identified at the land survey. Until then, price the
mineral-wool rate but leave the area provisional.
### 1b. Raised floor and site fill
The dock-height question is now **decided**: the whole building floor is
raised rather than forming a recessed dock pit. This is a civil works item
and must be included.
| Item | Quantity |
|---|---|
| Compacted structural fill under the building platform | **1,711 m³** |
| Fill build-up | 1.0 m compacted fill + 200 mm slab = **FFL +1.2 m** |
| Reinforced concrete edge beam to retained faces | **56.1 m³**, ~85 m of retained edge |
| Battered faces | Two faces battered at **1V:2H** rather than retained (no edge beam) |
The loading face and the car-park elevation are retained by the edge beam;
the other two faces are battered. The dispatch room behind the docks runs as
a buffer climate zone, separated from the conditioned warehouse by
interlocked high-speed roll doors.
**Access at grade.** With FFL at +1.2 m the building needs its own access,
now modelled and to be included:
| Item | Spec |
|---|---|
| Vehicle ramp | **10.5 m run × 4.5 m wide at 1:10**, rising 1,050 mm from yard level to FFL, sited at the far end of the building — opposite the docks, so it does not conflict with dock operations. **~22.9 m³** concrete |
| Personnel steps | **3 flights**: main entrance on the car-park elevation, plus two fire exits — one at the opposite end of the same elevation, one at the dock end. Each **1.5 m wide, 6 risers at 175 mm, 5 treads at 280 mm, 1.2 m top landing**. **~2.3 m³** each |
Two things deliberately not in the model, to be priced anyway: **handrails**
to both sides of every flight and to the ramp, and **door thresholds**.
The ramp is 1:10, which suits forklifts and vans but is **not** an
accessible gradient. **A step-free visitor entrance is now required**: the
plant will run public tours through a glazed visitor corridor (see
[crane, workshop and tours](../crane-workshop-tours.md)). Price a **1:12
ramp at the main entrance**, about 14.4 m of run for the 1.2 m rise plus
intermediate landings, with handrails both sides.
Exit positions are provisional: they are placed for reasonable escape
distances on a 60 × 25 m footprint, but final numbers and locations follow
the fire strategy and the racking layout, neither of which is fixed.
### 1c. Overhead crane and machine door
The building must carry an overhead crane for moving machines in, out and
to the maintenance workshop. Background and the reasoning behind each
figure: [crane, workshop and tours](../crane-workshop-tours.md).
| Item | Spec |
|---|---|
| Crane | Single-girder EOT, **5 t SWL** (3.2 t as an alternative price), span the full building width (~24 m between rail centres), electric wire-rope hoist with inverter drives, radio remote, light duty class |
| Runway | Both long walls, over the **production compartment only**: from the ramp-end wall to the production/warehouse fire wall, **~40 to 48 m** (estimate, set by the warehouse depth). Brackets or stepped columns, runway beams, rails, end stops, enclosed conductor rail |
| Frame | Designed for crane wheel loads and braking forces from day one |
| Hook height | **State the achievable hook height under the 7.0 m low eave.** Price **+1.0 m on the low eave** as an option |
| Machine door | ~**4.5 m wide × 5.0 m high** insulated sectional, fully sealed, at the ramp end; the runway reaches its inside face |
| Machine bay slab | The bay inside the machine door rated for a rigid truck reversing in: **wheel point loads**, not only the 30 kN/m² distributed rating |
| Ramp | Confirm the 10.5 m × 4.5 m 1:10 ramp and its transitions take a rigid truck reversing up to the machine door |
The crane itself may be quoted by a specialist sub; the runway, frame
premium and machine door belong in the shell price. Inside the crane zone
no wall may run full height across the building; internal partitions are
fit-out and are not in this price.
## 2. Detached utility yard
Simple industrial enclosures beside the main building.
| Building | Area | Height |
|---|---|---|
| Boiler hall, laid out for four 500 kg/h boiler modules | ~162 m² (18 × 9 m) | 6.0 m |
| Biomass fuel store | 42 m² | 5.0 m |
| Chiller compound: open to the sky, screened, four chiller pads (~4.0 × 2.6 m each) | ~135 m² (12.5 × 10.8 m) | screen ~2.5 m |
| Cooling pump and heat-exchanger room | ~40 m² (8 × 5 m) | 4.0 m |
The boiler hall and the chiller compound are built once for four modules
each, and the plant goes in one module at a time as presses arrive
([scale](../scale.md#detached-utility-yard-parking-and-what-that-moves)):
price the floor, pads, plinths and wall openings for all four now. The
sizes are estimates until the boiler and chiller vendors send footprints.
Air-cooled chillers need open air, so the earlier "chiller room" is an open
compound; the cooling tower pad of the water-cooled concept is deleted (a
dry cooler, if bought, gets a pad sized with its quote).
The 14 m flue stack comes with the boiler — excluded here. The boiler hall
envelope should be non-combustible (mineral-wool panels or masonry), not
PIR.
## 3. Site works
| Item | Quantity |
|---|---|
| Perimeter wall | **~444 m** boundary, **2.0 m** high block/precast on strip footing (~174 m³) |
| Main gate | **One** gate only: piers plus **bi-parting sliding leaves, 10.0 m clear opening** (2 × 5 m). The previously mooted second gate is deleted |
| Paving — heavy duty | **1,608 m²** rigid reinforced concrete for laden trucks: truck apron, dock face, internal circulation road, Phase 2 link |
| Paving — general | **2,779 m²** lighter hardstanding: car park, yard and margins |
| **Paving total** | **4,387 m²** — see note below |
| Car/scooter parking | Roofed canopies: **27.7 × 7.0 m (195 m², 10 cars)** + **13.7 × 5.5 m (76 m², 30 scooters)**, steel canopy built **PV-ready** for ~40 kWp (structure for the panels' dead load and uplift, conduit to the main board); panels later, not in this contract |
| Guard house | **12 m² (4 × 3 m)**, insulated/AC'd, with toilet; sited at the gate, north-west side |
| Tank foundations | Ring foundation for a **9 m dia × 4 m** fire water tank (**~250 m³, ~250 t full** — the geometry gives 254 m³ gross; if 200 m³ usable with freeboard is intended, the foundation still carries the full 250 t) sited in the **north-west corner of the plot**, with the **fire pump house adjacent to it**; plus a **5 m dia × 3 m** raw water tank. Tanks themselves are vendor-supplied bolted panels — foundations only |
| Fire main | Ring main runs from the north-west corner to the buildings — quote the **length**, not just "a ring main" |
| Drainage & sanitation | Site stormwater drainage, domestic septic/treatment for ~25 staff — **see note below** |
**On the paving quantity.** This is a deliberate increase: the site is now
paved continuously from the road frontage through to the Phase 2 building.
At 4,387 m² it is roughly 2.5× the 1,500–2,000 m² this sheet previously
carried, and it becomes one of the larger civil numbers in the package. Two
things follow:
- The two paving classes are quoted separately on purpose. Do **not** price
the whole 4,387 m² at truck spec.
- Roughly the last third of the general paving is the Phase 2 approach,
which will be dug up again for Phase 2 piling and foundations. **Option to
price:** compacted sub-base only now, surfaced after Phase 2 completes.
**On drainage.** 4,387 m² of pavement is about 46 % of the 9,567 m² plot,
but the figure that matters for attenuation is the **total sealed area**:
adding the main building (1,500 m²), utility yard (~379 m²), guard house
(12 m²) and parking canopies (271 m²) gives **~6,549 m², or 68 % of the
plot**. Quote the contractor that number, not the paving one.
Runoff increases materially over the agricultural baseline, and
stormwater attenuation — quite possibly a detention pond — may be required
for the factory permit. Ask the contractor to state what they have assumed.
## 4. Exclusions
State these so the number is clean: process machinery, PV system, HVAC
plant, chiller/boiler/tanks themselves, sprinkler system, internal fit-out,
transformer (PEA), and land works beyond normal grading.
## 5. Questions the contractor will ask
- **Soil conditions**: unknown — the plot is agricultural land in Mueang
Chi, Lamphun, likely soft former paddy. A soil boring test (~30–50k THB)
comes before any real number. For rough pricing, ask them to assume
soft-to-medium Lamphun valley soil and to **state the foundation
assumption they price** (footings vs driven piles; a piled slab can add
several hundred to 1,000+ THB/m²). The soil, not the slab spec, is the
main price risk in the whole package, and it now applies to 4,387 m² of
pavement and a 1,711 m³ fill platform as well as the building.
- **Tank proximity to the building**: the fire water tank sits about 4.5 m
from the main building. Full, it is ~250 t on a 9 m ring foundation. On
soft ground, ask whether they price a deeper tank foundation, ground
improvement, or want the tank moved further off.
- **Panel core**: PIR general with mineral wool at compartment and acoustic
walls (§1a) — separate rate per m², and any frame implications.
- **Sprinklers**: OH2 sprinkler system, ring main, and hydrants are planned
but not designed (see [facility security](../facility-security.md)). Ask
whether they price it or use a specialist sub — quoted separately either
way.
- **Racking height** in the warehouse zone: undecided; drives the fire
design, not the shell, but they may ask.
- **Crane**: achievable hook height at the 7.0 m eave, the frame premium
for crane loads, and whether they supply the crane or price a
specialist sub (§1c).
- **Permits**: ask whether the price includes permit drawings by a licensed
engineer for the building permit and Ror.Ngor. 4 factory license — rough
shell prices usually don't.
## 6. What to ask for back
- **THB/m² rough range for the PEB shell** at the insulated-panel spec
above — not the bare-shed spec
- Separate rates for **heavy-duty** and **general** paving
- A separate rate for **mineral-wool core** panel
- The **crane package** separately: runway and frame premium, machine
door, the crane itself, and the hook height they achieve
- A lump figure for the rest of the site works
- The foundation/geotech assumption behind all of it
That is enough to sanity-check against the ~24–42M THB Thai-sourced
utilities baseline in the [utilities CSV](utilities-investment.csv);
building construction is currently an unpriced line in
[scale](../scale.md).
Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

File diff suppressed because it is too large. Load diff
+458
View File
@@ -0,0 +1,458 @@
# Share price for the 40 % on offer: market-based ranges (October 2026)
What a share in the plant company could cost the co-investors who take up
the 40 % beside the lead investor, and what it could be worth once the
plant runs, worked from public market data (dated and linked below) and
the plan's own figures. The basis is the funding decision of 20 October
2026: **the shareholders fund the whole plant as share capital, with no
bank loan**. **This page is not a valuation opinion and not an offer
price.** Every result is an estimate or an illustration, given as a range
or as scenarios; the share price itself is for the shareholders'
agreement (business plan B, section 12.2). Computed 20 October 2026.
Owning documents: [total investment](total-investment.md#two-plans-a-at-180m-thb-and-b-at-215m-thb-october-2026)
(plans, shareholding and the Funding paragraph), [revenue model](revenue-model.md#operating-pictures-of-plan-a-and-plan-b-october-2026)
(operating pictures), [BOI](../boi.md) (debt-to-equity and incentives), the
[plant and business plan calculator](../fleet-calculator.html) (ten-year
cash view) and the [business plan, Plan B](../business-plan/CNX-Vinyl-Business-Plan-B.pdf)
(sections 8.3, tranches, and 12.2, ownership and structure).
## What is decided
- **Funding** (user, 20 October 2026): **the shareholders fund the whole
plant and get shares for it; no bank loan is planned.** Plan B's ~217M
THB is paid in as share capital, registered in full and called in
instalments against the tranches of business plan section 8.3
([total investment, Funding paragraph](total-investment.md#two-plans-a-at-180m-thb-and-b-at-215m-thb-october-2026)).
The share price, any founders' or in-kind shares and the call schedule
are not agreed.
- **Shareholding** (user, 20 October 2026): the lead investor holds **at
least 60 %** of the company that holds the plant and the BOI promotion,
so **at most 40 % is for sale**. Ploy Printing (intended strategic
co-investor, in cash, in kind or both), any founders' shares and any
further co-investor all come out of that 40 %
([total investment](total-investment.md#two-plans-a-at-180m-thb-and-b-at-215m-thb-october-2026)).
On ~217M of share capital at one price that is at least ~130M THB for
the lead investor and at most ~87M for the 40 %.
- **Plan B is the proposal**: ~217M THB at the midpoint (201.6M before
the 10M to 20M ramp-up reserve), labelled ~215M; ~156M to 277M from the
low to the high end of every block; no contingency (~30M at 15 % is not
in the price). Plan A (~182M) is the comparison only.
- **BOI**: debt-to-equity no higher than 3:1 for the life of the
privileges. With no debt the ceiling is met with room to spare and no
longer sets an equity floor; a loan added later would have to stay
within it. Vinyl pressing is expected in incentive **Group B: no
corporate income tax holiday on the core activity**; upgrade measures
(automation, R&D) may add limited exemptions, to be structured by a BOI
consultant ([BOI](../boi.md)). This page uses the 20 % Thai corporate
tax rate.
- **Operating picture, Plan B, mature year at 60 % specials**
([revenue model](revenue-model.md#operating-pictures-of-plan-a-and-plan-b-october-2026)):
revenue 2.28 / 3.65 / 5.41M USD, EBITDA 0.23 / 1.73 / 3.79M USD,
operating profit -0.55 / 1.24 / 3.50M USD (adverse / central /
favourable). The central EBITDA margin (~47 %) is far above the 15 to
25 % pressing plants earn, so **the adverse column is the honest one**;
the central column is used here only with that caveat.
- **Calculator, preset planB** ([fleet-calculator.html](../fleet-calculator.html),
read 20 October 2026): ten-year cumulative cash -6.56M to +12.92M USD,
cash payback in year ~4.2, IRR ~22 % (22.2 %), NPV ~4.7M USD (4.68M).
Its basis, from the page source: discount rate **10 %** (input
`discRate`, marked estimate), **pre-tax and pre-financing**, no terminal
value, "Corporate income tax and BOI's CIT exemptions ... are not
modelled", ramp 35 / 70 / 90 % in years 1 to 3, depreciation over 12.5
years. With no loan, pre-financing is the shareholders' own position.
- **FX**: 33 THB/USD (planning rate, total investment).
- **No loan terms are on file, and no loan is planned.** No interest
rate, repayment schedule or debt-service figure appears on this page.
The one levered table below ("if a loan were added later") uses the
most debt the 3:1 rule would allow, nothing repaid, only to show what
leverage would do to the figures; it is not the plan.
## Thai company law basics
From the Civil and Commercial Code (Thai text from the Office of the
Council of State with English translation on
[ThaiLawOnline](https://www.thailawonline.com/thai-civil-code/section-1105/),
cross-checked against the Siam Legal library, sections
[1096 to 1116](https://library.siam-legal.com/thai-law/civil-and-commercial-code-limited-companies-section-1096-1116/)
and [1117 to 1143](https://library.siam-legal.com/thai-law/civil-and-commercial-code-limited-companies-section-1117-1143/);
checked 20 October 2026; to be confirmed by Thai counsel in phase 0):
- **Section 1096**: the shareholders' liability is limited to the amount,
if any, unpaid on their shares. Capital registered but not yet called
is owed to the company.
- **Section 1117**: a share may not be less than **5 THB**. The par value
is otherwise free; 100 THB a share is a common choice and is used below
as the worked example (not decided).
- **Section 1105**: shares **may not be issued below par**. Issuing above
par (a share premium) is permitted **only if the memorandum of
association sanctions it**, and the premium is paid with the first
payment. The **first payment must be at least 25 %** of par.
- **Calls on the rest (sections 1120 to 1125)**: unless a general meeting
decides otherwise, the directors call the unpaid money (1120), with at
least **21 days' notice by registered letter** (1121). A shareholder who
misses a call owes interest from the due date (1122); the directors may
send a second registered notice with a reasonable deadline that can
warn of forfeiture (1123), then declare the shares forfeited (1124);
forfeited shares are sold without delay **by public auction**, the
proceeds pay the call and interest and any surplus goes back to the
shareholder (1125). This is the frame for calling the share capital in
instalments against the tranches.
- **Section 1108** (amended by Act No. 23 B.E. 2565, in force 7 February
2023): the statutory meeting ratifies the promoters' contracts and
expenses, fixes any payment to promoters, and fixes the shares to be
allotted as paid up **otherwise than in money**; the service or property
given for them must be described expressly to the meeting. **Section
1119**: otherwise every share is paid in money, and no set-off against
the company is allowed. After formation, new shares paid in kind need a
special resolution (**section 1221**). This is the route for founders'
work, the lead investor's pre-round costs and Ploy Printing's in-kind
contribution.
- **Section 1220**: capital is increased by special resolution;
**section 1222**: all new shares must first be offered to existing
shareholders in proportion to their holdings (statutory pre-emption).
- **Section 1194** (amended 2008): a special resolution needs **three
quarters of the votes of the shareholders present and entitled to
vote**. A 60 % holder alone therefore cannot pass one when the 40 %
attends: capital increases, in-kind allotments after formation and
changes to the memorandum or articles need part of the 40 %.
## Market data
Checked 20 October 2026. Damodaran files are the January 2026 release
(dated 5 January 2026) under
`https://pages.stern.nyu.edu/~adamodar/pc/datasets/`, read with pandas.
| Item | Value | Source | Data date |
|---|---|---|---|
| EV/EBITDA, Emerging Markets, firms with positive EBITDA | Packaging & Container **13.3x** (341 firms); Entertainment 14.9x; Machinery 25.0x; Chemical (Specialty) 16.0x; Total Market 12.3x | Damodaran, [vebitdaemerg.xls](https://pages.stern.nyu.edu/~adamodar/pc/datasets/vebitdaemerg.xls) | 5 Jan 2026 |
| EV/EBITDA, Global (cross-check) | 9.6x; 18.7x; 16.9x; 13.1x; 14.7x (same order) | [vebitdaGlobal.xls](https://pages.stern.nyu.edu/~adamodar/pc/datasets/vebitdaGlobal.xls) | 5 Jan 2026 |
| P/E, aggregate market cap / net income of money-making firms, EM (cross-check) | 18.9x; 18.8x; 35.7x; 24.8x; 16.6x | [peemerg.xls](https://pages.stern.nyu.edu/~adamodar/pc/datasets/peemerg.xls) | 5 Jan 2026 |
| P/E, same basis, Global | 16.2x; 27.8x; 27.9x; 21.9x; 20.3x | [peGlobal.xls](https://pages.stern.nyu.edu/~adamodar/pc/datasets/peGlobal.xls) | 5 Jan 2026 |
| Unlevered beta corrected for cash, EM | **0.61**; 1.22; 1.50; 1.11; **0.85** | [betaemerg.xls](https://pages.stern.nyu.edu/~adamodar/pc/datasets/betaemerg.xls) | 5 Jan 2026 |
| Unlevered beta corrected for cash, Global | 0.58; 0.98; 1.33; 1.04; 0.83 | [betaGlobal.xls](https://pages.stern.nyu.edu/~adamodar/pc/datasets/betaGlobal.xls) | 5 Jan 2026 |
| Thailand equity risk premium | **6.18 %** = mature market 4.20 % + country risk premium 1.98 % (Moody's Baa1, rating-based default spread 1.27 %); January 2026 file: 6.30 %; CDS-based alternative 5.04 % | Damodaran, [ctrypremJuly26.xlsx](https://pages.stern.nyu.edu/~adamodar/pc/datasets/ctrypremJuly26.xlsx) | 1 Jul 2026 (spreads corrected 9 Jul) |
| Thai corporate income tax | 20 % | same file, "Country Tax Rates" | 2025 |
| Thai government bond yield, 10 years | **2.30 %** | ThaiBMA, [government bond yield curve](https://www.thaibma.or.th/compositerpt/GovYieldCurve.aspx) | 19 Oct 2026 |
| Illiquidity discount (DLOM) | Restricted-stock studies **25 to 35 %** (Maher 35.4 % mean, 1969 to 1973; Silber 33.75 % median, 1981 to 1988; Johnson 20 %); after controlling for issuer differences Bajaj et al. ~7 %; pre-IPO transactions ~45 % (Emory), 32 to 75 % (Willamette); conventional practice 20 to 30 %; McCord v. Commissioner (2003): court accepted 20 % | Damodaran, [Marketability and Value: Measuring the Illiquidity Discount](https://pages.stern.nyu.edu/~adamodar/pdfiles/papers/liquidity.pdf), pp. 17, 28 to 30, 35 to 36 | July 2005 |
| Target returns of venture investors by stage | Start-up 50 to 70 %; **first stage 40 to 60 %**; second stage 35 to 50 %; bridge / IPO 25 to 35 %. Actual returns far lower (20-year early-stage VC 21.4 %, all VC 16.9 %, to 2007), the gap being failure risk | Damodaran, [Valuing Young, Start-up and Growth Companies](https://pages.stern.nyu.edu/~adamodar/pdfiles/papers/younggrowth.pdf), Tables 2 and 3, p. 15 (the paper gives no source line for Table 2) | May 2009 |
| SET-listed Thai peers, EV/EBITDA and P/E (secondary market-data site) | SCGP (SCG Packaging) 10.1x, 21.0x, EBITDA margin 14.8 %; TPAC (Thai Plaspac) **4.7x**, 5.5x, margin 18.0 %; SITHAI (Srithai Superware) 3.2x, 7.3x; GRAMMY (GMM Grammy, music and media) 8.6x, 51.9x | stockanalysis.com statistics pages, e.g. [SCGP](https://stockanalysis.com/quote/bkk/SCGP/statistics/), [TPAC](https://stockanalysis.com/quote/bkk/TPAC/statistics/), [SITHAI](https://stockanalysis.com/quote/bkk/SITHAI/statistics/), [GRAMMY](https://stockanalysis.com/quote/bkk/GRAMMY/statistics/) | 19 to 20 Oct 2026 |
Not used: a bank lending rate. No loan is planned, the methods below need
none, and none is on file for this project.
## Method
All amounts in M THB unless stated; EBITDA converted at 33 THB/USD.
Multiples are used unrounded (4.69x, 13.33x, 14.92x), so a hand check with
the rounded figures can differ by 1 or 2 THB a share.
- **A. Founding round at par, pari passu, all equity.** Everyone pays the
same price, par, in money (or in kind at the same value). Share capital
= the plan price; shares = capital / 100 THB; the lead investor's 60 %
and the 40 % in shares and THB. Plan B at ~217M, Plan B before the
reserve (201.6M) and Plan A (~182M) as the comparison. The capital is
registered in full and called in instalments: at least 25 % on
subscription (section 1105), the rest by the directors (section 1120)
against the tranche gates of business plan section 8.3.
- **B. Development premium.** Work and money spent before the round
(phase 0 at 1.3M to 2.6M THB; design, vendor work, the platform
software) credited as a pre-money value P of 0, 1.3, 2.6, 5, 10 or 20M.
The new cash C is Plan B's 217M. Post-money = P + C. With the share
count held at the par case (2,170,000), the cash pays (P + C) /
2,170,000 a share, the developers receive P / that price in shares paid
otherwise than in money, and the 40 % costs 0.4 x (P + C). A pre-money
credit and shares at par for the same amount give the same ownership;
the table shows it as a price because that is how a co-investor sees it.
- **C. Value once the plant runs** (mature year, ~year 4 to 5).
Enterprise value = mature-year EBITDA x EV/EBITDA; **net debt 0**, so
equity value = enterprise value; minority stake in a private company:
less a 20 to 35 % illiquidity discount (the restricted-stock range and
the court's 20 %); per share on the 2,170,000 shares. No cash is netted
either: cash the plant earns by then is assumed paid out or spent on
growth (the second Duplex is funded from revenue); cash kept in the
company would add to every value. Three multiples: **4.7x**, the median
of the three SET-listed plastics and packaging peers (TPAC, SITHAI,
SCGP); **13.3x**, Emerging Markets Packaging & Container, the closest
industry; **14.9x**, the median of the five EM industries (Machinery's
25.0x reflects machine builders and is not used on its own). EBITDA:
adverse, central, favourable, plus a cross-check at an industry-norm
margin: 20 % (the middle of the 15 to 25 % in the revenue model; the SET
peers earn 15 to 18 %) of central revenue, 0.73M USD. One sensitivity
table shows the same cases if a loan were added later at the 3:1
ceiling (equity 54.25M, 542,500 shares, debt 162.75M, nothing repaid).
- **D. Price a financial co-investor would pay today (venture-capital
method).** Post-money value today = equity value in year 5 from C
(net debt 0), before the illiquidity discount (the target returns
already price illiquidity and failure), divided by (1 + r) to the
fifth. Pre-money = post-money minus the 217M paid in; the justified
price per share = 100 THB x post-money / 217M. **Stage: first stage, 40
to 60 %.** The technology is proven (vendor presses, galvanics and
cutting lines in use elsewhere) and the product is known, so this is
not a start-up inventing a product; but there is no plant, no customer
and no validated price (roadmap item 1 is open), so it is not second
stage. Start-up rates (50 to 70 %) apply if market validation fails to
produce buyer prices; second-stage rates once the plant runs and sells.
Cross-check: a CAPM cost of equity, 2.30 % + beta x 6.18 %, with the EM
**unlevered** beta as it stands (no debt, so no relevering): Packaging
& Container 0.61, cost of equity **6.1 %**; Total Market 0.85, **7.5 %**.
CAPM prices market risk only: nothing for size, illiquidity or a plant
not yet built, which is what the gap to the venture targets measures.
The 10-year yield contains Thailand's default spread; netting it out,
as Damodaran does, would lower both by about 1.3 points, so the gross
yield is the cautious choice.
- **E.** The calculator's project return, which with no loan is also the
shareholders' return, against these rates.
## Results
### A. Founding round at par, pari passu, all equity (estimate)
| Case | Share capital | Shares at 100 THB | Lead investor, 60 % | Co-investors, 40 % | 25 % first payment (40 %'s part) |
|---|---|---|---|---|---|
| **Plan B, all equity** (~217M) | **217.0M** | **2,170,000** | 1,302,000 shares, **130.2M** | 868,000 shares, **86.8M** | 54.25M (21.7M) |
| Plan B before the reserve | 201.6M | 2,016,000 | 1,209,600 shares, 121.0M | 806,400 shares, 80.6M | 50.4M (20.2M) |
| Plan A, all equity (comparison) | 182.0M | 1,820,000 | 1,092,000 shares, 109.2M | 728,000 shares, 72.8M | 45.5M (18.2M) |
The price is **100 THB a share in every row**; a larger plan means more
shares, not a different price. At the legal minimum par of 5 THB Plan B
would be 43,400,000 shares at 5 THB: the same money for the same 40 %. In
practice the registered capital is set to a round figure. The 40 % at
par, ~86.8M THB, matches the plan's "at most ~87M" (total investment,
Funding paragraph; business plan 12.2).
**Which calls fall when** (illustrative; the calls follow the actual
tranche releases). The tranche shares of business plan section 8.3 are
ranges of the 201.6M before the reserve; the reserve is drawn from
tranche 4 on. Phase 0 (tranche 0) is spent before the company exists: in
the project calendar the company is incorporated after the BOI
certificate, so the promoters pay phase 0 and the statutory meeting
ratifies it (section 1108), reimbursed from the first call or credited as
shares at par (B).
| Call | When | Tranche need, M THB (share of 217M) | Call, share of 217M | Call, M THB | Lead investor, 60 % | The 40 % |
|---|---|---|---|---|---|---|
| 1 | On subscription, at incorporation: tranche 1 (BOI certificate, lease, zoning, soil, pricing validated) with phase 0 | 41.6 to 63.1 (19 to 29 %) | **25 %**, the legal minimum | 54.25 | 32.55 | 21.70 |
| 2 | Tranche 2: building permit, vendor build dates in writing | 70.6 to 90.7 (33 to 42 %) | 40 % | 86.80 | 52.08 | 34.72 |
| 3 | Tranche 3: building watertight, first machinery shipped | 30.2 to 40.3 (14 to 19 %) | 20 % | 43.40 | 26.04 | 17.36 |
| 4 | Tranche 4: metal path commissioned, first stampers; the reserve | 26.1 to 44.2 (12 to 20 %) | 15 % | 32.55 | 19.53 | 13.02 |
| | **Total** | | **100 %** | **217.00** | **130.20** | **86.80** |
The 25 / 40 / 20 / 15 split is one fit to the tranche ranges, rounded to
add up to 100 %; it is arithmetic, not a schedule. If tranche 1 lands at
its high end, the first payment is set above the 25 % minimum (~29 %) or
the second call comes forward. Each call needs at least 21 days' notice
(section 1121), so a call goes out three weeks before the money is due
to a vendor.
### B. Development premium (illustrative)
New cash 217M (all equity); share count held at 2,170,000.
| Pre-money credited | Post-money | Price the cash pays | Premium over par | Shares to the developers (share of company) | The 40 % costs |
|---|---|---|---|---|---|
| 0 (par) | 217.0M | 100 THB | 0 % | 0 | 86.8M |
| 1.3M (phase 0, low end) | 218.3M | 100.6 THB | 0.6 % | 12,923 (0.6 %) | 87.3M |
| 2.6M (phase 0, high end) | 219.6M | 101.2 THB | 1.2 % | 25,692 (1.2 %) | 87.8M |
| 5M | 222.0M | 102 THB | 2.3 % | 48,874 (2.3 %) | 88.8M |
| 10M | 227.0M | 105 THB | 4.6 % | 95,595 (4.4 %) | 90.8M |
| 20M | 237.0M | 109 THB | 9.2 % | 183,122 (8.4 %) | 94.8M |
On a 217M round the pre-round work is a small share of the company: the
phase 0 rows come to 0.6 to 1.2 %. A premium must still rest on
documented costs or assets: invoices for the phase 0 work, time records at
an agreed rate, the platform code and designs handed to the company.
Money already spent on the company's behalf is most simply counted as
capital at par or reimbursed as a promoter's expense ratified at the
statutory meeting (section 1108); either way it gives the same 0.6 to
1.2 %. Credit beyond documented spending is a valuation of work and needs
a basis the other shareholders accept. Whose credit it is matters for the
60/40: founders' in-kind shares come out of the 40 % (at 10M they would be
4.4 % of the company, leaving 35.6 % for Ploy Printing and others), the
lead investor's out of the 60 %. **For a company without a plant or
revenue, the defensible default is par.**
### C. What a share could be worth once the plant runs (estimate)
Mature year, **net debt 0** (all equity), 2,170,000 shares paid at 100
THB. Each cell: enterprise value, which is also the equity value; value
per share after a 35 % to 20 % illiquidity discount; in brackets, the
multiple on the 100 THB paid.
| Mature-year EBITDA | Thai listed peers, 4.7x | EM packaging, 13.3x | EM industry median, 14.9x |
|---|---|---|---|
| **Adverse**, 0.23M USD (7.6M THB) | 35.6M: **11 to 13 THB** (0.1x) | 101.2M: **30 to 37 THB** (0.3 to 0.4x) | 113.2M: **34 to 42 THB** (0.3 to 0.4x) |
| Industry-norm margin, 20 % of central revenue, 0.73M USD (24.1M THB) | 113.0M: 34 to 42 THB (0.3 to 0.4x) | 321.1M: 96 to 118 THB (1.0 to 1.2x) | 359.4M: 108 to 133 THB (1.1 to 1.3x) |
| Central, 1.73M USD (57.1M THB) | 267.8M: **80 to 99 THB** (0.8 to 1.0x) | 761.0M: 228 to 281 THB (2.3 to 2.8x) | 851.8M: 255 to 314 THB (2.6 to 3.1x) |
| Favourable, 3.79M USD (125.1M THB) | 586.6M: 176 to 216 THB (1.8 to 2.2x) | 1,667.2M: 499 to 615 THB (5.0 to 6.1x) | 1,866.0M: 559 to 688 THB (5.6 to 6.9x) |
What this means, plainly:
- **Without a loan the shares keep some value in the adverse case, but
lose most of it**: 11 to 42 THB for every 100 THB paid, a loss of 58 to
89 %. Nothing is owed ahead of the shareholders, so the plant's value
is theirs; at the adverse EBITDA that value is small.
- **At Thai listed multiples even the central case is below par** (80 to
99 THB), and so is an industry-norm margin at that multiple (34 to 42);
at the EM multiples the industry-norm margin is about par (96 to 133
THB). Only the central case at an EM-industry multiple (2.3 to 3.1x)
and the favourable case (1.8 to 6.9x) put a share clearly above what
was paid.
- **The large multiples of the earlier version of this page (7 to 25x
par) came from leverage**, not from the plant: with three quarters
borrowed, the same enterprise value, less the debt, was spread over a
quarter of the shares. The table below shows that case.
- The choice of multiple moves the result more than anything else: Thai
listed plastics and packaging companies trade at 3 to 10x EBITDA, the
EM industries at 12 to 25x.
**If a loan were added later (sensitivity, not the plan).** Equity at the
3:1 ceiling, 54.25M (542,500 shares at 100 THB), debt 162.75M, nothing
repaid, no loan terms assumed; value per share after the discount:
| Mature-year EBITDA | 4.7x | 13.3x | 14.9x |
|---|---|---|---|
| Adverse | ~0 (equity -127.2M) | ~0 (equity -61.6M) | ~0 (equity -49.5M) |
| Industry-norm margin | ~0 (equity -49.8M) | 190 to 234 THB (1.9 to 2.3x) | 236 to 290 THB (2.4 to 2.9x) |
| Central | 126 to 155 THB (1.3 to 1.5x) | 717 to 882 THB (7.2 to 8.8x) | 826 to 1,016 THB (8.3 to 10.2x) |
| Favourable | 508 to 625 THB (5.1 to 6.3x) | 1,803 to 2,219 THB (18 to 22x) | 2,041 to 2,512 THB (20 to 25x) |
Leverage multiplies the good cases and wipes the shares out in the bad
ones: the adverse case and an industry-norm margin at Thai listed
multiples leave nothing for the shareholders once the debt is repaid,
where all equity leaves 11 to 42 THB. Any interest and repayment would
change these values either way; none is assumed.
### D. What a financial co-investor would pay today (estimate)
Year-5 equity value from C (net debt 0, before the illiquidity discount),
discounted over five years. Price per share justified against par (100
THB); a price above 100 means the round could carry a premium at that
return, below 100 means par is already rich.
| Year-5 equity, central case | First stage 40 % | First stage 60 % | CAPM 6.1 % | CAPM 7.5 % |
|---|---|---|---|---|
| 4.7x, 267.8M | post-money 49.8M, **23 THB** | 25.5M, **12 THB** | 199.3M, 92 THB | 186.2M, 86 THB |
| 13.3x, 761.0M | 141.5M, **65 THB** | 72.6M, **33 THB** | 566.5M, 261 THB | 529.1M, 244 THB |
| 14.9x, 851.8M | 158.4M, **73 THB** | 81.2M, **37 THB** | 634.0M, 292 THB | 592.2M, 273 THB |
Other cases at the first-stage rates (40 % / 60 %): **adverse 3 / 2 THB
at 4.7x, 9 / 4 at 13.3x, 10 / 5 at 14.9x**; industry-norm margin 10 / 5,
28 / 14 and 31 / 16 THB; favourable 50 / 26 THB at 4.7x, 143 / 73 at
13.3x, 160 / 82 at 14.9x. So a purely financial investor at first-stage
target returns would pay **below par in every case but one**: the
favourable case at an EM multiple and the lower 40 % rate (143 to 160
THB). In the central case it would pay 12 to 73 THB, in the adverse case
2 to 10. Pre-money values are negative wherever the price is below 100
(for example -75.5M at 13.3x and 40 % in the central case). At the CAPM
cost of equity, which prices market risk only, the central case is
worth 86 to 292 THB today and the adverse case 11 to 39 THB. Ploy
Printing as a supplier and the founders as operators have reasons to
hold at par that a purely financial investor does not.
### E. Cross-check with the calculator
With no loan, **the shareholders' return is the project return**: the
calculator's ~22 % IRR (pre-tax, no terminal value) and ~4.7M USD NPV at
its 10 % discount rate are what the 217M of share capital (6.56M USD in
year 0) earns before tax on the calculator's picture. That clears the
CAPM cost of equity (6.1 to 7.5 %) and the calculator's 10 %, is close to
the returns venture funds actually earned (16.9 to 21.4 %, Damodaran
Table 3), and sits well below the 40 to 60 % first-stage targets, so the
calculator alone would not support a premium to a financial investor.
The 20 % corporate income tax (Group B, no CIT holiday on the core
activity) lowers it: a rough check, tax on the calculator's yearly cash
less straight-line depreciation over its 12.5 years (0.49M USD a year),
gives **~18 % after tax** (estimate). The calculator's cash view is
itself well above the revenue model's central EBITDA (2.23M against
1.73M USD), so this return is not the honest case either; in the adverse
case EBITDA pays the price back in ~37 years (revenue model).
## What it means
- **A founding round pari passu at par is the defensible default.** Until
the plant exists, a share is worth the cash behind it. At par (100 THB)
the 40 % is 868,000 shares for ~86.8M THB of Plan B's ~217M share
capital, and the lead investor's 60 % is 1,302,000 shares for ~130.2M,
the same price for everyone. The memorandum needs no premium clause for
this.
- **A development premium only for documented costs or assets.** Phase 0
money (1.3M to 2.6M THB) is 0.6 to 1.2 % of a 217M round and is most
simply counted as capital at par. Anything above documented spending
is a valuation of work; in-kind shares need their description before
the statutory meeting (section 1108) or a special resolution later
(section 1221), and a premium needs the memorandum's sanction (section
1105).
- **Later entrants pay a market-based price.** Once the plant runs and
its accounts show the real EBITDA, the market multiples put a share
anywhere from a tenth of par to several times par, so shares issued
after the founding round should be priced from results (C and D with
actual figures), not at par. Statutory pre-emption (section 1222) lets
the founding shareholders keep their share of such a round.
- **The 40 % now carries four times the money, and needs protection to
match.** All-equity funding puts ~86.8M THB into the 40 % instead of
~21.7M at the old 3:1 floor, with no lender ahead of it; the adverse
case still loses most of it, while the lead investor controls 60 % of
the votes. Items for the shareholders' agreement: keep statutory
pre-emption and do not waive it in the articles; information rights
(monthly management accounts, the BOI progress and annual reports, the
evidence for each tranche gate before its call); a board seat or
observer for the 40 %; reserved matters; and keep the three-quarters
threshold for special resolutions (section 1194), which already gives
the 40 % a say on capital increases, in-kind allotments and changes to
the memorandum.
- **The call schedule belongs in the agreement.** The directors make the
calls (section 1120) and the 60 % appoints most of them, so the
agreement should tie each call to its tranche gate (business plan 8.3),
make every call pro rata to all shareholders on the same date, and say
what happens when a shareholder misses one. The Code's route is
interest from the due date (section 1122), a second notice that can
warn of forfeiture (1123), forfeiture (1124) and a public auction of
the forfeited shares, the surplus returned (1125). The agreement can
add who may take up a missed call or the forfeited shares first, so a
stake does not pass to an outside bidder, and evidence that each
shareholder can meet its calls: the lead investor carries 60 % of each
one (~52M THB at the second call), so a missed call there would stall
the build.
## Caveats
- **Not a valuation opinion, not an offer price.** Ranges and scenarios
from public data and the plan's estimates, for discussion. No share
price is agreed; it goes into the shareholders' agreement.
- **No loan is planned and no loan terms are on file.** The levered table
in C is a sensitivity at the most the 3:1 rule allows; no interest
rate, schedule or debt-service figure is assumed.
- **The extra cost of specials is not modelled** in the revenue model's
direct cost, so every EBITDA here is an upper bound until compound
quotes exist.
- **Central is optimistic, adverse is honest.** The central EBITDA margin
(~47 %) is far above the 15 to 25 % pressing plants earn and the 15 to
18 % of the SET peers; the industry-norm row shows the difference.
- **Contingency is not in the price.** At 15 % (~30M THB), an overrun
funded by the shareholders at par adds ~300,000 shares at 100 THB
(pro rata, the 60/40 holds) and lowers every per-share value in C and D
by about an eighth; funded by a loan, it would add net debt instead.
- **Cash is not counted.** Net debt 0 nets no cash: cash the plant earns
before year 5 is assumed paid out (a return of its own, not in C) or
spent on growth; cash kept in the company adds to the values.
- **Market multiples are for listed companies**, most of them far larger
than this plant; a small private company would usually be priced below
them (estimate). The illiquidity discount covers part of that, not all.
Damodaran's Emerging Markets set (27,360 firms) spans many countries and
is not a Thai benchmark; the Thai listed peers are only three plastics
and packaging companies, read from a secondary market-data site.
- **Taxes and BOI**: EV/EBITDA is a pre-tax measure; the calculator is
pre-tax. The after-tax return in E assumes no CIT holiday on the core
activity (Group B, [BOI](../boi.md)); any upgrade-measure exemption
would raise it somewhat.
- **Timing**: year 5 after the round is the plant's third or fourth year
of sales (the build takes ~1.5 to 2 years), so a mature-year EBITDA by
then is itself optimistic; each extra year of delay divides D's values
by a further 1.4 to 1.6 at the first-stage rates. The calculator puts
all 6.56M USD in year 0; calling the capital over the build changes the
IRR a little either way.
- **Law**: the Code summaries are from English translations checked
against the Thai text online; Thai counsel confirms them in phase 0,
along with the call and forfeiture mechanics in the articles and how
BOI counts in-kind capital.
+324 -28
View File
@@ -4,40 +4,324 @@ Everything priced or estimated so far, rolled into one view. Blocks marked
"estimate" have no vendor confirmation; the rest trace to quotes or the "estimate" have no vendor confirmation; the rest trace to quotes or the
researched ranges in this repo. Treat all figures as budgetary with a wide researched ranges in this repo. Treat all figures as budgetary with a wide
margin (plus or minus 30 to 50% on the estimates) until RFQs replace them. margin (plus or minus 30 to 50% on the estimates) until RFQs replace them.
FX: ~38 THB/EUR. Compiled July 2026.
## Full vision, all blocks **Currency: USD and THB.** FX at 5 August 2026: **1 USD = 33 THB**.
Vendor quotes issued in another currency are kept in that currency
wherever they appear next to their source document, and converted here at
**1 EUR = 1.155 USD** and **1 GBP = 1.35 USD**. Original figures compiled
July 2026; the underlying THB estimates are unchanged, because EUR/THB at
~38 is where it was when they were made.
| Block | Low (EUR) | High (EUR) | Basis | ## Launch plant (October 2026)
Decided (user, October 2026): the plant launches **with everything in one
capital round**, commissioned in sequence, with no bridge stampers and no
outsourced cutting:
- one **Newbilt Duplex** system: two HRP 12 semi-automatic presses, an
EX 50 main and an EX 35 colour extruder
([pressing line](../equipment/pressing-line.md));
- one **Newbilt Classic** fully automatic press;
- one **Pheenix Alpha** galvanics line (PASU, PPPU, one PDPU, PMPB) with
zero-discharge water treatment
([galvanics and stamper prep](../equipment/galvanics.md));
- the **Sibert** stamper-prep line (VSF, VSP, VSC);
- a **Sillitoe SDMS** cutting room
([vendor landscape](../suppliers/vendor-landscape.md#mastering-and-cutting-sillitoe-audio-technology-australia));
- the **modular steam and cooling plant**: two 500 kg/h boiler modules and
two 250 kW chiller modules, in a boiler hall and a chiller compound
built for four each ([scale](../scale.md#utility-phasing-backbone-once-modules-with-the-presses)).
Cassette and CD-R duplication stay in. The second Duplex system and the
further Classics are growth options with room reserved, not in this
investment. Three presses make roughly 0.7 to 0.95 million records a year
on two shifts (estimate: the [scale](../scale.md) basis gives ~0.71 to
0.97 million, the planning rates of the
[fleet calculator](../fleet-calculator.html) ~0.94 million).
| Block | USD | THB | Basis |
|---|---|---|---| |---|---|---|---|
| Newbilt semi-auto line, full Duplex | 300,000 | 320,000 | 2024 quote 200,500 + quoted 2nd press/extruder ~100,000; expired, needs re-quote | | Phase 0: BOI consultant, legal and lease work, soil test, re-quotes | 40k – 80k | 1.3M – 2.6M | estimate |
| 2 automated presses (Pheenix AD12) | 500,000 | 800,000 | unverified ~$340k/press indicative + delivery and commissioning | | Newbilt Duplex system (two HRP 12, EX 50 + EX 35, trimmer, label oven, shrink wrapper, grinder, label punch) | 350k – 370k | 11.6M – 12.2M | 2024 quote EUR 200,500 for the Single 2.1 plus the quoted second press and extruder ~USD 115k; expired, re-quote |
| Galvanics line (Digital Matrix) | 280,000 | 560,000 | six-figure-USD turnkey inference from vendor research | | Newbilt Classic | 290k – 460k | 9.6M – 15.2M | placeholder (the old AD12 band per press); **no Newbilt price on file** |
| Zero-discharge water treatment (ZLD) | 80,000 | 210,000 | utilities CSV option row, 3-8M THB | | Pheenix galvanics line (PASU, PPPU, PDPU, PMPB) | 324k – 445k | 10.7M – 14.7M | **OMS's reference plus 20 %** (user, October 2026): OMS's 4-cell wet room with the know-how transfer, EUR 234k to 321k (~USD 270k to 371k, [galvanics](../equipment/galvanics.md#oms-introduction-letter-9-october-2026)), as the price basis for the Pheenix line; **no Pheenix price on file** (was 320k to 650k, estimate) |
| Stamper prep (Sibert VSP, VSF, VSC) | 50,000 | 150,000 | estimate, pricing unpublished | | Galvanics water: ZLD evaporator and DI water | 97k – 258k | 3.2M – 8.5M | [utilities CSV](utilities-investment.csv) rows, now launch scope |
| Mastering and cutting room (Agnew lathe and head, cutter amps, console, room treatment) | 250,000 | 500,000 | estimate, bespoke market | | Water-treatment building next to galvanics (~12 × 10 m, proposed) | 52k – 87k | 1.7M – 2.9M | estimate at the building rate below |
| Metrology and QC stack (confocal, profiler, XRF, inline vision, audio station) | 300,000 | 700,000 | estimate, phaseable | | Sibert VSF, VSP, VSC | 250k | 8.3M | Sibert's budget confirmation, 5 October 2026; its time, spares, shipping and travel in the freight and working-capital lines |
| Utilities, solar, HVAC, racking baseline | 630,000 | 1,100,000 | reviewed utilities CSV, 23.98-41.63M THB | | Cutting room: Sillitoe SDMS, spare cutterhead and support, mastering console and chain, monitoring, room build-out | 200k – 350k | 6.6M – 11.6M | SDMS list price USD 125k (ex tax and shipping); the rest estimate |
| Building ~1,500 m² plus civil works | 560,000 | 950,000 | estimate at 12,000-20,000 THB/m² Thai industrial construction plus ~20% site works | | Metrology and QC stack (XRF, laser confocal, wide-area profiler, inline vision on three presses, audio station) | 350k – 810k | 11.6M – 26.7M | estimate, phaseable ([quality automation](../quality-automation.md)) |
| Land 6-8 rai, if purchased | 315,000 | 840,000 | estimate at 2-4M THB/rai industrial; leasing cuts this to near zero upfront | | PVC lab, day-one tier | 55k – 150k | 1.8M – 5.0M | estimate, [quality automation](../quality-automation.md) |
| Traceability and factory software | 50,000 | 150,000 | estimate | | Utilities, steam, solar, battery, HVAC, clean zones, racking | 1,045k – 1,764k | 34.5M – 58.2M | [utilities CSV](utilities-investment.csv) baseline re-sized for three presses: chiller bank two modules instead of three; **biomass steam** (two 500 kg/h modules, 6M to 10M THB, plus the fuel store and handling, 1M to 2M) and **PV on the factory roof** (~520 kWp at 20 to 26 THB/W installed; office roof and parking canopies PV-ready), both user decisions of 17 October 2026; the battery installed (Thai market prices checked October 2026, sources in the CSV) |
| Freight, installation, training (non-Newbilt equipment) | 100,000 | 200,000 | estimate | | Building ~1,500 m² plus civil and site works | 650k – 1,100k | 21.4M – 36.3M | estimate at 12,000 – 20,000 THB/m² plus ~20 % site works; soil is the main variable |
| Working capital, PVC stock, spares | 100,000 | 200,000 | estimate | | Overhead crane, runway, frame premium, machine door | 97k – 227k | 3.2M – 7.5M | estimate, [crane, workshop and tours](../crane-workshop-tours.md) |
| Subtotal | ~3,500,000 | ~6,700,000 | | | Maintenance workshop and machine bay fit-out | 30k – 76k | 1.0M – 2.5M | estimate, same |
| Contingency 15% | ~500,000 | ~1,000,000 | | | Visitor corridor and accessible entrance | 67k – 148k | 2.2M – 4.9M | estimate, same |
| **Total, full vision** | **~4,000,000** | **~7,700,000** | **~150M to 290M THB** | | Utility yard built for four boiler and four chiller modules | 73k – 122k | 2.4M – 4.0M | estimate, [scale](../scale.md#detached-utility-yard-parking-and-what-that-moves) |
| Factory software, ERPNext, artist platform public side | 115k – 310k | 3.8M – 10.2M | estimate: factory software 60k – 170k, ERPNext implementation 15k – 50k ([digital factory](../digital-factory.md#erpnext-the-plants-erp)), artist platform 40k – 90k ([artist platform](../artist-platform.md)) |
| Cassette duplication and CD-R duplication | 55k – 190k | 1.8M – 6.3M | estimate, business plan sections 4.8 and 4.9 |
| Freight, installation, commissioning, training (Pheenix, Sibert, Sillitoe, Newbilt beyond its quoted 5 days) | 150k – 300k | 5.0M – 9.9M | estimate |
| Working capital, PVC stock, spares, lease deposit, first-year rent | 135k – 290k | 4.5M – 9.6M | estimate; land is leased, so no land purchase |
| Subtotal | ~4.42M – 7.79M | ~146M – 257M | midpoint ~6.11M USD, ~202M THB |
| Contingency 15 % | ~0.66M – 1.17M | ~22M – 39M | |
| **Total, launch plant** | **~5.1M – 9.0M USD** | **~168M – 296M THB** | midpoint ~7.02M USD, ~232M THB |
## Phased entry Not in the total: a **reserve for the ramp-up** (staff hired before first
revenue, overheads until volume covers them; ~10M to 20M THB, estimate),
CD replication, financing costs, currency moves, the archive's mobile
shelving (to quote), and the central hydraulic plant around the Newbilt
aggregates: standby pump set, accumulator station and ring main (not
costed yet; a Thai HPU builder quotes it,
[Chinese suppliers](../suppliers/china-utilities.md#hydraulics)). The blocks are vendor prices without Thai duty or
import VAT, so they assume BOI promotion: without it, ~5 % duty on ~2.3M
USD of imported machinery (~0.11M USD) comes on top, plus ~0.17M USD of
import VAT paid at the border and reclaimed later (estimates).
A credible launch phase is far smaller, roughly **1.5M to 2.5M EUR**: ### The investor's question: 180M THB, maybe 20 % more (October 2026)
*Superseded by [Two plans](#two-plans-a-at-180m-thb-and-b-at-215m-thb-october-2026)
below. Written against the earlier Pheenix estimate (USD 320k to 650k,
total ~227M THB at the midpoint); its galvanics lever is now the base
price.*
The project's investor asked whether the plant can be built for **180M
THB (~5.45M USD), possibly up to 20 % more (216M THB, ~6.55M USD)**.
| Case | Launch plant | Against 180M | Against 216M |
|---|---|---|---|
| Low end of every block | ~161M THB | fits, ~19M to spare | fits |
| Midpoint | ~227M THB | ~47M over | ~11M over |
| High end of every block | ~292M THB | ~112M over | ~76M over |
**Read honestly: 216M THB is a realistic target for the full equipment
list; 180M THB holds only if the open quotes land low.** At the midpoint
four levers bring the plant inside 216M without dropping any of the
machines decided above (midpoint values with their share of the
contingency, estimates):
| Lever | Saves | Launch plant after it |
|---|---|---|
| Rooftop solar and battery through a solar PPA (the EPC owns and finances the array, the plant buys the power) instead of buying them | ~12.3M THB | ~214M THB |
| Metrology launch tier (XRF, inline vision, audio station), the laser confocal and the wide-area profiler bought from revenue | ~10.1M THB | ~204M THB |
| Pheenix galvanics priced near OMS's reference for a 4-cell wet room | ~6.7M THB | ~198M THB |
| Visitor corridor built later; the plant runs without public tours at first | ~4.1M THB | ~193M THB |
Add the ramp-up reserve of ~10M to 20M THB and that is **~203M to 213M
THB, inside the 216M**. Reaching 180M at the midpoint needs scope cuts on
top: cassette and CD-R later (~4.6M THB) and renting a crane for the
installations while the frame stays crane-ready (~3.7M THB) give ~185M
before the reserve, still above 180M, so 180M is a low-quote outcome, not
a plan.
Chinese suppliers for the boilers, compressed air and hydraulics were
checked in October 2026
([Chinese suppliers](../suppliers/china-utilities.md)): about 2M THB at
the midpoint, ~2.5M with its share of the contingency, mostly on the two
boiler modules (ASME-stamped 1.25 MPa units from makers with Thai
references, installed by a Thai contractor) and a little on the
compressor (a Chinese brand bought through its Thai office). That is
about 1 % of the target and does not change the answer; the Newbilt
hydraulic aggregates stay Newbilt's. Chinese chillers and HVAC, larger
blocks, are not checked yet.
What decides it: the two largest machine lines have no price at all (the
Classic and the Pheenix galvanics line), and the building depends on the
soil. Four requests settle most of the band: the Newbilt re-quote for the
Duplex and the Classic, a Pheenix quote for the galvanics line, the
building RFQ with a soil test, and distributor quotes for the metrology
stack. Until they are in, quote **~216M THB** to the investor as the
target with the levers above, and 180M as the low-quote case.
## Two plans: A at ~180M THB and B at ~215M THB (October 2026)
**The main investor wants to go with Plan B** (user, 19 October 2026).
Plan B is the proposal from here on: the investor deck leads with it,
and Plan A stays as the comparison, the version with the lowest launch
capital. Nothing in either plan's figures changes with that choice.
**Shareholding (user, 20 October 2026): the main investor holds at least
60 % of the company** that holds the plant and the BOI promotion, so at
most **40 % is for sale** to other shareholders. Ploy Printing's stake
(cash, in kind or both), any founders' shares and any further
co-investor all come out of that 40 %. BOI promotion permits up to 100 %
foreign ownership of the promoted activity ([BOI](../boi.md)), so the
split needs no particular nationality on either side.
**Funding (user, 20 October 2026): the shareholders fund the whole plant
and get shares for it; no bank loan is planned.** Plan B's ~217M THB is
paid in as share capital, so at one share price the main investor's 60 %
is at least **~130M THB** and the 40 % at most **~87M THB** (~121M and
~81M on the 201.6M before the ramp-up reserve; Plan A for comparison:
~109M and ~73M of ~182M). Arithmetic only: the share price, any
founders' or in-kind shares and the call schedule are not agreed. BOI's
3:1 debt-to-equity ceiling is met with room to spare (no debt), so it no
longer sets an equity floor; the machinery, and in Plan B the owned PV
array and battery, stay unpledged and could secure a loan later if one
is ever needed. Thai company law lets the capital be registered in full
and called in instalments (at least 25 % on subscription, the rest called
by the directors), which fits releasing the money in tranches against
milestones. The terms go into the shareholders' agreement (business plan
section 12.2). Possible share prices from market data:
[share price](share-price.md).
Decided (user, October 2026): the business plan comes in **two
versions** for the investor, built from the same documents:
- **Plan A, ~180M THB**: the launch plant with every machine decided
above (one Duplex system, one Classic, galvanics, Sibert, the cutting
room), brought down with six cost levers.
- **Plan B, ~215M THB**: the same launch plant, one Duplex system and
one Classic, with everything in: none of Plan A's six levers taken.
First drawn as five presses at ~225M THB (Plan A plus 25 %); re-defined
by the user on 17 October 2026 ("plan b should also only start with 1
duplex and 1 classic, but with all levers"). In both plans the second
Duplex system is a growth step from revenue.
- **Both run on biomass steam, with PV on the factory roof only**
(user, 17 October 2026: "only put solar on the factory, prepare the
other buildings for solar, option a and b should operate on biomass").
The office roof and the parking canopies are built PV-ready. With
biomass the plant's running load falls to ~230 kW, so the best array
is ~500 to 550 kWp ([sustainability](../sustainability.md#pv-size-with-biomass-steam)),
about the ~520 kWp factory roof. Against the earlier electric steam
and ~640 kWp, in Plan B the biomass boilers and fuel store add ~3.8M
at the midpoint over the Thai electric bank and the smaller array saves
~2.8M, so it rises from ~216M to **~217M**; Plan A leases the array and
had the cheaper Chinese electric boilers, so it takes the full ~5.4M,
from ~177M to **~182M**. Biomass saves ~4.2M THB a year of steam energy
(calculator).
Both are priced **without contingency** (user decision) and **with the
ramp-up reserve**, because the reserve is cash the investor puts in
before volume carries the plant. Pheenix galvanics is priced at OMS's
reference plus 20 % in both. Midpoints, estimates:
| Plan A: launch plant with six levers | Saves | Subtotal after it |
|---|---|---|
| Launch plant, every block, no contingency | | ~201.6M THB (~6.11M USD) |
| Solar (~520 kWp on the factory roof) and battery through a solar PPA (the installer owns and finances the array, the plant buys the power) | ~14.7M | ~186.9M |
| Metrology launch tier: XRF, inline vision and audio station at launch; laser confocal and wide-area profiler (USD 180k to 350k) bought from revenue | ~8.8M | ~178.1M |
| Visitor corridor built later; no public tours at first | ~3.6M | ~174.5M |
| Cassette and CD-R duplication later | ~4.0M | ~170.5M |
| Crane rented for the installations; frame, runway and machine door stay crane-ready | ~3.2M | ~167.3M |
| Compressor through the Chinese route ([Chinese suppliers](../suppliers/china-utilities.md)); the route priced only electric boilers, so with biomass it saves only the compressor | ~0.25M | **~167.1M (~5.06M USD)** |
| Ramp-up reserve | | +10M to 20M |
| **Plan A** | | **~182M THB (~5.52M USD)**, ~2M above 180M at the midpoint (177M with the reserve's low end); ~132M to 233M from the low to the high end of every block |
| Plan B: the launch plant, everything in | USD | THB |
|---|---|---|
| Launch plant, every block, no contingency (the six lever items included: owned solar (~520 kWp) and battery ~14.7M, full metrology ~8.8M, visitor corridor ~3.6M, cassette and CD-R ~4.0M, bought crane ~3.2M, Thai compressor ~0.25M, together ~34.5M THB at the midpoint) | 4.42M – 7.79M | ~146M – 257M, **~201.6M (~6.11M USD)** at the midpoint |
| Ramp-up reserve | | +10M to 20M |
| **Plan B** | | **~217M THB (~6.56M USD): ~215M**, ~156M to 277M from the low to the high end of every block |
Plan B costs ~35M THB (~19 %) more than Plan A and, at the midpoint,
sits ~0.6M above the investor's 180M THB plus 20 % (216M) and 8.4M under
the 225M mark (its high end, ~277M, is above both). It keeps what Plan A leases or defers:
owned solar on the factory roof and the battery, the full
metrology stack from the first release, the visitor corridor and tours
from the start, cassette and CD-R, the bought crane, Thai-supplied
utilities with local service. Both plans have the same three presses and
make the same ~0.58 to 0.90 million records a year at the planned 60 %
specials (Duplex-limited); the operating pictures are in the
[revenue model](revenue-model.md#operating-pictures-of-plan-a-and-plan-b-october-2026).
The [plant and business plan calculator](../fleet-calculator.html) has
both as presets.
**Not in either plan price:**
- **Contingency.** The blocks are budgetary (plus or minus 30 to 50 % on
the estimates, top of this page), so the plans carry no buffer for
quotes landing high. At this page's 15 % that would be ~25M THB on
Plan A and ~30M on Plan B at the midpoint.
- The central hydraulic plant (not costed yet), the archive's mobile
shelving (to quote), CD replication, financing costs, currency moves,
and Thai duty and import VAT (the blocks assume BOI promotion).
**What decides between them:** not demand, since both make the same
records, but whether the investor funds ~35M THB more at launch for what
Plan A leases or buys from revenue. On the modelled numbers Plan B's
extra earns little: the same EBITDA in the revenue model (the calculator
puts Plan B ~0.06M USD a year ahead, the PPA power bill its owned array
avoids), more depreciation and a longer payback;
its case rests on that bill and on what the operating table leaves out:
full stamper metrology for the traceability pitch from the first release,
tours and the Payap programmes from day one, cassette and CD-R sales, and
utilities with local service. The BOI no longer promotes solar
installations (Announcement 3/2568, in force 1 July 2025; only the
battery may still qualify, see [BOI](../boi.md)), so owning the array
earns no tax benefit, only the bill. Most of Plan B's items can be added
to Plan A later from revenue; the corridor is cheaper to have from the
start. **Plan A over 180M:** the way back is a quote for a Chinese
biomass boiler (ZOZEN, Sitong, Taiguo and Yongxing build them; none
priced yet): ~2M or more below the Getabec-class package brings Plan A
to 180M at the midpoint. Both plans keep the second Duplex as a growth step, with its
floor, utility positions and ring-main tees reserved: ~15.4M THB at the
midpoint for the system (~8.7M), a third chiller module CH-3 (~2.1M),
their freight and installation (~1.2M) and the working capital for the
extra records (~3.4M), estimates on the calculator's basis, as first
priced for the five-press Plan B.
## Full vision, all blocks (July 2026, superseded)
The five-press full vision below is superseded by the launch plant above.
Scale, pressing line, roadmap, revenue model (which now has a launch-plant
operating picture) and the fleet calculator are re-based on the launch
plant; the business plan is next. It stays for the record of how the
blocks were built.
| Block | USD | THB | Basis |
|---|---|---|---|
| Newbilt semi-auto line, full Duplex | 350k – 370k | 11.5M – 12.2M | 2024 quote EUR 200,500 (~USD 232k) + quoted 2nd press/extruder ~USD 115k; expired, needs re-quote. The fleet has since changed, see the added-scope table |
| 2 automated presses (Pheenix AD12) | 580k – 920k | 19.1M – 30.5M | unverified ~USD 340k/press indicative + delivery and commissioning. Replaced by the Newbilt Classic in the current fleet, see the added-scope table |
| Galvanics line (Digital Matrix or Pheenix Alpha) | 320k – 650k | 10.7M – 21.4M | six-figure-USD turnkey inference from vendor research; the Pheenix range (2024 flyers, [galvanics and stamper prep](../equipment/galvanics.md)) is unpriced too; OMS's reference prices (letter, 9 October 2026) put a complete 4-cell wet room at EUR 224k basic to 311k advanced (~USD 259k to 359k; ~270k to 371k with know-how transfer), installation and water treatment extra: at or below this block's low end, kept until quotes exist |
| Zero-discharge water treatment (ZLD) | 90k – 240k | 3.0M – 8.0M | utilities CSV option row |
| Stamper prep (Sibert VSP, VSF, VSC) | 60k – 170k | 1.9M – 5.7M | estimate kept until the re-base; Sibert has since confirmed USD 250k for the three (its time, spares, shipping and travel extra), the difference is in the table below |
| Mastering and cutting room (Agnew or Sillitoe lathe system, cutter amps, console, room treatment) | 290k – 580k | 9.6M – 19.1M | estimate, bespoke market; the Sillitoe SDMS lists at USD 125k for lathe, head, amplifier and automation (ex tax, shipping), which makes the low end reachable; band kept until both quotes exist |
| Metrology and QC stack (confocal, profiler, XRF, inline vision, audio station) | 350k – 810k | 11.5M – 26.7M | estimate, phaseable |
| Utilities, solar, HVAC, racking baseline | 730k – 1,270k | 24.0M – 41.6M | reviewed [utilities CSV](utilities-investment.csv), THB-native; sized for one Duplex, the five-press re-size is in the table below |
| Building ~1,500 m² plus civil works | 650k – 1,100k | 21.4M – 36.2M | estimate at 12,000–20,000 THB/m² Thai industrial construction plus ~20% site works |
| Land 6–8 rai, if purchased | 360k – 970k | 12.0M – 32.0M | estimate at 2–4M THB/rai industrial; leasing cuts this to near zero upfront |
| Traceability and factory software | 60k – 170k | 1.9M – 5.7M | estimate |
| Freight, installation, training (non-Newbilt equipment) | 120k – 230k | 3.8M – 7.6M | estimate |
| Working capital, PVC stock, spares | 120k – 230k | 3.8M – 7.6M | estimate |
| Subtotal | ~4.1M – 7.7M | ~135M – 254M | |
| Contingency 15% | ~0.6M – 1.2M | ~20M – 38M | |
| **Total, full vision** | **~4.7M – 8.9M USD** | **~155M – 294M THB** | |
### Added scope, not yet in the roll-up
Decided, or re-priced by a vendor, after the roll-up above was compiled;
carried here until the next re-base folds them into the blocks (the
building, software and stamper prep lines, and the contingency on top).
| Block | USD | THB | Basis |
|---|---|---|---|
| Overhead crane, runway, frame premium, machine door | 97k – 227k | 3.2M – 7.5M | estimate, [crane, workshop and tours](../crane-workshop-tours.md) |
| Maintenance workshop and machine bay fit-out | 30k – 76k | 1.0M – 2.5M | estimate, same |
| Visitor corridor and accessible entrance | 67k – 148k | 2.2M – 4.9M | estimate, same |
| Artist platform, public side (calculator, campaigns, payments) | 40k – 90k | 1.3M – 3.0M | estimate, [artist platform](../artist-platform.md) |
| PVC material lab, day-one tier (incl. plaque press and sample conditioning) | 55k – 150k | 1.8M – 5.0M | estimate, [quality automation](../quality-automation.md); not costed in the metrology block above. The mature tier (torque rheometer, DSC, FTIR, ~120k – 240k) is deferred, with partner labs in between |
| Stamper prep re-priced: USD 250k for VSP, VSF and VSC against the 60k – 170k block above | +190k (low case) / +80k (high case) | +6.3M / +2.6M | Sibert's budget confirmation, email of 5 October 2026 ([galvanics and stamper prep](../equipment/galvanics.md)); itemised quotation to follow. Its time, spare parts, shipping and travel are extra and fall into the freight/installation and spares blocks above |
| Press fleet changed (October 2026) to two Newbilt Duplex systems (two presses each, EX 50 main extruder and EX 35 colour extruder) plus one Newbilt Classic, replacing the two blocks above (930k – 1,290k): Duplex system 1 as the first block (350k – 370k; the quote's second-extruder option becomes the EX 35), system 2 ~230k – 300k (two presses at the quoted ~115k per press and extruder set as the yardstick, plus hydraulic unit and EX 35, estimate; no EX 35 price on file), the Classic ~290k – 460k (the AD12 band per press as a placeholder; no Newbilt price on file) | −60k (low case) / −160k (high case) | −2.0M / −5.3M | estimate, [pressing line](../equipment/pressing-line.md); the Newbilt re-quote replaces it. The utilities for five presses are re-sized in the row below |
| Utilities re-sized for the five-press fleet (October 2026): boiler bank 2 × 500 kg/h, chiller bank 3 × 250 kW with plate heat exchanger and tanks, larger softener and loop treatment ([steam and cooling](../steam-cooling.html)) | +185k (low case) / +294k (high case) | +6.1M / +9.7M | estimate, [utilities CSV](utilities-investment.csv) re-based from 24.0M – 41.6M to 30.1M – 51.3M THB |
| Utility yard built for four boiler and four chiller modules (October 2026): yard ~379 m² against 178 m² ([scale](../scale.md#detached-utility-yard-parking-and-what-that-moves)) | 73k – 122k | 2.4M – 4.0M | estimate: the building rate above on the ~200 m² the yard grows by; the open chiller compound costs less than a building, so this is the cautious end. The valved branches and feeders for the empty positions are not priced yet |
| ERPNext for the whole plant (October 2026): configuration with Thai tax, integration with every tool, Nix packaging; `vinyl-erp` server | to quote | to quote | not in the sum: 3.5 to 6 person-months in-house or a partner quote (Ecosoft), plus 2k to 4k USD hardware ([digital factory](../digital-factory.md#erpnext-the-plants-erp)); no licence fee |
| Archive mobile shelving for the father and mother archive (October 2026) | to quote | to quote | not in the sum: A-Z Solutions publishes no prices; quote it and a Thai supplier ([facility security](../facility-security.md#archive-room-mobile-shelving)) |
| **Added so far** | **~678k – 1,027k** | **~22.3M – 33.9M** | about 13 to 17% on the full-vision subtotal |
## Phased entry (superseded October 2026)
Superseded by the launch plant above, which launches with galvanics, the
cutting room and three presses. The earlier phased entry, kept for
reference: a launch phase of roughly **1.7M to 2.9M USD (~57M to 95M
THB)**:
- Newbilt Single system (not Duplex yet) - Newbilt Single system (not Duplex yet)
- Bridge stampers from Stamper Discs, so no galvanics line at launch - Bridge stampers from Stamper Discs, so no galvanics line at launch
- Basic QC (microscope, benchtop PVC lab, sampled listening), full - Basic QC (microscope, benchtop PVC lab, sampled listening), full
metrology deferred metrology deferred; the PVC lab's day-one tier is the added-scope row
above
- Leased building instead of purchase, modest first solar array - Leased building instead of purchase, modest first solar array
- Galvanics, automated presses, full metrology, and the biomass boiler - Galvanics, the second Duplex system and the Classic, full metrology,
follow as revenue-funded or second-round expansions and the biomass boiler follow as revenue-funded or second-round
expansions
The planning already supports this: the Duplex-ready hydraulics, the The planning already supports this: the Duplex-ready hydraulics, the
bridge-supplier role for Stamper Discs, the staged electric-to-biomass bridge-supplier role for Stamper Discs, the staged electric-to-biomass
@@ -49,12 +333,24 @@ exactly this reason.
- **BOI**: machinery duty exemption applies across most of the equipment - **BOI**: machinery duty exemption applies across most of the equipment
blocks, and the solar and automation spend converts into CIT-exemption blocks, and the solar and automation spend converts into CIT-exemption
headroom; the application precedes every purchase order (see headroom; the application precedes every purchase order (see
[boi.md](../boi.md)) [boi.md](../boi.md)). The blocks are vendor prices without Thai duty or
- **Buy vs lease** on land and building swings roughly 0.9M to 1.8M EUR of import VAT, so the headline assumes promotion: without it, ~0.14M USD of
upfront capital duty and ~0.2M USD of import VAT (reclaimable later) come on top at the
start fleet (estimate)
- **Buy vs lease** on land and building swings roughly **1.0M to 2.1M
USD (~34M to 69M THB)** of upfront capital, and also moves the launch
date by about three quarters; see
[project-timeline.md](../project-timeline.md)
- **Biggest uncertainty bands**: metrology (partly a choice of ambition), - **Biggest uncertainty bands**: metrology (partly a choice of ambition),
the mastering/cutting room (bespoke vendor, no public pricing), the the mastering/cutting room (bespoke vendor, no public pricing), the
automated presses (single unverified price point), and land Newbilt Classic (no price on file), and land
- **Currency exposure is real and is not modelled here.** Revenue is
mostly USD/EUR from export customers, the cost base is mostly THB, and
the largest single equipment block is EUR-denominated and unhedged
against an order that will not be placed for roughly a year (see
[project-timeline.md](../project-timeline.md)). A 10% move in EUR/THB
between now and the Newbilt order is worth ~USD 25–35k on that line
alone. Ask for the re-quote to state its currency and validity period.
- Every band narrows only with RFQs; the supplier map in - Every band narrows only with RFQs; the supplier map in
[equipment-suppliers.md](../suppliers/equipment-suppliers.md) lists who [equipment-suppliers.md](../suppliers/equipment-suppliers.md) lists who
to ask to ask
+17 -16
View File
@@ -1,18 +1,19 @@
category,item,spec_summary,candidate_thai_suppliers,cost_low_thb,cost_high_thb,cost_basis,notes category,item,spec_summary,candidate_thai_suppliers,cost_low_thb,cost_high_thb,cost_basis,notes
steam,Electric/gas once-through boiler package,"~400-500 kg/h at 10 bar / 180 C incl. softener, feed tank, economizer, installed","Miura Thailand (Chachoengsao); Bangkok Industrial Boilers; STE Thailand",2500000,4000000,engineering estimate,"Miura-class modular once-through; BIB budget option ~2.0-3.5M; service is Bangkok-centric, confirm northern dispatch SLA" steam,Electric/gas once-through boiler bank (alternative),"2 x 500 kg/h modules at 10.5 bar / 180 C, lead/lag, shared feed tank, feed pumps, economizer, installed","Miura Thailand (Chachoengsao); Bangkok Industrial Boilers; STE Thailand; Chinese route (October 2026): ZOZEN, Sitong, Fangkuai, Taiguo (ASME claimed, Thai references, no Thai service partner), see suppliers/china-utilities.md",4500000,7000000,engineering estimate,"NOT included in baseline total since 17 Oct 2026 (user: both plans run on biomass); kept as the alternative. Launch plant (October 2026): one Duplex system and one Classic, 450-540 kg/h at Newbilt's 150-180 kg/h per press, so B-1 and B-2 both at launch; the boiler hall is built for four modules (scale.md utility phasing); a third module for N+1 is an RFQ option; Miura-class modular once-through; service is Bangkok-centric, confirm northern dispatch SLA; Chinese route estimate 2.8M-5.5M THB installed (two ASME-stamped 1.25 MPa bodies USD 15k-35k each, inspection and certification, freight, Thai contractor balance of plant), about 1.6M THB less at the midpoint; imported boilers need DIW certification-body verification either way"
steam,Biomass/wood-fired boiler package (option),"~0.5 t/h solid fuel (wood chips/pellets/rice husk) incl. fuel feed, grate, dust control, softener, installed",Getabec PCL (Thai fabrication and service),4000000,7000000,engineering estimate,"Sustainability path matching Deepgrooves NL precedent; Viessmann has no strong Thai channel; higher capex, lower fuel opex in the North; NOT included in baseline total" steam,"Biomass/wood-fired boiler package, 2 x 500 kg/h or one ~1 t/h","~1 t/h solid fuel (wood chips/pellets/rice husk) incl. fuel feed, grate, dust control, softener, installed",Getabec PCL (Thai fabrication and service),6000000,10000000,engineering estimate,"Baseline since 17 Oct 2026 (user: ""option a and b should operate on biomass""); the launch plant draws 450-540 kg/h, so the two 500 kg/h modules of the boiler hall (B-1, B-2) or one ~1 t/h package; Chinese makers build biomass boilers too (ZOZEN DZL, Sitong DZL/SZL, Taiguo, Yongxing; china-utilities.md), not priced yet; fuel ~300 t air-dry wood or ~460 t fresh chips a year at ~850k records, ~0.67M THB at 0.7 THB/kWh of heat (biomass.md); sustainability path matching Deepgrooves NL precedent"
steam,Steam balance of plant,"Traps, accumulator, condensate return",Forbes Marshall Thailand,0,0,included,"Largely included in boiler package rows; line kept for RFQ completeness" steam,Biomass fuel store and handling,"Covered fuel store (42 m2 in the site model, ~6-7 weeks of fresh chips; ~80 m2 for a 3-month monsoon stock), chip bay, ash bins, compact loader",Local steel-shed contractors; loader dealers (used compact loaders),1000000,2000000,engineering estimate,"biomass.md: fuel handling and storage come on top of the boiler package; shed at roughly half the main building's 12,000-20,000 THB/m2 plus a used loader (estimate)"
compressed_air,Screw compressor skid (oil-injected),"~7.5 kW VSD screw + refrigerated dryer (3 C PDP) + coalescing filters + ~500 L receiver, installed","Atlas Copco Thailand; Kaeser Thailand (SM-T/Aircenter); Ingersoll Rand Thailand",350000,600000,engineering estimate,"14-30 m3/h demand is small (5-10 hp class); oil-injected + filter train meets 5 micron / 3 C spec" steam,Steam balance of plant,"Traps, accumulator, condensate return",Forbes Marshall Thailand,0,0,included,Largely included in boiler package rows; line kept for RFQ completeness
compressed_air,True oil-free class-0 (option),Same duty in oil-free class-0,"Atlas Copco (ZR/ZT); Kaeser",1200000,1800000,engineering estimate,"Only if air contacts product stream; NOT included in baseline total" compressed_air,Screw compressor skid (oil-injected),"~7.5 kW VSD screw + refrigerated dryer (3 C PDP) + coalescing filters + ~500 L receiver, installed","Atlas Copco Thailand; Kaeser Thailand (SM-T/Aircenter); Ingersoll Rand Thailand; Chinese brands with Thai offices (October 2026): Kaishan Compressor (Thailand), Denair Thailand, see suppliers/china-utilities.md",350000,600000,engineering estimate,"14-30 m3/h demand is small (5-10 hp class); oil-injected + filter train meets 5 micron / 3 C spec; Chinese route estimate 0.15M-0.3M THB installed (PM VSD 11 kW class USD 2k-5k, dryer, receiver, filters, installation)"
cooling,Process chiller package 250 kW,"~71 RT air-cooled screw/scroll chiller + pumps + buffer tank + controls, installed, closed loop","Trane Thailand; Carrier Thailand; Daikin Applied Thailand; Hitachi Thailand",2500000,4000000,engineering estimate,"Newbilt spec: 220 l/min peak, 20-25 C supply; chiller is the safe choice for hot-season wet-bulb" compressed_air,True oil-free class-0 (option),Same duty in oil-free class-0,Atlas Copco (ZR/ZT); Kaeser,1200000,1800000,engineering estimate,Only if air contacts product stream; NOT included in baseline total
cooling,Cooling tower + HX loop (alternative),"FRP tower ~250-300 kW reject + plate HX + pumps + tanks + water treatment","Liang Chi Thailand (tower, large service org); Process Cooling Solutions; Tasaki (integrators)",1000000,2000000,engineering estimate,"Cheaper capex but wet-bulb-limited; hybrid tower + trim chiller is the efficiency-optimal design; NOT included in baseline total" cooling,Process chiller bank 2 x 250 kW,"2 x ~71 RT air-cooled screw/scroll chillers rated at 40 C ambient (CH-1, CH-2) + primary pumps + plate HX + warm and cold tanks + VFD supply pumps + controls, backbone (HX frame, tanks, pumps, mains) sized for four modules, installed",Trane Thailand; Carrier Thailand; Daikin Applied Thailand; Hitachi Thailand,4900000,7900000,engineering estimate,"Launch plant (October 2026): Duplex system ~261 kW hot-afternoon peak (scale.md) plus the Classic up to ~125 kW (Newbilt per press), ~390 kW against 500 kW installed; was 3 x 250 kW at 6.5-10.5M for five presses, less one module at ~1.6-2.6M THB (estimate); CH-3 and CH-4 come with the growth options; 3 x 350 kW frame pads stay the alternative (steam-cooling.html)"
water,Boiler feedwater duplex softener,~0.5-0.8 m3/h feedwater duty,"Veolia Water Technologies Thailand; Hydrotek; local RO/softener integrators",80000,200000,market estimate,May suffice alone for a small fire-tube boiler cooling,Cooling tower + HX loop (alternative),Dry cooler or FRP tower ~650-750 kW reject + plate HX + pumps + tanks + water treatment,"Liang Chi Thailand (tower, large service org); Process Cooling Solutions; Tasaki (integrators)",2000000,3500000,engineering estimate,Cheaper capex but wet-bulb-limited; hybrid tower + trim chiller is the efficiency-optimal design; NOT included in baseline total
water,RO skid (option),0.5-1 m3/h low-TDS feed,"Veolia; Hydrotek; local integrators",200000,500000,market estimate,"Only if low-TDS feed needed; NOT included in baseline total" water,Boiler feedwater duplex softener,~1.0-1.2 m3/h feedwater duty (five-press boiler bank),Veolia Water Technologies Thailand; Hydrotek; local RO/softener integrators,120000,300000,market estimate,May suffice alone for a small fire-tube boiler
water,Closed-loop cooling water treatment,"Side-stream filtration + dosing + conductivity blowdown control",Veolia; Hydrotek; local integrators,150000,400000,engineering estimate,Chemicals are ongoing opex on top water,RO skid (option),0.5-1 m3/h low-TDS feed,Veolia; Hydrotek; local integrators,200000,500000,market estimate,"Launch scope since October 2026 as the DI water supply for the galvanics PMPB (with polishing); carried in the galvanics water block of total-investment.md, so NOT included in this baseline total"
water,Galvanics ZLD evaporator (future),"Small MVR or low-temp vacuum evaporator for plating rinse, installed","Core unit imported (WTEYA, Greenlan, Fred); Thai integration via Veolia or Hydrotek",3000000,8000000,market estimate,"For the future galvanics line, zero-discharge requirement; NOT included in baseline total" water,Closed-loop cooling water treatment,Side-stream filtration + dosing + conductivity blowdown control,Veolia; Hydrotek; local integrators,200000,500000,engineering estimate,"Sized for the five-press loop with its open return tank (Newbilt press outlets are open, max. 2 bar); chemicals are ongoing opex on top"
storage,Pallet racking and shelving,"100-200 pallet positions selective/heavy-duty (beams sized 1000-1500 kg/pallet, records are dense) + archive and finished-goods shelving, installed","Jenbunjerd; local fabricators (Sahawatthanakit, UPR, SD Shelf); SSI Schaefer (premium)",800000,1500000,published list prices + engineering estimate,"SSI Schaefer premium tier ~1.5-3M for same scope; ~1000-2000 THB per pallet position at local tier" water,Galvanics ZLD evaporator,"Small MVR or low-temp vacuum evaporator for plating rinse, installed","Core unit imported (WTEYA, Greenlan, Fred); Thai integration via Veolia or Hydrotek",3000000,8000000,market estimate,"Launch scope since October 2026 (galvanics in-house from the start); carried as its own block in total-investment.md, so NOT included in this baseline total"
storage,Pallet racking and shelving,"100-200 pallet positions selective/heavy-duty (beams sized 1000-1500 kg/pallet, records are dense) + archive and finished-goods shelving, installed","Jenbunjerd; LPI Rack Range (Thailand), Bangkok/Samut Prakan, racking and office mobile shelving; local fabricators (Sahawatthanakit, UPR, SD Shelf); SSI Schaefer (premium)",800000,1500000,published list prices + engineering estimate,SSI Schaefer premium tier ~1.5-3M for same scope; ~1000-2000 THB per pallet position at local tier
hvac,Whole-factory HVAC,"~1500 m2 at 20-26 C, 35-60% RH, ePM1/F7-F9 filtration sized for burning-season PM2.5, ducting and controls","Daikin Thailand; Trane; Mitsubishi Electric; Carrier; filtration: Camfil Thailand, AAF",7500000,15000000,engineering estimate at 5000-10000 THB/m2,"RH low end of 35% is aggressive for tropics and drives desiccant cost; if 45-60% RH acceptable, cost drops materially" hvac,Whole-factory HVAC,"~1500 m2 at 20-26 C, 35-60% RH, ePM1/F7-F9 filtration sized for burning-season PM2.5, ducting and controls","Daikin Thailand; Trane; Mitsubishi Electric; Carrier; filtration: Camfil Thailand, AAF",7500000,15000000,engineering estimate at 5000-10000 THB/m2,"RH low end of 35% is aggressive for tropics and drives desiccant cost; if 45-60% RH acceptable, cost drops materially"
hvac,Clean-room-grade zone adder,"Cutting room + galvanics clean room, ~2 x 60 m2, ISO 7/8 with HEPA terminals, positive pressure, airlocks","Same HVAC vendors + clean-room contractors; Camfil HEPA",1200000,3400000,engineering estimate at 10000-28000 THB/m2 adder,Applied only to the two tight zones hvac,Clean-room-grade zone adder,"Cutting room + galvanics clean room, ~2 x 60 m2, ISO 7/8 with HEPA terminals, positive pressure, airlocks",Same HVAC vendors + clean-room contractors; Camfil HEPA,1200000,3400000,engineering estimate at 10000-28000 THB/m2 adder,Applied only to the two tight zones
solar,PV rooftop EPC (illustrative 300 kWp),"Turnkey C&I rooftop EPC incl. Deye hybrid inverters, at 25000-35000 THB/kWp","Solar Nicolo (Deye tier-1 distributor); Banpu NEXT; SCG Cleanergy; Sermsang; local Chiang Mai installers",7500000,10500000,market rate per kWp; size illustrative,"Final kWp open until site selection; grid tariff ~3.88 THB/kWh implies ~4-6 yr C&I payback" solar,"PV EPC, factory roof (~520 kWp on the Payap scenario plot)","Turnkey C&I EPC on the factory roof (~523 kWp in the parts model), incl. inverters (Deye hybrids where the battery connects), at 20000-26000 THB/kWp; office roof (~65 kWp) and car and scooter canopies (~54 kWp) PV-ready, panels later",Solar Nicolo (Deye tier-1 distributor); Banpu NEXT; SCG Cleanergy; Sermsang; CapSolar; local Chiang Mai installers,10400000,13520000,"market rate per kWp (October 2026 check): DEDE Thailand PV Status (Mahidol survey) 22-25 THB/W for 10 kW-1 MW C&I systems in 2023; CapSolar 2026 20-25 THB/W under 1 MWp (20-23 at 500 kWp); Saimai Solar 2026 list 5.4M THB for 300 kW (18 THB/W); top of range covers Deye SUN-50K-SG01HP3 hybrid inverters (160,500 THB each at Supsaringkan, about nine 50 kW units for ~430 kVA); size: the factory roof, user decision 17 Oct 2026 (was every roof and canopy, ~640 kWp, and before that an illustrative 300 kWp)","Size: with biomass steam the best array is ~500-550 kWp (hourly sketch, sustainability.md), so the factory roof's ~520 kWp; on the Mueang Chi hall the factory roof takes ~247 kWp (scale.md); PV-ready means structure for the panels, conduit and a spare way at the main board (in the building and site works); ~87% of the yield used on site under PEA zero export (estimate); self-consumed PV worth ~3.7 THB/kWh, ~4.1-5.8 yr payback (sustainability.md, grid tariff)"
solar,Battery stack 271 kWh (Gobel),"GP-SRA-HV314 HV LiFePO4 rack, 15 x 18 kWh packs, direct from Shenzhen, 50-60 day lead",Gobel Power (no Thai distributor; integration by solar EPC),1400000,2030000,vendor listed price USD 39900-58000 at ~35 THB/USD,"Confirm Deye BMS protocol compatibility and that the EPC warrants a mixed-vendor DC bus; certs (UN38.3/IEC 62619/CE) to be requested" solar,Battery stack 271 kWh (Gobel) installed,"GP-SRA-HV314 HV LiFePO4 rack, 15 x 18 kWh packs, direct from Shenzhen, 50-60 day lead; plus enclosure, fire detection and suppression, controls and installation",Gobel Power (no Thai distributor; integration by solar EPC),2000000,3500000,"battery: vendor listed price USD 39900-58000 at ~35 THB/USD = 1.40-2.03M THB, in line with DEDE's 5000-7000 THB/kWh for LiFePO4 (Mahidol survey); installed: estimate below CapSolar's 12000-15000 THB/kWh for a fully installed factory BESS (2026), because the Deye hybrid inverters in the PV row do the power conversion",Confirm Deye BMS protocol compatibility and that the EPC warrants a mixed-vendor DC bus; certs (UN38.3/IEC 62619/CE) to be requested
total,BASELINE TOTAL,"Electric steam + oil-injected air + chiller + softener + loop treatment + local racking + HVAC + clean zones + 300 kWp solar + 271 kWh BESS",,23980000,41630000,sum of baseline rows,"~630k-1100k EUR at 38 THB/EUR; excludes options rows (biomass premium, oil-free, tower alternative, RO, ZLD evaporator, SSI premium tier); all figures budgetary +/- 30%, get RFQs before BOI/finance filings" total,BASELINE TOTAL,Biomass boiler package (2 modules) + fuel store + oil-injected air + chiller bank (2 modules) + softener + loop treatment + local racking + HVAC + clean zones + ~520 kWp factory-roof solar + 271 kWh BESS,,34470000,58220000,sum of baseline rows,"Launch plant, one Duplex system and one Classic (October 2026; biomass steam and PV on the factory roof only 17 Oct 2026, was 34.37M-56.34M with electric steam and ~640 kWp; solar and battery re-priced from Thai market data and the array sized to every roof and canopy 17 Oct 2026, was 27.57M-47.50M at 300 kWp and 28.47M-48.73M before the re-price; was 30.07M-51.33M THB for five presses, 23.98M-41.63M for one Duplex); ~750k-1280k EUR at 38 THB/EUR; excludes options rows and the galvanics water rows (ZLD, DI), which total-investment.md carries with galvanics; all figures budgetary +/- 30%, get RFQs before BOI"
1 category item spec_summary candidate_thai_suppliers cost_low_thb cost_high_thb cost_basis notes
2 steam Electric/gas once-through boiler package Electric/gas once-through boiler bank (alternative) ~400-500 kg/h at 10 bar / 180 C incl. softener, feed tank, economizer, installed 2 x 500 kg/h modules at 10.5 bar / 180 C, lead/lag, shared feed tank, feed pumps, economizer, installed Miura Thailand (Chachoengsao); Bangkok Industrial Boilers; STE Thailand Miura Thailand (Chachoengsao); Bangkok Industrial Boilers; STE Thailand; Chinese route (October 2026): ZOZEN, Sitong, Fangkuai, Taiguo (ASME claimed, Thai references, no Thai service partner), see suppliers/china-utilities.md 2500000 4500000 4000000 7000000 engineering estimate Miura-class modular once-through; BIB budget option ~2.0-3.5M; service is Bangkok-centric, confirm northern dispatch SLA NOT included in baseline total since 17 Oct 2026 (user: both plans run on biomass); kept as the alternative. Launch plant (October 2026): one Duplex system and one Classic, 450-540 kg/h at Newbilt's 150-180 kg/h per press, so B-1 and B-2 both at launch; the boiler hall is built for four modules (scale.md utility phasing); a third module for N+1 is an RFQ option; Miura-class modular once-through; service is Bangkok-centric, confirm northern dispatch SLA; Chinese route estimate 2.8M-5.5M THB installed (two ASME-stamped 1.25 MPa bodies USD 15k-35k each, inspection and certification, freight, Thai contractor balance of plant), about 1.6M THB less at the midpoint; imported boilers need DIW certification-body verification either way
3 steam Biomass/wood-fired boiler package (option) Biomass/wood-fired boiler package, 2 x 500 kg/h or one ~1 t/h ~0.5 t/h solid fuel (wood chips/pellets/rice husk) incl. fuel feed, grate, dust control, softener, installed ~1 t/h solid fuel (wood chips/pellets/rice husk) incl. fuel feed, grate, dust control, softener, installed Getabec PCL (Thai fabrication and service) 4000000 6000000 7000000 10000000 engineering estimate Sustainability path matching Deepgrooves NL precedent; Viessmann has no strong Thai channel; higher capex, lower fuel opex in the North; NOT included in baseline total Baseline since 17 Oct 2026 (user: "option a and b should operate on biomass"); the launch plant draws 450-540 kg/h, so the two 500 kg/h modules of the boiler hall (B-1, B-2) or one ~1 t/h package; Chinese makers build biomass boilers too (ZOZEN DZL, Sitong DZL/SZL, Taiguo, Yongxing; china-utilities.md), not priced yet; fuel ~300 t air-dry wood or ~460 t fresh chips a year at ~850k records, ~0.67M THB at 0.7 THB/kWh of heat (biomass.md); sustainability path matching Deepgrooves NL precedent
4 steam Steam balance of plant Biomass fuel store and handling Traps, accumulator, condensate return Covered fuel store (42 m2 in the site model, ~6-7 weeks of fresh chips; ~80 m2 for a 3-month monsoon stock), chip bay, ash bins, compact loader Forbes Marshall Thailand Local steel-shed contractors; loader dealers (used compact loaders) 0 1000000 0 2000000 included engineering estimate Largely included in boiler package rows; line kept for RFQ completeness biomass.md: fuel handling and storage come on top of the boiler package; shed at roughly half the main building's 12,000-20,000 THB/m2 plus a used loader (estimate)
5 compressed_air steam Screw compressor skid (oil-injected) Steam balance of plant ~7.5 kW VSD screw + refrigerated dryer (3 C PDP) + coalescing filters + ~500 L receiver, installed Traps, accumulator, condensate return Atlas Copco Thailand; Kaeser Thailand (SM-T/Aircenter); Ingersoll Rand Thailand Forbes Marshall Thailand 350000 0 600000 0 engineering estimate included 14-30 m3/h demand is small (5-10 hp class); oil-injected + filter train meets 5 micron / 3 C spec Largely included in boiler package rows; line kept for RFQ completeness
6 compressed_air True oil-free class-0 (option) Screw compressor skid (oil-injected) Same duty in oil-free class-0 ~7.5 kW VSD screw + refrigerated dryer (3 C PDP) + coalescing filters + ~500 L receiver, installed Atlas Copco (ZR/ZT); Kaeser Atlas Copco Thailand; Kaeser Thailand (SM-T/Aircenter); Ingersoll Rand Thailand; Chinese brands with Thai offices (October 2026): Kaishan Compressor (Thailand), Denair Thailand, see suppliers/china-utilities.md 1200000 350000 1800000 600000 engineering estimate Only if air contacts product stream; NOT included in baseline total 14-30 m3/h demand is small (5-10 hp class); oil-injected + filter train meets 5 micron / 3 C spec; Chinese route estimate 0.15M-0.3M THB installed (PM VSD 11 kW class USD 2k-5k, dryer, receiver, filters, installation)
7 cooling compressed_air Process chiller package 250 kW True oil-free class-0 (option) ~71 RT air-cooled screw/scroll chiller + pumps + buffer tank + controls, installed, closed loop Same duty in oil-free class-0 Trane Thailand; Carrier Thailand; Daikin Applied Thailand; Hitachi Thailand Atlas Copco (ZR/ZT); Kaeser 2500000 1200000 4000000 1800000 engineering estimate Newbilt spec: 220 l/min peak, 20-25 C supply; chiller is the safe choice for hot-season wet-bulb Only if air contacts product stream; NOT included in baseline total
8 cooling Cooling tower + HX loop (alternative) Process chiller bank 2 x 250 kW FRP tower ~250-300 kW reject + plate HX + pumps + tanks + water treatment 2 x ~71 RT air-cooled screw/scroll chillers rated at 40 C ambient (CH-1, CH-2) + primary pumps + plate HX + warm and cold tanks + VFD supply pumps + controls, backbone (HX frame, tanks, pumps, mains) sized for four modules, installed Liang Chi Thailand (tower, large service org); Process Cooling Solutions; Tasaki (integrators) Trane Thailand; Carrier Thailand; Daikin Applied Thailand; Hitachi Thailand 1000000 4900000 2000000 7900000 engineering estimate Cheaper capex but wet-bulb-limited; hybrid tower + trim chiller is the efficiency-optimal design; NOT included in baseline total Launch plant (October 2026): Duplex system ~261 kW hot-afternoon peak (scale.md) plus the Classic up to ~125 kW (Newbilt per press), ~390 kW against 500 kW installed; was 3 x 250 kW at 6.5-10.5M for five presses, less one module at ~1.6-2.6M THB (estimate); CH-3 and CH-4 come with the growth options; 3 x 350 kW frame pads stay the alternative (steam-cooling.html)
9 water cooling Boiler feedwater duplex softener Cooling tower + HX loop (alternative) ~0.5-0.8 m3/h feedwater duty Dry cooler or FRP tower ~650-750 kW reject + plate HX + pumps + tanks + water treatment Veolia Water Technologies Thailand; Hydrotek; local RO/softener integrators Liang Chi Thailand (tower, large service org); Process Cooling Solutions; Tasaki (integrators) 80000 2000000 200000 3500000 market estimate engineering estimate May suffice alone for a small fire-tube boiler Cheaper capex but wet-bulb-limited; hybrid tower + trim chiller is the efficiency-optimal design; NOT included in baseline total
10 water RO skid (option) Boiler feedwater duplex softener 0.5-1 m3/h low-TDS feed ~1.0-1.2 m3/h feedwater duty (five-press boiler bank) Veolia; Hydrotek; local integrators Veolia Water Technologies Thailand; Hydrotek; local RO/softener integrators 200000 120000 500000 300000 market estimate Only if low-TDS feed needed; NOT included in baseline total May suffice alone for a small fire-tube boiler
11 water Closed-loop cooling water treatment RO skid (option) Side-stream filtration + dosing + conductivity blowdown control 0.5-1 m3/h low-TDS feed Veolia; Hydrotek; local integrators 150000 200000 400000 500000 engineering estimate market estimate Chemicals are ongoing opex on top Launch scope since October 2026 as the DI water supply for the galvanics PMPB (with polishing); carried in the galvanics water block of total-investment.md, so NOT included in this baseline total
12 water Galvanics ZLD evaporator (future) Closed-loop cooling water treatment Small MVR or low-temp vacuum evaporator for plating rinse, installed Side-stream filtration + dosing + conductivity blowdown control Core unit imported (WTEYA, Greenlan, Fred); Thai integration via Veolia or Hydrotek Veolia; Hydrotek; local integrators 3000000 200000 8000000 500000 market estimate engineering estimate For the future galvanics line, zero-discharge requirement; NOT included in baseline total Sized for the five-press loop with its open return tank (Newbilt press outlets are open, max. 2 bar); chemicals are ongoing opex on top
13 storage water Pallet racking and shelving Galvanics ZLD evaporator 100-200 pallet positions selective/heavy-duty (beams sized 1000-1500 kg/pallet, records are dense) + archive and finished-goods shelving, installed Small MVR or low-temp vacuum evaporator for plating rinse, installed Jenbunjerd; local fabricators (Sahawatthanakit, UPR, SD Shelf); SSI Schaefer (premium) Core unit imported (WTEYA, Greenlan, Fred); Thai integration via Veolia or Hydrotek 800000 3000000 1500000 8000000 published list prices + engineering estimate market estimate SSI Schaefer premium tier ~1.5-3M for same scope; ~1000-2000 THB per pallet position at local tier Launch scope since October 2026 (galvanics in-house from the start); carried as its own block in total-investment.md, so NOT included in this baseline total
14 storage Pallet racking and shelving 100-200 pallet positions selective/heavy-duty (beams sized 1000-1500 kg/pallet, records are dense) + archive and finished-goods shelving, installed Jenbunjerd; LPI Rack Range (Thailand), Bangkok/Samut Prakan, racking and office mobile shelving; local fabricators (Sahawatthanakit, UPR, SD Shelf); SSI Schaefer (premium) 800000 1500000 published list prices + engineering estimate SSI Schaefer premium tier ~1.5-3M for same scope; ~1000-2000 THB per pallet position at local tier
15 hvac Whole-factory HVAC ~1500 m2 at 20-26 C, 35-60% RH, ePM1/F7-F9 filtration sized for burning-season PM2.5, ducting and controls Daikin Thailand; Trane; Mitsubishi Electric; Carrier; filtration: Camfil Thailand, AAF 7500000 15000000 engineering estimate at 5000-10000 THB/m2 RH low end of 35% is aggressive for tropics and drives desiccant cost; if 45-60% RH acceptable, cost drops materially
16 hvac Clean-room-grade zone adder Cutting room + galvanics clean room, ~2 x 60 m2, ISO 7/8 with HEPA terminals, positive pressure, airlocks Same HVAC vendors + clean-room contractors; Camfil HEPA 1200000 3400000 engineering estimate at 10000-28000 THB/m2 adder Applied only to the two tight zones
17 solar PV rooftop EPC (illustrative 300 kWp) PV EPC, factory roof (~520 kWp on the Payap scenario plot) Turnkey C&I rooftop EPC incl. Deye hybrid inverters, at 25000-35000 THB/kWp Turnkey C&I EPC on the factory roof (~523 kWp in the parts model), incl. inverters (Deye hybrids where the battery connects), at 20000-26000 THB/kWp; office roof (~65 kWp) and car and scooter canopies (~54 kWp) PV-ready, panels later Solar Nicolo (Deye tier-1 distributor); Banpu NEXT; SCG Cleanergy; Sermsang; local Chiang Mai installers Solar Nicolo (Deye tier-1 distributor); Banpu NEXT; SCG Cleanergy; Sermsang; CapSolar; local Chiang Mai installers 7500000 10400000 10500000 13520000 market rate per kWp; size illustrative market rate per kWp (October 2026 check): DEDE Thailand PV Status (Mahidol survey) 22-25 THB/W for 10 kW-1 MW C&I systems in 2023; CapSolar 2026 20-25 THB/W under 1 MWp (20-23 at 500 kWp); Saimai Solar 2026 list 5.4M THB for 300 kW (18 THB/W); top of range covers Deye SUN-50K-SG01HP3 hybrid inverters (160,500 THB each at Supsaringkan, about nine 50 kW units for ~430 kVA); size: the factory roof, user decision 17 Oct 2026 (was every roof and canopy, ~640 kWp, and before that an illustrative 300 kWp) Final kWp open until site selection; grid tariff ~3.88 THB/kWh implies ~4-6 yr C&I payback Size: with biomass steam the best array is ~500-550 kWp (hourly sketch, sustainability.md), so the factory roof's ~520 kWp; on the Mueang Chi hall the factory roof takes ~247 kWp (scale.md); PV-ready means structure for the panels, conduit and a spare way at the main board (in the building and site works); ~87% of the yield used on site under PEA zero export (estimate); self-consumed PV worth ~3.7 THB/kWh, ~4.1-5.8 yr payback (sustainability.md, grid tariff)
18 solar Battery stack 271 kWh (Gobel) Battery stack 271 kWh (Gobel) installed GP-SRA-HV314 HV LiFePO4 rack, 15 x 18 kWh packs, direct from Shenzhen, 50-60 day lead GP-SRA-HV314 HV LiFePO4 rack, 15 x 18 kWh packs, direct from Shenzhen, 50-60 day lead; plus enclosure, fire detection and suppression, controls and installation Gobel Power (no Thai distributor; integration by solar EPC) 1400000 2000000 2030000 3500000 vendor listed price USD 39900-58000 at ~35 THB/USD battery: vendor listed price USD 39900-58000 at ~35 THB/USD = 1.40-2.03M THB, in line with DEDE's 5000-7000 THB/kWh for LiFePO4 (Mahidol survey); installed: estimate below CapSolar's 12000-15000 THB/kWh for a fully installed factory BESS (2026), because the Deye hybrid inverters in the PV row do the power conversion Confirm Deye BMS protocol compatibility and that the EPC warrants a mixed-vendor DC bus; certs (UN38.3/IEC 62619/CE) to be requested
19 total BASELINE TOTAL Electric steam + oil-injected air + chiller + softener + loop treatment + local racking + HVAC + clean zones + 300 kWp solar + 271 kWh BESS Biomass boiler package (2 modules) + fuel store + oil-injected air + chiller bank (2 modules) + softener + loop treatment + local racking + HVAC + clean zones + ~520 kWp factory-roof solar + 271 kWh BESS 23980000 34470000 41630000 58220000 sum of baseline rows ~630k-1100k EUR at 38 THB/EUR; excludes options rows (biomass premium, oil-free, tower alternative, RO, ZLD evaporator, SSI premium tier); all figures budgetary +/- 30%, get RFQs before BOI/finance filings Launch plant, one Duplex system and one Classic (October 2026; biomass steam and PV on the factory roof only 17 Oct 2026, was 34.37M-56.34M with electric steam and ~640 kWp; solar and battery re-priced from Thai market data and the array sized to every roof and canopy 17 Oct 2026, was 27.57M-47.50M at 300 kWp and 28.47M-48.73M before the re-price; was 30.07M-51.33M THB for five presses, 23.98M-41.63M for one Duplex); ~750k-1280k EUR at 38 THB/EUR; excludes options rows and the galvanics water rows (ZLD, DI), which total-investment.md carries with galvanics; all figures budgetary +/- 30%, get RFQs before BOI
File diff suppressed because it is too large. Load diff
Loaded 100 of 172 files, more files were not shown because too many files have changed in this diff. Show more