Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decode Smartwares SH5-TDR-F remote #360

Open
akemper opened this issue Aug 22, 2020 · 23 comments
Open

Decode Smartwares SH5-TDR-F remote #360

akemper opened this issue Aug 22, 2020 · 23 comments

Comments

@akemper
Copy link

akemper commented Aug 22, 2020

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
Copy link

Cilyan commented Sep 10, 2020

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:
#135 (comment)

@Cilyan
Copy link

Cilyan commented Sep 10, 2020

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
Copy link
Author

akemper commented Sep 11, 2020

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
Copy link

Cilyan commented Sep 15, 2020

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
  • 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.

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
Copy link

Cilyan commented Sep 15, 2020

@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.

@Cilyan
Copy link

Cilyan commented Sep 15, 2020

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.
  • 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).
  • 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.

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
Copy link
Author

akemper commented Sep 15, 2020

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
Copy link
Author

akemper commented Sep 15, 2020

@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
Copy link

Cilyan commented Sep 15, 2020

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
Copy link
Author

akemper commented Sep 15, 2020

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
Copy link
Author

akemper commented Sep 15, 2020

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
Copy link

Cilyan commented Sep 25, 2020

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 1technophile#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
Copy link
Author

akemper commented Sep 25, 2020

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

@Cilyan
Copy link

Cilyan commented Sep 25, 2020

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

  • I discovered that the 65th bit was important (see previous message). That it is a 0 or 1 is not important. Fortunately the code from 1technophile includes a condition where is the length is 64, two 0s will be added the first repetition and two 1s the following repetition. This is commented as "needed for KeeLoq", but this is actually important for us too. There is no way to change this behaviour depending on the protocol, at least at the moment.
  • Concerning the pulse lengths, I played a bit around and discovered that the plugs very pretty lenient about them. In the end, I opted for the values reported by the domadoo website, although they were a bit away from mine too. I guess the clock in these products is very cheap. My biggest concern was a bout the 240µs of low state expected for 1, but in the end, the fact that the high and low states are 275µs works just fine. How would you find a common divisor for 275 and 240 anyway unless you select a ridiculously small pulse length value? We could also argue that instead of writing down multiple of pulse length, it would be much more flexible to write the values in µs in the protocol, the code would not change a lot. But it would clearly introduce too much change for my goals, and needed to be strongly motivated. In the end, the plugs work with the current way the protocols are described, so why go for a more complex solution right now?
  • And finally, the first "1" is the headerFactor, this is a new feature of this version of 1technophile, and specifies how many times the header bit shall be sent. So 1 pulse of 275 high and 2750 low (instead of 2550 low in the protocol spec from domadoo) before sending the code. I did not really understand the difference between the preamble and the header, specially why the preambleFactor is divided by 2, "rounded half up", but I saw that some protocols needs both, so... there probably is a reason somewhere.

@akemper
Copy link
Author

akemper commented Sep 28, 2020

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
Copy link

Cilyan commented Sep 28, 2020

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
Copy link
Author

akemper commented Sep 28, 2020

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
Copy link

Cilyan commented Sep 28, 2020

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
Copy link
Author

akemper commented Sep 29, 2020

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
Copy link
Collaborator

1technophile commented Sep 30, 2020

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
Copy link
Author

akemper commented Oct 4, 2020

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
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants