standard-work-documenter
You are standard-work-documenter - a specialized skill for creating and maintaining standard work documentation for consistent and improvable operations.
Overview
This skill enables AI-powered standard work documentation including:
- Work element breakdown
- Time observation recording
- Standard work combination sheet generation
- Standard work layout diagram creation
- Job instruction breakdown sheet formatting
- Standard WIP calculation
- Visual work instruction creation
- Multi-format output (print, digital, video)
Capabilities
1. Work Element Breakdown
from dataclasses import dataclass
from typing import List, Optional
from enum import Enum
class ElementType(Enum):
MANUAL = "manual" # Operator work
WALK = "walk" # Movement
WAIT = "wait" # Waiting for machine
AUTO = "auto" # Machine automatic time
@dataclass
class WorkElement:
sequence: int
description: str
element_type: ElementType
time_seconds: float
key_points: List[str]
safety_notes: str = ""
quality_checks: List[str] = None
tools_required: List[str] = None
class StandardWorkBreakdown:
"""
Break down work into standardized elements
"""
def __init__(self, operation_name: str, takt_time: float):
self.operation_name = operation_name
self.takt_time = takt_time
self.elements: List[WorkElement] = []
def add_element(self, description: str, element_type: ElementType,
time: float, key_points: List[str], **kwargs):
element = WorkElement(
sequence=len(self.elements) + 1,
description=description,
element_type=element_type,
time_seconds=time,
key_points=key_points,
**kwargs
)
self.elements.append(element)
return element
def summary(self):
manual_time = sum(e.time_seconds for e in self.elements
if e.element_type == ElementType.MANUAL)
walk_time = sum(e.time_seconds for e in self.elements
if e.element_type == ElementType.WALK)
wait_time = sum(e.time_seconds for e in self.elements
if e.element_type == ElementType.WAIT)
auto_time = sum(e.time_seconds for e in self.elements
if e.element_type == ElementType.AUTO)
total_cycle_time = manual_time + walk_time + wait_time
return {
"operation": self.operation_name,
"total_elements": len(self.elements),
"manual_time": manual_time,
"walk_time": walk_time,
"wait_time": wait_time,
"auto_time": auto_time,
"cycle_time": total_cycle_time,
"takt_time": self.takt_time,
"takt_attainment": self.takt_time / total_cycle_time * 100 if total_cycle_time > 0 else 0
}
2. Time Observation Recording
import numpy as np
from scipy import stats
class TimeStudyRecorder:
"""
Record and analyze time observations
"""
def __init__(self, operation_name: str, num_cycles: int = 10):
self.operation_name = operation_name
self.target_cycles = num_cycles
self.observations = {} # {element_name: [times]}
def record_observation(self, element_name: str, time: float):
if element_name not in self.observations:
self.observations[element_name] = []
self.observations[element_name].append(time)
def analyze_element(self, element_name: str):
times = self.observations.get(element_name, [])
if not times:
return None
return {
"element": element_name,
"observations": len(times),
"mean": np.mean(times),
"std": np.std(times, ddof=1),
"min": np.min(times),
"max": np.max(times),
"cv": np.std(times, ddof=1) / np.mean(times) * 100,
"ci_95": stats.t.interval(0.95, len(times)-1,
loc=np.mean(times),
scale=stats.sem(times))
}
def calculate_standard_time(self, element_name: str,
performance_rating: float = 1.0,
allowance_factor: float = 1.15):
"""
Standard Time = Normal Time x Allowance Factor
Normal Time = Observed Time x Performance Rating
"""
analysis = self.analyze_element(element_name)
if not analysis:
return None
observed_time = analysis['mean']
normal_time = observed_time * performance_rating
standard_time = normal_time * allowance_factor
return {
"element": element_name,
"observed_time": observed_time,
"performance_rating": performance_rating,
"normal_time": normal_time,
"allowance_factor": allowance_factor,
"standard_time": standard_time
}
3. Standard Work Combination Sheet
def generate_combination_sheet(elements: List[WorkElement], takt_time: float):
"""
Generate standard work combination sheet
Shows manual work, walk, wait, and auto time on timeline
"""
sheet = {
"header": {
"operation": "",
"takt_time": takt_time,
"date": "",
"revision": ""
},
"timeline": [],
"totals": {
"manual": 0,
"walk": 0,
"wait": 0,
"auto": 0,
"cycle_time": 0
}
}
current_time = 0
for element in elements:
entry = {
"sequence": element.sequence,
"description": element.description,
"type": element.element_type.value,
"start_time": current_time,
"duration": element.time_seconds,
"end_time": current_time + element.time_seconds
}
sheet["timeline"].append(entry)
# Update totals
if element.element_type == ElementType.MANUAL:
sheet["totals"]["manual"] += element.time_seconds
elif element.element_type == ElementType.WALK:
sheet["totals"]["walk"] += element.time_seconds
elif element.element_type == ElementType.WAIT:
sheet["totals"]["wait"] += element.time_seconds
elif element.element_type == ElementType.AUTO:
sheet["totals"]["auto"] += element.time_seconds
# Auto time runs parallel, others sequential
if element.element_type != ElementType.AUTO:
current_time += element.time_seconds
sheet["totals"]["cycle_time"] = current_time
return sheet
def render_combination_chart(sheet, output_format='text'):
"""
Render visual representation of combination sheet
"""
takt = sheet["header"]["takt_time"]
max_time = max(takt, sheet["totals"]["cycle_time"])
# Text-based chart
chart_width = 60
scale = chart_width / max_time
lines = []
lines.append(f"Standard Work Combination Sheet")
lines.append(f"Takt Time: {takt:.1f}s | Cycle Time: {sheet['totals']['cycle_time']:.1f}s")
lines.append("=" * (chart_width + 20))
# Draw takt line position
takt_pos = int(takt * scale)
for entry in sheet["timeline"]:
start_pos = int(entry["start_time"] * scale)
end_pos = int(entry["end_time"] * scale)
# Choose symbol based on type
symbols = {
"manual": "M",
"walk": "W",
"wait": ".",
"auto": "A"
}
symbol = symbols.get(entry["type"], "?")
bar = " " * start_pos + symbol * (end_pos - start_pos)
bar = bar[:chart_width]
# Add takt marker
if takt_pos < len(bar):
bar = bar[:takt_pos] + "|" + bar[takt_pos+1:]
lines.append(f"{entry['sequence']:2d}. {entry['description'][:15]:15s} {bar}")