# Home Assistant Integration Plan for Lippert OneControl ## Overview This document outlines the plan to create a Home Assistant integration for Lippert OneControl RV systems via Bluetooth. ## Integration Architecture ### Option 1: ESPHome Bluetooth Proxy (Recommended) **Advantages:** - No need to reverse engineer full protocol if we can relay commands - Use ESP32 as Bluetooth<->WiFi bridge - Native Home Assistant integration - Reliable and well-supported **Components:** - ESP32 device with Bluetooth - ESPHome firmware - Home Assistant ESPHome integration **Implementation:** 1. Configure ESP32 as Bluetooth proxy 2. Discover OneControl device 3. Create custom component for command sending ### Option 2: Python-Based Custom Integration **Advantages:** - Direct control from Home Assistant host - Can run on Home Assistant server (if it has Bluetooth) - Full protocol implementation **Components:** - Python library using `bleak` for BLE communication - Home Assistant custom component (HACS) - Configuration via YAML or UI **Implementation:** ```python # Key libraries needed - bleak (Python BLE library) - homeassistant.components (HA integration) ``` ## Step-by-Step Implementation ### Phase 1: Protocol Discovery (Current Phase) - [ ] Complete .NET assembly decompilation - [ ] Capture Bluetooth packets using HCI snoop - [ ] Document command structure - [ ] Identify all GATT characteristics and UUIDs ### Phase 2: Python Library Development Create a Python library `pylippert_onecontrol`: ```python # pylippert_onecontrol/client.py from bleak import BleakClient import struct from .cobs import encode_packet # Implement COBS + CRC8 # Confirmed UUIDs from Decompiled Code SERVICE_UUID = "00000030-0200-A58E-E411-AFE28044E62C" CHAR_READ_UUID = "00000034-0200-A58E-E411-AFE28044E62C" CHAR_WRITE_UUID = "00000033-0200-A58E-E411-AFE28044E62C" class OneControlClient: def __init__(self, address): self.address = address self.client = None self._seq = 0 async def connect(self): self.client = BleakClient(self.address) await self.client.connect() def _next_seq(self): self._seq = (self._seq + 1) & 0xFFFF return self._seq async def send_command(self, cmd_type, table_id, payload): # 1. Build Packet # [Seq (2)] [CmdType (1)] [TableID (1)] [Payload...] seq = self._next_seq() packet = struct.pack("