# PyBusMonitor1553 - AI Coding Instructions

## Project Overview
MIL-STD-1553 bus monitor and simulator for radar system integration (GRIFO-F/TH). Receives/transmits 1553 messages over UDP, supports both CLI and Tkinter GUI modes.

## Architecture

### Data Flow
```
UDP Network → UdpHandler → MessageDispatcher → Message Objects (MsgA1-A8, MsgB1-B8)
                                    ↓
GUI/CLI ← RadarController ← TrafficScheduler → PacketBuilder → UDP Network
```

### Key Modules
- **lib1553/**: Protocol layer - message definitions, field descriptors, headers
- **core/**: Business logic - dispatcher, network, scheduler, controller
- **gui/**: Tkinter-based bus monitor interface
- **utils/**: Debug helpers (printer)

## Message System Patterns

### Adding New Messages
1. Create `msg_xx.py` in `lib1553/messages/` inheriting from `MessageBase`
2. Define `SUBADDRESS` (from `constants.Subaddress`) and `IS_TRANSMIT` (True=RT→BC, False=BC→RT)
3. Use field descriptors for data words:
```python
from ..message_base import MessageBase
from ..constants import Subaddress, SomeEnum
from ..fields import BitField, EnumField, ScaledField

class MsgXX(MessageBase):
    SUBADDRESS = Subaddress.XX
    IS_TRANSMIT = False  # BC→RT
    
    # Field: word_index (0-based), start_bit (0=MSB per 1553), width
    some_flag = BitField(word_index=0, start_bit=0, width=1)
    mode = EnumField(word_index=0, start_bit=1, width=4, enum_cls=SomeEnum)
    value = ScaledField(word_index=1, start_bit=0, width=16, lsb_value=0.5, signed=True)
```
4. Register in `lib1553/messages/__init__.py`
5. Add to `MessageDispatcher._init_registry()` in `core/dispatcher.py`

### Field Descriptors (`lib1553/fields.py`)
- `BitField`: Unsigned integers, flags
- `EnumField`: Maps to `IntEnum` classes in `constants.py`
- `ScaledField`: Physical values with LSB scaling (supports signed 2's complement)
- `ASCIIField`: Two characters packed in one 16-bit word

### Bit Numbering Convention
MIL-STD-1553 uses **MSB=0 numbering** (Bit 0 is the Most Significant Bit). The `Field` base class handles conversion to Python's LSB-first representation.

## Protocol Details

### UDP1553 Frame Structure
- UDP Header (64 bytes) with `0x1553` marker
- Message blocks: `0x3C3C` marker → Command Word → Data → `~CW` → `0x3E3E`
- End marker: `0x5315`

### Data Endianness
- UDP headers: Little Endian (ctypes structures)
- Message payload (32 words): **Big Endian** (network byte order) - see `MessageBase.pack()/unpack()`

## Development Commands

```bash
# Run application (GUI mode default)
python -m pybusmonitor1553

# Run with CLI mode
python -m pybusmonitor1553 --cli

# Run tests with coverage
pytest

# Environment variables for network config
PYBM_RX_IP=127.0.0.1 PYBM_RX_PORT=61553 python -m pybusmonitor1553
```

## Testing Patterns
- Tests in `tests/` use pytest with coverage (see `pytest.ini`)
- Mock messages using `MessageBase` with raw bytes or field setters
- Test field descriptors with minimal `DummyMsg(MessageBase)` classes
- Dispatcher tests build raw UDP packets using ctypes structures

## Constants & Enums
All ICD-defined enumerations are in `lib1553/constants.py` as `IntEnum`. Reference document sections noted in docstrings (e.g., "Ref. Tab. A1/01-A").

## Debug Flags
- `network.py`: `DEBUG_PACKETS = False` - hex dump received packets
- `scheduler.py`: `DEBUG_PACKETS = False`, `QUIET_MODE = False`
- `packet_builder.py`: `DEBUG_BUILD = False`

## Future Extensions

### Project Evolution
This codebase is designed to evolve from **passive bus monitor** to **active radar simulation platform**:

1. **Phase 2 - Command & Control**: GUI controls to modify radar parameters (mode, range, scan)
2. **Phase 3 - Target Injection**: Synthetic track generation to simulate radar returns
3. **Phase 4 - Integration Platform**: Scripting API, scenario playback, plugin system

### Extensibility Design
All message fields are **already modifiable** via descriptor pattern:
```python
msg_a1.master_mode = MasterMode.TWS
msg_a2.track_position_x = 15000.0
msg_a5.altitude = 10000.0
```

**Key Architecture Principles**:
- Field descriptors enable programmatic parameter modification
- `RadarController` centralizes state management (extend with validation/command queueing)
- `PacketBuilder` already supports sending modified messages
- Multi-rate scheduler can handle dynamic message addition
- No breaking changes required—new features add, not replace

**Extension Points**:
- `core/command_builder.py` (future) - Parameter validation layer
- `core/target_manager.py` (future) - Track kinematics for injection
- `RadarController.apply_config()` - Replace hardcoded defaults with profiles
- `Field.validate()` hook - Range/enum validation per ICD limits

**Critical Constraints**:
- 32-bit fields (velocity_x/y/z) are read-only properties (combine MSW+LSW words)
- Validity flags use inverse logic: 0=VALID, 1=INVALID
- Big Endian payload vs Little Endian headers
- Message rates must respect ICD timing (50Hz/25Hz/6.25Hz)

See `doc/Roadmap.md` for detailed evolution plan.
