import paho.mqtt.client as mqtt import time import umsgpack class Commander: currentVote = None # Stores voters that connect to maintain a majority. # Voters who do not vote in latest round are removed. connectedVoters = {} votes = [] taking_votes = False def __init__(self, timeout = 60): ''' Initial/default waiting time is 1 minute for votes to come in. ''' self.timeout = timeout self.client = mqtt.Client() self.client.connect('172.16.13.128') # Commander needs a will message too, for the decentralised version, so the # voters know to pick a new commander. def make_decision(self): # Could change this to be a strategy, for different implementations of making # a decision on the votes. votes = self._votes dif_votes = {} for vote in votes: # Get the average/max, etc. if str(vote) in dif_votes: dif_votes[str(vote)] = dif_votes[str(vote)] + 1 else: dif_votes[str(vote)] = 1 max_vote = None max_vote_num = 0 for vote in dif_votes.keys(): if dif_votes[vote] > max_vote_num: max_vote = vote max_vote_num = dif_votes[vote] return max_vote def get_votes(): message = {"type": "voteRequest"} message_packed = umsgpack.packb(message) # Publish a message that votes are needed. ms.client.publish("swarm1/voters", message_packed, qos) time.sleep(self.timeout) self.make_decision() def add_subscription(self, topic, callback=None, qos=0): ms.client.subscribe(topic) if callback is not None: ms.client.message_callback_add(topic, callback) def on_message(self, client, userdata, message): messageDict = umsgpack.unpackb() if "type" in messageDict.keys: if messageDict["type"] == "connect": # Voter just connected/reconnnected. elif messageDict["type"] == "vote": # Voter is sending in their vote. if messageDict[""] else: # Not a message we should be using. NotImplementedError def on_connect(client, userdata, flags, rc): self.client.subscribe("swarm1/commander")