def setup(): global Network, lora global sleep_time, STOP, myId global dust, meteo, thisGPS, useGPS display("MySense V %s" % __version__[:6], (0,0), clear=True) display("s/n " + myID) display("PM : " + Dust[dust]) display("meteo: " + Meteo[meteo]) if useGPS: display('G:%.4f/%.4f' % (thisGPS[LAT],thisGPS[LON])) sleep(15) if Network == 'TTN': # Connect to LoRaWAN display("Try LoRaWan", (0,0), clear=True) display("LoRa App EUI:") display(str(app_eui)) lora = LORA() if lora.connect(dev_eui,app_eui,app_key, ports=2, callback=CallBack): display("Joined LoRaWan") SendInfo() else: display("NOT joined LoRa!") lora = None Network = 'None' sleep(10) if Network == 'None': display("No network!", (0,0), clear=True) LED.blink(10,0.3,0xff00ff,True) # raise OSError("No connectivity") display("Setup done")
def send(self, data, port=2): """ Send data over the network. """ if (port < 2) or (port > len(self.s)): raise ValueError('Unknown LoRa port') if not self.s[port]: raise OSError('No socket') rts = True try: self.s[port].send(data) LED.blink(2, 0.1, 0x0000ff) # print("Sending data") # print(data) except OSError as e: if e.errno == 11: print("Caught exception while sending") print("errno: ", e.errno) rts = False LED.off() data = self.s[port].recv(64) # print("Received data:", data) if self.callback and data: self.callback(port, data) return rts
def runMe(): global lora, sleep_time, oled global useDust setup() # Setup network & sensors while True: toSleep = time() dData = DoDust() mData = DoMeteo() # Send packet if lora != None: if lora.send(DoPack(dData,mData,LocUpdate())): LED.off() else: display(" LoRa send ERROR") LED.blink(5,0.2,0x9c5c00,False) toSleep = sleep_time - (time() - toSleep) if useDust: if toSleep > 30: toSleep -= 15 useDust.Standby() # switch off laser and fan elif toSleep < 15: toSleep = 15 if not ProgressBar(0,63,128,2,toSleep,0xebcf5b,10): display('stopped SENSING', (0,0), clear=True) LED.blink(5,0.3,0xff0000,True) if STOP: sleep(60) oled.poweroff() # and put ESP in deep sleep: machine.deepsleep() return False
def ProgressBar(x,y,width,height,secs,blink=0,slp=1): global oled, LED, STOP if not oled: return rectangle(x,y,width,height) if (height > 4) and (width > 4): rectangle(x+1,y+1,width-2,height-2,0) x += 2; width -= 4; y += 2; height -= 4 elif width > 4: rectangle(x+1,y,width-2,height,0) x += 2; width -= 4; else: rectangle(x,y,width,height,0) step = width/(secs/slp); xe = x+width; myslp = slp if blink: myslp -= (0.1+0.1) for sec in range(int(secs/slp+0.5)): if STOP: return False if blink: LED.blink(1,0.1,blink,False) sleep(myslp) if x > xe: continue rectangle(x,y,step,height) oled.show() x += step return True
def DoDust(): global useDust, Dust, dust, nl, STOP, STOPPED, useGPS, lastGPS dData = {} display('PM sensing',(0,0),clear=True,prt=False) if useDust and (useDust.mode != useDust.NORMAL): useDust.Normal() if not showSleep(secs=15,text='starting up fan'): display('stopped SENSING', (0,0), clear=True) LED.blink(5,0.3,0xff0000,True) return [0,0,0] else: if useGPS != None: display("G:%.4f/%.4f" % (lastGPS[LAT],lastGPS[LON])) display('measure PM') if useDust: LED.blink(3,0.1,0x005500) # display('%d sec sample' % sample_time,prt=False) try: STOPPED = False try: SleepThread(sample_time,'%d sec sample' % sample_time) except: STOPPED = True display('%d sec sample' % sample_time) dData = useDust.getData() for cnt in range(10): if STOPPED: break STOP = True print('waiting for thread') sleep(2) STOP = False except Exception as e: display("%s ERROR" % Dust[dust]) print(e) LED.blink(3,0.1,0xff0000) dData = {} LED.blink(3,0.1,0x00ff00) if len(dData): for k in dData.keys(): if dData[k] == None: dData[k] = 0 try: if 'pm1' in dData.keys(): # and dData['pm1'] > 0: display(" PM1 PM2.5 PM10", (0,0), clear=True) display("% 2.1f % 5.1f% 5.1f" % (dData['pm1'],dData['pm25'],dData['pm10'])) else: display("ug/m3 PM2.5 PM10", (0,0), clear=True) display(" % 5.1f % 5.1f" % (dData['pm25'],dData['pm10'])) dData['pm1'] = 0 except: dData = {} if not dData: display("No PM values") LED.blink(5,0.1,0xff0000,True) dData = [0,0,0] else: dData = [round(dData['pm1'],1),round(dData['pm25'],1),round(dData['pm10'],1)] LED.off() return dData
def connect(self, dev_eui, app_eui, app_key, ports=1, callback=None): """ Connect device to LoRa. Set the socket and lora instances. """ dev_eui = unhexlify(dev_eui) app_eui = unhexlify(app_eui) app_key = unhexlify(app_key) self.callback = callback # call back routine on LoRa reply callback(port,response) # Disable blue blinking and turn LED off LED.heartbeat(False) LED.off() # Initialize LoRa in LORAWAN mode self.lora = LoRa(mode=LoRa.LORAWAN) # Join a network using OTAA (Over the Air Activation) self.lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) # Wait until the module has joined the network count = 0 while not self.lora.has_joined(): LED.blink(1, 2.5, 0xff0000) if count > 20: return False print("Trying to join: ", count) count += 1 # Create a LoRa socket LED.blink(2, 0.1, 0x009900) self.s = [] self.s.append(socket.socket(socket.AF_LORA, socket.SOCK_RAW)) # Set the LoRaWAN data rate self.s[0].setsockopt(socket.SOL_LORA, socket.SO_DR, 5) # Make the socket non-blocking self.s[0].setblocking(False) print("Success after %d tries" % count) # print("Create LoRaWAN socket") # Create a raw LoRa socket # default port 2 self.s.append(None) for nr in range(ports): print("Setting up port %d" % (nr + 2)) self.s.append(socket.socket(socket.AF_LORA, socket.SOCK_RAW)) self.s[nr + 2].setblocking(False) if nr: self.s[nr + 2].bind(nr + 2) LED.off() return True
def handle(self): req_raw = self.request.recv(1024) self.logger.debug("Recv from:{0}, data:{1}".format( self.client_address, req_raw)) try: req = json.loads(req_raw) except Exception: self.logger.exception( "Failed to parse request: {0}".format(req_raw)) socket.sendto(json.dumps({ "code": -1, "data": "Error" }), self.client_address) return if req['cmd'] == 'led-control': data = req['data'] led = LED(LED_NAMES.get(data['led-name'].upper())) if data['op'].lower() == 'blink': if led.blink(count=data.get('count', 1), delay=data.get('delay', 0.5)): self.request.sendall(json.dumps({"code": 0, "data": "OK"})) else: self.request.sendall( json.dumps({ "code": 1, "data": "FAIL" })) elif req['cmd'] == 'quit': tcp_stop_event.set() self.request.sendall(json.dumps({"code": 1, "data": "OK"})) self.logger.debug("Request handled.")
def connect(self, dev_eui, app_eui, app_key): """ Connect device to LoRa. Set the socket and lora instances. """ dev_eui = unhexlify(dev_eui) app_eui = unhexlify(app_eui) app_key = unhexlify(app_key) # Disable blue blinking and turn LED off LED.heartbeat(False) LED.off() # Initialize LoRa in LORAWAN mode self.lora = LoRa(mode=LoRa.LORAWAN) # Join a network using OTAA (Over the Air Activation) self.lora.join(activation=LoRa.OTAA, auth=(dev_eui, app_eui, app_key), timeout=0) # Wait until the module has joined the network count = 0 while not self.lora.has_joined(): LED.blink(1, 2.5, 0xff0000) # print("Trying to join: " , count) count = count + 1 # Create a LoRa socket LED.blink(2, 0.1) self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) # Set the LoRaWAN data rate self.s.setsockopt(socket.SOL_LORA, socket.SO_DR, 5) # Make the socket non-blocking self.s.setblocking(False) # print ("Joined! ", count) # print("Create LoRaWAN socket") # Create a raw LoRa socket self.s = socket.socket(socket.AF_LORA, socket.SOCK_RAW) self.s.setblocking(False)
def send(self, data): """ Send data over the network. """ try: self.s.send(data) LED.blink(2, 0.1, 0x00ff00) print("Sending data:") print(data) except OSError as e: if e.errno == 11: print("Caught exception while sending") print("errno: ", e.errno) LED.off() data = self.s.recv(64) print("Received data:", data) return data
import time import logging from led import LED_NAMES, LED from server import Server logging.basicConfig(level=logging.DEBUG) if __name__ == "__main__": print("Initializing...") led_usr1 = LED(LED_NAMES.USR1) print("blinking 'usr1'") s1 = led_usr1.blink() led_usr2 = LED(LED_NAMES.USR2) print("blinking 'usr2'") s2 = led_usr2.blink() if not (s1 and s2): print("Initialization failed") exit(-1) Server.start_all("config.json")
class LEDWeather: def __init__(self): self._show_timeout = 0 self._first_update = True self._led = LED(Pins.RED, Pins.GREEN, Pins.BLUE) self._led.blink((1, 0, 0)) self._simple = Geoclue.Simple.new('geoclue-where-am-i', # Let's cheat Geoclue.AccuracyLevel.EXACT, None, self._on_simple_ready) def close(self): self._unshedule_weather_show() self._led.close() def _on_simple_ready(self, simple, data): location = simple.get_location() self._on_location_updated(location) def _on_location_updated(self, location): latitude = location.get_property('latitude') longitude = location.get_property('longitude') world = GWeather.Location.get_world() city = world.find_nearest_city(latitude, longitude) self.info = GWeather.Info.new(city, GWeather.ForecastType.LIST) self.info.set_enabled_providers(GWeather.Provider.METAR | GWeather.Provider.YR_NO) self.info.connect('updated', self._on_weather_updated, None) self._update_timeout = GLib.timeout_add_seconds(3600, self._on_weather_update_timeout) def _on_weather_update_timeout(self): self._unshedule_weather_show() self._led.blink((1, 0, 0)) self.info.update() return True def _on_weather_updated(self, info, data): self._unshedule_weather_show() self._index = 0 if self._first_update: self._show_weather() self._first_update = False else: self._show_timeout = GLib.timeout_add_seconds(5, self._on_show_weather_timeout) def _on_show_weather_timeout(self): self._show_timeout = 0 forecast_time = self._get_current_forecast_time() n_blinks = round((forecast_time - time.time()) / 12 / 3600) if n_blinks > 0: self._led.blink((0, 1, 0), n_blinks, self._show_weather) else: self._show_weather() return False def _show_weather(self): forecasts = self.info.get_forecast_list() current_time = self._get_current_forecast_time() if self._index >= len(forecasts) or current_time >= time.time() + 3600 * 72: self._index = 0 self._led.show_weather(None) self._show_timeout = GLib.timeout_add_seconds(5, self._on_show_weather_timeout) return False current_time = self._get_current_forecast_time() str = time.strftime("%c", time.gmtime(current_time)) print("Weather at %s" % str) if self._index == 0: self._led.show_weather(self.info) else: self._led.show_weather(forecasts[self._index]) self._set_next_index() self._show_timeout = GLib.timeout_add_seconds(5, self._on_show_weather_timeout) return False def _set_next_index(self): forecasts = self.info.get_forecast_list() current_time = self._get_current_forecast_time() index = self._index next_index = -1 while index < len(forecasts): [ret, timestamp] = forecasts[index].get_value_update() if ret and timestamp >= current_time + 3600 * 12: next_index = index break else: index = index + 1 if next_index == -1: self._index = 0 else: self._index = next_index def _get_current_forecast_time(self): if self._index == 0: return time.time() forecasts = self.info.get_forecast_list() [ret, timestamp] = forecasts[self._index].get_value_update() if not ret: # Shouldn't be happening but let's be prepared return time.time() return timestamp def _unshedule_weather_show(self): if self._show_timeout == 0: return GLib.source_remove(self._show_timeout) self._show_timeout = 0
grovepi.pinMode(buzzer,"OUTPUT") while True: try: # Buzz for 1 second grovepi.digitalWrite(buzzer,1) print ('start') time.sleep(1) # Stop buzzing for 1 second and repeat grovepi.digitalWrite(buzzer,0) print ('stop') time.sleep(1) except KeyboardInterrupt: grovepi.digitalWrite(buzzer,0) break except IOError: print ("Error") led = LED(3) t = 0.02 d = 0.01 while t>=d: print t led.blink(100, t) t = t-d
def DoMeteo(): global useMeteo, nl, LF global Meteo, meteo global M_SDA, M_SCL mData = [0,0,0,0,0]; sData = "" if not useMeteo or not meteo: return mData # Measure temp oC, rel hum %, pres pHa, gas Ohm, aqi % LED.blink(3,0.1,0x002200,False) error = None try: nr = indexBus(i2cPINs,i2c,(M_SDA,M_SCL)) if (meteo == 4) and (not useMeteo.gas_base): # BME680 display("AQI base: wait"); nl -= LF i2c[nr].init(nr, pins=i2cPINs[nr]) # SPI oled causes bus errors sleep(1) try: mData[TEMP] = float(useMeteo.temperature) # string '20.12' sData += "%4.1f " % round(mData[TEMP],1) except: mData[TEMP] = 0; error = TEMP sData += " ? " try: mData[HUM] = float(useMeteo.humidity) # string '25' sData += "%2d " % round(mData[HUM]) except: mData[HUM] = 0; error = HUM sData += " ? " try: mData[PRES] = float(useMeteo.pressure) # string '1021.60' sData += "%4d " % round(mData[PRES]) except: mData[PRES] = 0; error = PRES sData += " ? " if meteo == 4: # BME680 try: mData[GAS] = float(useMeteo.gas) # Ohm 29123 # sData += "%4.1f " % round(mData[GAS]/1000.0,1) except: mData[GAS] = 0; error = GAS #sData += " ? " try: mData[AQI] = round(float(useMeteo.AQI),1) # 0-100% ok sData += "%2d" % round(mData[AQI]) except: mData[AQI] = 0; error = AQI sData += " ?" rectangle(0,nl,128,LF,0) except Exception as e: display("%s ERROR" % Meteo[meteo]) print(e) LED.blink(5,0.1,0xff00ff,True) return [0,0,0,0,0] if error != None: print("no value for %s" % ['oC','RH','hPa','gas','AQI'][error]) LED.blink(5,0.1,0xff0099,True) LED.off() nl += 6 # oled spacing display(" C hum%% pHa%s" % (' AQI' if mData[GAS] > 0 else '')) display("o",(8,-5),prt=False) display(sData) return mData # temp, hum, pres, gas, aqia
else: rectangle(x, y, width, height, 0) step = width / (secs / slp) xe = x + width myslp = slp if blink: myslp -= (0.1 + 0.1) for sec in range(int(secs / slp + 0.5)): if blink: LED.blink(1, 0.1, blink, False) sleep(myslp) if x > xe: continue rectangle(x, y, step, height) if oled: oled.show() x += step return True try: # Turn off hearbeat LED pycom.heartbeat(False) display('test bar', 0, 0, True) if not ProgressBar(0, 44, 128, 8, 10, 0xebcf5b, 1): LED.blink(5, 0.3, 0xff0000, True) else: LED.blink(5, 0.3, 0x00ff00, False) display("MySense PyCom", 0, 0, True) myID = binascii.hexlify(unique_id()).decode('utf-8') display("s/n " + myID, 0, 16, False) except: print("Failed")
from led import LED ledYellow = LED(15, "Red") ledYellow.blink(0.5, 3)
class ListenIn(object): def __init__(self, token, duration, interval, retrytime, last_uploaded_file): self.token = token self.duration = duration self.interval = interval self.retrytime = retrytime self.last_uploaded_file = last_uploaded_file self.led = LED(red=13, green=19, blue=26, initial_color='white') self._q = Queue() self.default_blink_interval = (5, 300) self.fast_blinking = (0.5, 500) def start_blinker(self): self._blinker_stop = Event() self._blinker_thread = Thread(target=self.blink_periodically) self._blinker_thread.start() def stop_blinker(self): self._blinker_stop.set() self._blinker_thread.join() def blink_periodically(self): last_blink_time = time.time() interval, duration = self.default_blink_interval while True: if self._blinker_stop.isSet(): break try: interval, duration = self._q.get_nowait() except Empty: pass if time.time() - last_blink_time > interval: self.led.blink(duration=duration) last_blink_time = time.time() time.sleep(0.1) def write_last_uploaded_ts(self): try: tmp_file = self.last_uploaded_file + '.tmp' open(tmp_file, 'w').write(str(int(time.time()))) os.rename(tmp_file, self.last_uploaded_file) except Exception: pass def listen(self): self.start_blinker() while True: try: logging.info('waiting for audio signal') self.led.set('purple') r = self.record_sample() next(r) logging.info('recording') self.led.set('red') sample = next(r) logging.info('uploading') self.led.set('blue') t0 = time.time() self.upload_sample(sample) except Exception as e: logging.error('%s: %s', e.__class__.__name__, e) self.led.set('orange') self._q.put(self.fast_blinking) time.sleep(self.retrytime) self._q.put(self.default_blink_interval) else: self.write_last_uploaded_ts() logging.info('sample recorded and uploaded, sleeping for %d seconds', self.interval) self.led.set('green') sleep_time = self.interval - (time.time() - t0) if sleep_time >= 0: time.sleep(sleep_time) def record_sample(self): output_file = '/tmp/output.mp3' processed_file = '/tmp/processed.mp3' downsampled_output_file = '/tmp/downsampled.1c.8k.flac' for f in output_file, downsampled_output_file: if os.path.exists(f): os.unlink(f) rec_cmd = 'rec --no-show-progress -t mp3 -C 0 {} highpass 60 silence 1 0.1 -35d 1 2.0 -35d trim 0 {}'.format( output_file, self.duration, ) rec_process = subprocess.Popen(rec_cmd.split()) while True: rc = rec_process.poll() if rc is not None: break try: if os.path.getsize(output_file) > 0: break except OSError: pass time.sleep(0.1) if rc is None: yield rc = rec_process.wait() if rc != 0: raise RuntimeError('failed to record: return code = {}'.format(rc)) normalize_cmd = 'sox --norm {} {}'.format(output_file, processed_file) subprocess.check_call(normalize_cmd.split()) downsample_cmd = 'sox {} -r 8000 -b 16 -c 1 {}'.format(processed_file, downsampled_output_file) subprocess.check_call(downsample_cmd.split()) w = Wave(downsampled_output_file) if w.length < self.duration: raise RuntimeError('sample duration too short ({}<{})'.format(w.length, self.duration)) if w.is_silence: raise RuntimeError('sample is silent') if w.is_noise: raise RuntimeError('sample is 50hz hum') yield open(processed_file).read() def assert_sample_is_valid(self, sample_file): pass def upload_sample(self, sample): url = 'http://api.listenin.io/upload?token={}'.format(self.token) requests.post(url, data=sample, timeout=60).raise_for_status() def cleanup(self): self.stop_blinker()