<commit_before>"""
    from blitz.communications.netscanner_manager import NetScannerManager as nm
    import time
    mynm = nm("172.16.31.10")
    time.sleep(10)
    mynm.stop_client()
"""

__author__ = '<NAME>'

import datetime
import logging
import Queue
import socket
import threading
import time

from blitz.communications.signals import logging_started, logging_stopped


class NetScannerManager(object):
    """
    A class which handles decoding and interpretation of TCP messages received
    from a NetScanner 9116 or 8IFC device.
    """

    # Steps in startup:
    #  1. Device handshake
    #  2. Device reset
    #  3. Set standard units (e.g kPa)
    #  4. Calibrate offset (i.e. set ambient to 0)
    #  5. Query data from all channels in decimal format (repeat)
    INIT_SEQUENCE = [
        ('A', 'NOP connection check'),
        ('B', 'reset device'),
        ('v01101 6.894757', 'use kPa'),
        ('h', 'zero offsets'),
        ('b', 'digital read data')
    ]

    REQUEST_TIMEOUT = 5.0

    SAMPLE_FREQUENCY = 2.0

    logger = logging.getLogger(__name__)

    def __init__(self, database, host, board_id="0A", port=9000):
        """
        Initialises a NetScannerManager which connects a TCP/IP connection to the device

        :param host: The host IP address of the NetScanner device
        :param port: The port of the NetScanner device
        :param database: The database to use to save serial data
        """

        self.__host = host
        self.__port = port
        self.__data = database
        self.__board_id = board_id
        self.receive_queue = Queue.Queue()
        self.__stop_event = threading.Event()
        self.__socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.__socket.settimeout(self.REQUEST_TIMEOUT)
        self.__run_thread(self.run_client)
        self.__thread = None
        self.__logging_start = datetime.datetime.now()
        self.__logging = False
        self.__logging_lock = threading.RLock()

        logging_started.connect(self.start_logging)
        logging_stopped.connect(self.stop_logging)

    def __run_thread(self, thread_target):
        self.__thread = threading.Thread(target=thread_target, args=[self.__stop_event])
        self.__thread.daemon = True
        self.__thread.start()

    def run_client(self, stop_event):
        try:
            self.__socket.connect((self.__host, self.__port))
        except Exception as e:
            self.logger.critical("Unable to start NetScanner:")
            self.logger.critical(e)
            return

        self.__logging_start = datetime.datetime.now()

        current_state = 0
        self.logger.debug("NetScanner starting polling loop")

        while not stop_event.is_set():

            if self.INIT_SEQUENCE[current_state][0] == self.INIT_SEQUENCE[-1][0]:
                # the handshake is finished, check if we should be logging
                with self.__logging_lock:
                    if not self.__logging:
                        time.sleep(1.0 / self.SAMPLE_FREQUENCY)
                        continue

            self.__socket.send(self.INIT_SEQUENCE[current_state][0])
            if current_state < len(self.INIT_SEQUENCE) - 1:
                self.logger.debug("Netscanner sent {0} message".format(self.INIT_SEQUENCE[current_state][1]))

            try:
                data = self.__socket.recv(1024)
            except Exception as e:
                self.logger.warning("NetScanner receive failed with exception... retrying. Exception was:")
                self.logger.warning(e)
            else:
                self.receive_message(data.encode('hex'))

                if current_state < len(self.INIT_SEQUENCE) - 1:
                    current_state += 1
                else:
                    # sample at approximately 2 Hz
                    time.sleep(1.0 / self.SAMPLE_FREQUENCY)

        # terminate the context before exiting
        self.__socket.close()
        self.logger.debug("NetScanner terminated")

    def start_logging(self, args):
        """
        Stores the current time when data logging commences so the correct timestamp can be provided to messages
        """
        self.__logging_start = datetime.datetime.now()

        with self.__logging_lock:
            self.__logging = True

    def stop_logging(self, args):
        """
        Stops the NetScanner manager from sampling from the NetScanner device
        """
        with self.__logging_lock:
            self.__logging = False

    def receive_message(self, message):
        """
        Receives and handles a new message received via TCP

        :param message: the message that was received
        """
        if message == "A":
            self.logger.debug("NetScanner received ACK from device")
        else:
            if self.__data:
                delta_t = (datetime.datetime.now() - self.__logging_start).microseconds / 1000.0
                delta_t = hex(int(delta_t))[2:].rjust(8, '0').upper()

                if len(self.__data) / 8 == 55:
                    # we just received the response to a calibration message 'h'
                    pass
                elif len(self.__data) / 8 != 16:
                    self.logger.warning(
                        "Received NetScanner message of unexpected length, read %s channels (not 16)" % len(results))
                else:
                    self.__data.queue(self.__board_id + "0AA1" + delta_t + message.upper())

    def stop_client(self):
        """
        Stops a client from polling the NetScanner by setting the stop_event<commit_msg>Message length error handling improvements<commit_after>"""
    from blitz.communications.netscanner_manager import NetScannerManager as nm
    import time
    mynm = nm("172.16.31.10")
    time.sleep(10)
    mynm.stop_client()
"""

__author__ = '<NAME>'

import datetime
import logging
import Queue
import socket
import threading
import time

from blitz.communications.signals import logging_started, logging_stopped


class NetScannerManager(object):
    """
    A class which handles decoding and interpretation of TCP messages received
    from a NetScanner 9116 or 8IFC device.
    """

    # Steps in startup:
    #  1. Device handshake
    #  2. Device reset
    #  3. Set standard units (e.g kPa)
    #  4. Calibrate offset (i.e. set ambient to 0)
    #  5. Query data from all channels in decimal format (repeat)
    INIT_SEQUENCE = [
        ('A', 'NOP connection check'),
        ('B', 'reset device'),
        ('v01101 6.894757', 'use kPa'),
        ('h', 'zero offsets'),
        ('b', 'digital read data')
    ]

    REQUEST_TIMEOUT = 5.0

    SAMPLE_FREQUENCY = 2.0

    logger = logging.getLogger(__name__)

    def __init__(self, database, host, board_id="0A", port=9000):
        """
        Initialises a NetScannerManager which connects a TCP/IP connection to the device

        :param host: The host IP address of the NetScanner device
        :param port: The port of the NetScanner device
        :param database: The database to use to save serial data
        """

        self.__host = host
        self.__port = port
        self.__data = database
        self.__board_id = board_id
        self.receive_queue = Queue.Queue()
        self.__stop_event = threading.Event()
        self.__socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.__socket.settimeout(self.REQUEST_TIMEOUT)
        self.__run_thread(self.run_client)
        self.__thread = None
        self.__logging_start = datetime.datetime.now()
        self.__logging = False
        self.__logging_lock = threading.RLock()

        logging_started.connect(self.start_logging)
        logging_stopped.connect(self.stop_logging)

    def __run_thread(self, thread_target):
        self.__thread = threading.Thread(target=thread_target, args=[self.__stop_event])
        self.__thread.daemon = True
        self.__thread.start()

    def run_client(self, stop_event):
        try:
            self.__socket.connect((self.__host, self.__port))
        except Exception as e:
            self.logger.critical("Unable to start NetScanner:")
            self.logger.critical(e)
            return

        self.__logging_start = datetime.datetime.now()

        current_state = 0
        self.logger.debug("NetScanner starting polling loop")

        while not stop_event.is_set():

            if self.INIT_SEQUENCE[current_state][0] == self.INIT_SEQUENCE[-1][0]:
                # the handshake is finished, check if we should be logging
                with self.__logging_lock:
                    if not self.__logging:
                        time.sleep(1.0 / self.SAMPLE_FREQUENCY)
                        continue

            self.__socket.send(self.INIT_SEQUENCE[current_state][0])
            if current_state < len(self.INIT_SEQUENCE) - 1:
                self.logger.debug("Netscanner sent {0} message".format(self.INIT_SEQUENCE[current_state][1]))

            try:
                data = self.__socket.recv(1024)
            except Exception as e:
                self.logger.warning("NetScanner receive failed with exception... retrying. Exception was:")
                self.logger.warning(e)
            else:
                self.receive_message(data.encode('hex'))

                if current_state < len(self.INIT_SEQUENCE) - 1:
                    current_state += 1
                else:
                    # sample at approximately 2 Hz
                    time.sleep(1.0 / self.SAMPLE_FREQUENCY)

        # terminate the context before exiting
        self.__socket.close()
        self.logger.debug("NetScanner terminated")

    def start_logging(self, args):
        """
        Stores the current time when data logging commences so the correct timestamp can be provided to messages
        """
        self.__logging_start = datetime.datetime.now()

        with self.__logging_lock:
            self.__logging = True

    def stop_logging(self, args):
        """
        Stops the NetScanner manager from sampling from the NetScanner device
        """
        with self.__logging_lock:
            self.__logging = False

    def receive_message(self, message):
        """
        Receives and handles a new message received via TCP

        :param message: the message that was received
        """
        if message == "A":
            self.logger.debug("NetScanner received ACK from device")
        else:
            if self.__data:
                delta_t = (datetime.datetime.now() - self.__logging_start).microseconds / 1000.0
                delta_t = hex(int(delta_t))[2:].rjust(8, '0').upper()

                if len(message) / 8 == 55:
                    # we just received the response to a calibration message 'h'
                    pass
                elif len(message) / 8 != 16:
                    self.logger.warning(
                        "Received NetScanner message of unexpected length, read %s channels" % (len(message) / 8))
                else:
                    self.__data.queue(self.__board_id + "0AA1" + delta_t + message.upper())

    def stop_client(self):
        """
        Stops a client from polling the NetScanner by setting the stop_event
{'fraction_non_alphanumeric': 0.09179131054131054, 'fraction_numerical': 0.014155982905982906, 'mean_word_length': 2.057430593358737, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1345584', 'n_tokens_mistral': 3235, 'n_tokens_neox': 2993, 'n_words': 838}