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 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 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 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 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 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 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_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 forget_pass(): ''' 用户忘记密码 :return: ''' try: # 参数校验 request_data = request.json param_checker = forget_pass_action(request_data) if not param_checker['type']: return error_response(param_checker['err_msg']) # 数据写入 email = request_data.get('email') # 加密过后的密文密码 password_hash = password_encode(request_data.get('password')) verifycode = generate_token() + generate_token() created_time = get_now_timestamp() user = User({ 'email': email, }) user_exist = user.get_from_email() != None if user_exist: user_find_pass_record = UserFindPass({ 'email': email, 'verifycode': verifycode, 'password': password_hash, 'created_time': created_time, }) user_find_pass_record.add() email_verify_link = 'http://localhost:5000/admin/login/forget_pass_confirm?code=' + verifycode # 邮件的标题 email_title = '新密码激活' # 邮件的内容 email_content = '''<!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>新密码激活邮件</title> </head> <body style="text-align: center"> <h1>{title}</h1> <p><a href="{link}">点击</a>即可激活新设置的密码</p> <p>或者复制下方字符串到浏览器打开</p> <p>{link}</p> </body> </html> '''.format(link=email_verify_link, title=mail_config['sender_name']) send_mail_async(email_title, email_content, [email]) return success_response() else: return error_response('该用户邮箱未注册') except Exception as e: error_logger(e) error_logger(error_code['1000_9003']) return error_response(error_code['1000_9003'])
def initialize_daily_first_intake_record_async(ts=get_now_timestamp()): ''' 分配子线程处理 :return: ''' initialize_daily_first_intake_record(ts)
def export_piginfo(): ''' 导出种猪信息 :return: ''' try: request_data = request.json from_time = request_data.get('fromTime', None) # 直接接收10位的数字时间戳 from_time = 0 if from_time == None else from_time end_time = request_data.get('endTime', None) # 直接接收10位的数字时间戳 end_time = get_now_timestamp() if end_time == None else end_time path = request_data.get('path', '~') filename = request_data.get('filename', get_now_time() + '-pig.csv') keys = request_data.get('keys', []) # 导出的字段名 type = request_data.get('type', None) # 导出的数据类型 time_asc = request_data.get('timeasc', None) # 倒数的时序 if len(keys) == 0: return error_response('导出字段不能为空') # bin 平台区分鉴别 if sys.platform.startswith('darwin'): mysql_bin = '/Applications/MAMP/Library/bin/mysql' else: mysql_bin = 'mysql' if type == 'station': stationid = request_data.get('stationid', None) if isinstance(stationid, str): stationid = stationid.zfill(12) where_str = " WHERE `stationid`=" + '"' + stationid + '"' else: return error_response('测定站号不合法') elif type == 'one': # 'one' earid = request_data.get('earid', None) if isinstance(earid, str): earid = earid.zfill(12) print(earid) where_str = " WHERE `earid`=" + '"' + earid + '"' else: return error_response('耳标号不合法') else: where_str = ' ' if time_asc: # 默认是时间逆序 orderby_str = ' ORDER BY `systime` ASC' else: orderby_str = ' ORDER BY `systime` DESC' auth_str = ' -u' + mysql_config['username'] + ' -p' + mysql_config[ 'password'] + ' --database=' + mysql_config['database'] sql_str = " --execute='SELECT " + "`" + "`,`".join( keys) + "`" + " FROM `pig_info`" + where_str + orderby_str + "'" sed_str = " | sed 's/\t/,/g;' " dest_file = path + '/' + filename print(sql_str) # 执行的命令 # /Applications/MAMP/Library/bin/mysql -uroot -proot --database=pig --execute='SELECT `id`,`earid` FROM `pig_info`' > ~/20181228-pig.csv command = mysql_bin + auth_str + sql_str + sed_str + ' > ' + dest_file exec_res = subprocess.call( command, shell=True, ) # 为 0 则正常执行,不为0则执行出现异常 if exec_res != 0: error_logger(sql_str + sed_str + ' > ' + dest_file) error_logger(error_code['1000_6101']) return error_response(error_code['1000_6101']) except Exception as e: error_logger(e) error_logger(error_code['1000_6102']) return error_response(error_code['1000_6102']) return success_response()
def get_piginfo(): ''' 获取种猪信息 :param type: all、station、one :param offset: 跳过的条数 :param earid: 对应 pig :param stationid: 对应 station :return: ''' request_data = request.json type = request_data.get('type', None) from_id = request_data.get('fromId', None) res = None ret = { 'list': [], 'lastId': None, 'hasNextPage': False, } try: from_time = request_data.get('fromTime', None) # 直接接收10位的数字时间戳 from_time = 0 if from_time == None else from_time end_time = request_data.get('endTime', None) # 直接接收10位的数字时间戳 end_time = get_now_timestamp() if end_time == None else end_time if type == 'station': # 'station' stationid = request_data.get('stationid', '').zfill(12) if stationid != None: res = PigInfo.get_station(stationid, from_id, from_time, end_time) else: return error_response('缺少测定站号') elif type == 'one': # 'one' earid = request_data.get('earid', '').zfill(12) if earid != None: res = PigInfo.get_one(earid, from_id, from_time, end_time) else: return error_response('缺少耳标号') else: # all res = PigInfo.get_all(from_id, from_time, end_time) # k v 赋值 for ind, item in enumerate(res): if ind < length_per_page: ret['list'].append({ 'id': item.id, 'earid': item.earid.lstrip('0'), 'stationid': item.stationid.lstrip('0'), 'foodintake': item.foodintake, 'weight': item.weight, 'bodylong': item.bodylong, 'bodywidth': item.bodywidth, 'bodyheight': item.bodyheight, 'bodytemperature': item.bodytemperature, 'systime': item.systime, 'stationtime': item.stationtime, }) if ind == length_per_page: ret['hasNextPage'] = True if ret['hasNextPage']: ret['lastId'] = ret['list'][-1:][0].get('id') # 获取最后一条记录的 id, 在下一次 else: ret['lastId'] = 0 except Exception as e: error_logger(e) error_logger(error_code['1000_6001']) return error_response(error_code['1000_6001']) return success_response(ret)
def pig_intake_once(): ''' 种猪一次采食,数据插入表中 :return: ''' try: request_data = request.json param_checker = add_one_record_action(request_data) if not param_checker['type']: error_logger(param_checker['err_msg']) return error_response(param_checker['err_msg']) # 需要使用到的数据初始化 earid = request_data.get('earid') stationid = request_data.get('stationid') # 种猪身体信息相关指标 food_intake = request_data.get('food_intake') weight = request_data.get('weight') body_long = request_data.get('body_long') body_width = request_data.get('body_width') body_height = request_data.get('body_height') # 系统初期没有这些指标 body_temp = 0 if request_data.get( 'body_temp') == None else request_data.get('body_temp') env_temp = 0 if request_data.get( 'env_temp') == None else request_data.get('env_temp') env_humi = 0 if request_data.get( 'env_humi') == None else request_data.get('env_humi') # 时间相关的指标 start_time = request_data.get('start_time') end_time = request_data.get('end_time') sys_time = get_now_timestamp() # 从内存中 依据耳标号查询到种猪的 pid,animanum,earid 信息 pig_identity_info = get_pig_info(earid, 'earid') if pig_identity_info: pid = pig_identity_info.get('pid') new_pigbase_record = PigBase({ 'pid': pid, 'food_intake': food_intake, 'weight': weight, 'body_long': body_long, 'body_width': body_width, 'body_height': body_height, 'body_temp': body_temp, 'env_temp': env_temp, 'env_humi': env_humi, 'start_time': start_time, 'end_time': end_time, 'sys_time': sys_time, }).add_one() # 今日首次采食判断处理 # today_first_intook_proc(start_time=start_time, pid=pid, pigbase_id=new_pigbase_record.id) # 将当前记录归入日评估 daily_assess(pid=pid, start_time=start_time, intake=food_intake, weight=weight) # 检查是否更换了测定站 # if stationid != pig_identity_info.get('stationid'): # PigList({ # 'id': pid, # 'stationid': stationid, # }).update_stationid() # initialize_piglist_async() # else: # # 1、新增种猪记录 # # 2、刷新内存数据 # # 3、获取到 pid,将基础数据写入 # new_piglist_record = PigList({ # 'facnum': '', # 系统自动生成的记录,不分配 facnum # 'stationid': stationid, # 'animalnum': '', # 系统自动生成的记录,不分配种猪号 # 'earid': earid, # 'entry_time': get_now_timestamp(), # }).entry_one() # new_pigbase_record = PigBase({ # 'pid': new_piglist_record.id, # 'food_intake': food_intake, # 'weight': weight, # 'body_long': body_long, # 'body_width': body_width, # 'body_height': body_height, # 'body_temp': body_temp, # 'env_temp': env_temp, # 'env_humi': env_humi, # 'start_time': start_time, # 'end_time': end_time, # 'sys_time': sys_time, # }).add_one() # # 今日首次采食判断处理 # today_first_intook_proc(sys_time=sys_time, pid=new_piglist_record.id, pigbase_id=new_pigbase_record.id) # # 将当前记录归入日评估 # daily_assess(pid=new_piglist_record.id, start_time=start_time, intake=food_intake, weight=weight) # # initialize_piglist_async() # ------------------- 智能测定站转换 ------------------- # 如果测定站不存在,说明种猪被投放到了一个新的测定站 # # 需要新创建一个测定站 # if not stationid_exist(stationid): # # 1、先创建测定站 # StationInfo({ # 'stationid': stationid, # 'comment': '测定站号自动生成,生成时间 ' + get_now_time('%Y年%m月%d日 -- %H:%M:%S'), # 'status': 'on', # 'changetime': get_now_timestamp(), # 'errorcode': '00000', # }).add_one() # # 刷新内存中的测定站数据 # initialize_station_list_async() return success_response() else: return error_response('种猪未入栏(耳标未在系统注册)') except Exception as e: error_logger(e) error_logger(error_code['1002_0001']) return error_response(error_code['1002_0001'])
def get_pig_base_info(): ''' 查询种猪的基础信息 :param type: all、station、one :param fromId: 初始的 id :param pid: 测定编号 type = 'one' :param stationId: 对应 station id :param fromTime: 起始时间 10 位数字时间戳 :param endTime: 起始时间 10 位数字时间戳 :return: ''' try: request_data = request.args type = request_data.get('type', 'all') from_id = request_data.get('fromId', None) res = None ret = { 'list': [], 'lastId': 0, 'hasNextPage': False, } from_time = request_data.get('fromTime', None) # 直接接收10位的数字时间戳 from_time = 0 if from_time == None else from_time end_time = request_data.get('endTime', None) # 直接接收10位的数字时间戳 end_time = get_now_timestamp() if end_time == None else end_time if type == 'station': # 'station' stationid = request_data.get('stationId') if bool(stationid): res = PigBase().get_from_one_station(stationid=stationid, from_id=from_id, from_time=from_time, end_time=end_time) else: return error_response('缺少测定站号') elif type == 'one': # 'one' pid = request_data.get('pid') if bool(pid): res = PigBase().get_from_one_pig(pid=pid, from_id=from_id, from_time=from_time, end_time=end_time) else: return error_response('缺少测定编号') else: # all res = PigBase().get_from_all_stations(from_id=from_id, from_time=from_time, end_time=end_time) # k v 赋值 for ind, item in enumerate(res): if ind < length_per_page: ret['list'].append({ # pig_base 'id': item.id, 'pid': item.pid, 'foodIntake': item.food_intake, 'weight': item.weight, 'bodyLong': item.body_long, 'bodyWidth': item.body_width, 'bodyHeight': item.body_height, 'bodyTemp': item.body_temp, 'envTemp': item.env_temp, 'envHumi': item.env_humi, 'startTime': item.start_time, 'endTime': item.end_time, 'sysTime': item.sys_time, # pig_list 'facNum': item.facnum, 'animalNum': item.animalnum, 'earId': item.earid, 'stationId': item.stationid, 'entryTime': item.entry_time, }) if ind == length_per_page: ret['hasNextPage'] = True if ret['hasNextPage']: ret['lastId'] = ret['list'][-1:][0].get('id') # 获取最后一条记录的 id, 在下一次 else: ret['lastId'] = 0 return success_response(ret) except Exception as e: error_logger(e) error_logger(error_code['1002_0003']) return error_response(error_code['1002_0003'])