Browse Source

I'm not sure but I'm guessing it has to do with the settings menu?

curiousmuch 7 years ago
parent
commit
f3c3f2e5b1

File diff suppressed because it is too large
+ 0 - 1
IdeasXMessages_pb2.py


+ 105 - 92
ideasxwscbackend/py.py → IdeasXWSCBackend.py

@@ -18,35 +18,23 @@ This class requires the following functionality:
 4) Parse IdeasX messages types given nothing more than a protofile 
 5) Subscribe to IdeasX devices 
 6) Invoke keystrokes if proper messages in a command is sent. 
+
+TODO: Develop logger class for print statements 
+TODO: Fix subscribe / unsubscribe functionality
+TODO: Implement Queue which will send signal when subscription ACK is RX
+TODO: Expand exceptions to only parser not general actions
 '''
-import sys
-import time
-import collections
+import sys, time, collections
 from ParsingTools import ParsingTools
-
-try:
-    import paho.mqtt.client as mqtt
-    import paho.mqtt.publish as mqtt_pub
-except ImportError:
-    # This part is only required to run the example from within the examples
-    # directory when the module itself is not installed.
-    #
-    # If you have the module installed, just use "import paho.mqtt.client"
-    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 PyQt5.QtCore import QObject, pyqtSignal, QSettings
+import paho.mqtt.client as mqtt  
 
 try:     
-    from protocolbuffers import IdeasXMessages_pb2 as IdeasXMessages
+    import IdeasXMessages_pb2 as IdeasXMessages
 except ImportError: 
     print("The python classes for IdeasX are missing. Try running the Makefile in" +
             "ideasX-messages.")
 
-from PyQt5.QtCore import QObject, pyqtSignal, QSettings
-    
     
 class IdeasXWSCNetworkThread(QObject): 
     
@@ -70,7 +58,7 @@ class IdeasXWSCNetworkThread(QObject):
         self.__app = 'Workstation-Client'
         
         # MQTT Topics 
-        self.__DEVICETYPE = ["/encoder/+"]
+        self.__DEVICETYPE = ["/encoder/+", "/actuator/+"]
         self.__COMMANDTOPIC = "/command"
         self.__DATATOPIC = "/data"
         self.__HEALTHTOPIC = "/health"
@@ -79,11 +67,14 @@ class IdeasXWSCNetworkThread(QObject):
         self.encoders = {}
         self.subscribedEncoders = []
         
+        self.actuators = {}
+        self.subscribedActuators = []
+        
         # IdeasX Parsers
-        self._healthParser = IdeasXMessages.HealthMessage()
-        self._dataParser = IdeasXMessages.DataMessage()
-        self._commandParser = IdeasXMessages.CommandMessage()
-        self._parserTools = ParsingTools()
+        self.__healthParser = IdeasXMessages.HealthMessage()
+        self.__dataParser = IdeasXMessages.DataMessage()
+        self.__commandParser = IdeasXMessages.CommandMessage()
+        self.__parserTools = ParsingTools()
         self.keyEmulator = IdeasXKeyEmulator()
         
         # MQTT Client Object
@@ -93,7 +84,7 @@ class IdeasXWSCNetworkThread(QObject):
         for device in self.__DEVICETYPE:
             self._mqttc.message_callback_add(device+self.__HEALTHTOPIC, self.mqtt_on_health)
             self._mqttc.message_callback_add(device+self.__DATATOPIC, self.mqtt_on_data)
-            #self._mqttc.message_callback_add(device+self.__COMMANDTOPIC, self.mqtt_on_command)       
+            self._mqttc.message_callback_add(device+self.__COMMANDTOPIC, self.mqtt_on_command)       
         
         self._mqttc.on_connect = self.mqtt_on_connect
         self._mqttc.on_disconnect = self.mqtt_on_disconnect 
@@ -103,8 +94,9 @@ class IdeasXWSCNetworkThread(QObject):
         if self.__mqttDebug: 
             self._mqttc.on_log = self.mqtt_on_log 
 
-#------------------------------------------------------------------------------
-# callback functions
+    '''
+     MQTT Callback Functions
+    '''
 
     def mqtt_on_connect(self, mqttc, backend_data, flags, rc): 
         if rc == 0: 
@@ -133,9 +125,9 @@ class IdeasXWSCNetworkThread(QObject):
         self.printInfo("Data Message")
         self.printLine()
         try: 
-            self._dataParser.ParseFromString(msg.payload)
-            print("GPIO States: " + bin(self._dataParser.button))
-            self.keyEmulator.emulateKey( self._parserTools.getModuleIDfromTopic(msg.topic),self._dataParser.button)
+            self.__dataParser.ParseFromString(msg.payload)
+            print("GPIO States: " + bin(self.__dataParser.button))
+            self.keyEmulator.emulateKey( self.__parserTools.getModuleIDfromTopic(msg.topic),self.__dataParser.button)
         except Exception as ex: 
             self.printError("Failure to parse message")
             if self.__debug:
@@ -151,20 +143,20 @@ class IdeasXWSCNetworkThread(QObject):
         self.printInfo("Health Message")
         self.printLine()
         try: 
-            self._healthParser.ParseFromString(msg.payload)
-            macID = self._parserTools.macToString(self._healthParser.module_id)
+            self.__healthParser.ParseFromString(msg.payload)
+            macID = self.__parserTools.macToString(self.__healthParser.module_id)
             
-            if self._healthParser.alive:
+            if self.__healthParser.alive:
                 temp_list = []
-                for field in self._healthParser.ListFields():
-                    temp_list.append((field[0].name, field[1]))  
-                temp_list.append(('time', time.time()))          
-                self.encoders[macID] = collections.OrderedDict(temp_list)
-                self.encoderUpdate.emit(self.getDevices())
+                for field in self.__healthParser.ListFields():
+                    temp_list.append((field[0].name, field[1]))                     # copy health message fields in to list 
+                temp_list.append(('time', time.time()))                             # add time the message was RX to the end
+                self.encoders[macID] = collections.OrderedDict(temp_list)           # store into a ordered dictionary
+                self.encoderUpdate.emit(self.getDevices())                          # send signal to the GUI
             else:
                 try: 
-                    self.encoders.pop(macID)
-                    self.encoderUpdate.emit()
+                    self.encoders.pop(macID)                                        # if the encoder isn't alive attempt to remove from dictionary
+                    self.encoderUpdate.emit()                                       # send signal to GUI
                 except KeyError: 
                     self.printError("Encoder ID " +macID+" is not stored")
             
@@ -172,22 +164,22 @@ class IdeasXWSCNetworkThread(QObject):
                 for encoder, fields in zip(self.encoders.keys(), self.encoders.values()): 
                     print(str(encoder) +" : "+ str(fields))
                 self.printLine()
-        except: 
+        except Exception as e:
+            print(e) 
             self.printError("Error: Failure to parse message")
             if self.__debug:
                 print("Raw Message: %s" %msg.payload)
             self.printLine()
             try: 
-                self.encoders.pop(msg.topic.split('/')[2])
+                deviceID = msg.topic.split('/')[2]
+                self.encoders.pop(deviceID)
                 self.encoderUpdate.emit(self.getDevices())
+                self.deactivateEncoder(deviceID)
             except: 
                 print("This is a fucking joke anyway")
 
-
-        
-
-#----------------------------------------------thy--------------------------------
-# General API Calls 
+    def mqtt_on_command(self, mqttc, backend_data, msg):
+        pass
         
     def cmdStartWorkstationClient(self, ip="server.ideasX.tech", port=1883, keepAlive=60):     
         self.ip = ip 
@@ -235,7 +227,6 @@ class IdeasXWSCNetworkThread(QObject):
             self._mqttc.connect(self.ip, int(self.port), self.keepAlive)
             for device in self.__DEVICETYPE:
                 self._mqttc.subscribe(device + self.__HEALTHTOPIC, 0)
-                self._mqttc.subscribe(device + self.__DATATOPIC, 0)
             self._mqttc.loop_start() # start MQTT Client Thread 
         except: 
             self.printError("There was a fucking mistake here.")
@@ -268,9 +259,11 @@ class IdeasXWSCNetworkThread(QObject):
         deviceType = str 
         deviceMACAddress = str(MAC_ID)
         '''
-        if deviceMACAddress in self.encoders.keys():
+        if deviceMACAddress not in self.encoders.keys():
+            self.printError("Device " + deviceMACAddress + " is not currently in the IdeasX system.")
+        else:
             if deviceType == None: 
-                deviceDataTopic = self.__DEVICETYPE[0] + deviceMACAddress + self.__DATATOPIC
+                deviceDataTopic = "/encoder/" + deviceMACAddress + self.__DATATOPIC
             else: 
                 deviceDataTopic = deviceType + deviceMACAddress + self.__DATATOPIC
                  
@@ -278,9 +271,7 @@ class IdeasXWSCNetworkThread(QObject):
             self.subscribedEncoders.append(deviceMACAddress)
             if self.__debug: 
                 self.printInfo("Device " + deviceMACAddress + " data topic was subscribed")
-        else: 
-            self.printError("Device " + deviceMACAddress + " is not currently in the IdeasX system.")
-            
+                    
     def deactivateEncoder(self, deviceMACAddress, deviceType=None, forceAction=False):
         '''
         Unsubscribe from device's data topic and send deactive command if no other WSC are using device. 
@@ -298,17 +289,34 @@ class IdeasXWSCNetworkThread(QObject):
             if self.__debug: 
                 self.printInfo("Device " + deviceMACAddress + " data topic was unsubscribed")
         else: 
-            self.printError("Device " + deviceMACAddress + " is not currently in the IdeasX System")    
-
+            self.printError("Device " + deviceMACAddress + " is not currently in the IdeasX System")  
+            
+    def resetDevice(self, deviceMACAddress, deviceType=None):
+        self.__commandParser.command = self.__commandParser.RESTART
+        self._mqttc.publish(self.__DEVICETYPE[0][:-1] + deviceMACAddress + self.__COMMANDTOPIC,
+                            self.__commandParser.SerializeToString().decode('utf-8') ,
+                            qos=1,
+                            retain=False)       
+        self.networkUpdate.emit("Sent reset command to device " + deviceMACAddress)
 
     def shutdownDevice(self, deviceMACAddress, deviceType=None):
-        self._commandParser.command = self._commandParser.SHUT_DOWN
+        self.__commandParser.command = self.__commandParser.SHUT_DOWN
         self._mqttc.publish(self.__DEVICETYPE[0][:-1] + deviceMACAddress + self.__COMMANDTOPIC,
-                            self._commandParser.SerializeToString().decode('utf-8') ,
+                            self.__commandParser.SerializeToString().decode('utf-8') ,
                             qos=1,
                             retain=False)
-        self.networkUpdate.emit("Send shutdown command to Encoder " + deviceMACAddress)
-        self.printInfo("Send Shutdown Command to Encoder " + deviceMACAddress)
+        self.networkUpdate.emit("Sent shutdown command to device " + deviceMACAddress)
+        
+    def updateDevice(self, deviceMACAddress, deviceType=None):
+        self.__commandParser.command = self.__commandParser.OTA_UPDATE
+        self._mqttc.publish(self.__DEVICETYPE[0][:-1] + deviceMACAddress + self.__COMMANDTOPIC,
+                    self.__commandParser.SerializeToString().decode('utf-8') ,
+                    qos=1,
+                    retain=False)
+        self.networkUpdate.emit("Sent OTA update request to device " + deviceMACAddress)
+        
+    #def configureIMU(self, deviceMACAddress, deviceType=None):
+        
         
     def printLine(self):
         print('-'*70)
@@ -402,7 +410,7 @@ class IdeasXKeyEmulator():
         
         
 if __name__ == "__main__": 
-    Host = "ideasx.dnuckdns.org"
+    Host = "ideasx.duckdns.org"
 #    Host = "192.168.0.101"
 #    Host = "10.42.0.1"
     Port = 1883 
@@ -412,39 +420,44 @@ if __name__ == "__main__":
     cmdPayload = None; 
     cmdArg = None;
     cmdTest = False; 
+#     
+#     encodeId = '23:34'
+#     
+#     km = IdeasXKeyEmulator()
+#     
+#     km.activateEncoder(encodeId)
+#     km.emulateKey(encodeId, 1)
+#     time.sleep(0.1)
+#     km.emulateKey(encodeId, 0) 
+#     time.sleep(0.1)
+# 
+#     km.emulateKey(encodeId, 2)
+#     time.sleep(0.1)
+#     km.emulateKey(encodeId, 0)
+#     time.sleep(0.1)
+#     km.emulateKey(encodeId, 4)
+#     time.sleep(0.1)
+#     km.emulateKey(encodeId, 0)
     
-    encodeId = '23:34'
-    
-    km = IdeasXKeyEmulator()
-    
-    km.activateEncoder(encodeId)
-    km.emulateKey(encodeId, 1)
-    time.sleep(0.1)
-    km.emulateKey(encodeId, 0) 
-    time.sleep(0.1)
 
-    km.emulateKey(encodeId, 2)
-    time.sleep(0.1)
-    km.emulateKey(encodeId, 0)
-    time.sleep(0.1)
-    km.emulateKey(encodeId, 4)
-    time.sleep(0.1)
-    km.emulateKey(encodeId, 0)
-    
-
-    
-#     wsc = WorkstationClientClass()
-#         
-#     if cmdTest: 
-#         wsc.cmdStartWorkstationClient(Host, Port, KeepAlive)
-#     else: 
-#         wsc.guiStartWorkstationClient(Host, Port, KeepAlive)
-#         time.sleep(3)
-#         wsc.activateEncoder('18:fe:34:f1:f2:8d')
+       
+    wsc = IdeasXWSCNetworkThread()
+         
+    if cmdTest: 
+        wsc.cmdStartWorkstationClient(Host, Port, KeepAlive)
+    else: 
+        wsc.guiStartWorkstationClient(Host, Port, KeepAlive)
+        time.sleep(3)
+        
+        (result, mid) = wsc._mqttc.subscribe('/encoders/18:fe:34:d2:6f:68/health', qos=0)
+        print(result, mid)
+        (result, mid) = wsc._mqttc.subscribe('/encoders/18:fe:34:d2:6f:68/health', qos=0)
+        print(result, mid)
+        wsc.activateEncoder('18:fe:34:d2:6f:68')
 #         print(wsc.subscribedEncoders)
 #         time.sleep(2)
-#         wsc.deactivateEncoder('18:fe:34:f1:f2:8d')
+#         wsc.deactivateEncoder('18:fe:34:d2:6f:68')
 #         print(wsc.subscribedEncoders)
-#         time.sleep(10)
-#         wsc.killWSC()
+        time.sleep(10)
+        wsc.killWSC()
         

+ 71 - 50
IdeasXWSCView.py

@@ -1,14 +1,26 @@
-#!/usr/bin/env python`
+
+'''
+IdeasXWSCView.py 
+
+TODO: Fix activate / deactivate functionality [done]
+TODO: Fix subscribe / unsubscribe functionality in backend [done]
+TODO: Develop queue message thinger for sub unsub with feedback from backend
+
+TODO: Develop structure for creating alias for device
+TODO: Develop structure for saving information into backend
+
+'''
 import sys
 import time
 import sip
 from PyQt5 import QtCore, QtGui, QtWidgets
-from mainwindow2 import Ui_MainWindow
-from ideasxdevice import Ui_IdeasXDevice
+from pyqt.mainwindow2 import Ui_MainWindow
+from pyqt.ideasxdevice import Ui_IdeasXDevice
 from IdeasXWSCBackend import IdeasXWSCNetworkThread
+from pyqt.encoderconfigurationdialog import Ui_SwitchConfigDialog
+from pyqt.devicedialog import Ui_Dialog
 from ParsingTools import ParsingTools
-from encoderconfigurationdialog import Ui_SwitchConfigDialog
-from devicedialog import Ui_Dialog
+
 
 class IdeasXSwitchDialog(QtWidgets.QDialog):
     
@@ -97,39 +109,42 @@ class IdeasXDeviceManager():
 
 class IdeasXEncoder(QtWidgets.QWidget):
     sendCommand = QtCore.pyqtSignal(['QString'], name='sendCommand')
+    activateDevice = QtCore.pyqtSignal(['QString', 'QString'], name='deactivateDevice')
+    deactivateDevice = QtCore.pyqtSignal(['QString', 'QString'], name='activateDevice')
+    __pathToIcon = {'network': './icon/network/', 
+                     'battery': './icon/battery/', 
+                     'battery_charging': './icon/battery/',
+                     'switch': './icon/switch/'
+                    }
+    __icon = {'network': ['network-wireless-offline-symbolic.png',
+                               'network-wireless-signal-weak-symbolic.png',
+                               'network-wireless-signal-ok-symbolic.png',
+                               'network-wireless-signal-good-symbolic.png',
+                               'network-wireless-signal-excellent-symbolic.png'],
+                    'battery': ['battery-empty-symbolic.png', 
+                                'battery-caution-symbolic.png',
+                                'battery-low-symbolic.png', 
+                                'battery-good-symbolic.png',
+                                'battery-full-symbolic.png'],
+                    'battery_charging': ['battery-empty-charging-symbolic.png', 
+                                         'battery-caution-charging-symbolic.png', 
+                                         'battery-low-charging-symbolic.png', 
+                                         'battery-good-charging-symbolic.png', 
+                                         'battery-full-charged-symbolic.png'],
+                    'switch': ['switch-one-enabled.png', 
+                               'switch-one-disabled.png', 
+                               'switch-two-enabled.png', 
+                               'switch-two-disabled.png', 
+                               'switch-adaptive-enabled.png', 
+                               'switch-adaptive-disabled.png']
+                   }
+    __deviceType = '/encoder/'
+
     
     def __init__(self, encoder, wsc): 
-        # This should become a static variable for the class
-        self.__pathToIcon = {'network': './icon/network/', 
-                             'battery': './icon/battery/', 
-                             'battery_charging': './icon/battery/',
-                             'switch': './icon/switch/'
-                            }
-        self.__icon = {'network': ['network-wireless-offline-symbolic.png',
-                                   'network-wireless-signal-weak-symbolic.png',
-                                   'network-wireless-signal-ok-symbolic.png',
-                                   'network-wireless-signal-good-symbolic.png',
-                                   'network-wireless-signal-excellent-symbolic.png'],
-                        'battery': ['battery-empty-symbolic.png', 
-                                    'battery-caution-symbolic.png',
-                                    'battery-low-symbolic.png', 
-                                    'battery-good-symbolic.png',
-                                    'battery-full-symbolic.png'],
-                        'battery_charging': ['battery-empty-charging-symbolic.png', 
-                                             'battery-caution-charging-symbolic.png', 
-                                             'battery-low-charging-symbolic.png', 
-                                             'battery-good-charging-symbolic.png', 
-                                             'battery-full-charged-symbolic.png'],
-                        'switch': ['switch-one-enabled.png', 
-                                   'switch-one-disabled.png', 
-                                   'switch-two-enabled.png', 
-                                   'switch-two-disabled.png', 
-                                   'switch-adaptive-enabled.png', 
-                                   'switch-adaptive-disabled.png']
-                       }
-        self.__deviceType = 'encoder'
         self.__deviceName = None
         self.__wsc = wsc
+        
         # Setup UI components
         super(IdeasXEncoder, self).__init__()
         self.__ui = Ui_IdeasXDevice()
@@ -138,7 +153,6 @@ class IdeasXEncoder(QtWidgets.QWidget):
         self.updateDevice(encoder)        
         self.updateSwitchIcons()
         
-
         # Setup Signals
         self.setupMenu()
         self.__ui.buttonActivate.clicked.connect(self.activateEncoder)
@@ -146,7 +160,8 @@ class IdeasXEncoder(QtWidgets.QWidget):
                                                                                  self.__wsc.keyEmulator.getAssignedKey(self.__strModuleID, self.__wsc.keyEmulator.switchOne)))
         self.__ui.buttonSwitchTwo.clicked.connect(lambda: self.openSwitchDialog(self.__wsc.keyEmulator.switchTwo,
                                                                                 self.__wsc.keyEmulator.getAssignedKey(self.__strModuleID, self.__wsc.keyEmulator.switchTwo)))
-        
+        self.activateDevice.connect(self.__wsc.activateEncoder)
+        self.deactivateDevice.connect(self.__wsc.deactivateEncoder)
         
     def openDeviceInformation(self):
         dialog = IdeasXDeviceInformationDialog()
@@ -170,26 +185,25 @@ class IdeasXEncoder(QtWidgets.QWidget):
               
     def setupMenu(self):
         shutdownAction = QtWidgets.QAction('Shutdown Encoder', self)
-        shutdownAction.triggered.connect(lambda: self.__wsc.shutdownDevice(self.__strModuleID, None))
+        resetAction = QtWidgets.QAction("Reset Encoder", self)
         testKeysAction = QtWidgets.QAction("Test Keys", self)
         openInfoAction = QtWidgets.QAction("Device Information", self)
+        startOTAAction = QtWidgets.QAction("OTA Update", self)
 
         testKeysAction.triggered.connect(self.testKeys)
         openInfoAction.triggered.connect(self.openDeviceInformation)
-        
+        startOTAAction.triggered.connect(lambda: self.__wsc.updateDevice(self.__strModuleID, None))
+        shutdownAction.triggered.connect(lambda: self.__wsc.shutdownDevice(self.__strModuleID, None))
+        resetAction.triggered.connect(lambda: self.__wsc.resetDevice(self.__strModuleID, None))
+
                 
         deviceMenu = QtWidgets.QMenu()
-        #deviceMenu.addSection("General Actions")
-        #deviceMenu.addAction("Pair Encoder with Actuator")
-        #deviceMenu.addAction("Train Adaptive Switch")
-        #deviceMenu.addAction("Configure Module")
-        #deviceMenu.addSection("Encoder Commands")
         deviceMenu.addAction(shutdownAction)
+        deviceMenu.addAction(resetAction)
         deviceMenu.addAction(openInfoAction)
-        #deviceMenu.addAction("Restart Encoder")
-        #deviceMenu.addAction("Update Firmware")
         deviceMenu.addSection("Engineering Tools")
         deviceMenu.addAction(testKeysAction)
+        deviceMenu.addAction(startOTAAction)
         
         self.__ui.buttonMenu.setPopupMode(2)
         self.__ui.buttonMenu.setMenu(deviceMenu)
@@ -198,9 +212,11 @@ class IdeasXEncoder(QtWidgets.QWidget):
     def activateEncoder(self):
         if self.__ui.buttonActivate.text() == "Activate":
             print("Activating Encoder: " + self.__ui.labelModuleID.text())
+            self.activateDevice.emit(self.__strModuleID, self.__deviceType)
             self.__ui.buttonActivate.setText("Deactivate")
         else: 
             print("Deactivating Encoder: " + self.__ui.labelModuleID.text())
+            self.deactivateDevice.emit(self.__strModuleID, self.__deviceType)
             self.__ui.buttonActivate.setText("Activate")
         
     def updateDevice(self, encoder):      
@@ -209,12 +225,20 @@ class IdeasXEncoder(QtWidgets.QWidget):
         self.__vcell = self._parserTools.calculateVCell(encoder['vcell'])
         self.__strModuleID = self._parserTools.macToString(encoder['module_id'])
         self.__updateTime = encoder['time']
+        self.__ota = encoder['ota']
         
         if self.__deviceName == None:
             self.setModuleID(self.__strModuleID)
         self.setSOCIcon(self.__soc)
         self.setRSSIIcon(self.__rssi)
         self.setStatusTime(self.__updateTime)
+        self.setOTAIcon(self.__ota)
+        
+    def setOTAIcon(self, ota):
+        if ota: 
+            self.__ui.labelOTA.show()
+        else: 
+            self.__ui.labelOTA.hide()
 
     def setModuleID(self, strModuleID):      
         self.__ui.labelModuleID.setText(strModuleID)
@@ -242,9 +266,8 @@ class IdeasXEncoder(QtWidgets.QWidget):
         self.__ui.labelBattery.setToolTip(str(soc) + "%")
         
     def setStatusTime(self, updateTime):
-        # set last update time or date
-        lastUpdate = time.ctime(updateTime).split(" ")
-        currentTime = time.ctime().split(" ")
+        lastUpdate = time.ctime(updateTime).replace("  ", " ").split(" ")
+        currentTime = time.ctime().replace("  ", " ").split(" ")
         if currentTime[1] != lastUpdate[1] or currentTime[2] != lastUpdate[2] or currentTime[4] != lastUpdate[4]: 
             lastUpdate = lastUpdate[1] + " " + lastUpdate[2] + " " + lastUpdate[4]
         else: 
@@ -252,7 +275,6 @@ class IdeasXEncoder(QtWidgets.QWidget):
         self.__ui.labelStatus.setText("Last Update: " + lastUpdate)
         
     def setRSSIIcon(self, rssi): 
-        # set rssi icon
         if rssi >= -50: 
             rssiIcon = 4
         elif rssi >= -60 and rssi < -50: 
@@ -294,7 +316,6 @@ class IdeasXEncoder(QtWidgets.QWidget):
             self.__wsc.keyEmulator.emulateKey(self.__strModuleID, payload)
             time.sleep(0.1)
 
-    
 
 class IdeasXMainWindow(QtWidgets.QMainWindow):
     def __init__(self, wsc):

+ 3 - 3
ParsingTools.py

@@ -4,7 +4,7 @@ class ParsingTools():
         '''
         mac_str = ""
         for byte in mac_bytes: 
-            mac_str = mac_str + format(byte, 'x') + ':'
+            mac_str = mac_str + format(byte, '02x') + ':'
         return mac_str[:-1].format('utf-8')
             
     def calculateVCell(self, raw_Vcell):
@@ -15,14 +15,14 @@ class ParsingTools():
     
     def getModuleIDfromTopic(self, topic):
         return topic.split('/')[2]
-    
+        
 class FieldGenerator():
     def generateMACID(self):
         import numpy as np
         macID = np.random.randint(255, size=5)
         macStr = ""
         for val in macID: 
-            macStr = macStr+ format(val, 'x') + ":" 
+            macStr = macStr + format(val, 'x') + ":" 
         return macStr[:-1]
 
     def generateRSSI(self):

BIN
icon/ota/updating.png


File diff suppressed because it is too large
+ 5 - 3
icon/svg/icons.svg


+ 0 - 0
pyqt/__init__.py


+ 11 - 5
pyqt/ideasxdevice.py

@@ -11,7 +11,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
 class Ui_IdeasXDevice(object):
     def setupUi(self, IdeasXDevice):
         IdeasXDevice.setObjectName("IdeasXDevice")
-        IdeasXDevice.resize(452, 84)
+        IdeasXDevice.resize(522, 84)
         sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
         sizePolicy.setHorizontalStretch(0)
         sizePolicy.setVerticalStretch(0)
@@ -60,20 +60,20 @@ class Ui_IdeasXDevice(object):
         self.labelSignal = QtWidgets.QLabel(self.widgetInfo)
         self.labelSignal.setGeometry(QtCore.QRect(117, 43, 31, 31))
         self.labelSignal.setToolTip("")
-        self.labelSignal.setPixmap(QtGui.QPixmap("../icon/network/network-wireless-signal-ok-symbolic.png"))
+        self.labelSignal.setPixmap(QtGui.QPixmap("./icon/network/network-wireless-signal-ok-symbolic.png"))
         self.labelSignal.setScaledContents(False)
         self.labelSignal.setObjectName("labelSignal")
         self.labelBattery = QtWidgets.QLabel(self.widgetInfo)
         self.labelBattery.setGeometry(QtCore.QRect(157, 43, 31, 31))
         self.labelBattery.setToolTip("")
         self.labelBattery.setStatusTip("")
-        self.labelBattery.setPixmap(QtGui.QPixmap("../icon/battery/battery-good-charging-symbolic.png"))
+        self.labelBattery.setPixmap(QtGui.QPixmap("./icon/battery/battery-good-charging-symbolic.png"))
         self.labelBattery.setScaledContents(False)
         self.labelBattery.setObjectName("labelBattery")
         self.buttonSwitchOne = QtWidgets.QToolButton(self.widgetInfo)
         self.buttonSwitchOne.setGeometry(QtCore.QRect(197, 43, 25, 31))
         icon = QtGui.QIcon()
-        icon.addPixmap(QtGui.QPixmap("../icon/switch/switch-one-enabled.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        icon.addPixmap(QtGui.QPixmap("./icon/switch/switch-one-enabled.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
         self.buttonSwitchOne.setIcon(icon)
         self.buttonSwitchOne.setIconSize(QtCore.QSize(30, 30))
         self.buttonSwitchOne.setAutoRaise(True)
@@ -89,11 +89,16 @@ class Ui_IdeasXDevice(object):
         self.buttonSwitchAdaptive = QtWidgets.QToolButton(self.widgetInfo)
         self.buttonSwitchAdaptive.setGeometry(QtCore.QRect(238, 43, 25, 31))
         icon2 = QtGui.QIcon()
-        icon2.addPixmap(QtGui.QPixmap("../icon/switch/switch-adaptive-disabled.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+        icon2.addPixmap(QtGui.QPixmap("./icon/switch/switch-adaptive-disabled.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
         self.buttonSwitchAdaptive.setIcon(icon2)
         self.buttonSwitchAdaptive.setIconSize(QtCore.QSize(30, 30))
         self.buttonSwitchAdaptive.setAutoRaise(True)
         self.buttonSwitchAdaptive.setObjectName("buttonSwitchAdaptive")
+        self.labelOTA = QtWidgets.QLabel(self.widgetInfo)
+        self.labelOTA.setGeometry(QtCore.QRect(272, 45, 36, 26))
+        self.labelOTA.setText("")
+        self.labelOTA.setPixmap(QtGui.QPixmap("./icon/ota/updating.png"))
+        self.labelOTA.setObjectName("labelOTA")
         self.labelDeviceType.raise_()
         self.labelSignal.raise_()
         self.labelBattery.raise_()
@@ -101,6 +106,7 @@ class Ui_IdeasXDevice(object):
         self.buttonSwitchTwo.raise_()
         self.buttonSwitchAdaptive.raise_()
         self.labelModuleID.raise_()
+        self.labelOTA.raise_()
         self.horizontalLayout.addWidget(self.widgetInfo)
         self.widgetControls = QtWidgets.QWidget(IdeasXDevice)
         sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)

+ 11 - 7
pyqt/mainwindow2.py

@@ -109,7 +109,7 @@ class Ui_MainWindow(object):
         self.networkPort.setInputMethodHints(QtCore.Qt.ImhPreferNumbers)
         self.networkPort.setText("")
         self.networkPort.setObjectName("networkPort")
-        self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.networkPort)
+        self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.networkPort)
         self.labelLocalBroker = QtWidgets.QLabel(self.groupNetwork)
         self.labelLocalBroker.setObjectName("labelLocalBroker")
         self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.labelLocalBroker)
@@ -120,14 +120,17 @@ class Ui_MainWindow(object):
         self.localPort = QtWidgets.QLineEdit(self.groupNetwork)
         self.localPort.setInputMethodHints(QtCore.Qt.ImhPreferNumbers)
         self.localPort.setObjectName("localPort")
-        self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.localPort)
+        self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.localPort)
+        self.labelOTA = QtWidgets.QLabel(self.groupNetwork)
+        self.labelOTA.setObjectName("labelOTA")
+        self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.labelOTA)
         self.otaServer = QtWidgets.QLineEdit(self.groupNetwork)
         self.otaServer.setText("")
         self.otaServer.setObjectName("otaServer")
         self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.otaServer)
-        self.labelOTA = QtWidgets.QLabel(self.groupNetwork)
-        self.labelOTA.setObjectName("labelOTA")
-        self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.labelOTA)
+        self.lineEdit_2 = QtWidgets.QLineEdit(self.groupNetwork)
+        self.lineEdit_2.setObjectName("lineEdit_2")
+        self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.lineEdit_2)
         self.verticalLayout_2.addWidget(self.groupNetwork)
         self.buttonBoxNetwork = QtWidgets.QDialogButtonBox(self.tabSetting)
         self.buttonBoxNetwork.setStandardButtons(QtWidgets.QDialogButtonBox.Apply|QtWidgets.QDialogButtonBox.Cancel)
@@ -205,7 +208,7 @@ class Ui_MainWindow(object):
         MainWindow.setStatusBar(self.statusbar)
 
         self.retranslateUi(MainWindow)
-        self.tabWidget.setCurrentIndex(2)
+        self.tabWidget.setCurrentIndex(0)
         QtCore.QMetaObject.connectSlotsByName(MainWindow)
 
     def retranslateUi(self, MainWindow):
@@ -222,8 +225,9 @@ class Ui_MainWindow(object):
         self.labelLocalBroker.setText(_translate("MainWindow", "Local Broker:"))
         self.localBroker.setPlaceholderText(_translate("MainWindow", "URL or IP"))
         self.localPort.setPlaceholderText(_translate("MainWindow", "Port"))
-        self.otaServer.setPlaceholderText(_translate("MainWindow", "URL or IP"))
         self.labelOTA.setText(_translate("MainWindow", "OTA Server:"))
+        self.otaServer.setPlaceholderText(_translate("MainWindow", "URL or IP"))
+        self.lineEdit_2.setPlaceholderText(_translate("MainWindow", "Port"))
         self.groupDeviceSettings.setTitle(_translate("MainWindow", "Device Settings"))
         self.labelAPSelector.setText(_translate("MainWindow", "Wi-Fi Access Point:"))
         self.selectAP.setPrefix(_translate("MainWindow", "Access Point "))

+ 113 - 7
qt/adaptiveswitchconfigdialog.ui

@@ -1,19 +1,125 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>Dialog</class>
- <widget class="QDialog" name="Dialog" >
-  <property name="geometry" >
+ <widget class="QDialog" name="Dialog">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>400</width>
-    <height>300</height>
+    <width>560</width>
+    <height>662</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string>Dialog</string>
   </property>
+  <layout class="QHBoxLayout" name="horizontalLayout">
+   <item>
+    <widget class="QGroupBox" name="groupBox">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="maximumSize">
+      <size>
+       <width>16777215</width>
+       <height>500</height>
+      </size>
+     </property>
+     <property name="title">
+      <string>Adaptive Switch Settings</string>
+     </property>
+     <property name="alignment">
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+     </property>
+     <property name="flat">
+      <bool>false</bool>
+     </property>
+     <property name="checkable">
+      <bool>false</bool>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout">
+      <item>
+       <widget class="QCheckBox" name="checkBox">
+        <property name="text">
+         <string>Enable / Disable</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QRadioButton" name="radioButton_4">
+        <property name="text">
+         <string>Sip + Puff</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QRadioButton" name="radioButton_3">
+        <property name="text">
+         <string>Gesture</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QRadioButton" name="radioButton">
+        <property name="text">
+         <string>Significant Motion</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QRadioButton" name="radioButton_2">
+        <property name="text">
+         <string>Tilt</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QRadioButton" name="radioButton_5">
+        <property name="text">
+         <string>Engineering Interface</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QGroupBox" name="groupBox_2">
+     <property name="title">
+      <string>Parameters</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout">
+      <item row="1" column="1">
+       <widget class="QPushButton" name="pushButton">
+        <property name="text">
+         <string>Send Configuration</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="0">
+       <spacer name="horizontalSpacer">
+        <property name="orientation">
+         <enum>Qt::Horizontal</enum>
+        </property>
+        <property name="sizeHint" stdset="0">
+         <size>
+          <width>40</width>
+          <height>20</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item row="0" column="0" colspan="2">
+       <widget class="QTextBrowser" name="textBrowser"/>
+      </item>
+     </layout>
+    </widget>
+   </item>
+  </layout>
  </widget>
  <resources/>
  <connections/>
 </ui>
-

+ 2 - 2
qt/encoderconfigurationdialog.ui

@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>222</width>
-    <height>190</height>
+    <width>198</width>
+    <height>184</height>
    </rect>
   </property>
   <property name="windowTitle">

+ 18 - 1
qt/ideasxdevice.ui

@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>452</width>
+    <width>522</width>
     <height>84</height>
    </rect>
   </property>
@@ -242,6 +242,22 @@
        <bool>true</bool>
       </property>
      </widget>
+     <widget class="QLabel" name="labelOTA">
+      <property name="geometry">
+       <rect>
+        <x>270</x>
+        <y>45</y>
+        <width>36</width>
+        <height>26</height>
+       </rect>
+      </property>
+      <property name="text">
+       <string/>
+      </property>
+      <property name="pixmap">
+       <pixmap>../icon/ota/updating.png</pixmap>
+      </property>
+     </widget>
      <zorder>labelDeviceType</zorder>
      <zorder>labelSignal</zorder>
      <zorder>labelBattery</zorder>
@@ -249,6 +265,7 @@
      <zorder>buttonSwitchTwo</zorder>
      <zorder>buttonSwitchAdaptive</zorder>
      <zorder>labelModuleID</zorder>
+     <zorder>labelOTA</zorder>
     </widget>
    </item>
    <item>

+ 14 - 7
qt/mainwindow.ui

@@ -60,7 +60,7 @@
        <enum>QTabWidget::West</enum>
       </property>
       <property name="currentIndex">
-       <number>2</number>
+       <number>0</number>
       </property>
       <property name="elideMode">
        <enum>Qt::ElideNone</enum>
@@ -258,7 +258,7 @@
              </property>
             </widget>
            </item>
-           <item row="2" column="1">
+           <item row="1" column="1">
             <widget class="QLineEdit" name="networkPort">
              <property name="inputMethodHints">
               <set>Qt::ImhPreferNumbers</set>
@@ -288,7 +288,7 @@
              </property>
             </widget>
            </item>
-           <item row="5" column="1">
+           <item row="4" column="1">
             <widget class="QLineEdit" name="localPort">
              <property name="inputMethodHints">
               <set>Qt::ImhPreferNumbers</set>
@@ -298,6 +298,13 @@
              </property>
             </widget>
            </item>
+           <item row="6" column="0">
+            <widget class="QLabel" name="labelOTA">
+             <property name="text">
+              <string>OTA Server:</string>
+             </property>
+            </widget>
+           </item>
            <item row="6" column="1">
             <widget class="QLineEdit" name="otaServer">
              <property name="text">
@@ -308,10 +315,10 @@
              </property>
             </widget>
            </item>
-           <item row="6" column="0">
-            <widget class="QLabel" name="labelOTA">
-             <property name="text">
-              <string>OTA Server:</string>
+           <item row="7" column="1">
+            <widget class="QLineEdit" name="lineEdit_2">
+             <property name="placeholderText">
+              <string>Port</string>
              </property>
             </widget>
            </item>

+ 0 - 480
qt/mainwindow.ui.autosave

@@ -1,480 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>525</width>
-    <height>648</height>
-   </rect>
-  </property>
-  <property name="sizePolicy">
-   <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-    <horstretch>0</horstretch>
-    <verstretch>0</verstretch>
-   </sizepolicy>
-  </property>
-  <property name="windowTitle">
-   <string>IdeasX Workstation Client</string>
-  </property>
-  <property name="documentMode">
-   <bool>false</bool>
-  </property>
-  <property name="dockNestingEnabled">
-   <bool>true</bool>
-  </property>
-  <property name="dockOptions">
-   <set>QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks|QMainWindow::VerticalTabs</set>
-  </property>
-  <property name="unifiedTitleAndToolBarOnMac">
-   <bool>false</bool>
-  </property>
-  <widget class="QWidget" name="centralwidget">
-   <property name="sizePolicy">
-    <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-     <horstretch>0</horstretch>
-     <verstretch>0</verstretch>
-    </sizepolicy>
-   </property>
-   <layout class="QVBoxLayout" name="verticalLayout">
-    <property name="spacing">
-     <number>6</number>
-    </property>
-    <property name="sizeConstraint">
-     <enum>QLayout::SetDefaultConstraint</enum>
-    </property>
-    <item>
-     <widget class="QTabWidget" name="tabWidget">
-      <property name="contextMenuPolicy">
-       <enum>Qt::DefaultContextMenu</enum>
-      </property>
-      <property name="layoutDirection">
-       <enum>Qt::LeftToRight</enum>
-      </property>
-      <property name="autoFillBackground">
-       <bool>true</bool>
-      </property>
-      <property name="tabPosition">
-       <enum>QTabWidget::West</enum>
-      </property>
-      <property name="currentIndex">
-       <number>2</number>
-      </property>
-      <property name="elideMode">
-       <enum>Qt::ElideNone</enum>
-      </property>
-      <property name="documentMode">
-       <bool>false</bool>
-      </property>
-      <property name="tabBarAutoHide">
-       <bool>true</bool>
-      </property>
-      <widget class="QWidget" name="tabEncoder">
-       <property name="maximumSize">
-        <size>
-         <width>16777215</width>
-         <height>16777215</height>
-        </size>
-       </property>
-       <attribute name="title">
-        <string>Encoders</string>
-       </attribute>
-       <layout class="QGridLayout" name="gridLayout">
-        <property name="sizeConstraint">
-         <enum>QLayout::SetDefaultConstraint</enum>
-        </property>
-        <property name="leftMargin">
-         <number>9</number>
-        </property>
-        <property name="topMargin">
-         <number>9</number>
-        </property>
-        <property name="rightMargin">
-         <number>9</number>
-        </property>
-        <property name="bottomMargin">
-         <number>9</number>
-        </property>
-        <item row="1" column="2">
-         <widget class="QLineEdit" name="searchEncoder">
-          <property name="placeholderText">
-           <string>Search for Encoders...</string>
-          </property>
-          <property name="clearButtonEnabled">
-           <bool>true</bool>
-          </property>
-         </widget>
-        </item>
-        <item row="1" column="1">
-         <spacer name="horizontalSpacer">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item row="0" column="0" colspan="3">
-         <widget class="QScrollArea" name="scrollEncoder">
-          <property name="autoFillBackground">
-           <bool>false</bool>
-          </property>
-          <property name="styleSheet">
-           <string notr="true"/>
-          </property>
-          <property name="widgetResizable">
-           <bool>true</bool>
-          </property>
-          <widget class="QWidget" name="contentEncoder">
-           <property name="geometry">
-            <rect>
-             <x>0</x>
-             <y>0</y>
-             <width>459</width>
-             <height>556</height>
-            </rect>
-           </property>
-          </widget>
-         </widget>
-        </item>
-       </layout>
-      </widget>
-      <widget class="QWidget" name="tabActuator">
-       <attribute name="title">
-        <string>Actuators</string>
-       </attribute>
-       <layout class="QGridLayout" name="gridLayout_2">
-        <property name="leftMargin">
-         <number>9</number>
-        </property>
-        <property name="topMargin">
-         <number>9</number>
-        </property>
-        <property name="rightMargin">
-         <number>9</number>
-        </property>
-        <property name="bottomMargin">
-         <number>9</number>
-        </property>
-        <item row="1" column="0">
-         <spacer name="horizontalSpacer_2">
-          <property name="orientation">
-           <enum>Qt::Horizontal</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>40</width>
-            <height>20</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-        <item row="1" column="1">
-         <widget class="QLineEdit" name="searchActuator">
-          <property name="autoFillBackground">
-           <bool>false</bool>
-          </property>
-          <property name="frame">
-           <bool>true</bool>
-          </property>
-          <property name="placeholderText">
-           <string>Search for Actuator</string>
-          </property>
-          <property name="clearButtonEnabled">
-           <bool>true</bool>
-          </property>
-         </widget>
-        </item>
-        <item row="0" column="0" colspan="2">
-         <widget class="QTableView" name="tableActuator">
-          <property name="enabled">
-           <bool>true</bool>
-          </property>
-          <property name="frameShadow">
-           <enum>QFrame::Plain</enum>
-          </property>
-          <property name="alternatingRowColors">
-           <bool>true</bool>
-          </property>
-          <property name="showGrid">
-           <bool>false</bool>
-          </property>
-          <property name="sortingEnabled">
-           <bool>true</bool>
-          </property>
-          <attribute name="horizontalHeaderStretchLastSection">
-           <bool>true</bool>
-          </attribute>
-          <attribute name="verticalHeaderVisible">
-           <bool>false</bool>
-          </attribute>
-         </widget>
-        </item>
-       </layout>
-      </widget>
-      <widget class="QWidget" name="tabSetting">
-       <attribute name="title">
-        <string>Settings</string>
-       </attribute>
-       <layout class="QVBoxLayout" name="verticalLayout_2">
-        <property name="leftMargin">
-         <number>9</number>
-        </property>
-        <property name="topMargin">
-         <number>9</number>
-        </property>
-        <property name="rightMargin">
-         <number>9</number>
-        </property>
-        <property name="bottomMargin">
-         <number>9</number>
-        </property>
-        <item>
-         <widget class="QGroupBox" name="groupNetwork">
-          <property name="title">
-           <string>Network Settings</string>
-          </property>
-          <layout class="QFormLayout" name="formLayout">
-           <item row="0" column="0">
-            <widget class="QLabel" name="labelNetworkBroker">
-             <property name="text">
-              <string>Network Broker:</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="1">
-            <widget class="QLineEdit" name="networkBroker">
-             <property name="inputMethodHints">
-              <set>Qt::ImhUrlCharactersOnly</set>
-             </property>
-             <property name="placeholderText">
-              <string>URL or IP</string>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="1">
-            <widget class="QLineEdit" name="networkPort">
-             <property name="inputMethodHints">
-              <set>Qt::ImhPreferNumbers</set>
-             </property>
-             <property name="text">
-              <string/>
-             </property>
-             <property name="placeholderText">
-              <string>Port</string>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="0">
-            <widget class="QLabel" name="labelLocalBroker">
-             <property name="text">
-              <string>Local Broker:</string>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="1">
-            <widget class="QLineEdit" name="localBroker">
-             <property name="inputMethodHints">
-              <set>Qt::ImhUrlCharactersOnly</set>
-             </property>
-             <property name="placeholderText">
-              <string>URL or IP</string>
-             </property>
-            </widget>
-           </item>
-           <item row="5" column="1">
-            <widget class="QLineEdit" name="localPort">
-             <property name="inputMethodHints">
-              <set>Qt::ImhPreferNumbers</set>
-             </property>
-             <property name="placeholderText">
-              <string>Port</string>
-             </property>
-            </widget>
-           </item>
-           <item row="6" column="1">
-            <widget class="QLineEdit" name="otaServer">
-             <property name="text">
-              <string/>
-             </property>
-             <property name="placeholderText">
-              <string>URL or IP</string>
-             </property>
-            </widget>
-           </item>
-           <item row="6" column="0">
-            <widget class="QLabel" name="labelOTA">
-             <property name="text">
-              <string>OTA Server:</string>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </widget>
-        </item>
-        <item>
-         <widget class="QDialogButtonBox" name="buttonBoxNetwork">
-          <property name="standardButtons">
-           <set>QDialogButtonBox::Apply|QDialogButtonBox::Cancel</set>
-          </property>
-         </widget>
-        </item>
-        <item alignment="Qt::AlignTop">
-         <widget class="QGroupBox" name="groupDeviceSettings">
-          <property name="title">
-           <string>Device Settings</string>
-          </property>
-          <layout class="QFormLayout" name="formLayout_2">
-           <item row="1" column="0">
-            <widget class="QLabel" name="labelAPSelector">
-             <property name="text">
-              <string>Wi-Fi Access Point:</string>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="1">
-            <widget class="QSpinBox" name="selectAP">
-             <property name="suffix">
-              <string/>
-             </property>
-             <property name="prefix">
-              <string>Access Point </string>
-             </property>
-             <property name="minimum">
-              <number>1</number>
-             </property>
-             <property name="maximum">
-              <number>5</number>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="0">
-            <widget class="QLabel" name="labelSSID">
-             <property name="text">
-              <string>SSID:</string>
-             </property>
-            </widget>
-           </item>
-           <item row="2" column="1">
-            <widget class="QLineEdit" name="wifiSSID"/>
-           </item>
-           <item row="3" column="0">
-            <widget class="QLabel" name="labelPassword">
-             <property name="text">
-              <string>Password:</string>
-             </property>
-            </widget>
-           </item>
-           <item row="3" column="1">
-            <widget class="QLineEdit" name="wifiPassword"/>
-           </item>
-          </layout>
-         </widget>
-        </item>
-        <item>
-         <widget class="QDialogButtonBox" name="buttonBoxDevice">
-          <property name="standardButtons">
-           <set>QDialogButtonBox::Cancel|QDialogButtonBox::Save</set>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QGroupBox" name="groupUpdat">
-          <property name="title">
-           <string>WSC Update Settings</string>
-          </property>
-          <layout class="QFormLayout" name="formLayout_3">
-           <item row="0" column="1">
-            <widget class="QLineEdit" name="lineEdit">
-             <property name="placeholderText">
-              <string>URL to GitHub Repository</string>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="0">
-            <widget class="QPushButton" name="pushButton">
-             <property name="text">
-              <string>Check for Update</string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="0">
-            <widget class="QLabel" name="label">
-             <property name="text">
-              <string>WSC Software Repository:</string>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </widget>
-        </item>
-        <item>
-         <widget class="QGroupBox" name="groupBox_2">
-          <property name="title">
-           <string>Global Commands</string>
-          </property>
-          <layout class="QFormLayout" name="formLayout_4">
-           <item row="0" column="0">
-            <widget class="QLabel" name="label_2">
-             <property name="text">
-              <string>Global Command: </string>
-             </property>
-            </widget>
-           </item>
-           <item row="0" column="1">
-            <widget class="QComboBox" name="comboBox">
-             <property name="currentText">
-              <string/>
-             </property>
-            </widget>
-           </item>
-           <item row="1" column="0">
-            <widget class="QPushButton" name="pushButton_2">
-             <property name="text">
-              <string>Send Command</string>
-             </property>
-            </widget>
-           </item>
-          </layout>
-         </widget>
-        </item>
-        <item>
-         <spacer name="verticalSpacer">
-          <property name="orientation">
-           <enum>Qt::Vertical</enum>
-          </property>
-          <property name="sizeHint" stdset="0">
-           <size>
-            <width>20</width>
-            <height>40</height>
-           </size>
-          </property>
-         </spacer>
-        </item>
-       </layout>
-      </widget>
-     </widget>
-    </item>
-   </layout>
-  </widget>
-  <widget class="QStatusBar" name="statusbar">
-   <property name="enabled">
-    <bool>true</bool>
-   </property>
-   <property name="toolTipDuration">
-    <number>-7</number>
-   </property>
-   <property name="layoutDirection">
-    <enum>Qt::RightToLeft</enum>
-   </property>
-  </widget>
- </widget>
- <resources/>
- <connections/>
-</ui>

Some files were not shown because too many files changed in this diff