rabin 4 years ago
parent
commit
ce712d284d
3 changed files with 193 additions and 1 deletions
  1. 1 1
      demeter/admin/templates/theme/stat.html
  2. 91 0
      demeter/daemon.py
  3. 101 0
      demeter/modbus.py

+ 1 - 1
demeter/admin/templates/theme/stat.html

@@ -18,7 +18,7 @@
         </div>
         <div class="x-body">
             <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="id" id="id" value="{% if data['info'] and 'id' in data['info'] and data['info']['id'] %}{{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">

+ 91 - 0
demeter/daemon.py

@@ -0,0 +1,91 @@
+# -*- coding: utf-8 -*-
+import os
+import sys
+import time
+import atexit
+import signal
+  
+  
+class Daemon(object):
+  def __init__(self, pidfile='/tmp/daemon.pid', stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
+    self.stdin = stdin
+    self.stdout = stdout
+    self.stderr = stderr
+    self.pidfile = pidfile
+  
+  def daemonize(self):
+    if os.path.exists(self.pidfile):
+      raise RuntimeError('Already running.')
+  
+    # First fork (detaches from parent)
+    try:
+      if os.fork() > 0:
+        raise SystemExit(0)
+    except OSError as e:
+      raise RuntimeError('fork #1 faild: {0} ({1})\n'.format(e.errno, e.strerror))
+  
+    os.chdir('/')
+    os.setsid()
+    os.umask(0o22)
+  
+    # Second fork (relinquish session leadership)
+    try:
+      if os.fork() > 0:
+        raise SystemExit(0)
+    except OSError as e:
+      raise RuntimeError('fork #2 faild: {0} ({1})\n'.format(e.errno, e.strerror))
+  
+    # Flush I/O buffers
+    sys.stdout.flush()
+    sys.stderr.flush()
+  
+    # Replace file descriptors for stdin, stdout, and stderr
+    with open(self.stdin, 'rb', 0) as f:
+      os.dup2(f.fileno(), sys.stdin.fileno())
+    with open(self.stdout, 'ab', 0) as f:
+      os.dup2(f.fileno(), sys.stdout.fileno())
+    with open(self.stderr, 'ab', 0) as f:
+      os.dup2(f.fileno(), sys.stderr.fileno())
+  
+    # Write the PID file
+    with open(self.pidfile, 'w') as f:
+      print(os.getpid(), file=f)
+  
+    # Arrange to have the PID file removed on exit/signal
+    atexit.register(lambda: os.remove(self.pidfile))
+  
+    signal.signal(signal.SIGTERM, self.__sigterm_handler)
+  
+  # Signal handler for termination (required)
+  @staticmethod
+  def __sigterm_handler(signo, frame):
+    raise SystemExit(1)
+  
+  def start(self):
+    try:
+      self.daemonize()
+    except RuntimeError as e:
+      print(e, file=sys.stderr)
+      raise SystemExit(1)
+  
+    self.run()
+  
+  def stop(self):
+    try:
+      if os.path.exists(self.pidfile):
+        with open(self.pidfile) as f:
+          os.kill(int(f.read()), signal.SIGTERM)
+      else:
+        print('Not running.', file=sys.stderr)
+        raise SystemExit(1)
+    except OSError as e:
+      if 'No such process' in str(e) and os.path.exists(self.pidfile):
+        os.remove(self.pidfile)
+  
+  def restart(self):
+    self.stop()
+    self.start()
+  
+  def run(self):
+  #继承类重写该方法
+    pass

+ 101 - 0
demeter/modbus.py

@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter
+    name:mqtt.py
+    author:rabin
+"""
+from demeter.core import *
+import paho.mqtt.client as mqtt
+#from gevent import monkey; monkey.patch_all()
+#import gevent
+
+class Connect(object):
+
+	def __init__(self, act):
+		act.connect = self
+		self.client = mqtt.Client()
+		state = hasattr(act, 'message')
+		if state:
+			self.client.on_connect = self.connectAndSub
+			self.client.on_message = act.message
+		else:
+			self.client.on_connect = self.connect
+		self.client.connect(Demeter.config['mqtt']['host'], Demeter.config['mqtt']['port'], int(Demeter.config['mqtt']['timeout']))
+		if state:
+			self.client.loop_forever()
+
+	def __del__(self):
+		pass
+
+	def getClient(self):
+		return self.client
+
+	def connect(self, client, userdata, flags, rc):
+		pass
+
+	def connectAndSub(self, client, userdata, flags, rc):
+		#print("Connected with result code "+str(rc))
+		#client.subscribe("sensor/#")
+		sub = Demeter.config['mqtt']['sub'].split(',')
+		for value in sub:
+			client.subscribe(value + "/#")
+		"""
+		gevent.joinall([
+			gevent.spawn(self.subscribe, client, 'sensor/#'),
+			gevent.spawn(self.subscribe, client, 'pic/#'),
+			gevent.spawn(self.subscribe, client, 'msg/#'),
+		])
+		"""
+
+	@staticmethod
+	def subscribe(client, key):
+		client.subscribe(key)
+
+	def handle(self, key, value):
+		Demeter.record(key, value)
+
+
+class Pub(object):
+
+	def __init__(self):
+		Connect(self)
+
+	def __del__(self):
+		pass
+
+	def push(self, key, msg, qos=0, retain=False, callback=False, param=False, feedback=False):
+		result = self.connect.getClient().publish(key,payload=msg,qos=qos,retain=retain)
+
+		self.callback = callback
+		self.param = param
+		if feedback == True and 'key' in self.param:
+			self.connect.client.on_message = self.feedback
+			self.connect.client.subscribe(self.param['key'])
+			self.connect.client.loop_forever()
+		elif qos in (1,2):
+			self.connect.client.on_publish = self.publish
+			self.connect.client.loop_forever()
+		#else:
+			#self.connect.client.disconnect()
+		return result
+
+	def publish(self, client, userdata, mid, msg='ok'):
+		self.callback(self.param, client, userdata, mid, msg)
+		self.connect.client.disconnect()
+
+	def feedback(self, client, userdata, msg):
+		if msg.topic == self.param['key']:
+			self.publish(client, userdata, 0, msg.payload)
+
+class Sub(object):
+
+	def __init__(self):
+		Connect(self)
+
+	def __del__(self):
+		pass
+
+	def message(self, client, userdata, msg):
+		#print(msg.topic+" "+str(msg.payload))
+		#return
+		self.connect.handle(msg.topic, str(msg.payload))