I am trying to control a cricket scoreboard with an app, the app sends the variables & someone has already written an integration that works.
The data is sent in the format FTS123 which means FieldingTeamScore was 123
The integration then converts this in to a variable called Target which is what the scoreboard (a Pi) expects
However, we need the target variable that’s sent to the Pi to be FTS+1 as the target required would be one more that the other team’s score
I would imagine this is a fairly simple adjustment but I have no idea where to start.
Any help would be greatly appreciated
Here’s the integration code (apologies if I should have attached this somehow but I couldn’t see where)
import serial, time
import sys
import dbus, dbus.mainloop.glib
from gi.repository import GLib
from example_advertisement import Advertisement
from example_advertisement import register_ad_cb, register_ad_error_cb
from example_gatt_server import Service, Characteristic
from example_gatt_server import register_app_cb, register_app_error_cb
BLUEZ_SERVICE_NAME = 'org.bluez'
DBUS_OM_IFACE = 'org.freedesktop.DBus.ObjectManager'
LE_ADVERTISING_MANAGER_IFACE = 'org.bluez.LEAdvertisingManager1'
GATT_MANAGER_IFACE = 'org.bluez.GattManager1'
GATT_CHRC_IFACE = 'org.bluez.GattCharacteristic1'
UART_SERVICE_UUID = '5a0d6a15-b664-4304-8530-3a0ec53e5bc1'
UART_RX_CHARACTERISTIC_UUID = 'df531f62-fc0b-40ce-81b2-32a6262ea440'
LOCAL_NAME = 'BT-Scoreboard'
mainloop = None
# Set all the Scoreboard variables to starting positions
Wickets = "0"
Overs = "-0"
BatTotal = "--0"
BatA = "--0"
BatB = "--0"
Target = "---"
Scoreboard = "4," + BatTotal + "," + Wickets + "," + Overs + "," + Target + "#"
# Open the serial port and set the Scoreboard to starting positions
with serial.Serial("/dev/ttyACM0", 57600, timeout=1) as arduino:
# time.sleep(0.1) #wait for serial to open
if arduino.isOpen():
print("{} connected!".format(arduino.port))
arduino.write(Scoreboard.encode())
print("Data Sent: " + Scoreboard)
arduino.close
class RxCharacteristic(Characteristic):
def __init__(self, bus, index, service):
Characteristic.__init__(self, bus, index, UART_RX_CHARACTERISTIC_UUID,
['write'], service)
def WriteValue(self, value, options):
global Wickets
global Overs
global BatTotal
global BatA
global BatB
global Target
global Scoreboard
try:
WriteReturn = '{}'.format(bytearray(value).decode())
ScoreType = WriteReturn[0:3]
ScoreData = WriteReturn[3:]
#if the bluetooth data is of type OVB, B1S, B2S, BTS, FTS then we need to update the scoreboard. Other messages can be ignore.
UpdateScoreboard = True
if ScoreType == "OVB": # Let's deal with Overs Bowled!
if ScoreData.find(".") == -1: # If there's no dot because it's the end of the over, just format the number and use it
Overs = ScoreData.rjust(2,"-")
else:
Overs = ScoreData.split(".",1)[0].rjust(2,"-") # If there's a dot, take whatever's before it. Cheap way of rounding down without using a float
elif ScoreType == "B1S": # Batsman 1 score formatted with leading dashes for blanks
BatA = ScoreData.rjust(3,"-")
elif ScoreType == "B2S": # Batsman 2 score formatted with leading dashes for blanks
BatB = ScoreData.rjust(3,"-")
elif ScoreType == "BTS": # Batting Team Score
TempSplit = ScoreData.split(" &",1)[0] # Current Inning Score only (split everything before the ampersand)
BatTotal = TempSplit.split("/",1)[0].rjust(3,"-") # Everything before the dash is the score, with leading dashes for blanks
Wickets = TempSplit.split("/",1)[1].replace("10","-") # Everything after the dash is the wickets, and if it's all out (10) then make it blank because we only have 1 digit
elif ScoreType == "FTS":
TempSplit = ScoreData.split(" &",1)[0] # Current Inning Score only
Target = TempSplit.split("/",1)[0].rjust(3,"-") # Everything before the dash is the score, with leading dashes for blanks
else:
print(WriteReturn + " (not used)")
#lets not send an update to the scoreboard
UpdateScoreboard = False
if UpdateScoreboard:
Scoreboard = "4," + BatTotal + "," + Wickets + "," + Overs + "," + Target + "#"
print(Scoreboard)
with serial.Serial("/dev/ttyACM0", 57600, timeout=1) as arduino:
# time.sleep(0.1) #wait for serial to open
if arduino.isOpen():
print("{} connected!".format(arduino.port))
arduino.write(Scoreboard.encode())
print("Data Sent: " + Scoreboard)
arduino.close
except:
print(sys.exc_info()[0], "occurred")
class UartService(Service):
def __init__(self, bus, index):
Service.__init__(self, bus, index, UART_SERVICE_UUID, True)
self.add_characteristic(RxCharacteristic(bus, 1, self))
class Application(dbus.service.Object):
def __init__(self, bus):
self.path = '/'
self.services = []
dbus.service.Object.__init__(self, bus, self.path)
def get_path(self):
return dbus.ObjectPath(self.path)
def add_service(self, service):
self.services.append(service)
@dbus.service.method(DBUS_OM_IFACE, out_signature='a{oa{sa{sv}}}')
def GetManagedObjects(self):
response = {}
for service in self.services:
response[service.get_path()] = service.get_properties()
chrcs = service.get_characteristics()
for chrc in chrcs:
response[chrc.get_path()] = chrc.get_properties()
return response
class UartApplication(Application):
def __init__(self, bus):
Application.__init__(self, bus)
self.add_service(UartService(bus, 0))
class UartAdvertisement(Advertisement):
def __init__(self, bus, index):
Advertisement.__init__(self, bus, index, 'peripheral')
self.add_service_uuid(UART_SERVICE_UUID)
self.add_local_name(LOCAL_NAME)
self.include_tx_power = True
def find_adapter(bus):
remote_om = dbus.Interface(bus.get_object(BLUEZ_SERVICE_NAME, '/'),
DBUS_OM_IFACE)
objects = remote_om.GetManagedObjects()
for o, props in objects.items():
if LE_ADVERTISING_MANAGER_IFACE in props and GATT_MANAGER_IFACE in props:
return o
print('Skip adapter:', o)
return None
def main():
global mainloop
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SystemBus()
adapter = find_adapter(bus)
if not adapter:
print('BLE adapter not found')
return
service_manager = dbus.Interface(
bus.get_object(BLUEZ_SERVICE_NAME, adapter),
GATT_MANAGER_IFACE)
ad_manager = dbus.Interface(bus.get_object(BLUEZ_SERVICE_NAME, adapter),
LE_ADVERTISING_MANAGER_IFACE)
app = UartApplication(bus)
adv = UartAdvertisement(bus, 0)
mainloop = GLib.MainLoop()
service_manager.RegisterApplication(app.get_path(), {},
reply_handler=register_app_cb,
error_handler=register_app_error_cb)
ad_manager.RegisterAdvertisement(adv.get_path(), {},
reply_handler=register_ad_cb,
error_handler=register_ad_error_cb)
try:
mainloop.run()
except KeyboardInterrupt:
adv.Release()
if __name__ == '__main__':
main()