Organizes 11 projects for Cerbo GX/Venus OS into a single repository: - axiom-nmea: Raymarine LightHouse protocol decoder - dbus-generator-ramp: Generator current ramp controller - dbus-lightning: Blitzortung lightning monitor - dbus-meteoblue-forecast: Meteoblue weather forecast - dbus-no-foreign-land: noforeignland.com tracking - dbus-tides: Tide prediction from depth + harmonics - dbus-vrm-history: VRM cloud history proxy - dbus-windy-station: Windy.com weather upload - mfd-custom-app: MFD app deployment package - venus-html5-app: Custom Victron HTML5 app fork - watermaker: Watermaker PLC control UI Adds root README, .gitignore, project template, and per-project .gitignore files. Sensitive config files excluded via .gitignore with .example templates provided. Made-with: Cursor
68 KiB
Watermaker PLC API Reference
Complete Technical Specification and Implementation Guide
Document Information
- Version: 3.0 (Reorganized Structure)
- Date: January 2026
- Purpose: Comprehensive reference combining PLC register specifications with RESTful API implementation guidance
- Scope: Complete watermaker system control, monitoring, and integration documentation
- Audience: System integrators, developers, technicians, and operators
Table of Contents
- Introduction
- 1.1 Document Overview
- 1.2 Audience & Purpose
- 1.3 Document Conventions
- Quick Start Guide
- 2.1 Installation
- 2.2 Configuration
- 2.3 Running the API
- 2.4 Basic Examples
- System Architecture
- 3.1 Hardware Platform
- 3.2 Software Components
- 3.3 Data Flow Overview
- API Reference
- Watermaker Operations
- PLC Register Reference
- 6.1 System Control Registers
- 6.2 Sensor Registers
- 6.3 Timer Registers
- 6.4 Counter Registers
- 6.5 RTC Registers
- 6.6 Invalid Reading Handling
- Error Handling
- Appendices
- Appendix A: Complete Register Address Table
- Appendix B: Output Coil Addresses
- Appendix C: API Data Groups Reference
- Appendix D: 32-bit Register Conversion
- Appendix E: Complete Mode/Step/Timer Reference
- Appendix F: Consumables Calculation Logic
- Appendix G: Quick Reference Command Summary
- Appendix H: Process Flow Diagrams
1. Introduction
1.1 Document Overview
This document provides a comprehensive reference for the Watermaker PLC system, combining detailed register-level specifications with practical RESTful API implementation guidance. It serves as both a technical specification for direct PLC communication and a practical guide for API-based system integration.
Key Features:
- Dual-Level Access: Direct PLC register manipulation and high-level API operations
- Real-time Monitoring: Comprehensive sensor data, timers, and system status
- Asynchronous Control: Multi-mode watermaker operation sequences with progress tracking
- Bandwidth Optimization: Selective data retrieval for efficient monitoring
- Thread-safe Operations: Concurrent access support with centralized caching
- Comprehensive Error Handling: Structured responses and troubleshooting guidance
1.2 Audience & Purpose
This document is intended for:
- System Integrators: Building applications that interface with the watermaker
- Developers: Implementing API clients or direct PLC communication
- Technicians: Troubleshooting and maintaining the system
- Operators: Understanding system behavior and monitoring capabilities
1.3 Document Conventions
Register Addressing
- Holding Registers: Standard Modbus holding registers (function code 3 for read, 6 for write)
- Input Registers: Read-only registers (function code 4)
- Address Format: Decimal addressing used throughout this document
- Data Width: 16-bit registers unless specified as 32-bit pairs
Data Types and Scaling
| Type | Description | Example |
|---|---|---|
| Direct | Raw register value used without modification | R1000 mode value |
| ÷10 | Divide register value by 10 for actual value | R1120: 125 = 12.5 GPM |
| IEEE 754 | 32-bit floating point from register pair | R5014/R5015 runtime hours |
| Bit-mapped | Individual bits within register represent separate controls | R71 commands |
Register Access Types
- Read-only: Sensor inputs, timers, counters (monitoring only)
- Write-only: Output controls (command only)
- Read/Write: System control, configuration registers
Terminology
| Term | Meaning |
|---|---|
| FWF | Fresh Water Flush |
| DTS | Dockside Treatment System |
| SP | Single Pass (sea water mode) |
| DP | Double Pass (sea water mode) |
| LPP | Low Pressure Pump |
| HPP | High Pressure Pump |
| APC | Automatic Pressure Control valve |
| TDS | Total Dissolved Solids (PPM) |
2. Quick Start Guide
2.1 Installation
# Clone repository
git clone <repository-url>
cd watermaker-plc-api
# Install dependencies
pip install -r requirements.txt
# Install package
pip install -e .
2.2 Configuration
Set environment variables for both PLC communication and API deployment:
# PLC Connection
export PLC_IP=198.18.100.141
export PLC_PORT=502
# API Configuration
export DATA_UPDATE_INTERVAL=5
export LOG_LEVEL=INFO
export FLASK_ENV=production
export SECRET_KEY=your-secret-key
2.3 Running the API
# Using the command line entry point
watermaker-api --host 0.0.0.0 --port 5000
# Or run directly
python -m api.main
2.4 Basic Examples
Monitor System Status
# Get complete system status
curl http://localhost:5000/api/status
# Get all sensor data
curl http://localhost:5000/api/sensors
# Get specific data groups (bandwidth optimized)
curl "http://localhost:5000/api/select?groups=temperature,pressure"
Control Operations
# Start DTS sequence
curl -X POST "http://localhost:5000/api/start?mode=dts"
# Stop current operation
curl -X POST http://localhost:5000/api/stop
# Skip current step (if allowed)
curl -X POST http://localhost:5000/api/skip
3. System Architecture
3.1 Hardware Platform
Raspberry Pi Zero 2 W (Preferred)
- Quad-core ARM Cortex-A53 @ 1GHz
- 512MB RAM
- Built-in WiFi 802.11 b/g/n & Bluetooth 4.2
- 40-pin GPIO header
- microSD card slot (minimum 16GB, Class 10)
- Mini HDMI port
- 2x micro USB ports
3.2 Software Components
┌──────────────────────────────────────────────────────────────┐
│ Client Applications │
├──────────────────────────────────────────────────────────────┤
│ RESTful API Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ Controllers │ │ Services │ │ Background Tasks │ │
│ │ │ │ │ │ │ │
│ │ • Status │ │ • Register │ │ • Continuous Monitoring │ │
│ │ • Sensors │ │ Reader │ │ • Data Caching │ │
│ │ • Control │ │ • Register │ │ • Sequence Management │ │
│ │ • Timers │ │ Writer │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
├──────────────────────────────────────────────────────────────┤
│ Data Cache Layer │
│ (Thread-safe, Centralized Storage) │
├──────────────────────────────────────────────────────────────┤
│ PLC Communication │
│ (Modbus TCP) │
├──────────────────────────────────────────────────────────────┤
│ Watermaker PLC Hardware │
│ Sensors • Pumps • Valves • Timers • Counters │
└──────────────────────────────────────────────────────────────┘
Key Components:
- PLCConnection: Thread-safe Modbus TCP communication
- DataCache: Centralized, thread-safe data storage with automatic updates
- RegisterReader: Service for reading PLC registers with error handling
- RegisterWriter: Service for writing PLC registers with validation
- BackgroundTaskManager: Continuous data updates and sequence monitoring
- Controllers: RESTful API endpoints organized by functional groups
3.3 Data Flow Overview
- Background Monitoring: Continuous PLC register polling updates centralized cache
- API Requests: Controllers retrieve data from cache (fast response) or directly from PLC
- Control Operations: API commands translate to specific register write sequences
- Status Tracking: Operation progress monitored through register state changes
4. API Reference
4.1 Monitoring Endpoints
System Status
GET /api/status
Response Format:
{
"connection": {
"status": "connected",
"plc_ip": "198.18.100.141",
"last_update": "2025-06-14T20:53:00Z"
},
"system": {
"mode": 7,
"submode": 1,
"status": 3,
"mode_name": "Single Pass Sea Water",
"status_name": "Running"
},
"rtc": {
"hour": 20,
"minutes": 53,
"seconds": 15,
"year": 2025,
"month": 6,
"day": 14
}
}
All Data
GET /api/all
Returns complete system data including sensors, timers, outputs, runtime, and water counters.
Selective Data Retrieval
GET /api/select?groups={group1,group2}&keys={reg1,reg2}
Parameters:
groups: Comma-separated list of data groups (see Appendix C)keys: Comma-separated list of specific register addresses
Examples:
# Get temperature and pressure sensors only
curl "http://localhost:5000/api/select?groups=temperature,pressure"
# Get specific registers
curl "http://localhost:5000/api/select?keys=1036,1003,1007,1121"
# Combined approach
curl "http://localhost:5000/api/select?groups=production_timer&keys=1036"
Sensors
GET /api/sensors
Response Format:
{
"pressure": {
"feed": 45,
"high_1": 850,
"high_2": 825
},
"temperature": {
"system": 82.5
},
"flow": {
"brine": 12.5,
"product_1": 8.5,
"product_2": 4.2
},
"quality": {
"tds_1": 125,
"tds_2": 45
}
}
Timers
GET /api/timers
Response Format:
{
"fwf_timer": {
"flush": 45.5
},
"production_timer": {
"priming": 65535,
"initialize": 65535,
"highpressure": 65535,
"stop": 65535,
"valve_positioning": 0,
"flush": 65535,
"fwf": 65535
}
}
Timer Value Interpretation:
- Active Timer: Value counts down from expected start value to 0
- Inactive Timer: Value = 65535 (indicates timer not running)
- Completed Timer: Value = 0 (timer has finished)
For complete timer register details, see Appendix E: Complete Mode/Step/Timer Reference.
Outputs
GET /api/outputs
Response Format:
{
"low_pressure_pump": 1,
"high_pressure_pump": 1,
"product_divert_valve": 0,
"flush_solenoid": 0,
"double_pass_solenoid": 1,
"shore_feed_solenoid": 1
}
Runtime
GET /api/runtime
Response Format:
{
"hours": 1247.5
}
Water Counters
GET /api/water_counters
Response Format:
{
"single_pass_total": 15420,
"single_pass_since_last": 125,
"double_pass_total": 8750,
"double_pass_since_last": 85,
"dts_total": 2340,
"dts_since_last": 45
}
4.2 Consumables Endpoints
The consumables tracking system monitors replaceable components (filters, membranes, pump oil) and calculates usage based on water production and runtime hours. For detailed calculation logic, see Appendix F.
Get All Consumables
GET /api/consumables
Response Format:
{
"consumables": {
"primary_membrane": {
"name": "Primary Sea Water Membrane",
"current_usage": 45230,
"limit": 100000,
"unit": "gallons",
"percent_consumed": 45.23,
"remaining": 54770,
"status": "OK"
},
"five_micron_filter": {
"name": "5 Micron Primary Filter",
"current_usage": 8500,
"limit": 10000,
"unit": "gallons",
"percent_consumed": 85.0,
"remaining": 1500,
"status": "Soon"
}
}
}
Status Values:
OK: < 80% consumed (green)Soon: 80-99% consumed (yellow warning)Replace: ≥ 100% consumed (red critical)
Get Consumables Summary
GET /api/consumables/summary
Response Format:
{
"needs_attention": [
{"id": "five_micron_filter", "name": "5 Micron Primary Filter", "percent": 102.5}
],
"approaching_limit": [
{"id": "hp_pump_oil", "name": "High Pressure Pump Oil", "percent": 85.0}
],
"total_consumables": 7
}
Get Specific Consumable
GET /api/consumables/{consumable_id}
Parameters:
consumable_id: One of:primary_membrane,secondary_membrane,five_micron_filter,small_carbon_filter,large_carbon_filter,hp_pump_oil,sea_strainer
Reset Consumable Counter
POST /api/consumables/{consumable_id}/reset
Resets the usage counter to 0 (typically called after replacing the consumable).
Set Consumable Limit
PUT /api/consumables/{consumable_id}/limit
Content-Type: application/json
{
"limit": 15000
}
4.3 Control Endpoints
All command endpoints return a predicted state immediately, allowing clients to update their UI without waiting for PLC verification. The prediction is verified asynchronously via WebSocket events. For complete prediction logic, see Appendix E.
Start Sequence
POST /api/start?mode={mode}
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
mode |
string | Yes | Operation mode: dts, single_pass, double_pass, fw_flush |
gallon_limit |
float | No | Maximum gallons before auto-stop |
time_limit |
integer | No | Maximum seconds before auto-stop |
run_type |
string | No | Run type: fill, gallons, timer, boat_wash, manual |
Response Format:
{
"success": true,
"mode": "dts",
"message": "DTS sequence started successfully",
"current_step": "valve_positioning",
"limits": {
"gallon_limit": 50.0,
"time_limit_seconds": 3600
},
"predicted_state": {
"system": {
"operating_mode": "dts",
"status": 0,
"status_name": "Valve Positioning",
"valve_positioning": true,
"active_timer": {
"timer_id": "dts_valve",
"value": 15.0,
"name": "Valve Positioning"
}
}
},
"verification_pending": true
}
Mode-Specific Initial States:
| Mode | Initial Status | Timer | Duration |
|---|---|---|---|
dts |
Valve Positioning | R138 | 15s |
single_pass |
Valve Positioning | R137 | 5s |
double_pass |
Valve Positioning | R137 | 5s |
fw_flush |
Flush Init | R135 | 10s |
Stop Sequence
POST /api/stop
Response Format:
{
"success": true,
"message": "Stop sequence initiated",
"predicted_state": {
"system": {
"status": 5,
"status_name": "Flushing",
"active_timer": {
"timer_id": "stop",
"value": 10.0,
"name": "Flush Init"
}
}
},
"verification_pending": true
}
Skip Current Step
POST /api/skip
Only valid during Priming (R1036=1) or Initializing (R1036=2) phases.
Response Format:
{
"success": true,
"message": "Step skipped successfully",
"previous_step": "priming",
"current_step": "initializing",
"predicted_state": {
"system": {
"status": 2,
"status_name": "Initializing",
"active_timer": {
"timer_id": "initialize",
"value": 60.0,
"name": "Initializing"
}
}
},
"verification_pending": true
}
Write Single Register
POST /api/write/register
Content-Type: application/json
{
"register": 1000,
"value": 7
}
4.4 WebSocket Events
After a command is executed and returns a predicted_state, the background task manager verifies the prediction against the actual PLC state. The result is broadcast via WebSocket to all connected clients.
Event: state_verified
Broadcast when the predicted state matches the actual PLC state.
{
"event": "state_verified",
"data": {
"command_type": "start",
"verification_time_ms": 150,
"timestamp": "2026-01-04T10:30:00Z"
}
}
Event: state_correction
Broadcast when the actual state differs from the prediction.
{
"event": "state_correction",
"data": {
"expected": {
"status": 0,
"status_name": "Valve Positioning"
},
"actual": {
"status": 1,
"status_name": "Priming"
},
"command_type": "start",
"timestamp": "2026-01-04T10:30:00Z"
}
}
Event: timer_correction
Broadcast when a timer value drifts significantly (>2 seconds) from the expected value.
{
"event": "timer_correction",
"data": {
"timer_id": "priming",
"actual_value": 165.5,
"expected_value": 168.0,
"drift_seconds": 2.5,
"timestamp": "2026-01-04T10:30:00Z"
}
}
Event: remote_change
Broadcast when a state change is detected from an external HMI panel (not initiated via API).
{
"event": "remote_change",
"data": {
"change_type": "remote_start",
"previous_state": {
"status": 0,
"status_name": "Idle"
},
"current_state": {
"status": 1,
"status_name": "Priming",
"operating_mode": "single_pass"
},
"timestamp": "2026-01-04T10:30:00Z"
}
}
Remote Change Types:
| Type | Description |
|---|---|
remote_start |
Production started from external HMI |
remote_stop |
Production stopped from external HMI |
remote_skip |
Step skipped from external HMI |
remote_mode_change |
Operating mode changed from external HMI |
4.5 Predictive State Response Format
All command responses include a predicted_state object:
{
"system": {
"operating_mode": "dts",
"status": 0,
"status_name": "Valve Positioning",
"valve_positioning": true,
"active_timer": {
"timer_id": "dts_valve",
"value": 15.0,
"name": "Valve Positioning"
}
}
}
Fields:
| Field | Type | Description |
|---|---|---|
operating_mode |
string | Current mode: dts, single_pass, double_pass, fwf, idle |
status |
integer | Production step: 0=Idle, 1=Prime, 2=Init, 3=Run, 4=Stop, 5=Flush |
status_name |
string | Human-readable status name |
valve_positioning |
boolean | True during valve positioning phase |
active_timer |
object/null | Timer information if a timer is active |
For complete prediction logic and state tables, see Appendix E.
5. Watermaker Operations
5.1 Operating Modes Overview
The watermaker system operates in four primary production modes:
| Mode | API Parameter | Description | Feed Source |
|---|---|---|---|
| DTS | dts |
Dockside Treatment System | Shore/city water |
| Single Pass | single_pass |
Single membrane sea water processing | Sea water |
| Double Pass | double_pass |
Dual membrane sea water processing | Sea water |
| Fresh Water Flush | fw_flush |
Post-production membrane flush | Onboard tank water |
System Screen Values (R1000)
The R1000 register indicates the current screen displayed on the HMI and can be used to control mode transitions:
| Value | Name | Description | API Mode |
|---|---|---|---|
| 65535 | Standby/Screen Saver | System in standby mode | - |
| 2 | Home | System idle at home screen | - |
| 5 | Priming | Prime with shore water | prime |
| 6 | Initializing | High pressure pump on, stabilize | init |
| 7 | Run | High pressure pump on, water to tank | run |
| 8 | Fresh Water Flush | Post-production or Manual flush | fw_flush |
| 33 | SeaWater Request | Long press - Single or double pass | single_pass/double_pass |
| 34 | DTS Request | Press and hold to START | dts |
5.2 Production Sequence
All water production modes follow a common sequence pattern:
Idle → Valve Positioning → Priming → Initializing → Running → Flushing → Idle
| Step | R1036 Value | Description | Typical Timer |
|---|---|---|---|
| Valve Positioning | 0 | Valves move to correct positions | R137 (5s) or R138 (15s) |
| Priming | 1 | Low pressure flush to prime system | R128 (180s) |
| Initializing | 2 | High pressure pump stabilization | R129 (60s) |
| Running | 3 | Active water production | None (continuous) |
| Stopping | 4 | Transition to flush | - |
| Flushing | 5 | Fresh water membrane flush | R135 (10s) then R139 (60s) |
Control Operations:
- Start: Only valid when R1036 = 0 (Idle)
- Stop: Valid when R1036 = 1, 2, 3, or 5
- Skip: Only valid when R1036 = 1 (Priming) or 2 (Initializing)
For the complete mode/step/timer reference including register values and detection algorithms, see Appendix E.
5.3 Mode-Specific Details
5.3.1 DTS Operation Sequence
DTS mode uses shore/city water through the freshwater membrane for polishing.
API: POST /api/start?mode=dts
├── Valve Positioning (R138 timer, 15s)
├── Priming (R128 timer, 180s)
├── Initializing (R129 timer, 60s)
├── Running (continuous)
├── Flushing (R135 → R139 timers)
└── Complete → Idle
Key Characteristics:
- Feed valve directed to dock water
- Low pressure pump typically off (shore pressure sufficient)
- Uses secondary membrane only
- Shore feed solenoid energized
5.3.2 Single Pass Operation Sequence
Single pass mode processes sea water through a single membrane.
API: POST /api/start?mode=single_pass
├── Valve Positioning (R137 timer, 5s)
├── Priming (R128 timer, 180s)
├── Initializing (R129 timer, 60s)
├── Running (continuous)
├── Flushing (R135 → R139 timers)
└── Complete → Idle
Key Characteristics:
- Feed valve directed to sea water
- Low pressure pump runs during operation
- Uses primary membrane only
- Product monitored via R1123 (TDS #1)
5.3.3 Double Pass Operation Sequence
Double pass mode provides ultra-pure water through two sequential membranes.
API: POST /api/start?mode=double_pass
├── Valve Positioning (R137 timer, 5s)
├── Priming (R128 timer, 180s)
├── Initializing Phase 1 (R129 timer, 60s)
├── PPM Stabilizing Phase 2 (R131 timer, 60s)
├── Running (continuous)
├── Flushing (R135 → R139 timers)
└── Complete → Idle
Key Characteristics:
- Feed valve directed to sea water
- Both membranes active during production
- Extra initialization phase for PPM stabilization (R131)
- Product monitored via both R1123 and R1124
5.3.4 Fresh Water Flush Sequence
Manual flush can be initiated from idle to preserve membranes.
API: POST /api/start?mode=fw_flush
├── Flush Init (R135 timer, 10s)
├── Flushing (R136 timer, 60s - manual FWF)
└── Complete → Idle
Key Characteristics:
- Uses onboard tank water via small carbon filter
- All pumps remain off
- Flush solenoid opens for gravity flow
- Distinguishes from post-production flush via R136 (manual) vs R139 (post-prod)
6. PLC Register Reference
6.1 System Control Registers
R1000 - System Mode (Read/Write)
- Function: Primary system mode control and status
- Unit: Mode code (see System Screen Values)
- Scale: Direct
- Access: Read/Write
- API:
GET /api/status(system.mode)
R1036 - Production Sequence Step (Read-only)
- Function: System operational status
- Unit: Status code
- Scale: Direct
- Access: Read-only
- API:
GET /api/status(system.status) - Values: 0=Idle, 1=Priming, 2=Initializing, 3=Running, 4=Stopping, 5=Flushing
R67 - Skip Operation Control (Write-only)
- Function: DTS step skip control register
- Unit: Command code
- Scale: Direct
- Access: Write-only
- API:
POST /api/skip - Values:
32841: Skip from priming to initialize (valid when R1036=1)32968: Skip from initialize to production (valid when R1036=2)
R71 - Mode Sequence Control (Write-only)
- Function: Operation mode start and stop control register
- Unit: Command code
- Scale: Direct
- Access: Write-only
- API:
POST /api/start,POST /api/stop - Start Commands (only when R1036=0/Idle):
64: Start Single Pass Sea Water128: Start Double Pass Sea Water256: Start DTS Mode32768: Fresh Water Flush - Ships Water
- Stop Commands (when R1036≠0/Non-idle):
512: Priming/Initializing Stop513: Running Stop1024: Fresh Water Flush Stop
6.2 Sensor Registers
Pressure Sensors
| Register | Name | Unit | Scale | API Field |
|---|---|---|---|---|
| R1003 | Feed Pressure | PSI | Direct | pressure.feed |
| R1005 | High Pressure #1 | PSI | Direct | pressure.high_1 |
| R1007 | High Pressure #2 | PSI | Direct | pressure.high_2 |
Flow Meters
| Register | Name | Unit | Scale | API Field |
|---|---|---|---|---|
| R1120 | Brine Flowmeter | GPM | ÷10 | flow.brine |
| R1121 | 1st Pass Product Flowmeter | GPM | ÷10 | flow.product_1 |
| R1122 | 2nd Pass Product Flowmeter | GPM | ÷10 | flow.product_2 |
Quality Sensors
| Register | Name | Unit | Scale | API Field |
|---|---|---|---|---|
| R1123 | Product TDS #1 | PPM | Direct | quality.tds_1 |
| R1124 | Product TDS #2 | PPM | Direct | quality.tds_2 |
Temperature
| Register | Name | Unit | Scale | API Field |
|---|---|---|---|---|
| R1125 | System Temperature | °F | ÷10 | temperature.system |
6.3 Timer Registers
For complete timer reference including which timers are active during each mode/step, see Appendix E.
| Register | Name | Duration | Purpose |
|---|---|---|---|
| R128 | Priming Timer | 180s | Low pressure system prime |
| R129 | Initialize Timer | 60s | High pressure stabilization |
| R131 | Init Phase 2 (PPM Stab) | 60s | Double Pass PPM stabilization |
| R135 | Stop/Flush Init Timer | 10s | Pre-flush setup |
| R136 | Manual FWF Timer | 60s | Manual fresh water flush |
| R137 | SW Valve Positioning | 5s | Sea water valve positioning |
| R138 | DTS Valve Positioning | 15s | DTS valve positioning |
| R139 | Post-Production Flush | 60s | Post-production flush |
Timer Value Scaling: All timer registers use ÷10 scaling. Value 1800 = 180.0 seconds.
6.4 Counter Registers
Runtime Hours
- Registers: R5014/R5015 (32-bit IEEE 754 float)
- Unit: Hours
- API:
GET /api/runtime
Water Production Counters (32-bit IEEE 754 float)
| Registers | Description | API Field |
|---|---|---|
| R5024/R5025 | Single-Pass Total Gallons | water_counters.single_pass_total |
| R5026/R5027 | Single-Pass Since Last | water_counters.single_pass_since_last |
| R5028/R5029 | Double-Pass Total Gallons | water_counters.double_pass_total |
| R5030/R5031 | Double-Pass Since Last | water_counters.double_pass_since_last |
| R5032/R5033 | DTS Total Gallons | water_counters.dts_total |
| R5034/R5035 | DTS Since Last Gallons | water_counters.dts_since_last |
For 32-bit register conversion examples, see Appendix D.
6.5 RTC Registers
| Register | Function | Unit | Range |
|---|---|---|---|
| R512 | RTC Hour | Hours | 0-23 |
| R513 | RTC Minutes | Minutes | 0-59 |
| R514 | RTC Seconds | Seconds | 0-59 |
| R516 | RTC Year | Year | - |
| R517 | RTC Month | Month | 1-12 |
| R518 | RTC Day | Day | 1-31 |
Note: R515 is not used.
6.6 Invalid Reading Handling
Reading Sensor Process Flow
- Return cache value if < 2 seconds old
- Register read
- If valid (not 65535): return value
- If invalid:
- Check cache age
- Use cache if < 5 seconds old
- If cache expired: two more read attempts
- Return error if all attempts fail
Implementation Notes
- Maintain timestamped sensor reading cache
- Cache invalidation required when communication errors occur
- Reduce number of fast reads to prevent overload
- Logging recommended for repeated invalid readings
- Writing to a register should invalidate cache for that register
7. Error Handling
7.1 API Error Codes
| Error Code | Description | Cause | Resolution |
|---|---|---|---|
| INVALID_MODE_TRANSITION | Cannot start operation | System not idle (R1036 ≠ 0) | Stop current operation first |
| PLC_COMMUNICATION_ERROR | Cannot communicate with PLC | Network/connection issue | Check PLC IP and network |
| REGISTER_READ_TIMEOUT | Register read timeout | PLC not responding | Verify PLC status and connection |
| REGISTER_WRITE_FAILED | Register write failed | PLC rejected write | Check register permissions |
| INVALID_SKIP_OPERATION | Skip not allowed | Wrong step for skip | Only skip from priming/initializing |
| TIMER_VALIDATION_ERROR | Timer value inconsistent | Unexpected timer state | Check system mode and step |
| PRESSURE_SAFETY_LIMIT | Pressure outside safe range | Sensor reading abnormal | Check pressure sensors and system |
7.2 Register Read Errors
- Null Value: Communication failure with PLC
- 65535 on Timer: Timer not active or system not in expected mode
- Unexpected Mode Values: External interference or manual operation
7.3 Control Sequence Failures
- R1000 Write Failure: Check PLC communication and register access
- Timer Not Starting: Verify mode transition completed successfully
- Valve Positioning Timeout: R138 may not reach 0 within 15 seconds (continue operation)
7.4 Troubleshooting Guide
Monitoring Best Practices
- Continuous Monitoring: Read R1000 regularly to detect external changes
- Timer Validation: Verify timer values are reasonable (not 65535 when expected to be active)
- Flow Validation: Confirm flow rates match expected values for current mode
- Pressure Monitoring: Ensure pressures are within safe operating ranges
Appendices
Appendix A: Complete Register Address Table
| Register | Name | Type | Unit | Scale | Access | Category | API Endpoint |
|---|---|---|---|---|---|---|---|
| R67 | Skip Operation Control | Control | Command | Direct | Write | Control | POST /api/skip |
| R71 | Mode Sequence Control | Control | Command | Direct | Write | Control | POST /api/start, /api/stop |
| R128 | Priming Timer | Timer | Seconds | ÷10 | Read | Timer | GET /api/timers |
| R129 | Init Timer (All Modes) | Timer | Seconds | ÷10 | Read | Timer | GET /api/timers |
| R131 | Init Timer Phase 2 (PPM Stab) | Timer | Seconds | ÷10 | Read | Timer | GET /api/timers |
| R135 | Stop/FWF Setup Timer | Timer | Seconds | ÷10 | Read | Timer | GET /api/timers |
| R136 | Manual FWF Flush Timer | Timer | Seconds | ÷10 | Read | Timer | GET /api/timers |
| R137 | SW Valve Positioning Timer | Timer | Seconds | ÷10 | Read | Timer | GET /api/timers |
| R138 | DTS Valve Positioning Timer | Timer | Seconds | ÷10 | Read | Timer | GET /api/timers |
| R139 | DTS Flush Timer | Timer | Seconds | ÷10 | Read | Timer | GET /api/timers |
| R512 | RTC Hour | RTC | Hours | Direct | R/W | RTC | GET /api/status |
| R513 | RTC Minutes | RTC | Minutes | Direct | R/W | RTC | GET /api/status |
| R514 | RTC Seconds | RTC | Seconds | Direct | R/W | RTC | GET /api/status |
| R516 | RTC Year | RTC | Year | Direct | R/W | RTC | GET /api/status |
| R517 | RTC Month | RTC | Month | Direct | R/W | RTC | GET /api/status |
| R518 | RTC Day | RTC | Day | Direct | R/W | RTC | GET /api/status |
| R1000 | System Mode | Control | Mode | Direct | R/W | System | GET /api/status |
| R1003 | Feed Pressure | Sensor | PSI | Direct | Read | Pressure | GET /api/sensors |
| R1005 | High Pressure #1 | Sensor | PSI | Direct | Read | Pressure | GET /api/sensors |
| R1007 | High Pressure #2 | Sensor | PSI | Direct | Read | Pressure | GET /api/sensors |
| R1036 | System Status | Status | Status | Direct | Read | System | GET /api/status |
| R1120 | Brine Flowmeter | Sensor | GPM | ÷10 | Read | Flow | GET /api/sensors |
| R1121 | 1st Pass Product Flowmeter | Sensor | GPM | ÷10 | Read | Flow | GET /api/sensors |
| R1122 | 2nd Pass Product Flowmeter | Sensor | GPM | ÷10 | Read | Flow | GET /api/sensors |
| R1123 | Product TDS #1 | Sensor | PPM | Direct | Read | Quality | GET /api/sensors |
| R1124 | Product TDS #2 | Sensor | PPM | Direct | Read | Quality | GET /api/sensors |
| R1125 | System Temperature | Sensor | °F | ÷10 | Read | Temperature | GET /api/sensors |
| R5014/R5015 | Runtime Hours | Counter | Hours | IEEE754 | Read | Runtime | GET /api/runtime |
| R5024/R5025 | Single-Pass Total Gallons | Counter | Gallons | IEEE754 | Read | Water | GET /api/water_counters |
| R5026/R5027 | Single-Pass Since Last | Counter | Gallons | IEEE754 | Read | Water | GET /api/water_counters |
| R5028/R5029 | Double-Pass Total Gallons | Counter | Gallons | IEEE754 | Read | Water | GET /api/water_counters |
| R5030/R5031 | Double-Pass Since Last | Counter | Gallons | IEEE754 | Read | Water | GET /api/water_counters |
| R5032/R5033 | DTS Total Gallons | Counter | Gallons | IEEE754 | Read | Water | GET /api/water_counters |
| R5034/R5035 | DTS Since Last Gallons | Counter | Gallons | IEEE754 | Read | Water | GET /api/water_counters |
Appendix B: Output Coil Addresses
Modbus Coil Access
Output coils are read and written using Modbus coil function codes:
| Operation | Function Code | Description |
|---|---|---|
| Read Coils | FC 01 (0x01) | Read discrete output status |
| Write Single Coil | FC 05 (0x05) | Write single discrete output |
| Write Multiple Coils | FC 15 (0x0F) | Write multiple discrete outputs |
Important Addressing Notes:
- Coil addresses in this document use the PLC address (1-based or direct)
- For Modbus protocol, subtract 1 if your library uses 0-based addressing
- Example: PLC address 256 → Modbus address 256 (or 255 for 0-based libraries)
Coil Address Table
| Address | Function | Description | API Field |
|---|---|---|---|
| 256 | Low Pressure Pump | Controls low pressure pump operation | outputs.low_pressure_pump |
| 257 | High Pressure Pump | Controls high pressure pump operation | outputs.high_pressure_pump |
| 258 | Quality Solenoid | Controls product quality divert valve | outputs.quality_solenoid |
| 259 | Flush Solenoid | Controls flush water valve operation | outputs.flush_solenoid |
| 260 | (Reserved) | Not currently used | - |
| 261 | (Reserved) | Not currently used | - |
| 262 | (Reserved) | Not currently used | - |
| 263 | Double Pass Solenoid | Controls double pass mode valve | outputs.double_pass_solenoid |
| 264 | Shore Feed Solenoid | Controls shore water feed valve | outputs.shore_feed_solenoid |
Reading Output Coils
from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('198.18.100.141', port=502)
client.connect()
# Read 9 coils starting at address 256 (covers addresses 256-264)
result = client.read_coils(address=256, count=9, slave=1)
if not result.isError():
low_pressure_pump = result.bits[0] # Address 256
high_pressure_pump = result.bits[1] # Address 257
quality_solenoid = result.bits[2] # Address 258
flush_solenoid = result.bits[3] # Address 259
# bits[4-6] are reserved (addresses 260-262)
double_pass_solenoid = result.bits[7] # Address 263
shore_feed_solenoid = result.bits[8] # Address 264
client.close()
Coil Values
| Value | State | Description |
|---|---|---|
| 0 / False | OFF | Output is de-energized |
| 1 / True | ON | Output is energized |
Appendix C: API Data Groups Reference
| Group | Description | Register Count | Registers Included |
|---|---|---|---|
| system | System status and mode | 2 | R1000, R1036 |
| pressure | Water pressure sensors | 3 | R1003, R1005, R1007 |
| temperature | Temperature monitoring | 1 | R1125 |
| flow | Flow rate meters | 3 | R1120, R1121, R1122 |
| quality | Water quality (TDS) sensors | 2 | R1123, R1124 |
| fwf_timer | Manual Fresh water flush timers | 1 | R136 |
| production_timer | Production process step timers | 7 | R128, R129, R131, R135, R137, R138, R139 |
| rtc | Real-time clock data | 6 | R512, R513, R514, R516, R517, R518 |
| outputs | Digital output controls | 6 | Coils 256-264 |
| runtime | System runtime hours | 1 | R5014/R5015 |
| water_counters | Water production counters | 6 | R5024-R5035 |
Appendix D: 32-bit Register Conversion
IEEE 754 Float Conversion (Runtime Hours)
import struct
def convert_ieee754_registers(high_reg, low_reg):
"""Convert two 16-bit registers to IEEE 754 float"""
combined = (high_reg << 16) | low_reg
return struct.unpack('!f', struct.pack('!I', combined))[0]
# Example: R5014=0x4298, R5015=0x0000
# Result: 76.0 hours
Gallon Counter Conversion (IEEE 754 Float)
def convert_gallon_counter(high_reg, low_reg):
"""Convert two 16-bit registers to IEEE 754 float gallons"""
combined = (high_reg << 16) | low_reg
return struct.unpack('!f', struct.pack('!I', combined))[0]
# Example: R5024=0x4796, R5025=0x18D5
# Result: 76808.83 gallons
API Response Format for 32-bit Values
{
"runtime": {
"hours": 76.0,
"raw_registers": {
"high": 17048,
"low": 0
}
},
"water_counters": {
"single_pass_total": 76808,
"raw_registers": {
"high": 1,
"low": 11272
}
}
}
Appendix E: Complete Mode/Step/Timer Reference
This appendix serves as the authoritative reference for all mode/step/timer relationships. When in doubt about state detection or timer behavior, refer to this section.
E.1 Core Register Overview
| Register | Name | Purpose | Key Values |
|---|---|---|---|
| R1036 | production_step | Current production sequence step | 0=Idle, 1=Prime, 2=Init, 3=Run, 4=Stop, 5=Flush |
| R1037 | step_detail | Step sub-phase indicator | 0=Idle, 1=Prime/Valve, 2=Init/Run, 4=Flush Init, 7=Flushing |
| R1038 | mode_indicator_1 | Secondary mode flag | 2=SW active (Run), 4=Idle/DTS/FWF |
| R1039 | mode_indicator_2 | Double pass indicator | 0=Single Pass/DTS/Idle, 1-2=Double Pass |
| R1040 | mode_indicator_3 | Primary mode discriminator | 0=SW/Idle, 2=DTS |
E.2 Detection Algorithm
1. Read R1036-R1040 as the primary state indicators
2. IF R1040 == 2 → MODE = DTS
3. ELSE IF R1040 == 0 AND R1039 == 0:
- IF R1038 == 4 → MODE = IDLE (unless R1036 > 0, then SINGLE_PASS)
- IF R1038 == 2 → MODE = SINGLE_PASS (active run)
4. ELSE IF R1040 == 0 AND R1039 > 0 → MODE = DOUBLE_PASS
5. IF R1036 == 5 → Check R1037 and flush timers for FWF detection
6. IF R1036 == 0 AND valve timer active → VALVE_POSITIONING phase
Key Implementation Notes:
-
FWF Detection: Mode indicators (R1038-R1040) show idle signature during FWF. Must use R1036=5 combined with R1037 and flush timers (R135, R136, R139) to detect flush state.
-
Valve Positioning: During startup, R1036 stays at 0 while valve timer (R137 or R138) counts down. Check timer activity to detect valve positioning phase.
-
Double Pass Init Phases: R1036 stays at 2 for both init phases. Distinguish by checking which timer is active:
- R129 active → First init phase (dp_init)
- R131 active → PPM stabilization phase (dp_stab)
-
Post-Production vs Manual Flush: Both show R1036=5, R1037=7. Distinguish by timer:
- R136 active → Manual FWF (user-initiated)
- R139 active → Post-production flush (after production)
E.3 Complete Mode/Step/Timer Tables
DTS (Dockside Treatment System) Mode
| Step | Abbreviation | R1036 | R1037 | R1038 | R1039 | R1040 | Active Timer | Duration |
|---|---|---|---|---|---|---|---|---|
| Valve Positioning | dts_valve | 0 | 1 | 4 | 0 | 2 | R138 | 15s |
| Priming | dts_prime | 1 | 1 | 4 | 0 | 2 | R128 | 180s |
| Initializing | dts_init | 2 | 2 | 4 | 0 | 2 | R129 | 60s |
| Running | dts_run | 3 | 2 | 4 | 0 | 2 | None | Continuous |
| Stopping | dts_stop | 4 | - | 4 | 0 | 2 | - | - |
| Flush Init | flush_init | 5 | 4 | 4 | 0 | 0* | R135 | 10s |
| Post-Prod Flush | post_prod_flush | 5 | 7 | 4 | 0 | 0* | R139 | 60s |
Note: During flush, mode indicators may reset to idle signature (R1038=4, R1039=0, R1040=0)
Single Pass Sea Water Mode
| Step | Abbreviation | R1036 | R1037 | R1038 | R1039 | R1040 | Active Timer | Duration |
|---|---|---|---|---|---|---|---|---|
| Valve Positioning | sp_valve | 0 | 0 | 4 | 0 | 0 | R137 | ~5s |
| Priming | sp_prime | 1 | 1 | 4 | 0 | 0 | R128 | 180s |
| Initializing | sp_init | 2 | 2 | 4 | 0 | 0 | R129 | 60s |
| Running | sp_run | 3 | 2 | 2 | 0 | 0 | None | Continuous |
| Stopping | sp_stop | 4 | - | 4 | 0 | 0 | - | - |
| Flush Init | flush_init | 5 | 4 | 4 | 0 | 0 | R135 | 10s |
| Post-Prod Flush | post_prod_flush | 5 | 7 | 4 | 0 | 0 | R139 | 60s |
Double Pass Sea Water Mode
| Step | Abbreviation | R1036 | R1037 | R1038 | R1039 | R1040 | Active Timer | Duration |
|---|---|---|---|---|---|---|---|---|
| Valve Positioning | dp_valve | 0 | 0 | 4 | 1 | 0 | R137 | ~5s |
| Priming | dp_prime | 1 | 1 | 4 | 1 | 0 | R128 | 180s |
| Initializing | dp_init | 2 | 2 | 4 | 2 | 0 | R129 | 60s |
| PPM Stabilizing | dp_stab | 2 | 2 | 4 | 1 | 0 | R131 | 60s |
| Running | dp_run | 3 | 2 | 4 | 1 | 0 | None | Continuous |
| Stopping | dp_stop | 4 | - | 4 | 1 | 0 | - | - |
| Flush Init | flush_init | 5 | 4 | 4 | 0 | 0 | R135 | 10s |
| Post-Prod Flush | post_prod_flush | 5 | 7 | 4 | 0 | 0 | R139 | 60s |
Note: Double Pass has an additional PPM Stabilization phase (R131) between Initialize and Run. R1036 stays at 2 during both init phases - use R129 vs R131 timer activity to distinguish.
Manual Fresh Water Flush (FWF)
| Step | Abbreviation | R1036 | R1037 | R1038 | R1039 | R1040 | Active Timer | Duration |
|---|---|---|---|---|---|---|---|---|
| Flush Init | flush_init | 5 | 4 | 4 | 0 | 0 | R135 | 10s |
| Manual Flushing | manual_fwf | 5 | 7 | 4 | 0 | 0 | R136 | 60s |
Idle State
| Step | Abbreviation | R1036 | R1037 | R1038 | R1039 | R1040 | Active Timer |
|---|---|---|---|---|---|---|---|
| Idle | idle | 0 | 0 | 4 | 0 | 0 | None |
E.4 Timer Register Summary
| Register | Timer Name | Used During | Duration | Purpose |
|---|---|---|---|---|
| R137 | sw_valve | SP/DP startup | ~5s | Sea water valve positioning |
| R138 | dts_valve | DTS startup | 15s | DTS valve positioning |
| R128 | priming | All modes (step 1) | 180s | Low pressure system prime |
| R129 | initialize | All modes (step 2) | 60s | High pressure stabilization |
| R131 | ppm_stab | Double Pass only | 60s | PPM quality stabilization |
| R135 | stop/flush_init | Flush entry | 10s | Pre-flush setup |
| R136 | flush | Manual FWF | 60s | Manual fresh water flush |
| R139 | fwf | Post-production | 60s | Post-production flush |
Timer Values: Raw register value ÷ 10 = seconds. Example: 1800 raw = 180.0 seconds.
E.5 Phase Prediction Logic
When a command is issued (start/skip/stop), the API predicts the next state immediately:
Start Command Predictions
| Mode | Predicted Initial State | Timer | Duration |
|---|---|---|---|
| DTS | Valve Positioning (R1036=0) | R138 | 15s |
| Single Pass | Valve Positioning (R1036=0) | R137 | 5s |
| Double Pass | Valve Positioning (R1036=0) | R137 | 5s |
| FW Flush | Flush Init (R1036=5, R1037=4) | R135 | 10s |
Timer Expiry Predictions
| Current Phase | Timer Expiring | Next Phase | Next Timer |
|---|---|---|---|
| Valve Positioning | R137/R138 | Priming (R1036=1) | R128 |
| Priming | R128 | Initializing (R1036=2) | R129 |
| Initializing (SP/DTS) | R129 | Running (R1036=3) | None |
| Initializing (DP) | R129 | PPM Stabilizing (R1036=2) | R131 |
| PPM Stabilizing | R131 | Running (R1036=3) | None |
| Flush Init | R135 | Flushing (R1036=5, R1037=7) | R136/R139 |
| Flushing | R136/R139 | Idle (R1036=0) | None |
Skip Command Predictions
| From Step | To Step | Timer Started |
|---|---|---|
| Priming (R1036=1) | Initializing (R1036=2) | R129 (60s) |
| Initializing (R1036=2, DTS/SP) | Running (R1036=3) | None |
| Initializing (R1036=2, DP) | PPM Stabilizing (R1036=2) | R131 (60s) |
Stop Command Predictions
| From Step | Predicted Next State | Timer |
|---|---|---|
| Priming (R1036=1) | Idle (R1036=0) | None |
| Initializing (R1036=2) | Idle (R1036=0) | None |
| Running (R1036=3) | Flush Init (R1036=5, R1037=4) | R135 (10s) |
| Flushing (R1036=5) | Idle (R1036=0) | None |
E.6 State Verification Flow
1. API receives command (start/skip/stop)
2. API generates predicted_state based on tables above
3. API sends command to PLC and returns predicted_state immediately
4. Background task polls R1036-R1040 within 2 seconds
5. IF actual state matches prediction:
- Emit "state_verified" WebSocket event
6. ELSE:
- Emit "state_correction" WebSocket event with actual state
7. During timer phases:
- Track active timer register
- When timer approaches 0, increase polling frequency
- Predict next phase when timer expires
- Verify against R1036-R1040 changes
Appendix F: Consumables Calculation Logic
This appendix documents how consumable usage is calculated for each component type.
F.1 Consumable Definitions
| Consumable ID | Name | Unit | Default Limit | Description |
|---|---|---|---|---|
primary_membrane |
Primary Sea Water Membrane | Gallons | 100,000 | RO membrane processing seawater |
secondary_membrane |
Secondary Fresh Water Membrane | Gallons | 100,000 | RO membrane for double-pass/DTS |
five_micron_filter |
5 Micron Primary Filter | Gallons | 10,000 | Pre-filter for sediment removal |
small_carbon_filter |
Small Activated Carbon Filter | Gallons | 5,000 | Carbon filter for flush water |
large_carbon_filter |
Large Activated Carbon Filter | Gallons | 20,000 | Carbon filter for shore/DTS water |
hp_pump_oil |
High Pressure Pump Oil | Hours | 500 | HP pump lubrication oil |
sea_strainer |
Low Pressure Inlet Pump Strainer | Gallons | 50,000 | Inlet strainer basket |
F.2 Mode-to-Consumable Mapping
Single Pass Mode
| Consumable | Usage Type | Explanation |
|---|---|---|
primary_membrane |
Product | Seawater membrane produces all product water |
five_micron_filter |
Total | Pre-filter processes all incoming water (product + brine) |
sea_strainer |
Total | Inlet strainer sees all incoming seawater |
hp_pump_oil |
Hours | HP pump runtime during production |
Double Pass Mode
| Consumable | Usage Type | Explanation |
|---|---|---|
primary_membrane |
Product | First-pass seawater processing |
secondary_membrane |
Product | Second-pass freshwater polishing |
five_micron_filter |
Total | Pre-filter processes all incoming water |
sea_strainer |
Total | Inlet strainer sees all incoming seawater |
hp_pump_oil |
Hours | HP pump runtime during production |
DTS (Dockside Treatment) Mode
| Consumable | Usage Type | Explanation |
|---|---|---|
secondary_membrane |
Product | Only freshwater membrane used with shore water |
five_micron_filter |
Total | Pre-filter processes shore water input |
large_carbon_filter |
Total | Carbon filter treats shore water feed |
hp_pump_oil |
Hours | HP pump runtime during production |
Fresh Water Flush Mode
| Consumable | Usage Type | Explanation |
|---|---|---|
small_carbon_filter |
Flush | Carbon filter treats flush water from tank |
DTS Flush Mode
| Consumable | Usage Type | Explanation |
|---|---|---|
five_micron_filter |
Flush | Pre-filter used during DTS flush |
large_carbon_filter |
Flush | Carbon filter used during DTS flush |
F.3 Usage Tracking Types
| Usage Type | Description | Calculation |
|---|---|---|
| Product | Product water only | Gallons output from membrane (potable water) |
| Total | Total water processed | Product gallons + Brine gallons |
| Flush | Flush water only | Gallons used during flush operations |
| Hours | Runtime hours | Accumulated HP pump operating time |
F.4 Brine Flow Integration Algorithm
Since the PLC only provides real-time brine flow rate (R1120) without a cumulative counter, the system integrates the flow rate over time using a BrineFlowIntegrator with multi-stage filtering:
Filtering Pipeline
- Zero Threshold Filter: Flow < 0.5 GPM treated as sensor noise
- Median Filter: 5-sample window removes transient spikes
- Exponential Moving Average: Smooths noise (α=0.3)
- Spike Detection: Readings > 3 standard deviations rejected
Integration Formula
gallons_increment = smoothed_flow_gpm × (time_delta_seconds / 60)
cumulative_gallons += gallons_increment
Configuration Parameters
| Parameter | Default | Description |
|---|---|---|
ema_alpha |
0.3 | EMA smoothing factor (0-1) |
spike_threshold |
3.0 | Standard deviations for spike rejection |
zero_threshold_gpm |
0.5 | Flow below this treated as zero |
median_window_size |
5 | Number of samples for median filter |
F.5 Update Frequency & Conditions
- Consumables are updated every monitoring cycle (default: 5 seconds)
- Updates only occur during active operation - when the system is idle (R1036 = 0), consumables freeze
Update Conditions by Production Step
| R1036 Value | Step | Consumables Updated? |
|---|---|---|
| 0 | Idle | No - consumables freeze |
| 1 | Priming | Yes |
| 2 | Initializing | Yes |
| 3 | Running | Yes |
| 5 | Flushing | Yes |
Status Thresholds
| Percent Consumed | Status | UI Indicator |
|---|---|---|
| 0% - 79% | OK | Green badge |
| 80% - 99% | Soon | Yellow badge |
| ≥ 100% | Replace | Red badge |
Appendix G: Quick Reference Command Summary
Essential API Commands
# System Status
curl http://localhost:5000/api/status
# Start Operations
curl -X POST "http://localhost:5000/api/start?mode=dts"
curl -X POST "http://localhost:5000/api/start?mode=single_pass"
curl -X POST "http://localhost:5000/api/start?mode=double_pass"
curl -X POST "http://localhost:5000/api/start?mode=fw_flush"
# Control Operations
curl -X POST http://localhost:5000/api/stop
curl -X POST http://localhost:5000/api/skip
# Monitoring
curl http://localhost:5000/api/sensors
curl http://localhost:5000/api/timers
curl "http://localhost:5000/api/select?groups=production_timer,pressure"
# Consumables
curl http://localhost:5000/api/consumables
curl http://localhost:5000/api/consumables/summary
curl -X POST http://localhost:5000/api/consumables/five_micron_filter/reset
# Direct Register Access
curl -X POST http://localhost:5000/api/write/register \
-H "Content-Type: application/json" \
-d '{"register": 1000, "value": 7}'
Essential Register Operations (Direct Modbus)
# Read system mode
modbus_client.read_holding_registers(1000, 1)
# Read system status
modbus_client.read_holding_registers(1036, 1)
# Start DTS sequence
modbus_client.write_register(1000, 34) # DTS Request
modbus_client.write_register(71, 256) # Start DTS
modbus_client.write_register(71, 0) # Clear control
modbus_client.write_register(1000, 5) # Begin priming
# Stop sequence (mode-dependent)
modbus_client.write_register(71, 512) # Mode 5 stop
modbus_client.write_register(71, 0) # Clear control
modbus_client.write_register(1000, 8) # Fresh water flush
Appendix H: Process Flow Diagrams
DTS Operation Flow
┌─────────────────────────────────────────────────────────────────┐
│ DTS OPERATION FLOW │
├─────────────────────────────────────────────────────────────────┤
│ │
│ API: POST /api/start?mode=dts │
│ ┌─────────────────┐ │
│ │ DTS Request │ R1000 = 34, R138 Timer (15s) │
│ │ (Screen 34) │ API: "valve_positioning" │
│ └─────────┬───────┘ │
│ │ Auto Advance (R138 → 0) │
│ ▼ │
│ ┌─────────────────┐ │
│ │ DTS Priming │ R1000 = 5, R1036 = 1 │
│ │ (Screen 5) │ R128 Timer (180s) │
│ │ Shore Pressure │ API: "priming" │
│ │ Flush │ │
│ └─────────┬───────┘ │
│ │ Auto Advance (R128 → 0) │
│ ▼ │
│ ┌─────────────────┐ │
│ │ DTS Initialize │ R1000 = 6, R1036 = 2 │
│ │ (Screen 6) │ R129 Timer (60s) │
│ │ High Pressure │ API: "initializing" │
│ │ Pump On, Divert │ │
│ └─────────┬───────┘ │
│ │ Auto Advance (R129 → 0) │
│ ▼ │
│ ┌─────────────────┐ │
│ │ DTS Production │ R1000 = 7, R1036 = 3 │
│ │ (Screen 7) │ No Timer (Continuous) │
│ │ Water to Tank │ API: "running" │
│ └─────────┬───────┘ │
│ │ API: POST /api/stop │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Fresh Water │ R1000 = 8, R1036 = 5 │
│ │ Flush │ R135 (10s) → R139 (60s) │
│ │ (Screen 8) │ API: "flushing" │
│ └─────────┬───────┘ │
│ │ Auto Complete (R139 → 0) │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Standby │ R1000 = 2, R1036 = 0 │
│ │ (Complete) │ API: "idle" │
│ └─────────────────┘ │
│ │
│ Skip Operations Available: │
│ • From Priming: POST /api/skip → R67=32841 │
│ • From Initialize: POST /api/skip → R67=32968 │
│ │
└─────────────────────────────────────────────────────────────────┘
Single Pass Operation Flow
┌─────────────────────────────────────────────────────────────────┐
│ SINGLE PASS OPERATION FLOW │
├─────────────────────────────────────────────────────────────────┤
│ │
│ API: POST /api/start?mode=single_pass │
│ ┌─────────────────┐ │
│ │ Valve Position │ R1000 = 33, R137 Timer (5s) │
│ │ (Screen 33) │ API: "valve_positioning" │
│ └─────────┬───────┘ │
│ │ Auto Advance (R137 → 0) │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Priming │ R1036 = 1, R128 Timer (180s) │
│ │ (Screen 5) │ LPP On, Prime System │
│ │ │ API: "priming" │
│ └─────────┬───────┘ │
│ │ Auto Advance (R128 → 0) │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Initializing │ R1036 = 2, R129 Timer (60s) │
│ │ (Screen 6) │ HPP On, Stabilize Pressure │
│ │ │ API: "initializing" │
│ └─────────┬───────┘ │
│ │ Auto Advance (R129 → 0) │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Running │ R1036 = 3, No Timer │
│ │ (Screen 7) │ Water Production Active │
│ │ │ API: "running" │
│ └─────────┬───────┘ │
│ │ POST /api/stop │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Flushing │ R1036 = 5 │
│ │ (Screen 8) │ R135 (10s) → R139 (60s) │
│ │ │ API: "flushing" │
│ └─────────┬───────┘ │
│ │ Auto Complete │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Idle │ R1036 = 0 │
│ │ (Complete) │ API: "idle" │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Double Pass Operation Flow
┌─────────────────────────────────────────────────────────────────┐
│ DOUBLE PASS OPERATION FLOW │
├─────────────────────────────────────────────────────────────────┤
│ │
│ API: POST /api/start?mode=double_pass │
│ ┌─────────────────┐ │
│ │ Valve Position │ R1000 = 33, R137 Timer (5s) │
│ │ (Screen 33) │ API: "valve_positioning" │
│ └─────────┬───────┘ │
│ │ Auto Advance (R137 → 0) │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Priming │ R1036 = 1, R128 Timer (180s) │
│ │ (Screen 5) │ LPP On, Prime Both Membranes │
│ └─────────┬───────┘ │
│ │ Auto Advance (R128 → 0) │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Initialize Ph 1 │ R1036 = 2, R129 Timer (60s) │
│ │ (Screen 6) │ First membrane stabilization │
│ └─────────┬───────┘ │
│ │ Auto Advance (R129 → 0) │
│ ▼ │
│ ┌─────────────────┐ │
│ │ PPM Stabilizing │ R1036 = 2, R131 Timer (60s) │
│ │ (Init Phase 2) │ Second membrane stabilization │
│ └─────────┬───────┘ │
│ │ Auto Advance (R131 → 0) │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Running │ R1036 = 3, No Timer │
│ │ (Screen 7) │ Dual Membrane Production │
│ └─────────┬───────┘ │
│ │ POST /api/stop │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Flushing │ R1036 = 5 │
│ │ (Screen 8) │ R135 (10s) → R139 (60s) │
│ └─────────┬───────┘ │
│ │ Auto Complete │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Idle │ R1036 = 0 │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
License
MIT License - see LICENSE file for details.
Document End
This comprehensive reference provides complete coverage of both PLC register specifications and RESTful API implementation for the watermaker system. For additional technical support, system integration assistance, or clarification on register operations and API usage, consult the development team or contact technical support.
Document Statistics:
- Version: 3.0 (Reorganized Structure)
- Total Sections: 7 major sections + 8 appendices
- Register Coverage: 35+ individual registers and register pairs
- API Endpoints: 20+ RESTful endpoints (including consumables tracking)
- Operation Modes: 4 primary modes (DTS, Single-Pass, Double-Pass, Fresh Water Flush)
- Reference Tables: 8 comprehensive appendices
- Consumables Tracked: 7 replaceable components with usage calculation
- Predictive State: Command responses include predicted state for instant UI updates
- WebSocket Events: 4 verification events
- Timer Values: PLC-verified (R137=5s, R138=15s)