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 today_first_intook_proc(*, start_time, pid, pigbase_id): ''' 判断本次采食是否是当天 intake_start_time 时间之后的首次采食 如果是则存入 首次采食数据表,并刷新 否则忽略 :param start_time: 10 位的时间戳 :param pid: 种猪 id :param pigbase_id: 对应的 pigbase 表的记录 id :return: ''' # 1、判断 sys_time 是否在当天的 intake_start_time 之后 # 2、判断 今天的 datestring(YYYYmmdd)和内存的 datestring,今天的大于内存的则 reset_record # 3、相等的则再判断 pid 是否已经存在,已经存在则不处理,不存在则添加到数据库,同时更新到内存 try: transformed_time = transform_time(start_time, '%Y%m%d') if is_after_intake_start_time(start_time): # 如果内存中的记录已经过期,则 reset_record if is_record_outdated(start_time): reset_record(start_time) # 如果该猪当天没有采食 if not has_pig_today_intook(pid): PigDailyFirstIntake({ 'pid': pid, 'pigbase_id': pigbase_id, 'record_date': transformed_time, }).add_one() # 添加到内存中之后,将 pid 也更新到内存中 add_pid(pid) except Exception as e: error_logger(e) error_logger(error_code['1002_0002'])
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 initialize_piglist(): ''' 从数据库中获取数据到内存 :return: ''' pig_animalnum_list.clear() pig_earid_list.clear() pig_id_list.clear() pig_identity_info_list.clear() try: res = PigList().get_all() for r in res: pig_animalnum_list.append(r.animalnum) pig_earid_list.append(r.earid) pig_id_list.append(r.id) pig_identity_info_list.append({ 'animalnum': r.animalnum, 'earid': r.earid, 'pid': r.id, 'stationid': r.stationid, }) print('initialize_piglist 种猪信息列表载入内存成功') except Exception as e: error_logger(e) error_logger(error_code['1100_2001'])
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 send_mail(title, content, receivers): ''' 发送邮件 :return: ''' # 接收邮件,可设置为你的QQ邮箱或者其他邮箱 # receivers 是 tuple,可以群发 # receivers = [receiver] message = MIMEText(content, 'html') # 邮件的正文内容 message['From'] = formataddr( (mail_config['sender_name'], mail_config['mail_user'])) message['To'] = formataddr(('种猪信息测定管理系统用户', 'all user')) message['Subject'] = Header(title) # 邮件主题 try: smtpObj = smtplib.SMTP() smtpObj.connect(mail_host, 25) # 25 为 SMTP 端口号 smtpObj.login(mail_user, mail_pass) smtpObj.sendmail(sender, receivers, message.as_string()) return True except smtplib.SMTPException as e: error_logger(e) error_logger(errorcode['1000_3001']) print("Error: 无法发送邮件") return False
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 facnum_exist(fac): ''' 检查输入的 facnum 是否存在 :return: ''' try: return fac in facnum except Exception as e: error_logger(e) error_logger(error_code['1100_2003'])
def forget_pass_confirm(): ''' 邮件找回密码,确认的网页 :return: ''' def temp(result, extra=''): return '''<!doctype html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>{result}</title> </head> <body style="text-align: center"> <h1>{result}</h1> <p>{extra}</p> </body> </html> '''.format(result=result, extra=extra) try: # 参数校验 request_data = request.args param_checker = forget_pass_confirm_action(request_data) if not param_checker['type']: return temp('激活<font color=red>失败</font>', param_checker['err_msg']) verifycode = request_data.get('code') user_find_pass = UserFindPass({ 'verifycode': verifycode, }) user_find_pass_record = user_find_pass.find() # 从数据库查询到高 verifycode 对应的数据库记录 if not user_find_pass_record: return temp('激活<font color=red>失败</font>', '校验码错误,无记录') user = User({ 'email': user_find_pass_record.email, }).get_from_email() user.password = user_find_pass_record.password user.update() # 将密码更新过来 user_find_pass_record.delete() # 删除数据库中的该条记录 return temp('激活<font color=green>成功</font>', '请使用新密码登录系统') except Exception as e: error_logger(e) error_logger(error_code['1000_9004']) return temp('激活<font color=red>失败</font>', error_code['1000_9004'])
def has_pig_today_intook(pid): ''' 判断种猪今天是否进行了采食 :param pid: :return: ''' try: return pid in daily_first_intake_record['pids'] except Exception as e: error_logger(e) error_logger(error_code['1100_4002'])
def is_after_intake_start_time(ts): ''' 检查输入的时间是否是在这个开始时间之后 :param t: 给定一个10位时间戳 :return: ''' try: # 201903082112 > 201903080800 True return transform_time(ts, '%Y%m%d%H%M') > get_now_time('%Y%m%d') + daily_intake_start_time[0] except Exception as e: error_logger(e) error_logger(error_code['1100_3002'])
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 initialize_station_list(): ''' 存数据库中获取数据到内存 :return: ''' # 将原引用中的数据全部清除掉,在重新存入数据 station_list.clear() try: res = StationInfo().get_all_station() for r in res: station_list.append(r.stationid) print('initialize_station_list 测定站信息载入内存成功') except Exception as e: error_logger(e) error_logger(error_code['1100_0001'])
def initialize_facnum(): ''' 从数据库中获取数据到内存 :return: ''' facnum.clear() try: res = SysCfg({ 'name': 'FAC_NUM', }).get_one() facnum.append(res.value) print('initialize_facnum 猪场代码载入内存成功') except Exception as e: error_logger(e) error_logger(error_code['1100_1002'])
def has_today_intake(pid=0): ''' 该种猪今天是否已经采食 :param pid: :return: ''' try: today_date = get_now_time('%Y%m%d') pig_record = pig_daily_assess_record.get(pid) if pig_record: # 找不到记录说明该猪之前没有进食过 return pig_record['recent']['record_date'] == today_date return False except Exception as e: error_logger(e) error_logger(error_code['1100_5002'])
def initialize_intake_start_time(): ''' 从数据库中获取数据到内存 :return: ''' # 清理数据 daily_intake_start_time.clear() try: res = SysCfg({ 'name': 'PIG_DAILY_INTAKE_START_TIME', }).get_one() daily_intake_start_time.append(res.value) print('initialize_intake_start_time 每日首次采食时间载入内存成功') except Exception as e: error_logger(e) error_logger(error_code['1100_3001'])
def initialize_daily_first_intake_record(ts=get_now_timestamp()): ''' 从数据库中获取数据到内存 :return: ''' try: reset_record(ts) res = PigDailyFirstIntake({ 'record_date': get_now_time('%Y%m%d'), }).get_all_from_record_date() for r in res: daily_first_intake_record['pids'].add(r.pid) # print(__name__, daily_first_intake_record) print('initialize_daily_first_intake_record 日首次采食数据载入内存成功') except Exception as e: error_logger(e) error_logger(error_code['1100_4001'])
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 add_today_record(pid, *, record_date, food_intake_count, food_intake_total, weight_ave, prev_weight_compare, prev_foodintake_compare): ''' 将当天计算好的数据保存到数据库,新增一条当天数据 :param params: :return: ''' try: PigDailyAssess({ 'pid': pid, 'food_intake_count': food_intake_count, 'food_intake_total': food_intake_total, 'weight_ave': weight_ave, 'prev_weight_compare': prev_weight_compare, 'prev_foodintake_compare': prev_foodintake_compare, 'record_date': record_date, }).add_one() except Exception as e: error_logger(e) error_logger(error_code['1100_5003'])
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 initialize_pig_daily_assess_record(): ''' 从数据库中获取数据到内存 这个数据初始化一次开销较大,只在最初始系统启动的时候,才会初始化一次 :return: ''' try: res = PigDailyAssess().get_all_last_two_days_record() for r in res: pid = r.pid # print(r.record_date.strftime('%Y%m%d'), '20190311' == r.record_date.strftime('%Y%m%d')) if not pig_daily_assess_record.get(pid): # 这是 recent 的数据 recent = { 'food_intake_count': r.food_intake_count, 'food_intake_total': r.food_intake_total, 'weight_ave': r.weight_ave, 'prev_weight_compare': r.prev_weight_compare, 'prev_foodintake_compare': r.prev_foodintake_compare, 'record_date': r.record_date.strftime('%Y%m%d'), } pig_daily_assess_record[pid] = { 'recent': recent, } else: # 这是 prev 的数据 prev = { 'food_intake_count': r.food_intake_count, 'food_intake_total': r.food_intake_total, 'weight_ave': r.weight_ave, 'prev_weight_compare': r.prev_weight_compare, 'prev_foodintake_compare': r.prev_foodintake_compare, 'record_date': r.record_date.strftime('%Y%m%d'), } pig_daily_assess_record[pid]['prev'] = prev # print(__name__, pig_daily_assess_record) print('initialize_pig_daily_assess_record 种猪一日信息数据载入内存成功') except Exception as e: error_logger(e) error_logger(error_code['1100_5001'])
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 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 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 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 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 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 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()