SOLVED: Omron BP5465 Bluetooth pairing works once, but would then fail on every subsequent connection…
My Home Assistant system is running HAOS in a KVM virtual machine, with a dedicated USB Bluetooth adapter passed directly through to the VM. The Bluetooth adapter is a FEASYCOM FSC-BP119 using a CSR8510 A10 controller.
@eigger I wanted to thank you so much for this integration, you must have put some much work into it! I have a PR for you - which only has one changed file (omron-driver.py) - which has fixed the issue I had with the above machine I just purchased.
Here is the repository link to add into HACS for anyone who has this blood pressure monitor (or one of the same class) for testing purposes so we can get @eigger to merge it in! GitHub - KruseLuds/hass-omron: Omron BLE BPM Home Assistant Integration · GitHub
The BP5465 could initially pair successfully with Home Assistant using the hass-omron custom integration, but after that initial pairing it would not reconnect correctly for any blood pressure measurements.
I tested newer hass-omron development code that contained changes around notification subscriptions/CCCD handling. That was worth testing because there had previously been work involving this device family and pairing behavior. Unfortunately the BP5465 still exhibited the same fundamental pattern - Fresh pairing succeeded, the next retained-bond connection (blood pressure measurement) failed. So preserving the CCCD state did not solve this particular BP5465 problem either.
After a lot of Bluetooth debugging, packet captures, source-code investigation, comparison with the official Omron Connect Android app, and quite a few experiments, I eventually discovered that the problem was not really the Bluetooth bond itself. The BP5465 appears to require an additional application-level registration/finalization operation during the initial pairing session. The official android “Omron Connect” app performs this operation, which the existing integration did not (yet!) have. Once I reproduced those missing operations in hass-omron, the problem disappeared. While using an Android Bluetooth HCI snoop capture from my Samsung phone, I examined a successful fresh pairing with Omron Connect. Near the end of the initial pairing session, the official app performed additional application-level EEPROM/memory operations. Two writes in particular stood out:
- A 38-byte write to address: 0x0058
- Followed by a 16-byte write to: 0x0088
Only after those operations did Omron Connect send the normal session-close command, 080f000000000007. The cuff then disconnected normally.
There had actually been previous experimentation in the hass-omron project involving similar memory mirroring for this family of devices. However, that earlier work involved a shorter 28-byte operation. The Android capture of a real fresh BP5465 pairing showed something different:
The official android Omron application performs a 38-byte write to 0x0058 during the fresh pairing process, and then it also performed the 16-byte operation at 0x0088 before closing the session. This suggested that the Bluetooth pairing itself was only part of what the cuff considered “pairing.”
There appeared to be another registration step inside the Omron application protocol. My working theory became, the Bluetooth SMP bond is successfully created, which is why the initial pairing works - but unless the application-level registration/finalization data is committed to the cuff before the first session closes, the cuff does not subsequently recognize that bond as valid. Therefore, on the next connection, even though BlueZ presents the exact LTK that the cuff previously distributed, the cuff rejects encryption with 0x06. That neatly explained a symptom that otherwise looked contradictory.
I modified the hass-omron driver to reproduce the relevant behavior seen in the official Android application, and the change is deliberately restricted to the HEM-7386T1 family and only runs during the initial pairing session. The driver now performs the equivalent pairing-registration finalization before the first memory session closes. In simplified terms, it:
- Reads the appropriate settings block beginning at 0x0010.
- Constructs the 38-byte registration block.
- Writes that block to 0x0058.
- Reads the corresponding clock/state block beginning at 0x0040.
- Constructs the 16-byte companion block.
- Writes that block to 0x0088.
- Continues with the existing normal session close.
The implementation uses the integration’s canonical profile resolver so that the actual BP5465 identifier HEM-7382T1-AZAZ is correctly recognized as belonging to the HEM-7386T1 family. This is also guarded so that these registration operations occur during fresh pairing only, ordinary retained-bond measurement sessions do NOT repeat them.
And if the upstream PR is accepted, hopefully nobody else with Omron blood pressure monitors (at least of the same HEM-7386T1 family as mine) will ever need to go through this entire adventure just to get their blood pressure monitor talking to Home Assistant. 
I did use ChatGPT for alot of the analysis… Fortunately only one file needed to change!