71 lines
4.3 KiB
Python
71 lines
4.3 KiB
Python
"""TEMPLATE — Technical Service Bulletin (TSB). Copy this folder to <PROJECT>/source/ and fill it in.
|
||||
|
|
|
|||
|
|
A known product issue and its fix, for every unit it affects. One number, two editions from this one
|
|||
|
|
script: the CUSTOMER edition (agencies, partners) and the INTERNAL edition (MPM field and support), which
|
|||
|
|
adds a Part 2 with diagnostic detail. The customer edition never contains Part 2. 2–5 pages.
|
|||
|
|
See MPM_Document_Standard.md §9.8.
|
|||
|
|
|
|||
|
|
Order: masthead (Compliance · Effective) → compliance pill → applicability (kv) → In short (dark)
|
|||
|
|
→ 1 Symptom → 2 Cause → 3 Corrective action → 4 Verification → 5 Parts → Compliance record
|
|||
|
|
→ [internal: PART 2 Diagnostic detail] → Revision history
|
|||
|
|
Compliance: Mandatory (red) = safety/failure, fix by a date · Recommended (gold) = fix at next visit
|
|||
|
|
· Informational (grey) = no action, awareness only.
|
|||
|
|
Numbers: customer code MPM for product-wide bulletins (TSB-MPM-LX270-01); a customer code when the
|
|||
|
|
issue is specific to one deployment. Subject = product family.
|
|||
|
|
"""
|
|||
|
|
import sys, pathlib
|
|||
|
|
HERE = pathlib.Path(__file__).resolve().parent
|
|||
|
|
sys.path.insert(0, str(next(p / "_STANDARDS" for p in HERE.parents if (p / "_STANDARDS").is_dir())))
|
|||
|
|
|
|||
|
|
from mpmdoc import Doc
|
|||
|
|
|
|||
|
|
REV, DATE = "0.1", "2026-11-06"
|
|||
|
|
HISTORY = [("0.1", DATE, "Initial draft.")]
|
|||
|
|
COMPLIANCE, PILL = "Recommended", "gold" # Mandatory/red · Recommended/gold · Informational/grey
|
|||
|
|
|
|||
|
|
for edition, slug in (("customer", "MPM_Product_Issue_TSB"), ("internal", "MPM_Product_Issue_TSB-Internal")):
|
|||
|
|
internal = edition == "internal"
|
|||
|
|
doc = Doc(
|
|||
|
|
number="TSB-MPM-SUBJ-01", rev=REV, date=DATE, subject="Product family",
|
|||
|
|
title="Product: Issue in a Few Words",
|
|||
|
|
lede="One line: what goes wrong, on which units, and what to do about it.",
|
|||
|
|
meta=[("Compliance", COMPLIANCE), ("Effective", "Nov 6, 2026")],
|
|||
|
|
slug=slug, classification=edition, history=HISTORY,
|
|||
|
|
)
|
|||
|
|
body = [
|
|||
|
|
doc.pill(COMPLIANCE, PILL),
|
|||
|
|
doc.kv([("Applies to", "Product, model, part number"),
|
|||
|
|
("Affected units", "Serial range, build dates or firmware versions"),
|
|||
|
|
("Not affected", "Units outside that range; how to tell"),
|
|||
|
|
("Labor estimate", "0.5 h per unit, one technician"),
|
|||
|
|
("Supersedes", "—"),
|
|||
|
|
("Distribution", "MPM field and support" if internal else "Customers and partners operating affected units")]),
|
|||
|
|
doc.result(["What happens, in one line.", "What to do, in one line.", "By when (Mandatory only)."]),
|
|||
|
|
doc.section("1. Symptom"),
|
|||
|
|
doc.p("What the rider, the agency or the platform sees. Exact: which LEDs, which message, how often."),
|
|||
|
|
doc.section("2. Cause"),
|
|||
|
|
doc.p("The cause in plain words. Customer edition: enough to trust the fix, no more."),
|
|||
|
|
doc.section("3. Corrective action"),
|
|||
|
|
doc.steps(["Power down the sign at the breaker and confirm it is dark.", "Replace the part (see §5).",
|
|||
|
|
"Power up and confirm the sign reports online on MP.TV."]),
|
|||
|
|
doc.section("4. Verification"),
|
|||
|
|
doc.bullets(["Sign reports online on MP.TV within 5 minutes.", "No dropout over a 10-minute content loop."], check=True),
|
|||
|
|
doc.section("5. Parts"),
|
|||
|
|
doc.table([("Part no.", "m", "22%"), ("Description", ""), ("Qty per unit", "r", "14%")],
|
|||
|
|
[["PN-0000", "Replacement part", "1"]]),
|
|||
|
|
doc.section("Compliance record"),
|
|||
|
|
doc.table([("Unit serial", "", "24%"), ("Site", ""), ("Date", "", "16%"), ("Technician", "", "20%"), ("Done", "c", "8%")],
|
|||
|
|
[["", "", "", "", '<span class="box"></span>']] * 6, cls="fill"),
|
|||
|
|
]
|
|||
|
|
if internal:
|
|||
|
|
body += [
|
|||
|
|
doc.part("Part 2", "Diagnostic detail", "MPM field and support only. Not for distribution.", internal=True),
|
|||
|
|
doc.section("Root cause"), doc.p("Failure analysis, test results, supplier findings."),
|
|||
|
|
doc.section("Field data"),
|
|||
|
|
doc.table([("Site", ""), ("Units", "r", "12%"), ("Failures", "r", "12%"), ("First seen", "", "18%")],
|
|||
|
|
[["Site name", "0", "0", "Nov 6, 2026"]]),
|
|||
|
|
doc.section("Support notes"),
|
|||
|
|
doc.bullets(["How to recognise the issue on a support call.", "Remote checks before dispatch."]),
|
|||
|
|
]
|
|||
|
|
doc.add(*body)
|
|||
|
|
doc.build()
|