Mold
The Mold Station is a real-time inventory management system that automatically tracks EPS (Expanded Polystyrene) blocks as they are created by the mold machine. The system integrates a Python monitoring application running on the mold machine computer with a web-based interface, providing operators with live visibility into block production and the ability to manage block data, flag problematic cycles, and verify block information.
Key Features:
- Real-time block data synchronization from mold machine
- Live table of blocks in inventory
- Inline editing of block properties
- Block flagging system for quality issues
- Automatic notifications to administrators
- Integration with silo and lot tracking
Access Requirements:
- User must be in one of these groups:
super_admin,mold, oradmin - Route:
/mold/view
Front-End Behavior
Main Interface

The Mold In Progress page displays a paginated, auto-refreshing table of all unused blocks currently in inventory, sorted by creation date (most recent first).
Table Columns:
- Block #: Sequential number assigned by mold machine (resets monthly)
- Created: Timestamp when block was molded (format: M/D/YY h:mm AM/PM)
- Density: EPS density type (e.g., "
1.5#EIFS", "2.0#EIFS") - Regrind %: Percentage of recycled bead used (0-100)
- Weight: Final block weight after molding (lbs)
- Silo Weight: Total bead weight loaded from silo (lbs)
- Height: Block height in inches
- Flag Icon: Visual indicator for problem blocks (grey = normal, red = flagged)
Interactive Features:
Inline Editing (Click any cell to edit):
- Density: Dropdown list of available densities
- Regrind %: Number input (0-100)
- Weight: Number input
- Silo Weight (
load_weight): Number input - Height: Number input
Changes are saved automatically via AJAX and trigger a success notification.
Auto-Refresh:
- Table data refreshes every 30 seconds to display newly created blocks
- Maintains current page position during refresh
Pagination:
- Default: 15 blocks per page
- Options: 15, 25, 50, 100
- Remote pagination (server-side)
Flag Block Feature
Purpose: Mark mold cycles with quality issues or problems for administrator review.
Workflow:
-
Operator clicks the flag icon next to a block
-
If block is not flagged (grey icon):
- Modal opens displaying:
- Block ID
- Block #
- Density
- Created timestamp
- Operator enters explanation in "What went wrong?" text area
- Clicks "Flag Mold" button
- System sends email notification to all administrators
- Icon turns red and modal closes
- Success notification: "Mold cycle flagged"
- Modal opens displaying:
-
If block already flagged (red icon):
- Single click immediately un-flags the block
- Icon returns to grey
- Success notification: "Mold cycle un-flagged"

Back-End Logic
Python Monitoring Script
Location: C:\Users\NIP\Desktop\shelter-ent-mold-app\main.py
The Python script runs continuously on the mold machine computer, monitoring changes to the monthly mold data file.
Configuration (settings.json):
{
"site_url": "https://dev.shelter-ent.app/index.php/",
"file_path": ".\\",
"mold_file_path": ".\\",
"controller": "api/mold",
"function": "import_mold_data",
"api_key": "YOUR_API_KEY",
"sleep_time": 30,
"headers": [...]
}
Key Functions:
File Monitoring (handle_file_change):
- Computes SHA3-512 hash of mold file every 30 seconds
- When hash changes, waits for file to stop changing (10-second intervals)
- Once stable, parses the file and exports to web application
Data Parsing (process_block_data):
- Reads tab-separated
.datfile fromC:\WINCC\dati\YYYYMM.dat - Parses 19 fields per block (time, date, recipe, block number, dimensions, weights, densities, cycle times, silo codes)
- Strips whitespace and structures data as JSON
- Stores local backup:
json_files\YYYYMM.json
API Communication (post_data):
- Posts JSON array to:
{site_url}/api/mold/import_mold_data - Includes Bearer token authentication
- Logs response status
Startup Behavior:
- Runs immediate export on script start
- Begins monitoring for file changes
- Displays: "DO NOT CLOSE THIS WINDOW (minimize it)"
Web Application Backend
Controller: App\Controllers\Mold (src/app/Controllers/Mold.php)
view() Method:
- Permission check:
super_admin,mold, oradmingroups - Renders:
mold/mold_in_progressview - Logs unauthorized access attempts
API Controller: App\Controllers\Api\Mold (src/app/Controllers/Api/Mold.php)
import_data() Method (/api/mold/import_mold_data):
-
Validates 19 block properties per record:
blocks.*.date: Valid date (m/d/Y format)blocks.*.time: Valid time (H:i:s format)blocks.*.block_num: Numeric (1-99998)blocks.*.height,*.weight,*.load_weight: Numeric > 0blocks.*.regrind: Numeric (0-100)blocks.*.density: Alpha-numeric stringblocks.*.raw_silo,*.ground_silo: Silo numbers- Silo codes for raw and ground material
-
Processes each block:
- Combines date + time into
createdtimestamp - Maps density string to database ID using
parse_density_string()helper - Defaults to "Custom" density if no match found
- Checks for existing block:
get_block(created, block_num) - If block doesn't exist → Creates new
Block_modelrecord - If block exists → Updates existing record
- Links block to lots from raw and ground silos
- Combines date + time into
-
Returns: Array of imported blocks with count
get_trend_data() Method (/api/mold/get_trend_data):
- Returns weekly mold statistics (see Helper Functions below)
API Controller: App\Controllers\Api\Block (src/app/Controllers/Api/Block.php)
get() Method (/api/block/get):
- Purpose: Fetches paginated blocks for table
- Parameters:
page,size(required)block_num,density,job_id(optional filters)
- Behavior:
- Returns only unused blocks (
date_used IS NULL) unlessjob_idspecified - Includes related
densitydata - Sorted by
created DESC
- Returns only unused blocks (
save() Method (/api/block/save):
- Purpose: Updates block properties from inline editing
- Validates:
block_id,density_id,block_num,created,height,regrind,weight,load_weight - Returns: Updated block model
flag() Method (/api/block/flag):
- Purpose: Flags/un-flags blocks for quality issues
- Parameters:
block_id: Block to flagflagged: 0 (un-flag) or 1 (flag)comments: Explanation (max 1000 chars, required even if empty string)
- Updates:
Block_modelfields:flagged,comments - Returns: Updated block
Model: App\Models\Block_model (src/app/Models/Block_model.php)
Table: block
Fillable Fields:
density_id,block_num,created,height,regrind,weight,depth,load_weight,raw_silo,ground_silo
Relationships:
density(): BelongsToDensity_modelcut_job(): BelongsToJob_modeleifs_blocks(): HasManyEifs_block_model(unused)used_eifs_blocks(): HasManyEifs_block_model(used)
Timestamps: Enabled (created_at, updated_at)
Helper Functions (src/app/Helpers/block_helper.php)
get_block(string $date, int $block_num): ?stdClass:
- Queries database for block matching date and block number
- Used to prevent duplicate blocks during import
- Returns first matching row or null
parse_density_string(string $density_string): int:
- Maps mold machine density labels to database density IDs
- Handles variations: spaces, hashtags, case-insensitive
- Returns density ID or -1 if not found
- Example: "1.5 regrind" → matches "
1.5#Regrind" density
get_mold_trend_data(): array:
- Calculates blocks created per weekday (this week vs last week)
- Computes average cycle time for each day
- Returns percentage change and weekly totals
- Used for dashboard analytics
get_average_cycle_time(Collection $blocks): string:
- Calculates mean time between block creation timestamps
- Returns formatted string: "Xh Ym Zs"
Data Flow
Mold Machine
↓ (exports to file)
C:\WINCC\dati\YYYYMM.dat
↓ (monitored by)
Python Script (main.py)
↓ (detects changes via hash)
Parse CSV → JSON
↓ (POST request)
API: /api/mold/import_mold_data
↓ (validates & processes)
Database: block table
↓ (fetched by)
API: /api/block/get
↓ (displays in)
Mold In Progress Page (Tabulator table)
↓ (operator edits)
API: /api/block/save
↓ (updates)
Database: block table
Developer Notes
Important Considerations
Duplicate Prevention:
- The
get_block()helper checks for existing blocks by date + block_num - Block numbers reset to 1 at the start of each month
- Import always updates existing blocks rather than creating duplicates
Density Matching:
parse_density_string()uses fuzzy matching for density labels- Multiple label variations tested (with/without spaces, hashtags)
- Falls back to "Custom" density if no match found
- Prevents import failures due to label mismatches
Silo/Lot Linking:
- Blocks are automatically linked to lots in the silos they were created from
- Links created in
block_lotsjunction table - Enables traceability of raw materials used in each block
Real-Time Updates:
- Python script runs on startup and monitors continuously
- Web interface refreshes table every 30 seconds
- Inline edits save immediately via AJAX
- No page reload required for data updates
Flagging System:
- Admin notification sent via
send_notification()helper - Notification includes all block details + operator comments
- Un-flagging requires no comment (empty string accepted)
Database Fields
Block Table Columns (from import):
- id (auto-increment)
- density_id (foreign key)
- block_num (from mold machine)
- created (parsed from date + time)
- height (inches)
- regrind (percentage 0-100)
- weight (block weight in lbs)
- load_weight (silo weight in lbs)
- depth (inches)
- raw_silo (silo number)
- ground_silo (silo number)
- raw_silo_code (raw material code)
- ground_silo_code (ground material code)
- cut_job_id (null until used)
- date_used (null until used)
- flagged (0 or 1)
- comments (operator notes)
- created_at (timestamp)
- updated_at (timestamp)
API Endpoints Used
| Endpoint | Method | Purpose |
|---|---|---|
/api/mold/import_mold_data | POST | Import block data from Python script |
/api/mold/get_trend_data | POST | Fetch weekly statistics |
/api/block/get | POST | Fetch paginated blocks for table |
/api/block/save | POST | Update block properties |
/api/block/flag | POST | Flag/un-flag blocks |
/api/density/get_all | POST | Load density dropdown options |
JavaScript Libraries
- Tabulator: Interactive table with inline editing and pagination
- jQuery: AJAX requests and DOM manipulation
- Moment.js: Date/time formatting
- Notify.js: Success/error notifications
Validation Rules
Import Validation:
- Dates must be valid
m/d/Yformat - Times must be valid
H:i:sformat - Block numbers: 1-99998
- Regrind: 0-100%
- Heights, weights must be > 0
- Silo numbers within acceptable ranges
Save Validation:
- All numeric fields ≥ 0
- Regrind ≤ 100
- Density ID must exist in database
- Block ID must exist
Flag Validation:
- Flagged must be 0 or 1
- Comments required (even if empty string)
- Max 1000 characters
Example Usage
Normal Operation
-
Mold Machine Starts:
- Python script launches automatically
- Performs initial export of all blocks in current month's file
- Begins monitoring for changes
-
Block is Molded:
- Mold machine writes block data to
202410.dat - Python script detects file hash change
- Waits for file to stabilize (10 seconds)
- Parses entire file and POSTs to API
- Web application validates and stores/updates blocks
- Mold machine writes block data to
-
Operator Views Page:
- Navigates to
/mold/view - Sees table of all unused blocks
- Table auto-refreshes every 30 seconds
- Navigates to
-
Operator Edits Block:
- Clicks "Regrind %" cell for block #1077
- Changes value from "0" to "8"
- Clicks outside cell
- AJAX request saves change
- Success notification appears
-
Operator Flags Problem Block:
- Clicks grey flag icon next to block #1075
- Modal opens with block details
- Types: "Block weight too low, density incorrect"
- Clicks "Flag Mold" button
- Admin receives email notification
- Icon turns red in table
Troubleshooting Scenario
Problem: Block appears in mold file but not in web application
Solution:
- Check Python script console for errors
- Verify script is running (should show "Waiting for file changes...")
- Check
logs/log-YYYY-MM-DD.txtfor error messages - Verify API key in
settings.jsonis valid - Check network connectivity between mold computer and web server
- Review web application logs for validation errors
Problem: Density shows as "Custom" when it should be specific type
Solution:
- Check exact density string in
.datfile - Add new variation to
parse_density_string()function - Or update density label in database to match mold machine output
Data Comparison (Admin Feature)
Purpose: Verify all blocks from mold file are in database
Workflow:
- Admin navigates to Admin Panel
- Clicks "Data Comparison" under Database section
- Selects and uploads block file (
.datformat) - Clicks "Compare Mold File to Inventory"
- System displays:
- Count of blocks not found
- Date and block number for each missing block
Use Case: Monthly audit to ensure no blocks were missed during import
Related Documentation
Integrated Systems
- [Pre-Expansion Station]: Blocks are created from pre-expanded bead
- [Inventory Management]: Blocks tracked as primary inventory
- [EIFS Cutting Station]: Uses blocks to create EIFS blocks
- [Line Cutting Station]: Uses blocks to create line items
- [Silo Management]: Tracks bead source for each block
- [Lot Tracking]: Links blocks to material lot numbers
Related Code Files
- Python Script:
C:\Users\NIP\Desktop\shelter-ent-mold-app\main.py - Settings:
shelter-ent-mold-app\settings.json - View Controller:
src/app/Controllers/Mold.php - API Controllers:
src/app/Controllers/Api/Mold.phpsrc/app/Controllers/Api/Block.php
- Model:
src/app/Models/Block_model.php - Helpers:
src/app/Helpers/block_helper.php - View:
src/app/Views/mold/mold_in_progress.php - JavaScript:
src/public/js/mold/mold_in_progress.js - CSS:
src/public/css/mold/mold_in_progress.css
Database Tables
block(primary)density(lookup)silo(material source)lot(material batch)block_lots(junction table)job(when blocks are used)eifs_block(derived inventory)
Cost Calculations
Labor Cost – Mold:
Mold Labor Cost = Molder Rate of Pay × Pre-defined Pre-Expansion Time
- Molder Rate of Pay: Hourly rate for employees labeled as "Mold"
- Pre-defined Pre-Expansion Time: Standard mold time per density/recipe
Material Cost per Block:
Block Material Cost =
[(Price per lb / 2) × (Block Weight × Regrind %)] +
[(Price per lb) × (Block Weight × Virgin %)] /
Number of Blocks Created