From dec6ca23b56d7ce8f5e535c421c540029c104297 Mon Sep 17 00:00:00 2001
From: Roman Bazalevsky <rvb@rvb.name>
Date: Fri, 23 Sep 2016 22:20:58 +0300
Subject: [PATCH 1/1] =?utf8?q?1)=20MQTT-=D0=B8=D0=BD=D1=82=D0=B5=D1=80?=
 =?utf8?q?=D1=84=D0=B5=D0=B9=D1=81=20=D0=BA=20Asterisk=20=D0=B4=D0=BB?=
 =?utf8?q?=D1=8F=20=D0=BE=D1=82=D1=81=D0=BB=D0=B5=D0=B6=D0=B8=D0=B2=D0=B0?=
 =?utf8?q?=D0=BD=D0=B8=D1=8F=20=D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD?=
 =?utf8?q?=D0=B8=D0=B9=20=D0=B7=D0=B2=D0=BE=D0=BD=D0=BA=D0=BE=D0=B2=202)?=
 =?utf8?q?=20MQTT-=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81?=
 =?utf8?q?=20=D0=BA=20PulseAudio=20(=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0?=
 =?utf8?q?=D0=B5=D1=82=20=D0=B2=20=D0=B4=D0=B2=D0=B5=20=D1=81=D1=82=D0=BE?=
 =?utf8?q?=D1=80=D0=BE=D0=BD=D1=8B)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=utf8
Content-Transfer-Encoding: 8bit

---
 mqtt-agi/mqtt                       |  66 +++++++
 mqtt-agi/mqtt.cfg                   |   4 +
 mqtt-mpd/mqmpd.cfg~                 |   8 -
 mqtt-pulse/DEADJOE                  | 147 +++++++++++++++
 mqtt-pulse/mqtt.cfg                 |   7 +
 mqtt-pulse/mqtt_pulse.py            | 281 ++++++++++++++++++++++++++++
 mqtt-pulse/mqtt_pulse.pyc           | Bin 0 -> 7020 bytes
 sensors-postprocess/openhab-db.conf |  10 +
 8 files changed, 515 insertions(+), 8 deletions(-)
 create mode 100755 mqtt-agi/mqtt
 create mode 100644 mqtt-agi/mqtt.cfg
 delete mode 100644 mqtt-mpd/mqmpd.cfg~
 create mode 100644 mqtt-pulse/DEADJOE
 create mode 100644 mqtt-pulse/mqtt.cfg
 create mode 100755 mqtt-pulse/mqtt_pulse.py
 create mode 100644 mqtt-pulse/mqtt_pulse.pyc
 create mode 100644 sensors-postprocess/openhab-db.conf

diff --git a/mqtt-agi/mqtt b/mqtt-agi/mqtt
new file mode 100755
index 0000000..6f69c7e
--- /dev/null
+++ b/mqtt-agi/mqtt
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+
+#
+# Usage:
+# AGI(/etc/asterisk/agi/mqtt,/etc/asterisk/agi/mqtt.cfg,calls/missed)
+# or, to override the extension:
+# AGI(/etc/asterisk/agi/mqtt,/etc/asterisk/agi/mqtt.cfg,calls/missed,+43123456789)
+#
+
+import sys
+from ConfigParser import ConfigParser
+import paho.mqtt.client as paho
+
+import json
+
+from pprint import pprint
+
+conffile, topic = sys.argv[1:3]
+
+config = ConfigParser()
+config.add_section('mqtt')
+# set defaults for anonymous auth
+config.set('mqtt', 'username', '')
+config.set('mqtt', 'password', '')
+config.set('mqtt', 'port', '1883')
+config.read(conffile)
+
+mqtt_server = config.get('mqtt', 'server')
+mqtt_port = config.getint('mqtt', 'port')
+mqtt_username = config.get('mqtt', 'username')
+mqtt_password = config.get('mqtt', 'password')
+
+agi = []
+while 1:
+    line = sys.stdin.readline()
+    if not line or line == "\n":
+        break
+    agi.append(line)
+
+agi = dict([line.rstrip('\n').replace('agi_', '', 1).split(': ', 1) for line in agi])
+
+if len(sys.argv) > 3:
+    agi['extension'] = sys.argv[3]
+
+def agi_exit(rc, *args):
+    if rc != 0:
+        print "VERBOSE rc=%s %s" % (rc, args)
+    sys.exit(rc)
+
+def on_connect(mosq, rc, *args):
+    if rc != 0:
+        agi_exit(1, "Connection failed: %d" % rc)
+
+def on_publish(mosq, *args):
+    # done
+    agi_exit(0)
+
+client = paho.Client('agi')
+client.username_pw_set(mqtt_username, mqtt_password)
+client.connect(mqtt_server, port=mqtt_port)
+client.on_connect = on_connect
+client.on_publish = on_publish
+
+client.publish(topic, payload=json.dumps(agi))
+client.loop()
+agi_exit(1, "Message publish timed out")
diff --git a/mqtt-agi/mqtt.cfg b/mqtt-agi/mqtt.cfg
new file mode 100644
index 0000000..c8e33a0
--- /dev/null
+++ b/mqtt-agi/mqtt.cfg
@@ -0,0 +1,4 @@
+[mqtt]
+server = localhost
+username = asterisk
+password = mypassword
diff --git a/mqtt-mpd/mqmpd.cfg~ b/mqtt-mpd/mqmpd.cfg~
deleted file mode 100644
index 51dec1e..0000000
--- a/mqtt-mpd/mqmpd.cfg~
+++ /dev/null
@@ -1,8 +0,0 @@
-mqhost=localhost
-mqport=1883
-mquser="mpd"
-mqpassword="wsufytcvtldtltv"
-mqtopic="mpd/out"
-mqcmd="mpd/in"
-hosts=("estia" "nefele" "orpheus")
-passwd=("gdetotamdaleko" "11093008" "malenkayakorobka")
diff --git a/mqtt-pulse/DEADJOE b/mqtt-pulse/DEADJOE
new file mode 100644
index 0000000..7069859
--- /dev/null
+++ b/mqtt-pulse/DEADJOE
@@ -0,0 +1,147 @@
+
+*** These modified files were found in JOE when it aborted on Fri Sep 23 20:31:28 2016
+*** JOE was aborted because the terminal closed
+
+*** Файл '(БезИмени)'
+mqtt_pulse.py
+
+*** Файл 'mqtt_pulse.py'
+#!/usr/bin/python
+
+from pulsectl import Pulse,PulseLoopStop
+
+import threading
+
+sink_name=None
+muted=False
+volume=None
+
+paLock1=threading.RLock()
+paLock2=threading.RLock()
+stopFlag=False
+
+def Init():
+  global pulse
+  pulse = Pulse("mqtt-pa")
+
+def Reconnect():
+  pulse.close()
+  Init()
+
+def GetDefaultOut():
+  return pulse.server_info().default_sink_name
+
+def GetDefaultSink():
+  sinkname=GetDefaultOut()
+  for sink in pulse.sink_list():
+    if sink.name==sinkname:
+      return sink
+
+def GetDefaultVolume():
+  return pulse.volume_get_all_chans(GetDefaultSink())
+
+def IsDefaultMuted():
+  return GetDefaultSink().mute<>0
+  
+def MuteDefault(mute = True):
+  return pulse.mute(GetDefaultSink(),mute)
+
+def EventListener(callback):
+  pulse.event_mask_set('all')
+  pulse.event_callback_set(callback)
+  pulse.event_listen()
+
+def EventProcess(ev):
+  raise PulseLoopStop
+
+def AcquirePALock():
+  paLock1.acquire()
+  
+  pulse.event_listen_stop()
+  paLock2.acquire()
+
+def ReleasePALock():
+  paLock2.release()
+  paLock1.release()
+
+def StateProcess():
+  global sink_name,muted,volume
+  try:
+    tname=threading.current_thread().name
+#    print tname+">trying to aquire lock"
+    AcquirePALock()
+#    print tname+">lock aquired"
+    current_sink=GetDefaultOut()
+    current_vol=round(GetDefaultVolume(),2)
+    current_muted=IsDefaultMuted()
+    if current_sink<>sink_name:
+      sink_name=current_sink
+      print tname+">sink: "+sink_name
+    if current_vol<>volume:
+      volume=current_vol
+      print tname+">volume: "+str(volume)
+    if current_muted<>muted:
+      muted=current_muted
+      print tname+">muted: "+str(muted)
+  finally:
+    ReleasePALock()
+#    print tname+">lock released"
+
+def PAListener():
+  while not stopFlag:    
+#    print "entering wait loop"
+    EventListener(EventProcess)
+#    print "event or break happened"
+    StateProcess()
+
+def RunBackground(process):
+  stopFlag=False
+  thread = threading.Thread(target=process,name="Background")
+  thread.start()
+
+def StopBackground():
+  global stopFlag
+  stopFlag=True
+  pulse.event_listen_stop()
+
+def CommandGetDefaultOut():
+  try:
+    tname=threading.current_thread().name
+#    print tname+">trying to aquire lock"
+    AcquirePALock()
+#    print tname+">lock aquired"
+    result=GetDefaultOut()
+  finally:
+    ReleasePALock()
+#    print tname+">lock released"
+  return result
+
+def CommandGetDefaultVolume():
+  try:
+    tname=threading.current_thread().name
+#    print tname+">trying to aquire lock"
+    AcquirePALock()
+#    print tname+">lock aquired"
+    result=GetDefaultVolume()
+  finally:
+    ReleasePALock()
+#    print tname+">lock released"
+  return result
+
+def CommandIsDefaultMuted():
+  try:
+    tname=threading.current_thread().name
+#    print tname+">trying to aquire lock"
+    AcquirePALock()
+#    print tname+">lock aquired"
+    result=IsDefaultMuted()
+  finally:
+    ReleasePALock()
+#    print tname+">lock released"
+  return result
+  
+*** Файл '* Startup Log *'
+Processing '/etc/joe/joerc'...
+Processing '/etc/joe/ftyperc'...
+Finished processing /etc/joe/ftyperc
+Finished processing /etc/joe/joerc
diff --git a/mqtt-pulse/mqtt.cfg b/mqtt-pulse/mqtt.cfg
new file mode 100644
index 0000000..6cbf04c
--- /dev/null
+++ b/mqtt-pulse/mqtt.cfg
@@ -0,0 +1,7 @@
+[mqtt]
+server = localhost
+username = pulse
+password = mypassword
+in = pulse/host/in
+out = pulse/host/out
+
diff --git a/mqtt-pulse/mqtt_pulse.py b/mqtt-pulse/mqtt_pulse.py
new file mode 100755
index 0000000..9faa0d7
--- /dev/null
+++ b/mqtt-pulse/mqtt_pulse.py
@@ -0,0 +1,281 @@
+#!/usr/bin/python
+
+from pulsectl import Pulse,PulseLoopStop
+
+import threading
+from time import sleep
+
+import sys
+from ConfigParser import ConfigParser
+import paho.mqtt.client as paho
+
+# ====================== PulseAudio-related part ========================
+
+sink_name=None
+muted=None
+volume=None
+
+callback_changed=None
+
+paLock1=threading.RLock()
+paLock2=threading.RLock()
+stopFlag=False
+
+debug=False
+
+def Init():
+  global pulse
+  pulse = Pulse("mqtt-pa")
+
+def Reconnect():
+  pulse.close()
+  Init()
+
+def GetDefaultOut():
+  return pulse.server_info().default_sink_name
+
+def GetDefaultSink():
+  sinkname=GetDefaultOut()
+  for sink in pulse.sink_list():
+    if sink.name==sinkname:
+      return sink
+
+def GetDefaultVolume():
+  return pulse.volume_get_all_chans(GetDefaultSink())
+
+def SetDefaultVolume(volume):
+  pulse.volume_set_all_chans(GetDefaultSink(), volume)
+
+def IsDefaultMuted():
+  return GetDefaultSink().mute<>0
+  
+def MuteDefault(mute = True):
+  return pulse.mute(GetDefaultSink(),mute)
+
+def AcquirePALock():
+  tname=threading.current_thread().name
+  if debug:
+    print tname," aquiring action..."
+  paLock1.acquire()
+  if debug:
+    print tname," aquired action..."
+  pulse.event_listen_stop()
+  if debug:
+    print tname," event_listener stop command sent..."
+    print tname," aquiring loop..."
+  paLock2.acquire()
+  if debug:
+    print tname," aquired loop..."
+
+def ReleasePALock():
+  tname=threading.current_thread().name
+  if debug:
+    print tname," releasing loop..."
+  paLock2.release()
+  if debug:
+    print tname," released loop..."
+    print tname," releasing action..."
+  paLock1.release()
+  if debug:
+    print tname," released action..."
+
+def AquireLoopLock():
+  tname=threading.current_thread().name
+  if debug:
+    print tname," aquiring loop..."
+  paLock2.acquire()
+  if debug:
+    print tname," aquired loop..."
+
+def ReleaseLoopLock():
+  tname=threading.current_thread().name
+  if debug:
+    print tname," releasing loop..."
+  paLock2.release()
+  if debug:
+    print tname," released loop..."
+
+def EventListener(callback):
+  pulse.event_mask_set('all')
+  pulse.event_callback_set(callback)
+  AquireLoopLock()
+  try:
+    pulse.event_listen()
+  finally:
+    ReleaseLoopLock()
+
+def EventProcess(ev):
+  raise PulseLoopStop
+
+def StateProcess():
+  global sink_name,muted,volume
+  AcquirePALock()
+  try:
+    tname=threading.current_thread().name
+    current_sink=GetDefaultOut()
+    current_vol=round(GetDefaultVolume(),2)
+    current_muted="ON" if IsDefaultMuted() else "OFF"
+    if current_sink<>sink_name:
+      sink_name=current_sink
+      if debug:
+        print 'sink='+sink_name
+      if callback_changed:
+        if debug:
+          print 'callback...'
+        callback_changed('sink',sink_name)
+    if current_vol<>volume:
+      volume=current_vol
+      if debug:
+        print 'volume='+str(volume)
+      if callback_changed:
+        if debug:
+          print 'callback...'
+        callback_changed('volume',str(volume))
+    if current_muted<>muted:
+      muted=current_muted
+      if debug:
+        print 'muted='+muted
+      if callback_changed:
+        if debug:
+          print 'callback...'
+        callback_changed('muted',muted)
+  finally:
+    ReleasePALock()
+
+def PAListener():
+  while not stopFlag:    
+    EventListener(EventProcess)
+    StateProcess()
+
+def RunBackground(process):
+  stopFlag=False
+  thread = threading.Thread(target=process,name="Background")
+  thread.start()
+
+def StopBackground():
+  global stopFlag
+  stopFlag=True
+  pulse.event_listen_stop()
+
+def CommandGetDefaultOut():
+  AcquirePALock()
+  try:
+    result=GetDefaultOut()
+  finally:
+    ReleasePALock()
+  return result
+
+def CommandGetDefaultVolume():
+  AcquirePALock()
+  try:
+    result=GetDefaultVolume()
+  finally:
+    ReleasePALock()
+  return result
+
+def CommandIsDefaultMuted():
+  AcquirePALock()
+  try:
+    result=IsDefaultMuted()
+  finally:
+    ReleasePALock()
+  return result
+
+def CommandSetDefaultVolume(volume):
+  AcquirePALock()
+  try:
+    SetDefaultVolume(volume)    
+  finally:
+    ReleasePALock()
+
+def CommandMuteDefault(mute=True):
+  AcquirePALock()
+  try:
+    MuteDefault(mute)    
+  finally:
+    ReleasePALock()
+
+# ====================== MQTT-related part ========================
+
+lockMQTT = threading.RLock()
+
+def on_message(mosq, obj, msg):
+  if debug:
+    print("Received: " + msg.topic + " " + str(msg.payload))  
+  try:
+    subtopic=msg.topic[len(mqtt_topic_in)+1:]
+    payload=msg.payload
+    if subtopic=="volume":
+      CommandSetDefaultVolume(float(payload))
+    elif subtopic=="muted":
+      if payload=="ON":
+        payload=True
+      elif payload=="OFF":
+        payload=False
+      else:
+        payload=int(payload)  
+      CommandMuteDefault(payload)
+    else:
+      if debug:
+        print "Unknown command"  
+  except:
+    if debug:
+      print "Command failed"    
+  
+def InitMQTT():
+
+  global client,mqtt_topic_in,mqtt_topic_out
+
+  conffile = sys.argv[1]
+
+  config = ConfigParser()
+  config.add_section('mqtt')
+  # set defaults for anonymous auth
+  config.set('mqtt', 'username', '')
+  config.set('mqtt', 'password', '')
+  config.set('mqtt', 'port', '1883')
+  config.set('mqtt', 'in', 'pulse/in')
+  config.set('mqtt', 'out', 'pulse/out')
+  config.read(conffile)
+
+  mqtt_server = config.get('mqtt', 'server')
+  mqtt_port = config.getint('mqtt', 'port')
+  mqtt_username = config.get('mqtt', 'username')
+  mqtt_password = config.get('mqtt', 'password')
+  mqtt_topic_in = config.get('mqtt', 'in')
+  mqtt_topic_out = config.get('mqtt', 'out')
+
+  client = paho.Client('pulse')
+  client.username_pw_set(mqtt_username, mqtt_password)
+  client.on_message=on_message
+  client.connect(mqtt_server, port=mqtt_port)
+  client.subscribe(mqtt_topic_in+'/#',1)
+
+def MQTTCallback(param,value):
+
+  lockMQTT.acquire()
+  try:
+    client.publish(mqtt_topic_out+'/'+param, payload=value)
+    if debug:
+      print "Sent "+param+"="+value
+  finally:
+    lockMQTT.release()
+
+def StartPulseListener():
+  global callback_changed
+  Init()
+  InitMQTT()
+  callback_changed=MQTTCallback
+  StateProcess()
+  RunBackground(PAListener)
+
+StartPulseListener()
+
+try:
+  while True:
+    try:
+      client.loop()
+    except KeyboardInterrupt:
+      break
+finally:
+  StopBackground()    
diff --git a/mqtt-pulse/mqtt_pulse.pyc b/mqtt-pulse/mqtt_pulse.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..af1559e89ca953fb52ee651ff6172facf9f18dae
GIT binary patch
literal 7020
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
P{bFgnTq?Vzxl-xBTeQzi

literal 0
HcmV?d00001

diff --git a/sensors-postprocess/openhab-db.conf b/sensors-postprocess/openhab-db.conf
new file mode 100644
index 0000000..1a1c175
--- /dev/null
+++ b/sensors-postprocess/openhab-db.conf
@@ -0,0 +1,10 @@
+[mysql]
+host=localhost
+user=openhab
+passwd=mypassword
+db=openhab
+[openhab]
+template=Sensor%
+[filter]
+window=5
+threshold=10
-- 
2.34.1