-
Notifications
You must be signed in to change notification settings - Fork 1
Even Realities G1 BLE Protocol
This doc aims to outline the BLE protocol for the Even Realities G1. The G1 operates with two BLE radios, one for the left side and one for the right. Some commands need to be sent individually to both sides and some are only sent to one side. Each radio operates as a stream of packets using the Nordic BLE UART.
These are some example sequences of Commands that can be used as basic building blocks.
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
The official app uses this for the teleprompter feature, but it can scroll any text such as a news feed or an ebook.
TODO
The official app uses this for Stocks, but it can be used for anything, for example heart rate over time or blood glucose levels.
These are messages the glasses will send to the app unprompted when an event happens or they want to put the status in.
TODO
TODO
The glasses send debug messages when debugging mode is enabled.The message is a null terminated ASCII string. See Enable/Disable Debug Mode (0x23 0x6C)
| Header | Message |
|---|---|
F4 |
Null Terminated ASCII Data.\0 |
| Header | Sub | Payload | Description |
|---|---|---|---|
F5 |
00 |
TouchPad Double Tap |
|
F5 |
01 |
TouchPad Single Tap |
|
F5 |
02 |
Head Up |
|
F5 |
03 |
Head Down |
|
F5 |
04 |
TouchPad Triple Tap |
|
F5 |
05 |
TouchPad Triple Tap |
|
F5 |
06 |
Worn |
|
F5 |
07 |
Not worn / Not in case |
|
F5 |
08 |
In Case / Lid open |
|
F5 |
09 |
00 / 01 |
Glasses side charging |
F5 |
0A |
00 ~ 64 |
Glasses side battery level |
F5 |
0B |
In case / Lid closed / Case plugged in |
|
F5 |
0C |
||
F5 |
0D |
||
F5 |
0E |
00 / 01 |
Case charging |
F5 |
0F |
00 ~ 64 |
Case battery level |
F5 |
10 |
||
F5 |
11 |
BLE Paired Success? |
|
F5 |
12 |
Right TouchPad pressed / held / released |
|
F5 |
17 |
Left TouchPad pressed and held |
|
F5 |
18 |
Left TouchPad pressed Released |
|
F5 |
19 |
||
F5 |
1A |
||
F5 |
1B |
||
F5 |
1C |
||
F5 |
1D |
||
F5 |
1E |
Open Dashboard (double tap) |
|
F5 |
1F |
Close Dashboard (double tap) |
|
F5 |
20 |
Double tap either side when set to translate or transcribe |
Commands are messages the App can send to the glasses. The glasses may optionally respond.
Many commands will simply respond with a generic success/failure message. The header will repeat the command id back, and one additional byte which will be either success or failure. This is recorded here and referenced by all commands that operate this way to avoid duplicating the same response for all such messages.
| Command | Subcommand | Description |
|---|---|---|
XX |
C9 |
Success |
XX |
CA |
Failure |
XX |
CB |
Continue data |
Adjust the brightness level or enable/disable auto brightness. Send to Right side. Response is generic.
| Command | Brightness | Auto |
|---|---|---|
01 |
00~2A |
00 / 01 |
This will activate or deactivate the silent mode of the glasses. Send to Both sides. Response is generic.
| Command | Enable/Disable | Description |
|---|---|---|
03 |
0C |
Silent Mode On |
03 |
0A |
Silent Mode Off |
Send over the config for notifications. This has JSON with some booleans and an allowlist for which apps to display notifications for. Send to Left side. Response is generic.
| Command | Chunk Count | Chunk | Payload (JSON) (Max size 180 bytes) |
|---|---|---|---|
04 |
01~FF |
00~FF |
{"calendar_enable":true, "Call_enable":true, "Msg_enable":true, "Ios_mail_enable":true, "app":{ "List":[ {"id":"com.app", "name":"App Name"}, ...], “enable”:true } |
Send settings to control the dashboard. The length includes full packet length, including the command, length, pad and sequence in addition to the payload. Subcommands are listed below with their payloads.
| Command | Length | Pad | Sequence | Payload |
|---|---|---|---|---|
06 |
XX |
00 |
FF |
XX XX XX XX ... |
Sets both the time and weather.
| Subcommand | Epoch Time 32bit (s) | Epoch Time 64bit (ms) | Weather Icon ID | Temp C | C/F | 24H/12H |
|---|---|---|---|---|---|---|
01 |
XX XX XX XX |
XX XX XX XX XX XX XX XX |
01-10 |
XX |
00/01 |
00/01 |
Set just the weather.
TODO
| Icon ID | Description |
|---|---|
00 |
None |
01 |
Night |
02 |
Clouds |
03 |
Drizzle |
04 |
Heavy Drizzle |
05 |
Rain |
06 |
Heavy Rain |
07 |
Thunder |
08 |
Thunder Storm |
09 |
Snow |
0A |
Mist |
0B |
Fog |
0C |
Sand |
0D |
Squalls |
0E |
Tornado |
0F |
Freezing |
10 |
Sunny |
TODO
TODO
cmd: L06, len: 189, data = 06 bd 00 6d 04 0b 00 01 00 00 01 02 01 01 01 08 47 4d 45 2e 58
TODO
len: 115, data = 06 73 00 52 05 01 00 01 00 00 02 02 01 01 01 08 ASCII
Set the dashboard mode, currently has three modes: minimal, dual, full
| Subcommand | Mode ID | Secondary Pane ID |
|---|---|---|
06 |
00~02 |
00~05 |
| Mode ID | Description |
|---|---|
00 |
Full |
01 |
Dual |
02 |
Minimal |
Only respected on Full or Dual Mode
| Secondary Pane ID | Description |
|---|---|
00 |
Notes |
01 |
Stock (graph) |
02 |
News |
03 |
Calendar |
04 |
Map |
05 + |
Empty |
The response repeats back the sequence
| Command | Request Length | Pad | Sequence | Subcommand | Payload |
|---|---|---|---|---|---|
06 |
07 |
00 |
00-FF |
XX |
XX XX |
TODO
Is this a timer?!?!
TODO
Sets what happens when the user lifts their head up. Send to Both sides. Response is generic
If the Local / Global is set to 03, the command can be sent to just the left and left will forward to the right? If set to 04, the command sends to both?
| Header | Packet size | Pad | Seq | Local / Global | Action |
|---|---|---|---|---|---|
08 |
06 |
00 |
00-FF |
03 / 04 |
00 / 02 |
| Action ID | Action |
|---|---|
00 |
Show the Dashboard |
01 |
?? |
02 |
Do Nothing |
TODO
| Subcommand ID | Description |
|---|---|
01 |
Init / Set Text |
02 |
Set Position |
03 |
Update Text |
04 |
None |
05 |
Exit |
TODO
| Subcommand ID | Description |
|---|---|
00 |
Init |
01 |
Update Trip Status |
02 |
Update Map Overview |
03 |
Set Panoramic Map |
04 |
App Sync Packet |
05 |
Exit |
06 |
Arrived |
Sets the angle at which the display turns on when the wearer looks up. Send to Right side. Response is generic
| Header | Angle | Level? |
|---|---|---|
0B |
00~3C |
01 ? |
TODO
Turn the microphone on or off. Send to XXX side. Response is generic
| Header | Enable / Disable |
|---|---|
0E |
00 / 01 |
Set or clear the base horizontal head up angle. Response is generic
TODO
| Subcommand ID | Description |
|---|---|
01 |
Clear |
02 |
Set |
TODO
The crc check value calculated using Crc32Xz big endian, combined with the bmp picture storage address and picture data.
TODO
After a successful Firmware Update, resources will still be allocated to the DFU firmware image. This command erases the image. Do NOT send this command unless you REALLY know what you are doing. Send to Both sides. Response is generic.
| Command |
|---|
17 |
Clears the screen of bitmaps. Also clears text?
TODO
TODO
TODO
This has subcommands that need to be sent in sequence.
TODO
TODO
Enables debug logging on the glasses. Response is generic. Oddly enough, 00 is enabled while C1 is disabled. See Debug Messages (0xF4).
| Command | Subcommand | Enable/Disable |
|---|---|---|
23 |
6C |
00 / C1 |
Reboots the glasses. No response.
| Command | Subcommand |
|---|---|
23 |
72 |
Send and the device should respond with fw build information
| Command | Subcommand |
|---|---|
23 |
74 |
This response kind of sucks because it has no header and is just raw ASCII data. Currently it always starts with “net”.
| ASCII Payload |
|---|
net build time: 2024-12-28 20:21:57, app build time 2024-12-28 20:20:45, ver 1.4.5, JBD DeviceID 4010 |
TODO
TODO
| Header | Packet size | Pad | Seq | SubCommand | Success |
|---|---|---|---|---|---|
26 |
06 |
00 |
00-FF |
XX |
C9/CA |
| Subcommand ID | Description |
|---|---|
01 |
Set something to 1 |
02 |
Set Raster Height and Depth |
03 |
give mic_transm_sem |
04 |
ble set lum gear |
05 |
Set Double Tap Action |
06 |
ble set lum coeffic |
07 |
Enable/Disable Long Press Action |
08 |
Set Activate Mic on Head Up |
Control the display’s height and depth. Must be called twice, first with the preview bit set to 1, and then a few seconds later with the bit set 0. The glasses will stay on permanently until the preview=0 command is sent, or if the preview=1 is not sent, the glasses will reject the setting.
| Header | Packet size | Pad | Seq | SubCommand | Preview | Height | Depth |
|---|---|---|---|---|---|---|---|
26 |
08 |
00 |
00-FF |
02 |
00/ 01 |
00-08 |
01-09 |
| Header | Packet size | Pad | Seq | SubCommand | Action |
|---|---|---|---|---|---|
26 |
06 |
00 |
00-FF |
04 |
XX |
| Action ID | Description |
|---|---|
00 |
None (Close Active Feature) |
01 |
|
02 |
Open Translate |
03 |
Open Teleprompter |
04 |
Show Dashboard |
05 |
Open Transcribe |
| Header | Packet size | Pad | Seq | SubCommand | Enable/Disable |
|---|---|---|---|---|---|
26 |
06 |
00 |
00-FF |
07 |
00 / 01 |
| Action ID | Description |
|---|---|
00 |
Disabled |
01 |
Enabled |
Enables or Disables streaming audio to the phone when the head is lifted..
| Header | Packet size | Pad | Seq | SubCommand | Enable/Disable (inverted) |
|---|---|---|---|---|---|
26 |
06 |
00 |
00-FF |
08 |
01 / 00 |
Enable or disable Wear Detection. When enabled, additional 0xF5 messages are sent when worn or not. Response is generic.
| Command | Enable/Disable |
|---|---|
27 |
00~01 |
Fetches the current screen brightness. Send to Right side.
| Command |
|---|
29 |
| Header | ?? | Brightness Value | Auto brightness Enabled |
|---|---|---|---|
29 |
65 |
00~2A |
00 / 01 |
TODO
There seems to be additional info in this, I’m not sure what it is though. Send to Both sides.
| Command |
|---|
2B |
| Header | ?? | Silent Enabled | State Code |
|---|---|---|---|
2B |
69 |
0C (true) / 0A (false) |
XX |
These codes are the same sent with the F5 device events.
| Code | State |
|---|---|
06 |
Glasses worn |
07 |
Glass not worn |
08 |
Glass in case, lid open |
0A |
Glasses in case, lid closed |
0B |
Glasses in case, lid closed, case plugged in |
Gets more detailed battery info than what the 0xF5 messages contain.
| Command | Subcommand |
|---|---|
2C |
01 |
Voltage A and Voltage B are a high accuracy partial voltage and a low accuracy partial voltage, they can be combined to get an accurate voltage from that battery. Most apps won’t care about this and can just parse the battery percentage byte.
| Header | Size ? | Battery Percentage | Battery Voltage A | Battery Voltage B |
|---|---|---|---|---|
2C |
66 |
00~64 |
00 00 00 00 |
00 00 00 00 |
TODO
| Command | Subcommand |
|---|---|
2C |
02 |
TODO
TODO
TODO
Returns the configured angle to activate the screen at. Send to Right side.
| Command |
|---|
32 |
| Header | Success | Angle |
|---|---|---|
32 |
C9 |
00~42 |
Fetches the Serial number of the individual lens.
| Command |
|---|
33 |
Response is ASCII
| Header | Magic | ASCII Payload |
|---|---|---|
33 (“3”) |
33 (“3”) |
47 31 52 31 45 4b 54 30 39 39 03 |
Fetched the Serial number of the Glasses.
| Command |
|---|
34 |
Response is ASCII
| Header | Magic | Frame Type | Frame Color | ID |
|---|---|---|---|---|
34 (“4”) |
34 (“4”) |
SXXX |
LXX |
LXXXXXX |
The serial number can be fetched from the BLE Scan Result object. For example:S110LAAL103842
The first 4 characters indicate the frame shape.
| Frame | Code | Description |
|---|---|---|
S100 |
A |
Round |
S110 |
B |
Square |
The next 3 characters indicate the color of the frames.
| Color | Code | Description |
|---|---|---|
LAA |
Grey1 |
Grey |
LBB |
Brown1 |
Brown |
LCC |
Green1 |
Green |
The two lenses communicate using Enhanced ShockBurst (ESB). This lists the ESB channel they are talking on.
| Command |
|---|
35 |
| Header | Success / Fail | Channel ID |
|---|---|---|
35 |
C9 / CA |
XX |
The two lenses communicate using Enhanced ShockBurst (ESB). Fetches the number of pending ESB notifications.
| Command |
|---|
36 |
| Header | Success / Fail | Notification Count |
|---|---|---|
36 |
C9 / CA |
XX |
Fetches the time since boot in seconds.
| Command |
|---|
37 |
| Header | Payload | ??? |
|---|---|---|
37 |
49 1a 00 00 |
00 / 01 |
??
TODO
Fetches the current configured option for wear detection. This enables or disables a proximity sensor on the glasses that can determine if the glasses are worn or not. Send to Either side.
| Command |
|---|
3A |
| Header | Success | Silent Enabled |
|---|---|---|
3A |
C9 |
00 / 01 |
Fetches the current screen height and depth values. Send to Right side.
| Command |
|---|
3B |
| Header | Success | Height | Depth |
|---|---|---|---|
3B |
C9 |
00~08 |
01~09 |
Fetches the current value, in seconds, for how long a notification will be shown to the user when it arrives.. Send to Left side.
| Command |
|---|
3C |
| Header | Success | Enabled | Timeout |
|---|---|---|---|
3C |
C9 |
00 / 01 |
00~FF |
TODO
Fetch buried point data, which is essentially user usage tracking: https://www.php.cn/faq/446290.html
| Command |
|---|
3E |
| Header | Success | Payload (197 bytes ?) |
|---|---|---|
3E |
C9 |
Example censored as it may contain private data. |
TODO
See Button Double Tap Settings (0x06)
TODO
Send a notification to the glasses. Divide the JSON payload into 180 byte segments and determine the number of chunks. Send multiple packets one for each chunk. The chunk count should be the same in all packets. The Chunk Index of each packet should increment by 1 as they are sent. Wait for a C9 (success) response before sending the next chunk. The msg_id in the JSON should be unique for each notification sent.
Send to Left side. Response is generic.
| Command | Pad? | Chunk Count | Chunk Index | Payload (JSON) (Max size 180 bytes) |
|---|---|---|---|---|
4B |
00 |
01~FF |
00~FF |
{"ncs_notification":{"msg_id":16,"action":0,"app_identifier":"nodomain.freeyourgadget.gadgetb","title":"Test notification","subtitle":"","message":"This is a test notification from Gadgetbridge","time_s":1749606217,"date":"2025-06-10 18:43:37","display_name":"Gadgetbridge"}} |
Clear a notification on the glasses. The msg_id should match one that was sent via the 0x4B command.
Send to Left side. Response is generic.
| Command | Payload (32-bit msg id) |
|---|---|
4C |
00 00 00 1b |
TODO
Sets the Device BLE MTU value. This should match the setting requested from the host OS ble stack, but never exceed 251. Send to Both sides. Response is generic.
| Command | MTU value |
|---|---|
4D |
FB (251) |
Enables or disables the notification auto displaying on the glasses and the amount of time that the notification will be shown. Send to Both sides. Response is generic.
| Command | Enable/Disable | Display Timeout (seconds) |
|---|---|---|
4F |
00~01 |
00~FF |
TODO
TODO
TODO