def __init__(self, settings=None): global GPIO_FAIL self.SIMULATION_MODE = GPIO_FAIL self.settings = settings if self.settings is None: self.settings = { } if not "VERSION" in self.settings: self.settings["VERSION"] = VERSION if not "SAMPLE_BUFFER_SIZE" in self.settings: self.size = DEFAULT_SIZE else: self.size = settings["SAMPLE_BUFFER_SIZE"] # times to control watchdog sends to platform self.prev_send_time = None self.display = Display(self.settings, self.SIMULATION_MODE) # Create a 30-entry x 1-second stats buffer self.stats_buffer = StatsBuffer(size=STATS_HISTORY_SIZE, duration=STATS_DURATION, settings=self.settings) self.sample_buffer = TimeBuffer(size=self.size, settings=self.settings, stats_buffer=self.stats_buffer ) self.event_buffer = TimeBuffer(size=EVENT_HISTORY_SIZE, settings=self.settings) self.events = Events(settings=self.settings, sample_buffer=self.sample_buffer, event_buffer=self.event_buffer, stats_buffer=self.stats_buffer )
def __init__(self, settings=None): print("SensorHub __init()__") self.settings = settings self.new_status = None # timestamp, weight of current pot of coffee self.grind_status = None # most recent timestamp, power from grinder self.brew_status = None # most recent timestamp, power from brew machine # LCD DISPLAY self.display = Display(self.settings) # EVENTS PATTERN MATCH self.events = Events(settings=self.settings) # Connect to the platform if ("SIMULATE_UPLINK" in self.settings and self.settings["SIMULATE_UPLINK"]): self.uplink = LinkSimulator(settings=self.settings) else: self.uplink = Uplink(settings=self.settings)
def __init__(self): #setting the pygame window title = "MacGyver's Maze" display = Display(600, 650, title) #Setting the map mapping = Map("mapping.txt") display.set_map(mapping) #Setting the characters bad_guy = Character(1, 14, "guardian.png", mapping) gyver = MacGyver(14, 0, "macgyver.png", mapping) display.set_characters(gyver, bad_guy) pygame.display.flip() self._start_game(mapping, gyver, bad_guy, display)
def __init__(self): """function to set the game : creating the map, placing the items randomly, MacGyver and the Guardian's location must be specified (y, x). Once it's done, starting the game. """ #setting the pygame window title = "MacGyver's Labyrinth" display = Display(600, 650, title) #Setting the map mapping = Map("mapping.txt") display.set_map(mapping) #Setting the characters bad_guy = Character(1, 14, "guardian.png", mapping) gyver = MacGyver(14, 0, "macgyver.png", mapping) display.set_characters(gyver, bad_guy) pygame.display.flip() self._start_game(mapping, gyver, bad_guy, display)
def __init__(self): self.display = Display(self, (const.WIN_WIDTH, const.WIN_HEIGHT)) self.player = Player(self)
class Sensor(object): # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- # __init__() called on startup # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- def __init__(self, settings=None): global GPIO_FAIL self.SIMULATION_MODE = GPIO_FAIL self.settings = settings if self.settings is None: self.settings = { } if not "VERSION" in self.settings: self.settings["VERSION"] = VERSION if not "SAMPLE_BUFFER_SIZE" in self.settings: self.size = DEFAULT_SIZE else: self.size = settings["SAMPLE_BUFFER_SIZE"] # times to control watchdog sends to platform self.prev_send_time = None self.display = Display(self.settings, self.SIMULATION_MODE) # Create a 30-entry x 1-second stats buffer self.stats_buffer = StatsBuffer(size=STATS_HISTORY_SIZE, duration=STATS_DURATION, settings=self.settings) self.sample_buffer = TimeBuffer(size=self.size, settings=self.settings, stats_buffer=self.stats_buffer ) self.event_buffer = TimeBuffer(size=EVENT_HISTORY_SIZE, settings=self.settings) self.events = Events(settings=self.settings, sample_buffer=self.sample_buffer, event_buffer=self.event_buffer, stats_buffer=self.stats_buffer ) # ----------------- # Start sensor # ----------------- def begin(self): # set counter for how many samples to collect before saving if self.settings is None or not "SAMPLE_SAVE_COUNT" in self.settings: self.save_count = 0 else: self.save_count = self.settings["SAMPLE_SAVE_COUNT"] self.save_counter = 0 # cumulative count of how many samples we've collected print("Set save_count to", self.save_count) self.display.begin() # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- # SEND DATA TO PLATFORM # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- # Post data to platform as json. # post_data is a python dictionary to be converted to json. def send_data(self, post_data): try: #print("send_data() to {}".format(self.settings["FEEDMAKER_URL"])) if not self.SIMULATION_MODE: response = requests.post( self.settings["FEEDMAKER_URL"], headers={ self.settings["FEEDMAKER_HEADER_KEY"] : self.settings["FEEDMAKER_HEADER_VALUE"] }, json=post_data ) print("status code:",response.status_code) debug_str = json.dumps( post_data, sort_keys=True, indent=4, separators=(',', ': ')) #print("sent:\n {}".format(debug_str)) except Exception as e: print("send_data() error with {}".format(post_data)) print(e) def send_weight(self, ts, weight_g): post_data = { 'msg_type': 'coffee_pot_weight', 'request_data': [ { 'acp_id': self.settings["SENSOR_ID"], 'acp_type': self.settings["SENSOR_TYPE"], 'acp_ts': ts, 'acp_units': 'GRAMS', 'weight': math.floor(weight_g+0.5), # rounded to integer grams 'version': self.settings["VERSION"] } ] } self.send_data(post_data) def send_event(self, ts, event_data): message_data = { 'acp_id': self.settings["SENSOR_ID"], 'acp_type': self.settings["SENSOR_TYPE"], 'acp_ts': ts, 'version': self.settings["VERSION"] } print("{:.3f},{:5.1f},{},".format(ts, event_data['weight'], event_data['event_code']), event_data) # merge dictionaries message_data = { **message_data, **event_data } post_data = { 'msg_type': 'coffee_pot_event', 'request_data': [ message_data ] } self.send_data(post_data) # -------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------- # # process_sample(timestamp, value) # # Here is where we process each sensor sample, updating the LCD and checking for events # # -------------------------------------------------------------------------------------- # -------------------------------------------------------------------------------------- def process_sample(self, ts, value): t_start = time.process_time() if self.settings["LOG_LEVEL"] == 1: print("process_sample got value {:.1f} at {:.3f} secs.".format(value, time.process_time() - t_start)) # store weight and time in sample_history self.sample_buffer.put(ts, value) if self.save_count > 0: self.save_counter += 1 if self.save_counter >= self.save_count: self.sample_buffer.save("../data/save_{:.3f}.csv".format(time.time())) self.save_counter = 0 # --------------------------------- # TEST EVENTS AND SEND TO PLATFORM # --------------------------------- events_now = self.events.test(ts, value) for event in events_now: self.event_buffer.put(ts, event) if event["event_code"] == self.events.EVENT_NEW: self.display.update_new(ts) self.send_event(ts, event) #---------------- # UPDATE DISPLAY # --------------- self.display.update(ts, self.sample_buffer, debug_list) # ------------------------------------------ # SEND 'WATCHDOG' (WITH WEIGHT) TO PLATFORM # ------------------------------------------ if self.prev_send_time is None: self.prev_send_time = ts WATCHDOG_PERIOD = 120 if ts - self.prev_send_time > WATCHDOG_PERIOD: sample_value, offset, duration, sample_count = self.sample_buffer.median(0,2) # from latest ts, back 2 seconds if not sample_value == None: print ("{:.3f},{:5.1f},WEIGHT,".format(ts, sample_value), "{}".format(time.ctime(ts))) self.send_weight(ts, sample_value) self.prev_send_time = ts if self.settings["LOG_LEVEL"] == 1: print("process_sample send data at {:.3f} secs.".format(time.process_time() - t_start)) else: print("process_sample send data NOT SENT as data value None") if self.settings["LOG_LEVEL"] == 1: print ("WEIGHT {:5.1f}, {}".format(value, time.ctime(ts))) if self.settings["LOG_LEVEL"] == 1: print("process_sample time (before sleep) {:.3f} secs.\n".format(time.process_time() - t_start)) # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- # finish() - cleanup and exit if main loop is interrupted # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- def finish(self): print("\n") if not self.SIMULATION_MODE: self.display.finish() print("GPIO cleanup()...") GPIO.cleanup() print("Exitting") sys.exit()
class SensorHub(object): """ The SensorHub is created by a SensorNode and provides a .process_reading() function that looks at the values in the various sensor buffers and decides whether an event should be sent to the platform. """ def __init__(self, settings=None): print("SensorHub __init()__") self.settings = settings self.new_status = None # timestamp, weight of current pot of coffee self.grind_status = None # most recent timestamp, power from grinder self.brew_status = None # most recent timestamp, power from brew machine # LCD DISPLAY self.display = Display(self.settings) # EVENTS PATTERN MATCH self.events = Events(settings=self.settings) # Connect to the platform if ("SIMULATE_UPLINK" in self.settings and self.settings["SIMULATE_UPLINK"]): self.uplink = LinkSimulator(settings=self.settings) else: self.uplink = Uplink(settings=self.settings) # start() is async to allow Uplink.put async def start(self, ts): self.display.begin() uplink_settings = {} uplink_settings["host"] = self.settings["PLATFORM_HOST"] uplink_settings["port"] = self.settings["PLATFORM_PORT"] uplink_settings["user"] = self.settings["PLATFORM_USER"] uplink_settings["password"] = self.settings["PLATFORM_PASSWORD"] await self.uplink.start(uplink_settings) # Send startup message startup_event = { "acp_ts": ts, "acp_id": self.settings["SENSOR_ID"], "acp_confidence": 1, "event_code": EventCode.STARTUP } #send to platform await self.uplink.put(self.settings["SENSOR_ID"], startup_event) # A LocalSensor or RemoteSensor will call this add_buffers() method to # make their TimeBuffers visible to Events # e.g. { "sample_buffer": self.sample_buffer, # "stats_buffer": self.stats_buffer # } def add_buffers(self, sensor_id, buffers): print("SensorHub adding buffers for {}".format(sensor_id)) self.events.sensor_buffers[sensor_id] = buffers # watchdog is called by Watchdog coroutine periodically async def watchdog(self): ts = time.time() print("{:.3f} SensorHub() watchdog...".format(ts)) # ------------------------------------------ # SEND 'STATUS' (WITH WEIGHT) TO PLATFORM # ------------------------------------------ weight_sensor_id = self.settings["WEIGHT_SENSOR_ID"] weight_sample_buffer = self.events.sensor_buffers[weight_sensor_id][ "sample_buffer"] sample_value, offset, duration, sample_count = weight_sample_buffer.median( 0, 2) if not sample_value == None: print("{:.3f} WEIGHT {:5.1f}".format(ts, sample_value)) await self.send_status(ts, sample_value) if self.settings["LOG_LEVEL"] == 1: print("SensorHub.watchdog() send status at {:.3f}".format( time.process_time())) else: print("SensorHub.watchdog() status NOT SENT as data value None") # send 'status' event (periodic) async def send_status(self, ts, weight_g): weight_event = { 'acp_id': self.settings["SENSOR_ID"], 'acp_type': self.settings["SENSOR_TYPE"], 'acp_ts': ts, 'acp_units': 'GRAMS', 'event_code': EventCode.STATUS, 'weight': math.floor(weight_g + 0.5), # rounded to integer grams 'version': self.settings["VERSION"] } # Add status (e.g. timestamp, weight) of latest brew if we have one if not self.new_status is None: weight_event["new_status"] = self.new_status # Add status (e.g. timestamp, power) of latest grind if we have one if not self.grind_status is None: weight_event["grind_status"] = self.grind_status # Add status (e.g. timestamp, power) of latest brewing if we have one if not self.brew_status is None: weight_event["brew_status"] = self.brew_status #send MQTT topic, message await self.uplink.put(self.settings["SENSOR_ID"], weight_event) # process_reading(ts, sensor_id) is called by each of the sensors, i.e. # LocalSensors and RemoteSensors, each time they have a reading to be # processed. The Events module can use 'sensor_id' to determine the # source of the reading. All events sent to the Platform are labelled # with the sensor_id of the sensor node, not the individual sensor. async def process_reading(self, ts, sensor_id): t_start = time.process_time() weight_sensor_id = self.settings["WEIGHT_SENSOR_ID"] weight_sample_buffer = self.events.sensor_buffers[weight_sensor_id][ "sample_buffer"] # --------------------------------- # TEST EVENTS AND SEND TO PLATFORM # --------------------------------- events_list = self.events.test(ts, sensor_id) for event in events_list: # display time of new brew is we have one event_code = event["event_code"] # If this event is a NEW POT then update display and record the time if event_code == EventCode.NEW: self.new_status = { "acp_ts": ts, "weight": event["weight"], "weight_new": event["weight_new"], "acp_confidence": event["acp_confidence"] } self.display.update_new(ts) # If this event is from the GRINDER then record the grind status for next COFFEE_STATUS event elif event_code == EventCode.GRINDING or event_code == EventCode.GRIND_STATUS: self.grind_status = { "acp_ts": ts, "power": event["value"]["ENERGY"]["Power"], "acp_units": "WATTS" } # For a 'status' message from a RemoteSensor we only store it and return. if event_code == EventCode.GRIND_STATUS: return # If this event is from the BREWER then record the brew status for the next COFFEE_STATUS event elif event_code == EventCode.BREWING or event_code == EventCode.BREW_STATUS: self.brew_status = { "acp_ts": ts, "power": event["value"]["ENERGY"]["Power"], "acp_units": "WATTS" } # For a 'status' message from a RemoteSensor we only store it and return. if event_code == EventCode.BREW_STATUS: return # piggyback a weight property if the event doesn't already include it. if not "weight" in event: weight_stats_buffer = self.events.sensor_buffers[ weight_sensor_id]["stats_buffer"] # we'll add a weight value for events that don't include it default_weight = weight_stats_buffer.get(0)["value"]["median"] if default_weight is None: default_weight = 0 event["weight"] = math.floor(default_weight + 0.5) # also piggyback the timestamp of the most recent new brew if not self.new_status is None: event["new_status"] = self.new_status # add acp_id, acp_ts, acp_type event_params = { "acp_ts": ts, "acp_id": self.settings["SENSOR_ID"], "acp_type": self.settings["SENSOR_TYPE"] } #send MQTT topic, message event_to_send = {**event, **event_params} await self.uplink.put(self.settings["SENSOR_ID"], event_to_send) self.display.update_event(ts, event) #---------------- # UPDATE DISPLAY # --------------- self.display.update(ts, weight_sample_buffer) if self.settings["LOG_LEVEL"] == 1: print("WEIGHT,{:.3f},{:.3f}".format( ts, weight_sample_buffer.get(0)["value"])) if self.settings["LOG_LEVEL"] == 1: print("process_reading time (before sleep) {:.3f} secs.\n".format( time.process_time() - t_start)) async def finish(self): await self.uplink.finish() if not self.settings["SIMULATE_DISPLAY"]: self.display.finish()
from classes.config import Config c = Config() from classes.display import Display d = Display(c.settings, True) # Emulate d.begin() from classes.display import Pot p = Pot(d.LCD) p.begin() import numpy import time def play(): for i in numpy.arange(0, 1, 0.01): p.update(i) time.sleep(0.1) for i in numpy.arange(1, 0, -0.01): p.update(i) time.sleep(0.1)
def main(): print("initializing") pool = ThreadPool(processes=1) #Time operator have to push button after product is detected IMG_SAVE_DELAY = 500 #This is used to signal that if operator dont push button then save image to approved folder flagPhotoSensor = False #Resolution on image resolution = (1280, 720) #Paths to put images path_approved = '/media/storage/good/' path_not_approved = '/media/storage/bad/' #Create camera object that takes images and store in approved or not approved folder camera = Camera(resolution, 'png', path_approved, path_not_approved) #GPIO stuff on_off = GPIO(7, 'in') disallowed_img = GPIO(138, 'in') disallowed_img.edge = 'rising' photoSensor = GPIO(140, 'in') photoSensor.edge = 'rising' #Create Display object display = Display() #Variable to handle debounce on input from photosensor lastPhotoSensorValue = False #Variable to handle debounce on input from operator button lastOperatorBtnValue = False #Get time in ms currentTime_ms = lambda: int(round(time.time() * 1000)) #Calculate new time - old time to get time difference between two events deltaTime_ms = lambda oldTime_ms: int(round(time.time() * 1000) ) - oldTime_ms #Store time to calculate time difference oldTime_ms = currentTime_ms() print("initialization done") #Run forever while True: #If system is turned on by switch, run program display.off() if on_off.read() or True: print("System started") #Make sure no old values are stored flagPhotoSensor = False camera.camera.start() #Stay in loop as long as system is turned on while on_off.read() or True: #If there is a product in front of camera, take a picture and record the time if photoSensor.read( ) and not lastPhotoSensorValue and not flagPhotoSensor: #img = camera.camera.get_image() async_img = pool.apply_async(camera.take_image) oldTime_ms = currentTime_ms() #Save that photo sensor has been high flagPhotoSensor = True #If operator push button before IMG_SAVE_DELAY time, save image to not approved folder #and blink red light once to inform operator while deltaTime_ms(oldTime_ms) <= IMG_SAVE_DELAY: if disallowed_img.read() and not lastOperatorBtnValue: img = async_img.get() threading.Thread(target=display.show_img, args=(img, False)).start() camera.save_img(img, False) flagPhotoSensor = False lastOperatorBtnValue = disallowed_img.read() #if operator dont push button before IMG_SAVE_DELAY time run out, save #image to approved folder and blink green light. if (deltaTime_ms(oldTime_ms) > IMG_SAVE_DELAY) and flagPhotoSensor: img = async_img.get() threading.Thread(target=display.show_img, args=(img, True)).start() camera.save_img(img, True) flagPhotoSensor = False camera.camera.stop() lastPhotoSensorValue = photoSensor.read()
def __init__(self): """let's create our class and display home page""" display = Display() display.home()