rabin 7 years ago
parent
commit
d6632f47fe

+ 1 - 1
conf/env.conf

@@ -19,7 +19,7 @@ password			= public
 timeout				= 60
 ;topic定义
 topic				= method/type/gateway/device
-sub					= pic,sensor,control,power
+sub					= pic,sensor,control,power,status
 
 [postgresql]
 host				= iot-pgsql

+ 20 - 1
cron.py

@@ -18,7 +18,7 @@ def switch(value):
 	Demeter.service('device').switchMul(value)
 				
 
-# 更改设备状态
+# 更改设备状态(离线)
 def device():
 	while 1:
 		model = Demeter.model('device_info')
@@ -33,6 +33,24 @@ def device():
 			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.cdate.assgin(cur, '<=')
+		model.hardware_type = 3
+		service = Demeter.service('device')
+		data = model.select()
+		for v in data:
+			model.id = v['id']
+			if v['exp'] == '-1':
+				msg = service.notice('timeout')
+			else:
+				msg = '1'
+			model.update(exp=msg)
+		gevent.sleep(timeSleep)
 		
 
 def timing():
@@ -86,6 +104,7 @@ def handle():
 		gevent.spawn(loop),
 		gevent.spawn(device),
 		gevent.spawn(savePic),
+		gevent.spawn(control),
 	])
 
 handle()

+ 7 - 4
front/page/device.py

@@ -589,10 +589,12 @@ class update_path(Load):
 		id = self.input('id')
 		value = self.input('value')
 		if id:
-			#response = yield tornado.gen.Task(self.switch, id, value)
-			#yield self.switch(id, value)
-			#Demeter.service('device').switch(id, value)
-			response = Shell.popen(Demeter.path + 'switch.py ' + id + ' ' + value, timeout=10)
+			Demeter.service('device').switch(id, value)
+			
+			self.out('yes', {'id':id})
+			"""
+			yield self.switch(id, value)
+			Shell.popen(Demeter.path + 'switch.py ' + id + ' ' + value, bg=True)
 			response = response.replace("\n", "")
 			if response == 'ok':
 				self.out('yes', {'id':id})
@@ -604,6 +606,7 @@ class update_path(Load):
 					response = info['name']
 
 				self.out(response)
+			"""
 		else:
 			self.out('no')
 

+ 17 - 2
front/static/pc/js/main.js

@@ -60,6 +60,9 @@ var Farm =
 	{
 		var self = this;
 		var e = $(obj);
+		if (e.attr('class').indexOf('loading') > -1) {
+			return;
+		}
 		var value = e.attr('data-status');
 		data = {};
 		data.id = id;
@@ -73,8 +76,10 @@ var Farm =
 		e.addClass('loading');
 		self.Request('post', url, data, function(msg)
 		{
-			e.removeClass('loading');
+			self.Load();
 			self.CreateLoop();
+			/*
+			e.removeClass('loading');
 			msg = eval('(' + msg + ')');
 			if (msg.status == 2) {
 				alert(msg.msg);
@@ -89,6 +94,7 @@ var Farm =
 				//关闭
 				e.removeClass('open');
 			}
+			*/
 		})
 	}
 
@@ -98,9 +104,13 @@ var Farm =
 		var e = $(obj);
 		var c = e.attr('class');
 		var p = e.parent();
+		if (p.find('.loading').length) {
+			return;
+		}
 		if (c.indexOf('disabled') != -1) {
 			return;
 		}
+		/*
 		var name = e.html();
 		var old = p.find('.open')
 		var oldDisabled = p.find('.disabled')
@@ -111,6 +121,7 @@ var Farm =
 		} else {
 			oldDisabled.removeClass('disabled');
 		}
+		*/
 		data = {};
 		data.id = id;
 		data.value = value;
@@ -118,6 +129,9 @@ var Farm =
 		e.addClass('loading');
 		self.Request('post', url, data, function(msg)
 		{	
+			self.Load();
+			self.CreateLoop();
+			/*
 			e.removeClass('loading');
 			self.CreateLoop();
 			msg = eval('(' + msg + ')');
@@ -133,6 +147,7 @@ var Farm =
 				}
 				return;
 			}
+			*/
 		})
 	}
 
@@ -246,7 +261,7 @@ var Farm =
 
 	,CreateLoop : function() {
 		if (!this.loop) {
-			this.loop = setInterval("Farm.Load()", 3600);
+			this.loop = setInterval("Farm.Load()", 1500);
 		}
 	}
 

+ 647 - 0
front/static/pc/lib/layer/hint.css

@@ -0,0 +1,647 @@
+/*! Hint.css - v2.5.0 - 2017-04-23
+* http://kushagragour.in/lab/hint/
+* Copyright (c) 2017 Kushagra Gour */
+
+/*-------------------------------------*	HINT.css - A CSS tooltip library
+\*-------------------------------------*/
+/**
+ * HINT.css is a tooltip library made in pure CSS.
+ *
+ * Source: https://github.com/chinchang/hint.css
+ * Demo: http://kushagragour.in/lab/hint/
+ *
+ */
+/**
+ * source: hint-core.scss
+ *
+ * Defines the basic styling for the tooltip.
+ * Each tooltip is made of 2 parts:
+ * 	1) body (:after)
+ * 	2) arrow (:before)
+ *
+ * Classes added:
+ * 	1) hint
+ */
+[class*="hint--"] {
+  position: relative;
+  display: inline-block;
+  /**
+	 * tooltip arrow
+	 */
+  /**
+	 * tooltip body
+	 */ }
+  [class*="hint--"]:before, [class*="hint--"]:after {
+    position: absolute;
+    -webkit-transform: translate3d(0, 0, 0);
+    -moz-transform: translate3d(0, 0, 0);
+    transform: translate3d(0, 0, 0);
+    visibility: hidden;
+    opacity: 0;
+    z-index: 1000000;
+    pointer-events: none;
+    -webkit-transition: 0.3s ease;
+    -moz-transition: 0.3s ease;
+    transition: 0.3s ease;
+    -webkit-transition-delay: 0ms;
+    -moz-transition-delay: 0ms;
+    transition-delay: 0ms; }
+  [class*="hint--"]:hover:before, [class*="hint--"]:hover:after {
+    visibility: visible;
+    opacity: 1; }
+  [class*="hint--"]:hover:before, [class*="hint--"]:hover:after {
+    -webkit-transition-delay: 100ms;
+    -moz-transition-delay: 100ms;
+    transition-delay: 100ms; }
+  [class*="hint--"]:before {
+    content: '';
+    position: absolute;
+    background: transparent;
+    border: 6px solid transparent;
+    z-index: 1000001; }
+  [class*="hint--"]:after {
+    background: #383838;
+    color: white;
+    padding: 8px 10px;
+    font-size: 12px;
+    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+    line-height: 12px;
+    white-space: nowrap; }
+  [class*="hint--"][aria-label]:after {
+    content: attr(aria-label); }
+  [class*="hint--"][data-hint]:after {
+    content: attr(data-hint); }
+
+[aria-label='']:before, [aria-label='']:after,
+[data-hint='']:before,
+[data-hint='']:after {
+  display: none !important; }
+
+/**
+ * source: hint-position.scss
+ *
+ * Defines the positoning logic for the tooltips.
+ *
+ * Classes added:
+ * 	1) hint--top
+ * 	2) hint--bottom
+ * 	3) hint--left
+ * 	4) hint--right
+ */
+/**
+ * set default color for tooltip arrows
+ */
+.hint--top-left:before {
+  border-top-color: #383838; }
+
+.hint--top-right:before {
+  border-top-color: #383838; }
+
+.hint--top:before {
+  border-top-color: #383838; }
+
+.hint--bottom-left:before {
+  border-bottom-color: #383838; }
+
+.hint--bottom-right:before {
+  border-bottom-color: #383838; }
+
+.hint--bottom:before {
+  border-bottom-color: #383838; }
+
+.hint--left:before {
+  border-left-color: #383838; }
+
+.hint--right:before {
+  border-right-color: #383838; }
+
+/**
+ * top tooltip
+ */
+.hint--top:before {
+  margin-bottom: -11px; }
+
+.hint--top:before, .hint--top:after {
+  bottom: 100%;
+  left: 50%; }
+
+.hint--top:before {
+  left: calc(50% - 6px); }
+
+.hint--top:after {
+  -webkit-transform: translateX(-50%);
+  -moz-transform: translateX(-50%);
+  transform: translateX(-50%); }
+
+.hint--top:hover:before {
+  -webkit-transform: translateY(-8px);
+  -moz-transform: translateY(-8px);
+  transform: translateY(-8px); }
+
+.hint--top:hover:after {
+  -webkit-transform: translateX(-50%) translateY(-8px);
+  -moz-transform: translateX(-50%) translateY(-8px);
+  transform: translateX(-50%) translateY(-8px); }
+
+/**
+ * bottom tooltip
+ */
+.hint--bottom:before {
+  margin-top: -11px; }
+
+.hint--bottom:before, .hint--bottom:after {
+  top: 100%;
+  left: 50%; }
+
+.hint--bottom:before {
+  left: calc(50% - 6px); }
+
+.hint--bottom:after {
+  -webkit-transform: translateX(-50%);
+  -moz-transform: translateX(-50%);
+  transform: translateX(-50%); }
+
+.hint--bottom:hover:before {
+  -webkit-transform: translateY(8px);
+  -moz-transform: translateY(8px);
+  transform: translateY(8px); }
+
+.hint--bottom:hover:after {
+  -webkit-transform: translateX(-50%) translateY(8px);
+  -moz-transform: translateX(-50%) translateY(8px);
+  transform: translateX(-50%) translateY(8px); }
+
+/**
+ * right tooltip
+ */
+.hint--right:before {
+  margin-left: -11px;
+  margin-bottom: -6px; }
+
+.hint--right:after {
+  margin-bottom: -14px; }
+
+.hint--right:before, .hint--right:after {
+  left: 100%;
+  bottom: 50%; }
+
+.hint--right:hover:before {
+  -webkit-transform: translateX(8px);
+  -moz-transform: translateX(8px);
+  transform: translateX(8px); }
+
+.hint--right:hover:after {
+  -webkit-transform: translateX(8px);
+  -moz-transform: translateX(8px);
+  transform: translateX(8px); }
+
+/**
+ * left tooltip
+ */
+.hint--left:before {
+  margin-right: -11px;
+  margin-bottom: -6px; }
+
+.hint--left:after {
+  margin-bottom: -14px; }
+
+.hint--left:before, .hint--left:after {
+  right: 100%;
+  bottom: 50%; }
+
+.hint--left:hover:before {
+  -webkit-transform: translateX(-8px);
+  -moz-transform: translateX(-8px);
+  transform: translateX(-8px); }
+
+.hint--left:hover:after {
+  -webkit-transform: translateX(-8px);
+  -moz-transform: translateX(-8px);
+  transform: translateX(-8px); }
+
+/**
+ * top-left tooltip
+ */
+.hint--top-left:before {
+  margin-bottom: -11px; }
+
+.hint--top-left:before, .hint--top-left:after {
+  bottom: 100%;
+  left: 50%; }
+
+.hint--top-left:before {
+  left: calc(50% - 6px); }
+
+.hint--top-left:after {
+  -webkit-transform: translateX(-100%);
+  -moz-transform: translateX(-100%);
+  transform: translateX(-100%); }
+
+.hint--top-left:after {
+  margin-left: 12px; }
+
+.hint--top-left:hover:before {
+  -webkit-transform: translateY(-8px);
+  -moz-transform: translateY(-8px);
+  transform: translateY(-8px); }
+
+.hint--top-left:hover:after {
+  -webkit-transform: translateX(-100%) translateY(-8px);
+  -moz-transform: translateX(-100%) translateY(-8px);
+  transform: translateX(-100%) translateY(-8px); }
+
+/**
+ * top-right tooltip
+ */
+.hint--top-right:before {
+  margin-bottom: -11px; }
+
+.hint--top-right:before, .hint--top-right:after {
+  bottom: 100%;
+  left: 50%; }
+
+.hint--top-right:before {
+  left: calc(50% - 6px); }
+
+.hint--top-right:after {
+  -webkit-transform: translateX(0);
+  -moz-transform: translateX(0);
+  transform: translateX(0); }
+
+.hint--top-right:after {
+  margin-left: -12px; }
+
+.hint--top-right:hover:before {
+  -webkit-transform: translateY(-8px);
+  -moz-transform: translateY(-8px);
+  transform: translateY(-8px); }
+
+.hint--top-right:hover:after {
+  -webkit-transform: translateY(-8px);
+  -moz-transform: translateY(-8px);
+  transform: translateY(-8px); }
+
+/**
+ * bottom-left tooltip
+ */
+.hint--bottom-left:before {
+  margin-top: -11px; }
+
+.hint--bottom-left:before, .hint--bottom-left:after {
+  top: 100%;
+  left: 50%; }
+
+.hint--bottom-left:before {
+  left: calc(50% - 6px); }
+
+.hint--bottom-left:after {
+  -webkit-transform: translateX(-100%);
+  -moz-transform: translateX(-100%);
+  transform: translateX(-100%); }
+
+.hint--bottom-left:after {
+  margin-left: 12px; }
+
+.hint--bottom-left:hover:before {
+  -webkit-transform: translateY(8px);
+  -moz-transform: translateY(8px);
+  transform: translateY(8px); }
+
+.hint--bottom-left:hover:after {
+  -webkit-transform: translateX(-100%) translateY(8px);
+  -moz-transform: translateX(-100%) translateY(8px);
+  transform: translateX(-100%) translateY(8px); }
+
+/**
+ * bottom-right tooltip
+ */
+.hint--bottom-right:before {
+  margin-top: -11px; }
+
+.hint--bottom-right:before, .hint--bottom-right:after {
+  top: 100%;
+  left: 50%; }
+
+.hint--bottom-right:before {
+  left: calc(50% - 6px); }
+
+.hint--bottom-right:after {
+  -webkit-transform: translateX(0);
+  -moz-transform: translateX(0);
+  transform: translateX(0); }
+
+.hint--bottom-right:after {
+  margin-left: -12px; }
+
+.hint--bottom-right:hover:before {
+  -webkit-transform: translateY(8px);
+  -moz-transform: translateY(8px);
+  transform: translateY(8px); }
+
+.hint--bottom-right:hover:after {
+  -webkit-transform: translateY(8px);
+  -moz-transform: translateY(8px);
+  transform: translateY(8px); }
+
+/**
+ * source: hint-sizes.scss
+ *
+ * Defines width restricted tooltips that can span
+ * across multiple lines.
+ *
+ * Classes added:
+ * 	1) hint--small
+ * 	2) hint--medium
+ * 	3) hint--large
+ *
+ */
+.hint--small:after,
+.hint--medium:after,
+.hint--large:after {
+  white-space: normal;
+  line-height: 1.4em;
+  word-wrap: break-word; }
+
+.hint--small:after {
+  width: 80px; }
+
+.hint--medium:after {
+  width: 150px; }
+
+.hint--large:after {
+  width: 300px; }
+
+/**
+ * source: hint-theme.scss
+ *
+ * Defines basic theme for tooltips.
+ *
+ */
+[class*="hint--"] {
+  /**
+	 * tooltip body
+	 */ }
+  [class*="hint--"]:after {
+    text-shadow: 0 -1px 0px black;
+    box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3); }
+
+/**
+ * source: hint-color-types.scss
+ *
+ * Contains tooltips of various types based on color differences.
+ *
+ * Classes added:
+ * 	1) hint--error
+ * 	2) hint--warning
+ * 	3) hint--info
+ * 	4) hint--success
+ *
+ */
+/**
+ * Error
+ */
+.hint--error:after {
+  background-color: #b34e4d;
+  text-shadow: 0 -1px 0px #592726; }
+
+.hint--error.hint--top-left:before {
+  border-top-color: #b34e4d; }
+
+.hint--error.hint--top-right:before {
+  border-top-color: #b34e4d; }
+
+.hint--error.hint--top:before {
+  border-top-color: #b34e4d; }
+
+.hint--error.hint--bottom-left:before {
+  border-bottom-color: #b34e4d; }
+
+.hint--error.hint--bottom-right:before {
+  border-bottom-color: #b34e4d; }
+
+.hint--error.hint--bottom:before {
+  border-bottom-color: #b34e4d; }
+
+.hint--error.hint--left:before {
+  border-left-color: #b34e4d; }
+
+.hint--error.hint--right:before {
+  border-right-color: #b34e4d; }
+
+/**
+ * Warning
+ */
+.hint--warning:after {
+  background-color: #c09854;
+  text-shadow: 0 -1px 0px #6c5328; }
+
+.hint--warning.hint--top-left:before {
+  border-top-color: #c09854; }
+
+.hint--warning.hint--top-right:before {
+  border-top-color: #c09854; }
+
+.hint--warning.hint--top:before {
+  border-top-color: #c09854; }
+
+.hint--warning.hint--bottom-left:before {
+  border-bottom-color: #c09854; }
+
+.hint--warning.hint--bottom-right:before {
+  border-bottom-color: #c09854; }
+
+.hint--warning.hint--bottom:before {
+  border-bottom-color: #c09854; }
+
+.hint--warning.hint--left:before {
+  border-left-color: #c09854; }
+
+.hint--warning.hint--right:before {
+  border-right-color: #c09854; }
+
+/**
+ * Info
+ */
+.hint--info:after {
+  background-color: #3986ac;
+  text-shadow: 0 -1px 0px #1a3c4d; }
+
+.hint--info.hint--top-left:before {
+  border-top-color: #3986ac; }
+
+.hint--info.hint--top-right:before {
+  border-top-color: #3986ac; }
+
+.hint--info.hint--top:before {
+  border-top-color: #3986ac; }
+
+.hint--info.hint--bottom-left:before {
+  border-bottom-color: #3986ac; }
+
+.hint--info.hint--bottom-right:before {
+  border-bottom-color: #3986ac; }
+
+.hint--info.hint--bottom:before {
+  border-bottom-color: #3986ac; }
+
+.hint--info.hint--left:before {
+  border-left-color: #3986ac; }
+
+.hint--info.hint--right:before {
+  border-right-color: #3986ac; }
+
+/**
+ * Success
+ */
+.hint--success:after {
+  background-color: #458746;
+  text-shadow: 0 -1px 0px #1a321a; }
+
+.hint--success.hint--top-left:before {
+  border-top-color: #458746; }
+
+.hint--success.hint--top-right:before {
+  border-top-color: #458746; }
+
+.hint--success.hint--top:before {
+  border-top-color: #458746; }
+
+.hint--success.hint--bottom-left:before {
+  border-bottom-color: #458746; }
+
+.hint--success.hint--bottom-right:before {
+  border-bottom-color: #458746; }
+
+.hint--success.hint--bottom:before {
+  border-bottom-color: #458746; }
+
+.hint--success.hint--left:before {
+  border-left-color: #458746; }
+
+.hint--success.hint--right:before {
+  border-right-color: #458746; }
+
+/**
+ * source: hint-always.scss
+ *
+ * Defines a persisted tooltip which shows always.
+ *
+ * Classes added:
+ * 	1) hint--always
+ *
+ */
+.hint--always:after, .hint--always:before {
+  opacity: 1;
+  visibility: visible; }
+
+.hint--always.hint--top:before {
+  -webkit-transform: translateY(-8px);
+  -moz-transform: translateY(-8px);
+  transform: translateY(-8px); }
+
+.hint--always.hint--top:after {
+  -webkit-transform: translateX(-50%) translateY(-8px);
+  -moz-transform: translateX(-50%) translateY(-8px);
+  transform: translateX(-50%) translateY(-8px); }
+
+.hint--always.hint--top-left:before {
+  -webkit-transform: translateY(-8px);
+  -moz-transform: translateY(-8px);
+  transform: translateY(-8px); }
+
+.hint--always.hint--top-left:after {
+  -webkit-transform: translateX(-100%) translateY(-8px);
+  -moz-transform: translateX(-100%) translateY(-8px);
+  transform: translateX(-100%) translateY(-8px); }
+
+.hint--always.hint--top-right:before {
+  -webkit-transform: translateY(-8px);
+  -moz-transform: translateY(-8px);
+  transform: translateY(-8px); }
+
+.hint--always.hint--top-right:after {
+  -webkit-transform: translateY(-8px);
+  -moz-transform: translateY(-8px);
+  transform: translateY(-8px); }
+
+.hint--always.hint--bottom:before {
+  -webkit-transform: translateY(8px);
+  -moz-transform: translateY(8px);
+  transform: translateY(8px); }
+
+.hint--always.hint--bottom:after {
+  -webkit-transform: translateX(-50%) translateY(8px);
+  -moz-transform: translateX(-50%) translateY(8px);
+  transform: translateX(-50%) translateY(8px); }
+
+.hint--always.hint--bottom-left:before {
+  -webkit-transform: translateY(8px);
+  -moz-transform: translateY(8px);
+  transform: translateY(8px); }
+
+.hint--always.hint--bottom-left:after {
+  -webkit-transform: translateX(-100%) translateY(8px);
+  -moz-transform: translateX(-100%) translateY(8px);
+  transform: translateX(-100%) translateY(8px); }
+
+.hint--always.hint--bottom-right:before {
+  -webkit-transform: translateY(8px);
+  -moz-transform: translateY(8px);
+  transform: translateY(8px); }
+
+.hint--always.hint--bottom-right:after {
+  -webkit-transform: translateY(8px);
+  -moz-transform: translateY(8px);
+  transform: translateY(8px); }
+
+.hint--always.hint--left:before {
+  -webkit-transform: translateX(-8px);
+  -moz-transform: translateX(-8px);
+  transform: translateX(-8px); }
+
+.hint--always.hint--left:after {
+  -webkit-transform: translateX(-8px);
+  -moz-transform: translateX(-8px);
+  transform: translateX(-8px); }
+
+.hint--always.hint--right:before {
+  -webkit-transform: translateX(8px);
+  -moz-transform: translateX(8px);
+  transform: translateX(8px); }
+
+.hint--always.hint--right:after {
+  -webkit-transform: translateX(8px);
+  -moz-transform: translateX(8px);
+  transform: translateX(8px); }
+
+/**
+ * source: hint-rounded.scss
+ *
+ * Defines rounded corner tooltips.
+ *
+ * Classes added:
+ * 	1) hint--rounded
+ *
+ */
+.hint--rounded:after {
+  border-radius: 4px; }
+
+/**
+ * source: hint-effects.scss
+ *
+ * Defines various transition effects for the tooltips.
+ *
+ * Classes added:
+ * 	1) hint--no-animate
+ * 	2) hint--bounce
+ *
+ */
+.hint--no-animate:before, .hint--no-animate:after {
+  -webkit-transition-duration: 0ms;
+  -moz-transition-duration: 0ms;
+  transition-duration: 0ms; }
+
+.hint--bounce:before, .hint--bounce:after {
+  -webkit-transition: opacity 0.3s ease, visibility 0.3s ease, -webkit-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);
+  -moz-transition: opacity 0.3s ease, visibility 0.3s ease, -moz-transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24);
+  transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s cubic-bezier(0.71, 1.7, 0.77, 1.24); }

File diff suppressed because it is too large
+ 4 - 0
front/static/pc/lib/layer/hint.min.css


+ 1 - 0
front/templates/pc/device/data.html

@@ -4,6 +4,7 @@
 <html>
     <head>
         {%include '../inc/header.html'%}
+        <link href="{{static_url('pc/lib/layer/hint.css')}}" rel="stylesheet">
         {% if 'camera' in data and data['camera'] %}
         <link href="{{static_url('pc/lib/player/video-js.min.css')}}" rel="stylesheet">
         {% end %}

+ 12 - 4
front/templates/pc/device/inc/data.html

@@ -39,12 +39,16 @@
             {% if 'noset' not in data %}
             <dd class="controller"></dd>
             {% end %}
+            {%set layer = False %}
+            {% if value['exp'] != '-1' and  value['exp'] != '1' and value['exp'] != 'None' and value['exp'] %}
+            {%set layer = value['exp'] %}
+            {% end %}
             <dt>
-                <button onclick="Farm.Button(this, '/device/update', '{{value['id']}}', 1, '#button_down_{{value['id']}}')" id="button_up_{{value['id']}}" class="btn-switch {% if value['value'] in ('2','3') %}disabled{% end %} {% if value['value'] in ('1','4') %}open{% end %}"></button>
+                <button {% if layer %}data-hint="{{layer}}"{% end %} onclick="Farm.Button(this, '/device/update', '{{value['id']}}', 1, '#button_down_{{value['id']}}')" id="button_up_{{value['id']}}" class="btn-switch {% if layer and value['cxnum'] in (1,4) %}hint--top hint--info hint--always {% end %} {% if value['exp'] == '-1' and value['cxnum'] in (1,4) %}loading{% end %} {% if value['value'] in ('2','3') %}disabled{% end %} {% if value['value'] in ('1','4') %}open{% end %}"></button>
 
-                <button onclick="Farm.Button(this, '/device/update', '{{value['id']}}', 5)" id="button_stop_{{value['id']}}" class="btn-switch {% if value['value'] == '5' %}open{% end %}"></button>
+                <button {% if layer %}data-hint="{{layer}}"{% end %} onclick="Farm.Button(this, '/device/update', '{{value['id']}}', 5)" id="button_stop_{{value['id']}}" class="btn-switch {% if layer and value['cxnum'] == 5 %}hint--top hint--info hint--always {% end %} {% if value['exp'] == '-1' and value['cxnum'] == 5 %}loading{% end %} {% if value['value'] == '5' %}open{% end %}"></button>
 
-                <button onclick="Farm.Button(this, '/device/update', '{{value['id']}}', 2, '#button_up_{{value['id']}}')" id="button_down_{{value['id']}}" class="btn-switch {% if value['value'] in ('1','4') %}disabled{% end %} {% if value['value'] in ('2','3') %}open{% end %}"></button>
+                <button {% if layer %}data-hint="{{layer}}"{% end %} onclick="Farm.Button(this, '/device/update', '{{value['id']}}', 2, '#button_up_{{value['id']}}')" id="button_down_{{value['id']}}" class="btn-switch {% if layer and value['cxnum'] in (2,3) %}hint--top hint--info hint--always {% end %} {% if value['exp'] == '-1' and value['cxnum'] in (2,3) %}loading{% end %} {% if value['value'] in ('1','4') %}disabled{% end %} {% if value['value'] in ('2','3') %}open{% end %}"></button>
             </dt>
             <dd class="tit">{{value['name']}}</dd>          
         </dl>
@@ -53,8 +57,12 @@
             {% if 'noset' not in data %}
             <dd class="controller"></dd>
             {% end %}
+            {%set layer = False %}
+            {% if value['exp'] != '-1' and  value['exp'] != '1' and value['exp'] != 'None' and value['exp'] %}
+            {%set layer = value['exp'] %}
+            {% end %}
             <dt>
-                <p href="javascript:;" data-status="{% if value['value'] == '1' %}0{% else %}1{% end %}"  onclick="Farm.Switch(this, '/device/update', '{{value['id']}}')" class="btn-switch {% if value['value'] == '1' %}open{% end %}"><i></i></p>
+                <p href="javascript:;" {% if layer %}data-hint="{{layer}}"{% end %} data-status="{% if value['value'] == '1' %}0{% else %}1{% end %}"  onclick="Farm.Switch(this, '/device/update', '{{value['id']}}')" class="{% if layer %}hint--top hint--info hint--always {% end %} {% if value['exp'] != '-1' and  value['exp'] != '1' %}data-layer{% end %} btn-switch {% if value['exp'] == '-1' %}loading{% end %} {% if value['value'] == '1' %}open{% end %}"><i></i></p>
             </dt>
             <dd class="tit">{{value['name']}}</dd>          
         </dl>

+ 2 - 2
pub.py

@@ -14,8 +14,8 @@ import base64
 
 """
 pub = Pub()
-key = 'status/valve/10086/100107'
-value = 'ok'
+key = 'status/blower/10086/100114'
+value = 'error'
 state = pub.push(key, value)
 print state
 

+ 51 - 20
service/device.py

@@ -56,8 +56,9 @@ class Device(object):
 		model.id = device_id
 		info = model.select(type='fetchone')
 		if info and info['status'] == True:
-			#model.id = device_id
-			#model.update(value=switch)
+			# 设置为loading状态,cxnum保存当前的值
+			model.id = device_id
+			model.update(exp='-1', cxnum=switch)
 			model = Demeter.model('device_gateway')
 			model.id = info['gateway_id']
 			gateway_info = model.select(type='fetchone')
@@ -78,26 +79,56 @@ class Device(object):
 					update = 'update/' + key
 					feedback = 'status/' + key
 					value = switch
-					pub.push(update, value, qos=0, callback=self.switchAction, param={'id':info['id'], 'key':feedback, 'switch':switch}, feedback=True)
+					#pub.push(update, value, qos=0, callback=self.switchAction, param={'info':info, 'key':feedback, 'switch':switch}, feedback=True)
+					pub.push(update, value)
 		else:
-			Demeter.error('offline')
+			model.id = device_id
+			model.update(exp='offline', cxnum=switch)
+			#Demeter.error('offline')
 
 	# 处理开关-响应
 	def switchAction(self, param, client, userdata, mid, msg='ok'):
-		if msg == 'ok':
-			model = Demeter.model('device_info')
-			model.id = param['id']
-			model.update(value=param['switch'])
-			print msg
-		else:
-			# 获取错误码
-			"""
-			model = Demeter.model('notice_type')
-			model.key = msg
-			info = model.select(type='fetchone')
-			if info:
-				Demeter.error(info['name'])
+		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')
 			else:
-				Demeter.error(msg)
-			"""
-			Demeter.error(msg)
+				msg = self.notice(msg)
+				model = Demeter.model('device_info')
+				model.id = info['id']
+				model.update(exp=msg)
+
+				model = Demeter.model('device_type')
+				model.id = info['type_id']
+				type_info = model.select(type='fetchone')
+				if type_info['unit'] == 'button':
+					if param['switch'] == 1:
+						oper = '升起'
+					elif param['switch'] == 2:
+						oper = '降下'
+					elif param['switch'] == 5:
+						oper = '停止'
+				else:
+					if param['switch'] == 1:
+						oper = '开启'
+					else:
+						oper = '关闭'
+				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

+ 20 - 0
service/record_status.py

@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter service
+    name:record_status.py 处理update控制器的实时错误码
+    author:rabin
+    key:status/type/gateway/device
+"""
+from demeter.core import *
+class Record_status(object):
+
+	def handle(self, record, config, value):
+		model = Demeter.model('device_info')
+		model.hardware_id = config['child']
+		model.hardware_type = 3
+		device = model.select(type='fetchone')
+		if device:
+			param = {}
+			param['info'] = device
+			Demeter.service('device').switchAction(param, False, False, False, msg=value)

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