LogicMachine Forum
Curtain Dooya dt82tv - Printable Version

+- LogicMachine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Gateway (https://forum.logicmachine.net/forumdisplay.php?fid=10)
+--- Thread: Curtain Dooya dt82tv (/showthread.php?tid=6290)



Curtain Dooya dt82tv - Zhiger2003 - 02.02.2026

Hello. I need to connect Dooya DT82TV electric curtains to a controller and control them via the RS-485 protocol. There are several problems. First, the curtains understand HEX(photo is attached) rather than the usual 0/1 or true/false, so I probably need to write code for conversion and understanding. Second, I also need a JSON profile (also code) to connect each device via Modbus. To be honest, I don't know how to program or write scripts at all. I would be very grateful if there was ready-made code and instructions on how to do everything.


RE: Curtain Dooya dt82tv - Daniel - 02.02.2026

How do you knw that they are modbus? Do you have any documentation? You cannot haev modbus and custom RS485 script running paraleal.


RE: Curtain Dooya dt82tv - admin - 02.02.2026

You can't use a profile because this is a custom protocol not Modbus.

For testing purposes use an event script. Change baudrate, parity and command bytes as needed.
Code:
require('serial') port = serial.open('/dev/RS485-1', {   baudrate = 9600,   parity = 'even',   duplex = 'half' }) command = string.char(0x55, 0x01, 0x01, 0x03, 0x02, 0xF9, 0x01) port:write(command)

If the test script works then it can be modified to send different commands depending on the input value. 4-bit value should work (e.g. up/down/stop).


RE: Curtain Dooya dt82tv - Zhiger2003 - 04.02.2026

(02.02.2026, 13:01)admin Wrote: You can't use a profile because this is a custom protocol not Modbus.

For testing purposes use an event script. Change baudrate, parity and command bytes as needed.
Code:
require('serial') port = serial.open('/dev/RS485-1', {   baudrate = 9600,   parity = 'even',   duplex = 'half' }) command = string.char(0x55, 0x01, 0x01, 0x03, 0x02, 0xF9, 0x01) port:write(command)

If the test script works then it can be modified to send different commands depending on the input value. 4-bit value should work (e.g. up/down/stop).

Thanks its working. Now i have another question, is it possible to give it a range with event script?


RE: Curtain Dooya dt82tv - Daniel - 04.02.2026

What do you mean by range? Do you want to stop it after a time? If yes then you can add os.delay(10) on the ened and then send stop command. Make sure to set event script execution to First instance only.


RE: Curtain Dooya dt82tv - admin - 04.02.2026

Attach an event script to a 4-bit object. A different command is sent depending on the input value (stop, up or down).
Code:
value = event.getvalue() up = bit.band(value, 8) ~= 0 stop = bit.band(value, 7) == 0 if stop then   command = string.char(0x55, 0x01, 0x01, 0x03, 0x03, 0x38, 0xC1) elseif up then   command = string.char(0x55, 0x01, 0x01, 0x03, 0x02, 0xF9, 0x01) else   command = string.char(0x55, 0x01, 0x01, 0x03, 0x01, 0xB9, 0x00) end require('serial') port = serial.open('/dev/RS485-1', {   baudrate = 9600,   parity = 'even',   duplex = 'half' }) port:write(command)



RE: Curtain Dooya dt82tv - AEK - 05.02.2026

(04.02.2026, 04:42)Zhiger2003 Wrote:
(02.02.2026, 13:01)admin Wrote: You can't use a profile because this is a custom protocol not Modbus.

For testing purposes use an event script. Change baudrate, parity and command bytes as needed.
Code:
require('serial') port = serial.open('/dev/RS485-1', {   baudrate = 9600,   parity = 'even',   duplex = 'half' }) command = string.char(0x55, 0x01, 0x01, 0x03, 0x02, 0xF9, 0x01) port:write(command)

If the test script works then it can be modified to send different commands depending on the input value. 4-bit value should work (e.g. up/down/stop).

Thanks its working. Now i have another question, is it possible to give it a range with event script?

Hi, I made this integration/ see the scripts
This one make string comand to send to rs485 port (with CRC calculation)
Code:
function cmd_str_crc (t)     if type(t) ~= 'table' then       log('входная переменная не таблица')       return       end     x, y = CRC16(t)     --log(x,y)     table.insert(t,x)     table.insert(t,y)     --log(t)     s=''     for i = 1 , #t do       s = s..string.char(t[i])       end     return s     end     function And(num1,num2)       local tmp1 = num1       local tmp2 = num2       local ret = 0       local count = 0       repeat           local s1 = tmp1 % 2           local s2 = tmp2 % 2           if s1 == s2 and s1 == 1 then               ret = ret + 2^count           end           tmp1 = math.modf(tmp1/2)           tmp2 = math.modf(tmp2/2)           count = count + 1       until(tmp1 == 0 and tmp2 == 0)       return ret   end       function Xor(num1,num2)       local tmp1 = num1       local tmp2 = num2       local ret = 0       local count = 0       repeat           local s1 = tmp1 % 2           local s2 = tmp2 % 2           if s1 ~= s2 then               ret = ret + 2^count           end           tmp1 = math.modf(tmp1/2)           tmp2 = math.modf(tmp2/2)           count = count + 1       until(tmp1 == 0 and tmp2 == 0)       return ret   end       function bit_rshift(value,n)       value = math.modf(value / (2^n))       return value   end     function CRC16(arr)       local tmp = 0xffff       for i=1,#arr do           tmp = Xor(arr[i],tmp)           for j=1,8 do               local tmp1 = And(tmp,0x01)               if tmp1 == 1 then                   tmp = bit_rshift(tmp,1)                   tmp = Xor(tmp,0xa001)               else                   tmp = bit_rshift(tmp,1)               end           end       end       local ret1 = (tmp % 256)       local ret2 = math.modf( tmp / 256)       return ret1,ret2   end     function motor_up(cur_group, cur_adr)     cmd = {cur_group, cur_adr, 0x03,0x01}     s = cmd_str_crc (cmd)     return s     end       function motor_down(cur_group, cur_adr)     cmd = {cur_group, cur_adr, 0x03,0x02}     s = cmd_str_crc (cmd)     return s     end     function motor_stop(cur_group, cur_adr)     cmd = {cur_group, cur_adr, 0x03,0x03}     s = cmd_str_crc (cmd)     return s     end     function motor_set_address(cur_group, cur_adr, new_group, new_adr)     cmd = {cur_group, cur_adr,0x02, 0x00, 0x02, new_group, new_adr}     s = cmd_str_crc (cmd)     return s     end
this one shows how to send 1 command
Code:
require('user.motor') require('serial') port = serial.open('/dev/RS485-1', {   baudrate = 9600,   databits = 8,   stopbits = 1,   parity = 'none',   duplex = 'half' }) -- движение t = { 0x55, 0x03, 0x02, 0x03,0x01} s = cmd_str_crc (t) port:write(s) os.sleep(2) -- остановка t = { 0x55, 0x03, 0x02, 0x03,0x03} s = cmd_str_crc (t) port:write(s) --[[ -- запись адреса t = { 0x55, 0x00, 0x00, 0x02,0x02, 0x01, 0x02} s = cmd_str_crc (t) port:write(s) ]]
And this is a deamon for several motors
Code:
-- kotov motors deamon if not port then     require('serial')   port = serial.open('/dev/RS485-1', {     baudrate = 9600,     databits = 8,     stopbits = 1,     parity = 'none',     duplex = 'half'   })   end -- стуктура таблицы - id приводов BL - новер комнаты -номер привода = группа, номер cmds = {   'BL' = {     ['27'] ={       ['1'] = { 0x0C, 0x05 },       ['2'] = { 0x0C, 0x06 },       ['3'] = { 0x0C, 0x07 }     },     ['29'] ={       ['1'] = { 0x0D, 0x08 },       ['2'] = { 0x0E, 0x07 }     }   } }     if not lb then     require('user.motor')   lb = require('localbus').new(0.5)   function groupcallback(event)     pref, cmd = unpack(grp.alias(event.dst):split('-'))     val = event.getvalue()     typ, room , num =unpack(pref:split('.'))     if cmds[typ] then       all_adr = cmds[typ][room][num]       if cmd == 'short' then         direction = 0x03       elseif cmd == 'stop' then         if val then           direction =0x02         else           direction = 0x01         end       else         log('некорректное имя группового адреса', grp.alias(event.dst))       end       port:write(motor_move(cur_group, cur_adr, direction))         end     --lb:sethandler('groupupdate', groupcallack)   lb:sethandler('groupwrite', groupcallback)   --lb:sethandler('groupresponse', groupcallback) end lb:step() --log(lb)

GA names for  motors are next
BL.09.2-long
BL.09.2-stop