# -*- coding: utf-8 -*- """ demeter service name:device.py 处理设备 author:rabin """ from demeter.core import * class Device(object): type_info = [] # 新增网关时,增加状态和电源或者其他设备 def addDeviceByGateway(self, gateway): hardware_id = gateway['hardware_id'] gateway_id = gateway['id'] farm_id = gateway['farm_id'] if hardware_id and gateway_id: self.add({'hardware_id':hardware_id,'server_id':gateway['server_id']}, '网关状态', farm_id, hardware_id, 5, gateway_id, 0, 0, 0, '2', 0, 0) ''' info = Demeter.service('common').list('device_info', search={'hardware_id':hardware_id}) if not info: # 网关状态 insert = {} insert['farm_id'] = farm_id insert['name'] = '网关状态' insert['hardware_id'] = hardware_id insert['gateway_id'] = gateway_id insert['hardware_type'] = 5 insert['value'] = '2' insert['type_id'] = 0 insert['status'] = False Demeter.service('common').update('device_info', None, insert) # 电源 """ insert = {} insert['farm_id'] = farm_id insert['name'] = '电源状态' insert['hardware_id'] = hardware_id insert['gateway_id'] = gateway_id insert['hardware_type'] = 4 insert['value'] = '0' insert['type_id'] = 8 insert['status'] = False Demeter.service('common').update('device_info', None, insert) """ ''' if gateway['server_id'] and gateway['product_id']: server = Demeter.service('common').one('setting_server', id=gateway['server_id']) if server['server_type'] == 2 or server['server_type'] == 3: code = Demeter.service('common').list('setting_modbus_code', search={'product_id':gateway['product_id']}) if code: for v in code: if v['slave_id']: #hardware_type = Demeter.service('core', 'setting').hardware_type(v['oper_type']) hardware_type = v['hardware_type'] device_type_key = v['device_type_key'].split("\r\n") j = 0; for i in device_type_key: device_type = Demeter.service('common').one('setting_device_type', key=i) if device_type: self.add({'type_id':device_type['id'],'server_id':gateway['server_id']}, device_type['name'], farm_id, 0, hardware_type, gateway_id, device_type['id'], gateway['server_id'], gateway['product_id'], '', v['id'], j) j = j + 1 # 添加设备 def add(self, where, name, farm_id, hardware_id, hardware_type, gateway_id, type_id, server_id, product_id, value, code_id, code_index): info = Demeter.service('common').list('device_info', search=where) if not info: if hardware_id < 1: device = Demeter.service('common').list('device_info', search={'gateway_id':gateway_id}, order='hardware_id desc', limit='0,1') if device: if '_' in device[0]['hardware_id']: temp = device[0]['hardware_id'].split('_') hardware_id = int(temp[1]) + 1 else: hardware_id = int(device[0]['hardware_id']) + 1 else: hardware_id = 100001 hardware_id = 's' + str(server_id) + '_' + str(hardware_id) device_info = Demeter.service('common').one('device_info', hardware_id=str(hardware_id)) if device_info: return insert = {} insert['farm_id'] = farm_id insert['name'] = name + '#' + str(hardware_id) insert['hardware_id'] = str(hardware_id) insert['gateway_id'] = gateway_id insert['server_id'] = server_id insert['product_id'] = product_id insert['hardware_type'] = hardware_type insert['value'] = value insert['type_id'] = type_id insert['status'] = False insert['code_id'] = code_id insert['code_index'] = code_index Demeter.service('common').update('device_info', None, insert) # 批量处理开关 def switchMul(self, value): if value['devices']: model = Demeter.model('device_info') value['devices'] = tuple(eval(value['devices'])) if value['oper'] == 1: switch = 1 else: switch = 2 # 直到执行成功才执行下一个 for v in value['devices']: feedback = self.switch(v, switch) if feedback: state = False while state == False: state = self.switchCheck(v) # 验证按钮执行状态 1为成功了 def switchCheck(self, device_id): model = Demeter.model('device_info') model.id = device_id #model.exp = '1' model.exp.nq('-1') info = model.select(type='fetchone') if info: return True return False # 处理开关-向设备发送请求 def switch(self, device_id, switch=1, mul=False, queue=False): model = Demeter.model('device_info') model.id = device_id info = model.select(type='fetchone') # 如果有批量控制,还要保存mul的id if mul: queue_model = Demeter.model('device_mul_queue') queue_model.mul_id = mul queue_model.device_id = info['id'] queue_model.status = 1 queue_model.value = switch if info['inorder']: queue_model.inorder = info['inorder'] else: queue_model.inorder = 100 queue_model.udate = info['udate'] queue_model.hardware_id = info['hardware_id'] queue_model.insert() return if info and info['status'] == True: """ if queue: oper = self.msg(info['type_id'], switch) queue_model = Demeter.model('device_mul_queue') queue_model.id = queue queue_model.update(oper='正在' + oper + info['name']) """ # 设置为loading状态,cxnum保存当前的值 model.id = device_id model.update(exp='-1', cxnum=switch, oper=True, operdate=Demeter.time()) model = Demeter.model('device_gateway') model.id = info['gateway_id'] gateway_info = model.select(type='fetchone') if info['type_id'] > 0: model = Demeter.model('setting_device_type') model.id = info['type_id'] type_info = model.select(type='fetchone') if type_info: info['hardware_id'] = str(info['hardware_id']) switch = str(switch) gateway_info['hardware_id'] = str(gateway_info['hardware_id']) feedback = self.send(type_info, gateway_info, info, switch) return feedback else: msg = self.notice('offline') model.id = device_id model.update(exp=msg, cxnum=switch, oper=True, operdate=Demeter.time()) self.mul(info, info['name'] + '失败:' + msg, False) #Demeter.error('offline') return '' # 处理开关-响应 def switchAction(self, param, client, userdata, mid, msg='ok'): info = param['info'] if info and info['status'] == True: param['switch'] = info['cxnum'] model = Demeter.model('device_gateway') model.id = info['gateway_id'] gateway = model.select(type='fetchone') if msg == 'ok': model = Demeter.model('device_info') model.id = info['id'] model.update(value=param['switch'], exp='1', oper=False, operdate=Demeter.time()) # 如果有批量控制 self.mul(info, info['name'] + '成功', True) else: msg = self.notice(msg) model = Demeter.model('device_info') model.id = info['id'] model.update(exp=msg, oper=True, operdate=Demeter.time()) # 如果有批量控制 self.mul(info, info['name'] + '失败:' + msg, False) oper = self.msg(info['type_id'], param['switch']) content = oper + gateway['name'] + '下的'+ info['name'] + '失败,错误提示:' + msg Demeter.service('record').msg(info['id'], content, info['farm_id'], 3) #Demeter.error(msg) def notice(self, msg): model = Demeter.model('notice_type') model.key = msg info = model.select(type='fetchone') if info: msg = info['name'] return msg def msg(self, type_id, switch): oper = '' type_model = Demeter.model('setting_device_type') type_model.id = type_id type_info = type_model.select(type='fetchone') if type_info['unit'] == 'button': if switch == 1: oper = '升起' elif switch == 2: oper = '降下' elif switch == 5: oper = '停止' else: if switch == 1: oper = '开启' else: oper = '关闭' return oper def mul(self, info, msg, state): model = Demeter.model('device_mul_queue') mul_model = Demeter.model('device_mul') model.device_id = info['id'] model.status = 1 queue = model.select() if queue: for v in queue: model.status = 1 model.device_id = info['id'] oper = self.msg(info['type_id'], v['value']) + msg if state: model.update(status=2, oper=oper, operdate=Demeter.time()) else: model.update(status=3, oper=oper, operdate=Demeter.time()) def save(self, config, value, name='', device_type=None): model = Demeter.model('device_gateway') model.hardware_id = config['parent'] gateway = model.select(type='fetchone') if gateway: #更新网关状态 self.gateway(config['parent'], gateway['farm_id'], gateway['id']) model_type = Demeter.model('hardware_type') model_type.key = config['method'] hard = model_type.select(type='fetchone') model = Demeter.model('device_info') model.hardware_id = config['child'] model.hardware_type = hard['id'] device = model.select(type='fetchone') if device: model.id = device['id'] if config['method'] == 'control' and (value == '0' or value == 0): model.update(status=True, cdate='time') return #update id = device['id'] if config['method'] == 'sensor' or config['method'] == 'power': value = Demeter.exp(device['exp'], value) if config['method'] == 'control': model.update(exp='1', value=value,status=True,cdate='time',oper=False, operdate=Demeter.time()) else: model.update(value=value,status=True,cdate='time') # 上下限判断 # 条件判断 if device['type_id'] > 0 and (hard['id'] == 2 or hard['id'] == 4): value = float(value) content = '' if device['max']: if value > device['max']: if device['cxtype'] == 1: if device['cxnum']: device['cxnum'] = device['cxnum'] + 1 else: device['cxnum'] = 1 if device['cxnum'] > 3: device['cxnum'] = 0 content = '从' + Demeter.date(device['cxdate']) + '到' + Demeter.date(Demeter.time()) + ',' + gateway['name'] + ','+device['name']+'超过'+str(device['max'])+device_type['unit']+',当前值'+str(value)+device_type['unit']+',请及时控制'+device_type['name']+'进行处理。' self.msg(id, content, gateway['farm_id'], 2) else: device['cxtype'] = 1 device['cxnum'] = 1 model.id = device['id'] if device['cxnum'] == 1: model.update(farm_id=gateway['farm_id'], cxnum=device['cxnum'],cxtype=device['cxtype'], cxdate='time') else: model.update(farm_id=gateway['farm_id'], cxnum=device['cxnum'],cxtype=device['cxtype']) if device['min']: if value < device['min']: if device['cxtype'] == 2: if device['cxnum']: device['cxnum'] = device['cxnum'] + 1 else: device['cxnum'] = 1 if device['cxnum'] > 3: device['cxnum'] = 0 content = '从' + Demeter.date(device['cxdate']) + '到' + Demeter.date(Demeter.time()) + ',' + gateway['name'] + ','+device['name']+'少于'+str(device['min'])+device_type['unit']+',当前值'+str(value)+device_type['unit']+',请及时控制'+device_type['name']+'进行处理。' self.msg(id, content, gateway['farm_id'], 2) else: device['cxtype'] = 2 device['cxnum'] = 1 model.id = device['id'] if device['cxnum'] == 1: model.update(farm_id=gateway['farm_id'], cxnum=device['cxnum'],cxtype=device['cxtype'], cxdate='time') else: model.update(farm_id=gateway['farm_id'], cxnum=device['cxnum'],cxtype=device['cxtype']) content = '' condition_model = Demeter.model('device_set_condition') condition_model.device_id = id condition_model.status = True condition = condition_model.select() if condition: for cv in condition: state = False text = '' cv['value'] = float(cv['value']) if cv['condition'] == 1 and value > cv['value']: state = True text = '超过' elif cv['condition'] == 2 and value < cv['value']: state = True text = '少于' elif value == cv['value']: state = True text = '等于' if state: if cv['notice'] == True: content = gateway['name'] + ','+device['name']+text+str(cv['value'])+device_type['unit']+',当前值'+str(value)+device_type['unit']+',请及时控制'+device_type['name']+'进行处理。' self.msg(id, content, gateway['farm_id'], 2) if cv['oper'] == 2: cv['oper'] = 1 Demeter.service('device').switchMul(cv) elif cv['oper'] == 3: cv['oper'] = 0 Demeter.service('device').switchMul(cv) else: #insert model.hardware_id = config['child'] model.farm_id = gateway['farm_id'] model.name = name model.hardware_type = hard['id'] model.gateway_id = gateway['id'] if device_type: model.type_id = device_type['id'] else: model.type_id = 0 model.value = value model.status = True id = model.insert() self.hardware(id, config['child'], gateway['farm_id'],gateway['id'], hard['id']) if config['method'] == 'pic': model_pic = Demeter.model('device_pic') model_pic.farm_id = gateway['farm_id'] model_pic.gateway_id = gateway['id'] model_pic.device_id = id model_pic.pic = value model_pic.insert() else: data = {} data['type'] = config['type'] data['gateway'] = config['parent'] data['device'] = config['child'] data['hard'] = config['method'] data['farm'] = gateway['farm_id'] data['source'] = value data['value'] = value data['time'] = Demeter.time() Demeter.model('data', 'tsdb').insert(data) def msg(self, device_id, content, farm_id, type_id): model = Demeter.model('msg') model.farm_id = farm_id model.content = content model.device_id = device_id model.type_id = type_id info = model.select(type='fetchone') if not info: model.farm_id = farm_id model.content = content model.device_id = device_id model.type_id = type_id model.insert() else: model.id = info['id'] model.update(content=content, cdate='time') def gateway(self, gateway, farm, id): gateway = str(gateway) # 更新网关状态 hardware_type = 5 model = Demeter.model('device_info') model.hardware_id = gateway model.hardware_type = hardware_type device = model.select(type='fetchone') if device: model.id = device['id'] model.update(value='1',status=True,cdate='time') else: model.hardware_id = gateway model.farm_id = farm model.name = '网关状态' model.status = True model.hardware_type = hardware_type model.gateway_id = id model.type_id = 0 model.value = '1' model.insert() self.hardware(id, gateway, farm, id, 1) def hardware(self, id, hardware_id, farm, gateway, hard): # 记录硬件设备 if hardware_id and id: model = Demeter.model('hardware') model.hardware_id = hardware_id info = model.select(type='fetchone') if not info: model.farm_id = farm model.hardware_id = hardware_id model.gateway_id = gateway model.device_id = id model.hardware_type = hard model.insert() # 通信 def send(self, type_info, gateway_info, info, switch): # 这里要向服务器发送pub请求了,暂时使用临时文件代替 #Demeter.temp(key=type_info['key'], name=info['hardware_id'], value=switch) feedback = '' state = False if 'server_id' in info and info['server_id']: server = Demeter.service('common').one('setting_server', id=info['server_id']) if server: if server['server_type'] == 2: feedback = self.send_modbus_tcp(type_info, gateway_info, info, switch, server) state = True elif server['server_type'] == 3: feedback = self.send_modbus_rtu(type_info, gateway_info, info, switch, server) state = True if not state: feedback = self.send_pub(type_info, gateway_info, info, switch) config = {'method':'control', 'type':type_info['key'], 'parent':gateway_info['hardware_id'], 'child':info['hardware_id']} name = type_info['name'] + '#' + str(info['hardware_id']) self.save(config, switch, name, type_info) def send_modbus_tcp(self, type_info, gateway_info, info, value, server): return Demeter.service('tcp', 'modbus').send(server, type_info, info, value) def send_modbus_rtu(self, type_info, gateway_info, info, value, server): return Demeter.service('rtu', 'modbus').send(server, type_info, info, value) def send_pub(self, type_info, gateway_info, info, value): from demeter.mqtt import Pub pub = Pub() key = type_info['key'] + '/' + gateway_info['hardware_id'] + '/' + info['hardware_id'] update = 'update/' + key feedback = 'status/' + key #pub.push(update, value, qos=0, callback=self.switchAction, param={'info':info, 'key':feedback, 'switch':switch}, feedback=True) pub.push(update, value) return feedback