def media_upload(files) : """Save file to SD card.""" log.info('Upload file') result = 0 for file in files: # Check if the file is one of the allowed types/extensions if file and allowed_file(file.filename): # Make the filename safe, remove unsupported chars filename = secure_filename(file.filename) # Move the file form the temporal folder to the upload # folder we setup try : file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) log.debug('file saved : %s',filename) result = result + 1 except UploadNotAllowed: log.error('file too large : %s',filename) else: log.warning('file not allowed : %s',filename) # Reload all song on playlist subprocess.call('mpc clear; mpc add %s; mpc update',app.config['UPLOAD_FOLDER']) log.debug('result : %s',result) return result
def mvt_counter(channel): """Incremente mvt conter on each call from GPIO triggering. @Imput . @Return . """ log.info('Incremente mvt conter') g.mvt_counter = g.mvt_counter + 1 log.debug('mvt_counter : %d', g.mvt_counter)
def mvt_counter(channel): """Incremente mvt conter on each call from GPIO triggering. @Imput . @Return . """ log.info("Incremente mvt conter") g.mvt_counter = g.mvt_counter + 1 log.debug("mvt_counter : %d", g.mvt_counter)
def agitation_ctr_exe(): """Agitation controller task. @Imput . @Return . """ log.info('Agitation controller task') with app.app_context(): signal.setitimer(signal.ITIMER_PROF, 60, 60) agitation_detect()
def agitation_ctr_exe(): """Agitation controller task. @Imput . @Return . """ log.info("Agitation controller task") with app.app_context(): signal.setitimer(signal.ITIMER_PROF, 60, 60) agitation_detect()
def agitation_count(): """Retreive number of mvt per minute and store it on db. @Imput . @Return . """ log.info('Retreive number of mvt per minute') log.debug('mvt_counter : %d', g.mvt_counter) db['mvt_count'] = g.mvt_counter g.mvt_counter = 0
def agitation_count(): """Retreive number of mvt per minute and store it on db. @Imput . @Return . """ log.info("Retreive number of mvt per minute") log.debug("mvt_counter : %d", g.mvt_counter) db["mvt_count"] = g.mvt_counter g.mvt_counter = 0
def terminate(): """Free resources. @Imput . @Return . """ log.info('Free resources') signal.alarm(0) GPIO.cleanup() exit(0)
def agitation_detect(): """Detect agitation from GPIO and call mvt_counter. @Imput . @Return . """ log.info("Set GPIO") GPIO.setmode(GPIO.BCM) # GPIO 24 set up as an input, pulled down, connected to 3V3 on button press GPIO.setup(app.config["GPIO_CHANNEL"], GPIO.IN, pull_up_down=GPIO.PUD_DOWN) GPIO.add_event_detect(app.config["GPIO_CHANNEL"], GPIO.RISING, callback=mvt_counter, bouncetime=300)
def terminate(): """Free resources. @Imput . @Return . """ log.info("Free resources") signal.alarm(0) GPIO.cleanup() exit(0)
def agitation_detect(): """Detect agitation from GPIO and call mvt_counter. @Imput . @Return . """ log.info('Set GPIO') GPIO.setmode(GPIO.BCM) # GPIO 24 set up as an input, pulled down, connected to 3V3 on button press GPIO.setup(app.config['GPIO_CHANNEL'], GPIO.IN, pull_up_down=GPIO.PUD_DOWN) GPIO.add_event_detect(app.config['GPIO_CHANNEL'], GPIO.RISING, callback=mvt_counter, bouncetime=300)
def steam_ctr_stop() : """Stop streamer. @Imput . @Return result. """ log.info('Stop streamer') try : check_call(["./Streamer.sh","Stop"]) result = 'Success' except CalledProcessError as e: log.exception('gst stop error : %s',e.returncode) result = 'Error' return result
def activity_ctr_exe(): """Activity controller task. @Imput . @Return . """ log.info("Activity controller task") g.refresh_count1 = 0 g.refresh_count2 = 0 # Set the signal handler signal.signal(signal.SIGTERM, handler) signal.signal(signal.SIGALRM, handler) # setup periodic alarm to evaluate sound level and set agitation level signal.alarm(app.config["REFRESH_RATE"])
def activity_ctr_exe(): """Activity controller task. @Imput . @Return . """ log.info('Activity controller task') g.refresh_count1 = 0 g.refresh_count2 = 0 # Set the signal handler signal.signal(signal.SIGTERM, handler) signal.signal(signal.SIGALRM, handler) # setup periodic alarm to evaluate sound level and set agitation level signal.alarm(app.config['REFRESH_RATE'])
def steam_ctr_restart() : """Restart streamer. @Imput . @Return result. """ log.info('Restart Streamer') result = 'Error' try : check_call(["./Streamer.sh","Restart"]) result = 'Success' except CalledProcessError as e: log.exception('gst restart error : %s',e.returncode) result = 'Error' return result
def media_VolDown() : """Volume down.""" log.info('Volume Down') try : subprocess.call('mpc volume - ') log.debug('Volume decreased') result = 'Success' except subprocess.CalledProcessError : # file not deleted log.error('Volume decrease error') log.warning('Return code : %s',subprocess.CalledProcessError.returncode) result = 'Error' log.debug('result : %s',result) return result
def media_Play() : """Play playlist songs.""" log.info('Play songs') try : subprocess.call('mpc play ') log.debug('Play') result = 'Success' except subprocess.CalledProcessError : # file not deleted log.error('Play error') log.warning('Return code : %s',subprocess.CalledProcessError.returncode) result = 'Error' log.debug('result : %s',result) return result
def handler(signum, frame): """Signals handler. SIGTERM to stop controller gracefully SIGALRM handle activity controller alarm SIGPROF handle agitation @Imput . @Return . """ log.info('Signals handler') log.debug('signal : %d', signum) if (signum == signal.SIGTERM): terminate() elif (signum == signal.SIGALRM): activity_check() elif (signum == signal.SIGPROF): agitation_count()
def normal_levels(agi_normal): """Calibrate the normal level to actual sound level. @Imput . @Return . """ log.info("Calibration") try: db["agi_normal"] = agi_normal db["lvl_normal"] = sound_level() log.debug("agi_normal : %s", agi_normal) log.debug("lvl_normal : {:10.4f}".format(db["lvl_normal"])) result = "Success" except: log.exception("Calibration error ") result = "Error" return result
def handler(signum, frame): """Signals handler. SIGTERM to stop controller gracefully SIGALRM handle activity controller alarm SIGPROF handle agitation @Imput . @Return . """ log.info("Signals handler") log.debug("signal : %d", signum) if signum == signal.SIGTERM: terminate() elif signum == signal.SIGALRM: activity_check() elif signum == signal.SIGPROF: agitation_count()
def normal_levels(agi_normal): """Calibrate the normal level to actual sound level. @Imput . @Return . """ log.info('Calibration') try: db['agi_normal'] = agi_normal db['lvl_normal'] = sound_level() log.debug('agi_normal : %s', agi_normal) log.debug("lvl_normal : {:10.4f}".format(db['lvl_normal'])) result = 'Success' except: log.exception('Calibration error ') result = 'Error' return result
def media_list() : """List song files.""" log.info('List songs') try : #TODO : list command titles = subprocess.check_output('') log.debug('Playlist titles : %s',titles) titles = titles.splitlines() result = titles except subprocess.CalledProcessError : # file not deleted log.error('list error') log.warning('Return code : %s',subprocess.CalledProcessError.returncode) result = 'Error' log.debug('result : %s',result) return result
def media_ctr() : """Control media center. @Imput command : [Upload,Delete,List,Play,Stop,VolUp,VolDown]. titles. @Return result : [%d,list,Success,Error]. """ log.info('media_ctr BEGIN') # Get the JSON data sent from the form data = request.get_json(force=True) log.info(data['command']) if (data['command'] == 'Upload') : result = media_upload(request.files.getlist("file[]")) elif (data['command'] == 'Delete') : result = media_del(data['titles']) elif (data['command'] == 'List') : result = media_list() elif (data['command'] == 'Play') : result = media_Play() elif (data['command'] == 'Stop') : result = media_Stop() elif (data['command'] == 'VolUp') : result = media_VolUp() elif (data['command'] == 'VolDown') : result = media_VolDown() else : log.warning('invalid command') result = 'None' log.debug(result) log.info('media_ctr END') return jsonify(result=result)
def stream_ctr() : """Control streamer. @Imput command : [Start,Stop,Restart]. @Return result : [Success,Error,None]. """ log.info('stream_ctr BEGIN') # Get the JSON data sent from the form data = request.get_json(force=True) log.info(data['command']) if (data['command'] == 'Start') : result = steam_ctr_start() elif (data['command'] == 'Stop') : result = steam_ctr_stop() elif (data['command'] == 'Restart') : result = steam_ctr_restart() else : log.warning('invalid command') result = 'None' log.debug(result) log.info('stream_ctr END') return jsonify(result=result)
def media_del(files) : """Delete file from SD card and reload playlist.""" log.info('Delete file') result = 0 for file in files: try : #delete file from directory subprocess.call('rm -f %s',file) log.debug('file deleted : %s',file) result = result + 1 except subprocess.CalledProcessError : # file not deleted log.error('file not deleted') log.warning('Return code : %s',subprocess.CalledProcessError.returncode) # Reload all song on playlist subprocess.call('mpc clear; mpc add %s; mpc update',app.config['UPLOAD_FOLDER']) log.debug('result : %s',result) return result
def sound_level(): """calculate sound level. @Imput . @Return energy. """ log.info('calculate sound level') # # set up audio input card = CARD recorder = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, card) recorder.setchannels(CHANNELS) recorder.setrate(RATE) recorder.setformat(INFORMAT) recorder.setperiodsize(FRAMESIZE) [length, data] = recorder.read() log.debug('length : %f', length) volume = audioop.max(data, 2) log.debug("volume : %f", volume) volume = audioop.rms(data, 2) log.debug("volume : %f", volume) return volume
def sound_level(): """calculate sound level. @Imput . @Return energy. """ log.info("calculate sound level") # # set up audio input card = CARD recorder = alsaaudio.PCM(alsaaudio.PCM_CAPTURE, alsaaudio.PCM_NORMAL, card) recorder.setchannels(CHANNELS) recorder.setrate(RATE) recorder.setformat(INFORMAT) recorder.setperiodsize(FRAMESIZE) [length, data] = recorder.read() log.debug("length : %f", length) volume = audioop.max(data, 2) log.debug("volume : %f", volume) volume = audioop.rms(data, 2) log.debug("volume : %f", volume) return volume
def activity_ctr() : """Control activity. @Imput command : [Start,Stop,Calibrate]. agi_normal (decimal). @Return result : [In progress,Success,Stoped,Error,None]. """ log.info('activity_ctr BEGIN') # Get the JSON data sent from the form data = request.get_json(force=True) log.info(data['command']) if (data['command'] == 'Start') : result = 'Error' if ((db.has_key('act_job_id')) and (db['act_job_id'] != '')) : result = 'In progress' else : # Start the agitation controller agi_job = agitation_ctr_exe.delay() result = agi_job.AsyncResult(agi_job.id).state if (result == states.SUCCESS) : # Start the activity controller act_job = activity_ctr_exe.delay() result = act_job.AsyncResult(act_job.id).state if (result == states.SUCCESS) : result = 'Success' db['act_job_id'] = act_job.AsyncResult(act_job.id).id elif (data['command'] == 'Stop') : result = 'Error' if ((not db.has_key('act_job_id')) or (db['act_job_id'] == '')) : result = 'Stoped' else : # Stop the activity controller revoke(act_job.id, terminate=True, signal='SIGTERM') result = act_job.AsyncResult(act_job.id).state if (result == states.REVOKED) : # Stop the agitation controller revoke(agi_job.id, terminate=True, signal='SIGTERM') result = agi_job.AsyncResult(agi_job.id).state if (result == states.REVOKED) : result = 'Success' db['act_job_id'] = '' elif (data['command'] == 'Calibrate') : # Calibrate the normale sound level result = normal_levels(data['agi_normal']) #TODO : adjust intervals else : log.warning('invalid command') result = 'None' log.debug(result) log.info('activity_ctr END') return jsonify(result=result)
def activity_check(): """Evaluate sound and agitation level. @Imput . @Return . """ log.info('Evaluate sound and agitation level') energy = sound_level() if (energy < db['lvl_normal']): # Quiet state log.debug('Quiet state') # We reset timer counter for agitation g.refresh_count1 = 0 g.refresh_count2 = 0 elif ((energy >= db['lvl_normal']) and (energy < db['lvl_normal'] + db['normal_interval'])): # Normal state log.debug('Normal state') g.refresh_count2 = 0 # If agitation stay higher than normal for a configurable periode if (db['mvt_count'] > db['agi_normal']) and ( g.refresh_count1 > app.config['REFRESH_COUNT']): log.debug('if-refresh_count1 : %s', g.refresh_count1) # We reduce the normal level db['lvl_normal'] = db['lvl_normal'] * ( app.config['REDUCTION_RATE'] / 100) log.debug('new lvl_normal : %s', db['lvl_normal']) g.refresh_count1 = 0 # If agitation is higher we increment timer counter elif (db['mvt_count'] > db['agi_normal']): g.refresh_count1 = g.refresh_count1 + 1 log.debug('elif-refresh_count1 : %s', g.refresh_count1) # If agitation return to normal we reset timer counter else: g.refresh_count1 = 0 log.debug('else-refresh_count1 : %s', g.refresh_count1) elif ((energy >= db['lvl_normal'] + db['normal_interval']) and (energy < db['lvl_normal'] + db['normal_interval'] + db['active_interval'])): # Active state log.debug('Active state') # We reset timer counter for agitation g.refresh_count1 = 0 # If active period is higher than a configurable periode if (g.refresh_count2 > app.config['REFRESH_COUNT']): log.debug('if-refresh_count2 : %s', g.refresh_count2) #TODO : If agitation is higher we send silent notification # if (db['mvt_count'] > db['agi_normal']) : # We increase the normal level db['lvl_normal'] = db['lvl_normal'] * ( 1 + (app.config['INCREASE_RATE'] / 100)) log.debug('new lvl_normal : %s', db['lvl_normal']) g.refresh_count2 = 0 else: g.refresh_count2 = g.refresh_count2 + 1 log.debug('else-refresh_count2 : %s', g.refresh_count2) elif (energy >= db['lvl_normal'] + db['normal_interval'] + db['active_interval']): # Criying state log.debug('Criying state') # We reset timer counter for agitation g.refresh_count1 = 0 g.refresh_count2 = 0
def activity_check(): """Evaluate sound and agitation level. @Imput . @Return . """ log.info("Evaluate sound and agitation level") energy = sound_level() if energy < db["lvl_normal"]: # Quiet state log.debug("Quiet state") # We reset timer counter for agitation g.refresh_count1 = 0 g.refresh_count2 = 0 elif (energy >= db["lvl_normal"]) and (energy < db["lvl_normal"] + db["normal_interval"]): # Normal state log.debug("Normal state") g.refresh_count2 = 0 # If agitation stay higher than normal for a configurable periode if (db["mvt_count"] > db["agi_normal"]) and (g.refresh_count1 > app.config["REFRESH_COUNT"]): log.debug("if-refresh_count1 : %s", g.refresh_count1) # We reduce the normal level db["lvl_normal"] = db["lvl_normal"] * (app.config["REDUCTION_RATE"] / 100) log.debug("new lvl_normal : %s", db["lvl_normal"]) g.refresh_count1 = 0 # If agitation is higher we increment timer counter elif db["mvt_count"] > db["agi_normal"]: g.refresh_count1 = g.refresh_count1 + 1 log.debug("elif-refresh_count1 : %s", g.refresh_count1) # If agitation return to normal we reset timer counter else: g.refresh_count1 = 0 log.debug("else-refresh_count1 : %s", g.refresh_count1) elif (energy >= db["lvl_normal"] + db["normal_interval"]) and ( energy < db["lvl_normal"] + db["normal_interval"] + db["active_interval"] ): # Active state log.debug("Active state") # We reset timer counter for agitation g.refresh_count1 = 0 # If active period is higher than a configurable periode if g.refresh_count2 > app.config["REFRESH_COUNT"]: log.debug("if-refresh_count2 : %s", g.refresh_count2) # TODO : If agitation is higher we send silent notification # if (db['mvt_count'] > db['agi_normal']) : # We increase the normal level db["lvl_normal"] = db["lvl_normal"] * (1 + (app.config["INCREASE_RATE"] / 100)) log.debug("new lvl_normal : %s", db["lvl_normal"]) g.refresh_count2 = 0 else: g.refresh_count2 = g.refresh_count2 + 1 log.debug("else-refresh_count2 : %s", g.refresh_count2) elif energy >= db["lvl_normal"] + db["normal_interval"] + db["active_interval"]: # Criying state log.debug("Criying state") # We reset timer counter for agitation g.refresh_count1 = 0 g.refresh_count2 = 0