Server : 2 BicycleManager - 17chuchu/AutomaticBicycleInterface GitHub Wiki
Table of Contents
BicycleManager.py
BicycleManager is a child class of WebSocket. It is used to connect to Bicycle applications that will upload a video stream from a bike to a room id. Its location is server/ServerApplication/component/BicycleManager.py
Initializing
Run a Thread that will keep this class running. This code is located at server/ServerApplication/urls.py
BicycleManager.initManager()  #line 19
Port
MeansManager is a web socket server so it needs a port. You can customize its port number here.
meansport = 7010.  #line 32
Handle Connected
This part will handle incoming connections of the bikes.
def handleConnected(self):  #line 71
    print('-- Bike Connection Incoming --')
    try:
        BicycleManager.bicycleid[str(self.address)] = "undefined"
        print('Bicycle Connection Successful :', self.address)
        comment = BikeComment.generateComment("None", "id", "None")  # Ask the bike for its id.
        self.sendMessage(json.dumps(comment))
        comment = BikeComment.generateComment("None", "requestopenroom", "None")  # Ask if the bike want to publish to a room.
        self.sendMessage(json.dumps(comment))
    except Exception as e:
        print("Message error is : " + e)
Handle Message
This part will handle all the messages sent to the web socket.
def handleMessage(self):  #Line 51
    print('-- Bike Message Incoming --')
    try:
        data = json.loads(self.data)  # Load JSON string into a dictionary.
        if(data['topic'] == 'id'):  # Check the topic of this message.
            print("Register Bike :", data['comment'])
            BicycleManager.bicycleid[str(self.address)] = data['comment']  # Save ip address of the bike.
            BicycleManager.bicyclesocketref[data['comment']] = self  # Save a reference of the socket client to a dictionary with the bike's id as a reference. 
        if(data['topic'] == 'requestopenroom'):
            print("Bike :",data['comment'],"want to publish to a room.")
            bikeid = data['comment']  # Get an id of the bike that wants to publish its video stream.
            BicycleManager.MeansManagerReference.registerNewRoom(bikeid)  # Call the function from MeansManager.py to create rooms for the bike and clients.
            comment = BikeComment.generateComment('','openroomtoken',BicycleManager.bicycleroom[bikeid])  # 
            self.sendMessage(json.dumps(comment))
    except Exception as e:
        print("Message error is : " + e)
Bind To Bike
This function will bind a user to a bike so the user can send commands like send control input to the bike.
This JSON string will be received from users.
{'code': 5, 'pack': '{"bikeid":"BK-1234","status":"true"}', 'token': 'ebe7340f128a48a0993d6ae0a89a092b'}
Here is the code's explanation.
@staticmethod
def bindToBike(status,bikeid,userid):
    if(status == "true" and bikeid in BicycleManager.bicycleid): # Check if the bike does exist.
        if(bikeid not in BicycleManager.usertimeout or bikeid not in BicycleManager.usertobike):  # If there is no user binds to the bike at that time allow the bike to be connected to this new user.
            BicycleManager.usertobike[bikeid] = userid
            BicycleManager.usertimeout[bikeid] = datetime.datetime.now().  # Set timeout. If the user has not send any input in one minute, new user can be connect to the bike immediately.
            print("Bike :", bikeid, "bind to a user", userid, "at", BicycleManager.bicycleid[bikeid])
            return True
        elif(bikeid in BicycleManager.usertimeout):  # If there is a user connected to the bike within 60 minute.
            print("Timeout is", (datetime.datetime.now() - BicycleManager.usertimeout[bikeid]).total_seconds())
            if((datetime.datetime.now() - BicycleManager.usertimeout[bikeid]).total_seconds() >= 60):  # If there is no input within one minute, the bike will be binded to a new user immediately 
                BicycleManager.usertimeout[bikeid] = datetime.datetime.now()
                BicycleManager.usertobike[bikeid] = userid
                print("Bike :", bikeid ,"bind to a user", userid ,"at", BicycleManager.bicycleid[bikeid])
                return True
            else:
                return float((datetime.datetime.now() - BicycleManager.usertimeout[bikeid]).total_seconds())  # Return the total second that a user need to wait before joining this bike.
    else:  # Status is False means that the bike will be seperate from the user.
        print("Seperate bike", bikeid ,"from user", userid)
        if(userid in BicycleManager.usertobike):
            BicycleManager.usertobike.pop(bikeid)
            BicycleManager.usertimeout.pop(bikeid)
        return True
Send Direction
This function will send user input (direction) to the bike that is binded to him/her. Inputs will be in a form of an array of string. For example ,python["down","up","right","left"].
This JSON string will be received from users.
{'code': 4, 'pack': '{"bikeid":"BK-1234","direction":["down"]}', 'token': 'ebe7340f128a48a0993d6ae0a89a092b'}
This JSON string will be sent to the bike.
{"command":"","topic":"givedirection","comment":["up","left"]}
Here is the code's explanation.
@staticmethod
def sendDirection(direction,bikeid,userid):
    if(BicycleManager.usertobike[userid] != bikeid):
        return False
    print("The direction is",json.dumps(BikeComment.generateComment("","givedirection",direction)))
    BicycleManager.bicyclesocketref[bikeid].sendMessage(json.dumps(BikeComment.generateComment("","givedirection",direction)))
    return True
BikeComment.py
BikeComment is a class that provides a template to create packages of information to be sent to the bike. BikeComment.py is located in server/ServerApplication/component/Comment/BikeComment.py
class BikeComment:
    @staticmethod
    def generateComment(command, topic, comment):
        data = dict()
        data['command'] = command
        data['topic'] = topic      # Topic that this package will go to.
        data['comment'] = comment  # Comment is the information that is needed to be sent along with this package.
        return data