{
  "feature": "obd-port-connection",
  "version": "1.0.0",
  "description": "Discover serial ports, negotiate baud rate with a diagnostic adapter, initialize it, validate OBD-II socket voltage, and auto-detect the vehicle protocol to establish a ready connection",
  "category": "integration",
  "tags": [
    "obd",
    "vehicle",
    "diagnostics",
    "serial",
    "connection",
    "discovery",
    "adapter",
    "protocol"
  ],
  "actors": [
    {
      "id": "system",
      "name": "Diagnostic System",
      "type": "system",
      "description": "The application initiating and managing the vehicle connection"
    }
  ],
  "fields": [
    {
      "name": "port",
      "type": "text",
      "required": false,
      "label": "Serial Port"
    },
    {
      "name": "baud_rate",
      "type": "number",
      "required": false,
      "label": "Baud Rate"
    },
    {
      "name": "timeout_seconds",
      "type": "number",
      "required": false,
      "label": "Read Timeout (seconds)",
      "default": 1
    },
    {
      "name": "protocol",
      "type": "select",
      "required": false,
      "label": "OBD-II Protocol",
      "options": [
        {
          "value": "auto",
          "label": "Auto-detect"
        },
        {
          "value": "SAE_J1850_PWM",
          "label": "SAE J1850 PWM"
        },
        {
          "value": "SAE_J1850_VPW",
          "label": "SAE J1850 VPW"
        },
        {
          "value": "ISO_9141_2",
          "label": "ISO 9141-2"
        },
        {
          "value": "ISO_14230_4_5baud",
          "label": "ISO 14230-4 (5-baud init)"
        },
        {
          "value": "ISO_14230_4_fast",
          "label": "ISO 14230-4 (fast init)"
        },
        {
          "value": "ISO_15765_4_11bit_500k",
          "label": "ISO 15765-4 CAN 11-bit 500kbps"
        },
        {
          "value": "ISO_15765_4_29bit_500k",
          "label": "ISO 15765-4 CAN 29-bit 500kbps"
        },
        {
          "value": "ISO_15765_4_11bit_250k",
          "label": "ISO 15765-4 CAN 11-bit 250kbps"
        },
        {
          "value": "ISO_15765_4_29bit_250k",
          "label": "ISO 15765-4 CAN 29-bit 250kbps"
        },
        {
          "value": "SAE_J1939",
          "label": "SAE J1939 (heavy trucks)"
        }
      ]
    },
    {
      "name": "connection_status",
      "type": "select",
      "required": false,
      "label": "Connection Status",
      "options": [
        {
          "value": "not_connected",
          "label": "Not Connected"
        },
        {
          "value": "adapter_connected",
          "label": "Adapter Connected"
        },
        {
          "value": "socket_connected",
          "label": "OBD Socket Connected"
        },
        {
          "value": "vehicle_connected",
          "label": "Vehicle Connected"
        }
      ],
      "default": "not_connected"
    }
  ],
  "states": {
    "field": "connection_status",
    "values": [
      {
        "name": "not_connected",
        "description": "No active connection; initial or reset state",
        "initial": true
      },
      {
        "name": "adapter_connected",
        "description": "Serial link established and adapter init commands succeeded; awaiting voltage check"
      },
      {
        "name": "socket_connected",
        "description": "OBD-II socket voltage validated above threshold; awaiting protocol detection"
      },
      {
        "name": "vehicle_connected",
        "description": "Vehicle ECU is responding; all OBD-II queries are available",
        "terminal": false
      }
    ],
    "transitions": [
      {
        "from": "not_connected",
        "to": "adapter_connected",
        "actor": "system",
        "description": "Port opened, baud rate negotiated, adapter reset and configured (echo off, headers on, linefeeds off)"
      },
      {
        "from": "adapter_connected",
        "to": "socket_connected",
        "actor": "system",
        "description": "Adapter reports socket voltage above 6V (ignition on)"
      },
      {
        "from": "socket_connected",
        "to": "vehicle_connected",
        "actor": "system",
        "description": "PID support query succeeds and a valid communication protocol is confirmed"
      },
      {
        "from": "vehicle_connected",
        "to": "not_connected",
        "actor": "system",
        "description": "Connection closed by caller or unrecoverable serial/communication error"
      },
      {
        "from": "adapter_connected",
        "to": "not_connected",
        "actor": "system",
        "description": "Voltage check fails or adapter stops responding"
      },
      {
        "from": "socket_connected",
        "to": "not_connected",
        "actor": "system",
        "description": "Protocol detection exhausted all candidates without success"
      }
    ]
  },
  "rules": {
    "port_discovery": [
      "When no port is specified, enumerate all candidate serial ports on the current platform",
      "Linux/Cygwin: scan /dev/rfcomm* and /dev/ttyUSB* patterns",
      "Windows: probe COM1 through COM255",
      "macOS: scan /dev/tty.* excluding Bluetooth modem ports",
      "Test each candidate port by opening it; exclude any that raise an access or hardware error",
      "Return ports in the order discovered; the first successful one is used by default"
    ],
    "baud_negotiation": [
      "Try baud rates in fixed sequence: 38400, 9600, 230400, 115200, 57600, 19200",
      "Send a delimiter byte sequence and wait up to 100ms for the adapter prompt character",
      "Accept the first baud rate that produces a valid adapter prompt",
      "Fail if no baud rate in the sequence succeeds"
    ],
    "adapter_initialization": [
      "Send a full reset command and wait at least 1 second before proceeding",
      "Disable echo so adapter responses are not echoed back",
      "Enable message headers so ECU source addresses are included in responses",
      "Disable linefeeds to simplify response parsing",
      "Each init command must return a success acknowledgement; abort if any fail"
    ],
    "voltage_check": [
      "Read the OBD-II socket voltage via the adapter after init",
      "Require at least 6V to confirm the socket is powered (vehicle ignition on)",
      "Do not proceed to protocol detection if voltage is below threshold"
    ],
    "protocol_detection": [
      "Use adapter auto-detect mode first; query PID support to trigger detection",
      "Read the detected protocol identifier from the adapter after the query",
      "If auto-detect fails, try protocols in likelihood order: CAN 11-bit 500k, CAN 11-bit 250k, J1850 PWM, CAN 29-bit 500k, CAN 29-bit 250k, J1850 VPW, ISO 9141-2, ISO 14230-4 5baud, ISO 14230-4 fast, J1939"
    ],
    "operational": [
      "All OBD queries must return a null/empty response if connection_status is not vehicle_connected",
      "is_connected() must return true only when status is vehicle_connected",
      "Closing the connection must release the serial port immediately and reset status to not_connected"
    ]
  },
  "outcomes": {
    "no_port_found": {
      "priority": 1,
      "error": "OBD_NO_PORT_FOUND",
      "given": [
        "no port is specified",
        "port enumeration finds no accessible serial ports"
      ],
      "then": [],
      "result": "Connection remains in not_connected state; caller receives an empty port list"
    },
    "port_access_denied": {
      "priority": 2,
      "error": "OBD_PORT_ACCESS_DENIED",
      "given": [
        "a port is specified or discovered",
        "opening the port raises a permissions or hardware-busy error"
      ],
      "then": [],
      "result": "Connection remains in not_connected state"
    },
    "baud_negotiation_failed": {
      "priority": 3,
      "error": "OBD_BAUD_NEGOTIATION_FAILED",
      "given": [
        "a serial port is accessible",
        "no baud rate in the negotiation sequence produces a valid adapter prompt"
      ],
      "then": [],
      "result": "Connection halts; adapter may be powered off or incompatible"
    },
    "adapter_init_failed": {
      "priority": 4,
      "error": "OBD_ADAPTER_INIT_FAILED",
      "given": [
        "baud rate is established",
        "one or more adapter initialization commands do not return a success acknowledgement"
      ],
      "then": [],
      "result": "Connection halts at not_connected; adapter may be damaged or incompatible"
    },
    "low_voltage": {
      "priority": 5,
      "error": "OBD_LOW_VOLTAGE",
      "given": [
        "adapter is initialized",
        "measured OBD-II socket voltage is below 6V"
      ],
      "then": [],
      "result": "Connection halts at adapter_connected; vehicle ignition is likely off"
    },
    "protocol_not_detected": {
      "priority": 6,
      "error": "OBD_PROTOCOL_NOT_DETECTED",
      "given": [
        "OBD-II socket voltage is valid",
        "all protocol candidates fail to produce a valid ECU response"
      ],
      "then": [],
      "result": "Connection halts at socket_connected; vehicle may not support OBD-II or ignition is off"
    },
    "connection_established": {
      "priority": 10,
      "given": [
        "a serial port is accessible",
        "baud rate negotiation succeeds",
        "all adapter initialization commands succeed",
        "OBD-II socket voltage is 6V or above",
        "a communication protocol is detected and confirmed with an ECU response"
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "connection_status",
          "from": "not_connected",
          "to": "vehicle_connected"
        },
        {
          "action": "emit_event",
          "event": "obd.connection.established",
          "payload": [
            "port",
            "baud_rate",
            "protocol",
            "connection_status"
          ]
        }
      ],
      "result": "System is in vehicle_connected state and ready to accept PID queries and diagnostic commands"
    },
    "connection_closed": {
      "priority": 9,
      "given": [
        "connection is in any non-not_connected state",
        "caller requests close"
      ],
      "then": [
        {
          "action": "transition_state",
          "field": "connection_status",
          "from": "vehicle_connected",
          "to": "not_connected"
        },
        {
          "action": "emit_event",
          "event": "obd.connection.closed",
          "payload": [
            "port"
          ]
        }
      ],
      "result": "Serial port is released and connection state resets to not_connected"
    }
  },
  "errors": [
    {
      "code": "OBD_NO_PORT_FOUND",
      "status": 503,
      "message": "No diagnostic adapter port found. Ensure the adapter is plugged in."
    },
    {
      "code": "OBD_PORT_ACCESS_DENIED",
      "status": 403,
      "message": "Could not open the specified port. It may be in use or require elevated permissions."
    },
    {
      "code": "OBD_BAUD_NEGOTIATION_FAILED",
      "status": 503,
      "message": "Could not establish communication speed with the adapter. Check power and cable."
    },
    {
      "code": "OBD_ADAPTER_INIT_FAILED",
      "status": 503,
      "message": "Adapter did not respond to initialization commands. It may be incompatible."
    },
    {
      "code": "OBD_LOW_VOLTAGE",
      "status": 503,
      "message": "OBD-II socket voltage is too low. Turn on the vehicle ignition and retry."
    },
    {
      "code": "OBD_PROTOCOL_NOT_DETECTED",
      "status": 503,
      "message": "Could not detect a supported OBD-II protocol. The vehicle may not be compatible."
    }
  ],
  "events": [
    {
      "name": "obd.connection.established",
      "description": "Vehicle connection fully established; protocol confirmed and ECU is responding",
      "payload": [
        "port",
        "baud_rate",
        "protocol",
        "connection_status"
      ]
    },
    {
      "name": "obd.connection.closed",
      "description": "Connection cleanly closed; serial port released",
      "payload": [
        "port"
      ]
    },
    {
      "name": "obd.connection.error",
      "description": "A connection-level error occurred during setup or operation",
      "payload": [
        "error_code",
        "port"
      ]
    }
  ],
  "related": [
    {
      "feature": "obd-pid-reading",
      "type": "required",
      "reason": "PID queries require an active vehicle_connected state"
    },
    {
      "feature": "obd-dtc-diagnostics",
      "type": "required",
      "reason": "DTC read/clear requires an active vehicle_connected state"
    },
    {
      "feature": "obd-realtime-sensors",
      "type": "required",
      "reason": "Sensor streaming requires an active vehicle_connected state"
    },
    {
      "feature": "obd-vin-extraction",
      "type": "required",
      "reason": "VIN reading requires an active vehicle_connected state"
    }
  ],
  "agi": {
    "goals": [
      {
        "id": "reliable_obd_port_connection",
        "description": "Discover serial ports, negotiate baud rate with a diagnostic adapter, initialize it, validate OBD-II socket voltage, and auto-detect the vehicle protocol to establish a ready connection",
        "success_metrics": [
          {
            "metric": "success_rate",
            "target": ">= 99.5%",
            "measurement": "Successful operations divided by total attempts"
          },
          {
            "metric": "error_recovery_rate",
            "target": ">= 95%",
            "measurement": "Errors that auto-recover without manual intervention"
          }
        ],
        "constraints": [
          {
            "type": "availability",
            "description": "Must degrade gracefully when dependencies are unavailable",
            "negotiable": false
          }
        ]
      }
    ],
    "autonomy": {
      "level": "supervised",
      "escalation_triggers": [
        "error_rate > 5"
      ]
    },
    "safety": {
      "action_permissions": [
        {
          "action": "no_port_found",
          "permission": "autonomous"
        },
        {
          "action": "port_access_denied",
          "permission": "autonomous"
        },
        {
          "action": "baud_negotiation_failed",
          "permission": "autonomous"
        },
        {
          "action": "adapter_init_failed",
          "permission": "autonomous"
        },
        {
          "action": "low_voltage",
          "permission": "autonomous"
        },
        {
          "action": "protocol_not_detected",
          "permission": "autonomous"
        },
        {
          "action": "connection_established",
          "permission": "autonomous"
        },
        {
          "action": "connection_closed",
          "permission": "autonomous"
        }
      ]
    },
    "tradeoffs": [
      {
        "prefer": "reliability",
        "over": "throughput",
        "reason": "integration failures can cascade across systems"
      }
    ],
    "coordination": {
      "protocol": "orchestrated",
      "consumes": [
        {
          "capability": "obd_pid_reading",
          "from": "obd-pid-reading",
          "fallback": "degrade"
        },
        {
          "capability": "obd_dtc_diagnostics",
          "from": "obd-dtc-diagnostics",
          "fallback": "degrade"
        },
        {
          "capability": "obd_realtime_sensors",
          "from": "obd-realtime-sensors",
          "fallback": "degrade"
        },
        {
          "capability": "obd_vin_extraction",
          "from": "obd-vin-extraction",
          "fallback": "degrade"
        }
      ]
    }
  },
  "extensions": {
    "source": {
      "repo": "https://github.com/brendan-w/python-OBD",
      "project": "python-OBD",
      "tech_stack": "Python, pyserial, ELM327 adapter",
      "files_traced": 4,
      "entry_points": [
        "obd/obd.py",
        "obd/elm327.py",
        "obd/utils.py",
        "obd/__init__.py"
      ]
    }
  }
}