Source code for NDMonitor.StartNewServer

"""
General server class.
Should not depend on the monitored device.

        Main functions of server:
        1. start server waiting for clients to connect, if connected - send values
        2. start reading from device using driver file
        3. log the data to the text file

Last updated: 02 Apr 2020
Created on Sat Apr 21 13:54:20 2018

@author: Victor Rogalev
"""
import _thread
import datetime as dt
import importlib
import shutil
import socket
import time
import os

from NDMonitor.List_Of_Servers import server_list
from NDMonitor.RepeatedTimer import RepeatedTimer


[docs]class PressureServer(): """Desciption of a pressure server class""" def __init__(self, name_id): super(self.__class__, self).__init__() print('new server being initialized') self.connections_counter = 0 self.pressure = '' self.name_id = name_id """find out parameters for the given server name_id""" self.host = server_list[self.name_id][0] self.port = server_list[self.name_id][1] self.com_port_name = server_list[self.name_id][2] self.driver_module = importlib.import_module(server_list[self.name_id][3]) # import driver module self.driver = self.driver_module.Driver(self.com_port_name) # initialize driver """configure initial logging""" self.filename_dynamic = self.name_id + '-log-dynamic.dat' self.old_filename = "" self.path = os.getcwd() self.log_path = self.path + "/logs" with open(self.filename_dynamic, "w+") as f: f.write('\n')
[docs] def start(self): """ Main functions of server: 1. start server waiting for clients to connect, if connected - send values 2. start reading from device using driver file 3. log the data """ """ self.get_pressure_thread every self.timing second receives pressure string from controller unit and logs it to a text file. Moved to a separate thread. """ self.timing = 1 self.get_pressure_loop = RepeatedTimer(self.timing, self.update_pressure_thread) _thread.start_new_thread(self.get_pressure_loop.start, ()) self.s = socket.socket() # Create a socket object self.s.bind((self.host, self.port)) # Bind to the port self.s.listen() # Enable client connection. print('Server started!\n Waiting for clients...') """ Here comes infinite loop constantly trying to accept connection """ while True: try: print('now will try to accept connection') c, addr = self.s.accept() # Establish connection with client. print('Got connection from', addr) self.connections_counter += 1 print('connected ', str(self.connections_counter), ' client(s)') _thread.start_new_thread(self.on_new_client, (c,)) except: pass
[docs] def on_new_client(self, client_socket): """ This function is called in a separate thread from start() function! Waits for incoming message from client and sends back pressure string. """ while True: time.sleep(0.5) # while loop discriminator - otherwise overload msg = client_socket.recv(1024) if not msg: self.connections_counter -= 1 break if msg.decode() == 'so you think you can tell': # print ("received from host: ", msg.decode()) client_socket.send(self.pressure.encode()) elif ("SETP" in msg.decode()) or ("RANGE" in msg.decode()): self.get_pressure_loop.stop() print("sending command ", msg.decode()) flag = True while flag: time.sleep(0.4) try: value = self.driver.get_pressure(msg.decode()) flag = False if value else True except: print("error setting command") pass client_socket.send(value.encode()) self.get_pressure_loop.start() else: pass print('connected ', str(self.connections_counter), ' client(s)') client_socket.shutdown(socket.SHUT_RDWR) client_socket.close()
[docs] def update_pressure_thread(self): """ start reading from device using driver file """ try: self.pressure = self.driver.get_pressure() # self.pressure is a STRING! print(self.pressure) self.log_the_data() except: print('no pressure received') pass
[docs] def log_the_data(self): # TODO: save log files to a separate folder """ Log the data to a file """ filename = self.name_id + '_log_' + dt.datetime.now().strftime("%y-%m-%d") + '.dat' """ empty dynamic file if new day """ if self.old_filename != filename: with open(self.filename_dynamic, "w+") as f: f.write('\n') self.old_filename = filename """ add comma in the end if missing """ if self.pressure[-1]!=",": self.pressure += "," """ write the value into dynamic file and copy it to log file """ with open(self.filename_dynamic, "a+") as f: log_data = dt.datetime.now().strftime("%H:%M:%S") + ',' + self.pressure + '\n' f.write(log_data) shutil.copy2(self.filename_dynamic, filename)
[docs]def new_server(*args): """ This function is called from the MainServer script to start a new server """ print('starting a new server') server_1 = PressureServer(*args) server_1.start()