def self_check(): """ celery任务 定时自检 :return: """ logging.debug('自检') current_time = int(time.time()) session = Session() try: # 获取站点配置信息 id_num = r.get('id_num') # 获取上次检查时间并检查时间间隔,判断程序运行状态 check_time = r.get('check_time') if check_time: check_time = int(check_time) # logging.debug('上次检查时间:{}'.format(datetime.datetime.fromtimestamp(check_time))) if current_time - check_time > CHECK_DELAY: check_time_err(id_num) r.set('check_time', current_time) # 检查与服务器通讯状态 con_time = r.get('con_time') if con_time: con_time = int(con_time) # logging.debug('上次服务器通讯时间:{}'.format(datetime.datetime.fromtimestamp(con_time))) if current_time - con_time > SERVER_TIMEOUT: connect_server_err(id_num) # 检查PLC通讯状态 plcs = r.get('plc') if not plcs: plc_models = session.query(YjPLCInfo) plcs = plc_info(r, plc_models) r.set('plc', plcs) for plc in plcs: plc_connect_time = int(plc['time']) # logging.debug('PLC连接时间:{}'.format(datetime.datetime.fromtimestamp(plc_connect_time))) # 超过一定时间的上传服务器 if current_time - plc_connect_time > PLC_TIMEOUT: connect_plc_err( id_num, plc_id=plc['id'], ) # 数据库写入,关闭连接 session.commit() finally: session.close()
def boot(): """ 开机初次运行 :return: """ logging.debug('boot ruuning') Base.metadata.create_all(bind=eng) r.set('id_num', ID_NUM)
def beats(): """ celery任务 与服务器的心跳连接 :param : :return: """ logging.debug('心跳连接') current_time = int(time.time()) # 从数据库获取站点信息 id_num = ID_NUM # 获取上次心跳时间 con_time = r.get('con_time') # 获取心跳时上传的数据 data = beats_data(id_num, con_time, current_time) # print(data) data = encryption_client(data) # 发送心跳包 try: rv = req_s.post(BEAT_URL, data=data, timeout=(CONNECT_TIMEOUT, REQUEST_TIMEOUT)) # 连接服务器失败 except (RequestException, MaxRetriesExceededError) as e: logging.warning('心跳连接错误:' + str(e)) connect_server_err(id_num) # 连接成功 else: # data = decryption_client(rv.json()) # print(rv.status_code) data = rv.json() # print(data) # 更新服务器通讯时间 r.set('con_time', current_time) # 配置有更新 if data.get('is_modify') == 1: logging.info('发现配置有更新,准备获取配置') get_config() before_running() if data.get('command'): remote_command(data.get('command'))
def check_upload(): """ 检查变量组上传时间,将满足条件的变量组数据打包上传 :return: """ # upload_time1 = time.time() logging.debug('检查变量组上传时间') # print('上传') current_time = int(time.time()) # 在redis中查询需要上传的变量组id group_upload_data = r.get('group_upload') # print(group_upload_data) for g in group_upload_data: if current_time >= g['upload_time']: g['is_uploading'] = True r.set('group_upload', group_upload_data) group_id = [] value_list = list() # dtime1 = time.time() for g in group_upload_data: if current_time >= g['upload_time']: value_list += upload_data(g, current_time) group_id.append(g['id']) g['last_time'] = g['upload_time'] g['upload_time'] = current_time + g['upload_cycle'] # 设置为不在上传的状态 g['is_uploading'] = False # print('下次上传时间', datetime.datetime.fromtimestamp(g['upload_time'])) # dtime2 = time.time() # print('data', dtime2 - dtime1) # print(group_id) # print('上传数据', len(value_list), value_list) # utime1 = time.time() upload(value_list, group_id) # utime2 = time.time() # print('upload', utime2 - utime1) r.set('group_upload', group_upload_data)
def get_config(): """ 连接服务器接口,获取本机变量信息 :return: """ gtime1 = int(time.time()) logging.debug('连接服务器,获取数据') current_time = time.time() # 获取本机信息 id_num = r.get('id_num') post_data = {'id_num': id_num} post_data = json.dumps(post_data) # logging.info('获取配置,发送请求:' + str(post_data)) # 连接服务器 try: time_c1 = time.time() rv = req_s.post(CONFIG_URL, data=post_data, timeout=(CONNECT_TIMEOUT, REQUEST_TIMEOUT)) time_c2 = time.time() print('连接服务器获取配置', time_c2 - time_c1) # 连接失败 except RequestException as e: logging.warning('获取配置错误:' + str(e)) connect_server_err(id_num) # 连接成功 else: # 记录本次服务器通讯时间 r.set('con_time', current_time) if rv.status_code == 200: rp = rv.json() # data = rp['data'] data = decryption_client(rp['data']) # print(data) time11 = time.time() with ConnMySQL() as db: cur = db.cursor() try: # 配置更新,清空现有表 cur.execute('SET foreign_key_checks = 0') cur.execute('truncate table `variables_groups`') cur.execute('truncate table alarm_info') # cur.execute('truncate table `values`') cur.execute('truncate table yjvariableinfo') cur.execute('truncate table yjgroupinfo') cur.execute('truncate table yjplcinfo') cur.execute('truncate table yjstationinfo') cur.execute('SET foreign_key_checks = 1') # 添加新获取的数据 station_sql = '''insert into `yjstationinfo` (id, station_name, mac, ip, note, id_num, plc_count, ten_id, item_id) values (%(id)s, %(station_name)s, %(mac)s, %(ip)s, %(note)s, %(id_num)s, %(plc_count)s, %(ten_id)s, %(item_id)s)''' cur.execute(station_sql, data['stations']) plc_sql = '''insert into `yjplcinfo`( id, station_id, plc_name, note, ip, mpi, type, plc_type, ten_id, item_id, rack, slot, tcp_port) values (%(id)s, %(station_id)s, %(plc_name)s, %(note)s, %(ip)s, %(mpi)s, %(type)s, %(plc_type)s, %(ten_id)s, %(item_id)s, %(rack)s, %(slot)s, %(tcp_port)s)''' cur.executemany(plc_sql, data['plcs']) group_sql = '''insert into `yjgroupinfo`( id, group_name, note, upload_cycle, acquisition_cycle, server_record_cycle, is_upload, ten_id, item_id, plc_id) values (%(id)s, %(group_name)s, %(note)s, %(upload_cycle)s, %(acquisition_cycle)s, %(server_record_cycle)s, %(is_upload)s, %(ten_id)s, %(item_id)s, %(plc_id)s)''' cur.executemany(group_sql, data['groups']) var_sql = '''insert into `yjvariableinfo` (id, variable_name, note, db_num, address, data_type, rw_type, ten_id, item_id, write_value, area, is_analog, analog_low_range, analog_high_range, digital_low_range, digital_high_range) values (%(id)s, %(variable_name)s, %(note)s, %(db_num)s, %(address)s, %(data_type)s, %(rw_type)s, %(ten_id)s, %(item_id)s, %(write_value)s, %(area)s, %(is_analog)s, %(analog_low_range)s, %(analog_high_range)s, %(digital_low_range)s, %(digital_high_range)s)''' cur.executemany(var_sql, data['variables']) relation_sql = '''insert into `variables_groups`(id, variable_id, group_id) values (%(id)s, %(variable_id)s, %(group_id)s)''' cur.executemany(relation_sql, data['variables_groups']) alarm_sql = '''insert into `alarm_info` (id, variable_id, alarm_type, note, type, symbol, `limit`, delay) values (%(id)s, %(variable_id)s, %(alarm_type)s, %(note)s, %(type)s, %(symbol)s, %(limit)s, %(delay)s)''' cur.executemany(alarm_sql, data['alarm']) except Error as e: logging.error('更新配置出错: ' + str(e)) db.rollback() db_commit_err(id_num, 'get_config') else: db.commit() finally: cur.close() time12 = time.time() print('清空添加配置', time12 - time11) logging.debug('发送配置完成确认信息') time21 = time.time() result = server_confirm(CONFIRM_CONFIG_URL) time22 = time.time() print('确认配置获取', time22 - time21) if result: logging.info('配置获取完成') else: logging.error('无法向服务器确认获取配置已完成') else: server_return_err(id_num, 'get_config') gtime2 = time.time() print('get_config', gtime2 - gtime1)
def check_alarm(): # time1 = time.time() # r.set('alarm_info', None) logging.debug('check alarm') # print('检查报警') # redis_alarm_variables(r) is_no_alarm = r.get('is_no_alarm') if is_no_alarm: return alarm_variables = r.get('alarm_variables') # print('报警变量', alarm_variables) if not alarm_variables: redis_alarm_variables(r) return # 循环报警变量,查看最近采集的数值是否满足报警条件 current_time = int(time.time()) alarm_data = list() session = Session() try: # print(alarm_variables) for alarm in alarm_variables: # 获取需要判断的采集数据 if alarm['delay']: values = session.query(Value).filter_by(var_id=alarm['var_id']). \ filter(Value.time > current_time - alarm['delay'] - 1).all() else: values = session.query(Value).filter_by(var_id=alarm['var_id']). \ order_by(Value.time.desc()).limit(1).all() # print(values[0].value) is_alarm = False if alarm['type'] == 1: for v in values: # print(v.value, v.var_id) if bool(v.value) == bool(alarm['limit']): is_alarm = True else: is_alarm = False break elif alarm['type'] == 2: if alarm['symbol'] == 1: for v in values: if v.value > alarm['limit']: is_alarm = True else: is_alarm = False break elif alarm['symbol'] == 2: for v in values: if v.value >= alarm['limit']: is_alarm = True else: is_alarm = False break elif alarm['symbol'] == 3: for v in values: if v.value < alarm['limit']: is_alarm = True else: is_alarm = False break elif alarm['symbol'] == 4: for v in values: if v.value <= alarm['limit']: is_alarm = True else: is_alarm = False break elif alarm['symbol'] == 5: for v in values: if v.value == alarm['limit']: is_alarm = True else: is_alarm = False break else: is_alarm = False else: is_alarm = False if is_alarm and not alarm['is_alarming']: alarm_data.append({'i': alarm['var_id'], 'a': is_alarm}) alarm['is_alarming'] = True elif not is_alarm and alarm['is_alarming']: alarm_data.append({'i': alarm['var_id'], 'a': is_alarm}) alarm['is_alarming'] = False r.set('alarm_variables', alarm_variables) if alarm_data: alarm_info = {'time': current_time, 'data': alarm_data} old_alarm = r.get('alarm_info') # print(old_alarm) if old_alarm: old_alarm.append(alarm_info) r.set('alarm_info', old_alarm) else: r.set('alarm_info', [alarm_info]) # print(alarm_info) # print(alarm_variables) # except Exception as e: # logging.exception('check_alarm' + str(e)) # session.rollback() finally: session.close()
def check_gather(): """ 检查变量采集时间,采集满足条件的变量值 :return: """ # time.sleep(30) with ConnMySQL() as db: cur = db.cursor() try: # lock_time2 = time.time() # print('lock_time', lock_time2 - lock_time1) # time1 = time.time() logging.debug('检查变量采集时间') current_time = int(time.time()) value_list = list() plcs = r.get('plc') group_read_data = r.get('group_read') for plc in plcs: # todo 循环内部 使用并发 group_id = [] for v in group_read_data: if v['plc_id'] == plc[ 'id'] and current_time >= v['read_time']: group_id.append(v['id']) v['read_time'] = current_time + v['read_cycle'] r.set('group_read', group_read_data) group_data = r.get('variable') variables = [ variable for group in group_data if group['group_id'] in group_id for variable in group['variables'] ] # print(variables) # print('采集数量', len(variables)) with plc_client(plc['ip'], plc['rack'], plc['slot'], plc['id']) as client: if client.get_connected(): plc['time'] = current_time if variables: while len(variables) > 0: variable_group = variables[:18] variables = variables[18:] # print(len(variables)) # print(plc) try: value_info = read_multi( plc=plc, variables=variable_group, current_time=current_time, client=client) except Snap7ConnectException: id_num = r.get('id_num') connect_plc_err(id_num, plc['id']) except Snap7ReadException as e: id_num = r.get('id_num') area, db_num, addr, data_type = e.args read_err(id_num=id_num, plc_id=plc['id'], plc_name=plc['name'], area=area, db_num=db_num, address=addr, data_type=data_type) else: value_list += value_info # ctime1 = time.time() value_insert_sql = "insert into `values`(var_id, value, time) values " if value_list: v = map(str, value_list) value_insert_sql = value_insert_sql + ','.join(v) cur.execute(value_insert_sql) db.commit() # value_data = {str(current_time): value_list} # if redis_value: # else: # r.set('value', value_data) # ctime2 = time.time() # print('commit', ctime2 - ctime1) r.set('plc', plcs) finally: # time2 = time.time() # print('采集时间' + str(time2 - time1)) cur.close()
def check_gather_redis(self): """ 检查变量采集时间,采集满足条件的变量值 :return: """ lock_time2 = time.time() # print('lock_time', lock_time2 - lock_time1) time1 = time.time() logging.debug('检查变量采集时间') current_time = int(time.time()) value_list = list() session = Session() plcs = r.get('plc') group_read_data = r.get('group_read') for plc in plcs: # todo 循环内部 使用并发 group_id = [] for v in group_read_data: if v['plc_id'] == plc['id'] and current_time >= v['read_time']: group_id.append(v['id']) v['read_time'] = current_time + v['read_cycle'] r.set('group_read', group_read_data) group_data = r.get('variable') variables = [ variable for group in group_data if group['group_id'] in group_id for variable in group['variables'] ] # print(variables) # print('采集数量', len(variables)) # client = plc_connect(plc) with plc_client(plc['ip'], plc['rack'], plc['slot'], plc['id']) as client: if client.get_connected(): plc['time'] = current_time if variables: # readsuan(variables) # variables = variables[0:2] # print('variables', len(variables)) while len(variables) > 0: variable_group = variables[:18] variables = variables[18:] # print(len(variables)) # print(plc) try: value_info = read_multi(plc=plc, variables=variable_group, current_time=current_time, client=client) except Snap7ReadException as e: id_num = r.get('id_num') area, db_num, addr, data_type = e.args read_err(id_num=id_num, plc_id=plc['id'], plc_name=plc['name'], area=area, db_num=db_num, address=addr, data_type=data_type) else: value_list += value_info # except Exception: # print('跳过一次采集') # client.disconnect() # client.destroy() # session.bulk_insert_mappings(Value, value_list) # session.commit() ctime1 = time.time() # value_insert_sql = "insert into `values`(var_id, value, time) values " # if value_list: # v = map(str, value_list) # # value_insert_sql = value_insert_sql + ','.join(v) # # cur.execute(value_insert_sql) # db.commit() redis_value = r.conn.hlen('value') # print(redis_value) # value_data = {str(current_time): value_list} value_list = pickle.dumps(value_list) # if redis_value: r.conn.hset('value', str(current_time), value_list) # else: # r.set('value', value_data) ctime2 = time.time() # print('commit', ctime2 - ctime1) r.set('plc', plcs)