Install
openclaw skills install co2-tank-monitorIoT monitoring simulation to predict CO2 tank depletion and prevent weekend gas outages in cell culture facilities. Monitors cylinder pressure, calculates co...
openclaw skills install co2-tank-monitorMonitor CO2 cylinder pressure and predict depletion times to prevent gas outages in cell culture incubators, particularly during weekends when laboratories are unmanned. Provides automated alerts and consumption tracking for proactive cylinder management.
Key Capabilities:
✅ Use this skill when:
❌ Do NOT use when:
freezer-sample-locator or specialized LN2 monitorsRelated Skills:
equipment-maintenance-log, lab-inventory-trackereln-template-creator, lab-budget-forecasterUpstream Skills:
equipment-maintenance-log: Track CO2 incubator maintenance history that affects consumption rateslab-inventory-tracker: Monitor cylinder inventory and replacement schedulesequipment-maintenance-log: Record calibration dates for pressure gaugesDownstream Skills:
eln-template-creator: Generate experiment templates that include gas monitoring checklistslab-budget-forecaster: Forecast CO2 gas costs based on consumption trendswaste-disposal-guide: Coordinate empty cylinder disposal with replacementComplete Workflow:
Daily Morning Check → co2-tank-monitor → equipment-maintenance-log → lab-inventory-tracker → Replacement Scheduling
Calculate remaining cylinder lifetime based on current pressure readings and historical consumption patterns.
from scripts.main import calculate_remaining_days, calculate_depletion_time
from datetime import datetime
# Current cylinder status
current_pressure = 8.0 # MPa
daily_consumption = 1.5 # MPa/day
# Calculate remaining time
remaining_days = calculate_remaining_days(current_pressure, daily_consumption)
print(f"Remaining days: {remaining_days:.1f}")
# Calculate depletion datetime
depletion_time = calculate_depletion_time(remaining_days)
print(f"Estimated depletion: {depletion_time.strftime('%Y-%m-%d %H:%M')}")
# Formula: remaining_days = pressure / daily_consumption
Parameters:
| Parameter | Type | Required | Description | Default |
|---|---|---|---|---|
pressure | float | Yes | Current cylinder pressure in MPa | 8.0 |
daily_consumption | float | Yes | Average daily consumption rate (MPa/day) | 1.5 |
capacity | int | No | Cylinder capacity in liters (10 or 40) | 40 |
Calculation Method:
remaining_days = current_pressure / daily_consumption
Best Practices:
Common Issues and Solutions:
Issue: Inaccurate consumption estimates
Issue: Pressure fluctuations causing false alerts
Identify if cylinder depletion will occur during weekends when laboratory staff is unavailable.
from scripts.main import is_weekend, will_deplete_on_weekend, calculate_depletion_time
from datetime import datetime
# Calculate depletion time
remaining_days = 3.5
depletion_time = calculate_depletion_time(remaining_days)
# Check if depletion is on weekend
if is_weekend(depletion_time):
print(f"⚠️ Warning: Depletion on {depletion_time.strftime('%A')}")
else:
print(f"✅ Depletion on weekday: {depletion_time.strftime('%A')}")
# Check weekend risk with alert threshold
alert_days = 2
weekend_risk = will_deplete_on_weekend(depletion_time, alert_days)
if weekend_risk:
print("🔴 CRITICAL: Cylinder will deplete during weekend!")
print(" Action: Replace before Friday or arrange weekend duty")
Weekend Risk Scenarios:
| Scenario | Risk Level | Action Required |
|---|---|---|
| Depletion on Saturday/Sunday | 🔴 High | Immediate replacement or weekend duty |
| Depletion Monday morning | 🟡 Medium | Replace Friday afternoon |
| Depletion Friday evening | 🟡 Medium | Monitor closely; replace if possible |
| Depletion mid-week | 🟢 Low | Schedule routine replacement |
Best Practices:
Common Issues and Solutions:
Issue: False weekend alerts for Monday depletion
Issue: Missing Friday evening depletion risk
Support different CO2 cylinder specifications commonly used in laboratory settings.
from scripts.main import simulate_sensor_data
# Cylinder specifications
CYLINDER_SPECS = {
10: {
"name": "Portable (10L)",
"full_pressure": 15.0, # MPa
"typical_usage": "Small incubators, backup",
"duration_1_5_mpa": "~10 days"
},
40: {
"name": "Standard (40L)",
"full_pressure": 15.0, # MPa
"typical_usage": "Main incubators, high usage",
"duration_1_5_mpa": "~40 days"
}
}
# Select appropriate cylinder
capacity = 40 # Liters
specs = CYLINDER_SPECS[capacity]
print(f"Cylinder: {specs['name']}")
print(f"Full pressure: {specs['full_pressure']} MPa")
print(f"Typical usage: {specs['typical_usage']}")
# Calculate capacity-based estimates
full_pressure = 15.0 # MPa (typical full cylinder)
daily_consumption = 1.5 # MPa/day
max_days = full_pressure / daily_consumption
print(f"Maximum duration at {daily_consumption} MPa/day: {max_days:.1f} days")
Cylinder Specifications:
| Capacity | Typical Use | Full Pressure | Duration (@1.5 MPa/day) |
|---|---|---|---|
| 10L | Small incubators, backup | ~15 MPa | ~10 days |
| 40L | Main incubators, heavy use | ~15 MPa | ~40 days |
Best Practices:
Common Issues and Solutions:
Issue: Wrong capacity setting causing prediction errors
Issue: Mixing cylinder sizes in same calculation
Generate color-coded status reports with specific recommendations based on urgency.
from scripts.main import get_status, calculate_remaining_days, calculate_depletion_time
# Example scenarios
scenarios = [
{"pressure": 12.0, "consumption": 1.5, "days": 2}, # Normal
{"pressure": 5.0, "consumption": 1.5, "days": 2}, # Caution
{"pressure": 2.5, "consumption": 1.5, "days": 2}, # Danger
]
for scenario in scenarios:
remaining = calculate_remaining_days(
scenario["pressure"],
scenario["consumption"]
)
depletion = calculate_depletion_time(remaining)
status_code, icon, status_text, recommendations = get_status(
remaining, scenario["days"], depletion
)
print(f"\nPressure: {scenario['pressure']} MPa")
print(f"Status: {icon} {status_text} (Code: {status_code})")
print("Recommendations:")
for rec in recommendations:
print(f" {rec}")
Status Levels:
| Code | Icon | Status | Condition | Action |
|---|---|---|---|---|
| 0 | 🟢 | Normal | Days > alert_days + 2 | No action needed |
| 1 | 🟡 | Caution | Days within alert_days + 2 | Monitor closely |
| 2 | 🔴 | Danger | Days ≤ alert_days or weekend depletion | Replace immediately |
Return Codes for Automation:
| Exit Code | Meaning | Automation Action |
|---|---|---|
| 0 | Normal | Continue routine monitoring |
| 1 | Caution | Send email notification |
| 2 | Danger | Send urgent alert; page on-call staff |
Best Practices:
Common Issues and Solutions:
Issue: Alert fatigue from frequent caution alerts
Issue: Missing critical weekend alerts
Generate randomized cylinder data for training staff without affecting real monitoring systems.
from scripts.main import simulate_sensor_data, calculate_remaining_days
# Generate 5 random scenarios for training
print("Training Scenarios (Simulated Data):\n")
for i in range(5):
pressure, capacity, consumption = simulate_sensor_data()
remaining = calculate_remaining_days(pressure, consumption)
print(f"Scenario {i+1}:")
print(f" Pressure: {pressure:.2f} MPa")
print(f" Capacity: {capacity} L")
print(f" Daily consumption: {consumption:.2f} MPa/day")
print(f" Estimated remaining: {remaining:.1f} days")
# Training question
if remaining < 3:
print(f" 🚨 ACTION: Replace immediately!")
elif remaining < 7:
print(f" ⚠️ ACTION: Schedule replacement this week")
else:
print(f" ✅ STATUS: Monitor normally")
print()
# Command line usage for simulation mode:
# python scripts/main.py --simulate
Training Applications:
| Use Case | Simulation Parameters | Learning Objective |
|---|---|---|
| New staff training | Various random scenarios | Recognize different alert levels |
| Weekend risk awareness | Force weekend depletion scenarios | Understand critical timing |
| Consumption calculation | Different pressure/consumption combos | Practice manual calculations |
| Emergency response | Low pressure scenarios (<3 MPa) | Learn urgent procedures |
Best Practices:
Common Issues and Solutions:
Issue: Simulation data too random for consistent training
Issue: Confusion between simulation and real data
Integrate with cron jobs or task schedulers for automated daily monitoring.
# Example cron setup (documented in comments)
"""
Cron job configuration for daily monitoring:
# Daily check at 9:00 AM
0 9 * * * cd /lab/scripts && python co2_tank_monitor.py --pressure $(cat /sensor/pressure.log | tail -1) --quiet
# Check before weekends (Friday at 5 PM)
0 17 * * 5 cd /lab/scripts && python co2_tank_monitor.py --pressure $(cat /sensor/pressure.log | tail -1)
# Log results
0 9 * * * cd /lab/scripts && python co2_tank_monitor.py >> /var/log/co2_monitor.log 2>&1
"""
# Integration with sensor reading
def read_sensor_data(sensor_log_path: str) -> float:
"""Read current pressure from sensor log file."""
try:
with open(sensor_log_path, 'r') as f:
lines = f.readlines()
# Get last line and extract pressure value
last_line = lines[-1].strip()
pressure = float(last_line.split()[0]) # Assumes format: "8.5 MPa"
return pressure
except Exception as e:
print(f"Error reading sensor: {e}")
return None
# Usage in automated script
sensor_pressure = read_sensor_data("/path/to/pressure_sensor.log")
if sensor_pressure:
# Run monitoring with actual sensor data
import subprocess
result = subprocess.run([
"python", "scripts/main.py",
"--pressure", str(sensor_pressure),
"--quiet"
], capture_output=True)
# Handle return code
if result.returncode == 2:
send_urgent_alert("CO2 cylinder requires immediate replacement!")
elif result.returncode == 1:
send_notification("CO2 cylinder needs attention soon")
Integration Patterns:
| Integration Type | Trigger | Action | Return Code Handling |
|---|---|---|---|
| Daily cron | 9:00 AM daily | Check status | Log results; alert if ≠0 |
| Pre-weekend | Friday 5 PM | Weekend risk check | Force alert if weekend risk |
| Real-time | Sensor threshold | Immediate check | Page on-call if danger |
| Manual | Lab staff | Ad-hoc check | Display full report |
Best Practices:
Common Issues and Solutions:
Issue: Cron job not executing
Issue: Sensor data unavailable
From daily monitoring to replacement scheduling:
# Step 1: Manual morning check with full report
python scripts/main.py --pressure 8.5 --daily-consumption 1.2
# Step 2: Automated daily check (in cron)
0 9 * * * python scripts/main.py --pressure $(cat sensor.log | tail -1) --quiet
# Step 3: Pre-weekend check
python scripts/main.py --pressure 5.5 --alert-days 3
# Step 4: Simulation for training
python scripts/main.py --simulate
Python API Usage:
from scripts.main import (
calculate_remaining_days,
calculate_depletion_time,
will_deplete_on_weekend,
get_status
)
from datetime import datetime
def monitor_co2_cylinder(
pressure: float,
daily_consumption: float,
capacity: int = 40,
alert_days: int = 2
) -> dict:
"""
Complete CO2 cylinder monitoring workflow.
Returns:
Dictionary with status, predictions, and recommendations
"""
# Calculate predictions
remaining_days = calculate_remaining_days(pressure, daily_consumption)
depletion_time = calculate_depletion_time(remaining_days)
# Assess weekend risk
weekend_risk = will_deplete_on_weekend(depletion_time, alert_days)
# Get status and recommendations
status_code, icon, status_text, recommendations = get_status(
remaining_days, alert_days, depletion_time
)
# Compile report
report = {
"timestamp": datetime.now().isoformat(),
"cylinder": {
"pressure_mpa": pressure,
"capacity_l": capacity,
"daily_consumption_mpa": daily_consumption
},
"prediction": {
"remaining_days": round(remaining_days, 1),
"depletion_time": depletion_time.isoformat(),
"weekend_risk": weekend_risk
},
"status": {
"code": status_code,
"level": status_text,
"icon": icon
},
"recommendations": recommendations,
"action_required": status_code >= 1
}
return report
# Execute monitoring
result = monitor_co2_cylinder(
pressure=6.5,
daily_consumption=1.5,
capacity=40,
alert_days=2
)
# Display formatted report
print(f"CO2 Cylinder Monitor Report")
print(f"{'='*40}")
print(f"Status: {result['status']['icon']} {result['status']['level']}")
print(f"Remaining: {result['prediction']['remaining_days']} days")
print(f"Depletion: {result['prediction']['depletion_time']}")
print(f"Weekend Risk: {'Yes' if result['prediction']['weekend_risk'] else 'No'}")
print(f"\nRecommendations:")
for rec in result['recommendations']:
print(f" {rec}")
Expected Output Files:
monitoring_logs/
├── co2_daily_checks.log # Daily monitoring results
├── co2_weekend_alerts.log # Weekend-specific alerts
└── co2_replacement_history.json # Cylinder change tracking
Scenario: Lab technician checks all CO2 cylinders every morning at 9 AM.
{
"monitoring_type": "daily_routine",
"schedule": "9:00 AM daily",
"cylinders": [
{"location": "Incubator A", "capacity": 40, "typical_consumption": 1.5},
{"location": "Incubator B", "capacity": 40, "typical_consumption": 1.2},
{"location": "Backup", "capacity": 10, "typical_consumption": 0.3}
],
"alert_threshold": 2,
"actions": {
"normal": "Log and continue",
"caution": "Schedule replacement within 3 days",
"danger": "Replace immediately or arrange weekend coverage"
}
}
Workflow:
Output Example:
Morning CO2 Check - 2026-02-09 09:00
=====================================
Incubator A (40L): 🟢 Normal - 12.5 days remaining
Incubator B (40L): 🟡 Caution - 4.2 days remaining
Backup (10L): 🟢 Normal - 8.1 days remaining
Action Required:
- Schedule Incubator B cylinder replacement for this week
Scenario: Before a 3-day weekend (e.g., Memorial Day), ensure adequate gas supply.
{
"monitoring_type": "pre_holiday",
"holiday": "Memorial Day Weekend",
"lab_closure": "3 days (Sat-Mon)",
"alert_days": 4,
"special_considerations": [
"No staff on-site for 72 hours",
"Critical experiments running",
"Extended alert threshold"
]
}
Workflow:
Output Example:
Pre-Holiday Assessment - Memorial Day Weekend
==============================================
🔴 CRITICAL: Incubator A cylinder will deplete on Sunday
Current pressure: 4.5 MPa
Depletion: Sunday 11:30 PM
⚠️ Lab closure: 3 days with no staff
IMMEDIATE ACTIONS:
1. Replace Incubator A cylinder TODAY (Friday)
2. Verify backup incubator is operational
3. Contact gas supplier for emergency weekend number
4. Transfer critical samples to Incubator B if concerned
Scenario: Train new technician on CO2 monitoring using simulation mode.
{
"training_type": "new_staff_onboarding",
"mode": "simulation",
"scenarios": [
{"name": "Normal operation", "pressure_range": [10, 15]},
{"name": "Approaching replacement", "pressure_range": [4, 6]},
{"name": "Critical weekend risk", "pressure_range": [2, 4]},
{"name": "Emergency low pressure", "pressure_range": [0.5, 2]}
],
"learning_objectives": [
"Recognize different alert levels",
"Calculate remaining days manually",
"Understand weekend risk",
"Learn replacement procedures"
]
}
Workflow:
Output Example:
Training Session - CO2 Monitoring
==================================
Scenario 1/5: Normal Operation
Simulated pressure: 12.3 MPa
Daily consumption: 1.4 MPa/day
Trainee calculation: 8.8 days remaining
Script result: 8.8 days remaining ✅
Discussion: What actions needed?
✓ Correct: Continue routine monitoring
Scenario 2/5: Weekend Risk
Simulated pressure: 3.8 MPa
Daily consumption: 1.5 MPa/day
Depletion: Sunday 2 PM
Status: 🔴 Danger
Discussion: What if this were Friday morning?
✓ Correct: Immediate replacement required
Scenario: Large facility with 6 incubators on different CO2 cylinders.
{
"facility_type": "multi_incubator",
"total_incubators": 6,
"cylinder_configuration": {
"main_incubators": {"count": 4, "capacity": 40, "consumption": "1.5-2.0 MPa/day"},
"backup_incubators": {"count": 2, "capacity": 10, "consumption": "0.3-0.5 MPa/day"}
},
"monitoring_strategy": "centralized_dashboard",
"rotation_schedule": "staggered_replacement"
}
Workflow:
Output Example:
Facility CO2 Dashboard - 2026-02-09
====================================
Main Incubators (40L):
Inc-01: 🟢 18.2 days | Last replaced: 2026-01-22
Inc-02: 🟡 4.5 days | REPLACE THIS WEEK
Inc-03: 🟢 22.1 days | Last replaced: 2026-01-15
Inc-04: 🟢 15.8 days | Last replaced: 2026-01-28
Backup Incubators (10L):
Back-01: 🟢 6.2 days
Back-02: 🟢 8.4 days
This Week Actions:
- Replace Inc-02 cylinder by Wednesday
- Order replacement for delivery next week
Monthly Consumption: 42 MPa (28% under budget)
Pre-Monitoring Setup:
During Daily Monitoring:
Alert Response:
Post-Replacement Verification:
Monitoring Setup Issues:
❌ Inconsistent reading times → Daily variations affect trend accuracy
❌ Wrong consumption estimates → Inaccurate depletion predictions
❌ Ignoring temperature effects → Pressure varies with ambient temperature
❌ Not accounting for usage variations → Weekend vs weekday consumption differs
Alert and Response Issues:
❌ Alert fatigue → Too many notifications cause important alerts to be missed
❌ Missing weekend alerts → Friday check doesn't catch Saturday depletion
❌ Delayed replacement → Waiting too long leads to actual depletion
❌ No backup plan → Cylinder fails with no replacement available
Calculation and Data Issues:
❌ Wrong cylinder capacity → 10L vs 40L confusion causes 4x error
❌ Pressure unit confusion → PSI vs MPa or Bar mixing
❌ Not tracking multiple cylinders → Mixing readings from different tanks
❌ Ignoring cumulative error → Small daily errors compound over weeks
Operational Issues:
❌ Gauges not calibrated → Inaccurate readings lead to wrong predictions
❌ Leaks undetected → Higher consumption than predicted
❌ Regulator problems → Pressure drops even with adequate gas
❌ No documentation → Cannot track trends or troubleshoot issues
Problem: Predicted depletion date consistently wrong
Problem: Frequent false alerts (alert fatigue)
Problem: Weekend depletion not detected
Problem: Cannot read pressure gauge accurately
Problem: Cylinder depletes faster than expected
Problem: Monitoring script not running automatically
grep CRON /var/log/syslogAvailable in references/ directory:
External Resources:
Located in scripts/ directory:
main.py - CO2 tank monitoring engine with prediction and alerting logic| Unit | MPa | PSI | Bar |
|---|---|---|---|
| MPa | 1.0 | 145.0 | 10.0 |
| PSI | 0.0069 | 1.0 | 0.069 |
| Bar | 0.1 | 14.5 | 1.0 |
Typical Cylinder Pressures:
Last Updated: 2026-02-09
Skill ID: 182
Version: 2.0 (K-Dense Standard)