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