-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4c74b19
Showing
10 changed files
with
638 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
install: | ||
cp dbus/org.fanatec.CSLElite.conf /etc/dbus-1/system.d/ | ||
cp dbus/org.fanatec.CSLElite.service /usr/share/dbus-1/system-services/ | ||
cp dbus/fanatec-input.py /usr/bin/ | ||
# cp org.fanatec.policy /usr/share/polkit-1/actions/ | ||
|
||
uninstall: | ||
rm /etc/dbus-1/system.d/org.fanatec.CSLElite.conf | ||
rm /usr/share/dbus-1/system-services/org.fanatec.CSLElite.service | ||
rm /usr/bin/fanatec-input.py | ||
# rm /usr/share/polkit-1/actions/org.fanatec.policy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Dbus interface and tools to communicate with the LEDs and display exposed by the [hid-fanatecff](https://github.com/gotzl/hid-fanatecff) driver. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#!/usr/bin/python | ||
|
||
from pydbus.generic import signal | ||
import glob | ||
|
||
def get_sysfs_base(PID): | ||
return glob.glob("/sys/module/hid_ftec/drivers/hid:ftec_csl_elite/0003:0EB7:%s.*"%(PID))[0] | ||
|
||
class CSLElite(object): | ||
""" | ||
<node> | ||
</node> | ||
""" | ||
def __init__(self): | ||
pass | ||
|
||
|
||
class CSLElitePedals(object): | ||
""" | ||
<node> | ||
<interface name='org.fanatec.CSLElite.Pedals'> | ||
<property name="Load" type="i" access="readwrite"> | ||
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/> | ||
</property> | ||
</interface> | ||
</node> | ||
""" | ||
|
||
def __init__(self): | ||
pass | ||
|
||
def get_sysfs(self, name): | ||
return "%s/%s"%(get_sysfs_base('6204'), name) | ||
|
||
@property | ||
def Load(self): | ||
return int(open(self.get_sysfs('load'),'r').read()) | ||
|
||
@Load.setter | ||
def Load(self, value): | ||
return int(open(self.get_sysfs('load'),'w').write(str(value))) | ||
|
||
PropertiesChanged = signal() | ||
|
||
|
||
class CSLEliteWheel(object): | ||
""" | ||
<node> | ||
<interface name='org.fanatec.CSLElite.Wheel'> | ||
<property name="Display" type="i" access="write"> | ||
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/> | ||
</property> | ||
<property name="RPM" type="ab" access="write"> | ||
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="true"/> | ||
</property> | ||
</interface> | ||
</node> | ||
""" | ||
|
||
def __init__(self): | ||
pass | ||
|
||
def get_sysfs(self, name): | ||
return "%s/%s"%(get_sysfs_base('0005'), name) | ||
|
||
def get_sysfs_rpm(self): | ||
sysfs_base = get_sysfs_base('0005') | ||
return "%s/leds/0003:0EB7:0005.%s::RPM"%(sysfs_base,sysfs_base.split(".")[-1]) | ||
|
||
@Display.setter | ||
def Display(self, value): | ||
return int(open(self.get_sysfs('display'),'w').write(str(value))) | ||
|
||
@RPM.setter | ||
def RPM(self, values): | ||
return list(map(lambda i: open('%s%i/brightness'%(self.get_sysfs_rpm(), i[0] + 1),'w').write('1' if i[1] else '0'), enumerate(values))) | ||
|
||
PropertiesChanged = signal() | ||
|
||
|
||
if __name__ == "__main__": | ||
from pydbus import SystemBus | ||
from gi.repository import GLib | ||
|
||
bus = SystemBus() | ||
r = bus.publish('org.fanatec.CSLElite', CSLElite(), | ||
('Pedals', CSLElitePedals()), | ||
('Wheel', CSLEliteWheel())) | ||
try: | ||
loop = GLib.MainLoop() | ||
loop.run() | ||
except (KeyboardInterrupt, SystemExit): | ||
print("Exiting") | ||
except Exception as e: | ||
raise e | ||
finally: | ||
r.unpublish() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<!DOCTYPE busconfig PUBLIC | ||
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN" | ||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> | ||
<busconfig> | ||
|
||
<policy context="default"> | ||
<!-- Allow everyone to talk to main service --> | ||
<allow send_destination="org.fanatec.CSLElite"/> | ||
<allow send_destination="org.fanatec.CSLElite.Pedals"/> | ||
<allow send_destination="org.fanatec.CSLElite.Wheel"/> | ||
</policy> | ||
|
||
<policy user="root"> | ||
<!-- Allow root to own the name on the bus --> | ||
<allow own="org.fanatec.CSLElite"/> | ||
<allow own="org.fanatec.CSLElite.Pedals"/> | ||
<allow own="org.fanatec.CSLElite.Wheel"/> | ||
</policy> | ||
</busconfig> | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[D-Bus Service] | ||
Name=org.fanatec.CSLElite | ||
Exec=/usr/bin/fanatec-input.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import socket | ||
import struct | ||
import select | ||
import threading | ||
|
||
class AcClient(threading.Thread): | ||
UDP_IP = "127.0.0.1" | ||
UDP_PORT = 9996 | ||
|
||
HANDSHAKE = 0 | ||
SUBSCRIBE_UPDATE = 1 | ||
SUBSCRIBE_SPOT = 2 | ||
DISMISS = 3 | ||
|
||
def __init__(self, ev): | ||
threading.Thread.__init__(self) | ||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | ||
self.sock.setblocking(0) | ||
self.ev = ev | ||
|
||
@staticmethod | ||
def client_data(sock, operation): | ||
sock.sendto(bytearray([ | ||
0x0,0x0,0x0,0x2, # android phone | ||
0x0,0x0,0x0,0x0, # version | ||
operation,0x0,0x0,0x0, | ||
]), (AcClient.UDP_IP, AcClient.UDP_PORT)) | ||
|
||
def run(self): | ||
import fanatec_led_server | ||
while not self.ev.isSet(): | ||
# handshake | ||
AcClient.client_data(self.sock, AcClient.HANDSHAKE) | ||
|
||
# response | ||
ready = select.select([self.sock], [], [], 2) | ||
if not ready[0]: | ||
# print("Timeout connecting to AC server") | ||
continue | ||
data, addr = self.sock.recvfrom(2048) | ||
|
||
# confirm | ||
AcClient.client_data(self.sock, AcClient.SUBSCRIBE_UPDATE) | ||
|
||
timeout_cnt = 0 | ||
while not self.ev.isSet(): | ||
ready = select.select([self.sock], [], [], .5) | ||
if not ready[0]: | ||
print('Timeout waiting for AC server data,', timeout_cnt) | ||
timeout_cnt+=1 | ||
if timeout_cnt>10: | ||
print('Quitting AC server') | ||
break | ||
continue | ||
|
||
timeout_cnt = 0 | ||
data, addr = self.sock.recvfrom(2048) | ||
speed_kmh = int(struct.unpack('<f', data[8:12])[0]) | ||
rpm = int(struct.unpack('<f', data[68:72])[0]) | ||
gear = int.from_bytes(data[76:80], byteorder='little') | ||
|
||
fanatec_led_server.set_leds([False if rpm<i*1000 else True for i in range(9)]) | ||
fanatec_led_server.set_display(speed_kmh) | ||
# print(speed_kmh, rpm, gear) | ||
|
||
AcClient.client_data(self.sock, AcClient.DISMISS) | ||
fanatec_led_server.clear() | ||
self.sock.setblocking(1) | ||
|
||
if __name__ == "__main__": | ||
try: | ||
ev = threading.Event() | ||
ac = AcClient(ev) | ||
ac.start() | ||
ac.join() | ||
|
||
except (KeyboardInterrupt, SystemExit): | ||
print("Exiting") | ||
except Exception as e: | ||
raise e | ||
finally: | ||
ev.set() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import socket | ||
import threading | ||
import time | ||
|
||
|
||
class F12020Client(threading.Thread): | ||
UDP_IP = "127.0.0.1" | ||
UDP_PORT = 20777 | ||
|
||
def __init__(self, ev): | ||
threading.Thread.__init__(self) | ||
self.sock = sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | ||
self.sock.bind((F12020Client.UDP_IP, F12020Client.UDP_PORT)) | ||
self.sock.setblocking(0) | ||
self.ev = ev | ||
|
||
def run(self): | ||
import fanatec_led_server | ||
while not self.ev.isSet(): | ||
try: | ||
data, addr = self.sock.recvfrom(2048) | ||
pkt_id = data[5] | ||
# only use telemetry packets | ||
if pkt_id != 6: continue | ||
car_idx = data[22] | ||
|
||
# start car delemetry data byte 24 | ||
# size of car delemetry data 58 | ||
car_telem_start = 24 + car_idx*58 | ||
speed = int.from_bytes(data[car_telem_start:car_telem_start+2], byteorder="little") | ||
gear = int(data[car_telem_start+15]) | ||
rpm = int.from_bytes(data[car_telem_start+16:car_telem_start+18], byteorder="little") | ||
suggestedGear = int(data[-1]) | ||
|
||
fanatec_led_server.set_leds([False if (rpm-5000)<i*1000 else True for i in range(9)]) | ||
fanatec_led_server.set_display(speed) | ||
# print(speed, rpm, gear) | ||
except: | ||
time.sleep(.5) | ||
|
||
if __name__ == "__main__": | ||
try: | ||
ev = threading.Event() | ||
f1 = F12020Client(ev) | ||
f1.start() | ||
f1.join() | ||
|
||
except (KeyboardInterrupt, SystemExit): | ||
print("Exiting") | ||
except Exception as e: | ||
raise e | ||
finally: | ||
ev.set() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#!/usr/bin/python3 | ||
import glob | ||
from pydbus import SystemBus | ||
|
||
bus = SystemBus() | ||
wheel = bus.get('org.fanatec.CSLElite', '/org/fanatec/CSLElite/Wheel') | ||
|
||
def set_leds(values): | ||
global wheel | ||
wheel.RPM = values | ||
|
||
def set_display(value): | ||
global wheel | ||
wheel.Display = value | ||
|
||
# clear leds and display | ||
def clear(): | ||
set_leds([False]*9) | ||
set_display(-1) | ||
|
||
|
||
if __name__ == "__main__": | ||
import threading | ||
from ac import AcClient | ||
from f1_2020 import F12020Client | ||
|
||
try: | ||
ev = threading.Event() | ||
# start f1 server | ||
f1 = F12020Client(ev) | ||
f1.start() | ||
|
||
# start ac client | ||
ac = AcClient(ev) | ||
ac.start() | ||
|
||
# run as long as the client threads are running, or CTRL+C | ||
print("Running ...") | ||
f1.join() | ||
ac.join() | ||
|
||
except (KeyboardInterrupt, SystemExit): | ||
print("Exiting") | ||
except Exception as e: | ||
raise e | ||
finally: | ||
ev.set() | ||
clear() | ||
|
Oops, something went wrong.