123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- '''
-
- WORKSTATION CLIENT BACKEND
- '''
- import sys
- try:
- import paho.mqtt.client as mqtt
- except ImportError:
-
-
-
-
- import os
- import inspect
- cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"../src")))
- if cmd_subfolder not in sys.path:
- sys.path.insert(0, cmd_subfolder)
- import paho.mqtt.client as mqtt
- from packet_handling import decode_client_list, decode_data_packet
- try:
- from ctype_bindings import SwitchPro6
- windows = True
- except AttributeError:
- print("Windows win32 API missing.\n Button presses will be still be represented in print statements.")
- global print_debug
- windows = False
- class WorkstationClientClass():
- def __init__(self, client_id=None, debug=True, mqttdebug=False):
- self.client_id = client_id
- self.debug = debug
- self.mqttdebug = mqttdebug
- self.mode_color = 'debug'
-
- self.data_topics = '/modules/+/data'
- self.clientlist_topic = '/workstations/modulehealth'
- self.clientlist = None
- self.subscribed_modules = []
- if windows:
- self.switchpro6 = SwitchPro6()
- self._mqttc = mqtt.Client(self.client_id, clean_session=True, userdata=None,
- protocol='MQTTv311')
- self._mqttc.message_callback_add(self.clientlist_topic, self.mqtt_on_client_list)
- self._mqttc.message_callback_add(self.data_topics, self.mqtt_on_data)
- self._mqttc.on_connect = self.mqtt_on_connect
- self._mqttc.on_disconnect = self.mqtt_on_disconnect
- if self.mqttdebug:
- self._mqttc.on_log = self.mqtt_on_log
-
- def mqtt_on_connect(self, mqttc, backend_data, flags, rc):
-
- if self.debug:
- if rc == 0:
- print('Connected to %s: %s' % (mqttc._host, mqttc._port))
- else:
- print('rc: ' + str(rc))
- def mqtt_on_client_list(self, mqttc, backend_data, msg):
- self.clientlist = decode_client_list(msg.payload)
-
- for active_module_id in self.subscribed_modules:
- for dead_module_id in self.clientlist[self.clientlist['alive']==0]['module_id']:
- if active_module_id == dead_module_id:
- if self.debug:
- print("Conflicting ID: " + str(active_module_id)+ \
- "\nAttempting to kill now.")
- self.unsubscribe_to_module(active_module_id)
- if self.debug:
- print(self.clientlist)
-
-
-
- def mqtt_on_data(self, mqttc, backend_data, msg):
-
- data = decode_data_packet(msg.payload)
- if windows:
- self.switchpro6.keymap_press(data[0])
- if self.debug:
- print(msg.topic+" "+str(msg.qos)+" "+str(msg.payload)+" "+str(data))
- def mqtt_on_log(self, mqttc, backend_data, level, string):
- print(string)
-
- def mqtt_on_disconnect(self, mqttc, backend_data, rc):
-
- if self.debug:
- if rc != 0:
- print("Client disconnected and its a mystery why!")
- else:
- print("Client successfully disconnected.")
-
- def start_workstation_client(self, ip="127.0.0.1", port=1883, keepalive=60):
- self.ip = ip
- self.port = port
- self.keepalive = keepalive
- self.clientlist = None
- self._mqttc.connect(ip, port, keepalive)
- self._mqttc.subscribe(self.clientlist_topic, 2)
- self._mqttc.loop_start()
-
- def subscribe_to_module(self, module_id):
- module_found = False
- if type(module_id) == int:
- module_id = str(module_id)
- if len(module_id) < 8:
- module_id = '0'*(8-len(module_id)) + module_id
-
- for active_module_id in self.clientlist[self.clientlist['alive']==1]['module_id']:
- if int(module_id) == active_module_id:
- module_found = True
- module_topic = '/modules/'+module_id+'/data'
- result, mid = self._mqttc.subscribe(module_topic, qos=0)
-
- if result == 0:
- if int(module_id) not in self.subscribed_modules:
- self.subscribed_modules.append(int(module_id))
-
- if self.debug:
- print("Module %s was successfully added" % module_id)
- else:
- if self.debug:
- print("Module is already subscribed")
- return result, mid
- if module_found == False:
- if self.debug:
- print("Module is not alive or in client list.")
- print("Module ID: " + str(module_id))
- return 3, None
-
- def unsubscribe_to_module(self, module_id):
- if type(module_id) == int:
- module_id = str(module_id)
- if len(module_id) < 8:
- module_id = '0'*(8-len(module_id)) + module_id
-
- if int(module_id) in self.subscribed_modules:
- module_topic = '/modules/'+module_id+'/data'
- result, mid = self._mqttc.unsubscribe(module_topic)
-
- if result == 0:
- self.subscribed_modules.remove(int(module_id))
-
- if self.debug:
- print("Module %s was successfully removed" % module_id)
- return result, mid
- else:
- if self.debug:
- print("Module is not subscribed")
- print("Subscribed Modules:\n", self.subscribed_modules)
- return 3, None
- def pair_module_to_puck(self, module_id, puck_id, pair=True):
- if type(module_id) == int:
- module_id = str(module_id)
- if len(module_id)<8:
- module_id = '0'*(8-len(module_id)) + module_id
- if type(puck_id) == int:
- puck_id = str(puck_id)
- if len(puck_id)<8:
- puck_id = '0'*(8-len(puck_id)) + puck_id
-
- module_found = False
-
-
- for active_module_id in self.clientlist[self.clientlist['alive']==1]['module_id']:
- if int(module_id) == active_module_id :
- module_found = True
- puck_topic = '/pucks/'+puck_id+'/command'
- if pair:
- payload = 'a/modules/'+str(module_id)+'/data'
- else:
- payload = 'd/modules/'+str(module_id)+'/data'
- result, mid = self._mqttc.publish(puck_topic, payload, 0, retain=False)
- if result == 0:
-
-
- if self.debug:
- print("Module %s was successfully paired" % module_id)
- return result, mid
- if module_found == False:
- if self.debug:
- print("Module is not alive or in client list.")
- print("Module ID: " + str(module_id))
- return 3, None
-
-
-
- if __name__ == "__main__":
- wsc = WorkstationClientClass()
- wsc.start_workstation_client(ip="server.ideasx.tech")
|