Subversion Repositories alarming

Compare Revisions

No changes between revisions

Regard whitespace Rev 5 → Rev 6

/trunk/Server/config.py
2,3 → 2,6
 
motion_stream_port = 8081;
 
enable_motion_detect = 1;
enable_doorbell_listener = 1;
 
/trunk/Server/daemon.py
10,8 → 10,10
import subprocess
import config
import threading
import subprocess as sp
 
g_subscribed = []
g_bellListenerProc = None
 
class S(BaseHTTPRequestHandler):
def _output(self, code, content):
126,6 → 128,7
# ---
 
global g_subscribed
global g_bellListenerProc
 
if pvget(postvars, "action")[0] == "client_subscribe": # 1.3.6.1.4.1.37476.2.4.1.1
client_ip = self.client_address[0]
184,11 → 187,16
 
if pvget(postvars, "action")[0] == "motion_on": # 1.3.6.1.4.1.37476.2.4.1.100
print "Motion start"
if config.enable_motion_detect:
os.system(os.path.dirname(os.path.abspath(__file__)) + "/motion/motion_start_safe")
 
if config.enable_doorbell_listener:
g_bellListenerProc = sp.Popen(['python3',os.path.dirname(os.path.abspath(__file__)) + "/doorbell/bell_listener.py"])
if pvget(postvars, "action")[0] == "motion_off": # 1.3.6.1.4.1.37476.2.4.1.101
print "Motion stop"
if config.enable_motion_detect:
os.system(os.path.dirname(os.path.abspath(__file__)) + "/motion/motion_stop_safe")
if config.enable_doorbell_listener:
sp.Popen.terminate(g_bellListenerProc)
 
self._output(200, '')
 
/trunk/Server/doorbell/bell_listener.py
0,0 → 1,123
#!/usr/bin/env python3
 
# This script listens to the microphone and detects a doorbell that plays 2 sounds ("ding" "dong")
# Please configure and adjust the script to your needings
 
import pyaudio
import wave
import numpy as np
import time
import os
 
CHUNK = 2*4096 # number of data points to read at a time
RATE = 48000 # time resolution of the recording device (Hz)
DEVICE = 1 # Webcam
TARGET_FREQ_DING = 3232 # Hz, in AudaCity, select "Analyze > Spectrum" to find out the frequency of your doorbell
TARGET_FREQ_DONG = 2781 # Hz
DING_TRES = 1.5
DONG_TRES = 2.4
DING_DONG_INTERVAL = 4 # max seconds between "ding" and "dong"
 
#SIMULATE_WAVEFILE = "test/doorbell_test.wav"
SIMULATE_WAVEFILE = ""
DEBUG = 2
 
# -------------------------------------------------------------
 
p = pyaudio.PyAudio()
 
if SIMULATE_WAVEFILE == "":
RATE = 48000 # TODO: read from hw-params
DTYPE = np.int16 # TODO: read from hw-params?
stream=p.open(format=pyaudio.paInt16,channels=1,rate=RATE,input=True, input_device_index=DEVICE, frames_per_buffer=CHUNK)
else:
wf = wave.open(SIMULATE_WAVEFILE, 'rb')
DTYPE = np.int16 # TODO: read from wave file?
RATE = wf.getframerate()
 
col_target_ding = []
col_target_dong = []
col_other = []
 
last_detected_ding = 0
last_detected_dong = 0
max_intensity_ding = 0
max_intensity_dong = 0
 
while True:
if SIMULATE_WAVEFILE == "":
indata = np.fromstring(stream.read(CHUNK),dtype=DTYPE)
else:
d = wf.readframes(CHUNK)
if len(d) == 0:
break;
indata = np.fromstring(d,dtype=DTYPE)
 
fftData = np.fft.fft(indata)
freqs = np.fft.fftfreq(fftData.size)
magnitudes = fftData[1:int(fftData.size/2)]
 
# Find out volume of target "ding" frequency
 
idx = (np.abs(freqs-TARGET_FREQ_DING/RATE)).argmin()
volume_target_ding = np.sum(np.abs(magnitudes[int(idx-1):int(idx+1)])) / 3
 
# Find out volume of target "dong" frequency
 
idx = (np.abs(freqs-TARGET_FREQ_DONG/RATE)).argmin()
volume_target_dong = np.sum(np.abs(magnitudes[int(idx-1):int(idx+1)])) / 3
 
# Find out the general volume
 
volume_other = np.mean(np.abs(magnitudes))
#volume_other = np.median(np.abs(magnitudes))
 
# Filter peaks
 
col_other.append(volume_other)
while len(col_other) > 5:
col_other.pop(0)
volume_other = (np.sum(col_other) + 10*volume_other) / 15
 
col_target_ding.append(volume_target_ding)
while len(col_target_ding) > 5:
col_target_ding.pop(0)
volume_target_ding = (np.sum(col_target_ding) + 10*volume_target_ding) / 15
 
col_target_dong.append(volume_target_dong)
while len(col_target_dong) > 5:
col_target_dong.pop(0)
volume_target_dong = (np.sum(col_target_dong) + 10*volume_target_dong) / 15
 
# Debug
if DEBUG > 1:
print("Debug: DING", volume_target_ding/volume_other, "DONG", volume_target_dong/volume_other)
 
# Check ratio
if (volume_target_ding/volume_other > DING_TRES):
if DEBUG > 0:
print("Detected: DING with intensity {}>{}".format(volume_target_ding/volume_other,DING_TRES))
last_detected_ding = time.time()
max_intensity_ding = max(max_intensity_ding, volume_target_ding/volume_other)
 
if (volume_target_dong/volume_other > DONG_TRES):
if DEBUG > 0:
print("Detected: DONG with intensity {}>{}".format(volume_target_dong/volume_other,DONG_TRES))
last_detected_dong = time.time()
max_intensity_dong = max(max_intensity_dong, volume_target_dong/volume_other)
 
interval = last_detected_dong - last_detected_ding
if (last_detected_ding > 0) and (last_detected_dong > 0) and (interval > 0) and (interval < DING_DONG_INTERVAL):
if DEBUG > 0:
print("Detected: DING DONG! with max intensity ding {} dong {}".format(max_intensity_ding, max_intensity_dong))
else:
print("DING DONG!")
os.system(os.path.dirname(os.path.abspath(__file__)) + "/detect.py")
last_detected_ding = 0
last_detected_dong = 0
max_intensity_ding = 0
max_intensity_dong = 0
 
if SIMULATE_WAVEFILE == "":
stream.close()
p.terminate()
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/Server/doorbell/detect.d/client_alert
0,0 → 1,48
#!/usr/bin/php
<?php
 
# --- PLEASE MODIFY:
 
# To which daemon server should the alarm be sent?
$url = "http://127.0.0.1:8085";
 
# Which targets should be reported?
$targets = array(
"1.3.6.1.4.1.37476.2.4.2.0", // Any
"1.3.6.1.4.1.37476.2.4.2.2001", // Sound, doorbell
"1.3.6.1.4.1.37476.1.2.1.2" // PRIVATE: Doorbell of Daniel Marschall
);
 
# --- DON'T MODIFY AFTER THIS LINE
 
$fields = array();
$fields[] = "action=server_alert"; // 1.3.6.1.4.1.37476.2.4.1.2
foreach ($targets as $target) {
// Note: We are not using http_build_query(), because it sends targets[0]=...&targets[1]=...,
// which is not what we need. We want targets=...&targets=...
$fields[] = "targets=".urlencode($target);
}
$fields_string = implode('&', $fields);
 
echo urldecode($fields_string)."\n";
 
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
$result = curl_exec($ch);
 
echo $result;
 
// Note: We are not using Python to send the alert, because the "import" command is extremely
// slow, and we need to send an alarm withhin milliseconds!
/*
import requests
d = {"action": "server_alert", "targets": [
"...",
"..."
]}
requests.post("http://127.0.0.1:8085", data=d)
*/
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/Server/doorbell/detect.d
Property changes:
Added: svn:ignore
+stop_spotify
/trunk/Server/doorbell/detect.py
0,0 → 1,10
#!/usr/bin/env python3
 
import os
 
dir=os.path.dirname(os.path.abspath(__file__)) + "/detect.d/"
 
for root, dirs, files in os.walk(dir):
for fname in files:
os.system(dir + fname + " &")
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/Server/doorbell/test/doorbell_test.wav
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/Server/doorbell/test/freq_test.py
0,0 → 1,34
#!/usr/bin/env python3
 
import pyaudio
import numpy as np
 
CHUNK = 2*4096 # number of data points to read at a time
RATE = 48000 # time resolution of the recording device (Hz)
DEVICE = 1 # Webcam
 
p = pyaudio.PyAudio()
 
stream=p.open(format=pyaudio.paInt16,channels=1,rate=RATE,input=True, input_device_index=DEVICE,
frames_per_buffer=CHUNK)
 
while True:
indata = np.fromstring(stream.read(CHUNK),dtype=np.int16)
 
# Take the fft and square each value
fftData=abs(np.fft.rfft(indata))**2
# find the maximum
which = fftData[1:].argmax() + 1
# use quadratic interpolation around the max
if which != len(fftData)-1:
y0,y1,y2 = np.log(fftData[which-1:which+2:])
x1 = (y2 - y0) * .5 / (2 * y1 - y2 - y0)
# find the frequency and output it
thefreq = (which+x1)*RATE/CHUNK
print("The freq is %f Hz." % (thefreq))
else:
thefreq = which*RATE/CHUNK
print("The freq is %f Hz." % (thefreq))
 
stream.close()
p.terminate()
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/Server/doorbell/test/record.sh
0,0 → 1,3
#!/bin/bash
arecord --device=plughw:1,0 --format S16_LE --rate 44100 -c1 /tmp/test.wav
 
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/Server/motion/motion_start_safe
11,5 → 11,7
system(escapeshellcmd(__DIR__.'/usbreset').' '.escapeshellarg("/dev/bus/usb/".$m[1]."/".$m[2]));
}
 
sleep(10);
 
system("service motion start");