def init(): global __led if __led != None or PIN_LED <= 0: return __led = NeoPixel(Pin(PIN_LED, Pin.OUT), 1) __led.fill((0, 0, 0)) __led.write()
class Rgb(NeoPixel): def __init__(self, pin, num=1): self.pin = pin self.num = num self.np = NeoPixel(Pin(self.pin, Pin.OUT), self.num) # self.np = super().__init__(Pin(self.pin, Pin.OUT), self.num) def simpleTest(self, wait_ms=500): self.np[0] = RED self.np.write() sleep_ms(wait_ms) self.np[0] = GREEN self.np.write() sleep_ms(wait_ms) self.np[0] = BLUE self.np.write() sleep_ms(wait_ms) self.np[0] = (0, 0, 0) self.np.write() def color(self, color=RED, i=0): self.np[i] = color self.np.write() def color_chase(self, np, num_pixels, color, wait): for i in range(self.num): self.np[i] = color self.np.write() sleep(wait) def rainbow_cycle(self, wait=3, intensity=2): for j in range(255): for i in range(self.num): rc_index = (i * 256 // self.num) + j self.np[i] = wheel(rc_index & 255, dev=intensity) self.np.write() sleep_ms(wait) def test(self): #https://github.com/maxking/micropython/blob/master/rainbow.py self.simpleTest() self.color_chase( self.np, self.num, RED, 0.1) # Increase the number to slow down the color chase self.color_chase(self.np, self.num, YELLOW, 0.1) self.color_chase(self.np, self.num, GREEN, 0.1) self.color_chase(self.np, self.num, CYAN, 0.1) self.color_chase(self.np, self.num, BLUE, 0.1) self.color_chase(self.np, self.num, PURPLE, 0.1) self.rainbow_cycle() # Increase the number to slow down the rainbow sleep(1) self.np.fill(BLACK) self.np.write()
def set_range(cls, pixels: NeoPixel, range_slice: slice, col: RGBBytesColor, clear_others: bool = False): if clear_others: pixels.fill(COL_BLACK) pix_range = NeoPixelRange(pixels, range_slice) pix_range.set_colors(col)
def blink(self, color=[255, 255, 255], times=3, interval=0.5): try: self.off() for i in range(times): NeoPixel.fill(self, color) NeoPixel.write(self) time.sleep(interval) NeoPixel.fill(self, [0, 0, 0]) NeoPixel.write(self) time.sleep(interval) finally: self.off()
def init(): global left_arm, right_arm, head, lights, display, footpedal, keypad left_arm = LazyServo(17, min_angle=90, max_angle=-90) right_arm = LazyServo(22) head = LazyServo(27) lights = NeoPixel(D18, 8) lights.fill((255, 0, 0)) display = CountDisplay(23, 24) footpedal = Button(25) keypad = Keypad([9, 11, 10, 5], [6, 13, 19, 26]) for row in keypad.keymap: for key in row: keypad.callbacks[key] = lambda: print(key)
def init_pixels(led_count: int) -> NeoPixel: ADDRESSABLE_LEDS = led_count # (30/m * 5m) / 3 [Addr is Groups of 3] print('Setting up neopixel + clearing lights') pixels = NeoPixel(board.D18, ADDRESSABLE_LEDS, brightness=1, auto_write=False, pixel_order="BRG") pixels.fill(COL_BLACK) pixels.show() return pixels
class Controller(): def __init__(self, ledsCount, color, brightness): self.pixels = NeoPixel(board.D18, ledsCount, auto_write=False, brightness=brightness) self.color = color self.brightness = brightness self.pixels.fill(self.color) self.show_pixels() def change_color(self, color): self.color = color self.pixels.fill(self.color) self.show_pixels() def change_brightness(self, brightness): self.brightness = abs(brightness / 100) self.pixels.brightness = self.brightness self.show_pixels() def set_pixels(self, leds, colors=[]): self.clear_pixels() if len(colors) <= 0: for led in leds: self.set_pixel(led, self.color) else: for i, led in enumerate(leds): self.set_pixel(led, colors[i]) self.pixels.show() def set_pixel(self, led, color): self.pixels[led] = color def show_pixels(self): self.pixels.show() def clear_pixels(self): self.pixels.fill((0, 0, 0)) def turn_off(self): self.clear_pixels() self.show_pixels() def turn_on(self): self.pixels.fill(self.color) self.show_pixels()
"b5wld0101-raw-out1", "b5wld0101-raw-out2") UPLOAD_V_FIELDS = ("b5wld0101-vth", "b5wld0101-vcc") UPLOAD_CPU_FIELDS = ("cpu-temperature", ) UPLOAD_FIELDS = UPLOAD_PM_FIELDS + UPLOAD_V_FIELDS + UPLOAD_CPU_FIELDS def d_print(level, *args, **kwargs): """A simple conditional print for debugging based on global debug level.""" if not isinstance(level, int): print(level, *args, **kwargs) elif debug >= level: print(*args, **kwargs) pixel = NeoPixel(MPP_NEOPIXEL, 1) pixel.fill(BLACK) ### Initialise the trio of sensors ### Plantower PMS5003 - serial connected pms5003_en = digitalio.DigitalInOut(PMS5003_EN) pms5003_en.direction = digitalio.Direction.OUTPUT pms5003_en.value = True pms5003_rst = digitalio.DigitalInOut(PMS5003_RST) pms5003_rst.direction = digitalio.Direction.OUTPUT pms5003_rst.value = True serial = busio.UART(PMS5003_TX, PMS5003_RX, baudrate=9600, timeout=15.0) ### Sensirion SPS30 - i2c connected i2c = busio.I2C(SPS30_SCL, SPS30_SDA) pms5003 = PM25_UART(serial) sps30 = SPS30_I2C(i2c, fp_mode=True)
from machine import Pin from neopixel import NeoPixel from time import sleep NUM_PIXELS = 14 np = NeoPixel(Pin(16), NUM_PIXELS) colours = { 'red': (255, 0, 0), 'green': (0, 255, 0), 'blue': (0, 0, 255), 'orange': (255, 165, 0), 'yellow': (255, 255, 0), 'yel_grn': (255, 255, 0), 'off': (0, 0, 0) } while True: np.fill(colours['off']) for i in range(7): np[i] = colours['yellow'] np.write() sleep(1) np.fill(colours['off']) for i in range(7, 14): np[i] = colours['blue'] np.write() sleep(1)
from gpiozero import Button from board import D18 from neopixel import NeoPixel import time import numpy # import threading from random import randint, choice # import pdb pixels = NeoPixel(D18, 16) pixels.fill((0, 0, 0)) # global jacks_pins jacks_pins = [13, 22, 6, 8, 3, 10, 20, 27, 19, 24, 23, 25, 16, 11, 12, 9] jacks_diodes = { 12: 15, 9: 14, 13: 13, 22: 12, 6: 11, 8: 10, 3: 9, 10: 8, 20: 7, 27: 6, 19: 5, 24: 4, 23: 3, 25: 2, 16: 1,
import time from machine import Pin from neopixel import NeoPixel np = NeoPixel(Pin(19), 12) RED = (255, 0, 0) YELLOW = (255, 150, 0) GREEN = (0, 255, 0) CYAN = (0, 255, 255) BLUE = (0, 0, 255) PURPLE = (180, 0, 255) while True: np.fill(RED) np.write() time.sleep(1) np.fill(GREEN) np.write() time.sleep(1) np.fill(BLUE) np.write() time.sleep(1) np.fadeinout(PURPLE) np.cycle(YELLOW, 30) np.bounce(CYAN, 30) np.color_chase(RED, 30) np.color_chase(YELLOW, 30) np.color_chase(GREEN, 30) np.color_chase(CYAN, 30) np.color_chase(BLUE, 30) np.color_chase(PURPLE, 30)
# # Shop: https://shop.mchobby.be/55-leds-neopixels-et-dotstar # Wiki: https://wiki.mchobby.be/index.php?title=MicroPython-Accueil#ESP8266_en_MicroPython from machine import Pin from neopixel import NeoPixel from time import sleep from os import urandom NEOPIXEL_PIN = 2 NEOPIXEL_COUNT = 8 NEOPIXEL_WAIT = 0.010 # 10 ms # NeoPixel( broche_signal, nbre_de_led ) np = NeoPixel( Pin(NEOPIXEL_PIN), NEOPIXEL_COUNT ) np.fill( (0,0,0) ) np.write() def wheel( wheel_pos ): """ caculate color based on a color wheel. Color are transistion r - g - b back r based on wheel_pos (0-255) """ assert 0<= wheel_pos <= 255, "Invalid wheel_pos!" wheel_pos = 255 - wheel_pos if( wheel_pos < 85 ): return ( 255-(wheel_pos*3), 0, wheel_pos*3 ) elif( wheel_pos < 170 ): wheel_pos -= 85 return ( 0, wheel_pos*3, 255-(wheel_pos*3) ) else: wheel_pos -= 170
class Glock(object): def __init__(self): self.code = utils.get_code() print("CURRENT KP CODE:", self.code) self.result_count = 0 self.last = -1 self.names = [ "Joel", "Obed", "Malcolm", "Omar", "Matt", "Chris", "Chinny" ] #thread variables self.kp_thread = None self.camera_thread = None self.stream_thread = None self.main_thread = None self.idle_thread = None #thread event signals self.kp_stop_signal = None self.camera_stop_signal = None self.stream_stop_signal = None self.main_stop_signal = None self.idle_stop_signal = None self.idle_blue_signal = Event() #system variables self.camera = None self.system_active_idle = False self.ran_validation = False self.keypad = None self.killed = False self.stream_process = None self.stream = None self.result_count = None self.init_done = False self.bytes = None self.key = None self.fps = None self.kp_active = False self.result_count = None self.frame_counter = 0 self.verification_frame_count = 0 # NeoPixel Setup self.pixel_pin = board.D21 self.num_pixels = 60 self.ORDER = GRB self.pixels = NeoPixel(self.pixel_pin, self.num_pixels, brightness=0.2, auto_write=False, pixel_order=self.ORDER) #setup GPIO pins self.GPIO_TRIGGER = 13 self.GPIO_ECHO = 19 self.GPIO_STRIKE = 20 self.LED_PIN = 25 #set GPIO direction (IN / OUT) #GPIO SETUP GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(self.GPIO_TRIGGER, GPIO.OUT) GPIO.setup(self.GPIO_ECHO, GPIO.IN) GPIO.setup(self.GPIO_STRIKE, GPIO.OUT) GPIO.setup(self.LED_PIN, GPIO.OUT) # LED pin def detect_face_frame(self, image): final = [] cascPath = "haarcascade_frontalface_default.xml" # Create the haar cascade faceCascade = opencv.CascadeClassifier(cascPath) gray = opencv.cvtColor(image, opencv.COLOR_BGR2GRAY) print("frame processing...") # cv2.destroyAllWindows() # Detect faces in the image faces = faceCascade.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=5) #If no faces were found tweak parameters if len(faces) == 0: faces = faceCascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=5) if len(faces) == 0: faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5) # Draw a rectangle around the faces for (x, y, w, h) in faces[::-1]: print("Found a face!") #Resize image to 120 pixels cropped = gray[y - 20:y + h + 20, x:x + w] final = np.array(opencv.resize(cropped, (100, 100))) opencv.imshow("Display WIndow", final) opencv.waitKey(0) opencv.destroyAllWindows() return final def find_face(self, img): global model_sigmoid global model_softmax global sig_input_details global soft_input_details global sig_output_details global soft_output_details face = self.detect_face_frame(img) #If no face found if face == []: return 0, -1 #Sigmoid output sig_input_data = np.reshape(np.array(face, dtype=np.float32), sig_input_details[0]['shape']) model_sigmoid.set_tensor(sig_input_details[0]['index'], sig_input_data) model_sigmoid.invoke() sig_output = model_sigmoid.get_tensor(sig_output_details[0]['index']) #Softmax Output soft_input_data = np.divide( np.reshape(np.array(face, dtype=np.float32), soft_input_details[0]['shape']), 255.0) model_softmax.set_tensor(soft_input_details[0]['index'], soft_input_data) model_softmax.invoke() soft_output = model_softmax.get_tensor(soft_output_details[0]['index']) sig = np.argmax(sig_output) soft = np.argmax(soft_output) print("Sig Raw Value: ", sig_output) print("Soft Raw Value: ", soft_output) print("Person: ", self.names[sig]) #If 2 differnt people if sig != soft: return -1, -1 #If not above threshold #elif else: return 1, sig def distance(self): #set Trigger to HIGH GPIO.output(self.GPIO_TRIGGER, True) # set Trigger after 0.01ms to LOW sleep(0.00001) GPIO.output(self.GPIO_TRIGGER, False) StartTime = time() StopTime = time() # save StartTime while GPIO.input(self.GPIO_ECHO) == 0: StartTime = time() # save time of arrival while GPIO.input(self.GPIO_ECHO) == 1: StopTime = time() # time difference between start and arrival TimeElapsed = StopTime - StartTime # multiply with the sonic speed (34300 cm/s) # and divide by 2, because there and back distance = (TimeElapsed * 34300) / 2 return distance def led_unlock_success(self): #stop idle led to allow for GREEN light if self.idle_stop_signal != None: self.idle_stop_signal.set() self.idle_thread.join() #start with green flash and then pulse self.pixels.fill((0, 225, 0)) for i in range(60): self.pixels[i] = (0, 125, 0) self.pixels.show() sleep(.01) for i in range(60): self.pixels[60 - i - 1] = (0, 50, 0) self.pixels.show() sleep(.01) def led_unlock_fail(self): #stop idle led to allow for RED light if self.idle_stop_signal != None: self.idle_stop_signal.set() self.idle_thread.join() #pluse in red for eek in range(3): for i in range(20): self.pixels.fill((225 - i, 0, 0)) self.pixels.show() sleep(.0005) sleep(.5) def restart_idle(self): #Function to restart IDLE LED Thread sleep(1) self.idle_stop_signal = Event() self.idle_blue_signal.clear() self.idle_thread = Thread(target=self.idle) self.idle_thread.start() def idle(self): print("starting IDLE LED thread") #Process to pulse either white or blue #will plulse in blue if signal is sent by keypad handler while not self.idle_stop_signal.wait(0): if self.idle_blue_signal.isSet(): for i in range(60): self.pixels[i] = (0, 0, 125) self.pixels.show() sleep(.01) for i in range(60): self.pixels[60 - i - 1] = (0, 0, 50) self.pixels.show() sleep(.01) else: for i in range(60): self.pixels[i] = (125, 125, 125) self.pixels.show() sleep(.01) for i in range(60): self.pixels[60 - i - 1] = (50, 50, 50) self.pixels.show() sleep(.01) def Validated(self): #add mutex on gpio ops? #activate strike for 10 sec GPIO.output(self.GPIO_STRIKE, GPIO.HIGH) print("GLOCK STRIKE ACTIVATED") sendText(True) self.led_unlock_success() #unlock strike and wait sleep(16) GPIO.output(self.GPIO_STRIKE, GPIO.LOW) self.ran_validation = True #send signal to restaart idle thread def Invalidated(self): #add mutex on gpips? print("GLOCK INVALID") sendText(False) self.led_unlock_fail() self.ran_validation = True def setup_stream(self): global output #loop to send cameera feed to streaming output class while not self.stream_stop_signal.wait(0): with PiCamera(resolution='1024x768', framerate=24) as self.camera: output = StreamingOutput() self.camera.start_recording(output, format='mjpeg', splitter_port=1, quality=0) sleep(_ONE_DAY_IN_SECONDS) self.camera.stop_recording() def CameraHandler(self): #Load models global model_sigmoid global model_softmax global sig_input_details global soft_input_details global sig_output_details global soft_output_details model_sigmoid = tf.lite.Interpreter(model_path="sigmoid.tflite") model_sigmoid.allocate_tensors() sig_input_details = model_sigmoid.get_input_details() sig_output_details = model_sigmoid.get_output_details() model_softmax = tf.lite.Interpreter(model_path="softmax.tflite") model_softmax.allocate_tensors() soft_input_details = model_softmax.get_input_details() soft_output_details = model_softmax.get_output_details() self.init_done = True print("Enter CameraHandler...") log_handler.emit("Enter CameraHandler...") self.result_count = 0 while not self.camera_stop_signal.wait(0): #if no one infrom of door or keypad currently in use then skip processing frame if self.system_active_idle == False or self.kp_active: # print("loop until motion") continue #grab every third frame from the camera to verfiy face if (self.verification_frame_count % 3 == 0): #capture image in array and send to ML suite rawCapture = PiRGBArray(self.camera, size=(1024, 768)) sleep(0.1) self.camera.capture(rawCapture, format="bgr", use_video_port=True, splitter_port=2) image = rawCapture.array result, person = self.find_face(image) rawCapture.truncate(0) if result == 0: #no face found in image print("NO FACE FOUND") log_handler.emit("NO FACE FOUND") continue elif (result == 1 and self.last == -1) or (result == 1 and self.last == person): #corect face found self.result_count += 1 last = person print("RESIDENT FACE FOUND") log_handler.emit("RESIDENT FACE FOUND") else: #face found but incorrect self.result_count -= 1 print("INCORRECT FACE FOUND") log_handler.emit("INCORRECT FACE FOUND") #need to see the same face twice in order to verify resident if (self.result_count == 2): self.Validated() self.result_count = 0 #reset "correct score" self.last = -1 #same logic..if two wrong faces then signal invalid elif (self.result_count == -2): self.Invalidated() self.result_count = 0 self.last = -1 else: continue self.verification_frame_count += 1 # count +=1 # #call verification on captured image def KeypadHandler(self): print("Enter KeypadHandler") log_handler.emit("Enter KeypadHandler") code_as_list = list(self.code) print("code as list: ", code_as_list) log_handler.emit("code as list: ", code_as_list) #create empty buffer for entered code entered_code = list() new_code_list = list() code_active = False # flag for signaling when input seq ready reset_active = False self.kp_active = False looking_new_code = False while not self.kp_stop_signal.wait(0): keys = self.keypad.pressed_keys #grab key pressed if len(keys) != 1: #eliminate multi press for keypad continue if keys == ["#"] and looking_new_code: #clear newcode being entered while in "enter code state" new_code_list = list() elif keys == ['*']: #input is reset and now look for code entered_code = list() new_code_list = list() code_active = True reset_active = False self.kp_active = True looking_new_code = False self.idle_blue_signal.clear() #reset master key code (usual '#' case) elif keys == ['#']: self.idle_blue_signal.set() entered_code = list() new_code_list = list() code_active = False reset_active = True self.kp_active = True looking_new_code = False elif reset_active: #regualar number is pressed while setting new key code ] #or to verifty old code for kp code change new_code_list += keys if looking_new_code: #if case will short to here if alrady entered old code to change to new if len(code_as_list) == len(new_code_list): #get new code print("new_code", new_code_list) log_handler.emit("new_code", new_code_list) as_string = [str(elem) for elem in new_code_list] as_string = ''.join(as_string) #update code variavles self.code = as_string utils.change_code(as_string) code_as_list = new_code_list #flash blue new_code_list = list() entered_code = list() looking_new_code = False reset_active = False self.idle_blue_signal.clear() self.kp_active = False elif len(code_as_list) == len( new_code_list): #submit old code for verification verification_res = (new_code_list == [ int(i) for i in code_as_list ]) #verify list print("old_code", new_code_list, "verified:", str(verification_res)) log_handler.emit("old_code", new_code_list, "verified:", str(verification_res)) if verification_res: #flash blue # time.sleep(1) # time.sleep(1) looking_new_code = True self.led_unlock_success() else: #flash red reset_active = False self.kp_active = False self.Invalidated() new_code_list = list() entered_code = list() elif code_active: entered_code += keys #add key to code if len(code_as_list) == len( entered_code): #submit code for verification code_active = False self.kp_active = False print("code", entered_code) log_handler.emit("code", entered_code) verification_res = (entered_code == [ int(i) for i in code_as_list ]) #verify list if verification_res == True: print("Validated") log_handler.emit("Validated") self.Validated() else: print("Invalidated") log_handler.emit("Invalidated") self.Invalidated() else: continue print("code", entered_code) print("reset_code", new_code_list) sleep(0.3) def MainHandler(self): print("Enter Main MainHandler...") # distances = [1000,1000,1000] #track last three disances #create queue of seen distances distances = [0, 0, 0] d_count = 0 d_max = 0 while not self.init_done: continue while not self.main_stop_signal.wait(0): sleep(0.5) distance = self.distance() distances[d_count % 3] = distance d_count += 1 print("Measured Distance = %.1f cm" % distance) # print(self.system_active_idle) # print(self.ran_validation) if (max(distances) < 90 and self.system_active_idle == False): #start process for camera and LED print("idlewake") self.system_active_idle = True self.restart_idle() self.kp_stop_signal = Event() self.kp_thread = Thread(target=self.KeypadHandler) self.kp_thread.start() elif (self.ran_validation == True): print("ran validation, restarting idle") log_handler.emit("ran validation, restarting idle") #clear pixels self.pixels.fill((0, 0, 0)) self.pixels.show() #restart the killed idle thread if person in front of sensor if max(distances) < 90: self.restart_idle() self.system_active_idle = True else: self.system_active_idle = False self.ran_validation = False elif (min(distances) > 90 and self.system_active_idle == True): #close ML and turn off LED print("no motion detected...close idle") log_handler.emit("no motion detected...close idle") self.system_active_idle = False self.idle_blue_signal.clear() self.idle_stop_signal.set() self.kp_stop_signal.set() self.idle_thread.join() self.kp_thread.join() print("kp joined") self.pixels.fill((0, 0, 0)) self.pixels.show() self.ran_validation = False try: self.camera_stop_signal.set() self.camera_thread.join() print("camera joined") self.idle_stop_signal.set( ) #stop self.idle_thread when main function exits self.idle_thread.join() except: return def run(self): #clear pixels self.pixels.fill((0, 0, 0)) self.pixels.show() self.stream_stop_signal = Event() self.stream_thread = Thread(target=self.setup_stream) self.stream_thread.start() self.keypad = keypad.keypad_setup() self.camera_stop_signal = Event() self.camera_thread = Thread(target=self.CameraHandler) self.camera_thread.start() self.main_stop_signal = Event() self.main_thread = Thread(target=self.MainHandler) self.main_thread.start() print("G_LOCK HAS BEEN STARTED") log_handler.emit("G_LOCK HAS BEEN STARTED") # def stream_serve(self): # p0 = subprocess.call(['sudo', 'pkill', 'uv4l']) #exit any hanging uv4l processes # command = "sudo uv4l -nopreview --auto-video_nr --driver raspicam --encoding mjpeg --width 640 --height 480 --framerate 20 --server-option '--port=2020' --server-option '--max-queued-connections=30' --server-option '--max-streams=25' --server-option '--max-threads=29'" # args = shlex.split(command) # p1 = subprocess.Popen(args) #start streaming server # print("BEGIN UV4L STREAMING") def kill(self): self.killed = True print("GLOCK KILL: Stopping threads") self.main_stop_signal.set() self.stream_stop_signal.set() self.stream_thread.join() self.main_thread.join() #clear pixels self.pixels.fill((0, 0, 0)) self.pixels.show()
class RFIDDoorUnlockClient: """Client class. Interacts directly with the MFRC522 RFID reader.""" def __init__(self, room_num, mfrc_reader, remote_addr, mqtt_obj, aes_key, aes_iv): self.room = room_num self.rdr = mfrc_reader self.server_addr = remote_addr self.mqtt = mqtt_obj self.__key = aes_key self.__iv = aes_iv # Only using the neopixel instance for showing visually if the RFID tag was valid self.np = NeoPixel(Pin(17,Pin.OUT),32) print("RFID Door Unlock Client created") self.__running_thread = _thread.start_new_thread(self.run, tuple()) def __str__(self): return ("Room: " + self.room + ", Verification Server: " + self.server_addr[0] + ":" + self.server_addr[1] + "\nAES 256 CBC Key: " + str(self.__key) + "\nAES 256 CBC IV: " + str(self.__iv)) def __repr__(self): return (self.room, repr(self.rdr), self.server_addr, repr(self.mqtt), self.__key, self.__iv) # TODO: Implement __del__ method as soon as MicroPython supports it # for user created classes def run(self): """Constantly running on a thread once the instance is created Based heavily off of the do_read method from Tasmi Devil's MFRC522 examples. """ while True: sleep_ms(100) # Small lag for the RFID reader uid_hash = '' (stat, tag_type) = self.rdr.request(self.rdr.REQIDL) if stat == self.rdr.OK: print("reader status OK") (stat, raw_uid) = self.rdr.anticoll() if stat == self.rdr.OK: print("reader status OK after anticoll") h = sha256() h.update(bytes(raw_uid)) uid_hash = h.digest() print("RFID tag UID SHA-256 hash:") print(uid_hash) secure_packet, n = self.make_secure_packet(uid_hash) print("Secure packet created") client = socket(AF_INET, SOCK_STREAM) client.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) client.connect(self.server_addr) print("Connected to server") client.sendall(secure_packet) # 64-byte packet print("Sent secure packet to server") # TODO: set up a timeout here. Only wait for so long response = client.recv(64) print("Received response from server") try: client.close() del client print("Disconnected from server") except AttributeError: print("Connection closed on server side") if self.verify(response, n): print("Passed verification") self.unlock_door() else: print("Failed verification") self.blink_fail_lights() def make_secure_packet(self, h): """Encrypts and returns plaintext appended with a 32B nonce (also returned) AES 256 CBC is used (as opposed to EBC which would not be secure in this implementation) """ nonce = urandom(32) plaintext = h + nonce e = aes(self.__key, 2, self.__iv) print("AES encrypter created") return e.encrypt(plaintext), nonce def verify(self, pkt, n): """Verifies the packet received has the same nonce as the one sent""" d = aes(self.__key, 2, self.__iv) plaintext = d.decrypt(pkt) payload = plaintext[:32] nonce = plaintext[32:] if n == nonce: print("Valid nonce") h = sha256() h.update(b'valid') # the string that is hashed on the server side if payload == h.digest(): print("Valid payload") return True return False def unlock_door(self): """Handles whatever things must be done to unlock the door In the specific version used for this project, this means 1: Publishing the unlocked status to the MQTT broker 2: Turning on the green LEDs 3: Physically unlocking the door 4: Waiting 5 seconds 5: Physically locking the door 6: Turning off the LEDs 7: Publishing the locked status to the MQTT broker """ #self.mqtt.connect() #print("Connected to MQTT broker") #self.mqtt.publish('/'+self.room_num+'/lock', 'unlocked') #print("'unlocked' sent to MQTT broker") #self.mqtt.disconnect() #print("Disconnected from MQTT broker") self.np.fill((0,10,0)) self.np.write() # TODO: Physically unlock the door sleep_ms(5000) # TODO: Physically lock the door self.np.fill((0,0,0)) self.np.write() #self.mqtt.connect() #print("Connected to MQTT broker") #self.mqtt.publish('/'+self.room_num+'/lock', 'locked') #print("'locked' sent to MQTT broker") #self.mqtt.disconnect() #print("Disconnected from MQTT broker") return def blink_fail_lights(self): """Blink the light pattern for a failed verification""" self.np.fill((10,0,0)) self.np.write() sleep_ms(100) self.np.fill((0,0,0)) self.np.write() sleep_ms(100) self.np.fill((10,0,0)) self.np.write() sleep_ms(100) self.np.fill((0,0,0)) self.np.write() sleep_ms(100) self.np.fill((10,0,0)) self.np.write() sleep_ms(100) self.np.fill((0,0,0)) self.np.write() sleep_ms(1000)
class ConfigManager: def __init__(self, config={}): self.config = config self.np = NeoPixel(Pin(5, Pin.OUT), 1, timing = True) self.np.fill((255, 0, 0)); self.np.write() self.wlan_ap = network.WLAN(network.AP_IF) self.wlan_sta = network.WLAN(network.STA_IF) # setup for ssid if self.config.get('device_name'): self.ap_name= self.config['device_name'] else: self.ap_name= "BlockyWifi_" + binascii.hexlify(machine.unique_id()).decode('ascii') self.ap_password = "******" self.wifi_status = 0 def connect(self, ssid, password): self.wlan_sta.active(True) self.wlan_sta.connect(ssid, password) a=0 print('Connecting to wifi') while not self.wlan_sta.isconnected() | (a > 99) : time.sleep(0.1) a+=1 print('.', end='') if self.wlan_sta.isconnected(): print('\nConnected. Network config:', self.wlan_sta.ifconfig()) self.wifi_status = 1 return True else : print('\nProblem. Failed to connect to :' + ssid) self.wifi_status = 2 self.wlan_sta.active(False) return False def _httpHandlerIndexGet(self, httpClient, httpResponse): print('Get index request') htmlFile = open('index.html', 'r') content = '' for line in htmlFile: content = content + line httpResponse.WriteResponseOk( headers = None, contentType = "text/html", contentCharset = "UTF-8", content = content) ''' available_networks = [] for nw in wlan_sta.scan(): available_networks.append({'ssid': nw[0].decode('utf-8'), 'rssi': nw[3]}) available_networks_str = ujson.dumps(networks) ''' def _httpHandlerCheckStatus(self, httpClient, httpResponse): print('Get check status request') if self.wifi_status == 1: content = 'OK' elif self.wifi_status == 2: content = 'Failed' else: content = '' httpResponse.WriteResponseOk(headers = None, contentType = "text/html", contentCharset = "UTF-8", content = content) if self.wifi_status == 1: print('Wait for rebooting') time.sleep(5) print('Rebooting') machine.reset() def _httpHandlerSaveConfig(self, httpClient, httpResponse): print('Get save config request') request_json = ujson.loads(httpClient.ReadRequestContent().decode('ascii')) self.wifi_status = 0 print(request_json) httpResponse.WriteResponseOk(headers = None, contentType = "text/html", contentCharset = "UTF-8", content = 'OK') if self.connect(request_json['ssid'], request_json['password']): # save config if not self.config.get('known_networks'): self.config['known_networks'] = [{'ssid': request_json['ssid'], 'password': request_json['password']}] else: exist_ssid = None for n in self.config['known_networks']: if n['ssid'] == request_json['ssid']: exist_ssid = n break if exist_ssid: exist_ssid['password'] = request_json['password'] # update WIFI password else: # add new WIFI network self.config['known_networks'].append({'ssid': request_json['ssid'], 'password': request_json['password']}) self.config['device_name'] = request_json['deviceName'] self.config['auth_key'] = request_json['authKey'] f = open('config.json', 'w') f.write(ujson.dumps(self.config)) f.close() def _httpHandlerScanNetworks(self, httpClient, httpResponse) : print('Receive request to scan networks') self.wlan_sta.active(True) networks = [] for nw in self.wlan_sta.scan(): networks.append({'ssid': nw[0].decode('ascii'), 'rssi': nw[3]}) content = ujson.dumps(networks) httpResponse.WriteResponseOk(headers = None, contentType = "application/json", contentCharset = "UTF-8", content = content) def start(self): self.wlan_sta.active(True) self.wlan_ap.active(True) self.wlan_ap.config(essid=self.ap_name, password=self.ap_password) routeHandlers = [ ("/", "GET", self._httpHandlerIndexGet), ("/aplist", "GET", self._httpHandlerScanNetworks), ("/status", "GET", self._httpHandlerCheckStatus), ("/save", "POST", self._httpHandlerSaveConfig) ] srv = MicroWebSrv(routeHandlers=routeHandlers) srv.Start(threaded=True) print('Now enter config mode') print('Connect to Wifi ssid :' + self.ap_name + ' , default pass: '******'And connect to Blocky via at 192.168.4.1') gc.collect() print(gc.mem_free()) return True
def delegate_format(pixel: neopixel.NeoPixel, input_item: any) -> None: item = input_item[0] pixel.fill((100, 100, 100))
def start_worker(): thread = threading.Thread(target=drive_leds) thread.daemon = True # Daemonize thread thread.start() # Start the execution def stop_leds(): global done done = True pixels.fill((0, 0, 0)) def button_callback(): date_time = datetime.datetime.now().strftime("%m/%d/%Y, %H:%M:%S") post_message_to_lack(f"@here button pressed! `{date_time}`") set_state({"mode": "nyan_cat"}) time.sleep(10) set_state({"mode": "per_step"}) if __name__ == '__main__': if os.getenv('WERKZEUG_RUN_MAIN') == 'true': post_message_to_lack("stairs pi has booted") # register_button(button_callback) pixels.fill((255, 255, 255)) atexit.register(stop_leds) start_worker() app.run(host="0.0.0.0", debug=True)
# couleur des autres pixels np[1] = (0, 255, 0) # vert np[2] = (0, 0, 128) # bleu (1/2 brillance) # Voir aussi HTML Color Picker # https://www.w3schools.com/colors/colors_picker.asp np[3] = (255, 102, 0) # Orange np[4] = (255, 0, 102) # Rose bonbon np[5] = (153, 51, 255) # Violet np[6] = (102, 153, 255) # bleu pastel np[7] = (153, 255, 153) # vert pastel # Envoyer l'info au NeoPixels np.write() sleep(2) # fill() permet de remplir tout # le NeoPixel avec une seule couleur colors = [(255, 0, 0), (0, 255, 0), (0, 0, 128), (255, 102, 0), (255, 0, 102), (153, 51, 128), (102, 153, 128), (153, 255, 128)] for color in colors: np.fill(color) np.write() sleep(2) # Eteindre les NeoPixels np.fill((0, 0, 0)) np.write()
import bme280
class LedStatus(): INDEX_COLOURS = [ 0x9CFF9C, 0x31FF00, 0x31CF00, 0xF0F000, 0xFFCF00, 0xFF9A00, 0xFF6464, 0xFF0000, 0x900000, 0xCE30FF ] def __init__(self): self.neo = NeoPixel(board.NEOPIXEL, 1, brightness=0.1) self.neo.fill(0) def show_air_quality(self, reading): # From: https://uk-air.defra.gov.uk/air-pollution/daqi?view=more-info&pollutant=pm25#pollutant if reading >= 71: self.neo.fill(self.INDEX_COLOURS[9]) elif reading >= 65 and reading <= 70: self.neo.fill(self.INDEX_COLOURS[8]) elif reading >= 59 and reading <= 64: self.neo.fill(self.INDEX_COLOURS[7]) elif reading >= 54 and reading <= 58: self.neo.fill(self.INDEX_COLOURS[6]) elif reading >= 48 and reading <= 53: self.neo.fill(self.INDEX_COLOURS[5]) elif reading >= 42 and reading <= 47: self.neo.fill(self.INDEX_COLOURS[4]) elif reading >= 36 and reading <= 41: self.neo.fill(self.INDEX_COLOURS[3]) elif reading >= 24 and reading <= 35: self.neo.fill(self.INDEX_COLOURS[2]) elif reading >= 12 and reading <= 23: self.neo.fill(self.INDEX_COLOURS[1]) else: self.neo.fill(self.INDEX_COLOURS[0])
def off(self): NeoPixel.fill(self, (0, 0, 0)) NeoPixel.write(self) self._on = False
class ArtNeoPixel(ArtPart): def __init__(self, pin=15, n=30, bpp=3, name=None, duration=10000, director=None): super().__init__(name=name, duration=duration, director=director) if type(pin) is not Pin: pin = Pin(pin, Pin.OUT) self.np = NeoPixel(pin, n, bpp) self.refresh_rate = 15 self.need_update = True self.running = True self.duration = duration # ms log.debug("{} lights on {}".format(self.np.n, self.np.pin)) self.cmds['random'] = self.random self.cmds['fade'] = self.fade self.cmds['bounce'] = self.bounce self.cmds['chase'] = self.chase self.cmds['clear'] = self.clear def __getitem__(self, key): return self.np[key] def __setitem__(self, key, value): self.np[key] = value def do_update(self): self.np.write() self.need_update = False return False def get_sublights(self, lights): if lights is None: lights = [j for j in range(self.np.n)] return len(lights), lights async def random(self, brightness=0.1, duration=5000, beat=300, start=0, lights=None, **kwargs): n, lights = self.get_sublights(lights) while self.running: await self.wait_for_start(start) begin_ms = ticks_ms() while duration is None or (ticks_diff(ticks_ms(), begin_ms) < duration): for j in lights: col = [int(c * brightness) for c in os.urandom(3)] self.np[j] = col self.need_update = True await asyncio.sleep_ms(beat) else: await self.clear(lights) return async def chase(self, color=(255, 255, 255), bgcolor=(0, 0, 0), cycles=4, duration=None, beat=200, start=0, lights=None, **kwargs): n, lights = self.get_sublights(lights) while self.running: await self.wait_for_start(start) begin_ms = ticks_ms() if duration is None: duration = cycles * beat * n else: cycles = duration // (beat * n) for i in range(cycles * n): if ticks_diff(ticks_ms(), begin_ms) > duration: await self.clear(lights) return self.np[lights[(i - 1) % n]] = bgcolor self.np[lights[i % n]] = color self.need_update = True await asyncio.sleep_ms(beat) await self.clear(lights) async def bounce(self, color=(255, 255, 255), bgcolor=(0, 0, 0), cycles=4, duration=None, beat=100, start=0, lights=None, **kwargs): await self.wait_for_start(start) n, lights = self.get_sublights(lights) if duration is None: duration = cycles * beat * n else: cycles = duration // (beat * n) begin_ms = ticks_ms() while self.running: for i in range(cycles * 2 * n): if ticks_diff(ticks_ms(), begin_ms) > duration: await self.clear(lights) return for j in lights: self.np[j] = bgcolor if (i // n) % 2 == 0: self.np[lights[i % n]] = color else: self.np[lights[n - 1 - (i % n)]] = color self.need_update = True await asyncio.sleep_ms(beat) async def fade(self, color=(255, 255, 255), cycles=3, step=8, beat=30, duration=None, start=0, lights=None, **kwargs): await self.wait_for_start(start) n, lights = self.get_sublights(lights) if duration is None: duration = cycles * beat * n begin_ms = ticks_ms() while self.running and ticks_diff(ticks_ms(), begin_ms) <= duration: log.debug("start fade, ticks==%d", ticks_diff(ticks_ms(), begin_ms)) for val in range(0, 256, step): # log.info("val={}".format(val)) for j in range(n): self.np[lights[j]] = [val & v for v in color] self.need_update = True await asyncio.sleep_ms(beat) if ticks_diff(ticks_ms(), begin_ms) > duration: await self.clear(lights) return for val in range(255, -1, -step): # log.info("val={}".format(val)) for j in range(n): self.np[lights[j]] = [val & v for v in color] self.need_update = True await asyncio.sleep_ms(beat) if ticks_diff(ticks_ms(), begin_ms) > duration: await self.clear(lights) return for j in range(n): self.np[lights[j]] = (0, 0, 0) log.debug("stop fade, ticks==%d", ticks_diff(ticks_ms(), begin_ms)) self.need_update = True await self.clear(lights) async def clear(self, lights=None, start=0, **kwargs): await self.wait_for_start(start) if lights is None: self.np.fill((0, 0, 0)) else: for i in range(len(lights)): self.np[lights[i]] = (0, 0, 0) self.np.write() async def stop(self, clear=True, **kwargs): if clear: self.np.fill((0, 0, 0)) self.np.write() self.running = False log.info("{}: stopping".format(self.name))
def color_wheel(pixel: neopixel.NeoPixel, input_item: colorify.Color) -> None: c = input_item pixel.fill(c.get_rgb()) c.change_hue(1)
neo = NeoPixel(28, n=8, brightness=0.3, autowrite=False) RED = (255, 0, 0) YELLOW = (255, 150, 0) GREEN = (0, 255, 0) CYAN = (0, 255, 255) BLUE = (0, 0, 255) PURPLE = (180, 0, 255) WHITE = (255, 255, 255) BLACK = (0, 0, 0) COLORS = (RED, YELLOW, GREEN, CYAN, BLUE, PURPLE, WHITE, BLACK) # fill for color in COLORS: neo.fill(color) neo.show() time.sleep(0.25) # chase for color in COLORS: for i in range(neo.n): neo[i] = color neo.show() time.sleep(0.025) # rainbow for i in range(255): neo.rainbow_cycle(i) neo.show() time.sleep(0.0025)
try: while True: network.process() time.sleep_ms(100) except: pass #machine.reset() config_btn = Pin(CONFIG_PIN, Pin.IN) status_led = NeoPixel(Pin(LED_PIN, Pin.OUT), 1, timing=True) if config_btn.value(): print('config button is pressed') # turn on config led status_led.fill((255, 0, 0)) status_led.write() # start while loop until btn is released press_begin = time.ticks_ms() press_duration = 0 while config_btn.value(): press_end = time.ticks_ms() press_duration = time.ticks_diff(press_end, press_begin) print(press_duration) if press_duration > 2000: break time.sleep_ms(100) # check how long it was pressed if press_duration > 2000:
class LOLRGB: def __init__(self): self._pin = Pin(DATA_PIN, Pin.OUT) self._np = NeoPixel(self._pin, WIDTH * HEIGHT) self._delay_ms = MEDIUM_PAUSE self._color = RED self._boundary = CHAR_BOUNDARY def set_delay_ms(self, delay_ms, persist=True): # number of ms between each column of pixels drawn to the display delay_ms = int(delay_ms) if delay_ms < 0: raise ValueError('Please provide a delay >= 0') if persist: self._delay_ms = delay_ms else: return delay_ms def set_color(self, color, persist=True): # tuple (r,g,b) = one colour # list of tuples = cycle through colours color = self._colorify(color) if persist: self._color = color else: return color def set_boundary(self, boundary, persist=True): # when to move onto the next colour when cycling through colours if not CHAR_BOUNDARY <= boundary <= WORD_BOUNDARY: raise ValueError('Please provide a boundary (0-1)') if persist: self._boundary = boundary else: return boundary def write(self, string, color=None, delay_ms=None, boundary=None): try: self._write(string, color, delay_ms, boundary) except KeyboardInterrupt: self._np.fill(BLACK) self._np.write() def _colorify(self, color, top=True): # ensures its a valid single colour tuple or a list of colour tuples if top and isinstance(color, list): for c in color: self._colorify(c, False) if len(color) == 1: return color[0] elif not isinstance(color, tuple) or len(color) != 3: raise ValueError( 'Invalid color. Must be a tuple (r,g,b) or list of tuples [(r,g,b),(r,g,b)]' ) return color def _stringify(self, string): # ensures the string is printable if isinstance(string, str): return string if isinstance(string, (int, float)): return str(string) if isinstance(string, (bytearray, bytes)): return string.decode("utf-8") raise TypeError('Could not interpret string') def _write(self, string, color=None, delay_ms=None, boundary=None): string = self._stringify(string) #if len(string) == 0: # raise ValueError('Please provide a non-empty string') if color is None: color = self._color else: color = self.set_color(color, False) num_colors = 1 if isinstance(color, tuple) else len(color) if delay_ms is None: delay_ms = self._delay_ms else: delay_ms = self.set_delay_ms(delay_ms, False) if boundary is None: boundary = self._boundary else: boundary = self.set_boundary(boundary, False) # number of columns to be drawn str_len_with_space = len(string) * _CHAR_AND_SPACE # number of frames to draw, starting with the string offscreen right # and ending offscreen left frames = WIDTH + str_len_with_space # for colour cycling num_spaces = 0 for frame in range(frames): self._np.fill(BLACK) # which column of pixels is currently being drawn # starts offscreen on the right and moves left on each frame cursor = WIDTH - frame # loop over each column that needs to be drawn column_from = max(cursor, 0) column_to = min(WIDTH, cursor + str_len_with_space) for column in range(column_from, column_to): # column number relative to the string str_column = column - cursor # which char of the string is being drawn char_index = str_column // _CHAR_AND_SPACE # column of font character including space (1-4) column_in_char = str_column % _CHAR_AND_SPACE # if multiple colours, detect word boundaries if num_colors > 1: num_spaces = string.count(' ', 0, char_index) # 0=48, A=65, a=97 ascii_code = ord(string[char_index]) # font only supports chars 32-127, anything more or less gets a # hollow rect (zero) or a filled rect (del) if ascii_code < _SPACE_CHAR: ascii_code = _ZERO_CHAR # hollow rect elif ascii_code > _DEL_CHAR: ascii_code = _DEL_CHAR # filled rect # ascii_code 32 (space), nothing to draw, skip ahead to the next char if ascii_code == _SPACE_CHAR: continue # only output font columns, skip spaces if column_in_char < _CHAR_WIDTH: # which char offset in the font font_position = ascii_code - _SPACE_CHAR # offset of the column in the font font_col = (font_position * _CHAR_WIDTH) + column_in_char # the page in the font that contains this char column # note: some chars span multiple bytes in the font # so its calculated at a column level font_page = font_position // _FONT_CHARS_PER_ROW # which byte in the font contains this char column font_index = (font_col // 8) + (font_page * 4 * _BYTES_PER_ROW) # how many bits to shift the byte to get this char column shift = 7 - (font_col % 8) # determine the colour for this column if num_colors == 1: char_color = color elif boundary == CHAR_BOUNDARY: char_color = color[(char_index - num_spaces) % num_colors] elif boundary == WORD_BOUNDARY: char_color = color[num_spaces % num_colors] # write column of pixel data for h in range(HEIGHT): self._np[column + WIDTH * h] = char_color if _TOMTHUMB[ font_index + _BYTES_PER_ROW * h] >> shift & 1 else BLACK # draw the pixels self._np.write() # pause between each frame if delay_ms > 0: sleep_ms(delay_ms)
return (0, 85 - pos, pos) pos = pos - 170 return (pos, 0, 85 - pos) # Raimbow from machine import Pin from neopixel import NeoPixel nf = NeoPixel(Pin(26), 192) for i in range(192): nf[i] = wheel(i) nf.write() # Turn off nf.fill((0, 0, 0)) nf.write() # Demo 5.3 - PIR from machine import Pin from time import sleep PIR = Pin(36, Pin.IN) while True: if PIR.value(): print('Movement detected !') else: print('Everything quiet...') sleep(1) # Demo 5.4 - External interrupts
PERIOD_MS = 500 colors = [(0, 0, 255), (16, 0, 128), (32, 0, 64), (64, 0, 32), (128, 0, 16), (255, 0, 0)] colors.extend(list(reversed(colors))[1:-1]) def solid(): elapsed = ticks_ms() // PERIOD_MS current = elapsed % len(colors) np.fill(colors[current]) np.write() def chase(): elapsed = ticks_ms() // PERIOD_MS for i in range(PIXEL_COUNT): current = (elapsed + 1) % len(colors) np[i] = colors[current] np.write() np = NeoPixel(PIXEL_PIN, PIXEL_COUNT) np.fill((0, 0, 0)) np.write() while True: chase() sleep(0.01)
from machine import Pin from neopixel import NeoPixel from time import sleep PIXEL_PIN = Pin(5, Pin.OUT) PIXEL_COUNT = 8 np = NeoPixel(PIXEL_PIN, PIXEL_COUNT) np.fill((0, 0, 0)) np.write() np.fill((255, 0, 0)) np.write() sleep(2) np.fill((0, 255, 0)) np.write() sleep(2) np.fill((0, 0, 255)) np.write() sleep(2) np.fill((0, 0, 0)) np.write()
class MainApp(IoTApp): """ This is your custom class that is instantiated as the main app object instance, it inherits from the supplied IoTApp class found in the libs/iot_app.py module which is copied when the Huzzah32 is prepared. This IoTApp in turn encapsulates an instance of the ProtoRig class (which is found in libs/proto_rig.py) and exposes a number of properties of this ProtoRig instance so you do not have to do this yourself. Also, the IoTApp provides an execution loop that can be started by calling the run() method of the IoTApp class (which is of course inherited into your custom app class). All you have to do is define your program by providing implementations of the init(), loop() and deinit() methods. Looping of your program can be controlled using the finished flag property of your custom class. """ AP_SSID = "DCETLocalVOIP" AP_PSWD = "" AP_TOUT = 5000 MQTT_ADDR = "192.168.." # Your desktop PC Wi-Fi dongle IP address MQTT_PORT = 1883 NTP_PORT = 123 # NTP server port number (by default this is port 123) # Literal string values can be converted to binary representation by using a b prefix MQTT_TEST_TOPIC_1 = b"cet235/test/ticks" MQTT_TEST_TOPIC_2 = b"cet235/test/secs" def init(self): """ The init() method is designed to contain the part of the program that initialises app specific properties (such as sensor devices, instance variables etc.) """ self.message = "None" self.gap = " " self.active = False self.topic_1_count = 0 self.topic_1_colour = 0 self.wifi_msg = "No WIFI" connect_count = 0 # Try to connect to WiFi 5 times, if unsuccessful then only try again if button A on # the OLED is pressed while connect_count < 5 and not self.is_wifi_connected(): self.oled_clear() self.wifi_msg = "Connect WIFI:{0}".format(connect_count + 1) self.oled_text(self.wifi_msg, 0, 0) self.oled_display() self.connect_to_wifi(wifi_settings=(self.AP_SSID, self.AP_PSWD, True, self.AP_TOUT)) connect_count += 1 if self.is_wifi_connected(): self.wifi_msg = "WIFI" self.ntp_msg = "NTP - RTC good" # Register with the MQTT broker and link the method mqtt_callback() as the callback # when messages are recieved self.set_rtc_by_ntp(ntp_ip=self.MQTT_ADDR, ntp_port=self.NTP_PORT) self.register_to_mqtt(server=self.MQTT_ADDR, port=self.MQTT_PORT, sub_callback=self.mqtt_callback) # Subscribe to topic "cet235/test/ticks" self.mqtt_client.subscribe(self.MQTT_TEST_TOPIC_1) # Subscribe to topic "cet235/test/secs" self.mqtt_client.subscribe(self.MQTT_TEST_TOPIC_2) self.oled_clear() self.oled_display() else: self.wifi_msg = "No WIFI" self.oled_clear() self.oled_display() self.neopixel_pin = self.rig.PIN_21 # Set pin 21 to be a digital output pin that is initially pulled down (off) self.neopixel_pin.init(mode=Pin.OUT, pull=Pin.PULL_DOWN) self.npm = NeoPixel(self.neopixel_pin, 32, bpp=3, timing=1) # self.rtc.datetime((2019, 3, 5, 1, 9, 0, 0, 0)) # Instantiate a BME680 object and configure it using the obtain_sensor_bme680() # method self.obtain_sensor_bme680() # Name of the file to write to the Huzzah32's root file system self.file_name = "access_data.csv" if self.file_exists(self.file_name): os.remove(self.file_name) self.file = open(self.file_name, "w+") self.access = False self.access_str = "" self.off = False self.count = 0 self.lightcount = 0 self.npm.fill((5, 5, 5)) self.npm.write() self.npm.write() def loop(self): """ The loop() method is called after the init() method and is designed to contain the part of the program which continues to execute until the finished property is set to True """ yr, mn, dy, dn, hr, mi, se, ms = self.rtc.datetime() self.oled_clear() output = "{0} {1:02d}-{2:02d}-{3}".format(self._DAY_NAMES[dn][0:3], dy, mn, yr) self.oled_text(output, 0, 12) output = "{0:02d}:{1:02d}:{2:02d}".format(hr, mi, se) self.oled_text(output, 0, 22) self.oled_display() sleep(0.1) if self.is_wifi_connected(): # Check for any messages received from the MQTT broker, note this is a non-blocking # operation so if no messages are currently present the loop() method continues self.mqtt_client.check_msg() # If sensor readings are available, read them once a second or so if self.sensor_bme680.get_sensor_data(): tm_reading = self.sensor_bme680.data.temperature # In degrees Celsius rh_reading = self.sensor_bme680.data.humidity # As a percentage (ie. relative humidity) self.oled_text("{0}c".format(tm_reading), 0, 0) self.oled_text("{0}%".format(rh_reading), 60, 0) self.oled_display() sleep(0.5) # Current date and time taken from the real-time clock now = self.rtc.datetime() year = now[0] month = now[1] day = now[2] hour = now[4] minute = now[5] second = now[6] if self.access: if self.count == 0: date_str = "{0}/{1}/{2}".format(day, month, year) time_str = "{0}:{1}:{2}".format(hour, minute, second) # Write to file self.file.write("{0},{1},{2},{3} \n".format( "ACCESS-STARTED", date_str, time_str, self.message)) # Format timestamp timestamp = "{0}-{1}-{2}|{3}:{4}:{5}".format( year, month, day, hour, minute, second) # Format line of data data_line = "{0},{1:.2f},{2:.2f},{3}\n".format( timestamp, tm_reading, rh_reading, self.message) # Write data line to the access_data.csv file if self.message != "None": self.file.write(data_line) # Set correct colour for NeoPixel matrix LEDS and correct access warning string if self.lightcount == 0: self.npm.fill((0, 0, 0)) self.npm.write() elif self.lightcount <= 5: self.npm.fill((0, 10, 0)) self.npm.write() elif self.lightcount > 5 and self.lightcount <= 10: self.npm.fill((10, 10, 0)) self.npm.write() elif self.lightcount > 10: self.npm.fill((10, 0, 0)) self.npm.write() # Increment seconds counter self.count += 1 self.lightcount += 1 def mqtt_callback(self, topic, msg): topic = self.MQTT_TEST_TOPIC_2 sleep(1) # decode the message self.message = (str(bytes(msg), "utf-8")) # statment to manage the type of message that it's receive if (self.message != "None"): self.access = True else: self.lightcount = 0 def deinit(self): """ The deinit() method is called after the loop() method has finished, is designed to contain the part of the program that closes down and cleans up app specific properties, for instance shutting down sensor devices. It can also be used to display final information on output devices (such as the OLED FeatherWing) """ # Clear the NeoPixel matrix self.npm.fill((0, 0, 0)) self.npm.write() # If an access period is currently active then write to the access_data.csv file that it # is now stopped and also the length of the access period in seconds if self.access: # Current date and time taken from the real-time clock to record as stop date and time # for this access period now = self.rtc.datetime() year = now[0] month = now[1] day = now[2] hour = now[4] minute = now[5] second = now[6] date_str = "{0}/{1}/{2}".format(day, month, year) time_str = "{0}:{1}:{2}".format(hour, minute, second) # Write to file, note: self.count is approximately the number of seconds that this access # period lasted self.file.write("{0},{1},{2},{3}\n".format("ACCESS-STOPPED", date_str, time_str, self.count)) # Make sure the access_data.csv file is closed self.file.close() def obtain_sensor_bme680(self): self.sensor_bme680 = BME680(i2c=self.rig.i2c_adapter, i2c_addr=0x76) self.sensor_bme680.set_temperature_oversample(OS_8X) self.sensor_bme680.set_humidity_oversample(OS_2X) self.sensor_bme680.set_filter(FILTER_SIZE_3) def file_exists(self, file_name): file_names = os.listdir() return file_name in file_names def btnA_handler(self, pin): if not self.access: # Current date and time taken from the real-time clock to record as start date and time # for this access period now = self.rtc.datetime() year = now[0] month = now[1] day = now[2] hour = now[4] minute = now[5] second = now[6] date_str = "{0}/{1}/{2}".format(day, month, year) time_str = "{0}:{1}:{2}".format(hour, minute, second) # Write to file self.file.write("{0},{1},{2}\n".format("ACCESS-STARTED", date_str, time_str)) # Update access information self.access = True self.access_str = "ACCESS" self.count = 0 def btnB_handler(self, pin): if self.access: now = self.rtc.datetime() year = now[0] month = now[1] day = now[2] hour = now[4] minute = now[5] second = now[6] date_str = "{0}/{1}/{2}".format(day, month, year) time_str = "{0}:{1}:{2}".format(hour, minute, second) # Write to file, note: self.count is approximately the number of seconds that this access # period lasted self.file.write("{0},{1},{2},{3}\n".format("ACCESS-STOPPED", date_str, time_str, self.count)) # Update access information self.access = False self.access_str = "" # Clear the NeoPixel matrix self.npm.fill((0, 0, 0)) self.npm.write()