device.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. # -*- coding: utf-8 -*-
  2. """
  3. demeter service
  4. name:device.py 处理设备
  5. author:rabin
  6. """
  7. from demeter.core import *
  8. class Device(object):
  9. type_info = []
  10. # 新增网关时,增加状态和电源或者其他设备
  11. def addDeviceByGateway(self, gateway):
  12. hardware_id = gateway['hardware_id']
  13. gateway_id = gateway['id']
  14. farm_id = gateway['farm_id']
  15. if hardware_id and gateway_id:
  16. self.add({'hardware_id':hardware_id,'server_id':gateway['server_id']}, '网关状态', farm_id, hardware_id, 5, gateway_id, 0, 0, 0, '2', 0, 0)
  17. '''
  18. info = Demeter.service('common').list('device_info', search={'hardware_id':hardware_id})
  19. if not info:
  20. # 网关状态
  21. insert = {}
  22. insert['farm_id'] = farm_id
  23. insert['name'] = '网关状态'
  24. insert['hardware_id'] = hardware_id
  25. insert['gateway_id'] = gateway_id
  26. insert['hardware_type'] = 5
  27. insert['value'] = '2'
  28. insert['type_id'] = 0
  29. insert['status'] = False
  30. Demeter.service('common').update('device_info', None, insert)
  31. # 电源
  32. """
  33. insert = {}
  34. insert['farm_id'] = farm_id
  35. insert['name'] = '电源状态'
  36. insert['hardware_id'] = hardware_id
  37. insert['gateway_id'] = gateway_id
  38. insert['hardware_type'] = 4
  39. insert['value'] = '0'
  40. insert['type_id'] = 8
  41. insert['status'] = False
  42. Demeter.service('common').update('device_info', None, insert)
  43. """
  44. '''
  45. if gateway['server_id'] and gateway['product_id']:
  46. server = Demeter.service('common').one('setting_server', id=gateway['server_id'])
  47. if server['server_type'] == 2 or server['server_type'] == 3:
  48. code = Demeter.service('common').list('setting_modbus_code', search={'product_id':gateway['product_id']})
  49. if code:
  50. for v in code:
  51. if v['slave_id']:
  52. #hardware_type = Demeter.service('core', 'setting').hardware_type(v['oper_type'])
  53. hardware_type = v['hardware_type']
  54. device_type_key = v['device_type_key'].split("\r\n")
  55. j = 0;
  56. for i in device_type_key:
  57. device_type = Demeter.service('common').one('setting_device_type', key=i)
  58. if device_type:
  59. 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)
  60. j = j + 1
  61. # 添加设备
  62. def add(self, where, name, farm_id, hardware_id, hardware_type, gateway_id, type_id, server_id, product_id, value, code_id, code_index):
  63. info = Demeter.service('common').list('device_info', search=where)
  64. if not info:
  65. if hardware_id < 1:
  66. device = Demeter.service('common').list('device_info', search={'gateway_id':gateway_id}, order='hardware_id desc', limit='0,1')
  67. if device:
  68. if '_' in device[0]['hardware_id']:
  69. temp = device[0]['hardware_id'].split('_')
  70. hardware_id = int(temp[1]) + 1
  71. else:
  72. hardware_id = int(device[0]['hardware_id']) + 1
  73. else:
  74. hardware_id = 100001
  75. hardware_id = 's' + str(server_id) + '_' + str(hardware_id)
  76. device_info = Demeter.service('common').one('device_info', hardware_id=str(hardware_id))
  77. if device_info:
  78. return
  79. insert = {}
  80. insert['farm_id'] = farm_id
  81. insert['name'] = name + '#' + str(hardware_id)
  82. insert['hardware_id'] = str(hardware_id)
  83. insert['gateway_id'] = gateway_id
  84. insert['server_id'] = server_id
  85. insert['product_id'] = product_id
  86. insert['hardware_type'] = hardware_type
  87. insert['value'] = value
  88. insert['type_id'] = type_id
  89. insert['status'] = False
  90. insert['code_id'] = code_id
  91. insert['code_index'] = code_index
  92. Demeter.service('common').update('device_info', None, insert)
  93. # 批量处理开关
  94. def switchMul(self, value):
  95. if value['devices']:
  96. model = Demeter.model('device_info')
  97. value['devices'] = tuple(eval(value['devices']))
  98. if value['oper'] == 1:
  99. switch = 1
  100. else:
  101. switch = 2
  102. # 直到执行成功才执行下一个
  103. for v in value['devices']:
  104. feedback = self.switch(v, switch)
  105. if feedback:
  106. state = False
  107. while state == False:
  108. state = self.switchCheck(v)
  109. # 验证按钮执行状态 1为成功了
  110. def switchCheck(self, device_id):
  111. model = Demeter.model('device_info')
  112. model.id = device_id
  113. #model.exp = '1'
  114. model.exp.nq('-1')
  115. info = model.select(type='fetchone')
  116. if info:
  117. return True
  118. return False
  119. # 处理开关-向设备发送请求
  120. def switch(self, device_id, switch=1, mul=False, queue=False):
  121. model = Demeter.model('device_info')
  122. model.id = device_id
  123. info = model.select(type='fetchone')
  124. # 如果有批量控制,还要保存mul的id
  125. if mul:
  126. queue_model = Demeter.model('device_mul_queue')
  127. queue_model.mul_id = mul
  128. queue_model.device_id = info['id']
  129. queue_model.status = 1
  130. queue_model.value = switch
  131. if info['inorder']:
  132. queue_model.inorder = info['inorder']
  133. else:
  134. queue_model.inorder = 100
  135. queue_model.udate = info['udate']
  136. queue_model.hardware_id = info['hardware_id']
  137. queue_model.insert()
  138. return
  139. if info and info['status'] == True:
  140. """
  141. if queue:
  142. oper = self.msg(info['type_id'], switch)
  143. queue_model = Demeter.model('device_mul_queue')
  144. queue_model.id = queue
  145. queue_model.update(oper='正在' + oper + info['name'])
  146. """
  147. # 设置为loading状态,cxnum保存当前的值
  148. model.id = device_id
  149. model.update(exp='-1', cxnum=switch, oper=True, operdate=Demeter.time())
  150. model = Demeter.model('device_gateway')
  151. model.id = info['gateway_id']
  152. gateway_info = model.select(type='fetchone')
  153. if info['type_id'] > 0:
  154. model = Demeter.model('setting_device_type')
  155. model.id = info['type_id']
  156. type_info = model.select(type='fetchone')
  157. if type_info:
  158. info['hardware_id'] = str(info['hardware_id'])
  159. switch = str(switch)
  160. gateway_info['hardware_id'] = str(gateway_info['hardware_id'])
  161. feedback = self.send(type_info, gateway_info, info, switch)
  162. return feedback
  163. else:
  164. msg = self.notice('offline')
  165. model.id = device_id
  166. model.update(exp=msg, cxnum=switch, oper=True, operdate=Demeter.time())
  167. self.mul(info, info['name'] + '失败:' + msg, False)
  168. #Demeter.error('offline')
  169. return ''
  170. # 处理开关-响应
  171. def switchAction(self, param, client, userdata, mid, msg='ok'):
  172. info = param['info']
  173. if info and info['status'] == True:
  174. param['switch'] = info['cxnum']
  175. model = Demeter.model('device_gateway')
  176. model.id = info['gateway_id']
  177. gateway = model.select(type='fetchone')
  178. if msg == 'ok':
  179. model = Demeter.model('device_info')
  180. model.id = info['id']
  181. model.update(value=param['switch'], exp='1', oper=False, operdate=Demeter.time())
  182. # 如果有批量控制
  183. self.mul(info, info['name'] + '成功', True)
  184. else:
  185. msg = self.notice(msg)
  186. model = Demeter.model('device_info')
  187. model.id = info['id']
  188. model.update(exp=msg, oper=True, operdate=Demeter.time())
  189. # 如果有批量控制
  190. self.mul(info, info['name'] + '失败:' + msg, False)
  191. oper = self.msg(info['type_id'], param['switch'])
  192. content = oper + gateway['name'] + '下的'+ info['name'] + '失败,错误提示:' + msg
  193. Demeter.service('record').msg(info['id'], content, info['farm_id'], 3)
  194. #Demeter.error(msg)
  195. def notice(self, msg):
  196. model = Demeter.model('notice_type')
  197. model.key = msg
  198. info = model.select(type='fetchone')
  199. if info:
  200. msg = info['name']
  201. return msg
  202. def msg(self, type_id, switch):
  203. oper = ''
  204. type_model = Demeter.model('setting_device_type')
  205. type_model.id = type_id
  206. type_info = type_model.select(type='fetchone')
  207. if type_info['unit'] == 'button':
  208. if switch == 1:
  209. oper = '升起'
  210. elif switch == 2:
  211. oper = '降下'
  212. elif switch == 5:
  213. oper = '停止'
  214. else:
  215. if switch == 1:
  216. oper = '开启'
  217. else:
  218. oper = '关闭'
  219. return oper
  220. def mul(self, info, msg, state):
  221. model = Demeter.model('device_mul_queue')
  222. mul_model = Demeter.model('device_mul')
  223. model.device_id = info['id']
  224. model.status = 1
  225. queue = model.select()
  226. if queue:
  227. for v in queue:
  228. model.status = 1
  229. model.device_id = info['id']
  230. oper = self.msg(info['type_id'], v['value']) + msg
  231. if state:
  232. model.update(status=2, oper=oper, operdate=Demeter.time())
  233. else:
  234. model.update(status=3, oper=oper, operdate=Demeter.time())
  235. def save(self, config, value, name='', device_type=None):
  236. model = Demeter.model('device_gateway')
  237. model.hardware_id = config['parent']
  238. gateway = model.select(type='fetchone')
  239. if gateway:
  240. #更新网关状态
  241. self.gateway(config['parent'], gateway['farm_id'], gateway['id'])
  242. model_type = Demeter.model('hardware_type')
  243. model_type.key = config['method']
  244. hard = model_type.select(type='fetchone')
  245. model = Demeter.model('device_info')
  246. model.hardware_id = config['child']
  247. model.hardware_type = hard['id']
  248. device = model.select(type='fetchone')
  249. if device:
  250. model.id = device['id']
  251. if config['method'] == 'control' and (value == '0' or value == 0):
  252. model.update(status=True, cdate='time')
  253. return
  254. #update
  255. id = device['id']
  256. if config['method'] == 'sensor' or config['method'] == 'power':
  257. value = Demeter.exp(device['exp'], value)
  258. if config['method'] == 'control':
  259. model.update(exp='1', value=value,status=True,cdate='time',oper=False, operdate=Demeter.time())
  260. else:
  261. model.update(value=value,status=True,cdate='time')
  262. # 上下限判断
  263. # 条件判断
  264. if device['type_id'] > 0 and (hard['id'] == 2 or hard['id'] == 4):
  265. value = float(value)
  266. content = ''
  267. if device['max']:
  268. if value > device['max']:
  269. if device['cxtype'] == 1:
  270. if device['cxnum']:
  271. device['cxnum'] = device['cxnum'] + 1
  272. else:
  273. device['cxnum'] = 1
  274. if device['cxnum'] > 3:
  275. device['cxnum'] = 0
  276. 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']+'进行处理。'
  277. self.msg(id, content, gateway['farm_id'], 2)
  278. else:
  279. device['cxtype'] = 1
  280. device['cxnum'] = 1
  281. model.id = device['id']
  282. if device['cxnum'] == 1:
  283. model.update(farm_id=gateway['farm_id'], cxnum=device['cxnum'],cxtype=device['cxtype'], cxdate='time')
  284. else:
  285. model.update(farm_id=gateway['farm_id'], cxnum=device['cxnum'],cxtype=device['cxtype'])
  286. if device['min']:
  287. if value < device['min']:
  288. if device['cxtype'] == 2:
  289. if device['cxnum']:
  290. device['cxnum'] = device['cxnum'] + 1
  291. else:
  292. device['cxnum'] = 1
  293. if device['cxnum'] > 3:
  294. device['cxnum'] = 0
  295. 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']+'进行处理。'
  296. self.msg(id, content, gateway['farm_id'], 2)
  297. else:
  298. device['cxtype'] = 2
  299. device['cxnum'] = 1
  300. model.id = device['id']
  301. if device['cxnum'] == 1:
  302. model.update(farm_id=gateway['farm_id'], cxnum=device['cxnum'],cxtype=device['cxtype'], cxdate='time')
  303. else:
  304. model.update(farm_id=gateway['farm_id'], cxnum=device['cxnum'],cxtype=device['cxtype'])
  305. content = ''
  306. condition_model = Demeter.model('device_set_condition')
  307. condition_model.device_id = id
  308. condition_model.status = True
  309. condition = condition_model.select()
  310. if condition:
  311. for cv in condition:
  312. state = False
  313. text = ''
  314. cv['value'] = float(cv['value'])
  315. if cv['condition'] == 1 and value > cv['value']:
  316. state = True
  317. text = '超过'
  318. elif cv['condition'] == 2 and value < cv['value']:
  319. state = True
  320. text = '少于'
  321. elif value == cv['value']:
  322. state = True
  323. text = '等于'
  324. if state:
  325. if cv['notice'] == True:
  326. content = gateway['name'] + ','+device['name']+text+str(cv['value'])+device_type['unit']+',当前值'+str(value)+device_type['unit']+',请及时控制'+device_type['name']+'进行处理。'
  327. self.msg(id, content, gateway['farm_id'], 2)
  328. if cv['oper'] == 2:
  329. cv['oper'] = 1
  330. Demeter.service('device').switchMul(cv)
  331. elif cv['oper'] == 3:
  332. cv['oper'] = 0
  333. Demeter.service('device').switchMul(cv)
  334. else:
  335. #insert
  336. model.hardware_id = config['child']
  337. model.farm_id = gateway['farm_id']
  338. model.name = name
  339. model.hardware_type = hard['id']
  340. model.gateway_id = gateway['id']
  341. if device_type:
  342. model.type_id = device_type['id']
  343. else:
  344. model.type_id = 0
  345. model.value = value
  346. model.status = True
  347. id = model.insert()
  348. self.hardware(id, config['child'], gateway['farm_id'],gateway['id'], hard['id'])
  349. if config['method'] == 'pic':
  350. model_pic = Demeter.model('device_pic')
  351. model_pic.farm_id = gateway['farm_id']
  352. model_pic.gateway_id = gateway['id']
  353. model_pic.device_id = id
  354. model_pic.pic = value
  355. model_pic.insert()
  356. else:
  357. data = {}
  358. data['type'] = config['type']
  359. data['gateway'] = config['parent']
  360. data['device'] = config['child']
  361. data['hard'] = config['method']
  362. data['farm'] = gateway['farm_id']
  363. data['source'] = value
  364. data['value'] = value
  365. data['time'] = Demeter.time()
  366. Demeter.model('data', 'tsdb').insert(data)
  367. def msg(self, device_id, content, farm_id, type_id):
  368. model = Demeter.model('msg')
  369. model.farm_id = farm_id
  370. model.content = content
  371. model.device_id = device_id
  372. model.type_id = type_id
  373. info = model.select(type='fetchone')
  374. if not info:
  375. model.farm_id = farm_id
  376. model.content = content
  377. model.device_id = device_id
  378. model.type_id = type_id
  379. model.insert()
  380. else:
  381. model.id = info['id']
  382. model.update(content=content, cdate='time')
  383. def gateway(self, gateway, farm, id):
  384. gateway = str(gateway)
  385. # 更新网关状态
  386. hardware_type = 5
  387. model = Demeter.model('device_info')
  388. model.hardware_id = gateway
  389. model.hardware_type = hardware_type
  390. device = model.select(type='fetchone')
  391. if device:
  392. model.id = device['id']
  393. model.update(value='1',status=True,cdate='time')
  394. else:
  395. model.hardware_id = gateway
  396. model.farm_id = farm
  397. model.name = '网关状态'
  398. model.status = True
  399. model.hardware_type = hardware_type
  400. model.gateway_id = id
  401. model.type_id = 0
  402. model.value = '1'
  403. model.insert()
  404. self.hardware(id, gateway, farm, id, 1)
  405. def hardware(self, id, hardware_id, farm, gateway, hard):
  406. # 记录硬件设备
  407. if hardware_id and id:
  408. model = Demeter.model('hardware')
  409. model.hardware_id = hardware_id
  410. info = model.select(type='fetchone')
  411. if not info:
  412. model.farm_id = farm
  413. model.hardware_id = hardware_id
  414. model.gateway_id = gateway
  415. model.device_id = id
  416. model.hardware_type = hard
  417. model.insert()
  418. # 通信
  419. def send(self, type_info, gateway_info, info, switch):
  420. # 这里要向服务器发送pub请求了,暂时使用临时文件代替
  421. #Demeter.temp(key=type_info['key'], name=info['hardware_id'], value=switch)
  422. feedback = ''
  423. state = False
  424. if 'server_id' in info and info['server_id']:
  425. server = Demeter.service('common').one('setting_server', id=info['server_id'])
  426. if server:
  427. if server['server_type'] == 2:
  428. feedback = self.send_modbus_tcp(type_info, gateway_info, info, switch, server)
  429. state = True
  430. elif server['server_type'] == 3:
  431. feedback = self.send_modbus_rtu(type_info, gateway_info, info, switch, server)
  432. state = True
  433. if not state:
  434. feedback = self.send_pub(type_info, gateway_info, info, switch)
  435. config = {'method':'control', 'type':type_info['key'], 'parent':gateway_info['hardware_id'], 'child':info['hardware_id']}
  436. name = type_info['name'] + '#' + str(info['hardware_id'])
  437. self.save(config, switch, name, type_info)
  438. return feedback
  439. def send_modbus_tcp(self, type_info, gateway_info, info, value, server):
  440. return Demeter.service('tcp', 'modbus').send(server, type_info, info, value)
  441. def send_modbus_rtu(self, type_info, gateway_info, info, value, server):
  442. return Demeter.service('rtu', 'modbus').send(server, type_info, info, value)
  443. def send_pub(self, type_info, gateway_info, info, value):
  444. from demeter.mqtt import Pub
  445. pub = Pub()
  446. key = type_info['key'] + '/' + gateway_info['hardware_id'] + '/' + info['hardware_id']
  447. update = 'update/' + key
  448. feedback = 'status/' + key
  449. #pub.push(update, value, qos=0, callback=self.switchAction, param={'info':info, 'key':feedback, 'switch':switch}, feedback=True)
  450. pub.push(update, value)
  451. return feedback