Yes, unfortunately. To pevent this need to create HA integration to receive and process on HA side. But this is out of my knowledge scope.
This can be done using BTHome integration but it needs to be implemented in an update: BTHome - Home Assistant
Hello, I am trying to use the implementation code for S-MATE2, but it gives me an error fro âunknown tag ! (75:5)â in File editor
Can someone tell me where I am going wrong?
Thanks to investigations in tasmota discussion mention before I could implement this into ESPHome. It adds hold repeat suppression and additional combos under hold (effectively extending possible combination up to 84). Values are reported via text sensor.
Youâll have to edit data inside structure
static R5_t R5[ 4 ]
where 4 means how many R5 you have plus one (if you have three, put 4 inside brackets).
First entry have to be as is (itâs the current captured data and cannot be configured).
Then youâll have to have as many configuration as you defined with at least .DeviceID and .pTexSensor defined.
You can obtain DeviceID from output (where UKNOWN DeviceID[???] there is unknown DeviceID).
pTextSensor is id of text template sensor defined later.
compile under esp-idf framework.
enable debug logging to see DeviceID (while not known).
esp32_ble_tracker:
scan_parameters:
interval: 100ms
#window: 99ms
#active: True
on_ble_advertise:
- mac_address:
- "66:55:44:33:22:11"
then:
- lambda: |-
if ( x.address_uint64 () == 0x665544332211 ) {
typedef enum {
BUTTON_ID_1 = 0, BUTTON_ID_2 = 1, BUTTON_ID_3 = 2, BUTTON_ID_4 = 3, BUTTON_ID_5 = 4, BUTTON_ID_6 = 5,
BUTTON_ID_MAX = BUTTON_ID_6,
} ButtonID_e;
typedef enum {
BUTTON_ACTION_SINGLE = 0, BUTTON_ACTION_DOUBLE = 1, BUTTON_ACTION_HOLD = 2,
BUTTON_ACTION_NA = 3,
BUTTON_ACTION_MAX = 3,
} ButtonAction_e;
typedef enum {
BUTTON_MASK_1 = 0x01, BUTTON_MASK_2 = 0x02, BUTTON_MASK_3 = 0x04, BUTTON_MASK_4 = 0x08, BUTTON_MASK_5 = 0x10, BUTTON_MASK_6 = 0x20,
BUTTON_MASK_ALL= 0x3F,
BUTTON_MASK_IN = 0x80,
} ButtonMask_e;
typedef struct R5_t {
union {
struct {
// uint16_t BcnAdvType;
// uint8_t C1[6];
uint8_t DeviceType;
uint8_t C2;
uint8_t SeqNum;
uint32_t DeviceID;
uint32_t Payload;
// uint8_t PayloadAux[5];
} __attribute__((packed));
struct {
uint32_t UUIDS[3];
} __attribute__((packed));
} __attribute__((packed));
union {
uint32_t PayloadDecoded;
struct {
uint8_t Pre[2];
uint8_t ButtonID = 0xFF;
uint8_t ButtonAction = BUTTON_ACTION_NA;
} __attribute__((packed));
} __attribute__((packed));
TextSensor* pTextSensor;
uint8_t PrevButtonID;
uint8_t PrevButtonAction;
uint8_t HoldComboEnable = 0x00;
uint8_t HoldRepeatDisable = 0x3F;
} R5_t;
const char* ButtonActionStr[] = { "SINGLE", "DOUBLE", "HOLD", "N/A" };
const uint32_t DecodeMagic = 0x43C4F2FD;
#
# ================= EDIT BELOW TO YOUR NEEDS ===================
#
static R5_t R5[ 4 ] = {
{ },
{
.DeviceID = 0xA0A1A2A3,
.pTextSensor = R5_1,
.HoldComboEnable = BUTTON_MASK_6 | BUTTON_MASK_2,
.HoldRepeatDisable = BUTTON_MASK_2 | BUTTON_MASK_6 | BUTTON_MASK_5
},
{ .DeviceID = 0xB0A1A2A3,
.pTextSensor = R5_2,
.HoldRepeatDisable = BUTTON_MASK_ALL
},
{ .DeviceID = 0xC0A1A2A3,
.pTextSensor = R5_3,
.HoldRepeatDisable = BUTTON_MASK_ALL
}
};
R5_t* pR5C = &R5[0];
R5_t* pR5 = NULL;
uint8_t R5CI = 0;
pR5C->UUIDS[0] = x.get_service_uuids()[2].get_uuid().uuid.uuid32;
pR5C->UUIDS[1] = x.get_service_uuids()[3].get_uuid().uuid.uuid32;
pR5C->UUIDS[2] = x.get_service_uuids()[4].get_uuid().uuid.uuid32;
for ( uint8_t inx=1; inx < ( sizeof(R5)/sizeof(R5[0]) ); inx++ ) {
if ( R5[inx].DeviceID == pR5C->DeviceID ) { pR5 = &R5[inx]; R5CI = inx; break; } }
if ( pR5 == NULL ) {
ESP_LOGD("ble_adv", "SONOFF R5: UNKNOWN DeviceId[%0X] DeviceType[%X] SeqNum[%0X] RSSI[%i]", pR5C->DeviceID, pR5C->DeviceType, pR5C->SeqNum, x.get_rssi() );
return;
}
if ( pR5->Payload == pR5C->Payload )
return;
ESP_LOGD("ble_adv", "--------------------------------------" );
ESP_LOGD("ble_adv", "SONOFF R5: %08X %08X %08X ", pR5C->UUIDS[0], pR5C->UUIDS[1], pR5C->UUIDS[2] );
memcpy( &(pR5->UUIDS), &(pR5C->UUIDS), sizeof(((R5_t*)0)->UUIDS) );
ESP_LOGD("ble_adv", "SONOFF R5: DeviceId[%0X] DeviceIndex[%i] DeviceType[%X] SeqNum[%0X] RSSI[%i]", pR5->DeviceID, R5CI, pR5->DeviceType, pR5->SeqNum, x.get_rssi() );
pR5->PrevButtonID = pR5->ButtonID;
pR5->PrevButtonAction = pR5->ButtonAction;
ESP_LOGD("ble_adv", "SONOFF R5: Payload : [%08X] Magic[%08X]", pR5->Payload, DecodeMagic );
pR5->PayloadDecoded = pR5->Payload ^ DecodeMagic;
uint32_t xorsalt = pR5->PayloadDecoded & 0x000000FF;
ESP_LOGD("ble_adv", "SONOFF R5: PayloadDecoded: [%08X] xorsalt[%08X]", pR5->PayloadDecoded, xorsalt );
xorsalt = xorsalt | (xorsalt << 8) | (xorsalt << 16) | (xorsalt << 24);
pR5->PayloadDecoded = pR5->PayloadDecoded ^ xorsalt;
ESP_LOGD("ble_adv", "SONOFF R5: PayloadDecoded: [%08X] xorsalt[%08X]", pR5->PayloadDecoded, xorsalt );
if ( ( pR5->ButtonID > BUTTON_ID_MAX ) || ( pR5->ButtonAction > BUTTON_ACTION_MAX ) )
return;
ESP_LOGD("ble_adv", "SONOFF R5: Button[%d-%s] Prev[%d-%s] HoldComboEnable[%02X] HoldRepeatDisable[%02X]",
(pR5->ButtonID)+1, ButtonActionStr[pR5->ButtonAction], (pR5->PrevButtonID)+1, ButtonActionStr[pR5->PrevButtonAction], pR5->HoldComboEnable, pR5->HoldRepeatDisable );
if ( pR5->ButtonAction == BUTTON_ACTION_HOLD ) {
if ( ( pR5->ButtonID == pR5->PrevButtonID ) && ( pR5->PrevButtonAction == BUTTON_ACTION_HOLD ) && ( ( 0x01 << pR5->ButtonID ) & pR5->HoldRepeatDisable ) ) {
ESP_LOGD("ble_adv", "SONOFF R5: IN HOLD NOT PROCESSING" );
return;
}
if ( ( 0x01 << pR5->ButtonID ) & pR5->HoldComboEnable ) {
pR5->HoldComboEnable |= BUTTON_MASK_IN;
ESP_LOGD("ble_adv", "SONOFF R5: IN COMBO HoldComboEnable[%02X] Combo[%02X]", pR5->HoldComboEnable, ( 0x01 << pR5->ButtonID ) );
return;
}
}
char out[24];
if ( pR5->HoldComboEnable & BUTTON_MASK_IN ) {
pR5->HoldComboEnable &= ~BUTTON_MASK_IN;
sprintf( (char*) &out, ".%d-%s-%d-%s", (pR5->PrevButtonID)+1, ButtonActionStr[ BUTTON_ACTION_HOLD ], (pR5->ButtonID)+1, ButtonActionStr[pR5->ButtonAction] );
} else {
sprintf( (char*) &out, ".%d-%s", (pR5->ButtonID)+1, ButtonActionStr[pR5->ButtonAction] );
}
(pR5->pTextSensor)->publish_state( std::string( (char*) &out+1 ) );
(pR5->pTextSensor)->publish_state( std::string( (char*) &out ) );
}
return;
text_sensor:
- platform: template
id: R5_1
name: "R5 1"
- platform: template
id: R5_2
name: "R5 2"
- platform: template
id: R5_3
name: "R5 3"
Thank you everyone for your interests in SONOFF products, especially S-Mate and R5.
We are developing an eWeLink Remote add-on for Home Assistant OS which could import S-Mate, S-Mate 2, R5 to Home Assistant through MQTT, so you can use them in automations. We should be able to release it next week.
PS: We know this solution wonât work for everyone, but it should simplify the use of eWeLink Remote devices in HA a lot for many users.
Nice to hear. will it also support other SONOFF products?
This is an eWeLink Remote add-on, so itâs intended to support devices using the eWeLink Remote protocol from SONOFF and other brands.
If you want to import SONOFFâs Zigbee devices, you can use Home Assistantâs build-in ZHA or Zigbee2MQTT. If you want to import SONOFFâs Wi-Fi devices, I would suggest AlexxITâs SonoffLAN custom integration which does a pretty good job.
As many Home Assistant users have eagerly anticipated, the eWeLink-Remote Add-on has finally arrived! It supports devices such as R5, R5W, S-Mate, and S-Mate2, serving as eWeLink-Remote gateways.
Find more details HERE.
64-bit x86 architecture isnât currently supported, it should be any soon.
Creating separate automation for R5âs six buttons, each with three actions, isnât exactly the most exciting task. So, I made a blueprint to simplify it. Download the archive, extract it, and place the YAML file in the config folder under config/blueprints/automation/community.
sonoff_r5_ble_mqtt_button_matrix.7z (1.0 KB)
It provides full control over the Sonoff R5 BLE MQTT remote using MQTT Discovery-based device triggers. It supports all six buttons with three click types: Single, Double, and Long Click. To use it, your Sonoff R5 must be discovered via MQTT and expose device triggers.
Works well, but is it possible to get long press release event? Iâd like to control dimmer with Sonoff S-Mate2.
Thank you for trying out. Controlling dimmer with Long Press Release event is a meaningful use case.
Sadly, SONOFF S-Mate2 itself doesnât report Long Press Release event, and it also doesnât support OTA. So for the S-Mate2 in your hand, it canât.
Thanks. Do you recommend any other battery-powered device instead of S-Mate2 to control dimmer?
Waiting for the 64bits compatibility
I donât think SONOFF has a suitable battery-powered device that can meet your needs from what I know.
I have talked to SONOFFâs product manager about this feature request (support Long Press Release event in order to control dimmer). He is pleased to accept it but hasnât confirmed the release date. I will check with him again in a few days.
Hi everyone, thank you all for using eWeLink-Remote devices such as SONOFF R5 and S-Mate. We have released eWeLink-Remote Gateway add-on v0.2.0 for Home Assistant.
This time, eWeLink-Remote Gateway will not just working on HA over iHost, but also on other Home Assistant OS running on ARM64 and AMD64 devices.
Here is release note:
- Add-on adds support for x64 architecture
- Optimizes the default name display of the eWeLink-Remote sub-device entity
- After the eWeLink-Remote sub-device entity name is changed, the entity name associated in the automation will change accordingly (after the entity name is changed, the automation can run normally but the UI display will change to Unknown trigger. After re-saving, the UI display can return to normal)
Please take your time to try it out. As always, we are very grateful for any feedback.
Good, we need one also for Home Assistant Container running on docker. so, it should have an integration instead of addon.
Hi Michael,
Do you know if the ewelink remote add-on supports Bluetooth proxies?
I am using esp home Bluetooth proxies but I canât get my R5 to work through the proxies. I managed to pair it using the BT hardware on my HA host and the integration does pick up state changes when the R5 is in range of that device but not through the esp32 devices.
Hi, thank you for using eWeLink-Remote Gateway add-on.
We should be able to release a new version supporting Bluetooth Proxy at the end of this month. We are going to start dev version testing tomorrow. If you are interested in dev version testing, we would love to invite you.
For the details, please refer to eWeLink Meets Home Assistant: The Missing R5/S-Mate Link - HA over iHost - eWeLink Forum
Sure I can test it out.
Hi,
We have prepared a beta environment to try out the new Bluetooth Proxy support with the eWeLink-Remote Gateway add-on.
You can follow the steps below to install and test it. If you encounter any issues during setup or use, please feel free to share your feedback with us.
Please note:
-
The eWeLink-Remote Gateway add-on in this beta release is hosted in a personal repository for testing purposes.
-
In the future, this add-on will be merged into the official repository once the feature is stable.
Usage Steps
1. Install the ble_passthrough Custom Integration
-
Make sure HACS is installed.
-
Open HACS â top-right menu â Custom repositories.
-
Add the repository URL:
https://github.com/iHost-Open-Source-Project/ble_passthroughSelect Integration as the category.
-
Search for BLE Passthrough in HACS and install it.
-
After installation, add the following to your
configuration.yaml:ble_passthrough: -
Save the file and restart Home Assistant.
2. Install the eWeLink-Remote Gateway add-on
-
Go to Home Assistant â Settings â Add-ons â Add-on Store.
-
Click the top-right ⎠menu â Repositories.
-
Add the repository URL:
https://github.com/H1355054467/ha-test -
Go back to the Add-on Store, search for eWeLink-Remote Gateway, and install it.
-
Once installed, start the add-on and optionally enable Start on boot.
3. Verify Operation
-
Make sure your Bluetooth Proxy device is connected to Home Assistant and receiving BLE advertisements.
-
In Home Assistant Developer Tools â Events, listen to the
ble_passthrough.adv_receivedevent and confirm that advertisement data is updating. -
Start the eWeLink-Remote Gateway add-on and add/pair your sub-devices.
-
Operate the sub-device button (single-click/double-click/long-press) and confirm that automations are triggered.
