示例#1
0
def open_listener():

    from GlobalContext import DispatchContext
    for each_line in DispatchContext.lines:
        # start a thread to listen line server
        ip_port = str(each_line.ip) + ':' + str(each_line.port)
        if ip_port in DispatchContext.address_list:
            continue
        DispatchContext.address_list.append(ip_port)
        thread_listener = threading.Thread(target=listen_a_port, args=(each_line.ip, each_line.port), name=('listener:' + ip_port))
        thread_listener.setDaemon(True)
        thread_listener.start()
        Logger.info("start a new thread for listener a port.")
    # listen query port
    for each_line in DispatchContext.lines:
        # start a thread to listen line server
        ip_port = str(each_line.query_ip) + ':' + str(each_line.query_port)
        if ip_port in DispatchContext.address_list:
            continue
        DispatchContext.address_list.append(ip_port)
        thread_listener = threading.Thread(target=listen_a_port, args=(each_line.query_ip, each_line.query_port), name=('listener:' + ip_port))
        thread_listener.setDaemon(True)
        thread_listener.start()
        Logger.info("start a new thread for listener a port to query.")
    return 0
 def get_dedicated_connection(cls): # 专用连接:数据库服务端一个专有进程处理该连接,相对于共享连接而言
     try:
         return cls.pool.dedicated_connection()
     except Exception as e:
         Logger.error("when get dedicated connection from pool!")
         Logger.error(repr(e))
         return None
示例#3
0
def send_order_status_to_database(order_no_value, order_status_value,
                                  order_id):
    Logger.info('try to update order line ,id:' + str(order_id) +
                ' ,order_no :' + str(order_no_value) + ',order_status :' +
                str(order_status_value))
    if order_id is None:
        Logger.info('order_id is None for send_order_status_to_database!')
        return -1
    if order_no_value is None:
        Logger.info(
            'order_no_value is None for send_order_status_to_database!')
        return -2
    if order_status_value is None:
        Logger.info(
            'order_status_value is None for send_order_status_to_database!')
        return -3

    sql_sentence = SqlCollection.update_order_info.format(
        order_no=r"'" + str(order_no_value) + r"'",
        order_status_id=order_status_value,
        id=order_id)
    from GlobalContext import DispatchContext
    rows, error_info = DatabaseInterface.execute_commit_sql(
        DispatchContext.db_connect, sql_sentence)
    if error_info is not None or rows is None:
        Logger.error('send_order_status_to_database error!!! error_info: ' +
                     str(error_info))
        return -2
    return 0
 def get_connection(cls):
     try:
         return cls.pool.connection()
     except Exception as e:
         Logger.error("when get connection from pool!")
         Logger.error(repr(e))
         return None
示例#5
0
    def load_sql_interfaces(cls):
        try:
            # 如果文件不是uft-8编码方式,读取文件可能报错
            cls.get_order_info = cls.process_sql_file_special_character(open('sql/get_order_info.sql', 'r', encoding='utf-8').read())
            cls.update_order_info = cls.process_sql_file_special_character(open('sql/update_order_info.sql', 'r', encoding='utf-8').read())
            return 0

        except Exception as e:
            Logger.error('when SqlCollection.load_sql_interfaces()!')
            Logger.error(repr(e))
            return -1
示例#6
0
def get_order_info(database_connection):
    db_conn = database_connection
    sql_sentence = SqlCollection.get_order_info
    rows, error_info = DatabaseInterface.execute_commit_sql(
        db_conn, sql_sentence)
    if error_info is not None or rows is None:
        Logger.error("get agv info failed due to SQL execution! error_info: " +
                     str(error_info))
        return None
    else:
        return rows
    def create_pool(cls):
        try:
            cls.pool = PooledDB(psycopg2, maxconnections = configs.max_connection_num,
                                mincached = configs.min_cached_num, maxcached = configs.max_cached_num,
                                maxshared = configs.max_shared_num, application_name = configs.application_name_for_database_connection,
                                host = configs.database_host, port=configs.database_port, dbname = configs.database_name,
                                user = configs.database_user_name, password=configs.database_password)
            return cls

        except Exception as e:
            Logger.fatal("failed to initialize Database Connection Pool. System is exiting!")
            Logger.fatal(repr(e))
            ToolFunctions.sys_exit(301)
    def load_config_from_database(cls, database_connection):
        # 这里从数据库中读取所有配置参数
        #
        rows, error_info = DatabaseInterface.execute_commit_sql(
            database_connection, "select 1")
        if error_info is not None:
            Logger.error(
                'cannot load configuration from the database since the SQL execution fails.'
            )
            return cls

        configs.configs_from_database = cls

        return cls
示例#9
0
def update_order_status_to_database() -> int:
    from GlobalContext import DispatchContext
    for this_line in DispatchContext.lines:
        if this_line.messages is None:
            Logger.info('this_line  message is not responed !')
            continue
        else:
            if this_line.messages.request_message is not None and this_line.messages.is_response is True:
                ''' 临时方案 需要将返回来的数据中获取订单编号订单状态 目前暂定 4 ,即接收到回复之后将订单置为4'''
                temp_order_num = str(
                    this_line.messages.response_message['data'])
                temp_order_status = 4
                send_result = send_order_status_to_database(
                    temp_order_num, temp_order_status, this_line.order_id)
                this_line.sent_back_database_times += 1
                if send_result < 0:
                    Logger.info('send io basket_num to database  failed !!!')
            else:
                Logger.info(' this line message is not responsed!')

        if this_line.sent_back_database_times >= 3:
            # 内存回收
            temp_order_id = this_line.order_id
            DispatchContext.lines_listindex_dict.pop(
                int(DispatchContext.lines.index(this_line)))
            DispatchContext.lines_id_dict.pop(int(this_line.order_id))
            DispatchContext.lines.remove(this_line)
            Logger.info(
                'line has been removed from DispatchContext.lines for order_id :'
                + str(temp_order_id))
    return 0
示例#10
0
def execute_commit_sql(database_connection, sql_sentence):
    rows = None
    error_info = None
    try:
        cur = database_connection.cursor()
        cur.execute(sql_sentence)
        rows = cur.fetchall()
        database_connection.commit()
        cur.close()
        # Logger.debug('One SQL was successfully executed: \n' + sql_sentence)

    except Exception as e:
        Logger.error(
            'One SQL failed to execute: \n' + str(sql_sentence)
        )  # need use str() conversion to avoid sql_sentence is None
        error_info = 'Error: ' + str(repr(e))
        Logger.error(error_info)

    return rows, error_info
示例#11
0
def load_order_info(rows) -> int:
    if rows is None:
        Logger.error('input row is None!')
        return -1
    line_count = len(rows)
    if line_count <= 0:
        Logger.info("no line info to load.")
        return 0
    for each_line in range(0, line_count):
        current_row = rows[each_line]
        order_line_info = resolve_line_info(current_row)

        if order_line_info is None:
            Logger.error('orderdata ignored  row = ' + str(current_row))
            continue
        # if line_info.ip is None or line_info.port is None or line_info.type_id is None:
        #     Logger.error('linedata ignored2. row = ' + str(current_row))
        #     continue
        from GlobalContext import DispatchContext
        if order_line_info.order_id not in DispatchContext.lines_id_dict.keys(
        ):
            DispatchContext.lines.append(order_line_info)
            DispatchContext.lines_listindex_dict[DispatchContext.lines.index(
                order_line_info)] = order_line_info
            DispatchContext.lines_id_dict[
                order_line_info.order_id] = order_line_info
    return 0
示例#12
0
def Work_Interaction_Loop():
    Logger.info('start interaction logic loop')
    from GlobalContext import DispatchContext
    # Logger.info('data_package_id : ' + str(DispatchContext.data_package_id))
    while True:
        DispatchContext.all_lock.acquire()
        try:
            for current_line in DispatchContext.lines:
                if current_line.messages is None:
                    current_line.send_generate_task_mesg()
                    Logger.info('send the request message !!!' +
                                str(current_line.messages.request_message))
                print(current_line.messages)
                print(current_line)
                # print(DispatchContext.lines_id_dict[each_line_info.order_id])
        except Exception as e:
            Logger.error('when execute dispatch logic!')
            Logger.error(repr(e))

        DispatchContext.all_lock.release()
        Logger.info('Thread for interaction logic keeps alive.')
        time.sleep(0.3)  # sleep time unit is second
def reload_config_from_database():
    while (True):
        database_connection = None
        try:
            database_connection = db_pool.get_connection()
            ConfigFromDatabase.load_config_from_database(database_connection)

        except Exception as e:
            Logger.error("when reload configurations from database!")
            Logger.error(repr(e))
            if database_connection is not None:
                try:
                    database_connection.close()
                except Exception as e2:
                    Logger.error(
                        'when try to close the database connection after error during reloading configurations from database.'
                    )
                    Logger.error(repr(e2))

        database_connection.close()
        Logger.info('Thread to reload config from database keeps alive.')
        time.sleep(configs.reload_config_from_database_interval)
示例#14
0
def resolve_line_info(current_row) -> OrderData or None:
    if current_row is None:
        Logger.error('input current_row is None for resolve_line_info!')
        return None
    try:  # 数据解析
        order_line_info = OrderData()
        order_line_info.order_id = int(current_row[0])

        if current_row[1] is not None:
            order_line_info.order_type_id = int(current_row[1])
        else:
            order_line_info.order_type_id = None

        if current_row[2] is not None:
            order_line_info.order_status_id = int(current_row[2])
        else:
            order_line_info.order_status_id = None

        if current_row[3] is not None:
            order_line_info.location_id = str(current_row[3])
        else:
            order_line_info.location_id = None

        if current_row[4] is not None:
            order_line_info.location_name = current_row[4]
        else:
            order_line_info.location_name = None

        if current_row[5] is not None:
            order_line_info.destination_location_id = int(current_row[5])
        else:
            order_line_info.destination_location_id = 0

        if current_row[6] is not None:
            order_line_info.destination_location_name = current_row[6]
        else:
            order_line_info.destination_location_name = None

        if current_row[7] is not None:
            order_line_info.priority = int(current_row[7])
        else:
            order_line_info.priority = 0

        order_line_info.is_sent = False

        return order_line_info
    except Exception as e:
        Logger.error("cannot resolve loaded line_info: " + str(current_row))
        Logger.error(repr(e))
        return None
示例#15
0
def do_connect(host,port):
    from GlobalContext import DispatchContext
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
    # DispatchContext.all_lock.acquire()
    result = None
    try:
        str_address = str(host) + ':' + str(port)
        if str_address in DispatchContext.ip_and_port_connect_dict.keys():
            return DispatchContext.ip_and_port_connect_dict[str_address]

        Logger.info('start to connect this server:' + str_address)
        sock.connect((host, port))
        Logger.info('socket connect success!address: ' + str_address)
        DispatchContext.ip_and_port_connect_dict[str_address] = sock
        Logger.info('connect' + str_address + ' success')
        result = sock
    except Exception as e :
        Logger.info('tcp connect error,ip: ' + str(host) + ' ,port:' + str(port))
        # time.sleep(3)

    # DispatchContext.all_lock.release()
    return result
示例#16
0
def listen_a_port(this_ip, this_port):
    # connect
    from GlobalContext import DispatchContext
    ip_and_port = str(this_ip) + ':' + str(this_port)
    this_socket = do_connect(this_ip, this_port)

    while True:
        try:
            if this_socket is None:
                Logger.info('connect ' + str(ip_and_port) + ' error,try again!')
                this_socket = do_connect(this_ip, this_port)
                continue

            data = this_socket.recv(1024).decode('utf8')
            Logger.info('recv data package: ' + str(data))
            if is_heartbeat(data, this_socket):
                Logger.info('is_heartbeat ok')
                continue
            check_result = check_and_update_package_data(data)
            if check_result:
                Logger.info('add to line.messages')

            if data == '':  # 连接中断时返回''
                if ip_and_port in DispatchContext.ip_and_port_connect_dict.keys():
                    DispatchContext.ip_and_port_connect_dict[ip_and_port].close()
                    DispatchContext.ip_and_port_connect_dict.pop(ip_and_port)
                    Logger.info('pop socket:' + str(ip_and_port))
                this_socket = do_connect(this_ip, this_port)
                time.sleep(1)

        except Exception as e:
            Logger.error("when get data from tcp!")
            try:
                this_socket.send('HEAD00010006000000041234TAIL'.encode('utf8'))  # 发送心跳报文测试连接状态
            except:
                this_socket = do_connect(this_ip, int(this_port))
        time.sleep(0.1)
示例#17
0
    def send_generate_task_mesg(self):
        ''' 发送 任务方法 '''
        from GlobalContext import DispatchContext
        # if self.is_sent is False:
        #     Logger.info('this line.message has not sent!,try to  send message!')
        #     return -1
        if self.messages is None:
            new_message = OrderMessage()
            new_message.data_package_id = get_data_package_id()
            temp_message = {
                "reqCode":
                "2312257536",
                "taskTyp":
                "W01",
                "wbCode":
                "",
                "positionCodePath": [{
                    "positionCode": "A2",
                    "type": "00"
                }, {
                    "positionCode": "A4",
                    "type": "00"
                }],
                "podCode":
                "-1",
                "AgvCode":
                "6"
            }
            #选择发送订单的模板   # 1 : W01  2:W02  数据库插入时 需要控制 订单类型 即模板类型
            if self.order_type_id == 1:
                # 1 : W01  2:W02
                temp_message['taskTyp'] = 'W01'
            else:
                # 1 : W01  2:W02
                temp_message['taskTyp'] = 'W02'

            temp_message["reqCode"] = str(new_message.data_package_id)
            temp_message['positionCodePath'][0]['positionCode'] = str(
                self.location_name)
            temp_message['positionCodePath'][1]['positionCode'] = str(
                self.destination_location_name)
            new_message.request_message = json.dumps(temp_message)

            try:
                url = "http://192.168.101.34:80/cms/services/rest/hikRpcService/genAgvSchedulingTask"
                a = requests.post(url)
                headers = {'content-type': 'application/json'}
                ret = requests.post(url,
                                    data=new_message.request_message,
                                    headers=headers)
                new_message.request_times = 1
                new_message.request_time = time.time()
                self.is_sent = True
                Logger.info(
                    'this line has sent the request for generating  task!!')
                print(ret.status_code)
                if ret.status_code == 200:
                    Logger.info(
                        ' this line message has been responed, send status:200!'
                    )
                    text = json.loads(ret.text)
                    Logger.info('recv the return message ' + str(text))
                    new_message.is_response = True  # 发送已收到回复
                    new_message.response_message = text  # 记录发送之后,收到的回复的数据
                    new_message.return_code = 0  # 发送已收到回复
                else:
                    Logger.info(
                        ' the status_code is not 200  some error occur! please check it now'
                        + str(ret.status_code))
                self.messages = new_message
                DispatchContext.package_id_line_dict[
                    new_message.data_package_id] = self
            except Exception as e:
                Logger.error('the socket connect failed!')
                Logger.error(repr(e))
        else:
            '''
            消息 不为空  表示已经发送了 消息
            '''
            if self.messages.is_response:  # 消息发送已经收到回复
                Logger.info(
                    'this request message is responsed,need not to send message again!'
                )
            else:  # when return != 0 发送了没有收到回复  需要再次发送
                self.messages.request_times += 1
                self.messages.request_time = time.time()
                url = "http://192.168.101.34:80/cms/services/rest/hikRpcService/genAgvSchedulingTask"
                a = requests.post(url)
                headers = {'content-type': 'application/json'}
                ret = requests.post(url,
                                    data=self.messages.request_message,
                                    headers=headers)
                print(ret.status_code)
                if ret.status_code == 200:
                    text = json.loads(ret.text)
                    Logger.info('recv the return message ' + str(text))
                    self.messages.response_message = text
                    self.messages.return_code = 0
                Logger.info('message is not responsed,send again:' +
                            str(self.messages.request_message))
        return 0
def synchronize_data():
    if DatabaseResource.database_connection is None or DispatchContext.db_connect:
        DatabaseResource.database_connection = db_pool.get_connection()
    db_conn = DatabaseResource.database_connection
    DispatchContext.db_connect = db_conn
    Logger.info('Starting to synchronize data with database in this cycle...')
    while True:
        try:
            error_flag = False
            Logger.info(
                'Starting to synchronize data with database in this cycle...')
            # synchronizing data

            # data_package_id

            # write config_file_path to config.ini
            import configparser
            import os
            config_file_path = os.getcwd() + "/config/config.ini"
            config_writer = configparser.ConfigParser()
            config_writer.read(config_file_path)
            config_writer.set('tcp_connect_config', 'data_package_id',
                              str(DispatchContext.data_package_id))
            config_writer.write(open(config_file_path, 'w'))

            try:
                DispatchContext.all_lock.acquire()

                # 实时 将数据库中的数据 读取到内存中
                lines = get_order_info(db_conn)
                load_result = load_order_info(lines)
                if load_result < 0:
                    Logger.error('send_database_agv_command failed!')
                    error_flag = True

                # 实时将 订单返回的数据  回写到数据库
                update_result = update_order_status_to_database()
                if update_result < 0:
                    Logger.error(
                        'send_database to  order_info order_status failed!')
                    error_flag = True

                # update_result = refresh_line_io_states(db_conn)
                # if update_result < 0:
                #     Logger.error('send_database_agv_command failed!')
                #     error_flag = True

                # update_result = update_line_status_to_database()
                # if update_result < 0:
                #     print(update_result)this_line basket num for update_all_io_to_zero!
                #     Logger.error('send_database line status  to io_state failed!')
                #     error_flag = True

            except Exception as e:
                Logger.error('when refresh data to DispatchContext!')
                Logger.error(repr(e))

            DispatchContext.all_lock.release()
            if error_flag:
                raise Exception('error happened when synchronize data!')

            # from GlobalContext import DispatchContext
            for each_line_info in DispatchContext.lines:
                print(each_line_info)
                print(DispatchContext.lines_id_dict[each_line_info.order_id])

            # from Line import send_order_status_to_database
            # send_order_status_to_database('erghyfjugkyf',4,2)

        except Exception as e:
            Logger.error("when synchronizing data with database!")
            Logger.error(repr(e))

            # test database connection
            test_db_result = DatabaseInterface.test_database_connection(
                db_conn)
            if test_db_result:
                Logger.info(
                    'database connection for synchronization data was tested and showed to be good.'
                )
            else:
                # connection is bad, try to close current connection and get a new one
                Logger.error(
                    "synchronize_data(): database connection is bad, trying to close current connection and get a new one."
                )
                old_db_conn = db_conn
                new_db_conn = db_pool.get_connection()
                if new_db_conn is None:
                    Logger.error(
                        "synchronize_data(): cannot get a new database connection!"
                    )
                else:
                    Logger.info(
                        "synchronize_data(): already got a new database connection."
                    )
                    db_conn = DatabaseResource.database_connection = new_db_conn
                    try:
                        old_db_conn.close()
                    except Exception as e2:
                        Logger.error(
                            'synchronize_data():  when try to close the old database connection after getting a new one!'
                        )
                        Logger.error(repr(e2))

        Logger.info('Thread for data synchronization keeps alive.')
        time.sleep(0.3)  # sleep time unit is second
示例#19
0
def check_and_update_package_data(package_data):
    package_data = package_data.strip()
    message_len = len(package_data)
    # print('the data length:' + str(len(package_data)))
    Logger.info('check_and_update_package_data this message')
    # if message_len != 28 or message_len != 40:
    #     Logger.info('package_data len error,ignore it!')
    #     return False
    # 交互响应
    if message_len == 28:
        if package_data[0:4] != 'HEAD' or package_data[24:28] != 'TAIL':
            Logger.info('package_data formal error,ignore it!')
            return False

        data_package_id = int(package_data[4:8])
        do_code = int(package_data[8:12])
        error_code = int(package_data[12:16])
        data_len = int(package_data[16:20])
        return_code = int(package_data[20:24])
        if do_code != 2 or error_code != 0:
            Logger.info('do_code or error_code error ignore it!')
            return False

        from GlobalContext import DispatchContext
        if data_package_id not in DispatchContext.package_id_line_dict.keys():
            Logger.info('have not send this package id')
            return False

        if return_code != 0:
            return False

        this_line: LineData = DispatchContext.package_id_line_dict[data_package_id]
        if this_line.messages is None:
            Logger.info('messages is None for check_and_update_package_data,line: ' + str(this_line))
            return False

        current_message = this_line.messages
        current_message.response_time = time.time()
        current_message.is_response = True
        current_message.response_message = package_data
        current_message.return_code = return_code
        Logger.info('add data to line!')
        return True
    # 查询回复
    if message_len == 40:
        if package_data[0:4] != 'HEAD' or package_data[36:40] != 'TAIL':
            Logger.info('package_data formal error,ignore it!')
            return False
        # print('data length is :'+str(message_len))
        '''将 数量 返回到 轨道类中  并更新到数据库'''
        data_package_id = int(package_data[4:8])
        opt_code = int(package_data[8:12])
        error_code = int(package_data[12:16])
        data_len = int(package_data[16:20])
        return_code = int(package_data[20:24])
        line_id = int(package_data[24:28])
        slice_num = int(package_data[28:32])
        real_basket_num = int(package_data[32:36])

        if opt_code != 3 or error_code != 0:
            Logger.info('do_code or error_code error ignore it!')
            return False

        from GlobalContext import DispatchContext
        if data_package_id not in DispatchContext.query_package_id_line_dict.keys():
            Logger.info('have not send this package id')
            return False

        this_line: LineData = DispatchContext.query_package_id_line_dict[data_package_id]
        if this_line.id == line_id:
            Logger.info('set line' + str(this_line.id) + '.basket_num = ' + str(real_basket_num) + ',slice_num = ' + str(slice_num))
            this_line.basket_num = real_basket_num
            this_line.slice_num = slice_num
        else:
            Logger.info('return line: ' + str(line_id) + '+basket num to line:' + str(this_line.id) + ', ignore it!')

        if this_line.query_messages is None:
            Logger.info('query_messages is None for check_and_update_package_data,line: ' + str(this_line))
            return False

        current_query_message = this_line.query_messages
        current_query_message.response_time = time.time()
        current_query_message.is_response = True
        current_query_message.response_message = package_data
        current_query_message.return_code = return_code

        return True