tjaworski / AceMagic-S1-LED-TFT-Linux

ACEMAGIC S1 Mini TFT/LCD and LED Control for Linux
GNU General Public License v3.0
100 stars 10 forks source link

Thanks for sharing the info!! Working on a python fork that can run for CasaOS #5

Closed venturem closed 4 months ago

venturem commented 4 months ago

Hello,

Thanks for sharing the details of LED and TFT. I was trying to get this working over last weekend with pyusb, but without success. If there is any hint you can share further please do so.

Is there a interrupt that needs to be called before writing to USB ? I can see some flicker on the LEDs ,but they do not stop or change theme or intensity as expected.

tjaworski commented 4 months ago

I'm not really a python guy. but do you have the byte stream you are sending? what pyusb function are you using to send the commands to the device?

venturem commented 4 months ago

I tried sending the below sequences.

led_rainbow=b'\xfa\x01\x01\x01\x00'
led_rainbow_cmd=[0xFA,0x02,0x01,0x01,0x00]

I've tried various values as per your tables - to no effect. First as a direct stream , and secondly as a sequence of bytes (since that's what Wireshark shows) No luck.

So I tried to be smart and send the whole thing via 4 fold loop

     command =  0xFA
     for theme in range(6,0,-1):
          for intensity in range(6,0,-1):
               for speed in range(6,0,-1):                    
                    checksum = command+intensity+speed
                    checksum_lsb = checksum & -checksum
                    print(f"{command} {theme} {intensity} {speed} {checksum} {checksum_lsb}")
                    ep.write(command.to_bytes(length=2,byteorder="big"))
                    ep.write(theme.to_bytes(length=2,byteorder="big"))
                    ep.write(intensity.to_bytes(length=2,byteorder="big"))
                    ep.write(speed.to_bytes(length=2,byteorder="big"))
                    ep.write(checksum_lsb.to_bytes(length=2,byteorder="big"))
                    sleep(0.1) 
                    c = input()

No luck there as well.

tjaworski commented 4 months ago

ok, for the LED strip, the commands I posted are not the usb byte stream. find the ch341 device serial port, you should see something like this in your syslog

 usbcore: registered new interface driver ch341
 usbserial: USB Serial support registered for ch341-uart
 ch341 1-7:1.0: ch341-uart converter detected
 usb 1-7: ch341-uart converter now attached to ttyUSB0

your /dev/ should have something like this:

crw-rw---- 1 root dialout 188, 0 Mar 26 17:31 /dev/ttyUSB0

open the /dev/ttyUSB0 like a serial port (using pySerial or like) at 9600 baud and write your byte stream.

venturem commented 4 months ago

Ok, my bad. I guess I was trying TFT method with LEDs. Thanks for the tip. I'll give this a shot and update here.

Once I get this reasonably steady, will post the code in forked repo so that the world can use this. I've been looking for this for too long. 😊

tjaworski commented 4 months ago

if you want to use it via usb, you will need to figure out which usb hid report/function the device needs. I can circle back to this later. I still need to find the fan rpm info after I make a first of my panel software.

tjaworski commented 4 months ago

ok, here are the scripts to turn on and off from command line using just stty and echo:

off:

stty -F /dev/ttyUSB0 cs8 raw -hupcl

/usr/bin/echo -n -e "\xfa" > /dev/ttyUSB0
/usr/bin/echo -n -e "\x04" > /dev/ttyUSB0
/usr/bin/echo -n -e "\x05" > /dev/ttyUSB0
/usr/bin/echo -n -e "\x05" > /dev/ttyUSB0
/usr/bin/echo -n -e "\x08" > /dev/ttyUSB0

stty -F /dev/ttyUSB0 hupcl

on:

stty -F /dev/ttyUSB0 cs8 raw -hupcl

/usr/bin/echo -n -e "\xfa" > /dev/ttyUSB0
/usr/bin/echo -n -e "\x01" > /dev/ttyUSB0
/usr/bin/echo -n -e "\x05" > /dev/ttyUSB0
/usr/bin/echo -n -e "\x05" > /dev/ttyUSB0
/usr/bin/echo -n -e "\x05" > /dev/ttyUSB0

stty -F /dev/ttyUSB0 hupcl
venturem commented 4 months ago

I've run into a completely different issue. My PC is not showing a /dev/USB device

DMESG shows below

[    4.532340] usbserial: USB Serial support registered for ch341-uart
[    4.532357] ch341 1-7:1.0: ch341-uart converter detected
[    4.532725] usb 1-7: ch341-uart converter now attached to ttyUSB0
[  125.769832] evict_inodes inode 00000000634150fc, i_count = 1, was skipped!
[  127.013414] veth3ccf80e: entered promiscuous mode
[  938.907201] ch341-uart ttyUSB0: ch341-uart converter now disconnected from ttyUSB0
[  938.907229] ch341 1-7:1.0: device disconnected

Seems that the device gets disconnected. I researched on this issue and brltty is not installed on this device.

sudo apt-get autoremove brltty
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Package 'brltty' is not installed, so not removed
0 to upgrade, 0 to newly install, 0 to remove and 147 not to upgrade.

Linux kernel is

Linux homeserver 6.5.0-14-generic #14~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Mon Nov 20 18:15:30 UTC 2 x86_64 x86_64 x86_64 GNU/Linux

lsmod shows that driver is loaded

lsmod | grep 341
ch341                  24576  0
usbserial              69632  1 ch341
vmwgfx                434176  0

This is all I could get to in the morning. I will do further digging after work.

tjaworski commented 4 months ago

have you rebooted since you tried to access the led strip via pyusb?

venturem commented 4 months ago

So you did trigger a thought when you spoke about reboot. I had rebooted earlier but had not looked at the BIOS. Seems that the bios setting for power usage needs to be "TURBO" else the USB peripherals are powered down if unused.

And so moving on from there on, I implemented a code based on PySerial, but still no luck.

import serial
from time import sleep
ser = serial.Serial('/dev/ttyUSB0',baudrate=9600, 
                    bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, 
                    stopbits=serial.STOPBITS_TWO, timeout=None, xonxoff=False, rtscts=True, 
                    write_timeout=None, dsrdtr=False, inter_byte_timeout=None)
print(ser.name)
for i in range(1,100):
    len = ser.write(b'\xfa\x04\x05\x05\x08')
    print(f"Bytes written : {len}")
    sleep(0.25)

ser.flush()
ser.close()

I'm getting a feeling that the hex codes are not standard across all devices and they may have changed either the value or sequence. Sadly the machine is headless, so I'll possibly have to attach a monitor , boot into Windoz and try Wireshark myself. I'll keep this thread posted about what I find.

PS : When I run the above loop, I do see a few times the LED sequence flips, so there seems to be some effect of sending data over serial. It just does not switch off as expected.

tjaworski commented 4 months ago

I noticed that you can't send the bytes sequentially too fast. send 1 byte at a time, and pause for 10ms. did you try the echo commands I posted above?

in my code, I just use a regular file I/o to write to /dev/ttyUSB0 one byte at a time, works just fine. (note I'm using writeFile() which basically will open, write, close for each byte. this also guarantees that each byte will be flushed.


function next_byte_write(device, buffer, index, size, fulfill) {

    if (index < size) {

        const _one_byte = new DataView(buffer.buffer, index, 1);

        fs.writeFile(device, _one_byte, 'binary', err => {

            // throttle down each byte write by 10ms
            setTimeout(() => {

                next_byte_write(device, buffer, 1 + index, size, fulfill);
            }, 10);
        });
    }
    else {
        fulfill();
    }
}

function set_off(device) {

    return new Promise((fulfill, reject) => {

        const _buffer = new Uint8ClampedArray(BUFFER_SIZE);
        const _header = new DataView(_buffer.buffer);

        _header.setUint8(0, SIGNATURE_BYTE);
        _header.setUint8(1, THEME_OFF);
        _header.setUint8(2, 0x05);
        _header.setUint8(3, 0x05);
        _header.setUint8(4, checksum(_header));

        next_byte_write(device, _buffer, 0, BUFFER_SIZE, fulfill);
    });
}
tjaworski commented 4 months ago

Here is the log from LedControl.exe, they basically open the device, and not sure why but they set the baud to 10000, do a few resets, and send the bytes 1 at a time (look at the IRP_MJ_WRITE section) and purge the buffers.


00000000    22:25:47.2699151        PnP Event: Connect  DOWN    0x00000000  5c 00 3f 00 3f 00 5c 00 55 00 53 00 42 00 23 00 56 00 49 00 …   \.?.?.\.U.S.B.#.V.I.…

00000001    22:26:29.4243603    +42.1544452 IRP_MJ_CREATE - process 5652 (LedControl.exe)   DOWN    0x00000000      
00000002    22:26:29.4249780    +0.0006177  IRP_MJ_CREATE   UP  0x00000000      

00000023    22:26:29.4252836    +0.0000032  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_BAUD_RATE    DOWN    0x00000000  10 27 00 00     .'..
00000024    22:26:29.4254613    +0.0001777  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_BAUD_RATE    UP  0x00000000

IOCTL_SERIAL_SET_BAUD_RATE: Set baud rate
  Baud Rate=10000

00000025    22:26:29.4254681    +0.0000068  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_RTS  DOWN    0x00000000      
00000026    22:26:29.4254686    +0.0000005  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_RTS  UP  0x00000000      

00000027    22:26:29.4254721    +0.0000035  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_DTR  DOWN    0x00000000      
00000028    22:26:29.4255199    +0.0000478  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_DTR  UP  0x00000000      

00000029    22:26:29.4255237    +0.0000038  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_LINE_CONTROL DOWN    0x00000000  00 00 08    ...
00000030    22:26:29.4255242    +0.0000005  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_LINE_CONTROL UP  0x00000000      

IOCTL_SERIAL_SET_LINE_CONTROL: Set line control
  WordLength=8
  StopBits=1 stop bit
  Parity=No parity

00000031    22:26:29.4255264    +0.0000022  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_CHARS    DOWN    0x00000000  1a 00 00 1a 11 13   ......
00000032    22:26:29.4255267    +0.0000003  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_CHARS    UP  0x00000000      

IOCTL_SERIAL_SET_CHARS: Set special characters
  EofChar=0x1a
  ErrorChar=0x0
  BreakChar=0x0
  EventChar=0x1a
  XonChar=0x11
  XoffChar=0x13

00000033    22:26:29.4255290    +0.0000023  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_HANDFLOW DOWN    0x00000000  00 00 00 00 40 00 00 00 36 43 00 00 36 43 00 00     ....@...6C..6C..
00000034    22:26:29.4256733    +0.0001443  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_HANDFLOW UP  0x00000000      

IOCTL_SERIAL_SET_HANDFLOW: Set handshake information
  ControlHandShake=0
  FlowReplace=64
  XonLimit=17206
  XoffLimit=17206

00000043    22:26:29.4256897    +0.0000030  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_BAUD_RATE    DOWN    0x00000000  10 27 00 00     .'..
00000044    22:26:29.4258310    +0.0001413  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_BAUD_RATE    UP  0x00000000      

IOCTL_SERIAL_SET_BAUD_RATE: Set baud rate
  Baud Rate=10000

00000045    22:26:29.4258347    +0.0000037  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_RTS  DOWN    0x00000000      
00000046    22:26:29.4258349    +0.0000002  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_RTS  UP  0x00000000      

00000047    22:26:29.4258386    +0.0000037  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_DTR  DOWN    0x00000000      
00000048    22:26:29.4258389    +0.0000003  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_DTR  UP  0x00000000      

00000049    22:26:29.4258416    +0.0000027  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_LINE_CONTROL DOWN    0x00000000  00 00 08    ...
00000050    22:26:29.4258419    +0.0000003  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_LINE_CONTROL UP  0x00000000      

IOCTL_SERIAL_SET_LINE_CONTROL: Set line control
  WordLength=8
  StopBits=1 stop bit
  Parity=No parity

00000051    22:26:29.4258437    +0.0000018  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_CHARS    DOWN    0x00000000  1a 00 00 1a 11 13   ......
00000052    22:26:29.4258440    +0.0000003  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_CHARS    UP  0x00000000      

IOCTL_SERIAL_SET_CHARS: Set special characters
  EofChar=0x1a
  ErrorChar=0x0
  BreakChar=0x0
  EventChar=0x1a
  XonChar=0x11
  XoffChar=0x13

00000053    22:26:29.4258457    +0.0000017  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_HANDFLOW DOWN    0x00000000  00 00 00 00 40 00 00 00 36 43 00 00 36 43 00 00     ....@...6C..6C..
00000054    22:26:29.4260220    +0.0001763  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_HANDFLOW UP  0x00000000      

IOCTL_SERIAL_SET_HANDFLOW: Set handshake information
  ControlHandShake=0
  FlowReplace=64
  XonLimit=17206
  XoffLimit=17206

00000055    22:26:29.4260312    +0.0000092  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_DTR  DOWN    0x00000000      
00000056    22:26:29.4260315    +0.0000003  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_DTR  UP  0x00000000      

00000065    22:26:29.4260464    +0.0000033  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_BAUD_RATE    DOWN    0x00000000  10 27 00 00     .'..
00000066    22:26:29.4261903    +0.0001439  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_BAUD_RATE    UP  0x00000000      

IOCTL_SERIAL_SET_BAUD_RATE: Set baud rate
  Baud Rate=10000

00000067    22:26:29.4261937    +0.0000034  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_RTS  DOWN    0x00000000      
00000068    22:26:29.4262406    +0.0000469  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_RTS  UP  0x00000000      

00000069    22:26:29.4262443    +0.0000037  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_DTR  DOWN    0x00000000      
00000070    22:26:29.4262445    +0.0000002  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_DTR  UP  0x00000000      

00000071    22:26:29.4262468    +0.0000023  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_LINE_CONTROL DOWN    0x00000000  00 00 08    ...
00000072    22:26:29.4262471    +0.0000003  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_LINE_CONTROL UP  0x00000000      

IOCTL_SERIAL_SET_LINE_CONTROL: Set line control
  WordLength=8
  StopBits=1 stop bit
  Parity=No parity

00000073    22:26:29.4262489    +0.0000018  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_CHARS    DOWN    0x00000000  1a 00 00 1a 11 13   ......
00000074    22:26:29.4262492    +0.0000003  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_CHARS    UP  0x00000000      

IOCTL_SERIAL_SET_CHARS: Set special characters
  EofChar=0x1a
  ErrorChar=0x0
  BreakChar=0x0
  EventChar=0x1a
  XonChar=0x11
  XoffChar=0x13

00000075    22:26:29.4262574    +0.0000082  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_HANDFLOW DOWN    0x00000000  00 00 00 00 00 00 00 00 36 43 00 00 36 43 00 00     ........6C..6C..
00000076    22:26:29.4264457    +0.0001883  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_HANDFLOW UP  0x00000000      

IOCTL_SERIAL_SET_HANDFLOW: Set handshake information
  ControlHandShake=0
  FlowReplace=0
  XonLimit=17206
  XoffLimit=17206

00000077    22:26:29.4264501    +0.0000044  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_RTS  DOWN    0x00000000      
00000078    22:26:29.4264503    +0.0000002  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_RTS  UP  0x00000000      

00000079    22:26:29.4264586    +0.0000083  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_TIMEOUTS DOWN    0x00000000  ff ff ff ff ff ff ff ff c8 00 00 00 00 00 00 00 00 00 00 00     ....................
00000080    22:26:29.4264590    +0.0000004  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_TIMEOUTS UP  0x00000000      

IOCTL_SERIAL_SET_TIMEOUTS: Set timeouts
  ReadIntervalTimeout=4294967295
  ReadTotalTimeoutMultiplier=4294967295
  ReadTotalTimeoutConstant=200
  WriteTotalTimeoutMultiplier=0
  WriteTotalTimeoutConstant=0

00000081    22:26:29.4266234    +0.0001644  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_WAIT_MASK    DOWN    0x00000000  fb 01 00 00     ....
00000082    22:26:29.4266242    +0.0000008  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_WAIT_MASK    UP  0x00000000      

IOCTL_SERIAL_SET_WAIT_MASK: Set current event mask
  WaitMask=RXCHAR: Any Character received, RXFLAG: Received certain character, CTS: CTS changed state, DSR: DSR changed state, RLSD: RLSD changed state, BREAK: BREAK received, ERR: Line status error occurred, RING: Ring signal detected

00000083    22:26:29.4269882    +0.0003640  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_QUEUE_SIZE   DOWN    0x00000000  00 10 00 00 00 08 00 00     ........
00000084    22:26:29.4269892    +0.0000010  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_QUEUE_SIZE   UP  0x00000000      

IOCTL_SERIAL_SET_QUEUE_SIZE: Set queue size
  InSize=4096
  OutSize=2048

00000086    22:26:29.4323204    +0.0050907  IRP_MJ_WRITE    DOWN    0x00000000  fa  .
00000088    22:26:29.4376825    +0.0052680  IRP_MJ_WRITE    DOWN    0x00000000  01  .
00000090    22:26:29.4428868    +0.0051073  IRP_MJ_WRITE    DOWN    0x00000000  03  .
00000092    22:26:29.4482400    +0.0052282  IRP_MJ_WRITE    DOWN    0x00000000  03  .
00000094    22:26:29.4537388    +0.0052331  IRP_MJ_WRITE    DOWN    0x00000000  01  .

00000096    22:26:29.4539554    +0.0001173  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_WAIT_MASK    DOWN    0x00000000  00 00 00 00     ....
00000098    22:26:29.4540515    +0.0000923  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_SET_WAIT_MASK    UP  0x00000000      

IOCTL_SERIAL_SET_WAIT_MASK: Set current event mask
  WaitMask=None

00000099    22:26:29.4540661    +0.0000146  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_DTR  DOWN    0x00000000      
00000100    22:26:29.4540671    +0.0000010  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_CLR_DTR  UP  0x00000000      

00000101    22:26:29.4540905    +0.0000234  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_PURGE    DOWN    0x00000000  0a 00 00 00     ....
00000102    22:26:29.4540915    +0.0000010  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_PURGE    UP  0x00000000      

IOCTL_SERIAL_PURGE: Purge requests
  Purge mask=RXABORT: Receive buffer, RXCLEAR: Write buffer

00000103    22:26:29.4540961    +0.0000046  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_PURGE    DOWN    0x00000000  05 00 00 00     ....
00000104    22:26:29.4541016    +0.0000055  IRP_MJ_DEVICECONTROL: IOCTL_SERIAL_PURGE    UP  0x00000000      

IOCTL_SERIAL_PURGE: Purge requests
  Purge mask=TXABORT: Read requests, TXCLEAR: Write requests

00000105    22:26:29.4541217    +0.0000201  IRP_MJ_CLOSE    DOWN    0x00000000      
00000106    22:26:29.4545320    +0.0004103  IRP_MJ_CLOSE    UP  0x00000000      
venturem commented 4 months ago

I tried various permutations and combinations with the timer to no avail.

import serial
from time import sleep
ser = serial.Serial('/dev/ttyUSB0',baudrate=9600, 
                    bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, 
                    stopbits=serial.STOPBITS_ONE, timeout=None, xonxoff=True, rtscts=False, 
                    write_timeout=None, dsrdtr=False, inter_byte_timeout=None)

print(ser.name)

sleep_timer=0.01
off_bytes=[0xfa,0x04,0x05,0x05,0x08]

for i in range(1,100):
    sleep(1)
    for byte in off_bytes:
        len = ser.write(byte)
        print(f"Bytes written : {len}")
        # sleep_timer-=0.0001
        sleep(sleep_timer)

ser.flush()
ser.close()

Definitely seems like I am missing something - and also tried the scripts once again, but did not work for me. Seems I need to do a trace to find the sequence on my machine.

venturem commented 4 months ago

Eureka !!!

So - after many tries there is light at end of the tunnel !! And its all a game of timings

The most important aspect of whole thing seems to be the timing interval of serial writes, and it has to be exactly 0.005 seconds.

How do I know - because of the trace below. I was fiddling with Wireshark but did not get very far, so instead downloaded another program (They're not sponsoring me ;) ) Free Device Monitoring Studio

Screenshot 2024-04-04 121211

So if you observe , all other timings are variable, but the timing for command sequence has interval of 5 msecs. That's the critical aspect. You change that interval and the code stops working !

Another tool that helped me mock the request is Open Serial Monitor https://github.com/gthvidsten/open-serial-port-monitor

Screenshot 2024-04-04 121245

AND finally the working code....

import serial
from time import sleep

s = serial.Serial('/dev/ttyUSB0', timeout=10,baudrate=10000)

print(s)
try:
    s.open()    
except:
    pass

print(s.writable())

data_off   = [b'\xfa', b'\x04' , b'\x03' , b'\x03' , b'\x04']
data_auto  = [b'\xfa', b'\x05' , b'\x03' , b'\x03' , b'\x05']
data_rainbow  = [b'\xfa', b'\x01' , b'\x03' , b'\x03' , b'\x01']
data_breath  = [b'\xfa', b'\x02' , b'\x03' , b'\x03' , b'\x02']
data_cycle  = [b'\xfa', b'\x03' , b'\x03' , b'\x03' , b'\x03']

data = data_off

for i in range(0,100):
    sleep(5)
    match(i%4):
        case 0 :
            print("OFF")
            data = data_off
        case 1 :
            print("Rainbow")
            data = data_rainbow
        case 2 :
            print("Breath")
            data = data_breath
        case 3 :
            print("Cycle")

            data = data_cycle
    for d in data:
        res = s.write(d)    
        sleep(0.005) # The critical part - who would have imagined !

s.flush()
s.close()

BEWARE - Code has no error handling. Device is hard coded - not self detected.

Again my sincere thanks to @tjaworski for his initial work and support. You rock bro!! Further code and updates will be posted on repo once I have some free time.

mreymann commented 4 months ago

I've just installed Ubuntu Noble Numbat (development branch) and can confirm that this works! Hooray!!! 👍 😃

venturem commented 4 months ago

Closing the issue !!! Hope this helps everyone out there.

mreymann commented 4 months ago

Can I re-open this issue?

@tjaworski said: crc = LSB(signature + theme + intensity + speed) How do I calculate the crc in Python?

venturem commented 4 months ago

@mreymann - I'll be posting the code in forked repo by next week. With error handling and human readable params. If you cant wait then just add up everything and do bitwise AND with 0x0f. You will get the CRC.

venturem commented 4 months ago

@mreymann - Python code added to forked repo. Cheers !