Commit f0c9daeeb5c3777e531a3078f4e250e19c8595c4

Authored by bdubois
1 parent 861b8b8a60
Exists in master

Mainly cosmetic changes and add decode/encode to read/write procedure on socket

Showing 1 changed file with 28 additions and 38 deletions Inline Diff

eddsctrl_server/eddsctrlserver
#!/usr/bin/python2.7 1 1 #!/usr/bin/python3
# -*- coding: utf-8 -*- 2 2 # -*- coding: utf-8 -*-
3 3
"""package eddsctrl_server 4 4 """package eddsctrl_server
author Benoit Dubois 5 5 author Benoit Dubois
copyright FEMTO ENGINEERING 6 6 copyright FEMTO ENGINEERING
license GPL v3.0+ 7 7 license GPL v3.0+
brief DDS controller, server part. 8 8 brief DDS controller, server part.
details This package provides interface to handle DDS package. 9 9 details This package provides interface to handle DDS package.
This package implements server part of a client/server architecture. 10 10 This package implements server part of a client/server architecture.
Code inspired from Python Module of the Week website (BSD licence): 11 11 Code inspired from Python Module of the Week website (BSD licence):
http://pymotw.com/2/select/ 12 12 http://pymotw.com/2/select/
for the logic and from: 13 13 for the logic and from:
http://eli.thegreenplace.net/2011/08/02/length-prefix-framing-for-protocol-buffers/ 14 14 http://eli.thegreenplace.net/2011/08/02/length-prefix-framing-for-protocol-buffers/
for the message using the length prefix technique. 15 15 for the message using the length prefix technique.
""" 16 16 """
17 17
import logging 18 18 # Ctrl-c closes the application
CONSOLE_LOG_LEVEL = logging.DEBUG 19 19 import signal
FILE_LOG_LEVEL = logging.DEBUG 20 20 signal.signal(signal.SIGINT, signal.SIG_DFL)
21 21
import os 22 22 import os
try: 23 23 import logging
import configparser 24 24 import configparser
except ImportError: 25 25 from queue import Queue, Empty
import ConfigParser as configparser 26
try: 27
from queue import Queue, Empty 28
except ImportError: 29
from Queue import Queue, Empty 30
from struct import pack, unpack 31 26 from struct import pack, unpack
from select import select 32 27 from select import select
from socket import socket, AF_INET, SOCK_STREAM 33 28 from socket import socket, AF_INET, SOCK_STREAM
34 29
from dds.ad9912dev import Ad9912Dev as DdsDevice # for actual use 35 30 from dds.ad9912dev import Ad9912Dev as DdsDevice # for actual use
#from dds.dds_emul import TestUsbDds as DdsDevice # for test without DDS 36 31 #from dds.dds_emul import TestUsbDds as DdsDevice # for test without DDS
37 32 from eddsctrl_server.constants import SERVER_PORT, SERVERHOST, \
from eddsctrl_server.constants import APP_NAME, SERVER_PORT, SERVERHOST, \ 38
DEFAULT_IFREQ, DEFAULT_OFREQ, DEFAULT_AMP, DEFAULT_PHY, \ 39 33 DEFAULT_IFREQ, DEFAULT_OFREQ, DEFAULT_AMP, DEFAULT_PHY, \
CFG_SERVER_FILE, LOG_SERVER_FILE 40 34 CFG_SERVER_FILE, LOG_SERVER_FILE
41 35
36 CONSOLE_LOG_LEVEL = logging.DEBUG
37 FILE_LOG_LEVEL = logging.DEBUG
42 38
#============================================================================== 43 39 #==============================================================================
class EDdsCtrlServer(object): 44 40 class EDdsCtrlServer(object):
"""Class dedicated to interface socket client with DDS device. 45 41 """Class dedicated to interface socket client with DDS device.
Provide a basic interface to handle client queries: 46 42 Provide a basic interface to handle client queries:
Message is built using the length prefix technique: length is sent as a 47 43 Message is built using the length prefix technique: length is sent as a
packed 4-byte little-endian integer. 48 44 packed 4-byte little-endian integer.
Allow only 4 queries, changement of output frequency, input frequency, 49 45 Allow only 4 queries, changement of output frequency, input frequency,
phase or amplitude value. 50 46 phase or amplitude value.
Message structure is simple: 51 47 Message structure is simple:
- Length of message, 52 48 - Length of message,
- Exclamation mark 53 49 - Exclamation mark
- Character identifier, 54 50 - Character identifier,
- Exclamation mark 55 51 - Exclamation mark
- Value 56 52 - Value
- Exclamation mark 57 53 - Exclamation mark
There are 8 valid identifiers: 58 54 There are 8 valid identifiers:
- 'o[?]' for set/get output frequency 59 55 - 'o[?]' for set/get output frequency
- 'i[?]' for set/get input frequency 60 56 - 'i[?]' for set/get input frequency
- 'p[?]' for set/get phase 61 57 - 'p[?]' for set/get phase
- 'a[?]' for set/get amplitude 62 58 - 'a[?]' for set/get amplitude
""" 63 59 """
64 60
def __init__(self, settings_file=None): 65 61 def __init__(self, settings_file=None):
"""Constructor: initialize the server. 66 62 """Constructor: initialize the server.
:param settings_file: file containing setting data value (str) 67 63 :param settings_file: file containing setting data value (str)
:returns: None 68 64 :returns: None
""" 69 65 """
# Retrieve parameter values from 'ini' file 70 66 # Retrieve parameter values from 'ini' file
if settings_file is None: 71 67 if settings_file is None:
raise ValueError("Parameter settings_file missing.") 72 68 raise ValueError("Parameter settings_file missing.")
self._settingsf = settings_file 73 69 self._settingsf = settings_file
config = configparser.ConfigParser() 74 70 config = configparser.ConfigParser()
config.read(settings_file) 75 71 config.read(settings_file)
try: 76 72 try:
self._port = config.getint('dds_ctrl', 'server_port') 77 73 self._port = config.getint('dds_ctrl', 'server_port')
ifreq = config.getfloat('dds_ctrl', 'ifreq') 78 74 ifreq = config.getfloat('dds_ctrl', 'ifreq')
ofreq = config.getfloat('dds_ctrl', 'ofreq') 79 75 ofreq = config.getfloat('dds_ctrl', 'ofreq')
phase = config.getfloat('dds_ctrl', 'phase') 80 76 phase = config.getfloat('dds_ctrl', 'phase')
amp = config.getint('dds_ctrl', 'amp') 81 77 amp = config.getint('dds_ctrl', 'amp')
except KeyError as ex: 82 78 except KeyError as ex:
logging.critical("Correct or delete the configuration file.") 83 79 logging.critical("Correct or delete the configuration file.")
raise KeyError("Key %s not found in configuration file:"% str(ex)) 84 80 raise KeyError("Key %s not found in configuration file:"% str(ex))
# Init devices 85 81 # Init devices
self._init_dds(ifreq, ofreq, phase, amp) 86 82 self._init_dds(ifreq, ofreq, phase, amp)
self._init_server() 87 83 self._init_server()
# Start threaded server 88 84 # Start threaded server
self._server_loop() 89 85 self._server_loop()
90 86
def _init_dds(self, ifreq, ofreq, phase, amp): 91 87 def _init_dds(self, ifreq, ofreq, phase, amp):
"""Create and configure a DDS object. 92 88 """Create and configure a DDS object.
:param ifreq: dds input frequency (float) 93 89 :param ifreq: dds input frequency (float)
:param ofreq: dds output frequency (float) 94 90 :param ofreq: dds output frequency (float)
:param phase: dds output phase (float) 95 91 :param phase: dds output phase (float)
:param amp: dds output amplitude (int) 96 92 :param amp: dds output amplitude (int)
:returns: None 97 93 :returns: None
""" 98 94 """
self._dds = DdsDevice() 99 95 self._dds = DdsDevice()
try: 100 96 try:
self._dds.set_ifreq(ifreq) 101 97 self._dds.set_ifreq(ifreq)
self._dds.set_ofreq(ofreq) 102 98 self._dds.set_ofreq(ofreq)
self._dds.set_phy(phase) 103 99 self._dds.set_phy(phase)
self._dds.set_amp(amp) 104 100 self._dds.set_amp(amp)
self._dds.set_hstl_output_state(False) 105 101 self._dds.set_hstl_output_state(False)
self._dds.set_cmos_output_state(False) 106 102 self._dds.set_cmos_output_state(False)
except Exception as ex: 107 103 except Exception as ex:
raise Exception("Unexpected error during DDS initialisation: %s" \ 108 104 raise Exception("Unexpected error during DDS initialisation: %s" \
% str(ex)) 109 105 % str(ex))
logging.debug("DDS inititialization done") 110 106 logging.debug("DDS inititialization done")
111 107
def _init_server(self): 112 108 def _init_server(self):
"""Create and configure a basic server object. 113 109 """Create and configure a basic server object.
:returns: None 114 110 :returns: None
""" 115 111 """
try: 116 112 try:
self.server = socket(AF_INET, SOCK_STREAM) 117 113 self.server = socket(AF_INET, SOCK_STREAM)
self.server.setblocking(0) 118 114 self.server.setblocking(0)
host = SERVERHOST # Get local machine name 119 115 host = SERVERHOST # Get local machine name
self.server.bind((host, self._port)) # Bind to the port 120 116 self.server.bind((host, self._port)) # Bind to the port
self.server.listen(3) # Now wait for client connection 121 117 self.server.listen(3) # Now wait for client connection
except IOError as ex: 122 118 except IOError as ex:
raise IOError("EDDSCTRLSERVER: %s, have you closed properly the " \ 123 119 raise IOError("EDDSCTRLSERVER: %s, have you closed properly the " \
"server? " % str(ex)) 124 120 "server? " % str(ex))
except Exception as ex: 125 121 except Exception as ex:
raise Exception("EDDSCTRLSERVER: unexpected error during server " \ 126 122 raise Exception("EDDSCTRLSERVER: unexpected error during server " \
"initialisation: %s" % str(ex)) 127 123 "initialisation: %s" % str(ex))
# Sockets from which we expect to read 128 124 # Sockets from which we expect to read
self.inputs = [self.server] 129 125 self.inputs = [self.server]
# Sockets to which we expect to write 130 126 # Sockets to which we expect to write
self.outputs = [] 131 127 self.outputs = []
# Outgoing message queues (socket:Queue) 132 128 # Outgoing message queues (socket:Queue)
self.message_queues = {} 133 129 self.message_queues = {}
logging.debug("Server initialization done") 134 130 logging.debug("Server initialization done")
135 131
def _server_loop(self): 136 132 def _server_loop(self):
"""Main server loop: Handle connection, read and write on server socket. 137 133 """Main server loop: Handle connection, read and write on server socket.
:returns: None 138 134 :returns: None
""" 139 135 """
while self.inputs: 140 136 while self.inputs:
# Await an event on a readable socket descriptor 141 137 # Await an event on a readable socket descriptor
readable, writable, exceptional = select(self.inputs, \ 142 138 readable, writable, exceptional = select(self.inputs, \
self.outputs, \ 143 139 self.outputs, \
self.inputs) 144 140 self.inputs)
# Handle inputs 145 141 # Handle inputs
self._handle_readable(readable) 146 142 self._handle_readable(readable)
# Handle outputs 147 143 # Handle outputs
self._handle_writable(writable) 148 144 self._handle_writable(writable)
# Handle exceptional condition 149 145 # Handle exceptional condition
self._handle_exceptional(exceptional) 150 146 self._handle_exceptional(exceptional)
151 147
def _handle_readable(self, socket_list): 152 148 def _handle_readable(self, socket_list):
"""Read message from client. 153 149 """Read message from client.
Message is built using the length prefix technique. See: 154 150 Message is built using the length prefix technique. See:
http://eli.thegreenplace.net/2011/08/02/length-prefix-framing-for-protocol-buffers/ 155 151 http://eli.thegreenplace.net/2011/08/02/length-prefix-framing-for-protocol-buffers/
:param socket_list: List of socket usable to receive data 156 152 :param socket_list: List of socket usable to receive data
:returns: None 157 153 :returns: None
""" 158 154 """
for sock in socket_list: 159 155 for sock in socket_list:
# Received a connect to the server (listening) socket 160 156 # Received a connect to the server (listening) socket
if sock is self.server: 161 157 if sock is self.server:
self._accept_connect() 162 158 self._accept_connect()
# Established connection 163 159 # Established connection
else: 164 160 else:
header_data = self._recv_n_bytes(sock, 4) 165 161 header_data = self._recv_n_bytes(sock, 4)
if header_data == None: 166 162 if header_data is None:
logging.error("Message seems received but no data to read") 167 163 logging.error("Message seems received but no data to read")
return 168 164 return
if len(header_data) == 4: 169 165 if len(header_data) == 4:
msg_len = unpack('<L', header_data)[0] 170 166 msg_len = unpack('<L', header_data)[0]
data = self._recv_n_bytes(sock, msg_len) 171 167 data = self._recv_n_bytes(sock, msg_len).decode('utf-8')
# Check message validity 172 168 # Check message validity
if data == None: 173 169 if data is None:
logging.error("Message received but no data to read") 174 170 logging.error("Message received but no data to read")
return 175 171 return
if len(data) != msg_len: 176 172 if len(data) != msg_len:
logging.error("Bad message length") 177 173 logging.error("Bad message length")
return 178 174 return
logging.debug("receive %s from %s", \ 179 175 logging.debug("receive %s from %s", \
data, sock.getpeername()) 180 176 data, sock.getpeername())
# Handle message 181 177 # Handle message
ret_data = self._input_msg_handler(data) 182 178 ret_data = self._input_msg_handler(data)
# Return data to client 183 179 # Return data to client
self.message_queues[sock].put(ret_data) 184 180 self.message_queues[sock].put(ret_data)
# Add output channel for response 185 181 # Add output channel for response
if sock not in self.outputs: 186 182 if sock not in self.outputs:
self.outputs.append(sock) 187 183 self.outputs.append(sock)
else: 188 184 else:
# Interpret empty result as closed connection 189 185 # Interpret empty result as closed connection
logging.info("Closing connection after reading no data") 190 186 logging.info("Closing connection after reading no data")
# Stop listening for input on the connection 191 187 # Stop listening for input on the connection
if sock in self.outputs: 192 188 if sock in self.outputs:
self.outputs.remove(sock) 193 189 self.outputs.remove(sock)
self.inputs.remove(sock) 194 190 self.inputs.remove(sock)
sock.close() 195 191 sock.close()
# Remove message queue 196 192 # Remove message queue
del self.message_queues[sock] 197 193 del self.message_queues[sock]
198 194
def _handle_writable(self, socket_list): 199 195 def _handle_writable(self, socket_list):
"""Send message to client. 200 196 """Send message to client.
:param socket_list: List of socket object usable to send data 201 197 :param socket_list: List of socket object usable to send data
:returns: None 202 198 :returns: None
""" 203 199 """
for sock in socket_list: 204 200 for sock in socket_list:
try: 205 201 try:
next_msg = self.message_queues[sock].get_nowait() 206 202 next_msg = self.message_queues[sock].get_nowait()
except Empty: 207 203 except Empty:
self.outputs.remove(sock) 208 204 self.outputs.remove(sock)
else: 209 205 else:
self._send_msg(sock, next_msg) 210 206 self._send_msg(sock, next_msg)
logging.debug("send %s to %s", next_msg, sock.getpeername()) 211 207 logging.debug("send %s to %s", next_msg, sock.getpeername())
212 208
def _handle_exceptional(self, socket_list): 213 209 def _handle_exceptional(self, socket_list):
"""Handle error with socket by closing it. 214 210 """Handle error with socket by closing it.
:param socket_list: List of socket object in exceptional condition 215 211 :param socket_list: List of socket object in exceptional condition
:returns: None 216 212 :returns: None
""" 217 213 """
try: 218 214 try:
for sock in socket_list: 219 215 for sock in socket_list:
logging.warning("handling exceptional condition for %s", \ 220 216 logging.warning("handling exceptional condition for %s", \
sock.getpeername()) 221 217 sock.getpeername())
# Stop listening for input on the connection 222 218 # Stop listening for input on the connection
self.inputs.remove(sock) 223 219 self.inputs.remove(sock)
if sock in outputs: 224 220 if sock in self.outputs:
self.outputs.remove(sock) 225 221 self.outputs.remove(sock)
sock.close() 226 222 sock.close()
# Remove message queue 227 223 # Remove message queue
del self.message_queues[sock] 228 224 del self.message_queues[sock]
except Exception as ex: 229 225 except Exception as ex:
logging.error("Unexpected error: %s", ex) 230 226 logging.error("Unexpected error: %s", ex)
231 227
def _input_msg_handler(self, msg): 232 228 def _input_msg_handler(self, msg):
"""Handle message from clients. Message format is defined in 233 229 """Handle message from clients. Message format is defined in
:class:`eddsctrl.server.eddsctrlsserver.EDdsCtrlServer`. 234 230 :class:`eddsctrl.server.eddsctrlsserver.EDdsCtrlServer`.
Message contains a command to update DDS device state. 235 231 Message contains a command to update DDS device state.
:param msg: A formated string message (str) 236 232 :param msg: A formated string message (str)
:returns: Return actual value of parameter in DDS (float) 237 233 :returns: Return actual value of parameter in DDS (float)
""" 238 234 """
split_msg = msg.split("!") 239 235 split_msg = msg.split("!")
index = split_msg[1].strip('\0') # Remove extra binary NULL characters 240 236 index = split_msg[1].strip('\0') # Remove extra binary NULL characters
value = split_msg[2] 241 237 value = split_msg[2]
config = configparser.ConfigParser() 242 238 config = configparser.ConfigParser()
config.read(self._settingsf) 243 239 config.read(self._settingsf)
if index == "o": 244 240 if index == "o":
retval = self._dds.set_ofreq(float(value)) 245 241 retval = self._dds.set_ofreq(float(value))
config.set('dds_ctrl', 'ofreq', str(self._dds.get_ofreq())) 246 242 config.set('dds_ctrl', 'ofreq', str(self._dds.get_ofreq()))
elif index == "p": 247 243 elif index == "p":
retval = self._dds.set_phy(float(value)) 248 244 retval = self._dds.set_phy(float(value))
config.set('dds_ctrl', 'phase', str(self._dds.get_phy())) 249 245 config.set('dds_ctrl', 'phase', str(self._dds.get_phy()))
elif index == "a": 250 246 elif index == "a":
retval = self._dds.set_amp(int(value)) 251 247 retval = self._dds.set_amp(int(value))
config.set('dds_ctrl', 'amp', str(self._dds.get_amp())) 252 248 config.set('dds_ctrl', 'amp', str(self._dds.get_amp()))
elif index == "i": 253 249 elif index == "i":
retval = self._dds.set_ifreq(float(value)) 254 250 retval = self._dds.set_ifreq(float(value))
config.set('dds_ctrl', 'ifreq', str(self._dds.get_ifreq())) 255 251 config.set('dds_ctrl', 'ifreq', str(self._dds.get_ifreq()))
elif index == "o?": 256 252 elif index == "o?":
retval = self._dds.get_ofreq() 257 253 retval = self._dds.get_ofreq()
elif index == "p?": 258 254 elif index == "p?":
retval = self._dds.get_phy() 259 255 retval = self._dds.get_phy()
elif index == "a?": 260 256 elif index == "a?":
retval = self._dds.get_amp() 261 257 retval = self._dds.get_amp()
elif index == "i?": 262 258 elif index == "i?":
retval = self._dds.get_ifreq() 263 259 retval = self._dds.get_ifreq()
else: # Bad identifier, message not valid 264 260 else: # Bad identifier, message not valid
logging.error("Bad identifier," \ 265 261 logging.error("Bad identifier, expected o[?], p[?], a[?] or i[?]: "
"expected o[?], p[?], a[?] or i[?]: ", \ 266 262 + index + " given")
index, " given") 267
return 268 263 return
# Write modification to setting file 269 264 # Write modification to setting file
with open(self._settingsf, 'w') as fd: 270 265 with open(self._settingsf, 'w') as fd:
config.write(fd) 271 266 config.write(fd)
# Note that value actually writed in DDS (retval) can be a bit different 272 267 # Note that value actually writed in DDS (retval) can be a bit different
# than value sended to DDS (value). 273 268 # than value sended to DDS (value).
274
275
276
msg = "!" + index + "!" + str(retval) + "!" 277 269 msg = "!" + index + "!" + str(retval) + "!"
return msg 278 270 return msg
279 271
@staticmethod 280 272 @staticmethod
def _send_msg(sock, msg): 281 273 def _send_msg(sock, msg):
"""Method for sending 'msg' to socket. 282 274 """Method for sending 'msg' to socket.
Message is built using the length prefix technique. See: 283 275 Message is built using the length prefix technique. See:
http://eli.thegreenplace.net/2011/08/02/length-prefix-framing-for-protocol-buffers/ 284 276 http://eli.thegreenplace.net/2011/08/02/length-prefix-framing-for-protocol-buffers/
:param sock: a valid socket object 285 277 :param sock: a valid socket object
:param msg: message to be send (str) 286 278 :param msg: message to be send (str)
:returns: None 287 279 :returns: None
""" 288 280 """
header = pack('<L', len(msg)) 289 281 header = pack('<L', len(msg))
try: 290 282 try:
sock.sendall(header + msg) 291 283 sock.sendall(header + msg.encode('utf-8'))
except IOError as ex: 292 284 except IOError as ex:
logging.error("Error during sending: %s", ex) 293 285 logging.error("Error during sending: %s", ex)
294 286
@staticmethod 295 287 @staticmethod
def _recv_n_bytes(sock, n): 296 288 def _recv_n_bytes(sock, nb):
"""Convenience method for receiving exactly n bytes from socket 297 289 """Convenience method for receiving exactly n bytes from socket
(assuming it's open and connected). 298 290 (assuming it's open and connected).
:param sock: socket object which receives the n bytes 299 291 :param sock: socket object which receives the n bytes
:param n: number of bytes to be received (int) 300 292 :param nb: number of bytes to be received (int)
:returns: data received (str) 301 293 :returns: data received (str)
""" 302 294 """
data = '' 303 295 data = ''
while len(data) < n: 304 296 while len(data) < nb:
try: 305 297 try:
chunk = sock.recv(n - len(data)) 306 298 chunk = sock.recv(nb - len(data))
if chunk == '': 307 299 if chunk == '':
break 308 300 break
data += chunk 309 301 data += chunk
except IOError as ex: 310 302 except IOError as ex:
logging.error("Socket error in _recv_n_bytes: %s", ex) 311 303 logging.error("Socket error in _recv_n_bytes: %s", ex)
return 312 304 return
except Exception as ex: 313 305 except Exception as ex:
logging.error("Error in _recv_n_bytes: %s", ex) 314 306 logging.error("Error in _recv_n_bytes: %s", ex)
return 315 307 return
return data 316 308 return data
317 309
def _accept_connect(self): 318 310 def _accept_connect(self):
"""Server accept connection from client. 319 311 """Server accept connection from client.
:returns: a new socket object related to client connection (socket) 320 312 :returns: a new socket object related to client connection (socket)
""" 321 313 """
# A "readable" server socket is ready to accept a connection 322 314 # A "readable" server socket is ready to accept a connection
connection, client_address = self.server.accept() 323 315 connection, client_address = self.server.accept()
logging.info("New connection from %s", client_address) 324 316 logging.info("New connection from %s", client_address)
connection.setblocking(0) 325 317 connection.setblocking(0)
self.inputs.append(connection) 326 318 self.inputs.append(connection)
self.outputs.append(connection) 327 319 self.outputs.append(connection)
# Give the connection a queue for data we want to send 328 320 # Give the connection a queue for data we want to send
self.message_queues[connection] = Queue() 329 321 self.message_queues[connection] = Queue()
return connection 330 322 return connection
331 323
332 324
#============================================================================== 333 325 #==============================================================================
def reset_settings(settings_file): 334 326 def reset_settings(settings_file):
"""Resets the "settings" file with default values. 335 327 """Resets the "settings" file with default values.
:param settings_file: file containing setting data value (str) 336 328 :param settings_file: file containing setting data value (str)
:returns: None 337 329 :returns: None
""" 338 330 """
config = configparser.ConfigParser() 339 331 config = configparser.ConfigParser()
config.add_section('dds_ctrl') 340 332 config.add_section('dds_ctrl')
config.set('dds_ctrl', 'server_port', str(SERVER_PORT)) 341 333 config.set('dds_ctrl', 'server_port', str(SERVER_PORT))
config.set('dds_ctrl', 'ofreq', str(DEFAULT_OFREQ)) 342 334 config.set('dds_ctrl', 'ofreq', str(DEFAULT_OFREQ))
config.set('dds_ctrl', 'phase', str(DEFAULT_PHY)) 343 335 config.set('dds_ctrl', 'phase', str(DEFAULT_PHY))
config.set('dds_ctrl', 'amp', str(DEFAULT_AMP)) 344 336 config.set('dds_ctrl', 'amp', str(DEFAULT_AMP))
config.set('dds_ctrl', 'ifreq', str(DEFAULT_IFREQ)) 345 337 config.set('dds_ctrl', 'ifreq', str(DEFAULT_IFREQ))
# Write modification to setting file 346 338 # Write modification to setting file
with open(settings_file, 'w') as fd: 347 339 with open(settings_file, 'w') as fd:
fd.truncate(0) # Reset file contents 348 340 fd.truncate(0) # Reset file contents
config.write(fd) 349 341 config.write(fd)
logging.info("Settings file reseted.") 350 342 logging.info("Settings file reseted.")
351 343
352 344
#============================================================================== 353 345 #==============================================================================
def configure_logging(): 354 346 def configure_logging():
"""Configures logs. 355 347 """Configures logs.
""" 356 348 """
date_fmt = "%d/%m/%Y %H:%M:%S" 357 349 date_fmt = "%d/%m/%Y %H:%M:%S"
log_format = "%(asctime)s %(levelname) -8s %(filename)s " + \ 358 350 log_format = "%(asctime)s %(levelname) -8s %(filename)s " + \
" %(funcName)s (%(lineno)d): %(message)s" 359 351 " %(funcName)s (%(lineno)d): %(message)s"
logging.basicConfig(level=FILE_LOG_LEVEL, \ 360 352 logging.basicConfig(level=FILE_LOG_LEVEL, \
datefmt=date_fmt, \ 361 353 datefmt=date_fmt, \
format=log_format, \ 362 354 format=log_format, \
filename=LOG_SERVER_FILE, \ 363 355 filename=LOG_SERVER_FILE, \
filemode='w') 364 356 filemode='w')
console = logging.StreamHandler() 365 357 console = logging.StreamHandler()
# define a Handler which writes messages to the sys.stderr 366 358 # define a Handler which writes messages to the sys.stderr
console.setLevel(CONSOLE_LOG_LEVEL) 367 359 console.setLevel(CONSOLE_LOG_LEVEL)
# set a format which is simpler for console use 368 360 # set a format which is simpler for console use
console_format = '%(levelname) -8s %(filename)s (%(lineno)d): %(message)s' 369 361 console_format = '%(levelname) -8s %(filename)s (%(lineno)d): %(message)s'
formatter = logging.Formatter(console_format) 370 362 formatter = logging.Formatter(console_format)
# tell the handler to use this format 371 363 # tell the handler to use this format
console.setFormatter(formatter) 372 364 console.setFormatter(formatter)
# add the handler to the root logger 373 365 # add the handler to the root logger
logging.getLogger('').addHandler(console) 374 366 logging.getLogger('').addHandler(console)
375 367
376 368
#============================================================================== 377 369 #==============================================================================
def eddsctrlserver(settings_file): 378 370 def main(settings_file):
371 """Main
372 """
configure_logging() 379 373 configure_logging()
if os.path.isfile(settings_file) is False: 380 374 if os.path.isfile(settings_file) is False:
logging.error("Settings file missing: create one with default values.") 381 375 logging.error("Settings file missing: create one with default values.")
reset_settings(settings_file) 382 376 reset_settings(settings_file)
EDdsCtrlServer(settings_file) 383 377 EDdsCtrlServer(settings_file)
384 378
385 379
#============================================================================== 386 380 #==============================================================================