upload NK edge code
This commit is contained in:
parent
52db1f209e
commit
a2a6263eef
98
EDGE_CODE/audio_stream_classifier.py
Normal file
98
EDGE_CODE/audio_stream_classifier.py
Normal file
@ -0,0 +1,98 @@
|
||||
import os
|
||||
import alsaaudio
|
||||
import audioop
|
||||
import numpy
|
||||
import shutil
|
||||
import asyncio
|
||||
import time
|
||||
import datetime
|
||||
import collections
|
||||
import scipy.io.wavfile as wavfile
|
||||
from pyAudioAnalysis import MidTermFeatures as mtF
|
||||
from pyAudioAnalysis import audioTrainTest as aT
|
||||
|
||||
fs = 44100
|
||||
start_time = 0
|
||||
daily_counter = 0
|
||||
std = None
|
||||
mean = None
|
||||
classifier = None
|
||||
sec_60_que = None
|
||||
class_names = None
|
||||
microphone = 'hw:CARD=LX3000,DEV=0'
|
||||
record_path = "Last60Sample/"
|
||||
permanent_path = "DailySamples/"
|
||||
conv = datetime.datetime.fromtimestamp
|
||||
|
||||
|
||||
def background( f ):
|
||||
def wrapped(*args,**kwargs):
|
||||
return asyncio.get_event_loop().run_in_executor(None,f,*args,*kwargs)
|
||||
return wrapped
|
||||
|
||||
def record_analyze_audio( mid_term_buffer_size_in_sec ):
|
||||
print("Press Ctr+C to stop recording")
|
||||
inp = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NONBLOCK,device=microphone)
|
||||
inp.setchannels(1)
|
||||
inp.setrate(fs)
|
||||
inp.setformat(alsaaudio.PCM_FORMAT_S16_LE)
|
||||
inp.setperiodsize(512)
|
||||
mid_term_buffer_size = int(mid_term_buffer_size_in_sec * fs)
|
||||
cur_window = []
|
||||
append = cur_window.append
|
||||
mid_term_buffer = []
|
||||
d = os.path.dirname(record_path)
|
||||
if os.path.exists(d) and record_path!=".":
|
||||
shutil.rmtree(record_path)
|
||||
os.makedirs(record_path)
|
||||
d = os.path.dirname(permanent_path)
|
||||
if os.path.exists(d) and permanent_path!=".":
|
||||
shutil.rmtree(permanent_path)
|
||||
os.makedirs(permanent_path)
|
||||
while 1:
|
||||
l,data = inp.read()
|
||||
if l :
|
||||
[append(audioop.getsample(data, 2, i)) for i in range(l)]
|
||||
if (len(cur_window)+len(mid_term_buffer)>mid_term_buffer_size):
|
||||
samples_to_copy_to_mid_buffer = mid_term_buffer_size - len(mid_term_buffer)
|
||||
else:
|
||||
samples_to_copy_to_mid_buffer = len(cur_window)
|
||||
mid_term_buffer += cur_window[0:samples_to_copy_to_mid_buffer]
|
||||
del(cur_window[0:samples_to_copy_to_mid_buffer])
|
||||
if len(mid_term_buffer) == mid_term_buffer_size:
|
||||
predict(mid_term_buffer)
|
||||
mid_term_buffer = []
|
||||
|
||||
@background
|
||||
def predict( mid_term_buffer ):
|
||||
global sec_60_que
|
||||
global daily_counter
|
||||
[mt_features, st_features, _] = mtF.mid_feature_extraction(mid_term_buffer, fs, 2.0*fs, 2.0*fs, 0.020*fs, 0.020*fs)
|
||||
curFV = (mt_features[:,0] - mean) / std
|
||||
[result,P] = aT.classifier_wrapper(classifier, 'svm', curFV)
|
||||
cur_wav_file_name = "%s%s_%s.wav"%(record_path,conv(time.time()).strftime('%S,%f'),str(class_names[int(result)]))
|
||||
permanent_name = "%s/%s_%s.wav"%(permanent_path,conv(time.time()).strftime('%H:%M_%S,%f'),str(class_names[int(result)]))
|
||||
mid_term_buffer_array = numpy.int16(mid_term_buffer)
|
||||
wav_to_remove=sec_60_que.popleft()
|
||||
if os.path.exists(str(wav_to_remove)):
|
||||
os.remove(wav_to_remove)
|
||||
if daily_counter != conv(time.time()).strftime('%d'):
|
||||
shutil.rmtree(permanent_path)
|
||||
daily_counter = conv(time.time()).strftime('%d')
|
||||
wavfile.write(cur_wav_file_name, fs, mid_term_buffer_array)
|
||||
if not os.path.exists(permanent_path) :
|
||||
os.makedirs(permanent_path)
|
||||
wavfile.write(permanent_name, fs, mid_term_buffer_array)
|
||||
sec_60_que.append(cur_wav_file_name)
|
||||
|
||||
def start( duration_of_record,name_of_model ):
|
||||
global classifier
|
||||
global mean
|
||||
global std
|
||||
global class_names
|
||||
global sec_60_que
|
||||
duration = int(duration_of_record)
|
||||
model_name = name_of_model
|
||||
sec_60_que = collections.deque(int(60/duration)*[0],int(60/duration))
|
||||
[classifier, mean,std,class_names,mt_win,mt_step,st_win,st_step, compute_beat] = aT.load_model(model_name)
|
||||
record_analyze_audio( mid_term_buffer_size_in_sec = duration )
|
25
EDGE_CODE/buzzer.py
Normal file
25
EDGE_CODE/buzzer.py
Normal file
@ -0,0 +1,25 @@
|
||||
import asyncio
|
||||
import RPi.GPIO as GPIO
|
||||
from time import sleep
|
||||
|
||||
class Buzzer:
|
||||
def __init__(self):
|
||||
GPIO.setwarnings(False)
|
||||
GPIO.setmode(GPIO.BCM)
|
||||
self.buzzer=23
|
||||
GPIO.setup(self.buzzer,GPIO.OUT)
|
||||
|
||||
def background(f):
|
||||
def wrapped(*args,**kwargs):
|
||||
return asyncio.get_event_loop().run_in_executor(None,f,*args,*kwargs)
|
||||
return wrapped
|
||||
|
||||
@background
|
||||
def beep(self):
|
||||
i=0
|
||||
while i < 3 :
|
||||
GPIO.output(self.buzzer,GPIO.HIGH)
|
||||
sleep(0.2)
|
||||
GPIO.output(self.buzzer,GPIO.LOW)
|
||||
sleep(0.8)
|
||||
i+=1
|
9
EDGE_CODE/dht_22.py
Normal file
9
EDGE_CODE/dht_22.py
Normal file
@ -0,0 +1,9 @@
|
||||
import Adafruit_DHT
|
||||
|
||||
class dht22:
|
||||
def __init__(self):
|
||||
self.dht_sensor = Adafruit_DHT.DHT22
|
||||
self.dht_pin = 4
|
||||
|
||||
def get_humidity_temperature(self):
|
||||
return Adafruit_DHT.read_retry(self.dht_sensor, self.dht_pin)
|
143
EDGE_CODE/guard_node_device.py
Normal file
143
EDGE_CODE/guard_node_device.py
Normal file
@ -0,0 +1,143 @@
|
||||
import time
|
||||
import threading
|
||||
import glob
|
||||
import asyncio
|
||||
import websockets
|
||||
import buzzer
|
||||
import dht_22
|
||||
import audio_stream_classifier as a_s_c
|
||||
from multiprocessing import Process
|
||||
from os import listdir
|
||||
from os.path import isfile,join,getctime
|
||||
from scipy.io import wavfile
|
||||
from azure.iot.device import IoTHubDeviceClient, Message, MethodResponse
|
||||
|
||||
CONNECTION_STRING = "HostName=AgriHub.azure-devices.net;DeviceId=Guard_Node_00001;SharedAccessKey=8zv3Rh3zmTu7Eqw75TgTBJ/8Dtepc3JvIUum9yLzmvs="
|
||||
MSG_TXT = '{{"d":{d},"h":{h},"t":{t},"b":{b},"st":{st},"s":{sw},"g":{g},"w":{w},"f":{f},"p":{sp},"c":{c},"tem":{tem:0.1f},"hum":{hum:0.1f}}}'
|
||||
PATH='Last60Sample'
|
||||
INTERVAL = 15
|
||||
EXTRA_INTERVAL = 0
|
||||
STURNUS_ALERT = False
|
||||
WS_SERVER_URI= "ws://192.168.1.71:8765"
|
||||
|
||||
def iothub_client_init():
|
||||
client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
|
||||
return client
|
||||
|
||||
async def send_wav(file_name):
|
||||
print('Start Sending wav')
|
||||
try:
|
||||
async with websockets.connect(WS_SERVER_URI) as websocket:
|
||||
sr, x = wavfile.read(file_name)
|
||||
byte_message = x.tobytes()
|
||||
await websocket.send(byte_message)
|
||||
print("Wav sent")
|
||||
reply = await websocket.recv()
|
||||
print("Reply arrived:" + reply)
|
||||
except:
|
||||
print('Server unavailable!')
|
||||
|
||||
def start_recording():
|
||||
print ("Start Recording")
|
||||
a_s_c.start(1,"svm5ClassesAGRIREDUCED")
|
||||
print ("Recording Started")
|
||||
|
||||
def downlink_message_listener(device_client):
|
||||
while True:
|
||||
method_request = device_client.receive_method_request()
|
||||
print (
|
||||
"\nDownlink message arrived with with:\nmethodName = {method_name}".format(
|
||||
method_name=method_request.name
|
||||
)
|
||||
)
|
||||
if method_request.name == "RequestAudioSample":
|
||||
try:
|
||||
list_of_files = glob.glob("Last60Sample/*sturnus.wav")
|
||||
last_sturnus = max(list_of_files,key=getctime)
|
||||
asyncio.run(send_wav(file_name=last_sturnus))
|
||||
except ValueError:
|
||||
response_payload = {"Response": "Invalid parameter"}
|
||||
response_status = 400
|
||||
else:
|
||||
response_payload = {"Response": "Executed direct method {}".format(method_request.name)}
|
||||
response_status = 200
|
||||
elif method_request.name == "RequestAlert":
|
||||
try:
|
||||
global STURNUS_ALERT
|
||||
STURNUS_ALERT = True
|
||||
except ValueError:
|
||||
response_payload = {"Response": "Invalid parameter"}
|
||||
response_status = 400
|
||||
else:
|
||||
response_payload = {"Response": "Executed direct method {}".format(method_request.name)}
|
||||
response_status = 200
|
||||
else:
|
||||
response_payload = {"Response": "Direct method {} not defined".format(method_request.name)}
|
||||
response_status = 404
|
||||
|
||||
method_response = MethodResponse(method_request.request_id, response_status, payload=response_payload)
|
||||
device_client.send_method_response(method_response)
|
||||
|
||||
def iothub_client_telemetry():
|
||||
global STURNUS_ALERT
|
||||
global EXTRA_INTERVAL
|
||||
try:
|
||||
BUZZER = buzzer.Buzzer()
|
||||
DHT22 = dht_22.dht22()
|
||||
client = iothub_client_init()
|
||||
# Start a thread to listen downlink messages
|
||||
device_method_thread = threading.Thread(target=downlink_message_listener, args=(client,))
|
||||
device_method_thread.daemon = True
|
||||
device_method_thread.start()
|
||||
print("Waiting 60 seconds to fill the buffer")
|
||||
time.sleep(61)
|
||||
print ( "IoT Hub device sending periodic messages, press Ctrl-C to exit" )
|
||||
while True:
|
||||
only_files = [f[10:-4] for f in listdir(PATH) if isfile(join(PATH,f))]
|
||||
|
||||
DOG = only_files.count('dog')
|
||||
HOOPOE = only_files.count('hoopoe')
|
||||
TRACTOR = only_files.count('tractor')
|
||||
BLACKBIRD = only_files.count('blackbird')
|
||||
STURNUS = only_files.count('sturnus')
|
||||
SWALLOW = only_files.count('swallow')
|
||||
GOOSE = only_files.count('goose')
|
||||
WIND = only_files.count('wind')
|
||||
FIELD = only_files.count('field')
|
||||
SPARROW = only_files.count('sparrow')
|
||||
CRUSHAT = only_files.count('crushat')
|
||||
HUMIDITY, TEMPERATURE = DHT22.get_humidity_temperature()
|
||||
|
||||
msg_txt_formatted = MSG_TXT.format(d=DOG,h=HOOPOE,t=TRACTOR,b=BLACKBIRD,st=STURNUS,sw=SWALLOW,g=GOOSE,w=WIND,f=FIELD,sp=SPARROW,c=CRUSHAT,tem=TEMPERATURE,hum=HUMIDITY)
|
||||
message = Message(msg_txt_formatted)
|
||||
# Add a custom application property to the message.
|
||||
if STURNUS_ALERT == True:
|
||||
message.custom_properties["sturnus_alert"] = True
|
||||
BUZZER.beep()
|
||||
STURNUS_ALERT = False
|
||||
else:
|
||||
message.custom_properties["sturnus_alert"] = False
|
||||
# Send the message.
|
||||
print( "Sending message: {}".format(message) )
|
||||
client.send_message(message)
|
||||
print( "Message sent" )
|
||||
print( "Sleeping: ", (INTERVAL + EXTRA_INTERVAL))
|
||||
time.sleep(INTERVAL + EXTRA_INTERVAL)
|
||||
EXTRA_INTERVAL = 0
|
||||
if(STURNUS_ALERT):
|
||||
EXTRA_INTERVAL = 15
|
||||
except KeyboardInterrupt:
|
||||
print ( "IoTHubClient stopped" )
|
||||
|
||||
def runInParallel(*fns):
|
||||
proc = []
|
||||
for fn in fns:
|
||||
p = Process(target=fn)
|
||||
p.start()
|
||||
proc.append(p)
|
||||
for p in proc:
|
||||
p.join()
|
||||
|
||||
if __name__ == '__main__':
|
||||
print ( "Press Ctrl-C to exit" )
|
||||
runInParallel(start_recording, iothub_client_telemetry)
|
Loading…
Reference in New Issue
Block a user