rabin 7 years ago
parent
commit
761480c264

+ 56 - 34
admin/page/device.py

@@ -223,9 +223,9 @@ class info_path(Load):
 			,height = '300'
 			,add = False
 			#,edit = False
-			,search = (('farm_id-select-','type_id-select-', 'gateway_id-select-', 'hardware_type-select-'), (u'选择农场',u'设备名称',u'设备类型',u'网关',u'硬件类型'))
-			,thead = (u'所属农场', u'设备名称', u'设备id', u'连接状态', u'值', u'设备类型', u'网关',u'硬件类型')
-			,tbody = ('farm','name', 'hardware_id', 'status', 'show_num', 'type', 'gateway', 'hardware_type')
+			,search = (('farm_id-select-','type_id-select-', 'gateway_id-select-', 'hardware_type-select-'), (u'选择农场',u'设备类型',u'网关',u'硬件类型'))
+			,thead = (u'所属农场', u'设备名称', u'设备id', u'连接状态', u'值', u'设备类型', u'网关',u'硬件类型')
+			,tbody = ('farm','name', 'hardware_id', 'status', 'show', 'type', 'gateway', 'hardware_type')
 			,state = False
 		)
 		self.data['common']['search_farm_id-select-'] = Demeter.config['setting']['farmList']
@@ -238,20 +238,26 @@ class info_path(Load):
 			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']
-				info = self.service('common').one('device_type', id=value['type_id'])
-				self.data['list'][key]['type'] = info['name']
+				self.data['list'][key]['type'] = '无'
+				if value['type_id']:
+					info = self.service('common').one('device_type', id=value['type_id'])
+					if info:
+						self.data['list'][key]['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:
 					self.data['list'][key]['status'] = '断开'
-
-				if value['show_num']:
+				if value['num'] and value['show']:
+					value['show'] = str(value['show'])
 					# 根据设备类型type_id得到单位和计算公式
-					self.data['list'][key]['show_num'] = '<a href="/device/stat?id='+value['id']+'">' + value['show_num'] + '</a><br />更新时间:' + Demeter.date(value['cdate'])
+					self.data['list'][key]['show'] = '<a href="/device/stat?id='+value['id']+'&search_date-select-=1&method=list">'+value['show'] + '</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 value['show']:
+					self.data['list'][key]['show'] = '<a href="/device/pic?id='+value['id']+'"><img src="'+value['show']+'" width="200px"/></a><br />更新时间:' + Demeter.date(value['cdate'])
 				else:
-					self.data['list'][key]['show_num'] = '0'
+					self.data['list'][key]['show'] = ''
+
 				hardware_type = self.service('common').one('hardware_type', id=value['hardware_type'])
 				self.data['list'][key]['hardware_type'] = hardware_type['name']
 
@@ -278,41 +284,57 @@ class info_update_path(Load):
 	def delete(self):
 		self.commonDelete('device_info')
 
-class stat_path(Load):
+class pic_path(Load):
 	@Web.auth
 	def get(self):
 		self.common(
-			name = u'设备统计'
-			,path = 'stat'
+			name = u'摄像头图片'
+			,path = 'pic'
 			,width = '600'
 			,height = '300'
-			,add = False
-			,edit = False
-			,search = (('label-1','cdate-time-start','cdate-time-end', 'date-select-'), (u'日期范围',u'开始时间',u'截止时间',u'周期选择'))
+			#,add = False
+			#,edit = False
+			,search = (('label-1','cdate-time-start','cdate-time-end'), (u'日期范围',u'开始时间',u'截止时间'))
+			,thead = (u'图片地址', u'更新时间')
+			,tbody = ('pic', 'cdate')
 			,state = False
 		)
-		self.data['common']['search_date-select-'] = [{'id':'1d', 'name':'一天'},{'id':'7d', 'name':'一周'},{'id':'1m', 'name':'一个月'},{'id':'6m', 'name':'半年'}]
+
+		self.commonList('device_pic')
+		if self.data['list']:
+			for key, value in enumerate(self.data['list']):
+				self.data['list'][key]['pic'] = '<img src="'+value['pic']+'" width="200px" />'
+		self.commonView('list')
+
+class stat_path(Load):
+	@Web.auth
+	def get(self):
+		method = self.input('method', 'avg')
 		id = self.input('id')
+		self.common(
+			name = u'设备统计'
+			,path = 'stat'
+			,search = (('label-1','cdate-time-start','cdate-time-end', 'date-select-'), (u'日期范围',u'开始时间',u'截止时间',u'周期选择'))
+		)
 		data = self.service('common').one('device_info', id=id)
-		model = Demeter.model('data', 'tsdb')
-		search = []
-		if 'date-select-' in self.data['search'] and self.data['search']['date-select-']:
-			value = self.data['search']['date-select-']
-			if value == '1d':
-				search.append('group by time(30m) where time > now() – 1d')
-			elif value == '7d':
-				search.append('group by time(300m) where time > now() – 7d')
-			elif value == '1m':
-				search.append('group by time(1d) where time > now() – 1m')
-			elif value == '6m':
-				search.append('group by time(10d) where time > now() – 6m')
-		search = "".join(search)
-		self.data['list'] = model.get(data['farm_id'], data['hardware_id'], search=search)
-		#print self.data['list']
-		if self.data['list']:
-			self.data['category'] = json.dumps(self.data['list'][0])
-			self.data['value'] = json.dumps(self.data['list'][1])
+		typeInfo = self.service('common').one('device_type', id=data['type_id'])
+		farm = self.service('common').one('farm', id=data['farm_id'])
 		self.data['info'] = data
+		self.data['type'] = typeInfo
+		self.data['farm'] = farm
+		self.data['method'] = method
+
+		model = Demeter.model('data', 'tsdb')
+		self.data['common']['search_date-select-'] = model.dateConfig()
+		search = {}
+		if 'cdate-time-start' in self.data['search']:
+			search['start'] = self.data['search']['cdate-time-start']
+		if 'cdate-time-end' in self.data['search']:
+			search['end'] = self.data['search']['cdate-time-end']
+		if 'date-select-' in self.data['search']:
+			search['group'] = self.data['search']['date-select-']
+		self.data['list'] = model.getData(method, search, data)
+
 		self.commonView('stat')
 
 

+ 31 - 7
admin/templates/common/stat.html

@@ -42,13 +42,14 @@ var myChart = echarts.init(document.getElementById('main'));
 // 指定图表的配置项和数据
 var option = {
     title: {
-        text: '{{data['info']['name']}}'
+        text: '{{data['info']['name']}}',
+        subtext: '数据来自{{data['farm']['name']}}'
     },
     tooltip: {
         trigger: 'axis'
     },
     legend: {
-        data:['{{data['info']['name']}}']
+        data:[{% for key,value in enumerate(data['list']) %}{% if key > 0 %},{% end %}'{{value['name']}}'{% end %}]
     },
     grid: {
         left: '3%',
@@ -57,25 +58,48 @@ var option = {
         containLabel: true
     },
     toolbox: {
+        show: true,
         feature: {
+            dataZoom: {
+                yAxisIndex: 'none'
+            },
+            dataView: {readOnly: false},
+            magicType: {type: ['line', 'bar']},
+            restore: {},
             saveAsImage: {}
         }
     },
     xAxis: {
         type: 'category',
         boundaryGap: false,
-        data: {% raw data['category'] %}
+        data: {% for key,value in enumerate(data['list']) %}{% if key == 0 %}{% raw value['data']['time'] %}{% end %}{% end %}
     },
     yAxis: {
-        type: 'value'
+        type: 'value',
+        axisLabel: {
+            formatter: '{value} {{data['type']['unit']}}'
+        }
     },
     series: [
+        {% for key,value in enumerate(data['list']) %}
+        {% if key > 0 %},{% end %}
         {
-            name:'{{data['info']['name']}}',
+            name:'{{value['name']}}',
             type:'line',
-            stack: '总量',
-            data:{% raw data['value'] %}
+            data:{% raw value['data']['value'] %},
+            markPoint: {
+                data: [
+                    {type: 'max', name: '最大值'},
+                    {type: 'min', name: '最小值'}
+                ]
+            },
+            markLine: {
+                data: [
+                    {type: 'average', name: '平均值'}
+                ]
+            }
         }
+        {% end %}
     ]
 };
 

+ 6 - 1
admin/templates/theme/list.html

@@ -127,7 +127,12 @@ $ = layui.jquery;//jquery
 lement = layui.element();//面包导航
 laypage = layui.laypage;//分页
 layer = layui.layer;//弹出层
-
+layer.ready(function(){ //为了layer.ext.js加载完毕再执行
+  layer.photos({
+    photos: '#tbody'
+    //,shift: 5 //0-6的选择,指定弹出图片动画类型,默认随机
+  });
+}); 
 if ($('.load').length) {
     $('.load').each(function()
     {

+ 5 - 3
admin/templates/theme/stat.html

@@ -17,7 +17,9 @@
             <a class="layui-btn layui-btn-small" style="margin-top:3px;float:right"  href="javascript:window.history.back();" title="返回"><i class="layui-icon">&#xe619;</i></a>
         </div>
         <div class="x-body">
-            <form class="layui-form x-center" action="" style="width:auto">
+            <form class="layui-form x-center" action="{{data['common']['path']}}" style="width:auto">
+            <input type="hidden" name="id" id="id" value="{% if data['info'] and 'id' in data['info'] and data['info']['id'] > 0 %}{{data['info']['id']}}{% end %}" />
+            <input type="hidden" name="method" id="method" value="{% if 'method' in data and data['method'] %}{{data['method']}}{% end %}" />
                 <div class="layui-form-pane" style="margin-top: 15px;">
                   <div class="layui-form-item">
                    {% block search %}
@@ -60,7 +62,7 @@ if ($('.time').length) {
     laydate = layui.laydate;//日期插件
     var start = {
         //min: laydate.now()
-        max: '2099-06-16 23:59:59'
+        max: laydate.now()
         ,format: 'YYYY-MM-DD hh:mm:ss'
         ,istoday: true
         ,istime: true
@@ -72,7 +74,7 @@ if ($('.time').length) {
 
     var end = {
         //min: laydate.now()
-        max: '2099-06-16 23:59:59'
+        max: laydate.now()
         ,format: 'YYYY-MM-DD hh:mm:ss'
         ,istoday: true
         ,istime: true

+ 11 - 1
conf/env.conf

@@ -24,6 +24,7 @@ password			= public
 timeout				= 60
 ;topic定义
 topic				= method/type/gateway/device
+sub					= pic,sensor
 
 [postgresql]
 host				= iot-pgsql
@@ -52,4 +53,13 @@ max_buffer_size		= 210763776
 ;子进程
 process				= 0
 ;top菜单的数据来源
-top 				= farm
+top 				= farm
+
+;前台配置
+[front]
+port				= 8088
+debug				= True
+;请求的buffersize
+max_buffer_size		= 210763776
+;子进程
+process				= 0

File diff suppressed because it is too large
+ 45 - 0
front/api/device.py


+ 39 - 1
front/api/farm.py

@@ -79,4 +79,42 @@ class index_path(Load):
 			self.out(u'请输入联系电话')
 			return
 		state = self.service('common').update('farm', id, update)
-		self.out('yes', {'id':state})
+		self.out('yes', {'id':state})
+
+class msg_path(Load):
+	"""
+	@api {get} /farm/msg 获取消息通知
+	@apiVersion 1.0.0
+	@apiName getMsg
+	@apiGroup Farm
+
+	@apiParam {String} page 页数
+
+	@apiSuccess {Object[]} setting 基本信息
+	@apiSuccess {String}   setting.name  站点名
+	@apiSuccess {Number}   setting.farm  当前的农场ID
+
+	@apiSuccess {Object[]} list 消息列表
+	@apiSuccess {Number}   list.id	消息ID
+	@apiSuccess {String}   list.content  消息内容
+	@apiSuccess {String}   list.cdates	消息时间
+	@apiSuccess {String}   list.cdate	消息时间戳
+
+	@apiSuccess {Object[]} page 分页信息
+	@apiSuccess {String}   page.current  当前页
+	@apiSuccess {String}   page.total	总页数
+	@apiSuccess {String}   page.num	每页数据条数
+	@apiSuccess {String}   page.totalNum	总数据条数
+
+	@apiErrorExample 操作成功
+	{"status": 1, "msg": "yes", "code": 0, "data": {"setting": {"farm": 1, "user": 0, "name": "\u519c\u5c0f\u76d2", "copyright": "2017 nongxiaohe.com v1.0.0", "site": "http://www.nongxiaohe.com/"}, "list": []}}
+	@apiErrorExample 操作失败
+	{"status": 2, "msg": "\u64cd\u4f5c\u5931\u8d25", "code": 0, "data": {}}
+	"""
+	@auth
+	def get(self):
+		self.data['list'] = self.service('common').list('msg', state=True, page=True)
+		for key, value in enumerate(self.data['list']):
+			self.data['list'][key]['cdates'] = Demeter.date(value['cdate'])
+
+		self.out('yes', self.data)

+ 1 - 1
front/api/main.py

@@ -21,7 +21,7 @@ class index_path(Load):
 	@apiSuccess {Object[]} farm 农场基本信息
 	@apiSuccess {String}   farm.name  农场名
 
-	@apiSuccess {Object[]} gateway 网关信息
+	@apiSuccess {Object[]} gateway 网关信息(环境监测)
 	@apiSuccess {String}   gateway.name  网关名称
 	@apiSuccess {String}   gateway.id    网关ID
 	@apiErrorExample 操作成功

+ 12 - 0
front/api/origin.py

@@ -14,6 +14,8 @@ class index_path(Load):
 	@apiName getOrigin
 	@apiGroup Farm
 
+	@apiParam {String} page 页数
+
 	@apiSuccess {Object[]} setting 基本信息
 	@apiSuccess {String}   setting.name  站点名
 	@apiSuccess {Number}   setting.farm  当前的农场ID
@@ -21,6 +23,13 @@ class index_path(Load):
 	@apiSuccess {Object[]} list 溯源批次列表信息
 	@apiSuccess {String}   list.name  名称
 	@apiSuccess {String}   list.id	ID
+
+	@apiSuccess {Object[]} page 分页信息
+	@apiSuccess {String}   page.current  当前页
+	@apiSuccess {String}   page.total	总页数
+	@apiSuccess {String}   page.num	每页数据条数
+	@apiSuccess {String}   page.totalNum	总数据条数
+	
 	@apiErrorExample 操作成功
 	{"status": 1, "msg": "yes", "code": 0, "data": {"setting": {"farm": 1, "user": 0, "name": "\u519c\u5c0f\u76d2", "copyright": "2017 nongxiaohe.com v1.0.0", "site": "http://www.nongxiaohe.com/"}, "list": [{"pic": "http://192.168.15.10:8087/upload/2017/08/30/455f9d6c26b5c989b32eda1809e58d5f.jpg", "method_id": null, "land_id": "249be20d-5759-5af0-9859-b770d9f44e2a", "farm_id": 1, "state": true, "amount": "100ml", "workdate": 1504105397, "category_id": "9365ea66-be55-56f7-a511-059fc85a9478", "cdate": 1504076614, "id": "19e05f00-ae55-5605-be12-86dcd2866df9"}], "page": {"current": 1, "ajax": false, "total": 1.0, "num": 15, "totalNum": 1}}}
 	@apiErrorExample 操作失败
@@ -65,6 +74,9 @@ class index_path(Load):
 	@auth
 	def post(self):
 		id = self.input('id', None)
+		if not id:
+			self.out('no')
+			return
 		update = {}
 		update['pic'] = self.input('update_pic')
 		update['gateway_id'] = self.input('update_device_id')

+ 12 - 0
front/api/work.py

@@ -14,6 +14,8 @@ class index_path(Load):
 	@apiName getWorkList
 	@apiGroup Farm
 
+	@apiParam {String} page 页数
+
 	@apiSuccess {Object[]} setting 基本信息
 	@apiSuccess {String}   setting.name  站点名
 	@apiSuccess {Number}   setting.farm  当前的农场ID
@@ -21,6 +23,13 @@ class index_path(Load):
 	@apiSuccess {Object[]} list 农事列表信息
 	@apiSuccess {String}   list.name  名称
 	@apiSuccess {String}   list.id	ID
+
+	@apiSuccess {Object[]} page 分页信息
+	@apiSuccess {String}   page.current  当前页
+	@apiSuccess {String}   page.total	总页数
+	@apiSuccess {String}   page.num	每页数据条数
+	@apiSuccess {String}   page.totalNum	总数据条数
+
 	@apiErrorExample 操作成功
 	{"status": 1, "msg": "yes", "code": 0, "data": {"setting": {"farm": 1, "user": 0, "name": "\u519c\u5c0f\u76d2", "copyright": "2017 nongxiaohe.com v1.0.0", "site": "http://www.nongxiaohe.com/"}, "list": [{"pic": "http://192.168.15.10:8087/upload/2017/08/30/455f9d6c26b5c989b32eda1809e58d5f.jpg", "method_id": null, "land_id": "249be20d-5759-5af0-9859-b770d9f44e2a", "farm_id": 1, "state": true, "amount": "100ml", "workdate": 1504105397, "category_id": "9365ea66-be55-56f7-a511-059fc85a9478", "cdate": 1504076614, "id": "19e05f00-ae55-5605-be12-86dcd2866df9"}], "page": {"current": 1, "ajax": false, "total": 1.0, "num": 15, "totalNum": 1}}}
 	@apiErrorExample 操作失败
@@ -65,6 +74,9 @@ class index_path(Load):
 	@auth
 	def post(self):
 		id = self.input('id', None)
+		if not id:
+			self.out('no')
+			return
 		update = {}
 		update['pic'] = self.input('update_pic')
 		update['category'] = self.input('update_category')

+ 85 - 32
model/data.py

@@ -37,46 +37,99 @@ class Data(Model):
 		}]
 		return json
 
-	def select(self, farm, device, type=None, hard=None, gateway=None, value=None, search=None):
+	def get(self, farm, device, col='value', search=''):
 		data = {}
 		data['farm'] = farm
 		data['device'] = device
 		self.setTable(data)
-		where = []
-		if type:
-			where.append('type = \'' + type + '\'')
-		if hard:
-			where.append('hard = \'' + hard + '\'')
-		if gateway:
-			where.append('gateway = \'' + gateway + '\'')
 		if search:
-			for value in search:
-				where.append(value)
-		if where:
-			where = ' where ' + " and ".join(where)
-		#group by time(30m) where time > now() – 1d 30分钟聚合,大于昨天的数据 1d 1h
-		sql = 'select value from ' + self.table + where
-		data = self.db.query(sql)
-		return [value for value in data.raw['series'][0]['values']]
-
-	def get(self, farm, device, search=''):
-		data = {}
-		data['farm'] = farm
-		data['device'] = device
-		self.setTable(data)
-		sql = 'select value from ' + self.table + search
+			search = ' where ' + search
+		sql = 'select ' + col + ' from ' + self.table + search
 		data = self.db.query(sql)
 		value = []
 		time = []
 		rows = []
-		utc_format='%Y-%m-%dT%H:%M:%S'
+		utc_format = '%Y-%m-%dT%H:%M:%S'
 		local_format = "%Y-%m-%d %H:%M:%S"
-		if data.raw['series'][0]['values']:
+		if 'series' in data.raw and data.raw['series'][0]['values']:
 			for values in data.raw['series'][0]['values']:
-				temp = values[0].split('.')
-				utc = Demeter.mktime(temp[0], utc_format) + 3600*8
-				date = Demeter.date(utc, local_format)
-				value.append(values[1])
-				time.append(date)
-				rows.append([values[0], values[1]])
-		return (time, value, rows)
+				if values[1]:
+					v = int(round(values[1]))
+					temp = values[0].split('.')
+					uformat = utc_format
+					if len(temp) <= 1:
+						uformat = utc_format + 'Z'
+					utc = Demeter.mktime(temp[0], uformat) + 3600*8
+					date = Demeter.date(utc, local_format)
+					value.append(v)
+					time.append(date)
+					rows.append([date, v])
+		return {'time':time, 'value':value, 'rows':rows}
+
+	def getData(self, method, data, config):
+		search = ''
+		col = 'value'
+		utc_format = '%Y-%m-%dT%H:%M:%SZ'
+		if ('start' in data and data['start']) or ('end' in data and data['end']):
+			if 'start' in data and data['start']:
+				start = Demeter.mktime(data['start'])
+				startDate = Demeter.date(start - 3600*8, utc_format)
+				search = 'time > \'' + str(startDate) + '\''
+
+			if 'end' in data and data['end']:
+				end = Demeter.mktime(data['end'])
+				endDate = Demeter.date(end - 3600*8, utc_format)
+				search = search + ' and time < \'' + str(endDate) + '\''
+				search = search + self.group(self.day(start, end))
+			else:
+				now = Demeter.time()
+				search = search + self.group(self.day(start, now))
+
+		elif 'group' in data and data['group']:
+			value = data['group']
+			time = 'time > now()'
+			search = time + ' - ' + value + 'd' + self.group(int(value))
+
+		result = []
+		if method == 'avg':
+			col = 'mean(value) as value'
+			result.append(self.load(config, search, col, '平均'))
+		elif method == 'maxmin':
+			col = 'max(value) as value'
+			result.append(self.load(config, search, col, '最高'))
+			col = 'min(value) as value'
+			result.append(self.load(config, search, col, '最低'))
+		else:
+			col = 'value'
+			if 'group' in search:
+				temp = search.split('group')
+				search = temp[0]
+			result.append(self.load(config, search, col, '明细'))
+		return result
+
+	def load(self, config, search, col, name):
+		result = {}
+		result['data'] = self.get(config['farm_id'], config['hardware_id'], search=search, col=col)
+		result['name'] = name
+		if result['data']:
+			result['data']['time'] = json.dumps(result['data']['time'])
+			result['data']['value'] = json.dumps(result['data']['value'])
+		return result
+
+	def group(self, day):
+		if day >= 180:
+			return ' group by time(10d)'
+		elif day >= 30:
+			return ' group by time(1d)'
+		elif day >= 7:
+			return ' group by time(60m)'
+		elif day >= 1:
+			return ' group by time(5m)'
+		else:
+			return ' group by time(1m)'
+
+	def day(self, start, end):
+		return math.ceil(round(float((end - start) / (3600*24))))
+
+	def dateConfig(self):
+		return [{'id':'1', 'name':'一天'},{'id':'7', 'name':'一周'},{'id':'30', 'name':'一个月'},{'id':'180', 'name':'半年'}]

+ 1 - 1
model/device_info.py

@@ -19,7 +19,7 @@ class Device_info(Model):
 	gateway_id = Fields(type='uuid', comment='网关id')
 	type_id = Fields(type='int', comment='设备类型')
 	num = Fields(type='int', default='0', comment='设备数据')
-	show_num = Fields(type='varchar(100)', comment='设备数据计算之后的数值')
+	show = Fields(type='varchar(500)', comment='设备数据计算之后的数值')
 	status = Fields(type='boolean', default='False', comment='设备连接状态')
 	state = Fields(type='boolean', default='True', comment='数据存在状态')
 	cdate = Fields(type='int', default='time', comment='创建时间')

+ 19 - 0
model/device_pic.py

@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:device_pic.py
+    author:rabin
+"""
+from __load__ import *
+
+class Device_pic(Model):
+	__table__ = 'device_pic'
+	__comment__ = '设备图片记录表'
+	id = Fields(type='uuid', primaryKey=True, comment='图片ID', uuid='farm_id')
+	farm_id = Fields(type='int', default='setting.farm', comment='园区ID', match='not')
+	gateway_id = Fields(type='uuid', comment='网关id')
+	device_id = Fields(type='uuid', comment='设备id')
+	pic = Fields(type='text', comment='图像记录')
+	state = Fields(type='boolean', default='True', comment='数据存在状态')
+	cdate = Fields(type='int', default='time', comment='创建时间')

+ 1 - 1
model/device_set.py

@@ -12,7 +12,7 @@ class Device_set(Model):
 	__comment__ = '设备设置'
 	id = Fields(type='uuid', primaryKey=True, comment='设备设置ID', uuid='farm_id')
 	farm_id = Fields(type='int', default='setting.farm', comment='园区ID', match='not')
-	device_id = Fields(type='int', comment='设备id')
+	device_id = Fields(type='uuid', comment='设备id')
 	max = Fields(type='smallint', comment='最大上限')
 	min = Fields(type='smallint', comment='最小下限')
 	state = Fields(type='boolean', default='True', comment='数据存在状态')

+ 24 - 23
model/msg.py

@@ -1,24 +1,25 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-    demeter database
-    name:msg.py
-    author:rabin
-    mqtt里的key:msg/type_key/farm_id/uid,value
-
-"""
-from __load__ import *
-
-class Msg(Model):
-	__table__ = 'msg'
-	__comment__ = '消息表'
-	id = Fields(type='uuid', primaryKey=True, comment='消息ID', uuid='farm_id')
-	farm_id = Fields(type='int', default='setting.farm', comment='园区ID')
-	uid = Fields(type='uuid', comment='用户ID')
-	type_id = Fields(type='int', comment='分类ID')
-	link = Fields(type='varchar(255)', comment='消息链接')
-	content = Fields(type='text', comment='消息内容')
-	push = Fields(type='varchar(50)', comment='推送')
-	status = Fields(type='boolean', default='False', comment='是否已读')
-	state = Fields(type='boolean', default='True', comment='数据存在状态')
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:msg.py
+    author:rabin
+    mqtt里的key:msg/type_key/farm_id/uid,value
+
+"""
+from __load__ import *
+
+class Msg(Model):
+	__table__ = 'msg'
+	__comment__ = '消息表'
+	id = Fields(type='uuid', primaryKey=True, comment='消息ID', uuid='farm_id')
+	farm_id = Fields(type='int', default='setting.farm', comment='园区ID')
+	device_id = Fields(type='uuid', comment='设备ID')
+	uid = Fields(type='uuid', comment='用户ID')
+	type_id = Fields(type='int', comment='分类ID')
+	link = Fields(type='varchar(255)', comment='消息链接')
+	content = Fields(type='text', comment='消息内容')
+	push = Fields(type='varchar(50)', comment='推送')
+	status = Fields(type='boolean', default='False', comment='是否已读')
+	state = Fields(type='boolean', default='True', comment='数据存在状态')
 	cdate = Fields(type='int', default='time', comment='创建时间')

+ 22 - 14
pub.py

@@ -6,6 +6,7 @@
     author:rabin
 """
 from demeter.mqtt import *
+from demeter.tcp import *
 import random
 import time
 
@@ -33,7 +34,7 @@ def pic():
 	pub = Pub()
 	key = 'pic/'
 	key = 'pic/pic_'
-	gateway = '/' + gateway + '/100001'
+	gateway = '/' + gateway + '/200001'
 	with open('admin/static/images/banner.png', 'rb') as f:
 		data = f.readlines()
 		total = len(data)
@@ -46,18 +47,25 @@ def pic():
 			print k
 			i = i+1
 
+#sensor()
+#pic()
 
-	#with open('test.png', 'w') as f:
-		#f.writelines(data)
-
-	"""
-	handle = open('admin/static/images/banner.png', 'rb')
-	img = handle.read(1)
-	handle.close()
-	data = struct.pack('c', img)
-	print data
-	"""
-	#pub.push(key, value)
+def tcp_sensor():
+	# 模拟设备数据
+	gateway = '10086'
+	def device():
+		return str(random.randint(100000, 100010))
+	def val():
+		return str(random.randint(1, 50))
 
-sensor()
-#pic()
+	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)
+tcp_sensor()

+ 55 - 5
service/record_pic.py

@@ -23,9 +23,9 @@ class Record_pic(object):
 		self.pic[name][index] = value
 		picLen = len(self.pic[name])
 		if picLen >= total:
-			self.create(name)
+			self.create(name, config)
 
-	def create(self, name):
+	def create(self, name, config):
 		pic = sorted(self.pic[name].items(), key=lambda e:e[0], reverse=False)
 		data = []
 		day = str(date.today())
@@ -39,8 +39,58 @@ class Record_pic(object):
 		with open(file_path, 'wb') as f:
 			f.writelines(data)
 			del self.pic[name]
+		file_path = file_path.replace(Demeter.path + 'runtime', '')
+		self.write(file_path, name, config)
 
-		self.write(file_path)
+	def write(self, file, name, config):
+		show_value = file
+		value = 0
+		model = Demeter.model('device_gateway')
+		model.hardware_id = config['parent']
+		gateway = model.select(type='fetchone')
+		if gateway:
+			model.id = gateway['id']
+			model.update(status=True,farm_id=gateway['farm_id'])
+			model = Demeter.model('device_info')
+			model.hardware_id = config['child']
+			device = model.select(type='fetchone')
+			model_type = Demeter.model('hardware_type')
+			model_type.key = config['method']
+			hard = model_type.select(type='fetchone')
+			if device:
+				#update
+				model.id = device['id']
+				id = device['id']
+				model.update(farm_id=gateway['farm_id'], num=value,show=show_value,status=True,cdate='time')
+			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']
+				model.num = value
+				model.show = show_value
+				model.status = True
+				id = model.insert()
+			self.hardware(id, config['child'], gateway['farm_id'],gateway['id'], hard['id'])
 
-	def write(self, file):
-		return
+			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 = file
+			model_pic.insert()
+
+	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()

+ 14 - 14
service/record_sensor.py

@@ -26,14 +26,15 @@ class Record_sensor(object):
 				model = Demeter.model('device_info')
 				model.hardware_id = config['child']
 				device = model.select(type='fetchone')
+				model_type = Demeter.model('hardware_type')
+				model_type.key = config['method']
+				hard = model_type.select(type='fetchone')
 				if device:
 					#update
 					model.id = device['id']
-					model.update(farm_id=gateway['farm_id'], num=value,show_num=show_value,status=True,cdate='time')
+					id = device['id']
+					model.update(farm_id=gateway['farm_id'], num=value,show=show_value,status=True,cdate='time')
 				else:
-					model_type = Demeter.model('hardware_type')
-					model_type.key = config['method']
-					hard = model_type.select(type='fetchone')
 					#insert
 					model.hardware_id = config['child']
 					model.farm_id = gateway['farm_id']
@@ -42,10 +43,10 @@ class Record_sensor(object):
 					model.gateway_id = gateway['id']
 					model.type_id = device_type['id']
 					model.num = value
-					model.show_num = show_value
+					model.show = show_value
 					model.status = True
 					id = model.insert()
-					self.hardware(id, config['child'], gateway['farm_id'],gateway['id'], hard['id'])
+				self.hardware(id, config['child'], gateway['farm_id'],gateway['id'], hard['id'])
 
 				data = {}
 				data['type'] = config['type']
@@ -55,6 +56,7 @@ class Record_sensor(object):
 				data['farm'] = gateway['farm_id']
 				data['source'] = value
 				data['value'] = show_value
+				data['time'] = Demeter.time()
 
 				Demeter.model('data', 'tsdb').insert(data)
 
@@ -64,11 +66,9 @@ class Record_sensor(object):
 			model.hardware_id = hardware_id
 			info = model.select(type='fetchone')
 			if not info:
-				insert = {}
-				insert['farm_id'] = farm
-				insert['hardware_id'] = hardware_id
-				insert['gateway_id'] = gateway
-				insert['device_id'] = id
-				insert['hardware_type'] = hard
-				model.insert()
-		
+				model.farm_id = farm
+				model.hardware_id = hardware_id
+				model.gateway_id = gateway
+				model.device_id = id
+				model.hardware_type = hard
+				model.insert()

Some files were not shown because too many files changed in this diff