"""Enums del modelo de datos core. Toda enumeración del producto vive aquí para tener una única fuente de verdad y poder serializarla consistentemente a `.vmsproj` y `.vmspack`. Convención de valores: snake_case_minúsculas ASCII para que sean estables en JSON/YAML/SQLite sin problemas de encoding. """ from __future__ import annotations from enum import StrEnum # --------------------------------------------------------------------------- # Buque # --------------------------------------------------------------------------- class VesselType(StrEnum): """Categoría principal del buque (Parte 2 sec 3, Paso 1).""" YACHT_MOTOR = "yacht_motor" YACHT_SAIL = "yacht_sail" FISHING = "fishing" PATROL = "patrol" FERRY = "ferry" OFFSHORE_SUPPORT = "offshore_support" class VesselSubtype(StrEnum): """Subcategoría que afina el tipo principal.""" # Yacht motor PLANING = "planing" SEMI_PLANING = "semi_planing" DISPLACEMENT = "displacement" # Fishing PURSE_SEINER = "purse_seiner" # cerquero TRAWLER = "trawler" # arrastrero LONGLINER = "longliner" # palangrero # Patrol COASTAL = "coastal" OCEANIC = "oceanic" # Ferry PASSENGER = "passenger" ROLL_ON_ROLL_OFF = "ro_ro" # Offshore support AHTS = "ahts" # Anchor Handling Tug Supply PSV = "psv" # Platform Supply Vessel # Catch-all OTHER = "other" # --------------------------------------------------------------------------- # Catálogo maestro de sistemas (Parte 1 sec 7) # --------------------------------------------------------------------------- class SystemId(StrEnum): """ID estable de cada sistema del catálogo maestro. Coincide con `vmssailor/library/systems_catalog.json`. El menú lateral del Runtime se genera a partir de los sistemas que el proyecto tenga habilitados. """ # Propulsión y maquinaria MAIN_ENGINE = "main_engine" TRANSMISSION = "transmission" SHAFT_PROPELLER = "shaft_propeller" THRUSTER = "thruster" # Maniobra y trimado TRIM_STERNDRIVE = "trim_sterndrive" TRIM_TABS = "trim_tabs" CPP = "cpp" GYROSTABILIZER = "gyrostabilizer" FIN_STABILIZER = "fin_stabilizer" JOYSTICK_DOCKING = "joystick_docking" # Generación eléctrica GENSET = "genset" SHORE_POWER = "shore_power" INVERTER_CHARGER = "inverter_charger" BATTERY_BANK = "battery_bank" MSB = "msb" ESB = "esb" UPS = "ups" SOLAR = "solar" SMART_DC_BUSBAR = "smart_dc_busbar" SMART_PANEL = "smart_panel" # Aislamiento eléctrico SECTIONALIZING = "sectionalizing" EMERGENCY_ISOLATION = "emergency_isolation" BREAKERS = "breakers" LOCKOUT_TAGOUT = "lockout_tagout" # Fluidos FUEL = "fuel" LUBE_OIL = "lube_oil" HYDRAULIC_OIL = "hydraulic_oil" FW_COOLING = "fw_cooling" SW_COOLING = "sw_cooling" STARTING_AIR = "starting_air" BILGE = "bilge" BALLAST = "ballast" GREY_WATER = "grey_water" BLACK_WATER = "black_water" POTABLE_WATER = "potable_water" SW_SERVICE = "sw_service" WATERMAKER = "watermaker" # Seguridad FIRE_DETECTION = "fire_detection" FIRE_EXTINGUISHING = "fire_extinguishing" FIFI_EXTERNAL = "fifi_external" EMERGENCY_BILGE = "emergency_bilge" GAS_DETECTION = "gas_detection" MOB = "mob" # Ambiente HVAC = "hvac" ENGINE_VENT = "engine_vent" HEATING = "heating" REFRIGERATION = "refrigeration" # Iluminación NAV_LIGHTS = "nav_lights" DECK_LIGHTS = "deck_lights" INTERIOR_LIGHTS = "interior_lights" EMERGENCY_LIGHTS = "emergency_lights" SEARCHLIGHTS = "searchlights" # Tanques estructurales FUEL_TANKS = "fuel_tanks" WATER_TANKS = "water_tanks" GREY_BLACK_TANKS = "grey_black_tanks" VOIDS = "voids" COFFERDAMS = "cofferdams" # Cubierta y maniobra WINDLASS = "windlass" ANCHOR_SYSTEM = "anchor_system" MOORING = "mooring" DAVITS = "davits" GANGWAY = "gangway" CRANE = "crane" # Específicos por tipo FISHING_MACHINERY = "fishing_machinery" LARGE_FRIDGE_HOLDS = "large_fridge_holds" ROV = "rov" DIVING_SYSTEM = "diving_system" # --------------------------------------------------------------------------- # Equipos # --------------------------------------------------------------------------- class EquipmentCategory(StrEnum): """Categoría de un EquipmentModel para clasificar la biblioteca.""" ENGINE_MAIN = "engine_main" GENSET = "genset" PUMP = "pump" VALVE = "valve" TANK = "tank" HEAT_EXCHANGER = "heat_exchanger" FILTER_SEPARATOR = "filter_separator" COMPRESSOR = "compressor" SENSOR = "sensor" INDICATOR = "indicator" BREAKER = "breaker" INVERTER = "inverter" BATTERY = "battery" THRUSTER = "thruster" STABILIZER = "stabilizer" WATERMAKER = "watermaker" LIGHTING = "lighting" HVAC_UNIT = "hvac_unit" OTHER = "other" # --------------------------------------------------------------------------- # Señales físicas y canales de tarjeta # --------------------------------------------------------------------------- class ChannelType(StrEnum): """Tipo de canal físico en la tarjeta AR-NMEA-IO-v1.0.""" AI = "ai" # Analog Input (4 por tarjeta) DI = "di" # Digital Input (5 por tarjeta) DO = "do" # Digital Output (10 por tarjeta) RPM = "rpm" # Frequency input (1 por tarjeta) class SignalType(StrEnum): """Tipo eléctrico de la señal conectada a un canal.""" # Analógicas SIG_4_20_MA = "4-20ma" SIG_0_10_V = "0-10v" SIG_0_5_V = "0-5v" RTD_PT100 = "rtd_pt100" RTD_PT1000 = "rtd_pt1000" THERMOCOUPLE_K = "thermocouple_k" THERMOCOUPLE_J = "thermocouple_j" RESISTIVE_SENDER = "resistive_sender" # tank sender, etc. VOLTAGE_DIVIDER = "voltage_divider" # batería con divisor # Digitales / discretas DRY_CONTACT = "dry_contact" CONTACT_24VDC = "contact_24vdc" RELAY_NO = "relay_no" RELAY_NC = "relay_nc" # Frecuencia PULSE_MAGNETIC_PICKUP = "pulse_magnetic_pickup" PULSE_INDUCTIVE = "pulse_inductive" PULSE_TACHO = "pulse_tacho" # --------------------------------------------------------------------------- # Protocolos y buses # --------------------------------------------------------------------------- class Protocol(StrEnum): """Protocolo por el que se accede a un tag.""" MODBUS_RTU = "modbus_rtu" MODBUS_TCP = "modbus_tcp" NMEA2000 = "nmea2000" J1939 = "j1939" INTERNAL = "internal" # tags virtuales calculados, no van al bus class BusRole(StrEnum): """Rol de una tarjeta en su bus (Parte 2 sec 3, Paso 7).""" MODBUS_SLAVE = "modbus_slave" MODBUS_MASTER = "modbus_master" NMEA2000_NODE = "nmea2000_node" DUAL = "dual" # Modbus + NMEA 2000 simultáneo BRIDGE = "bridge" # Lee NMEA 2000, expone como Modbus # --------------------------------------------------------------------------- # Filtros locales (firmware tarjeta) # --------------------------------------------------------------------------- class FilterType(StrEnum): """Filtro local que aplica la tarjeta antes de reportar (Parte 4 sec 7).""" NONE = "none" MOVING_AVG = "moving_avg" MEDIAN = "median" DEADBAND = "deadband" RATE_LIMIT = "rate_limit" # --------------------------------------------------------------------------- # Tags: control, autoridad, calidad # --------------------------------------------------------------------------- class ControlMode(StrEnum): """Estado del tag respecto a control. Filosofía monitor-now / control-later: todos los tags se definen con capacidad de control desde el día 1 aunque empiecen como MONITOR. """ MONITOR = "monitor" MANUAL = "manual" AUTO = "auto" FUTURE = "future" # actuador físico aún no instalado class AuthorityRequired(StrEnum): """Qué estación debe tener autoridad para ejecutar el control.""" BRIDGE = "bridge" ENGINE = "engine" EITHER = "either" class Quality(StrEnum): """Calidad del valor leído (OPC UA estilo).""" GOOD = "good" BAD = "bad" UNCERTAIN = "uncertain" STALE = "stale" # último conocido pero sensor offline # --------------------------------------------------------------------------- # Alarmas # --------------------------------------------------------------------------- class AlarmPriority(StrEnum): """Prioridad de alarma (Parte 3 sec 3, Parte 1 sec 6).""" EMERGENCY = "emergency" HIGH = "high" LOW = "low" INFO = "info" class AlarmState(StrEnum): """Estado de una alarma activa.""" ACTIVE = "active" # disparada, no ack ACK = "ack" # ack pero condición persiste CLEARED = "cleared" # condición resuelta # --------------------------------------------------------------------------- # Unidades SI obligatorias internas # --------------------------------------------------------------------------- class UnitSI(StrEnum): """Lista cerrada de unidades SI permitidas en `Tag.unit_si` / `Sensor.unit_si`. Regla de oro: todo internamente en SI. Conversión a imperial solo en UI. """ # Sin unidad / boolean NONE = "none" BOOL = "bool" PERCENT = "%" # Eléctricas VOLT = "V" AMPERE = "A" WATT = "W" KILOWATT = "kW" KILOWATT_HOUR = "kWh" HERTZ = "Hz" OHM = "ohm" # Mecánicas RPM = "rpm" NEWTON_METER = "Nm" METER = "m" METER_PER_SECOND = "m/s" METER_PER_SECOND_SQ = "m/s2" DEGREE = "deg" DEGREE_PER_SECOND = "deg/s" # Fluidos PASCAL = "Pa" KILOPASCAL = "kPa" BAR = "bar" LITER = "L" CUBIC_METER = "m3" LITER_PER_HOUR = "L/h" LITER_PER_MINUTE = "L/min" CUBIC_METER_PER_HOUR = "m3/h" # Térmicas DEGREE_CELSIUS = "C" KELVIN = "K" # Tiempo SECOND = "s" HOUR = "h" # Masa KILOGRAM = "kg" TONNE = "t"