-
Notifications
You must be signed in to change notification settings - Fork 1
Even Realities G1 BLE Protocol
The Even Realities 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.
TODO: Describe the NRF UART BLE UUIDs TODO: Explain Global Sequence
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.
These messages come when certain events happen on the glasses. See: Dashboard Set (0x06) for the Dashboard and Pane modes.
Sent when the user looks up.
| Header | Size | ?? | ?? | Event? | Num Unread | Low Power | Dashboard Mode | Pane Mode | Pane Page Number |
|---|---|---|---|---|---|---|---|---|---|
22 |
0A |
00 |
00 |
01 |
00 ~ FF |
00 / 01 |
00 ~ 02 |
00 ~ 05 |
01 ~ 04 |
Sent when the user taps the right side while looking up.
| Header | Size | ?? | ?? | Event? | Dashboard Mode | Pane Mode | Pane Page Number |
|---|---|---|---|---|---|---|---|
22 |
08 |
00 |
00 |
02 |
00 ~ 02 |
00 ~ 05 |
01 ~ 04 |
A continuous Audio Stream sent when the user looks up and Head Up Microphone is enabled or the Microphone is manually enabled. See: Activate Microphone on Head Lift Settings (0x08) and Microphone Set (0x0E). The Audio Sequence is different from the Global Sequence, and will reset each time the microphone is enabled or disabled.
| Header | Audio Sequence | Audio Data (LC3) |
|---|---|---|
F1 |
00 ~ FF |
XX XX ... |
The glasses send debug messages when debugging mode is enabled.The message is a null terminated ASCII string. See Debug Mode Set (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 and 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 |
Shows a previously uploaded file as a bitmap on the screen. The image file must be uploaded before it can be displayed. See: File Upload (0x15)
| Command | File ID | CRC |
|---|---|---|
16 |
0D 0E |
The crc value is calculated using Crc32Xz big endian, combined with the bmp picture storage address and picture data.
Clears the screen of bitmaps. Also clears text? TODO
Adjust the brightness level or enable/disable auto brightness. Send to Right side. Response is generic.
| Command | Brightness | Auto |
|---|---|---|
01 |
00 ~ 2A |
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 |
Send settings to control the dashboard. The length includes full packet length, including the command, length, pad, sequence and subcommand payload. Subcommands are listed below with their payloads.
| Command | Length | Pad | Sequence |
|---|---|---|---|
06 |
XX |
00 |
00 ~ FF |
| Subcommand Payload |
|---|
XX XX XX XX ... |
| Command | Request Length | Pad | Sequence | Subcommand | Chunk Count | Pad | Chunk | Pad | Success |
|---|---|---|---|---|---|---|---|---|---|
06 |
XX |
00 |
00-FF |
XX |
01 ~ FF |
00 |
01 ~ FF |
00 |
00 / 01 |
| Command | Length | Pad | Sequence |
|---|---|---|---|
06 |
16 |
00 |
00 ~ FF |
| 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 |
00 |
TODO: This is just a guess
| Command | Length | Pad | Sequence |
|---|---|---|---|
06 |
08 |
00 |
00 ~ FF |
| Subcommand | Weather Icon ID | Temp C | C/F |
|---|---|---|---|
02 |
01-10 |
XX |
00/01 |
| Icon ID | Description | Icon ID | Description | |
|---|---|---|---|---|
00 |
None |
09 |
Snow |
|
01 |
Night |
0A |
Mist |
|
02 |
Clouds |
0B |
Fog |
|
03 |
Drizzle |
0C |
Sand |
|
04 |
Heavy Drizzle |
0D |
Squalls |
|
05 |
Rain |
0E |
Tornado |
|
06 |
Heavy Rain |
0F |
Freezing |
|
07 |
Thunder |
10 |
Sunny |
|
08 |
Thunder Storm |
11+ |
Error |
Set the dashboard mode, currently has three modes: minimal, dual, full
| Command | Length | Pad | Sequence |
|---|---|---|---|
06 |
07 |
00 |
00 ~ FF |
| 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 |
Sets the data to be shown on the calendar pane of the Dashboard.
| Command | Length | Pad | Sequence |
|---|---|---|---|
06 |
XX |
00 |
00 ~ FF |
| Subcommand | Chunk Count | Pad | Chunk | Pad | ?? | Number of Events | Events... |
|---|---|---|---|---|---|---|---|
03 |
01 ~ FF |
00 |
01 ~ FF |
00 |
01 03 03 |
XX |
XX XX ... |
Chunk Indexes at 1 not 0 for this command.
Each event entry will be composed of three strings that will take up two lines in the calendar. The official app uses Text 01 as the Title, Text 02 as the time, and Text 03 as the location.
Text (01) |
|
|---|---|
Text (02) |
Text (03) |
The event entries are sent in a list of entries each with three strings. Each string can have a length of 0 to indicate the field is blank.
| Text | Len | Value(ASCII) | Text | Len | Value(ASCII) | Text | Len | Value(ASCII) |
|---|---|---|---|---|---|---|---|---|
01 |
01~FF |
XX XX ... |
02 |
01 ~ FF |
XX XX ... |
03 |
01~FF |
XX XX ... |
TODO
| Command | Length | Pad | Sequence |
|---|---|---|---|
06 |
XX |
00 |
00 ~ FF |
| Subcommand | Chunk Count | Pad | Chunk | Pad | |||
|---|---|---|---|---|---|---|---|
04 |
01 ~ FF |
00 |
01 ~ FF |
00 |
TODO
| Command | Length | Pad | Sequence |
|---|---|---|---|
06 |
XX |
00 |
00 ~ FF |
| Subcommand | Chunk Count | Pad | Chunk | Pad | |||
|---|---|---|---|---|---|---|---|
05 |
01 ~ FF |
00 |
01 ~ FF |
00 |
TODO
| Command | Length | Pad | Sequence |
|---|---|---|---|
06 |
XX |
00 |
00 ~ FF |
| Subcommand | Chunk Count | Pad | Chunk | Pad | |||
|---|---|---|---|---|---|---|---|
07 |
01 ~ FF |
00 |
01 ~ FF |
00 |
TODO
Sets the calendar event displayed below the clock then the dashboard is in Full Mode.
TODO
TODO
Also used to upgrade a font, it seems. 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 Display 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 |
TODO See: Button Double Tap Settings (0x06)
05 |
Get Double Tap Action |
|---|---|
06 |
Get ble set lum coeffic |
07 |
Get Enable/Disable Long Press Action |
08 |
Get Activate Mic on Head Up |
Fetches the current screen height and depth values. Send to Right side.
| Command |
|---|
3B |
| Header | Success | Height | Depth |
|---|---|---|---|
3B |
C9 |
00 ~ 08 |
01 ~ 09 |
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 ? |
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 |
Send to Right side.
| Command |
|---|
32 |
| Header | Success | Angle |
|---|---|---|
32 |
C9 |
00 ~ 42 |
Set or clear the base horizontal head up angle. Response is generic TODO
TODO
| Subcommand ID | Description |
|---|---|
01 |
Clear |
02 |
Set |
Get some basic info about the device.
| Command | Subcommand |
|---|---|
2C |
01 / 02 |
| Header | Model (ASCII) | Left Battery | Right Battery | ?? | L Major Version | L Minor Version | L Sub Version | R Major Version | R Minor Version | R Sub Version |
|---|---|---|---|---|---|---|---|---|---|---|
2C |
A / B |
00~64 |
00 ~ 64 |
00 00 00 |
01 |
06 |
03 |
01 |
06 |
03 |
TODO
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 |
57 |
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 |
02 |
Fetches the time since boot in seconds.
| Command |
|---|
37 |
| Header | Payload | ?? |
|---|---|---|
37 |
49 1a 00 00 |
00 / 01 |
Fetch buried point data, which is essentially user usage tracking: https://www.php.cn/faq/446290.html
| Command |
|---|
3E |
| Header | Success | JSON Payload |
|---|---|---|
3E |
C9 |
Example censored as it may contain private data. |
Set the language for the glasses.
| Command | Size | Pad | Sequence | Magic | Language ID |
|---|---|---|---|---|---|
3D |
06 |
00 |
XX |
01 |
XX |
| ID | Language |
|---|---|
01 |
Chinese |
02 |
English |
03 |
Japanese |
04 |
?? |
05 |
French ? |
06 |
German |
07 |
Spanish ? |
0E |
Italian |
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 |
Fetches the current state of the silent mode setting. Additionally contains the State of the glasses. 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 |
Turn the microphone on or off. Send to Left side. Response is generic
| Header | Enable / Disable |
|---|---|
0E |
00 / 01 |
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) |
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 |
Send over the config for notifications. This has JSON with some booleans and an allowlist for which apps to display notifications for. The easiest way to use this on android is to set a single app as allowed and just put all notifications under that particular app id. 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 } |
TODO
Get the ANCS settings.
TODO
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 |
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 |
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
TODO
Enables debug logging on the glasses. Response is generic. Oddly enough, 00 is enabled while C1 is disabled. See: Debug (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
| Subcommand ID | Description |
|---|---|
01 |
Init / Set Text |
02 |
Set Position |
03 |
Update Text |
04 |
None |
05 |
Exit |
TODO
TODO
Display full screen text. The official app uses this to show the response for the AI voice prompt. This can also be used to show just the text without the AI context. Send to Both sides.
| Command | Size | Sequence | Chunk Count | Pad | Chunk | Pad | Display Style | Canvas State | Position | Page | Page Count | Payload (UTF-8) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
4E |
XX |
00 ~ FF |
01 ~ FF |
00 |
01 ~ FF |
00 |
X |
X |
XX XX |
XX |
XX |
XX XX ... |
The display style is only 4bits, not a full byte.
| Display Style ID | Description |
|---|---|
0 |
?? |
1 |
?? |
2 |
?? |
3 |
Even AI displaying / Auto Scroll |
4 |
Even AI Complete |
5 |
Even AI displaying / Manual Scroll |
6 |
Even AI Network Error |
7 |
Show Text only |
The Canvas State is only 4bits, not a full byte.
| Canvas State | Description |
|---|---|
0 |
Draw to existing Canvas |
1 |
Start New Canvas |
Is this a stop watch or timer?!?! TODO
TODO
TODO
TODO This has subcommands that need to be sent in sequence.
Removes the current Host (phone or PC) mac address from the glasses as a paired device. You should probably just unpair from the host device instead. Do NOT send this command unless you REALLY know what you are doing. Send to Both sides. Response is generic.
| Command |
|---|
47 |
Before a fw update, and after a successful Firmware Update, resources will 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 |
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 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 |
TODO. Send to Both sides.
| Command | Size | ?? | ?? | ?? | ?? |
|---|---|---|---|---|---|
50 |
06 |
00 |
00 |
01 |
01 |
The full command is repeated back.
| Command | Size | ?? | ?? | ?? | ?? |
|---|---|---|---|---|---|
50 |
06 |
00 |
00 |
01 |
01 |