def insert_piginfo(): ''' 以模板的形式渲染页面 ''' request_data = request.json param_checker = insert_piginfo_action(request_data) if not param_checker['type']: return json.jsonify({ 'success': False, 'err_msg': param_checker['err_msg'] }) new_pig_info = PigInfo( dict(earid=request_data.get('earid').zfill(12), stationid=request_data.get('stationid').zfill(12), foodintake=request_data.get('foodintake'), weight=request_data.get('weight'), bodylong=request_data.get('bodylong'), bodywidth=request_data.get('bodywidth'), bodyheight=request_data.get('bodyheight'), bodytemperature=request_data.get('bodytemperature'), stationtime=request_data.get('stationtime'), systime=int(time.time()))) try: # 插入传入的数据和数据模型不一致的时候,或者由于其他原因插入失败的时候,或报异常 new_pig_info.add_one() except Exception as e: error_logger(e) error_logger(error_code['1000_0001']) return error_response(error_code['1000_0001']) return success_response()
def exit_one(): ''' 出栏一头猪,出栏不是删除一头猪,而是将该猪的出栏时间填充上即可 :param pid: 出栏一头猪 :return: ''' try: request_data = request.json param_checker = exit_one_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) record_id = request_data.get('recordId') PigList({ 'record_id': record_id, 'exit_time': get_now_timestamp(), }).exit_one() initialize_piglist_async() return success_response() except Exception as e: error_logger(e) error_logger(error_code['1001_0003']) return error_response(error_code['1001_0003'])
def update_errorcode(): ''' 更改已有的故障码 :return: ''' try: request_data = request.json id = request_data.get('id', None) errorcode = request_data.get('errorcode', None) comment = request_data.get('comment', None) if not id: return error_response('缺少记录id') if not errorcode: return error_response('缺少故障码') if not comment: return error_response('缺少注释') StationErrorcodeReference({ 'id': id, 'errorcode': errorcode, 'comment': comment, }).update_one() except Exception as e: error_logger(e) error_logger(error_code['1000_7301']) return error_response(error_code['1000_7301']) return success_response()
def update_station(): ''' 更改一个测定站的记录信息 :return: ''' try: # 参数校验 request_data = request.json param_checker = update_station_action(request_data) if not param_checker['type']: return error_response(param_checker['err_msg']) stationid = request_data.get('stationid') if not stationid_exist(stationid): return error_response('测定站不存在') comment = request_data.get('comment') status = request_data.get('status') errorcode = request_data.get('errorcode') changetime = get_now_timestamp() # 将记录修改 StationInfo({ 'stationid': stationid, 'comment': comment, 'status': status, 'errorcode': errorcode, 'changetime': changetime, }).update_one() return success_response() except Exception as e: error_logger(e) error_logger(error_code['1000_5004']) return error_response(error_code['1000_5004'])
def delete_station(): ''' 删除一个测定站记录 :return: ''' try: # 参数校验 request_data = request.json param_checker = delete_station_action(request_data) if not param_checker['type']: return error_response(param_checker['err_msg']) stationid = request_data.get('stationid') if not stationid_exist(stationid): return error_response('测定站不存在') # 将记录删除 ret = StationInfo({ 'stationid': stationid, }).delete_one() # 重新获取新的测定站号列表数据 initialize_station_list_async() return success_response(ret) except Exception as e: error_logger(e) error_logger(error_code['1000_5003']) return error_response(error_code['1000_5003'])
def exit_one_station(): ''' 出栏一个测定站的所有猪 :param stationId: 测定站号 :return: ''' try: request_data = request.json param_checker = exit_one_station_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) stationid = request_data.get('stationId') PigList({ 'stationid': stationid, }).exit_one_station(get_now_timestamp()) initialize_piglist_async() return success_response() except Exception as e: error_logger(e) error_logger(error_code['1001_0004']) return error_response(error_code['1001_0004'])
def sigup(): ''' 用户注册 :return: ''' try: # 参数校验 request_data = request.json param_checker = signup_action(request_data) if not param_checker['type']: return error_response(param_checker['err_msg']) # 数据写入 username = request_data.get('username') # 加密过后的密文密码 password_hash = password_encode(request_data.get('password')) email = request_data.get('email') phone = request_data.get('phone') token = generate_token() rank = 'common' created_time = get_now_timestamp() last_login_time = created_time new_user = User({ 'username': username, 'password': password_hash, 'email': email, 'phone': phone, 'token': token, 'rank': rank, 'created_time': created_time, 'last_login_time': last_login_time, }) # 检查是否已经有相同的用户名、邮箱、手机号注册 if new_user.get_from_username(): return error_response('用户名已存在') if new_user.get_from_email(): return error_response('邮箱已存在') if new_user.get_from_phone(): return error_response('手机号已存在') # 重复性校验没有问题,则将用户数据写入,并返回信息 new_user.signup() return success_response({ 'user': { 'username': new_user.username, 'token': new_user.token, 'rank': new_user.rank, }, }) except Exception as e: error_logger(e) error_logger(error_code['1000_9001']) return error_response(error_code['1000_9001'])
def total_perstation(): ''' 测定站某日所有猪的采食总量的统计表 :param stationId: 测定站 id :param time: 日期(当天开始的时间戳 10 位) :return: ''' try: request_data = request.args param_checker = total_perstation_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) stationid = request_data.get('stationId') date = transform_time(int(request_data.get('time')), '%Y%m%d') # 查询 res = db.session.query(PigList.id, PigList.earid, PigList.animalnum, PigList.facnum, PigDailyAssess.food_intake_total) \ .outerjoin(PigDailyAssess, PigList.id == PigDailyAssess.pid) \ .filter(PigList.stationid == stationid, PigDailyAssess.record_date == date) \ .all() ret = { 'data': [], # [{ facNum: 'xxxx', earId: 'xxxxxxxxxxx', animalNum: 'asdasdasdasd', intake: xxx }] 'total': 0, # 这段时间的总采食量 'ave': 0, # 这段时间的平均采食量 } pig_count = 0 # 统计到的种猪的头数 for item in res: ret['data'].append({ 'id': item.id, 'facNum': item.facnum, 'earId': item.earid, 'animalNum': item.animalnum, 'intake': item.food_intake_total, }) ret['total'] = ret['total'] + item.food_intake_total pig_count = pig_count + 1 ret['total'] = round(ret['total'], 2) if pig_count: ret['ave'] = round(ret['total'] / pig_count, 2) return success_response(ret) except Exception as e: error_logger(e) error_logger(error_code['1004_0001']) return error_response(error_code['1004_0001'])
def intake_trend(): ''' 个体采食量趋势图数据获取 :param pid: 种猪 id :param startTime: 起始时间 10 位数字时间戳 :param endTime: 起始时间 10 位数字时间戳 :return: ''' try: request_data = request.args param_checker = intake_trend_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) pid = request_data.get('pid') start_date = transform_time(int(request_data.get('startTime')), '%Y%m%d') end_date = transform_time(int(request_data.get('endTime')), '%Y%m%d') # 查询 res = db.session.query(PigDailyAssess.food_intake_total, PigDailyAssess.record_date) \ .filter(PigDailyAssess.pid == pid, PigDailyAssess.record_date >= start_date, PigDailyAssess.record_date <= end_date) \ .all() ret = { 'data': [], # [{ date: '2019-01-02', intake_total: 100.11 }] 'total': 0, # 这段时间的总采食量 'ave': 0, # 这段时间的平均采食量 } day_count = 0 # 统计的天数 for item in res: ret['data'].append({ 'date': item.record_date.strftime('%m-%d'), 'intake_total': item.food_intake_total, }) ret['total'] = ret['total'] + item.food_intake_total day_count = day_count + 1 ret['total'] = round(ret['total'], 2) if day_count: ret['ave'] = round(ret['total'] / day_count, 2) return success_response(ret) except Exception as e: error_logger(e) error_logger(error_code['1004_0001']) return error_response(error_code['1004_0001'])
def delete_errorcode(): ''' 删除故障码 :return: ''' try: request_data = request.json target_id = request_data.get('id') if not target_id: return error_response('缺少id') StationErrorcodeReference({'id': target_id}).delete_one() except Exception as e: error_logger(e) error_logger(error_code['1000_7101']) return error_response(error_code['1000_7101']) return success_response()
def entry_one(): ''' 入栏一头猪 :return: ''' try: request_data = request.json param_checker = entry_one_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) pid = request_data.get('pid') animalnum = request_data.get('animalNum') earid = request_data.get('earId') stationid = request_data.get('stationId') entry_time = get_now_timestamp() pig_data = { 'id': pid, 'stationid': stationid, 'animalnum': animalnum, 'facnum': '', 'earid': earid, 'entry_time': entry_time, } # 防止破坏数据库存储规范,未出栏的种猪不允许使用相同的测定编号或者耳标号 exist_info = PigList(pig_data).can_pig_entry() if not exist_info['exist']: PigList(pig_data).entry_one() initialize_piglist_async() return success_response(pig_data) else: return error_response(exist_info['msg']) except Exception as e: error_logger(e) error_logger(error_code['1001_0002']) return error_response(error_code['1001_0002'])
def get_all_kvs(): ''' 获取设置表所有 kv 对 :return: ''' try: res = SysCfg.get_all_kvs() ret = [] for r in res: ret.append({ 'name': r.name, 'value': r.value, 'comment': r.comment, }) except Exception as e: error_logger(e) error_logger(error_code['1000_8001']) return error_response(error_code['1000_8001']) return success_response(ret)
def signin(): ''' 用户登录 :return: ''' try: # 参数校验 request_data = request.json param_checker = signin_action(request_data) if not param_checker['type']: return error_response(param_checker['err_msg']) # 数据写入 username = request_data.get('username') # 加密过后的密文密码 password_hash = password_encode(request_data.get('password')) last_login_time = get_now_timestamp() token = generate_token() user = User({ 'username': username, 'password': password_hash, }) user_in_db = user.get_from_username() # 用户的登录信息校验通过,则把用户的信息保存到数据库 if user_in_db and user_in_db.password == user.password: user_in_db.signin(token=token, last_login_time=last_login_time) return success_response({ 'user': { 'username': user_in_db.username, 'token': user_in_db.token, 'rank': user_in_db.rank, }, }) else: return error_response('用户名或密码错误') except Exception as e: error_logger(e) error_logger(error_code['1000_9002']) return error_response(error_code['1000_9002'])
def update_piginfo(): ''' 修改一头种猪的信息,不包括出栏 :return: ''' try: request_data = request.json param_checker = update_piginfo_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) # 不需要修改测定站 id,后面猪进食的时候,系统会自动将猪所属哪个测定站作比对,确定是否进行修正(换栏智能处理) #------------------------------------------------ pid = request_data.get('pid') record_id = request_data.get('recordId') animalnum = request_data.get('animalNum') earid = request_data.get('earId') pig_data = { 'id': pid, 'record_id': record_id, 'animalnum': animalnum, 'earid': earid, } # 防止破坏数据库存储规范,未出栏的种猪不允许使用相同的测定编号或者耳标号 exist_info = PigList(pig_data).can_update_piginfo() if not exist_info['exist']: PigList(pig_data).update_piginfo() initialize_piglist_async() return success_response() else: return error_response(exist_info['msg']) except Exception as e: error_logger(e) error_logger(error_code['1001_0005']) return error_response(error_code['1001_0005'])
def get_errorcode(): ''' 查询故障码 :return: ''' try: res = StationErrorcodeReference.get_all() ret = [] for r in res: ret.append({ 'id': r.id, 'errorcode': r.errorcode, 'comment': r.comment, }) ret = sorted(ret, key=lambda item: item['errorcode'], reverse=True) except Exception as e: error_logger(e) error_logger(error_code['1000_7001']) return error_response(error_code['1000_7001']) return success_response(ret)
def set_station(): ''' 设定测定站的开关机状态 :return: ''' try: request_data = request.json # [['000000000010', 'open_device'], ['000000000011', 'close_device']] setting_pairs = request_data.get( 'settingPairs' ) # [[stationid, status]] status => close_device or open_device if len(setting_pairs) > 0: setDeviceStatus(setting_pairs) return success_response() else: return error_response('需要指定测定站和状态') except Exception as e: error_logger(e) error_logger(error_code['1000_5005']) return error_response(error_code['1000_5005'])
def get_piglist_from_station(): ''' 查询一栏里面的所有猪 :param stationId: 对应 station id :return: ''' try: request_data = request.args param_checker = get_piglist_from_station_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) stationid = request_data.get('stationId') noexit = False if request_data.get('noexit') == 'false' else True # 默认 为 True,不查询已经出栏的 piglist_res = PigList({ 'stationid': stationid, }).get_from_station(noexit) ret = [] for r in piglist_res: ret.append({ 'id': r.id, # 记录的 id 'facNum': r.facnum, 'animalNum': r.animalnum, 'earId': r.earid, 'stationId': r.stationid, 'entryTime': r.entry_time, 'exitTime': r.exit_time, 'recordId': r.record_id, }) return success_response(ret) except Exception as e: error_logger(e) error_logger(error_code['1001_0001']) return error_response(error_code['1001_0001'])
def add_contact(): ''' 添加消息联系方式(邮件) :return: ''' request_data = request.json param_checker = add_contact_action(request_data) if not param_checker['type']: return json.jsonify({'success': False, 'err_msg': param_checker['err_msg']}) new_item = NotificationContact(dict( email=request_data.get('email'), # 自动截取前250个字符存储到数据库 comment=request_data.get('comment'), )) try: new_item.add_one() except Exception as e: error_logger(e) error_logger(error_code['1000_4001']) return error_response(error_code['1000_4001']) return success_response()
def stationinfo(): try: res = StationInfo.query.all() station_off = [] # off 状态的排在前面 station_err = [] # err 状态排在中间 station_on = [] # on 正常状态的排在第三类 for r in res: if r.status == 'off': station_off.append({ 'id': r.id, # 记录的 id 'stationid': r.stationid.lstrip('0'), # 测定站 id 'status': r.status, # 测定站状态 'changetime': r.changetime, # 测定站状态修改时间 'errorcode': r.errorcode, # 错误码 }) elif r.status == 'on' and r.errorcode != '00000': station_err.append({ 'id': r.id, # 记录的 id 'stationid': r.stationid.lstrip('0'), # 测定站 id 'status': r.status, # 测定站状态 'changetime': r.changetime, # 测定站状态修改时间 'errorcode': r.errorcode, # 错误码 }) else: station_on.append({ 'id': r.id, # 记录的 id 'stationid': r.stationid.lstrip('0'), # 测定站 id 'status': r.status, # 测定站状态 'changetime': r.changetime, # 测定站状态修改时间 'errorcode': r.errorcode, # 错误码 }) ret = station_off + station_err + station_on except Exception as e: error_logger(e) error_logger(error_code['1000_5001']) return error_response(error_code['1000_5001']) return success_response(ret)
def update_kv(): ''' 更改某个 KV 对的值 :return: ''' try: request_data = request.json param_checker = update_kv_action(request_data) if not param_checker['type']: return error_response(param_checker['err_msg']) name = request_data.get('name', None) value = request_data.get('value', None) if name == cfg_keys.get('PIG_BASE_DATA_FIELDS'): # 参数校验合格之后,将参数拼接成字符串 value = ','.join(value) if not name: return error_response('缺少属性名') if not value: return error_response('缺少属性值') SysCfg({ 'name': name, 'value': value, }).update_kv() # 如果更改了猪场代码,则重新将猪场代码载入内存 if name == cfg_keys.get('FAC_NUM'): initialize_facnum_async() # 如果日首次采食的开始时间,则重新将猪场代码载入内存 if name == cfg_keys.get('PIG_DAILY_INTAKE_START_TIME'): initialize_intake_start_time_async() return success_response() except Exception as e: error_logger(e) error_logger(error_code['1000_8002']) return error_response(error_code['1000_8002'])
def add_errorcode(): ''' 新增故障码 :return: ''' try: request_data = request.json errorcode = request_data.get('errorcode', None) comment = request_data.get('comment', None) if not errorcode: return error_response('缺少故障码') if not comment: return error_response('缺少注释') StationErrorcodeReference({ 'errorcode': errorcode, 'comment': comment, }).add_one() except Exception as e: error_logger(e) error_logger(error_code['1000_7201']) return error_response(error_code['1000_7201']) return success_response()
def get_one_kv(): ''' 获取设置表指定的 kv 对 :return: ''' try: request_data = request.args param_checker = get_one_kv_action(request_data) if not param_checker['type']: return error_response(param_checker['err_msg']) name = request_data.get('name', None) r = SysCfg({ 'name': name, }).get_one() return success_response({ 'name': r.name, 'value': r.value, 'comment': r.comment, }) except Exception as e: error_logger(e) error_logger(error_code['1000_8003']) return error_response(error_code['1000_8003'])
def add_station(): ''' 添加一条测定站记录 :return: ''' try: # 参数校验 request_data = request.json param_checker = add_station_action(request_data) if not param_checker['type']: return error_response(param_checker['err_msg']) stationid = request_data.get('stationid') if stationid_exist(stationid): return error_response('测定站已存在') comment = request_data.get('comment') status = request_data.get('status') # 将该条记录添加到数据库中 ret = StationInfo({ 'stationid': stationid, 'comment': comment, 'status': status, 'errorcode': '00000', 'changetime': get_now_timestamp(), }).add_one() # 重新获取新的测定站号列表数据 initialize_station_list_async() return success_response(ret) except Exception as e: error_logger(e) error_logger(error_code['1000_5002']) return error_response(error_code['1000_5002'])
def get_all_station(): ''' 获取所有测定站信息 :return: ''' request_data = request.args # 将off状态的放在首部 errFirst = request_data.get('errFirst') == 'true' try: res = StationInfo().get_all_station() station_off = [] # off 状态的排在前面 station_err = [] # err 状态排在中间 station_on = [] # on 正常状态的排在第三类 for r in res: if r.status == 'off': station_off.append({ 'id': r.id, # 记录的 id 'stationid': r.stationid, # 测定站 id 'comment': r.comment, 'status': r.status, # 测定站状态 'changetime': r.changetime, # 测定站状态修改时间 'errorcode': r.errorcode, # 错误码 'reason': r.reason, # 状态描述 }) elif r.status == 'on' and r.errorcode != '00000': # 数据库对这个故障码没有对应的记录,则显示故障码并提示 if not r.reason: station_err.append({ 'id': r.id, # 记录的 id 'stationid': r.stationid, # 测定站 id 'comment': r.comment, 'status': r.status, # 测定站状态 'changetime': r.changetime, # 测定站状态修改时间 'errorcode': r.errorcode, # 错误码 'reason': str(r.errorcode) + ',无故障描述', # 状态描述 }) else: station_err.append({ 'id': r.id, # 记录的 id 'stationid': r.stationid, # 测定站 id 'comment': r.comment, 'status': r.status, # 测定站状态 'changetime': r.changetime, # 测定站状态修改时间 'errorcode': r.errorcode, # 错误码 'reason': r.reason, # 状态描述 }) else: station_on.append({ 'id': r.id, # 记录的 id 'stationid': r.stationid, # 测定站 id 'comment': r.comment, 'status': r.status, # 测定站状态 'changetime': r.changetime, # 测定站状态修改时间 'errorcode': r.errorcode, # 错误码 'reason': r.reason, # 状态描述 }) if errFirst: ret = station_off + station_err + station_on else: ret = station_on + station_off + station_err return success_response(ret) except Exception as e: error_logger(e) error_logger(error_code['1000_5001']) return error_response(error_code['1000_5001'])
def weight_change(): ''' 体重变化趋势图 :param type: 是显示一个测定站的数据还是显示一头猪的数据 `station` 查询一个测定站的所有猪的体重变化,`pig` 一头猪的体重变化 :param startTime: 开始时间(代表当天的时间戳 10 位) :param endTime: 结束时间(代表当天的时间戳 10 位) :param stationId: 测定站 id,`type=station` 时 :param pid: 种猪 id,`type=pig` 时 :return: ''' try: request_data = request.args param_checker = weight_change_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) r_type = request_data.get('type') pid = request_data.get('pid') stationid = request_data.get('stationId') start_date = transform_time(int(request_data.get('startTime')), '%Y%m%d') end_date = transform_time(int(request_data.get('endTime')), '%Y%m%d') earIdArr = set() ret = { 'earIdArr': [], # 种猪号构成的数组 'data': [], # [ { 'date': '01-10', 'animalNum1': xx } ] } print(pid) if r_type == 'station': # 查询一个测定站里面的猪的体重变化 res = db.session.query(PigList.earid, PigDailyAssess.weight_ave, PigDailyAssess.record_date) \ .outerjoin(PigDailyAssess, PigList.id == PigDailyAssess.pid) \ .filter(PigList.stationid == stationid, PigDailyAssess.record_date >= start_date, PigDailyAssess.record_date <= end_date) \ .all() date_weight_info = {} # { '01-10': { 'animalNum1': xxx } } for v in res: date = v.record_date.strftime('%m-%d') earIdArr.add(v.earid) if date_weight_info.get(date): date_weight_info[date][v.earid] = v.weight_ave else: date_weight_info[date] = {v.earid: v.weight_ave} for date in date_weight_info: temp_data = { 'date': date, } for earid in date_weight_info[date]: temp_data[earid] = date_weight_info[date][earid] ret['data'].append(temp_data) else: # r_type == 'pig' # 查询一头猪的体重变化 res = db.session.query(PigList.earid, PigDailyAssess.weight_ave, PigDailyAssess.record_date) \ .outerjoin(PigDailyAssess, PigList.id == PigDailyAssess.pid) \ .filter(PigList.id == pid, PigDailyAssess.record_date >= start_date, PigDailyAssess.record_date <= end_date) \ .all() date_weight_info = {} # { '01-10': { 'animalNum1': xxx } } for v in res: date = v.record_date.strftime('%m-%d') earIdArr.add(v.earid) if date_weight_info.get(date): date_weight_info[date][v.earid] = v.weight_ave else: date_weight_info[date] = {v.earid: v.weight_ave} for date in date_weight_info: temp_data = { 'date': date, } for animalNum in date_weight_info[date]: temp_data[animalNum] = date_weight_info[date][animalNum] ret['data'].append(temp_data) ret['data'].sort(key=lambda x: x.get('date')) ret['earIdArr'] = list(earIdArr) return success_response(ret) except Exception as e: error_logger(e) error_logger(error_code['1005_0002']) return error_response(error_code['1005_0002'])
def get_pig_abnormal_analyse_info(): ''' 预警分析(测定站下种猪),查询一个测定站下所有的猪的采食、体重值和同前日的差值 :param stationId: 对应 station id :param startTime: 起始时间 10 位数字时间戳 :param endTime: 起始时间 10 位数字时间戳 :return: ''' try: request_data = request.args param_checker = get_pig_abnormal_analyse_info_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) stationid = request_data.get('stationId') start_time = int(request_data.get('startTime')) end_time = int(request_data.get('endTime')) start_date = transform_time(start_time, '%Y%m%d') end_date = transform_time(end_time, '%Y%m%d') # 并表查询 res = db.session.query(PigList.animalnum, PigList.earid, PigDailyAssess.food_intake_total, PigDailyAssess.prev_foodintake_compare, PigDailyAssess.weight_ave, PigDailyAssess.prev_weight_compare, PigDailyAssess.record_date) \ .join(PigDailyAssess, PigList.id == PigDailyAssess.pid) \ .filter(PigList.stationid == stationid, PigDailyAssess.record_date >= start_date, PigDailyAssess.record_date <= end_date) \ .all() ret = { 'dateArr': [], # 包含的日期区间 ['02-19', '02-20', '02-21'] 'data': [], # [{ animalnum, earid, '02-19': { food_intake_total, prev_foodintake_compare, weight_ave, prev_weight_compare }, ... },] } date_arr = get_date_intervals( start_time, end_time, fm='%m-%d') # ['02-19', '02-20', '02-21'] ret_data = [] temp_ret_data = {} # { earid: {xxx} } for v in res: if temp_ret_data.get(v.earid): # 内部已经有该耳标号的记录了,只需要把对应日期的数据填充进去 temp_ret_data[v.earid][v.record_date.strftime('%m-%d')] = { 'food_intake_total': v.food_intake_total, 'prev_foodintake_compare': v.prev_foodintake_compare, 'weight_ave': v.weight_ave, 'prev_weight_compare': v.prev_weight_compare, } else: # 内部没有记录,则添加该耳标号的一个日期的记录 temp_ret_data[v.earid] = { 'animalNum': v.animalnum, 'earId': v.earid, v.record_date.strftime('%m-%d'): { 'food_intake_total': v.food_intake_total, 'prev_foodintake_compare': v.prev_foodintake_compare, 'weight_ave': v.weight_ave, 'prev_weight_compare': v.prev_weight_compare, } } for td_earid in temp_ret_data: one_pig_data = temp_ret_data[td_earid] for d in date_arr: # 对没有数据的日期进行数据填充 if not one_pig_data.get(d): one_pig_data[d] = { 'food_intake_total': 0, 'prev_foodintake_compare': 0, 'weight_ave': 0, 'prev_weight_compare': 0, } ret_data.append(one_pig_data) ret['dateArr'] = date_arr ret['data'] = ret_data return success_response(ret) except Exception as e: error_logger(e) error_logger(error_code['1006_0001']) return error_response(error_code['1006_0001'])
def stationinfo(): ''' 以模板的形式渲染页面 ''' request_data = request.json param_checker = stationinfo_action(request_data) if not param_checker['type']: return json.jsonify({ 'success': False, 'err_msg': param_checker['err_msg'] }) station_info_record = StationInfo( dict( stationid=request_data.get('stationid').zfill(12), status=request_data.get('status'), changetime=get_now_timestamp(), errorcode=request_data.get('errorcode'), )) try: # 插入传入的数据和数据模型不一致的时候,或者由于其他原因插入失败的时候,或报异常 # StationInfo.check_stationid(request_data.get('stationid')) station_info_record.exist_update_or_add( stationid=request_data.get('stationid').zfill(12), status=request_data.get('status'), changetime=get_now_timestamp(), errorcode=request_data.get('errorcode'), ) @asyncFunc def notification(): contacts_from_db = NotificationContact.get_prev(50) contacts = [] for c in contacts_from_db: contacts.append(c[0]) # 当错误码不是完全正常的时候,需要发送短信 # 发送来机器运行故障的时候,发送故障通知 if request_data.get('status') == 'on' and str( request_data.get( 'errorcode')) != station_errorcode_on_normal_code: mail_message = '测定站出现<b><font color=red>故障</font></b><br>' \ ' 测定站id:<font color=red>' + request_data.get('stationid') + '</font><br>' \ '错误码:<font color=red>' + request_data.get( 'errorcode') + '</font><br>' \ '<b>请尽快检查并排除故障</b>' send_mail_async('测定站运行故障', mail_message, contacts) # 添加一条记录到通知记录表里面 add_record = NotificationRecord( dict(email='all', message=mail_message, created_time=get_now_timestamp())) add_record.add_one() # 发送来关机指令的时候,发送测定站关机通知 if request_data.get('status') == 'off': mail_message = '测定站<b><font color=red>停机</font></b><br>' \ '测定站id:<font color=red>' + request_data.get('stationid') + '</font><br>' \ '错误码:<font color=red>' + request_data.get( 'errorcode') + '</font><br>' \ '<b>请尽快检查并排除故障</b>' send_mail_async('测定站已停机', mail_message, contacts) # 添加一条记录到通知记录表里面 add_record = NotificationRecord( dict(email='all', message=mail_message, created_time=get_now_timestamp())) add_record.add_one() notification() except Exception as e: error_logger(e) error_logger(error_code['1000_1001']) return error_response(error_code['1000_1001']) return success_response()
def daily_weight_gain_and_fcr(): ''' 日增重和饲料转化率统计(FCR) :param startTime: 开始时间(代表当天的时间戳 10 位) :param endTime: 结束时间(代表当天的时间戳 10 位) :param stationId: 测定站 id :return: ''' try: request_data = request.args param_checker = daily_weight_gain_and_fcr_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) stationid = request_data.get('stationId') start_date = transform_time(int(request_data.get('startTime')), '%Y%m%d') end_date = transform_time(int(request_data.get('endTime')), '%Y%m%d') ret = [] res = db.session.query(PigList.id, PigList.earid, PigList.animalnum, PigDailyAssess.food_intake_total, PigDailyAssess.weight_ave, PigDailyAssess.record_date) \ .outerjoin(PigDailyAssess, PigList.id == PigDailyAssess.pid) \ .filter(PigList.stationid == stationid, PigDailyAssess.record_date >= start_date, PigDailyAssess.record_date <= end_date) \ .order_by(asc(PigDailyAssess.record_date)) \ .all() start_date_weight = {} # 开始日期的体重 { pid: xxx } xxx 体重 end_date_weight = {} # 结束日期的体重 { pid: xxx } xxx 体重 day_count = {} # 统计的总天数 { pid: xxx } xxx 天数 period_food_intake_total = {} # { pid: xxx } xxx 这段时间总的采食量 pig_info = {} # { pid: { pid: xxx, earId: xxx, animalNum: xxx } } pid_set = set() for v in res: if v.id in pid_set: # 如果有该种猪的信息记录了 end_date_weight[v.id] = v.weight_ave else: # 如果没有该种猪的信息记录 pid_set.add(v.id) pig_info[v.id] = { 'pid': v.id, 'earId': v.earid, 'animalNum': v.animalnum, } start_date_weight[v.id] = v.weight_ave end_date_weight[v.id] = v.weight_ave day_count[v.id] = 0 period_food_intake_total[v.id] = 0 day_count[v.id] = day_count[v.id] + 1 period_food_intake_total[v.id] = period_food_intake_total[v.id] + 1 for pid in pid_set: one_pig_all_info = { 'pid': pid, 'earId': pig_info[pid]['earId'], 'animalNum': pig_info[pid]['animalNum'], 'dailyWeightGain': round((end_date_weight[pid] - start_date_weight[pid]) / day_count[pid], 3), } if (end_date_weight[pid] - start_date_weight[pid]) != 0: print( period_food_intake_total[pid], end_date_weight[pid] - start_date_weight[pid], round( period_food_intake_total[pid] / (end_date_weight[pid] - start_date_weight[pid]), 2)) one_pig_all_info['fcr'] = round( period_food_intake_total[pid] / (end_date_weight[pid] - start_date_weight[pid]), 2) else: one_pig_all_info['fcr'] = 0 ret.append(one_pig_all_info) return success_response(ret) except Exception as e: error_logger(e) error_logger(error_code['1005_0004']) return error_response(error_code['1005_0004'])
def food_intake_interval_analysis(): ''' 采食量区间分析 :param stationId: 测定站 id :param startTime: 开始时间(代表当天的时间戳 10 位) :param endTime: 结束时间(代表当天的时间戳 10 位) :return: ''' try: request_data = request.args param_checker = food_intake_interval_analysis_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) s_type = request_data.get('type') stationid = request_data.get('stationId') start_time = request_data.get('startTime') end_time = request_data.get('endTime') if s_type == 'one': # 查询,时间都是用的 PigBase.start_time res = db.session.query(PigList.id, PigBase.food_intake) \ .outerjoin(PigBase, PigList.id == PigBase.pid) \ .filter(PigList.stationid == stationid, PigBase.start_time >= start_time, PigBase.start_time <= end_time) \ .all() else: # 查询所有测定站的数据 res = db.session.query(PigList.id, PigBase.food_intake) \ .outerjoin(PigBase, PigList.id == PigBase.pid) \ .filter(PigBase.start_time >= start_time, PigBase.start_time <= end_time) \ .all() record_count = 0 # 记录的总数,用来统计百分数 intake_interval_count = { '0-200': 0, # [0, 200) '200-400': 0, # [200, 400) '400-600': 0, '600-800': 0, '800-1000': 0, '1000-1200': 0, '1200-1400': 0, '1400-1600': 0, '>1600': 0, } ret = { 'count': 0, # 统计的总量 'data': [], } for item in res: record_count = record_count + 1 if item.food_intake < 200: intake_interval_count[ '0-200'] = intake_interval_count['0-200'] + 1 elif item.food_intake < 400: intake_interval_count[ '200-400'] = intake_interval_count['200-400'] + 1 elif item.food_intake < 600: intake_interval_count[ '400-600'] = intake_interval_count['400-600'] + 1 elif item.food_intake < 800: intake_interval_count[ '600-800'] = intake_interval_count['600-800'] + 1 elif item.food_intake < 1000: intake_interval_count[ '800-1000'] = intake_interval_count['800-1000'] + 1 elif item.food_intake < 1200: intake_interval_count[ '1000-1200'] = intake_interval_count['1000-1200'] + 1 elif item.food_intake < 1400: intake_interval_count[ '1200-1400'] = intake_interval_count['1200-1400'] + 1 elif item.food_intake < 1600: intake_interval_count[ '1400-1600'] = intake_interval_count['1400-1600'] + 1 else: intake_interval_count[ '>1600'] = intake_interval_count['>1600'] + 1 if record_count != 0: # 计算百分数 for k in intake_interval_count: ret['data'].append({ 'intake': k, 'count': intake_interval_count[k], 'frequency': round(intake_interval_count[k] / record_count, 2), }) ret['count'] = record_count return success_response(ret) except Exception as e: error_logger(e) error_logger(error_code['1005_0001']) return error_response(error_code['1005_0001'])
def intake_frequency_in_day_interval(): ''' 不同时段采食频率分布图 :param type: 是选则的一个测定站还是所有的测定站 `all` `one` :param startTime: 开始时间(代表当天的时间戳 10 位) :param endTime: 结束时间(代表当天的时间戳 10 位) :param stationId: 测定站 id :return: ''' try: request_data = request.args param_checker = intake_frequency_in_day_interval_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) s_type = request_data.get('type') stationid = request_data.get('stationId') start_time = request_data.get('startTime') end_time = request_data.get('endTime') ret = { 'count': 0, # 统计的总量 'data': [], # [ { 'date': '01-10', 'animalNum1': xx } ] } if s_type == 'one': # 查询一个测定站里面的猪的体重变化 res = db.session.query(PigList.id, PigBase.start_time) \ .outerjoin(PigBase, PigList.id == PigBase.pid) \ .filter(PigList.stationid == stationid, PigBase.start_time >= start_time, PigBase.start_time <= end_time) \ .all() else: # s_type == 'all' 查询所有测定站的数据 res = db.session.query(PigList.id, PigBase.start_time) \ .outerjoin(PigBase, PigList.id == PigBase.pid) \ .filter(PigBase.start_time >= start_time, PigBase.start_time <= end_time) \ .all() time_interval_arr = [ '00:00-02:00', # [0 , 2) time_interval_arr[0] '02:00-04:00', # [2 , 4) '04:00-06:00', '06:00-08:00', '08:00-10:00', '10:00-12:00', '12:00-14:00', '14:00-16:00', '16:00-18:00', '18:00-20:00', '20:00-22:00', '22:00-24:00', ] record_inter_count = [0 for i in range(12)] # 每个时间段的记录数 one_day_seconds = 86400 local_time_zone_add = 28800 # 8 * 3600 interval_seconds = 7200 # 2 * 3600 for v in res: ret['count'] = ret['count'] + 1 inter = int((v.start_time + local_time_zone_add) % one_day_seconds / interval_seconds) # 0 , 1, 2 record_inter_count[inter] = record_inter_count[inter] + 1 # print(' pid => {pid}, time => {time} '.format(pid=v.id, time=v.start_time)) # print('inter => {inter}'.format(inter=inter)) # 构建返回的数据 for k, v in enumerate(record_inter_count): if ret['count'] != 0: ret['data'].append({ 'interval': time_interval_arr[k], 'count': v, 'frequency': round(v / ret['count'], 2) }) else: ret['data'].append({ 'interval': time_interval_arr[k], 'count': v, 'frequency': 0 }) return success_response(ret) except Exception as e: error_logger(e) error_logger(error_code['1005_0003']) return error_response(error_code['1005_0003'])