feat: Implement configurable pump control preprocessing logic #5

Merged
solipsism merged 34 commits from feature/pump-control-preprocessing into master 2025-11-17 14:23:42 +00:00
4 changed files with 395 additions and 0 deletions
Showing only changes of commit afeac4bf84 - Show all commits

View File

@ -0,0 +1,156 @@
#!/usr/bin/env python3
"""
Script to initialize and persist sample tag metadata
"""
import sys
import os
import json
# Add the src directory to the Python path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'src'))
from src.core.tag_metadata_manager import tag_metadata_manager
def create_and_save_sample_metadata():
"""Create sample tag metadata and save to file"""
print("Initializing Sample Tag Metadata...")
print("=" * 60)
# Create sample stations
print("\n🏭 Creating Stations...")
station1_id = tag_metadata_manager.add_station(
name="Main Pump Station",
tags=["primary", "control", "monitoring", "water_system"],
description="Primary water pumping station for the facility",
station_id="station_main"
)
print(f" ✓ Created station: {station1_id}")
station2_id = tag_metadata_manager.add_station(
name="Backup Pump Station",
tags=["backup", "emergency", "monitoring", "water_system"],
description="Emergency backup pumping station",
station_id="station_backup"
)
print(f" ✓ Created station: {station2_id}")
# Create sample equipment
print("\n🔧 Creating Equipment...")
equipment1_id = tag_metadata_manager.add_equipment(
name="Primary Pump",
station_id="station_main",
tags=["pump", "primary", "control", "automation"],
description="Main water pump with variable speed drive",
equipment_id="pump_primary"
)
print(f" ✓ Created equipment: {equipment1_id}")
equipment2_id = tag_metadata_manager.add_equipment(
name="Backup Pump",
station_id="station_backup",
tags=["pump", "backup", "emergency", "automation"],
description="Emergency backup water pump",
equipment_id="pump_backup"
)
print(f" ✓ Created equipment: {equipment2_id}")
equipment3_id = tag_metadata_manager.add_equipment(
name="Pressure Sensor",
station_id="station_main",
tags=["sensor", "measurement", "monitoring", "safety"],
description="Water pressure monitoring sensor",
equipment_id="sensor_pressure"
)
print(f" ✓ Created equipment: {equipment3_id}")
equipment4_id = tag_metadata_manager.add_equipment(
name="Flow Meter",
station_id="station_main",
tags=["sensor", "measurement", "monitoring", "industrial"],
description="Water flow rate measurement device",
equipment_id="sensor_flow"
)
print(f" ✓ Created equipment: {equipment4_id}")
# Create sample data types
print("\n📈 Creating Data Types...")
data_type1_id = tag_metadata_manager.add_data_type(
name="Pump Speed",
tags=["setpoint", "control", "measurement", "automation"],
description="Pump motor speed control and feedback",
units="RPM",
min_value=0,
max_value=3000,
default_value=1500,
data_type_id="speed_pump"
)
print(f" ✓ Created data type: {data_type1_id}")
data_type2_id = tag_metadata_manager.add_data_type(
name="Water Pressure",
tags=["measurement", "monitoring", "alarm", "safety"],
description="Water pressure measurement",
units="PSI",
min_value=0,
max_value=100,
default_value=50,
data_type_id="pressure_water"
)
print(f" ✓ Created data type: {data_type2_id}")
data_type3_id = tag_metadata_manager.add_data_type(
name="Pump Status",
tags=["status", "monitoring", "alarm", "diagnostic"],
description="Pump operational status",
data_type_id="status_pump"
)
print(f" ✓ Created data type: {data_type3_id}")
data_type4_id = tag_metadata_manager.add_data_type(
name="Flow Rate",
tags=["measurement", "monitoring", "optimization"],
description="Water flow rate measurement",
units="GPM",
min_value=0,
max_value=1000,
default_value=500,
data_type_id="flow_rate"
)
print(f" ✓ Created data type: {data_type4_id}")
# Add some custom tags
print("\n🏷️ Adding Custom Tags...")
custom_tags = ["water_system", "industrial", "automation", "safety", "municipal"]
for tag in custom_tags:
tag_metadata_manager.add_custom_tag(tag)
print(f" ✓ Added custom tag: {tag}")
# Export metadata to file
print("\n💾 Saving metadata to file...")
metadata_file = os.path.join(os.path.dirname(__file__), 'sample_metadata.json')
metadata = tag_metadata_manager.export_metadata()
with open(metadata_file, 'w') as f:
json.dump(metadata, f, indent=2)
print(f" ✓ Metadata saved to: {metadata_file}")
# Show summary
print("\n📋 FINAL SUMMARY:")
print("-" * 40)
print(f" Stations: {len(tag_metadata_manager.stations)}")
print(f" Equipment: {len(tag_metadata_manager.equipment)}")
print(f" Data Types: {len(tag_metadata_manager.data_types)}")
print(f" Total Tags: {len(tag_metadata_manager.all_tags)}")
print("\n✅ Sample metadata initialization completed!")
print("\n📝 Sample metadata includes:")
print(" - 2 Stations: Main Pump Station, Backup Pump Station")
print(" - 4 Equipment: Primary Pump, Backup Pump, Pressure Sensor, Flow Meter")
print(" - 4 Data Types: Pump Speed, Water Pressure, Pump Status, Flow Rate")
print(" - 33 Total Tags including core and custom tags")
if __name__ == "__main__":
create_and_save_sample_metadata()

181
sample_metadata.json Normal file
View File

@ -0,0 +1,181 @@
{
"stations": {
"station_main": {
"id": "station_main",
"name": "Main Pump Station",
"tags": [
"primary",
"control",
"monitoring",
"water_system"
],
"attributes": {},
"description": "Primary water pumping station for the facility"
},
"station_backup": {
"id": "station_backup",
"name": "Backup Pump Station",
"tags": [
"backup",
"emergency",
"monitoring",
"water_system"
],
"attributes": {},
"description": "Emergency backup pumping station"
}
},
"equipment": {
"pump_primary": {
"id": "pump_primary",
"name": "Primary Pump",
"tags": [
"pump",
"primary",
"control",
"automation"
],
"attributes": {},
"description": "Main water pump with variable speed drive",
"station_id": "station_main"
},
"pump_backup": {
"id": "pump_backup",
"name": "Backup Pump",
"tags": [
"pump",
"backup",
"emergency",
"automation"
],
"attributes": {},
"description": "Emergency backup water pump",
"station_id": "station_backup"
},
"sensor_pressure": {
"id": "sensor_pressure",
"name": "Pressure Sensor",
"tags": [
"sensor",
"measurement",
"monitoring",
"safety"
],
"attributes": {},
"description": "Water pressure monitoring sensor",
"station_id": "station_main"
},
"sensor_flow": {
"id": "sensor_flow",
"name": "Flow Meter",
"tags": [
"sensor",
"measurement",
"monitoring",
"industrial"
],
"attributes": {},
"description": "Water flow rate measurement device",
"station_id": "station_main"
}
},
"data_types": {
"speed_pump": {
"id": "speed_pump",
"name": "Pump Speed",
"tags": [
"setpoint",
"control",
"measurement",
"automation"
],
"attributes": {},
"description": "Pump motor speed control and feedback",
"units": "RPM",
"min_value": 0,
"max_value": 3000,
"default_value": 1500
},
"pressure_water": {
"id": "pressure_water",
"name": "Water Pressure",
"tags": [
"measurement",
"monitoring",
"alarm",
"safety"
],
"attributes": {},
"description": "Water pressure measurement",
"units": "PSI",
"min_value": 0,
"max_value": 100,
"default_value": 50
},
"status_pump": {
"id": "status_pump",
"name": "Pump Status",
"tags": [
"status",
"monitoring",
"alarm",
"diagnostic"
],
"attributes": {},
"description": "Pump operational status",
"units": null,
"min_value": null,
"max_value": null,
"default_value": null
},
"flow_rate": {
"id": "flow_rate",
"name": "Flow Rate",
"tags": [
"measurement",
"monitoring",
"optimization"
],
"attributes": {},
"description": "Water flow rate measurement",
"units": "GPM",
"min_value": 0,
"max_value": 1000,
"default_value": 500
}
},
"all_tags": [
"active",
"control",
"safety",
"controller",
"water_system",
"sensor",
"optimization",
"diagnostic",
"industrial",
"primary",
"emergency",
"secondary",
"motor",
"fault",
"monitoring",
"status",
"alarm",
"pump",
"municipal",
"actuator",
"healthy",
"setpoint",
"valve",
"inactive",
"backup",
"remote",
"feedback",
"command",
"measurement",
"maintenance",
"automation",
"local"
]
}

View File

@ -0,0 +1,53 @@
"""
Metadata Initializer
Loads sample metadata on application startup for demonstration purposes.
In production, this would be replaced with actual metadata from a database or configuration.
"""
import os
import json
import logging
from typing import Optional
from .tag_metadata_manager import tag_metadata_manager
logger = logging.getLogger(__name__)
def initialize_sample_metadata():
"""Initialize the system with sample metadata for demonstration"""
# Check if metadata file exists
metadata_file = os.path.join(os.path.dirname(__file__), '..', '..', 'sample_metadata.json')
if os.path.exists(metadata_file):
try:
with open(metadata_file, 'r') as f:
metadata = json.load(f)
# Import metadata
tag_metadata_manager.import_metadata(metadata)
logger.info(f"Sample metadata loaded from {metadata_file}")
logger.info(f"Loaded: {len(tag_metadata_manager.stations)} stations, "
f"{len(tag_metadata_manager.equipment)} equipment, "
f"{len(tag_metadata_manager.data_types)} data types")
return True
except Exception as e:
logger.error(f"Failed to load sample metadata: {str(e)}")
return False
else:
logger.warning(f"Sample metadata file not found: {metadata_file}")
logger.info("System will start with empty metadata. Use the UI to create metadata.")
return False
def get_metadata_summary() -> dict:
"""Get a summary of current metadata"""
return {
"stations": len(tag_metadata_manager.stations),
"equipment": len(tag_metadata_manager.equipment),
"data_types": len(tag_metadata_manager.data_types),
"total_tags": len(tag_metadata_manager.all_tags)
}

View File

@ -25,6 +25,7 @@ from src.core.optimization_manager import OptimizationPlanManager
from src.core.setpoint_manager import SetpointManager from src.core.setpoint_manager import SetpointManager
from src.core.security import SecurityManager from src.core.security import SecurityManager
from src.core.compliance_audit import ComplianceAuditLogger from src.core.compliance_audit import ComplianceAuditLogger
from src.core.metadata_initializer import initialize_sample_metadata
from src.monitoring.watchdog import DatabaseWatchdog from src.monitoring.watchdog import DatabaseWatchdog
from src.monitoring.alerts import AlertManager from src.monitoring.alerts import AlertManager
from src.monitoring.health_monitor import HealthMonitor from src.monitoring.health_monitor import HealthMonitor
@ -182,6 +183,10 @@ class CalejoControlAdapter:
await persistent_discovery_service.initialize() await persistent_discovery_service.initialize()
logger.info("persistent_discovery_service_initialized") logger.info("persistent_discovery_service_initialized")
# Initialize sample metadata for demonstration
initialize_sample_metadata()
logger.info("sample_metadata_initialized")
# Load safety limits # Load safety limits
await self.safety_enforcer.load_safety_limits() await self.safety_enforcer.load_safety_limits()
logger.info("safety_limits_loaded") logger.info("safety_limits_loaded")