rabin 5 éve
szülő
commit
1e91649d23
47 módosított fájl, 1595 hozzáadás és 629 törlés
  1. 3 1
      admin/page/__load__.py
  2. 162 33
      admin/page/device.py
  3. 135 0
      admin/page/hardware.py
  4. 0 135
      admin/page/modbus.py
  5. 135 0
      admin/page/setting.py
  6. 1 1
      conf/dev.conf
  7. 192 0
      cron.py
  8. 9 0
      cron/modbus/client.py
  9. 138 0
      cron/modbus/server.py
  10. 138 0
      cron/mqtt/pub.py
  11. 28 0
      cron/mqtt/sub.py
  12. 14 0
      cron/switch.py
  13. 51 17
      install.py
  14. 16 0
      modbus.py
  15. 23 0
      model/device_gateway.py
  16. 6 2
      model/device_info.py
  17. 19 0
      model/hardware.py
  18. 16 0
      model/hardware_type.py
  19. 0 17
      model/modbus_device_group.py
  20. 12 12
      model/setting_device.py
  21. 17 0
      model/setting_product.py
  22. 4 5
      model/setting_server.py
  23. 9 0
      mqtt.py
  24. 1 0
      runtime/postgresql/device_gateway
  25. 1 1
      runtime/postgresql/device_info
  26. 1 1
      runtime/postgresql/farm
  27. 1 0
      runtime/postgresql/farm_work
  28. 1 0
      runtime/postgresql/farm_work_category
  29. 1 0
      runtime/postgresql/farm_work_land
  30. 1 0
      runtime/postgresql/hardware_type
  31. 1 1
      runtime/postgresql/manage_admin
  32. 1 0
      runtime/postgresql/manage_log
  33. 1 1
      runtime/postgresql/manage_role
  34. 0 1
      runtime/postgresql/modbus_device
  35. 0 1
      runtime/postgresql/modbus_device_group
  36. 0 1
      runtime/postgresql/modbus_server
  37. 1 0
      runtime/postgresql/msg_type
  38. 1 0
      runtime/postgresql/notice_type
  39. 1 0
      runtime/postgresql/setting_device
  40. 1 0
      runtime/postgresql/setting_product
  41. 1 0
      runtime/postgresql/setting_server
  42. 433 0
      service/device.py
  43. 0 209
      service/mqtt/device.py
  44. 1 186
      service/mqtt/record.py
  45. 0 1
      service/setting/__init__.py
  46. 18 2
      service/setting/core.py
  47. 0 1
      service/zeus/__init__.py

+ 3 - 1
admin/page/__load__.py

@@ -1,2 +1,4 @@
 # -*- coding: utf-8 -*-
-from demeter.admin.page.__load__ import *
+from demeter.admin.page.__load__ import *
+
+Demeter.config['setting']['farmList'] = Demeter.service('common').list('farm')

+ 162 - 33
admin/page/device.py

@@ -6,6 +6,83 @@
 """
 from .__load__ import *
 
+class gateway_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			name = u'网关'
+			,path = 'gateway'
+			,width = '600'
+			,height = '500'
+			#,add = False
+			#,edit = False
+			,search = (('label-1','cdate-time-start','cdate-time-end','name-input-mlike'), (u'日期范围',u'开始时间',u'截止时间',u'网关名称'))
+			,thead = (u'网关名称', u'网关ID', u'所属产品', u'关联服务', u'网关连接状态', u'更新时间')
+			,tbody = ('name', 'hardware_id', 'product', 'server', 'status', 'cdate')
+			,state = False
+		)
+		self.list('device_gateway')
+		if self.data['list']:
+			for key, value in enumerate(self.data['list']):
+				device = self.service('common').list('device_info', search={'hardware_id':value['hardware_id']})
+				self.data['list'][key]['status'] = '断开'
+				self.data['list'][key]['product'] = '无'
+				self.data['list'][key]['server'] = '无'
+
+				if value['product_id']:
+					product = self.service('common').one('setting_product', id=value['product_id'])
+					self.data['list'][key]['product'] = product['name']
+				if value['server_id']:
+					server = self.service('common').one('setting_server', id=value['server_id'])
+					self.data['list'][key]['server'] = server['name']
+				if device:
+					for v in device:
+						if v['value']:
+							v['value'] = float(v['value'])
+							if v['hardware_type'] == 5 and v['value'] == 1:
+								self.data['list'][key]['status'] = '连接'
+							elif v['hardware_type'] == 4 and v['value']:
+								self.data['list'][key]['power_status'] = '连接'
+								self.data['list'][key]['power_num'] = v['value']
+		self.show('list')
+
+class gateway_update_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		id = self.input('id')
+		if id:
+			#hardware_id = 'hardware_id-show-required'
+			hardware_id = 'hardware_id-input-required'
+		else:
+			hardware_id = 'hardware_id-input-required'
+		self.set(
+			path = 'gateway'
+			,label = (u'网关名称', u'网关ID', u'所属产品', u'关联服务', u'设备分布图纸')
+			,update = ('name-input-required',hardware_id,'product_id-select-','server_id-select-', 'pic-pic-')
+			,update_product_id = self.service('common').list('setting_product')
+			,update_server_id = self.service('common').list('setting_server')
+		)
+		self.one('device_gateway')
+		self.show('update')
+	@Web.auth
+	@Web.setting
+	def post(self):
+		id = self.update('device_gateway')
+		self.device(id)
+
+	@Web.auth
+	@Web.setting
+	def delete(self):
+		self.drop('device_gateway')
+
+	@Web.auth
+	@Web.setting
+	def device(self, id):
+		info = self.service('common').one('device_gateway', id=id)
+		self.service('device').addDeviceByGateway(info)
+		
 class info_path(Load):
 	@Web.auth
 	@Web.setting
@@ -15,24 +92,37 @@ class info_path(Load):
 			,path = 'info'
 			,width = '600'
 			,height = '400'
-			#,button = ({'name':'添加摄像机','link':'/device/camera_update'},{'name':'添加摄像头','link':'/device/camera_pic_update'})
-			#,add = False
+			,button = ({'name':'添加摄像机','link':'/device/camera_update'},{'name':'添加摄像头','link':'/device/camera_pic_update'})
+			,add = False
 			#,edit = False
-			,search = (('device_id-select-','server_id-select-','name-input-mlike', 'status-hidden-'), (u'设备类型',u'服务类型',u'设备名称', '设备状态'))
-			,thead = (u'设备名称', u'设备类型', u'服务类型', u'当前值', u'设备状态')
-			,tbody = ('name', 'device', 'server', 'value', 'status')
+			,search = (('hardware_type-select-','type_id-select-','name-input-mlike', 'status-hidden-'), (u'硬件类型',u'设备类型',u'设备名称', '设备状态'))
+			,thead = (u'设备名称', u'设备id', u'当前值', u'设备类型', u'网关',u'硬件类型')
+			,tbody = ('name', 'hardware_id', 'value', 'type', 'gateway', 'hardware_type')
 			,state = True
 		)
-		self.data['common']['search_device_id-select-'] = self.service('common').list('modbus_device')
-		self.data['common']['search_server_id-select-'] = self.service('common').list('modbus_server')
-
+		self.data['common']['search_type_id-select-'] = self.service('common').list('setting_device')
+		self.data['common']['search_gateway_id-select---farm_id'] = self.service('common').list('device_gateway')
+		self.data['common']['search_hardware_type-select-'] = self.service('common').list('hardware_type')
+		"""
+		if self.data['common']['search_hardware_type-select-']:
+			del self.data['common']['search_hardware_type-select-'][0]
+		"""
 		status = self.input('search_status-hidden-', False)
 		if status:
 			self.data['search']['status'] = False
 
-		self.list('device_info', order='inorder asc, udate asc, device_id asc')
+		self.list('device_info', order='inorder asc, type_id asc,udate asc,hardware_id asc')
 		if self.data['list']:
 			for key, value in enumerate(self.data['list']):
+				farm = self.service('common').one('farm', id=value['farm_id'])
+				self.data['list'][key]['farm'] = farm['name']
+				self.data['list'][key]['type'] = '无'
+				if value['type_id']:
+					type_info = self.service('common').one('setting_device', id=value['type_id'])
+					if type_info:
+						self.data['list'][key]['type'] = type_info['name']
+				info = self.service('common').one('device_gateway', id=value['gateway_id'])
+				self.data['list'][key]['gateway'] = info['name']
 				if value['status']:
 					self.data['list'][key]['status'] = '已连接'
 				else:
@@ -40,15 +130,14 @@ class info_path(Load):
 
 				if not value['value']:
 					value['value'] = ''
-
-				device = self.service('common').one('modbus_device', id=value['device_id'])
-				server = self.service('common').one('modbus_server', id=value['server_id'])
-
-				if device and device['slave_type'] == 1:
-					if device['unit']:
-						value['value'] = value['value'] + ' ' + device['unit']
+					self.data['list'][key]['value'] = '无'
+				elif value['hardware_type'] == 2 or value['hardware_type'] == 4:
+					if value['type_id'] and type_info:
+						value['value'] = value['value'] + ' ' + type_info['unit']
 					self.data['list'][key]['value'] = '<a href="/device/stat?id='+value['id']+'&search_date-select-=1&method=list">'+value['value'] + '</a><br />更新时间:' + Demeter.date(value['cdate']) + '<br /><a href="/device/stat?id='+value['id']+'&search_date-select-=1&method=avg">[平均值统计]</a> <a href="/device/stat?id='+value['id']+'&search_date-select-=1&method=maxmin">[高低值统计]</a>'
-				elif device and device['slave_type'] == 2:
+				elif value['hardware_type'] == 6:
+					self.data['list'][key]['value'] = '<a href="/device/pic?id='+value['id']+'"><img src="'+value['value']+'" width="200px"/></a><br />更新时间:' + Demeter.date(value['cdate'])
+				elif value['hardware_type'] == 3:
 					if value['status']:
 						status = ''
 					else:
@@ -60,8 +149,14 @@ class info_path(Load):
 					else:
 						self.data['list'][key]['value'] = '<input type="checkbox" lay-filter="switch" name="switch" lay-skin="switch" '+status+' value="0" data-value="1" data-id="'+value['id']+'" data-url="'+url+'">'
 					self.data['list'][key]['value'] = ''
-				elif device and (device['slave_type'] == 3 or device['slave_type'] == 4):
-					self.data['list'][key]['value'] = '<a href="/device/pic?id='+value['id']+'"><img src="'+value['value']+'" width="200px"/></a><br />更新时间:' + Demeter.date(value['cdate'])
+				elif value['hardware_type'] == 5:
+					if value['value'] == '1':
+						self.data['list'][key]['value'] = '已连接'
+					else:
+						self.data['list'][key]['value'] = '已断开'
+
+				hardware_type = self.service('common').one('hardware_type', id=value['hardware_type'])
+				self.data['list'][key]['hardware_type'] = hardware_type['name']
 
 
 		self.show('list')
@@ -82,13 +177,39 @@ class info_update_path(Load):
 	@Web.setting
 	def get(self):
 		self.one('device_info')
-		self.set(
-			path = 'info'
-			,label = (u'设备名称', u'设备类型', u'服务类型', u'当前值/摄像地址', u'排序')
-			,update = ('name-input-required','device_id-select-required','server_id-select-','value-text-','inorder-input-')
-			,update_device_id = self.service('common').list('modbus_device')
-			,update_server_id = self.service('common').list('modbus_server')
-		)
+		if self.data['info']['hardware_type'] == 7:
+			self.set(
+				path = 'camera'
+				#,label = (u'摄像机名称', u'摄像机id', u'所属农场', u'选择网关', u'选择硬件类型', u'摄像机地址')
+				#,update = ('name-input-required','hardware_id-show-','farm_id-select-required','gateway_id-select-required','hardware_type-select-required','value-text-required')
+				,label = (u'摄像机名称', u'摄像机id', u'所属农场', u'选择网关', u'摄像机地址', u'排序')
+				,update = ('name-input-required','hardware_id-show-','farm_id-select-required-gateway_id','gateway_id-select-required--farm_id','value-text-required','inorder-input-')
+				,update_farm_id = Demeter.config['setting']['farmList']
+				,update_gateway_id = self.service('common').list('device_gateway')
+				#,update_hardware_type = self.service('common').list('hardware_type')
+			)
+		elif self.data['info']['hardware_type'] == 6:
+			self.set(
+				path = 'camera_pic'
+				,label = (u'摄像头名称', u'摄像头id', u'所属农场', u'选择网关', u'摄像头地址', u'排序')
+				,update = ('name-input-required','hardware_id-show-','farm_id-select-required-gateway_id','gateway_id-select-required--farm_id','value-text-required','inorder-input-')
+				,update_farm_id = Demeter.config['setting']['farmList']
+				,update_gateway_id = self.service('common').list('device_gateway')
+			)
+		elif self.data['info']['hardware_type'] in (2,4):
+			self.set(
+				path = 'info'
+				#,label = (u'设备名称', u'设备id', u'计算公式', u'实时计算公式')
+				#,update = ('name-input-required','hardware_id-show-',u'exp-text--{n}为当前数据,只处理最新数据',u'out_exp-text--处理所有数据,比较消耗服务器资源')
+				,label = (u'设备名称', u'设备id', u'计算公式', u'排序')
+				,update = ('name-input-required','hardware_id-show-',u'exp-input--{n}为当前数据,只处理最新数据','inorder-text-')
+			)
+		else:
+			self.set(
+				path = 'info'
+				,label = (u'设备名称', u'设备id', u'排序')
+				,update = ('name-input-required','hardware_id-show-','inorder-input-')
+			)
 		self.show('update')
 	@Web.auth
 	@Web.setting
@@ -98,6 +219,14 @@ class info_update_path(Load):
 	@Web.setting
 	def delete(self):
 		self.drop('device_info')
+		"""
+		self.one('device_info')
+		if self.input('state') == 'True' or (self.data['info'] and 'hardware_type' in self.data['info'] and self.data['info']['hardware_type'] == 7):
+			self.drop('device_info')
+		else:
+			#除摄像机之外,其余设备不允许删除
+			self.out('no')
+		"""
 
 class camera_path(Load):
 	@Web.auth
@@ -111,8 +240,8 @@ class camera_update_path(Load):
 	def get(self):
 		self.set(
 			path = 'camera'
-			,label = (u'摄像机名称', u'摄像机地址',u'排序')
-			,update = ('name-input-required','farm_id-select-required-gateway_id','gateway_id-select-required--farm_id','value-text-required','inorder-text-')
+			,label = (u'摄像机名称', u'摄像机id', u'所属农场', u'选择网关', u'摄像机地址',u'排序')
+			,update = ('name-input-required','hardware_id-input-required','farm_id-select-required-gateway_id','gateway_id-select-required--farm_id','value-text-required','inorder-text-')
 			,update_farm_id = Demeter.config['setting']['farmList']
 			,update_gateway_id = self.service('common').list('device_gateway')
 		)
@@ -194,7 +323,7 @@ class stat_path(Load):
 			,search = (('label-1','cdate-time-start','cdate-time-end', 'date-select-'), (u'日期范围',u'开始时间',u'截止时间',u'周期选择'))
 		)
 		data = self.service('common').one('device_info', id=id)
-		typeInfo = self.service('common').one('device_type', id=data['type_id'])
+		typeInfo = self.service('common').one('setting_device', id=data['type_id'])
 		farm = self.service('common').one('farm', id=data['farm_id'])
 		self.data['info'] = data
 		self.data['type'] = typeInfo
@@ -229,7 +358,7 @@ class type_path(Load):
 			,tbody = ('id', 'name', 'key', 'unit', 'cdate')
 			,state = True
 		)
-		self.list('device_type')
+		self.list('setting_device')
 		self.show('list')
 
 class type_update_path(Load):
@@ -243,16 +372,16 @@ class type_update_path(Load):
 			,label = (u'类型名称', u'类型标识',u'类型单位')
 			,update = ('name-input-required','key-input-required','unit-input-')
 		)
-		self.one('device_type')
+		self.one('setting_device')
 		self.show('update')
 	@Web.auth
 	@Web.setting
 	def post(self):
-		self.update('device_type')
+		self.update('setting_device')
 	@Web.auth
 	@Web.setting
 	def delete(self):
-		self.drop('device_type')
+		self.drop('setting_device')
 
 
 class printer_path(Load):

+ 135 - 0
admin/page/hardware.py

@@ -0,0 +1,135 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter web page
+    name:hardware.py 硬件相关页面
+    author:rabin
+"""
+from .__load__ import *
+
+class hardware_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			name = u'硬件设备'
+			,path = '/hardware/hardware'
+			,width = '600'
+			,height = '600'
+			,add = False
+			,edit = False
+			,search = (('farm_id-select-','hardware_type-select-','hardware_id-input-mlike'), (u'选择农场',u'硬件类型', u'硬件id'))
+			,thead = (u'所属农场', u'硬件类型', u'硬件id',u'网关名',u'设备名', u'接入时间')
+			,tbody = ('farm','type', 'hardware_id', 'gateway', 'device', 'cdate')
+			,state = False
+		)
+		self.data['common']['search_farm_id-select-'] = Demeter.config['setting']['farmList']
+		self.data['common']['search_hardware_type-select-'] = self.service('common').list('hardware_type')
+		self.list('hardware')
+		if self.data['list']:
+			for key, value in enumerate(self.data['list']):
+				farm = self.service('common').one('farm', id=value['farm_id'])
+				self.data['list'][key]['farm'] = farm['name']
+				htype = self.service('common').one('hardware_type', id=value['hardware_type'])
+				self.data['list'][key]['type'] = htype['name']
+
+				gateway = self.service('common').one('device_gateway', id=value['gateway_id'])
+				self.data['list'][key]['gateway'] = '无效'
+				if gateway:
+					self.data['list'][key]['gateway'] = gateway['name']
+				self.data['list'][key]['device'] = '无效'
+				if value['device_id']:
+					device = self.service('common').one('device_info', id=value['device_id'])
+					if device:
+						self.data['list'][key]['device'] = device['name']
+					
+		self.show('list')
+
+class hardware_update_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			path = '/hardware/hardware'
+			,label = (u'硬件类型',u'硬件id')
+			,update = ('hardware_type-select-required','hardware_id-input-required')
+			,update_hardware_type = self.service('common').list('hardware_type')
+		)
+		self.one('hardware')
+		self.show('update')
+	@Web.auth
+	@Web.setting
+	def post(self):
+		self.update('hardware')
+	@Web.auth
+	@Web.setting
+	def delete(self):
+		self.drop('hardware')
+
+class type_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			name = u'硬件类型'
+			,path = '/hardware/type'
+			,button = ({'name':'重启守护进程','link':'/hardware/restart_cron','ajax':True,'icon':'&#xe631;'},{'name':'重启mqtt订阅服务','link':'/hardware/restart_sub','ajax':True,'icon':'&#xe631;'},{'name':'重启园区服务','link':'/hardware/restart_front','ajax':True,'icon':'&#xe631;'},{'name':'重启后台服务','link':'/hardware/restart_admin','ajax':True,'icon':'&#xe631;'},{'name':'重启网站服务','link':'/hardware/restart_web','ajax':True,'icon':'&#xe631;'})
+			,width = '600'
+			,height = '300'
+			,search = (('name-input-mlike',), (u'类型名称',))
+			,thead = (u'类型ID',u'类型名称',u'类型key', u'更新时间')
+			,tbody = ('id', 'name', 'key', 'cdate')
+			,state = False
+		)
+		self.list('hardware_type')
+		self.show('list')
+
+class type_update_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			path = '/hardware/type'
+			,label = (u'类型名称', u'类型key')
+			,update = ('name-input-required', 'key-input-required')
+		)
+		self.one('hardware_type')
+		self.show('update')
+	@Web.auth
+	@Web.setting
+	def post(self):
+		self.update('hardware_type')
+	@Web.auth
+	@Web.setting
+	def delete(self):
+		self.drop('hardware_type')
+
+class restart_cron_path(Load):
+	@Web.auth
+	@Web.setting
+	def post(self):
+		Shell.popen("ps -ef | grep cron.py | grep -v grep |awk '{print $1}'|xargs kill -9")
+		Shell.popen('/usr/local/demeter/cron.py >/dev/null &')
+
+class restart_sub_path(Load):
+	@Web.auth
+	@Web.setting
+	def post(self):
+		Shell.popen("ps -ef | grep sub.py | grep -v grep |awk '{print $1}'|xargs kill -9")
+
+class restart_admin_path(Load):
+	@Web.auth
+	@Web.setting
+	def post(self):
+		Shell.popen("ps -ef | grep admin.py | grep -v grep |awk '{print $1}'|xargs kill -9")
+
+class restart_front_path(Load):
+	@Web.auth
+	@Web.setting
+	def post(self):
+		Shell.popen("ps -ef | grep front.py | grep -v grep |awk '{print $1}'|xargs kill -9")
+
+class restart_web_path(Load):
+	@Web.auth
+	@Web.setting
+	def post(self):
+		Shell.popen("ps -ef | grep web.py | grep -v grep |awk '{print $1}'|xargs kill -9")

+ 0 - 135
admin/page/modbus.py

@@ -1,135 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-    demeter modbus page
-    name:modbus.py 服务协议管理
-    author:rabin
-"""
-from .__load__ import *
-
-class server_path(Load):
-	@Web.auth
-	@Web.setting
-	def get(self):
-		self.set(
-			name = u'服务管理'
-			,path = '/modbus/server'
-			,width = '600'
-			,height = '600'
-			,search = (('label-1','cdate-time-start','cdate-time-end','name-input-mlike'), (u'日期范围',u'开始时间',u'截止时间',u'服务名称'))
-			,thead = (u'服务名称', u'服务类型', u'服务地址', u'服务端口', u'更新时间')
-			,tbody = ('name', 'server_type', 'server_host', 'server_port', 'cdate')
-			,state = True
-		)
-		self.list('modbus_server')
-		if self.data['list']:
-			for key, value in enumerate(self.data['list']):
-				if value['server_type'] == 1:
-					self.data['list'][key]['server_type'] = 'tcp'
-				else:
-					self.data['list'][key]['server_type'] = 'rtu'
-		self.show('list')
-
-class server_update_path(Load):
-	@Web.auth
-	@Web.setting
-	def get(self):
-		self.set(
-			path = '/modbus/server'
-			,label = (u'服务名称',u'服务类型',u'服务地址',u'服务端口')
-			,update = ('name-input-required','server_type-select-required','server_host-input-required','server_port-input-required')
-			,update_server_type = Demeter.service('core', 'modbus').server_type()
-		)
-		self.one('modbus_server')
-		self.show('update')
-	@Web.auth
-	@Web.setting
-	def post(self):
-		self.update('modbus_server')
-	@Web.auth
-	@Web.setting
-	def delete(self):
-		self.drop('modbus_server')
-
-
-class group_path(Load):
-	@Web.auth
-	@Web.setting
-	def get(self):
-		self.set(
-			name = u'分组管理'
-			,path = '/modbus/group'
-			,width = '600'
-			,height = '600'
-			,search = (('label-1','cdate-time-start','cdate-time-end','name-input-mlike'), (u'日期范围',u'开始时间',u'截止时间',u'分组名称'))
-			,thead = (u'分组名称',u'分组标识', u'更新时间')
-			,tbody = ('name', 'key', 'cdate')
-			,state = True
-		)
-		self.list('modbus_device_group')
-		self.show('list')
-
-class group_update_path(Load):
-	@Web.auth
-	@Web.setting
-	def get(self):
-		self.set(
-			path = '/modbus/group'
-			,label = (u'分组名称',u'分组标识')
-			,update = ('name-input-required','key-input-required')
-		)
-		self.one('modbus_device_group')
-		self.show('update')
-	@Web.auth
-	@Web.setting
-	def post(self):
-		self.update('modbus_device_group')
-	@Web.auth
-	@Web.setting
-	def delete(self):
-		self.drop('modbus_device_group')
-
-class device_path(Load):
-	@Web.auth
-	@Web.setting
-	def get(self):
-		self.set(
-			name = u'设备管理'
-			,path = '/modbus/device'
-			,width = '600'
-			,height = '600'
-			,search = (('label-1','cdate-time-start','cdate-time-end','name-input-mlike','group_id-select-'), (u'日期范围',u'开始时间',u'截止时间',u'设备名称',u'选择分组'))
-			,thead = (u'设备名称', u'所属分组', u'更新时间')
-			,tbody = ('name', 'group', 'cdate')
-			,state = True
-		)
-		self.data['common']['search_group_id-select-'] = self.service('common').list('modbus_device_group')
-		self.list('modbus_device')
-		if self.data['list']:
-			for key, value in enumerate(self.data['list']):
-				group = self.service('common').one('modbus_device_group', id=value['group_id'])
-				self.data['list'][key]['group'] = group['name']
-		self.show('list')
-
-class device_update_path(Load):
-	@Web.auth
-	@Web.setting
-	def get(self):
-		self.set(
-			path = '/modbus/device'
-			,label = (u'设备名称',u'选择分组',u'设备类型',u'从机id',u'寄存器类型',u'寄存器地址',u'寄存器长度',u'单位',u'计算公式',u'数据类型',u'可选项')
-			,update = ('name-input-required','group_id-select-required','slave_type-select-required','slave_id-input-','register_type-select-','register_address-input-','register_length-input-','unit-input-','exp-text--{n}为当前数据','data_type-select-','data_option-text--多个换行隔开')
-			,update_group_id = self.service('common').list('modbus_device_group')
-			,update_slave_type = Demeter.service('core', 'modbus').slave_type()
-			,update_register_type = Demeter.service('core', 'modbus').register_type()
-			,update_data_type = Demeter.service('core', 'modbus').data_type()
-		)
-		self.one('modbus_device')
-		self.show('update')
-	@Web.auth
-	@Web.setting
-	def post(self):
-		self.update('modbus_device')
-	@Web.auth
-	@Web.setting
-	def delete(self):
-		self.drop('modbus_device')

+ 135 - 0
admin/page/setting.py

@@ -0,0 +1,135 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter setting page
+    name:setting.py 服务协议管理
+    author:rabin
+"""
+from .__load__ import *
+
+class server_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			name = u'服务管理'
+			,path = '/setting/server'
+			,width = '600'
+			,height = '600'
+			,search = (('label-1','cdate-time-start','cdate-time-end','name-input-mlike'), (u'日期范围',u'开始时间',u'截止时间',u'服务名称'))
+			,thead = (u'服务名称', u'服务类型', u'服务地址', u'服务端口', u'更新时间')
+			,tbody = ('name', 'server_type', 'server_host', 'server_port', 'cdate')
+			,state = True
+		)
+		self.list('setting_server')
+		if self.data['list']:
+			server_type = Demeter.service('core', 'setting').server_type()
+			for key, value in enumerate(self.data['list']):
+				self.data['list'][key]['server_type'] = server_type[value['server_type']-1]['name']
+		self.show('list')
+
+class server_update_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			path = '/setting/server'
+			,label = (u'服务名称',u'服务类型',u'服务地址',u'服务端口')
+			,update = ('name-input-required','server_type-select-required','server_host-input-required','server_port-input-required')
+			,update_server_type = Demeter.service('core', 'setting').server_type()
+		)
+		self.one('setting_server')
+		self.show('update')
+	@Web.auth
+	@Web.setting
+	def post(self):
+		self.update('setting_server')
+	@Web.auth
+	@Web.setting
+	def delete(self):
+		self.drop('setting_server')
+
+
+class product_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			name = u'产品管理'
+			,path = '/setting/product'
+			,width = '600'
+			,height = '600'
+			,search = (('label-1','cdate-time-start','cdate-time-end','name-input-mlike'), (u'日期范围',u'开始时间',u'截止时间',u'产品名称'))
+			,thead = (u'产品名称',u'产品标识', u'更新时间')
+			,tbody = ('name', 'key','cdate')
+			,state = True
+		)
+		self.list('setting_product')
+		self.show('list')
+
+class product_update_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			path = '/setting/product'
+			,label = (u'产品名称',u'产品标识')
+			,update = ('name-input-required','key-input-required')
+		)
+		self.one('setting_product')
+		self.show('update')
+	@Web.auth
+	@Web.setting
+	def post(self):
+		self.update('setting_product')
+	@Web.auth
+	@Web.setting
+	def delete(self):
+		self.drop('setting_product')
+
+class device_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			name = u'设备管理'
+			,path = '/setting/device'
+			,width = '600'
+			,height = '600'
+			,search = (('label-1','cdate-time-start','cdate-time-end','name-input-mlike','product_id-select-'), (u'日期范围',u'开始时间',u'截止时间',u'设备名称',u'选择产品'))
+			,thead = (u'设备名称',u'设备标识', u'所属产品', u'单位', u'更新时间')
+			,tbody = ('name','key', 'product','unit', 'cdate')
+			,state = True
+		)
+		self.data['common']['search_product_id-select-'] = self.service('common').list('setting_product')
+		self.list('setting_device')
+		if self.data['list']:
+			for key, value in enumerate(self.data['list']):
+				product = self.service('common').one('setting_product', id=value['product_id'])
+				self.data['list'][key]['product'] = product['name']
+				if not value['unit']:
+					value['unit'] = '无'
+		self.show('list')
+
+class device_update_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.set(
+			path = '/setting/device'
+			,label = (u'设备名称',u'设备标识',u'所属产品',u'单位',u'计算公式',u'设备类型',u'数据类型',u'可选项',u'从机id',u'寄存器类型',u'寄存器地址',u'寄存器长度')
+			,update = ('name-input-required','key-input-required','product_id-select-required','unit-input-','exp-text--{n}为当前数据','oper_type-select-required','data_type-select-','data_option-text--多个换行隔开','modbus_slave_id-input-','modbus_register_type-select-','modbus_register_address-input-','modbus_register_length-input-')
+			,update_product_id = self.service('common').list('setting_product')
+			,update_oper_type = Demeter.service('core', 'setting').oper_type()
+			,update_modbus_register_type = Demeter.service('core', 'setting').register_type()
+			,update_data_type = Demeter.service('core', 'setting').data_type()
+		)
+		self.one('setting_device')
+		self.show('update')
+	@Web.auth
+	@Web.setting
+	def post(self):
+		self.update('setting_device')
+	@Web.auth
+	@Web.setting
+	def delete(self):
+		self.drop('setting_device')

+ 1 - 1
conf/dev.conf

@@ -60,7 +60,7 @@ process				= 0
 ;定义后台父级菜单
 menu_parent			= 农场管理:&#xe62e;,设备管理:&#xe62c;,服务管理:&#xe614;
 ;定义后台子级菜单
-menu_child			= 基础资料:/farm/info?id=1,用户管理:/farm/user,产品管理:/farm/product,地块管理:/work/land,农事管理:/work/work;设备列表:/device/info,设备分组:/device/group;设备配置:/modbus/device,服务配置:/modbus/server,分组配置:/modbus/group
+menu_child			= 基础资料:/farm/info?id=1,用户管理:/farm/user,产品管理:/farm/product,地块管理:/work/land,农事管理:/work/work;网关列表:/device/gateway,设备列表:/device/info;产品配置:/setting/product,设备配置:/setting/device,服务配置:/setting/server,硬件类型:/hardware/type
 
 ;cookie
 cookie_secret       = 61oETzKXQAGaYekL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=

+ 192 - 0
cron.py

@@ -0,0 +1,192 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:admin.py
+    author:rabin
+"""
+import time
+from demeter.core import *
+from gevent import monkey; monkey.patch_socket()
+import gevent
+from pic import pic
+from demeter.mqtt import *
+# 处理定时命令、周期命令、条件控制、消息、设备状态等
+timeSleep = 10
+
+# 开关设备
+def switch(value):
+	Demeter.service('device').switchMul(value)
+				
+
+# 更改设备状态(离线)
+def device():
+	while 1:
+		model = Demeter.model('device_info')
+		cur = Demeter.time() - 1800
+		model.cdate.assgin(cur, '<=')
+		model.status = True
+		data = model.select()
+		for v in data:
+			model.id = v['id']
+			if v['hardware_type'] == 5:
+				model.update(value='0', status=False)
+			elif v['hardware_type'] != 7 and v['hardware_type'] != 6:
+				model.update(status=False)
+		gevent.sleep(60)
+
+# 更改控制设备的超时状态
+def control():
+	while 1:
+		model = Demeter.model('device_info')
+		cur = Demeter.time() - 10
+		model.operdate.assgin(cur, '<=')
+		model.oper = True
+		model.hardware_type = 3
+		service = Demeter.service('device')
+		data = model.select()
+		if data:
+			for v in data:
+				model.id = v['id']
+				if v['exp'] == '-1':
+					msg = service.notice('timeout')
+					service.mul(v, v['name'] + '失败:' + msg, False)
+					model.update(exp=msg, oper=True, operdate=Demeter.time())
+				else:
+					msg = '1'
+					service.mul(v, '', True)
+					model.update(exp=msg, oper=False, operdate=Demeter.time())
+
+		gevent.sleep(1)
+		
+
+# 批量控制的队列 这块有点乱,但时间太紧,只有两天时间,以后改造优化
+def mulQueue():
+	while 1:
+		mul_model = Demeter.model('device_mul')
+		device_model = Demeter.model('device_info')
+		model = Demeter.model('device_mul_queue')
+
+		model.status = 1
+		data = model.select(type='fetchone', order='inorder asc,udate asc,hardware_id asc')
+		service = Demeter.service('device')
+
+		# 查看当前有没有正在执行的设备,如果有,不能继续执行了
+		msg = service.notice('timeout')
+		device_model.oper = True
+		device_model.exp.nq(msg)
+		device_model.hardware_type = 3
+		device = device_model.select(type='fetchone')
+
+		if not device and data and not data['operstate']:
+			service.switch(data['device_id'], switch=data['value'], mul=False, queue=data['id'])
+			model.id = data['id']
+			model.update(operstate=True)
+			#mul_model.id = data['mul_id']
+			#mul_model.update(oper='')
+
+		# 将执行完成的进行清理
+		mul_model.oper.nq('')
+		data = mul_model.select()
+		if data:
+			for v in data:
+				devicesNum = len(tuple(eval(v['devices'])))
+				model.status.ins((2,3))
+				cur = Demeter.time() - 10
+				model.operdate.assgin(cur, '<=')
+				queue = model.select()
+				num = len(queue)
+				if num == devicesNum:
+					errorNum = 0
+					model.mul_id = v['id']
+					model.update(status=4)
+					for qv in queue:
+						if qv['status'] == 3:
+							errorNum = errorNum + 1
+					mul_model.id = v['id']
+					if errorNum == devicesNum:
+						mul_model.update(oper='', value=v['old'])
+					else:
+						mul_model.update(oper='')
+
+		gevent.sleep(1)
+
+# 批量控制的队列清理,10小时清理一次24小时之前完成的数据
+def mulQueueDrop():
+	while 1:
+		num = 3600*24
+		model = Demeter.model('device_mul_queue')
+		model.status = 4
+		cur = Demeter.time() - num
+		model.operdate.assgin(cur, '<=')
+		model.delete()
+
+		gevent.sleep(36000)
+
+def timing():
+	while 1:
+		model = Demeter.model('device_set_timing')
+		model.status = 0
+		cur = Demeter.time()
+		model.zdate.assgin(cur, '<=')
+		data = model.select()
+		if data:
+			for value in data:
+				switch(value)
+				model.id = value['id']
+				model.update(status=1)
+		gevent.sleep(timeSleep)
+
+def loop():
+	while 1:
+		model = Demeter.model('device_set_loop')
+		cur = Demeter.time()
+		date = Demeter.date(cur, '%Y-%m-%d-%w-%H-%M')
+		date = date.split('-')
+		week = date[3]
+		day = date[2]
+		model.status = True
+		model.hour = date[4]
+		model.minute = date[5]
+		data = model.select()
+		if data:
+			for value in data:
+				state = False
+				value['loop'] = value['loop'].split(',')
+				if value['looptype'] == 2:
+					if week in value['loop']:
+						state = True
+				elif value['looptype'] == 3:
+					if day in value['loop']:
+						state = True
+				if state:
+					switch(value)
+		gevent.sleep(timeSleep)
+
+def savePic():
+	while 1:
+		pic()
+		gevent.sleep(1800)
+
+# 同步时间,24小时同步一次
+def timeSync():
+	while 1:
+		pub = Pub()
+		key = 'time/bh'
+		value = Demeter.date(Demeter.time())
+		pub.push(key, value)
+		gevent.sleep(3600*24)
+
+def handle():
+	gevent.joinall([
+		gevent.spawn(timing),
+		gevent.spawn(loop),
+		gevent.spawn(device),
+		gevent.spawn(savePic),
+		gevent.spawn(control),
+		gevent.spawn(timeSync),
+		gevent.spawn(mulQueue),
+		gevent.spawn(mulQueueDrop),
+	])
+
+handle()

+ 9 - 0
cron/modbus/client.py

@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:sub.py
+    author:rabin
+"""
+from demeter.core import *
+
+Demeter.service('tcp', 'modbus').client()

+ 138 - 0
cron/modbus/server.py

@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:pub.py
+    author:rabin
+"""
+from demeter.mqtt import *
+from demeter.tcp import *
+import ConfigParser
+import random
+import time
+import base64
+
+"""
+pub = Pub()
+key = 'status/valve/10086/100107'
+value = 'ok'
+state = pub.push(key, value)
+"""
+pub = Pub()
+key = 'control/airdryer/10011/1001151'
+value = '0'
+state = pub.push(key, value)
+
+print state
+"""
+def callback(param, client, userdata, mid):
+	print mid
+
+pub = Pub()
+key = 'update/test/222/222'
+value = 2
+state = pub.push(key, value, 2, callback=callback, param='ttt')
+print state
+"""
+def push():
+	# 模拟传感器设备数据
+	gateway = 10086
+	def device(min):
+		max = min + 9
+		return str(random.randint(min, max))
+	def val(min, max):
+		return str(round(random.uniform(min, max), 2))
+
+	def switch():
+		return str(random.randint(0, 1))
+
+	hard = 'sensor'
+	pubType = (
+		{'hard':'sensor','type':'temprature','device':100000,'value':(-20, 30)}
+		,{'hard':'sensor','type':'humidity','device':100010,'value':(30, 80)}
+		,{'hard':'sensor','type':'light','device':100020,'value':(3000, 13000)}
+		,{'hard':'power','type':'power','device':100090,'value':(1, 50)}
+		,{'hard':'control','type':'valve','device':100100}
+		,{'hard':'control','type':'blower','device':100110}
+		,{'hard':'power','type':'power','device':10086,'value':(1, 50)}
+		)
+	pub = Pub()
+	while True:
+		config = Demeter.temp()
+		for v in pubType:
+			if v['device'] == gateway:
+				id = v['device']
+			else:
+				id = device(v['device'])
+			key = v['hard']+'/'+v['type']+'/'+str(gateway)+'/'+str(id)
+			if 'value' in v:
+				value = val(v['value'][0], v['value'][1])
+			else:
+				value = config[v['type']][id]
+			print 'key:' + key + ' value:' + value
+			pub.push(key, value)
+		time.sleep(1)
+
+def pic():
+	gateway = '10086'
+	pub = Pub()
+	key = 'pic/pic_'
+	gateway = '/' + gateway + '/200001'
+	with open('front/static/pc/images/376a00e6.tmp2.jpg', 'rb') as f:
+		data = f.readlines()
+		total = len(data)
+		key = key + str(total) + '_'
+		i = 0
+		print key
+		for value in data:
+			k = key + str(i) + gateway
+			pub.push(k, value)
+			print k
+			i = i+1
+
+#push()
+#pic()
+
+def tcp_sensor():
+	# 模拟设备数据
+	gateway = '10086'
+	def device():
+		return str(random.randint(100000, 100010))
+	def val():
+		return str(random.randint(1, 50))
+
+	hard = 'sensor'
+	pubType = ('temperature', 'humidity')
+	client = Client('0.0.0.0', 8000)
+	while True:
+		for v in pubType:
+			key = hard+'/'+v+'/'+gateway+'/'+device()
+			value = val()
+			print 'key:' + key + ' value:' + value
+			client.send(key+'|:|'+value)
+		time.sleep(1)
+
+def tcp_pic():
+	gateway = '10086'
+	client = Client('0.0.0.0', 8000)
+	key = 'pic/'
+	key = 'pic/pic_'
+	gateway = '/' + gateway + '/200001'
+	with open('admin/static/images/banner.png', 'rb') as f:
+		data = f.readlines()
+		total = len(data)
+		key = key + str(total) + '_'
+		i = 0
+		#print key
+		for value in data:
+			k = key + str(i) + gateway
+			#print value
+			#print value
+			print k
+			client.send(k + '|:|' +value)
+			#print k
+			i = i+1
+	client.close()
+
+#tcp_sensor()
+#tcp_pic()

+ 138 - 0
cron/mqtt/pub.py

@@ -0,0 +1,138 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:pub.py
+    author:rabin
+"""
+from demeter.mqtt import *
+from demeter.tcp import *
+import ConfigParser
+import random
+import time
+import base64
+
+"""
+pub = Pub()
+key = 'status/valve/10086/100107'
+value = 'ok'
+state = pub.push(key, value)
+"""
+pub = Pub()
+key = 'control/airdryer/10011/1001151'
+value = '0'
+state = pub.push(key, value)
+
+print state
+"""
+def callback(param, client, userdata, mid):
+	print mid
+
+pub = Pub()
+key = 'update/test/222/222'
+value = 2
+state = pub.push(key, value, 2, callback=callback, param='ttt')
+print state
+"""
+def push():
+	# 模拟传感器设备数据
+	gateway = 10086
+	def device(min):
+		max = min + 9
+		return str(random.randint(min, max))
+	def val(min, max):
+		return str(round(random.uniform(min, max), 2))
+
+	def switch():
+		return str(random.randint(0, 1))
+
+	hard = 'sensor'
+	pubType = (
+		{'hard':'sensor','type':'temprature','device':100000,'value':(-20, 30)}
+		,{'hard':'sensor','type':'humidity','device':100010,'value':(30, 80)}
+		,{'hard':'sensor','type':'light','device':100020,'value':(3000, 13000)}
+		,{'hard':'power','type':'power','device':100090,'value':(1, 50)}
+		,{'hard':'control','type':'valve','device':100100}
+		,{'hard':'control','type':'blower','device':100110}
+		,{'hard':'power','type':'power','device':10086,'value':(1, 50)}
+		)
+	pub = Pub()
+	while True:
+		config = Demeter.temp()
+		for v in pubType:
+			if v['device'] == gateway:
+				id = v['device']
+			else:
+				id = device(v['device'])
+			key = v['hard']+'/'+v['type']+'/'+str(gateway)+'/'+str(id)
+			if 'value' in v:
+				value = val(v['value'][0], v['value'][1])
+			else:
+				value = config[v['type']][id]
+			print 'key:' + key + ' value:' + value
+			pub.push(key, value)
+		time.sleep(1)
+
+def pic():
+	gateway = '10086'
+	pub = Pub()
+	key = 'pic/pic_'
+	gateway = '/' + gateway + '/200001'
+	with open('front/static/pc/images/376a00e6.tmp2.jpg', 'rb') as f:
+		data = f.readlines()
+		total = len(data)
+		key = key + str(total) + '_'
+		i = 0
+		print key
+		for value in data:
+			k = key + str(i) + gateway
+			pub.push(k, value)
+			print k
+			i = i+1
+
+#push()
+#pic()
+
+def tcp_sensor():
+	# 模拟设备数据
+	gateway = '10086'
+	def device():
+		return str(random.randint(100000, 100010))
+	def val():
+		return str(random.randint(1, 50))
+
+	hard = 'sensor'
+	pubType = ('temperature', 'humidity')
+	client = Client('0.0.0.0', 8000)
+	while True:
+		for v in pubType:
+			key = hard+'/'+v+'/'+gateway+'/'+device()
+			value = val()
+			print 'key:' + key + ' value:' + value
+			client.send(key+'|:|'+value)
+		time.sleep(1)
+
+def tcp_pic():
+	gateway = '10086'
+	client = Client('0.0.0.0', 8000)
+	key = 'pic/'
+	key = 'pic/pic_'
+	gateway = '/' + gateway + '/200001'
+	with open('admin/static/images/banner.png', 'rb') as f:
+		data = f.readlines()
+		total = len(data)
+		key = key + str(total) + '_'
+		i = 0
+		#print key
+		for value in data:
+			k = key + str(i) + gateway
+			#print value
+			#print value
+			print k
+			client.send(k + '|:|' +value)
+			#print k
+			i = i+1
+	client.close()
+
+#tcp_sensor()
+#tcp_pic()

+ 28 - 0
cron/mqtt/sub.py

@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:sub.py
+    author:rabin
+"""
+from demeter.mqtt import *
+import random
+Sub()
+
+"""
+data = {}
+data['type'] = 'temprature'
+data['gateway'] = '10086'
+data['device'] = '100010'
+data['hard'] = 'sensor'
+data['farm'] = 1
+data['source'] = str(random.randint(1, 50))
+data['value'] = str(random.randint(1, 50))
+
+model = Demeter.model('data', 'tsdb')
+#model.insert(data)
+
+data = model.select(data['farm'], data['device'], type=data['type'], hard=data['hard'], gateway=data['gateway'])
+
+print data
+"""

+ 14 - 0
cron/switch.py

@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:pub.py
+    author:rabin
+"""
+from service.device import *
+import sys
+
+id = sys.argv[1]
+value = sys.argv[2]
+device = Device()
+device.switch(id, value)

+ 51 - 17
install.py

@@ -30,29 +30,63 @@ def farm():
 
 def device():
 	# 以下类型只能新增,不能随意更改或删除
-	# 初始化设备类型
-	device_type = (
-		{'name':'温度', 'key':'temprature', 'unit':'℃'}
-		,{'name':'湿度', 'key':'humidity','unit':'%RH'}
-		,{'name':'光照', 'key':'light','unit':'LUX'}
-		,{'name':'二氧化碳', 'key':'co2','unit':'PPM'}
-		,{'name':'风速', 'key':'speed','unit':'km/h'}
-		,{'name':'风向', 'key':'direction','unit':''}
-		,{'name':'PM2.5', 'key':'pm2.5','unit':'μg/m3'}
-		,{'name':'电源', 'key':'power','unit':'V'}
-		,{'name':'阀门', 'key':'valve','unit':''}
-		,{'name':'放风机', 'key':'blower','unit':''}
-		,{'name':'卷帘机', 'key':'curtain','unit':''}
+
+	# 初始化默认服务
+	setting_server = (
+		{'name':'默认mqtt服务', 'server_type':1, 'server_host': '192.168.33.10', 'server_port':'8010'}
+		,{'name':'默认modbusTcp服务', 'server_type':2, 'server_host': '192.168.33.10', 'server_port':'8010'}
+		)
+	model = Demeter.model('setting_server')
+	for value in setting_server:
+		model.server_type = value['server_type']
+		model.server_host = value['server_host']
+		model.server_port = value['server_port']
+		info = model.select(type='fetchone')
+		if not info:
+			model.name = value['name']
+			model.server_type = value['server_type']
+			model.server_host = value['server_host']
+			model.server_port = value['server_port']
+			model.insert()
+
+	# 初始化默认产品
+	product = (
+		{'name':'默认产品', 'key':'product'},
+		)
+	model = Demeter.model('setting_product')
+	for value in product:
+		model.key = value['key']
+		info = model.select(type='fetchone')
+		if not info:
+			model.key = value['key']
+			model.name = value['name']
+			model.insert()
+
+	# 初始化设备,主要是初始化mqtt的默认设备
+	setting_device = (
+		{'name':'温度', 'key':'temprature', 'unit':'℃','oper_type':1}
+		,{'name':'湿度', 'key':'humidity','unit':'%RH','oper_type':1}
+		,{'name':'光照', 'key':'light','unit':'LUX','oper_type':1}
+		,{'name':'二氧化碳', 'key':'co2','unit':'PPM','oper_type':1}
+		,{'name':'风速', 'key':'speed','unit':'km/h','oper_type':1}
+		,{'name':'风向', 'key':'direction','unit':'','oper_type':1}
+		,{'name':'PM2.5', 'key':'pm2.5','unit':'μg/m3','oper_type':1}
+		,{'name':'电源', 'key':'power','unit':'V','oper_type':1}
+		,{'name':'阀门', 'key':'valve','unit':'','oper_type':2}
+		,{'name':'放风机', 'key':'blower','unit':'','oper_type':2}
+		,{'name':'卷帘机', 'key':'curtain','unit':'','oper_type':2}
 		)
-	model = Demeter.model('device_type')
-	for value in device_type:
+	model = Demeter.model('setting_device')
+	for value in setting_device:
 		model.key = value['key']
 		info = model.select(type='fetchone')
 		if not info:
 			model.key = value['key']
 			model.name = value['name']
-			#model.exp = '{n}'
+			model.exp = '{n}'
+			model.product_id = 1
 			model.unit = value['unit']
+			model.oper_type = value['oper_type']
 			model.insert()
 
 	# 初始化硬件类型 1/1/2/3/4/5/6
@@ -106,5 +140,5 @@ def device():
 
 manage()
 farm()
-#device()
+device()
 Demeter.echo('install success!')

+ 16 - 0
modbus.py

@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:admin.py
+    author:rabin
+"""
+from demeter.core import *
+
+param = {}
+param['method'] = 'm'
+Demeter.getopt(param)
+
+Demeter.echo(Demeter.option['method'])
+
+if Demeter.option['method'] == 'client':
+	Demeter.service('tcp', 'modbus').client()

+ 23 - 0
model/device_gateway.py

@@ -0,0 +1,23 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:device_gateway.py
+    author:rabin
+"""
+from .__load__ import *
+
+class Device_gateway(Model):
+	__table__ = 'device_gateway'
+	__comment__ = '设备网关管理'
+	id = Fields(type='uuid', primaryKey=True, comment='网关ID', uuid='farm_id')
+	farm_id = Fields(type='int', default='setting.farm', comment='园区ID', match='not')
+	name = Fields(type='varchar(50)', comment='网关名')
+	hardware_id = Fields(type='bigint', comment='硬件id', match='number|硬件id必须是数字')
+	product_id = Fields(type='int', comment='产品id')
+	server_id = Fields(type='int', comment='服务id')
+	pic = Fields(type='varchar(255)', comment='设备分布图纸')
+	camera = Fields(type='varchar(500)', comment='摄像头实时流地址')
+	stat = Fields(type='boolean', default='False', comment='是否显示趋势图')
+	state = Fields(type='boolean', default='True', comment='数据存在状态')
+	cdate = Fields(type='int', default='time', comment='创建时间')

+ 6 - 2
model/device_info.py

@@ -1,3 +1,4 @@
+#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 """
     demeter database
@@ -12,9 +13,12 @@ class Device_info(Model):
 	id = Fields(type='uuid', primaryKey=True, comment='设备ID', uuid='farm_id')
 	farm_id = Fields(type='int', default='setting.farm', comment='园区ID', match='not')
 	name = Fields(type='varchar(50)', comment='设备名')
-	device_id = Fields(type='int', comment='设备id', match='number|设备id必须是数字')
-	server_id = Fields(type='int', comment='服务id', match='number|服务id必须是数字')
+	hardware_id = Fields(type='bigint', comment='硬件id', match='number|硬件id必须是数字')
+	hardware_type = Fields(type='int', comment='硬件类型')
+	gateway_id = Fields(type='uuid', comment='网关id')
+	type_id = Fields(type='int', comment='设备类型,从旧版本过度,不做任何修改,直接关联setting_device里的id')
 	value = Fields(type='varchar(1000)', comment='设备传过来的值')
+	exp = Fields(type='varchar(500)', comment='表达式')
 	max = Fields(type='float', comment='最大上限', match='numberFloat|最大上限必须是数字')
 	min = Fields(type='float', comment='最小下限', match='numberFloat|最小下限必须是数字')
 	cxnum = Fields(type='int', comment='超限次数')

+ 19 - 0
model/hardware.py

@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:hardware.py
+    author:rabin
+"""
+from .__load__ import *
+
+class Hardware(Model):
+	__table__ = 'hardware'
+	__comment__ = '硬件设备表'
+	id = Fields(type='uuid', primaryKey=True, comment='硬件设备表ID', uuid='farm_id')
+	farm_id = Fields(type='int', default='setting.farm', comment='园区ID', match='not')
+	hardware_id = Fields(type='bigint', comment='硬件id', unique=True)
+	hardware_type = Fields(type='int', comment='硬件类型')
+	device_id = Fields(type='uuid', comment='设备id')
+	gateway_id = Fields(type='uuid', comment='网关id')
+	state = Fields(type='boolean', default='True', comment='数据存在状态')
+	cdate = Fields(type='int', default='time', comment='创建时间')

+ 16 - 0
model/hardware_type.py

@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:hardware_type.py
+    author:rabin
+"""
+from .__load__ import *
+
+class Hardware_type(Model):
+	__table__ = 'hardware_type'
+	__comment__ = '硬件类型'
+	id = Fields(type='int', primaryKey=True, autoIncrement=True, comment='硬件类型ID')
+	name = Fields(type='varchar(50)', comment='硬件类型名')
+	key = Fields(type='varchar(50)', comment='硬件类型标识', unique=True)
+	state = Fields(type='boolean', default='True', comment='数据存在状态')
+	cdate = Fields(type='int', default='time', comment='创建时间')

+ 0 - 17
model/modbus_device_group.py

@@ -1,17 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-    demeter database
-    name:hardware.py
-    author:rabin
-"""
-from .__load__ import *
-
-class Modbus_device_group(Model):
-	__table__ = 'modbus_device_group'
-	__comment__ = 'modbus设备分组表'
-	id = Fields(type='int', primaryKey=True, autoIncrement=True, comment='设备组id')
-	farm_id = Fields(type='int', default='setting.farm', comment='园区ID', match='not')
-	name = Fields(type='varchar(50)', comment='分组名称')
-	key = Fields(type='varchar(50)', comment='分组标识')
-	state = Fields(type='boolean', default='True', comment='数据存在状态')
-	cdate = Fields(type='int', default='time', comment='创建时间')

+ 12 - 12
model/modbus_device.py → model/setting_device.py

@@ -6,21 +6,21 @@
 """
 from .__load__ import *
 
-class Modbus_device(Model):
-	__table__ = 'modbus_device'
-	__comment__ = 'modbus设备表'
+class Setting_device(Model):
+	__table__ = 'setting_device'
+	__comment__ = '设备表-对应旧版本设备类型表'
 	id = Fields(type='int', primaryKey=True, autoIncrement=True, comment='设备id')
-	farm_id = Fields(type='int', default='setting.farm', comment='园区ID', match='not')
 	name = Fields(type='varchar(50)', comment='设备名称')
-	group_id = Fields(type='int', comment='分组id')
-	slave_id = Fields(type='int', comment='从机id', unique=True)
-	slave_type = Fields(type='int', comment='1读取2写入')
-	register_type = Fields(type='int', comment='寄存器类型')
-	register_address = Fields(type='varchar(100)', comment='寄存器地址')
-	register_length = Fields(type='varchar(50)', comment='寄存器长度')
-	data_type = Fields(type='int', comment='数据类型')
-	data_option = Fields(type='text', comment='数据类型选项')
+	key = Fields(type='varchar(50)', comment='设备标识')
+	product_id = Fields(type='int', comment='产品id')
 	exp = Fields(type='varchar(100)', comment='计算公式')
 	unit = Fields(type='varchar(10)', comment='单位')
+	oper_type = Fields(type='int', comment='1读取2写入')
+	data_type = Fields(type='int', comment='数据类型')
+	data_option = Fields(type='text', comment='数据类型选项')
+	modbus_slave_id = Fields(type='int', comment='从机id', unique=True)
+	modbus_register_type = Fields(type='int', comment='寄存器类型')
+	modbus_register_address = Fields(type='varchar(100)', comment='寄存器地址')
+	modbus_register_length = Fields(type='varchar(50)', comment='寄存器长度')
 	state = Fields(type='boolean', default='True', comment='数据存在状态')
 	cdate = Fields(type='int', default='time', comment='创建时间')

+ 17 - 0
model/setting_product.py

@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:hardware.py
+    author:rabin
+"""
+from .__load__ import *
+
+class Setting_product(Model):
+	__table__ = 'setting_product'
+	__comment__ = '产品表-对应旧版本硬件类型表'
+	id = Fields(type='int', primaryKey=True, autoIncrement=True, comment='产品ID')
+	name = Fields(type='varchar(50)', comment='产品名称')
+	key = Fields(type='varchar(50)', comment='产品标识')
+	agreement = Fields(type='int', comment='接入协议1mqtt2modbus---废弃')
+	state = Fields(type='boolean', default='True', comment='数据存在状态')
+	cdate = Fields(type='int', default='time', comment='创建时间')

+ 4 - 5
model/modbus_server.py → model/setting_server.py

@@ -6,13 +6,12 @@
 """
 from .__load__ import *
 
-class Modbus_server(Model):
-	__table__ = 'modbus_server'
-	__comment__ = 'modbus服务配置表'
+class Setting_server(Model):
+	__table__ = 'setting_server'
+	__comment__ = '服务配置表'
 	id = Fields(type='int', primaryKey=True, autoIncrement=True, comment='服务id')
-	farm_id = Fields(type='int', default='setting.farm', comment='园区ID', match='not')
 	name = Fields(type='varchar(50)', comment='服务名称')
-	server_type = Fields(type='int', comment='服务协议类型1tcp2rtu')
+	server_type = Fields(type='int', comment='服务协议类型1mqtt2modbus_tcp3modbus_rtu')
 	server_host = Fields(type='varchar(50)', comment='服务地址')
 	server_port = Fields(type='varchar(50)', comment='服务端口')
 	state = Fields(type='boolean', default='True', comment='数据存在状态')

+ 9 - 0
mqtt.py

@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:admin.py
+    author:rabin
+"""
+from demeter.core import *
+
+Demeter.service('tcp', 'modbus').client()

+ 1 - 0
runtime/postgresql/device_gateway

@@ -0,0 +1 @@
+[["cdate", 1], ["id", 1], ["state", 1], ["server_id", 1], ["name", 1], ["camera", 1], ["product_id", 1], ["hardware_id", 1], ["pic", 1], ["stat", 1], ["farm_id", 1]]

+ 1 - 1
runtime/postgresql/device_info

@@ -1 +1 @@
-[["min", 1], ["value", 1], ["cxdate", 1], ["max", 1], ["device_id", 1], ["state", 1], ["operdate", 1], ["id", 1], ["cdate", 1], ["server_id", 1], ["farm_id", 1], ["cxtype", 1], ["cxnum", 1], ["status", 1], ["name", 1], ["oper", 1], ["inorder", 1], ["udate", 1]]
+[["cxtype", 1], ["state", 1], ["min", 1], ["type_id", 1], ["cxnum", 1], ["oper", 1], ["name", 1], ["inorder", 1], ["udate", 1], ["gateway_id", 1], ["max", 1], ["id", 1], ["operdate", 1], ["farm_id", 1], ["hardware_type", 1], ["cxdate", 1], ["exp", 1], ["value", 1], ["cdate", 1], ["hardware_id", 1], ["status", 1]]

+ 1 - 1
runtime/postgresql/farm

@@ -1 +1 @@
-[["cdate", 1], ["master_name", 1], ["tel", 1], ["welcome", 1], ["gateway", 1], ["id", 1], ["address", 1], ["info", 1], ["location", 1], ["state", 1], ["pic", 1], ["master_pic", 1], ["name", 1]]
+[["name", 1], ["cdate", 1], ["welcome", 1], ["state", 1], ["pic", 1], ["info", 1], ["master_name", 1], ["location", 1], ["id", 1], ["gateway", 1], ["tel", 1], ["address", 1], ["master_pic", 1]]

+ 1 - 0
runtime/postgresql/farm_work

@@ -0,0 +1 @@
+[["state", 1], ["amount", 1], ["id", 1], ["land_id", 1], ["category_id", 1], ["method_id", 1], ["cdate", 1], ["farm_id", 1], ["pic", 1], ["workdate", 1]]

+ 1 - 0
runtime/postgresql/farm_work_category

@@ -0,0 +1 @@
+[["state", 1], ["id", 1], ["cdate", 1], ["farm_id", 1], ["name", 1]]

+ 1 - 0
runtime/postgresql/farm_work_land

@@ -0,0 +1 @@
+[["state", 1], ["id", 1], ["cdate", 1], ["farm_id", 1], ["name", 1]]

+ 1 - 0
runtime/postgresql/hardware_type

@@ -0,0 +1 @@
+[["name", 1], ["cdate", 1], ["id", 1], ["state", 1], ["key", 1]]

+ 1 - 1
runtime/postgresql/manage_admin

@@ -1 +1 @@
-[["username", 1], ["cdate", 1], ["id", 1], ["password", 1], ["role_id", 1], ["state", 1], ["mobile", 1]]
+[["username", 1], ["state", 1], ["mobile", 1], ["role_id", 1], ["cdate", 1], ["password", 1], ["id", 1]]

+ 1 - 0
runtime/postgresql/manage_log

@@ -0,0 +1 @@
+[["cdate", 1], ["id", 1], ["state", 1], ["data", 1], ["model", 1], ["method", 1], ["admin_id", 1]]

+ 1 - 1
runtime/postgresql/manage_role

@@ -1 +1 @@
-[["state", 1], ["cdate", 1], ["id", 1], ["top", 1], ["auth", 1], ["oper", 1], ["name", 1]]
+[["name", 1], ["top", 1], ["state", 1], ["oper", 1], ["auth", 1], ["cdate", 1], ["id", 1]]

+ 0 - 1
runtime/postgresql/modbus_device

@@ -1 +0,0 @@
-[["slave_type", 1], ["slave_id", 1], ["data_option", 1], ["farm_id", 1], ["register_type", 1], ["name", 1], ["unit", 1], ["group_id", 1], ["exp", 1], ["state", 1], ["id", 1], ["cdate", 1], ["register_length", 1], ["data_type", 1], ["register_address", 1]]

+ 0 - 1
runtime/postgresql/modbus_device_group

@@ -1 +0,0 @@
-[["farm_id", 1], ["state", 1], ["cdate", 1], ["id", 1], ["key", 1], ["name", 1]]

+ 0 - 1
runtime/postgresql/modbus_server

@@ -1 +0,0 @@
-[["farm_id", 1], ["state", 1], ["cdate", 1], ["id", 1], ["server_host", 1], ["server_type", 1], ["name", 1], ["server_port", 1]]

+ 1 - 0
runtime/postgresql/msg_type

@@ -0,0 +1 @@
+[["name", 1], ["push", 1], ["state", 1], ["key", 1], ["cdate", 1], ["id", 1]]

+ 1 - 0
runtime/postgresql/notice_type

@@ -0,0 +1 @@
+[["name", 1], ["cdate", 1], ["id", 1], ["state", 1], ["key", 1]]

+ 1 - 0
runtime/postgresql/setting_device

@@ -0,0 +1 @@
+[["name", 1], ["modbus_register_length", 1], ["modbus_register_address", 1], ["state", 1], ["modbus_slave_id", 1], ["unit", 1], ["product_id", 1], ["key", 1], ["oper_type", 1], ["exp", 1], ["data_type", 1], ["data_option", 1], ["cdate", 1], ["id", 1], ["modbus_register_type", 1]]

+ 1 - 0
runtime/postgresql/setting_product

@@ -0,0 +1 @@
+[["state", 1], ["id", 1], ["agreement", 1], ["cdate", 1], ["key", 1], ["name", 1]]

+ 1 - 0
runtime/postgresql/setting_server

@@ -0,0 +1 @@
+[["id", 1], ["server_type", 1], ["cdate", 1], ["name", 1], ["server_host", 1], ["server_port", 1], ["state", 1]]

+ 433 - 0
service/device.py

@@ -0,0 +1,433 @@
+# -*- 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}, '网关状态', farm_id, hardware_id, 5, gateway_id, 0, '2')
+
+			'''
+			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:
+				device = Demeter.service('common').list('setting_device', search={'product_id':gateway['product_id']})
+				if device:
+					for v in device:
+						if v['modbus_slave_id']:
+							hardware_type = Demeter.service('core', 'setting').hardware_type(v['oper_type'])
+							self.add({'type_id':v['id']}, v['name'], farm_id, v['id'], hardware_type, gateway_id, v['id'], '')
+	# 添加设备
+	def add(self, where, name, farm_id, hardware_id, hardware_type, gateway_id, type_id, value):
+		info = Demeter.service('common').list('device_info', search=where)
+		if not info:
+			insert = {}
+			insert['farm_id'] = farm_id
+			insert['name'] = name
+			insert['hardware_id'] = hardware_id
+			insert['gateway_id'] = gateway_id
+			insert['hardware_type'] = hardware_type
+			insert['value'] = value
+			insert['type_id'] = type_id
+			insert['status'] = False
+			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('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'])
+					# 这里要向服务器发送pub请求了,暂时使用临时文件代替
+					#Demeter.temp(key=type_info['key'], name=info['hardware_id'], value=switch)
+					#pub
+					pub = Pub()
+					key = type_info['key'] + '/' + gateway_info['hardware_id']  + '/' + info['hardware_id']
+					update = 'update/' + key
+					feedback = 'status/' + key
+					value = switch
+					#pub.push(update, value, qos=0, callback=self.switchAction, param={'info':info, 'key':feedback, 'switch':switch}, feedback=True)
+					pub.push(update, value)
+
+					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('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)
+				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):
+		# 更新网关状态
+		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 > 0:
+			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():
+		pass
+		#from demeter.mqtt import *
+		pub = Pub()
+		pub.push(update, value)

+ 0 - 209
service/mqtt/device.py

@@ -1,209 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-    demeter service
-    name:device.py 处理设备
-    author:rabin
-"""
-from demeter.core import *
-from demeter.mqtt import *
-class Device(object):
-	type_info = []
-	# 新增网关时,增加状态和电源
-	def upGatewayStatus(self, farm_id, gateway_id, hardware_id):
-		if hardware_id and gateway_id > 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)
-				"""
-			
-	# 批量处理开关
-	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('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'])
-					# 这里要向服务器发送pub请求了,暂时使用临时文件代替
-					#Demeter.temp(key=type_info['key'], name=info['hardware_id'], value=switch)
-					#pub
-					pub = Pub()
-					key = type_info['key'] + '/' + gateway_info['hardware_id']  + '/' + info['hardware_id']
-					update = 'update/' + key
-					feedback = 'status/' + key
-					value = switch
-					#pub.push(update, value, qos=0, callback=self.switchAction, param={'info':info, 'key':feedback, 'switch':switch}, feedback=True)
-					pub.push(update, value)
-
-					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('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())

+ 1 - 186
service/mqtt/record.py

@@ -35,189 +35,4 @@ class Record(object):
 			cls().handle(self, config, value)
 
 	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)
-				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):
-		# 更新网关状态
-		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 > 0:
-			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()
+		Demeter.service('device').save(config,value, name, device_type)

+ 0 - 1
service/device/__init__.py → service/setting/__init__.py

@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 """
     demeter init

+ 18 - 2
service/modbus/core.py → service/setting/core.py

@@ -3,6 +3,11 @@ from demeter.core import *
 
 class Core(object):
 
+    def agreement(self):
+        return [
+        {'id':1,'name':'mqtt'}
+        ,{'id':2,'name':'modbus'}]
+
     def register_type(self):
         return [
         {'id':1,'name':'线圈寄存器'}
@@ -10,7 +15,7 @@ class Core(object):
         ,{'id':3,'name':'保持寄存器'}
         ,{'id':4,'name':'输入寄存器'}]
 
-    def slave_type(self):
+    def oper_type(self):
         return [{'id':1,'name':'读取'},{'id':2,'name':'写入'},{'id':3,'name':'拍照'},{'id':4,'name':'摄像'}]
 
     def data_type(self):
@@ -22,4 +27,15 @@ class Core(object):
 
 
     def server_type(self):
-        [{'id':1,'name':'tcp'},{'id':2,'name':'rtu'}]
+        return [{'id':1,'name':'mqtt'},{'id':2,'name':'modbus_tcp'},{'id':3,'name':'modbus_rtu'}]
+
+    # 根据oper_type判断是传感器还是控制器
+    def hardware_type(self, oper_type):
+        if oper_type == 1:
+            return 2
+        elif oper_type == 2:
+            return 3
+        elif oper_type == 3:
+            return 6
+        elif oper_type == 4:
+            return 7

+ 0 - 1
service/zeus/__init__.py

@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 """
     demeter init