Skip to content

Instantly share code, notes, and snippets.

@simeon-walker
Forked from andrewcchen/tuya_ir_encode.js
Created May 9, 2024 22:08
Show Gist options
  • Save simeon-walker/d2daf2d5017bea93c37c61534903984a to your computer and use it in GitHub Desktop.
Save simeon-walker/d2daf2d5017bea93c37c61534903984a to your computer and use it in GitHub Desktop.
Encode an NEC IR command into code for Tuya ZS06/ZS08/TS1201
/*
Encode an NEC IR command into code for Tuya ZS06/ZS08/TS1201
Usage: encode_nec("<four bytes in hex, two bytes of address followed by two bytes of command>")
If your address and/or command is just one byte (8 bits), append the complement of the byte after it to make it two bytes.
Example:
encode_nec("04fb08f7") // encodes nec address 0x04 and command 0x08
See:
https://www.sbprojects.net/knowledge/ir/nec.php
https://www.zigbee2mqtt.io/devices/ZS06.html
https://github.com/Koenkk/zigbee2mqtt/issues/11633
Tuya ZS06 uses a custom encoding of ir codes. I figured enough of the encoding to generate arbitary ir codes, but there are additional encoding features to save bytes that I haven't figured out.
The encoding is base64 encoding of any number of concatenated command blocks, where each block is:
- 1 byte of [length]-1 (length <= 32 bytes is supported)
- [length] number of bytes of little endian 16 bit integers
- Each integer describes the length of time in microseconds to keep the tramsitter's current on/off state, before flipping
The initial state is on, so the first 16 bit integer describes on time, the second off time, the third on time again, etc.
*/
function encode_nec(hex) {
function le(x) {
x = x & 0xffff;
return [ x & 0xff, x >> 8 ];
}
let output = [ 4-1, ...le(9000), ...le(4500) ];
for (const x of Buffer.from(hex, 'hex')) {
output.push(32-1);
for (let i = 0; i < 8; i++) {
output.push(...le(560));
if (x & (1 << i)) {
output.push(...le(2250-560));
} else {
output.push(...le(1125-560));
}
}
}
output.push(2-1, ...le(560));
return Buffer.from(new Uint8Array(output)).toString('base64');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment