sui77 / rc-switch

Arduino lib to operate 433/315Mhz devices like power outlet sockets.
1.91k stars 659 forks source link

Decode Smartwares SH5-TDR-F remote #360

Open akemper opened 4 years ago

akemper commented 4 years ago

Hi,

I want to expand sources to decode also signals from SH5-TDR-F remote with self-learning receivers. I started capturing the received signal. It consists of eight identical, sequential bursts as illustrated in the attached picture. While the overall timing and leading sync pulse are pretty obvious, I don't understand how the individual bits itself are encoded.

The total of 32, constant-length low periods suggest 32 bits being encoded in every burst, but I have no clue how this maps to either one, two or three toggling pulses in-between these. Furthermore, there is always one more "one-toggle" as compared to the "three-toggles", thus ensuring a constant length of the overall burst. Anybody having either a good hint or even better understanding how the individual bits might be encoded?

Burst

Thx Andreas

Cilyan commented 4 years ago

Hello there! Just go interested in this too. I'll be posting my scans later for comparison, the environment I'm in right now is very noisy (probably due to my alarm system). I was thinking that maybe the encoding was a kind of "tristate", with actually 0, 1 and F being encoded? (This is a theory, totally out of the blue, just thinking). image Here is button 1 ON of the remote. Mine would read 1122 1232221232131322222222222132212 Your would read 1122 312321321312232222222222131321 Shame that for a start, the number of groups is not the same... But at least it seems to start with this "122", I've got some samples where the first "1" is not there and the low state duration between it and the rest of the code is globally very random, so I wonder if that could be just an artifact? This trace look similar: https://github.com/sui77/rc-switch/issues/135#issuecomment-297411246

Cilyan commented 4 years ago

Looks like simple Intertechno on 64 bits in the end... If you read french: https://blog.domadoo.fr/guides/principe-du-protocole-homeeasy/ I'll check tomorrow.

akemper commented 4 years ago

Hi Cilyan,

thank you very much for the valuable hints! From what I've seen so far I fully agree with you. Two things I didn't have in mind so far were:

  1. "0" and "1" being endcoded with different total lengths, thus giving the constant length "gaps" in-between the pulses
  2. Each individual bit being encoded again into two, thus ending up with a total of 2 32 = 64 bits or even 2 36 (DIM extension) = 72 bits.

With this in the end also this remote might use a flavor of the Intertechno V3 protocol, as described in FHEM post.

Thx Andreas

Cilyan commented 3 years ago

Good, so I was able to confirm that the protocol is very like the one describe on the domadoo website, and that they call "HomeEasy" protocol.

The frames are coded like this:

RRRRRRRRRRRRRRRRRRRRRRRRRRFNBBBB

Then, there is a "second pass", where 0 is converted to 01 and 1 to 10.

Decoding a received frame is done backward, but the most valuable information is the remote ID, which is the same in every frames.

Now, however, I still need to workout the protocol timings. For the moment, that doesn't work. I used the branch from @atsage (https://github.com/atsage/rc-switch) to be able to send 32 bits of code (64 pulses) and the two protocol timings I tested were

{ 110, {  2, 23 }, {  2,  3 }, {  2, 12 }, false }

and

{ 275, {  1,  9 }, {  1,  1 }, {  1,  5 }, false }

but neither work well. On some very rare occasions, when there is noise on the frequency, I manage to switch off the plug, which lets me think I'm not far away, but this is totally unreliable.

Cilyan commented 3 years ago

@akemper If I try to match your graph (by eye, it's not easy), these are the parameters I find:

I hope it matches something on your side.

Cilyan commented 3 years ago

Some more good news.

Some bad news... RCSwitch is unable to send such a protocol. First, because the delay between retries cannot be modified, second because RCSwitch sends the sync bit after the code, not before, and finally because we need to send 65 pulses in addition to sync pulse, which is larger than even what the unsigned long long allows.

To support this protocol, one would first need to change RCSwitch to allow more than 64 pulses to be sent (there is code lying around with implementation over an array of bytes, but not always very tidy), then have an option to send the sync pulse at the beginning of the frame, and finally have an option to introduce delay between retries.

I'll think about that, but seeing how the project deals globally with PRs, I will probably stay on a solution tailored to my needs, which will probably be to pre-compute the pulses on the computer and send then to the arduino over serial, which the arduino will then apply.

Here is a basis ready to be modified for such a job: https://github.com/raimohanska/intertechno-433-on-off/blob/master/intertechno-433-on-off.ino

akemper commented 3 years ago

Good, so I was able to confirm that the protocol is very like the one describe on the domadoo website, and that they call "HomeEasy" protocol. I agree that this is most likely at least one of the known names for this protocol.

The frames are coded like this:

RRRRRRRRRRRRRRRRRRRRRRRRRRFNBBBB
* `RRRRRRRRRRRRRRRRRRRRRRRRRR` is the remote control ID, on 26 bits.

* `F` is the "group flag" that tells if all devices should react (ALL ON/ALL OFF buttons).

* `N` is the ON/OFF, with `1` is ON, `0` is OFF.

* `BBBB` is the button number, which is also 1 (0b0001) when the group flag is set.

I have two of these remotes and also took traces from different keys there. When I have some more time (most likely during next weekend) I will further verify this, while I'm pretty sure these general assumptions are correct from what I've seen already.

Then, there is a "second pass", where 0 is converted to 01 and 1 to 10.

Yes, this is a bit tricky. I started using https://github.com/1technophile/rc-switch as being part of OpenMQTTGateway, It does not yet seem to support a second pass, but at least looks like being 64bit-enabled from what I've seen so far.

Decoding a received frame is done backward, but the most valuable information is the remote ID, which is the same in every frames.

Now, however, I still need to workout the protocol timings. For the moment, that doesn't work. I used the branch from @atsage (https://github.com/atsage/rc-switch) to be able to send 32 bits of code (64 pulses) and the two protocol timings I tested were

{ 110, {  2, 23 }, {  2,  3 }, {  2, 12 }, false }

and


{ 275, {  1,  9 }, {  1,  1 }, {  1,  5 }, false }
I spent some time during the afternoon to further drilldown into my traces. From there my "decoding string" would be finally { 260, {  1,  10 }, {  1,  1 }, {  1,  5 }, false }
akemper commented 3 years ago

@akemper If I try to match your graph (by eye, it's not easy), these are the parameters I find:

* remote: 62020608

* SINGLE (no group)

* ON

* Button nb 4

I hope it matches something on your side.

Could well be, but unfortunately I don't remember which trace I attached. What kind of encoding did you choose for the remote ID? 26bits to eight digits suggests octal base?

Cilyan commented 3 years ago

Could well be, but unfortunately I don't remember which trace I attached. What kind of encoding did you choose for the remote ID? 26bits to eight digits suggests octal base?

This is just decimal. If corresponds to "11101100100101110000000000" in binary. But maybe I made a mistake while reading the bits from the trace.

akemper commented 3 years ago

Some more good news.

* The plug needs a last "0" 65th pulse, or that won't work. It doesn't seem to change and in my tests for the moment, it is always 0.

Very good point, which I noticed during the afternoon as well, due to counting a total of 66 pulses. What I did not yet check / understand if this might be some kind of preamble or extended sync. Mentioning the idea of a preamble is mainly due to additional functionality in the above mentioned rc-switch fork for the gateway. I did not yet understand what this is about, but could well be that this belongs to the Keeloq routines included in the fork.

* The precision of the pulse length is not very important, I managed to make it work with a "basis" of 220µs to 275µs. However, it is not to the point that the necessary sync bit at the start can be replaced by a 1. The low state delay is too different between both (2550µs for sync, 1330µs for 1).

I didn't test this myself yet, but just saw sometimes a bit of jitter in my traces. Especially the sync was not always a clear {1,10} but sometimes at least closer to {1,9}. However, from comparing sample and averaging over all bursts I'm quite confident regarding the schema / timing posted below.

* There is a necessary delay between retries (the remote sends the same command several times at each press of the button and the separation time between these copies is important). Below 10000µs (10ms), the plug doesn't always react and the probability of reaction decreases as we lower this separation time.

In total I've always seen eight identical bursts. Furthermore, I found that the low interval between two bursts is 41 times low level, i.e. from the falling edge of the 65th bit to the rising edge of the sync pulse. The mentioned fork of rc-switch supports in addition a guard interval, hoping that this can be used to separate repetitive bursts.

Some bad news... RCSwitch is unable to send such a protocol. First, because the delay between retries cannot be modified, second because RCSwitch sends the sync bit after the code, not before, and finally because we need to send 65 pulses in addition to sync pulse, which is larger than even what the unsigned long long allows.

As mentioned I want to go into more detail there with the enhanced version of rc-switch, hoping that most of the points might be covered there. Thus good to have at least a more detailed understanding what is required in addition.

To support this protocol, one would first need to change RCSwitch to allow more than 64 pulses to be sent (there is code lying around with implementation over an array of bytes, but not always very tidy), then have an option to send the sync pulse at the beginning of the frame, and finally have an option to introduce delay between retries.

I'll think about that, but seeing how the project deals globally with PRs, I will probably stay on a solution tailored to my needs, which will probably be to pre-compute the pulses on the computer and send then to the arduino over serial, which the arduino will then apply.

I have a similar thinking there, i.e. I would prefer to merge this into the official repo. But let's see how to get it working at all.

Here is a basis ready to be modified for such a job: https://github.com/raimohanska/intertechno-433-on-off/blob/master/intertechno-433-on-off.ino

akemper commented 3 years ago

Some more good news.

* The plug needs a last "0" 65th pulse, or that won't work. It doesn't seem to change and in my tests for the moment, it is always 0.

Very good point, which I noticed during the afternoon as well, due to counting a total of 66 pulses. What I did not yet check / understand if this might be some kind of preamble or extended sync. Mentioning the idea of a preamble is mainly due to additional functionality in the above mentioned rc-switch fork for the gateway. I did not yet understand what this is about, but could well be that this belongs to the Keeloq routines included in the fork.

* The precision of the pulse length is not very important, I managed to make it work with a "basis" of 220µs to 275µs. However, it is not to the point that the necessary sync bit at the start can be replaced by a 1. The low state delay is too different between both (2550µs for sync, 1330µs for 1).

I didn't test this myself yet, but just saw sometimes a bit of jitter in my traces. Especially the sync was not always a clear {1,10} but sometimes at least closer to {1,9}. However, from comparing sample and averaging over all bursts I'm quite confident regarding the schema / timing posted below.

* There is a necessary delay between retries (the remote sends the same command several times at each press of the button and the separation time between these copies is important). Below 10000µs (10ms), the plug doesn't always react and the probability of reaction decreases as we lower this separation time.

In total I've always seen eight identical bursts. Furthermore, I found that the low interval between two bursts is 41 times low level, i.e. from the falling edge of the 65th bit to the rising edge of the sync pulse. The mentioned fork of rc-switch supports in addition a guard interval, hoping that this can be used to separate repetitive bursts.

Some bad news... RCSwitch is unable to send such a protocol. First, because the delay between retries cannot be modified, second because RCSwitch sends the sync bit after the code, not before, and finally because we need to send 65 pulses in addition to sync pulse, which is larger than even what the unsigned long long allows. As mentioned I want to go into more detail there with the enhanced version of rc-switch, hoping that most of the points might be covered there. Thus good to have at least a more detailed understanding what is required in addition. To support this protocol, one would first need to change RCSwitch to allow more than 64 pulses to be sent (there is code lying around with implementation over an array of bytes, but not always very tidy), then have an option to send the sync pulse at the beginning of the frame, and finally have an option to introduce delay between retries. I'll think about that, but seeing how the project deals globally with PRs, I will probably stay on a solution tailored to my needs, which will probably be to pre-compute the pulses on the computer and send then to the arduino over serial, which the arduino will then apply. I have a similar thinking there, where I would prefer to merge this into the official repo. But let's see how to get it working at all. Here is a basis ready to be modified for such a job: https://github.com/raimohanska/intertechno-433-on-off/blob/master/intertechno-433-on-off.ino

Cilyan commented 3 years ago

I made it work, at least for my plugs, it could be nice if you can confirm this works for you too.

You can check integration of the feature in https://github.com/1technophile/rc-switch/pull/2 (if Florian does answer, I don't know if he is willing to/has time to work on this), or the feature is already available in https://github.com/Cilyan/rc-switch (be sure to be on dev branch, I followed 1technophile's branching).

akemper commented 3 years ago

Thanks for going ahead there. Hopefully I will find time again to verify during the upcoming weekend.

Cilyan commented 3 years ago

I saw you edited away your questions but anyway, here are some answer. Someone may find them useful as they are legitimate

akemper commented 3 years ago

I've added your proposed timing to the rc-switch library included in latest OpenMQTTGateway 0.9.5 Unfortunately for receiving at least it does not work yet, i.e it randomly decodes to either protocol version 25 or 29, but not 35 as it should. Will continue with this during the week and compare transmitted signals from hand transmitter to the ones from rc-switch.

Cilyan commented 3 years ago

I have to admit, I did not test the reception as the library and examples were not yet configured to do that. At least, you need to change the number of states RCSwitch saves before decoding, so you can get the full 64 bits of code. At least 1 sync bit + 64 bits data + 1 bit of closing, two states each => 132. https://github.com/1technophile/rc-switch/blob/385a7e065f225c159bcd0d1b6278495423a1bd23/src/RCSwitch.h#L62 But then, I'm not sure that the decoding/guessing algorithm is well suited for this kind of code.

akemper commented 3 years ago

Receiving for me is even more interesting, since to my knowledge at least my shutter switches can learn also other (simpler) codes transmitted. But I try to go into more detail during the week and keep you updated.

Cilyan commented 3 years ago

I will have to give it a try also in the coming weeks (yeah, unfortunately not sooner). But my guess is that at the moment the decoding logic is too trivial. It was okay to decode a few protocols that were distinct from each other. But now that it handles many more protocols, it needs a better heuristic to decide which protocol suits the best. At the moment, apart from some special paths, the first protocol that matches the first pulses is used.

I would recomand to at least change the logic to try all protocols so your receiving logic behind can pickup the one that suits its needs. But this will not be done with just a few lines changed.

akemper commented 3 years ago

Thanks for the hints regarding further code changes. I fully agree there with you and plan to continue in the evening. During this week at least I will focus on just getting Smartwares packets sent by the gateway. Soon as I find time in the future I'll dig deeper into receiving as well and potentially hack rc-switch specifically for this purpose.

1technophile commented 3 years ago

it randomly decodes to either protocol version 25 or 29, but not 35

I suspect that the uC as difficulty with this numerous protocols or maybe there is an issue in the code, it would be interesting to remove a part of them for your tests. I encountered that when integrating the self-powered doorbell DG-SD10, I had to remove a part of the protocols to have it decoded.

akemper commented 3 years ago

Couple of minor updates after spending additional hours during the weekend. The proposed timing { 275, 0, { 0, 0 }, 1, { 1, 10 }, { 1, 1 }, { 1, 5 }, false, 37 } for Smartwares self-learning remote worked for me as well. Still I did some quite detailed comparison between traces recorded from my two remotes vs. what comes out of rc-switch. Afterall I found { 260, 0, { 0, 0 }, 1, { 1, 10 }, { 1, 1 }, { 1, 5 }, false, 36 } to be a perfect match, when transmitting in total 66 pulses (1 sync + 64 bits + 1 padding). To transmit only one instead of two padding bits I commented adding 66th bit for 64-bit codes. With this exact timing, I tried again decoding a received signal, after largely increasing RCSWITCH_MAX_CHANGES. Still receiving didn't work at all, i.e. it always comes down to either protocol #25 or protocol #29. Since there aren't any obvious similarities nor the decoded delay matches well the one from protocol definition, obviously this doesn't work at all. Even more, when commenting all other protocol definitions except for the expected one, no valid data gets received at all. So obviously the decoding needs major changes / improvements to work as expected. I might put some more effort there during the next weeks and months, including shortening the transmitted code, but for now leaving it to transmit-only operation.

louisnichols commented 1 year ago

Hi!

I've read this thread and noticed that success has been limited. Being a noob, I don't think I'd be able to replicate all the code changes that have been discussed here and the limitations would be showstoppers for me anyway.

But perhaps I can help in a different way. I found a reference on a German forum to this thread from another (dead) forum (wayback machine link):

https://web.archive.org/web/20190316180849/https://www.sweetpi.de/blog/329/ein-ueberblick-ueber-433mhz-funksteckdosen-und-deren-protokolle

At some point in the thread, someone makes this comment (Google translate)

Hello,
the problem is solved.
Smartwares uses roughly protocol 3

The times are 235 µs and 1175 µs
The code is made up as follows
Init: 235 high 2560 low
Code: like protocol 3
Sync: 235 high ca 10000 low

The chip used (also Elro) is SYN520
[http://www.dexsilicium.com/SYN520R.pdf](https://web.archive.org/web/20190316180849/http://www.dexsilicium.com/SYN520R.pdf)

Could this help?

Apologies if this is info that has already been known here.

krzyspx commented 1 year ago

here is the solution https://github.com/krzyspx/Sender_Smartwares_sh4_for_esp8266- https://github.com/krzyspx/Monitor_Smartwares_sh4_for_esp8266