Nochmal zusammengefasst:
zuerst setzt man das Template.
Für einen 1Ch
{"NAME":"TX Ultimate 1","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,0,224,3232,0,480,3200,0,0,0,3840,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Backlog Pixels 28"}
2Ch
{"NAME":"TX Ultimate 2","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,225,224,3232,0,480,3200,0,0,0,3840,0,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Backlog Pixels 28"}
3Ch
{"NAME":"TX Ultimate 3","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,225,224,3232,0,480,3200,0,0,0,3840,226,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Backlog Pixels 28"}
4Ch
{"NAME":"TX Ultimate 4","GPIO":[0,0,7808,0,7840,3872,0,0,0,1376,0,7776,0,225,224,3232,0,480,3200,227,0,0,3840,226,0,0,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"Backlog Pixels 28"}
Danach erstelle ich unter Werkzeuge -> Dateisystem verwalten eine Datei mit dem Namen txultimate.be mit folgendem Inhalt:
class TXUltimate : Driver
static header = bytes('AA55')
var ser # create serial port object
# intialize the serial port, if unspecified Tx/Rx are GPIO 16/17
def init(tx, rx)
if !tx tx = 19 end
if !rx rx = 22 end
self.ser = serial(rx, tx, 115200, serial.SERIAL_8N1)
tasmota.add_driver(self)
end
def split_55(b)
var ret = []
var s = size(b)
var i = s-2 # start from last-1
while i > 0
if b[i] == 0xAA && b[i+1] == 0x55
ret.push(b[i..s-1]) # push last msg to list
b = b[(0..i-1)] # write the rest back to b
end
i -= 1
end
ret.push(b)
return ret
end
def crc16(data, poly)
if !poly poly = 0x1021 end
# CRC-16/CCITT-FALSE HASHING ALGORITHM
var crc = 0xFFFF
for i:0..size(data)-1
crc = crc ^ data[i] << 8
for j:0..7
if crc & 0x8000
crc = (crc << 1) ^ poly
else
crc = crc << 1
end
end
end
return crc & 0xFFFF
end
def encode(payload)
var msg_crc = self.crc16(bytes(payload)) # calc crc
var b = bytes('AA55') # add header
b += bytes(payload) # add payload
b.add(msg_crc, -2) # add calculated crc 2 bytes, big endian
return b
end
# send a string payload (needs to be a valid json string)
def send(payload)
print("TXU: Sent =", payload)
var payload_bin = self.encode(payload)
self.ser.write(payload_bin)
log("TXU: Sent = " + str(payload_bin), 2)
end
# read serial port
def every_50ms()
if self.ser.available() > 0
var msg = self.ser.read() # read bytes from serial as bytes
import string
if size(msg) > 0
# print("TXU: Raw =", msg)
if msg[0..1] == self.header
var lst = self.split_55(msg)
for i:0..size(lst)-1
msg = lst[i]
print(msg)
var event = ""
var params = ""
if msg[3] == 0x02 # 02 signifies a touch event
# print('Touch event')
if msg[4] == 0x01 # data lenght 1 is a press
if msg[5] < 0x0B
event = "Short"
params = ',"Channel":' + str(msg[5])
print('Short press zone:', msg[5])
elif msg[5] == 0x0B
event = "Multi"
print('Multi press')
elif msg[5] > 0x0B
event = "Long"
params = ',"Channel":' + str(msg[5]-16)
print('Long press zone:', msg[5])
end
elif msg[4] == 0x02 # data length 3 is a release
event = "Touch"
params = ',"Channel":' + str(msg[6])
print('Touch event:', msg[5], 'pos:', msg[6])
if msg[5] != 0x00
event = "Dash"
params = ',"From":' + str(msg[6]) + ',"To":' + str(msg[5])
print('Mini swipe channel', msg[5], '->', msg[6])
end
elif msg[4] == 0x03 # data lenght 1 is a swipe
if msg[5] == 0x0C
event = "Swipe right"
params = ',"From":' + str(msg[6]) + ',"To":' + str(msg[7])
print('Swipe left-right', msg[6], '->', msg[7])
elif msg[5] == 0x0D
event = "Swipe left"
params = ',"From":' + str(msg[6]) + ',"To":' + str(msg[7])
print('Swipe right-left', msg[6], '->', msg[7])
end
end
var jm = string.format("{\"TXUltimate\":{\"Action\":\"%s\"%s}}",event,params)
tasmota.publish_result(jm, "RESULT")
end
end
end
end
end
end
end
txu=TXUltimate()
und damit diese Datei auch beim Start geladen wird, noch eine weitere Datei mit dem Namen autoexec.be mit dem Inhalt
load("txultimate.be")
Dann geht es weiter mit den Rules. Ich lasse ganz bewusst Rule1 von dieser Seite weg, da sie bei mir ziemliches Chaos verursacht. Bei Mehrchannelschaltern werden z.b. die Channel wild durcheinander geschaltet. Außerdem habe ich bei mir das Backlight per Script geschaltet. Es schaltet sich abends an und morgens aus. Das funktioniert mit der Rule auch nicht, da es sich dann bei jedem Tastendruck an- bzw ausschaltet.
Damit der Touch die Relais schaltet, benutze ich folgende Rule von @Dieter_P
rule2 On TXultimate#Action$!Touch do break
rule2 + On TXUltimate#Channel=1 do power1 toggle endon
rule2 + On TXUltimate#Channel=<xxx> do power1 toggle endon
rule2 + On TXUltimate#Channel=5 do power2 toggle endon
rule2 + On TXUltimate#Channel=<xxx> do power2 toggle endon
rule2 + On TXUltimate#Channel=10 do power3 toggle endon
rule2 + On TXUltimate#Channel=<xxx> do power3 toggle endon
Hier im Beispiel für einen 3Ch-Schalter. Wobei ich aber nicht einfach die Channel übernehme, sondern sie selber austeste. Da man sowieso in der Konsole ist, muss man hier nur auf das Touch an der gewünschten Stelle drücken und die Konsole gibt den Channel aus. Den übernehme ich dann in die Rule, hier gekennzeichnet mit dem <xxx>.
Das wars eigentlich auch schon. Der Schalter sollte nun funktionieren.