sensus icon indicating copy to clipboard operation
sensus copied to clipboard

Covert from miniDSP format to broadlinh base64

Open bobmorane06 opened this issue 11 months ago • 15 comments

Bonjour Pascal, I'm trying to convert codes in 32 bits hexadecimal to base64 for a broadlink device.

The codes for miniDSP devices are here https://support.minidsp.com/support/solutions/articles/47001137495-ir-commands-for-minidsp-products

Does sensus support this translation, are the codes in NEC format?

I managed to enter the codes in "command (hex)" and to get a broadlink B64 result if I click on Preset in the Commands section, but the code doesn't work with my Broadlink rm4 mini in Home Assistant (it sends a command, but not the proper one). I know that the rm4 works, since if I learn a command via Home Assistant then I can play it back, but there are commands in the URL above that don't have a button on the original remote.

What would the b64 be for the command 35 CA 22 DD ? What should I configure in your tool ?

I could move this question to Discussions, but thought it may help people with the same setup as mine to have it here.

bobmorane06 avatar Apr 03 '25 12:04 bobmorane06

Hi Bob,

First impression is that the page you're linking contains erroneous instructions about how to interpret their own code.

Explanation:

Using command 35 CA 40 BF, they say:

0x35 is the Address
0xCA is the Complement of the Address (i.e. 0xFF - 0x35 = 0xCA)	
0x40 is the Command	
0xBF is the Complement of the Command (i.e. 0xFF - 0x40 = 0xBF)

But if you enter 35 CA 40 BF in Sensus Command (Hex) field and click the left arrow, you'll see this is detected as an encoded NEC command, short command being ac02.

If you want an explanation, from there you can click Presets button in Commands panel, then hit Convert. Once done, go down to Raw analysis, and hit Read raw. Scroll down to read the binary:

> Nec encoding detected  with shift value: 0/1 *00110101 11001010 + 01000000 10111111*
hex: *** 35ca 40bf *** - short: < ac02 >

Byte 1 is indeed invert of byte 2, same for next pair. Meaning values #2 and #4 are checksum that can be ignored. Bytes 1 and 3 indeed have values 0x35 and 0x40, but they have to be read LSB first, meaning from right to left.

10101100 for byte 1 (address) = 0xAC
01000000 for byte 3 (command) = 0x02

Solution (I hope):

Enter the commands they give in , i.e. 35 CA 0E F1 in Sensus Command (Hex) field, click Presets button in Commands panel, then hit Convert - you should get the correct Broadlink code, and also see the corresponding short command detected, ac70 in this example - provided that a 38029Hz signal is expected (else you can adjust this as well). For safety you can add a repeat value of 1 or 2 in the Broadlink panel.

Broadlink B64 Command 35 CA 0E F1 with 2 repeats for miniDSP devices:

JgJGAAABJwAFxRISEhISNxI3EhISNxISEjcSNxI3EhISEhI3EhISNxISEhISEhISEhISNxI3EjcSEhI3EjcSNxI3EhISEhISEjcNBQ==

Let me know if this helps, Pascal

pasthev avatar Apr 03 '25 14:04 pasthev

Thanks for the super quick response Pascal, the code you generated works. However, I am not able to replicate and I get instead: JgJKAAABJwAFxRISEhISNxI3EhISNxISEjcSNxI3EhISEhI3EhISNxISEhISEhISEhISNxI3EjcSEhI3EjcSNxI3EhISEhISEjc3AAEnDQUAAAAAAAAAAAAAAAA=

What am I doing wrong ?

For my tests, do you mind translating 35 CA 22 DD?

Image

bobmorane06 avatar Apr 03 '25 15:04 bobmorane06

edited

Ah, glad this worked!

All seems good in your screenshot, although I guess you took it after another conversion, since the Commands shown values are no longer exactly the ones from the presets.

However, your code JgJKAAABJwAFxRISEhISNxI3EhISNxISEjcSNxI3EhISEhI3EhISNxISEhISEhISEhISNxI3EjcSEhI3EjcSNxI3EhISEhISEjc3AAEnDQUAAAAAAAAAAAAAAAA= seems valid, even if values slightly differ from mine. You don't have to worry about the slight number differences, due to roundups following encoding back and forth. i.e. 552 like in your screenshot or 562 like the default Preset are microseconds values: no consequences at such a tiny scale.

Result for 35 CA 22 DD:

JgJKAAABJwAFxRISEhISNxI3EhISNxISEjcSNxI3EhISEhI3EhISNxISEhISEhI3EhISEhISEjcSEhI3EjcSEhI3EjcSNxISEjc3AAEnDQUAAAAAAAAAAAAAAAA=

Image

pasthev avatar Apr 03 '25 15:04 pasthev

Merci. Unfortunately I was wrong, your code didn't work, when sending any command converted by Sensus, it actually runs the previous valid command sent by the real remote. (which as a coincidence was the same as the hexa code used :-))

How about looking at a command that I know works ? This is a command learnt by Home Assistant from the real remote that actually works, it is supposed to be 35 CA 06 F9 on the miniDSP page JgBYAAABJZMUNhMSFDUTEhQ2EzYUERQTEhITNxISFDYUERQRFDUTNxQREzYTNxMSExITEhQRFBEUNhQRFBEUNhQ1FDYTNhM3EwAFHgABJ0kTAAxXAAEnSRMADQU=

When I paste it into the Broadlink B64 and hit convert, it does not give me a NEC command. Is the raw analysis giving information to understand the problem?

bobmorane06 avatar Apr 03 '25 16:04 bobmorane06

OK, it was my second assumption - I was typing it when I received your message saying it worked... When they say in their example that 0x35 is the Address and 0x40 is the Command, they're mistaken about the LSB First encoding...

They know their commands for sure 3540 but when they filled this page, they tried to extend the NEC long commands and got it wrong in their table, as confirmed by the example they're giving.

Your Broadlink working command sends ac53 609f, which is 3506 NEC short. So, in their (wrong) list of code, you have to take only bytes 1 and 3, which are the real Shorts.

i.e. 35 CA 40 BF is not a valid NEC command. Short is 3540 (bytes 1 & 3), and the valid resulting NEC command really is ac53 02fd

Now for a detail that may be of importance later on : add a 0 to the GAP in Commands Panel, make it 90000 to add a long silence after the command.

Example for Standby command 3540 with two repeats:

JgJKAAABJwAFxRI3EhISNxISEjcSNxISEhISEhI3EhISNxISEhISNxI3EhISEhISEhISEhISEjcSEhI3EjcSNxI3EjcSNxISEjc3AAuLDQUAAAAAAAAAAAAAAAA=

Image

pasthev avatar Apr 03 '25 17:04 pasthev

Merci bcp Pascal, mais ça ne marche tjrs pas ! :-( The example you gave me didn't work.

Can we learn more from the working code e.g. JgBYAAABJZMUNhMSFDUTEhQ2EzYUERQTEhITNxISFDYUERQRFDUTNxQREzYTNxMSExITEhQRFBEUNhQRFBEUNhQ1FDYTNhM3EwAFHgABJ0kTAAxXAAEnSRMADQU= ?

I pasted it in the field "Broadlink B64", then clicked "Read Raw" and replicated what I could find for header, gap etc (without understanding them), but nothing worked. What are the signals (1) and (2), they look like a header without data??

b64 converted from 3506 Image

Command converted from working b64 code

Image

bobmorane06 avatar Apr 03 '25 17:04 bobmorane06

OK, I think I see where the problem lies. Do exactly the same, but after setting Presets, change for these values:

Header: 9000, 4500 Ptrail: 562 Gap: 40000

These are the (rounded) values that you get from your working signal when you click convert in Broadlink B64 panel.

Broadlink B64 for command 3506:

JgJIAAABJ5MSNxISEjcSEhI3EjcSEhISEhISNxISEjcSEhISEjcSNxISEjcSNxISEhISEhISEhISNxISEhISNxI3EjcSNxI3EgAFIQ0FAAAAAAAAAAAAAAAAAAA=

Image

3540:

JgJIAAABJ5MSNxISEjcSEhI3EjcSEhISEhISNxISEjcSEhISEjcSNxISEjcSNxISEhISEhISEhISNxISEhISNxI3EjcSNxI3EgAFIQ0FAAAAAAAAAAAAAAAAAAA=

3522:

JgJIAAABJ5MSNxISEjcSEhI3EjcSEhISEhISNxISEjcSEhISEjcSNxISEjcSNxISEhISEhISEhISNxISEhISNxI3EjcSNxI3EgAFIQ0FAAAAAAAAAAAAAAAAAAA=

Will make my day if it works :) Pascal

pasthev avatar Apr 03 '25 18:04 pasthev

Nope 😭

What is weird is that the miniDSP device receives a command, but it is the same as what was last successfully used. I am wondering if this could be a limitation of Home Assistant, i.e. something in the B64 code that makes it re-send the last one ?

Is there an easy way to read the code emitted by the Broadlink device? An android camera? No. 60 fps is not enough for 40 MHz.. I have an oscilloscope but would need an IR receiver IC...

These are the ones learnt by HA:

    "SHD Power": {
      "mute": "JgBYAAABJpMUNRQREzcTEhM2FDYUERMSFRATNxMSEzYTEhMTEzYTNhQSExITNhM3ExITEhMSExITNxM2ExITEhQ2EzYTNxM2FAAFHQABKUcUAAxVAAEpSBMADQU=",
      "power": "JgBcABQ1ExIVNRMSFDUTNxMSExITEhU1ExITNhMSFBETNxM2FBETExQRFBETEhMSEzYTEhQ2EzYTNxM3EzYUNRMTEzYUAAUdAAEpRxQADFYAAShIEwAMVwABJkkTAA0F",
      "volume up": "JgBYAAABJ5IUNRQREzcUERM2FDYTEhMSExITNxMSEzYTEhMSFDYTNhMTEzYUERQ2ExITEhQRFRAUNRQSEjcTEhQ2EzYUNhM2EwAFHgABKUcUAAxXAAEmSRMADQU=",
      "volume down": "JgBQAAABJ5EUNRMSEzcTEhQ1FDYTEhMSExIUNhMSEzYUERMSFDYUNRM3ExITEhQ2ExIUERQRFBEUERM3EzYTEhM3FDUTNxM2FAAFHgABKEcUAA0F",
      "right": "JgBYAAABJpIUNhMSEzYTEhM3EzcTEhMSFBETNhQRFDYUERQRFDUUNhMSEzcTEhQRExITEhM2FBITNhMSEzcUNRQ2EzYUERQ2EwAFHgABKEgTAAxWAAEnSRMADQU=",
      "left": "JgBYAAABJpIUNhMSEzcTEhM2FDYUERQRExITNhMTEzYTEhMSEzcTNhM3FBETEhUQExITEhU1ExITEhM2EzcTNhQ2EzYTExI3EwAFHgABKUcUAAxWAAEmSRMADQU=",
      "play pause": "JgBQAAABJZMUNhMSEzYUERM3FDUTExQRExITNhQREzcUERMSEzcTNhQ2EzYTEhMSFRATEhQ2ExITEhMSEzcTNhQ2EzYUERM3EwAFHgABJ0kTAA0F",
      "dirac": "JgBYAAABJZMUNhMSFDUTEhQ2EzYUERQTEhITNxISFDYUERQRFDUTNxQREzYTNxMSExITEhQRFBEUNhQRFBEUNhQ1FDYTNhM3EwAFHgABJ0kTAAxXAAEnSRMADQU=",
      "source": "JgBYAAABJpMTNhMSEzYUERQ2FDUUERMSFBITNhQRFDYUERMSFDUUNhMSFDUUNhQ1ExMTEhQRFBETNhQRFBITEhM2FDYUNRQ2FAAFHQABJ0kUAAxWAAEnSBQADQU=",
      "preset 1": "JgBYAAABJpIUNhMSFDYTEhM2FDYUERMSExITNhQRFDYUERQRFDYUNRQ2FBEUERMSExITEhMSFBEUERQ2FDUUNhQ1EzcUNRQ2FAAFHQABKEgUAAxWAAEmSRQADQU=",
      "preset 2": "JgBUABwtFBEVNBQRFTUUNRQSFRAVEBM2FBEVNRMSFRATNxM2FBEUNhMSFRAVEBMSFRATEhU1FBEVNBQ2FDUUNhM2FDYUAAUdAAEpRxQADFUAASdJFAANBQ==",
      "preset 3": "JgBgAAABJ5EUNhQRFTQUEhM2EzcTEhQRExITNhQRFTUUERMSEzcTNhM3ExIVNBQRExITExQRFRATEhU0ExITNxQ1FDYUNRQ2FAAFHQABKUcTAAxWAAEpRxQADFUAASpHFAANBQ==",
      "preset 4": "JgBYAAABJ5EUNhUQFTQWEBU0FTUVEBUQFRAVNBUQFjQVEBUQFTUVNBUQFRAVEBUQFREVEBUQFRAVNBU1FTQVNRU0FDYVNBQ2EwAFHgABKUcUAAxVAAEpRxQADQU="

bobmorane06 avatar Apr 03 '25 19:04 bobmorane06

At this point I'd suspect something coming from HA... But weird thing is that all your learnt signals include a gap with a long high at the end of the sequence, which I've never seen.

Things you can try:

Set repeat code to 0, in case HA would have a problem with Broadlink built-in repeats, i.e.

Command 3540 JgJIAAABJ5MSNxISEjcSEhI3EjcSEhISEhISNxISEjcSEhISEjcSNxISEjcSNxISEhISEhISEhISNxISEhISNxI3EjcSNxI3EgAFIQ0FAAAAAAAAAAAAAAAAAAA= becomes JgBIAAABJ5MSNxISEjcSEhI3EjcSEhISEhISNxISEjcSEhISEjcSNxISEjcSNxISEhISEhISEhISNxISEhISNxI3EjcSNxI3EgAFIQ0FAAAAAAAAAAAAAAAAAAA=

Try sending your exact working sequence without the repeated low high trailers:

JgBIAAABI5ETNhMSEzMTEhM2EzYTERMTEhITNxISEzYTERMREzMTNxMREzYTNxMSExITEhMRExETNhMRExETNhMzEzYTNhM3EwANBQ0FAAAAAAAAAAAAAAAAAAA=

pasthev avatar Apr 03 '25 19:04 pasthev

None of these codes worked unfortunately.

Try sending your exact working sequence without the repeated low high trailers:

How did you manipulate the code to include / exclude the repeated low high trailers?

Is there a way to modify a code learnt, e.g. use the b64 of 0x350c to get the b64 of 0x3506?

bobmorane06 avatar Apr 03 '25 20:04 bobmorane06

You can easily manipulate the numbers in the Raw panel - in there you'll be able to see the direct result of the Commands panel parameters, eg. zero, one, ptrail, etc.

re:ways to read the IR codes, I've always used the broadlink itself like you did, but for RF, I built a small and very simple circuit with a cheap IR receiver circuit and an audio jack... very fun to do ; you record an audio sample when you press the remote, then display the wav or mp3 in Audacity on any audio editor, and there you can see the signal just like Sensus does (with a bit more noise, but easy to read). I guess this is also doable with an IR receiver.

pasthev avatar Apr 03 '25 20:04 pasthev

Thanks Pascal.

OK, I got it working with another tool, irgen https://github.com/elupus/irgen. I'm sharing if it helps you or others.

For 0x3522 I had to use decimal 53 0 35

  • 53 (0x35) → Address (device ID).
  • 0 → Subdevice (some NEC variants need this, and it may default to 0x00 if not specified).
  • 35 (0x22) → Function (command).
pipx install irgen
irgen -i necx1 -d 53 0 34 -o broadlink_base64

Outcome: JgBGAAABKJQSNxISEjcSEhI3EjcSEhISEhISEhISEhISEhISEhISEhISEjcSEhISEhISNxISEhISNxISEjcSNxI3EhISNxI3EjcAAA==

C'était un peu tiré par les cheveux !

Could I have achieved the same with sensus ?

PS: wow for the analysis in audacity ! 😁

bobmorane06 avatar Apr 03 '25 21:04 bobmorane06

By the way tank you so much for your help, without you I wouldn't have understood to use only bytes 1 and 3 from the miniDSP page, and I learned a lot 🙏

bobmorane06 avatar Apr 03 '25 21:04 bobmorane06

Wow ! This is simply a NEC Extended protocol, in which you no longer use byte 2 as a checksum for byte 1, but use it to extend the address, sometimes called "subdevice". Meaning that the MiniDSP documentation is even more wrong than we thought, as the codes they're proposing are NEC standard with byte 2 as checksum.

NEX Extended is is properly detected by Sensus. If you enter your Broadlink B64 string, hit Convert and then Read Raw, you get:

> Nec-Extended encoding detected with shift value: 0/2 *10101100 00000000 + 01000100 10111011* - hex: *** ac00 44bb *** - short: < 0035 + 22 >

Image

To give you a clearer explanation, you're not adding a zero when you type decimal 53 0 35 in irgen, but rather telling it to use NEC Extended encoding, where byte 2 will hold the MSB of the address rather than the checksum. Because the address is 0x35, second byte will be 00. If address was 0x0f35 In NEC Extended, second byte would hold the inverted value of 0x0f. NEC Extended allows to use a total 65536 Address, minus all those where byte 2 is the invert of byte 1, belonging to NEC standard encoding.

To answer your question, Sensus can read and convert NEC Extended, but not from the Commands panel, which is a shame - I have to use a checkbox, which will have the same effect as adding flag 0 in irgen. For now, what you can do is type your Short command, ie 3520, hit the right arrow, and in the result, ac53 04fb, 0x53 being the checksum of 0xac, just replace it with 00: ac00 04fb. Then set presets and hit convert. If you click Read Raw, you'll see:

> Nec-Extended encoding detected with shift value: 0/1 *10101100 00000000 + 00000100 11111011* - hex: *** ac00 04fb *** - short: < 0035 + 20 >

Since Byte 2 isn't complement of byte 1, Sensus is assuming NECx encoding.

Native support of NECx is already implemented with a checkbox in my other application, IRTuya:

Image

I'm giving you these explanations about NECx because there seems to be something wrong, and your issue might not be fully solved yet. i.e., the working code you gave me earlier:

JgBYAAABJZMUNhMSFDUTEhQ2EzYUERQTEhITNxISFDYUERQRFDUTNxQREzYTNxMSExITEhQRFBEUNhQRFBEUNhQ1FDYTNhM3EwAFHgABJ0kTAAxXAAEnSRMADQU=

is NEC standard, not NECx. Was it for the same device ?

Also, the string you got from irgen is lacking ptrail / gap: in NEC protocol, you're supposed to send a long silence, more or less equivalent to the length of the address+command (the 40000 value I asked you to add earlier) - this is probably an additional argument in your irgen command, but IR is usually quite tolerant with this, except if you send the signal repeatedly.

Hope this helps, adding the NECx checkbox to my checklist :) Pascal

pasthev avatar Apr 04 '25 16:04 pasthev

Thank you so much for the deep dive Pascal.

I'm confused:

The command that I gave you, JgBYAAABJZMUNhMSFDUTEhQ2EzYUERQTEhITNxISFDYUERQRFDUTNxQREzYTNxMSExITEhQRFBEUNhQRFBEUNhQ1FDYTNhM3EwAFHgABJ0kTAAxXAAEnSRMADQU= that works and that is NEC standard, is obtained through a learning command sent by Home Assistant via the Broadlink RM4 Mini. It is 35 CA 06 F9 on the miniDSP site, or 35 06.

If I convert 3506 with irgen irgen -i necx1 -d 53 0 06 -o broadlink_base64 then I get JgBGAAABKJQSNxISEjcSEhI3EjcSEhISEhISEhISEhISEhISEhISEhISEjcSNxISEhISEhISEhISNxISEhISNxI3EjcSNxI3EjcAAA== , which your tool decodes as NECx

But both work when transmitted.

Note: With https://irtuya.streamlit.app/, for the conversion to work I had to enter 35 00 06, not 35 06.

I'm sharing just for your information, there is no more action required for me, as using irgen allowed me to have all commands that I needed.

Encore merci.

bobmorane06 avatar Apr 07 '25 10:04 bobmorane06