def endCurrentSession(self): """ Ends a running session :return: """ self.programQuit.set() # Signal remote add thread to stop self.shouldEnd.set() # Signal local add thread endTimestamp = datetime.datetime.now() endTimestamp = endTimestamp.strftime( "%Y-%m-%d %H:%M:%S") # Get timestamp configInterface.setConfig( 'config.cfg', 'latestsession', {'end': endTimestamp}) # Write the timestamp to configfile self.widgetList.mainMenu.sessionEnded() # Change main menu appearance Database.endCurrentSession( self.localDatabase, self.localSessionId) # Give the local session an end time if self.useRemote: # If using remote self.shouldEndRemote.set() Database.endCurrentSession( self.remoteDatabase, self.remoteSessionId) # Give the remote session an end time self.dataDisplay.close() # Close the datadisplay window self.sessionRunning = False self.showMainMenu() # Display main menu
def nextPage(self): """ Handles what happens when the next button is pressed :return: """ errorocurred = False if self.remote: # If a remote database should be used host = self.databaseform.host.text() user = self.databaseform.user.text() port = self.databaseform.port.text() name = self.databaseform.database.text() password = self.databaseform.password.text() if not host: message = "Du måste ange en host" self._messageToUser(messagetext=message, closebuttontext="Stäng") errorocurred = True elif not user: message = "Du måste ange en användare" self._messageToUser(messagetext=message, closebuttontext="Stäng") errorocurred = True elif not port: message = "Du måste ange en port" self._messageToUser(messagetext=message, closebuttontext="Stäng") errorocurred = True elif not name: message = "Du måste ange en databas" self._messageToUser(messagetext=message, closebuttontext="Stäng") errorocurred = True elif not password: message = "Du måste ange ett lösenord" self._messageToUser(messagetext=message, closebuttontext="Stäng") errorocurred = True else: newremotevalues = { 'host': host, 'user': user, 'port': port, 'name': name, 'password': password } configInterface.setConfig( 'config.cfg', self.writesection, newremotevalues ) # Write the database settings to the configfile if not errorocurred: self.okPressed.emit() # Emit the okPressed signal
def _nextPage(self): """ Handles what happens when the next button is pressed :return: """ exceptionraised = False self.channellist = {} channellistforwrite = {} try: for i in range(60): # For each row in the table item = self.tableWidget.item(i, 0) if item.checkState( ) == QtCore.Qt.Checked: # If a channel has been chosen channelid = "%d" % (i + 1) channelidalias = "%s" % ( self.tableWidget.verticalHeaderItem(i).text(), ) channelunit = "%s" % (self.tableWidget.item(i, 1).text(), ) channeltolerance = "%s" % (self.tableWidget.item( i, 2).text(), ) channelname = "%s" % (self.tableWidget.item(i, 3).text(), ) channelstorhet = "%s" % (self.tableWidget.cellWidget( i, 4).currentText()) if channelname == "": raise AttributeError if channelname in self.channellist: exceptionraised = True duplicatenames = "Kanalnamn måste vara unika!" self._messageToUser(duplicatenames, closebuttontext="Stäng") break self.channellist[channelname] = \ [channelid, channelunit, channeltolerance, channelidalias, channelstorhet] # Collect channel information and add it to the list of channels channellistforwrite[channelname] = \ str([channelid, channelunit, channeltolerance, channelidalias, channelstorhet]) float( channeltolerance ) # Raises a ValueError if channeltolerance can not be converted to float self.sessionname = self.nameinput.text() self.sessionintervall = self.intervallinput.text() try: self.sessionintervall = float( self.sessionintervall ) # Check if intervall is correct type except ValueError: exceptionraised = True wrongintervalltype = "Tidsintervall måste anges som ett nummer" self._messageToUser(wrongintervalltype, closebuttontext="Stäng" ) # If not, prompt user with error message if not self.sessionname: # If no text in name field noname = "Du måste namnge mätningen" self._messageToUser( noname, closebuttontext="Stäng") # Prompt user with a message elif not self.sessionintervall: # else if ni text in intervall field nointervall = "Du måste ange ett tidsintervall" self._messageToUser( nointervall, closebuttontext="Stäng") # Prompt user with a message elif self.channellist == {}: # If no channel has been selected nochannels = "Du måste välja minst en kanal!" self._messageToUser( nochannels, closebuttontext="Stäng") # Prompt the user with a message elif not exceptionraised: self.okPressed.emit( ) # If no error, emit signal to change page parser = configparser.ConfigParser() with open('config.cfg', 'r+') as r: # Reads from the configfile parser.read_file(r) parser.remove_section( 'channels') # Removes the previous channels with open('config.cfg', 'w+') as w: parser.write(w) # Writes the removal to the file configInterface.setConfig( 'config.cfg', 'channels', channellistforwrite ) # Writes the new channels to the configfile except AttributeError: # A channel is missing some input textmissing = \ "Kanal %s saknar nödvändig information!" % (channelidalias) self._messageToUser( textmissing, closebuttontext="Stäng" ) # Tell the user which channel is missing input self.channellist = {} except ValueError: # Wrong type has been inputted into the tolerance field wronginputtype = \ "Kanal %s har fel typ av tolerans, " \ "tolerans ska vara ett flyttal t.ex. 42.0" \ % (channelidalias) self._messageToUser( wronginputtype, closebuttontext="Stäng" ) # Tell the user which channel has wrong type of tolerance self.channellist = {}
def run(self): """ Fetches values from a local database and adds them to a remote database :return: """ pid = configInterface.readConfig('config.cfg', 'piid') piid = int( pid['piid']) # Gets the id of the Raspberry pi running the program while not self.addedAllData: try: if self.programQuit.wait( 0): # If signaled that the program wants to terminate self.timeInterval = 0 # Do additions immediately if not self.shouldEnd.wait( self.timeInterval * 10): # Wait for timeintervall seconds sessionSettings = configInterface.readConfig( 'config.cfg', 'latestsession') start = sessionSettings['start'] end = sessionSettings[ 'end'] # Get previous previous search parameters if not end == '': # If the session has been ended checkEnd = datetime.datetime.strptime( end, '%Y-%m-%d %H:%M:%S') checkStart = datetime.datetime.strptime( start, '%Y-%m-%d %H:%M:%S') if checkEnd > checkStart: # Check if the last search parameter is greater than the end value fo the session self.addedAllData = True end = datetime.datetime.now( ) # Get new end value to use in local database search valueList = Database.getMeasurements( databaseValues=self.localDatabase, sessionId=self.sessionId, channelId=None, startTime=start, endTime=end ) # Get measurements from the local database templatestAddTime = None templatestAddFractions = None new = [] for row in valueList: # For each row in the result timestamp = row[2].strftime('%Y-%m-%d %H:%M:%S') timestampFractions = row[3] templatestAddTime = row[2].strftime( '%Y-%m-%d %H:%M:%S') templatestAddFractions = row[3] data = row[4] # Add measurementvalues to a new list remoteChannel = row[1] + 60 * ( piid - 1) # Convert local id to remoteid if not (timestamp == self.latestAddTime and timestampFractions == self.latestAddFractions): new.append( (self.remoteSessionId, remoteChannel, timestamp, timestampFractions, data) ) # If the timestamp in this result matches the last timestamp in the previous result # dont add it to the new list if not new == []: Database.remoteAddToDatabase( self.remoteDatabase, new ) # If the list is not empty, add values to the remote database self.latestAddTime = templatestAddTime self.latestAddFractions = templatestAddFractions # Set latest add timestamp if self.databaseIsDown: # If the database was down, the database is now up since the addition was succesful self.connectionEstablished.emit( ) # Signals main thread that the database is connected self.databaseIsDown = False newStart = end.strftime( '%Y-%m-%d %H:%M:%S' ) # Write the end time used in the search to the configfile # To be used as start time in the next search configInterface.setConfig('config.cfg', 'latestsession', {'start': newStart}) else: self.shouldEnd.clear() except pymysql.err.Error as E: # If the database raises an exception if not self.databaseIsDown: self.noConnection.emit( ) # Signal the main thread that the database is down self.databaseIsDown = True print(E) self.programQuit.clear()
def startSession(self): """ Starts a new session :return: """ try: w = self.widgetList.widget settings = self.widgetList.channelSettingsIndex self.useRemote = w( self.widgetList.databaseSettingsIndex).useRemote( ) # Checks if a remote database should be used self.localDatabase = configInterface.readConfig( 'config.cfg', 'default') # Gets configuration for the local database sessionName = w(settings).sessionname # Gets the sessionname channelList = w( settings ).channellist # Gets a list of channels to use in the session timeInterval = w(settings).sessionintervall localChannels = copy.deepcopy( channelList) # Gets the time intervall for the session if self.useRemote: # If a remote should be used self.remoteDatabase = \ configInterface.readConfig('config.cfg', 'remote') # Get remote database configurations if configInterface.hasSection('config.cfg', 'piid'): identifiers = configInterface.readConfig( 'config.cfg', 'piid') self.uuid = identifiers['uuid'] if not Database.remotePiExists(self.remoteDatabase, identifiers['uuid']): newIdentifiers = Database.remoteAddNewPi( self.remoteDatabase) print(newIdentifiers) configInterface.setConfig('config.cfg', 'piid', {'piid': str(self.piid)}) else: self.piid = Database.remoteGetPiid( self.remoteDatabase, self.uuid) configInterface.setConfig('config.cfg', 'piid', {'piid': str(self.piid)}) else: newIdentifiers = Database.remoteAddNewPi( self.remoteDatabase) print(newIdentifiers) self.uuid = newIdentifiers['uuid'] self.piid = int(newIdentifiers['piid']) configInterface.setConfig('config.cfg', 'piid', { 'uuid': self.uuid, 'piid': str(self.piid) }) remoteChannels = self.convertToRemoteChannels(channelList) self.remoteSessionId = \ Database.remoteStartNewSession(databaseValues=self.remoteDatabase, name=sessionName, channels=remoteChannels, piid=self.uuid) # Make a new session entry to the remote database self.localSessionId = \ Database.startNewSession(databaseValues=self.localDatabase, name=sessionName, channels=localChannels) # Make a new session entry to the local database currentTime = datetime.datetime.now() startSearchValue = currentTime.strftime('%Y-%m-%d %H:%M:%S') startFractions = str( currentTime.microsecond) # Get timestamp for session start writeItem = { 'start': startSearchValue, 'startfractions': startFractions, 'localdatabase': str(self.localDatabase), 'localsessionid': str(self.localSessionId), 'timeintervall': str(timeInterval), 'end': '' } # Add session information to configfile if self.useRemote: # If a remote is used writeItem['remotedatabase'] = str(self.remoteDatabase) writeItem['remotesessionid'] = str( self.remoteSessionId ) # Add information about the remote session parser = configparser.ConfigParser() with open('config.cfg', 'r') as r: parser.read_file(r) parser.remove_section( 'latestsession' ) # Remove previous information from the configfile with open('config.cfg', 'w') as w: parser.write(w) configInterface.setConfig( 'config.cfg', 'latestsession', writeItem) # Write the new information to the configfile addThread = Addthread(localDatabase=self.localDatabase, sessionId=self.localSessionId, shouldEnd=self.shouldEnd, channelList=localChannels, timeInterval=timeInterval) addThread.start( ) # Create a thread for adding to the local database and start it if self.useRemote: # If a remote database is used remoteAddThread = AddRemoteThread( remoteDatabase=self.remoteDatabase, localDatabase=self.localDatabase, remoteSessionId=self.remoteSessionId, sessionId=self.localSessionId, shouldEnd=self.shouldEndRemote, programQuit=self.programQuit, timeInterval=timeInterval) remoteAddThread.connectionEstablished.connect( self.stopWarningUser) remoteAddThread.noConnection.connect(self.warnUser) remoteAddThread.start( ) # Create a thread for adding to the remote database and start it self.dataDisplay = DataDisplay( databaseValues=self.localDatabase, sessionId=self.localSessionId, channelList=localChannels, ongoing=True, timeInterval=timeInterval ) # Create a new window for displaying data self.dataDisplay.show() # Show the window self.widgetList.mainMenu.sessionStarted( ) # Change appearance of mainmenu self.showMainMenu() # Display the mainmeny self.sessionRunning = True except pymysql.err.Error as E: if E.args[0] == 1045: # If mysql connection denied message = "Anslutning nekad, se över port, användare och lösenord" self.messageToUser(messageText=message, closeButtonText="Stäng") if E.args[0] == 2003: # If mysql connection cant be found message = "Kunde inte anluta till host: '%s'" % ( self.remoteDatabase['host']) self.messageToUser(messageText=message, closeButtonText="Stäng") if E.args[0] == 1049: # If the database wasnt found message = "Hittade ingen database med namnet '%s'" % ( self.remoteDatabase['name']) self.messageToUser(messageText=message, closeButtonText="Stäng") if E.args[0] == 1062: # If mysql integrity error message = "Minst två kanaler har samma namn. Kanalnamn måste vara unika" self.messageToUser(messageText=message, closeButtonText="Stäng") except ValueError as V: # If wrong value in port field print(V) wrongPortType = "Fel typ för 'Port', ett heltal förväntas" self.messageToUser(messageText=wrongPortType, closeButtonText="Stäng")