def __init__(self): """Initialise the bentv_ui class - reads the configuration file and initialises the screen and GPIO monitor""" print "bentv.__init__()" configPath = "%s/%s" % (os.path.dirname( os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath, self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self.debounce_ms = self.cfg.getConfigInt("debounce_ms") self.shortpress_ms = self.cfg.getConfigInt("shortpress_ms") self.hostname, self.ipaddr = self.getHostName() print self.hostname, self.ipaddr self.timeDown = 0.0 self.presetNo = 1 self.shortPress = False self.longPress = False self.initScreen() self.initGPIO() self.UIMode = self.CAMERA_MODE # Next line changes mode to start in # FITDECT_MODE. self.changeUIMode() # Initialises the messages.
def __init__(self): """Initialise the bentv_ui class - reads the configuration file and initialises the screen and GPIO monitor""" print "bentv.__init__()" configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath,self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self.debounce_ms = self.cfg.getConfigInt("debounce_ms") self.shortpress_ms = self.cfg.getConfigInt("shortpress_ms") self.hostname, self.ipaddr = self.getHostName() print self.hostname, self.ipaddr self.timeDown = 0.0 self.presetNo = 1 self.shortPress = False self.longPress = False self.initScreen() self.initGPIO() self.UIMode = self.CAMERA_MODE # Next line changes mode to start in # FITDECT_MODE. self.changeUIMode() # Initialises the messages.
def __init__(self): """Initialise the bentv_ui class - reads the configuration file and initialises the screen and GPIO monitor""" print "bentv.__init__()" configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath,self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self.hostname, self.ipaddr = self.getHostName() print self.hostname, self.ipaddr self.presetNo = 1 self.initScreen() self.initGPIO()
def __init__(self,port = None): print "runServer.__init__()" print os.path.realpath(__file__) configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath,self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self._wkdir = self.cfg.getConfigStr("working_directory") if (self.debug): print "working_directory=%s\n" % self._wkdir self._tmpdir = self.cfg.getConfigStr("tmpdir") if (self.debug): print "tmpdir=%s\n" % self._tmpdir if (port == None): port = '/dev/ttyUSB0' print "Opening Serial Connection on %s" % port self.ser = serial.Serial(port,9600,timeout=1) print "Waiting for serial comms to settle..." time.sleep(2) print "Reading first line of data, and ignoring it." line = self.ser.readline() # throw away any part lines print "line=%s" % line self.start() print "waiting for some data..." while(self.ser.inWaiting() < 10): print "waiting - inWaiting()=%d" % self.ser.inWaiting() time.sleep(1) print "wait over!" print "ignoring a few lines for start command to register..." for n in range(0,5): line = self.ser.readline() # throw away any part lines print "line=%s" % line #Initialise data lists. self.t=[] # initialize the data lists self.d1=[] self.d2=[] self.d3=[] self.d4=[] self.d5=[] self.d6=[] # Start web server self._ws = webServer.WebServer(self) webServer.setRoutes(self._ws) # Run our main loop. self.run()
def __init__(self, save=False, inFile=None): print "benFinder.__init__()" print os.path.realpath(__file__) configPath = "%s/%s" % (os.path.dirname( os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath, self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self._wkdir = self.cfg.getConfigStr("working_directory") if (self.debug): print "working_directory=%s\n" % self._wkdir self._tmpdir = self.cfg.getConfigStr("tmpdir") if (self.debug): print "tmpdir=%s\n" % self._tmpdir # Check if we are running from live kinect or a file. if (inFile): device = depth.CV_CAP_FILE else: device = depth.CV_CAP_FREENECT # Initialise the captureManager self._captureManager = CaptureManager(device, None, True, inFile=inFile) self._captureManager.channel = depth.CV_CAP_OPENNI_DEPTH_MAP # If we are runnign from a file, use the first frame as the # background image. if (inFile): self.saveBgImg() # If we have asked to save the background image, do that, and exit, # otherwise initialise the seizure detector. if (save): self.saveBgImg() else: self.loadBgImg() self.autoBackgroundImg = None self._status = self.ALARM_STATUS_OK self._ts = TimeSeries( tslen=self.cfg.getConfigInt("timeseries_length")) self._frameCount = 0 self._outputFrameCount = 0 self._nPeaks = 0 self._ts_time = 0 self._rate = 0 self._ws = webServer.benWebServer(self) self._ws.setBgImg( "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("background_depth"))) self._ws.setChartImg( "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("chart_fname"))) self._ws.setRawImg( "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("raw_image_fname"))) self._ws.setMaskedImg( "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("masked_image_fname"))) self._ws.setDataFname( "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("data_fname"))) self._ws.setAnalysisResults({}) webServer.setRoutes(self._ws) self.run()
class BenFinder(object): configFname = "config.ini" configSection = "benFinder" ALARM_STATUS_OK = 0 # All ok, no alarms. ALARM_STATUS_WARN = 1 # Warning status ALARM_STATUS_FULL = 2 # Full alarm status. ALARM_STATUS_NOT_FOUND = 3 # Benjamin not found in image # (area below config area_threshold parameter) def __init__(self, save=False, inFile=None): print "benFinder.__init__()" print os.path.realpath(__file__) configPath = "%s/%s" % (os.path.dirname( os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath, self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self._wkdir = self.cfg.getConfigStr("working_directory") if (self.debug): print "working_directory=%s\n" % self._wkdir self._tmpdir = self.cfg.getConfigStr("tmpdir") if (self.debug): print "tmpdir=%s\n" % self._tmpdir # Check if we are running from live kinect or a file. if (inFile): device = depth.CV_CAP_FILE else: device = depth.CV_CAP_FREENECT # Initialise the captureManager self._captureManager = CaptureManager(device, None, True, inFile=inFile) self._captureManager.channel = depth.CV_CAP_OPENNI_DEPTH_MAP # If we are runnign from a file, use the first frame as the # background image. if (inFile): self.saveBgImg() # If we have asked to save the background image, do that, and exit, # otherwise initialise the seizure detector. if (save): self.saveBgImg() else: self.loadBgImg() self.autoBackgroundImg = None self._status = self.ALARM_STATUS_OK self._ts = TimeSeries( tslen=self.cfg.getConfigInt("timeseries_length")) self._frameCount = 0 self._outputFrameCount = 0 self._nPeaks = 0 self._ts_time = 0 self._rate = 0 self._ws = webServer.benWebServer(self) self._ws.setBgImg( "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("background_depth"))) self._ws.setChartImg( "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("chart_fname"))) self._ws.setRawImg( "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("raw_image_fname"))) self._ws.setMaskedImg( "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("masked_image_fname"))) self._ws.setDataFname( "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("data_fname"))) self._ws.setAnalysisResults({}) webServer.setRoutes(self._ws) self.run() def run(self): """Run the main loop.""" while (True): self._captureManager.enterFrame() frame = self._captureManager.frame if frame is not None: if (self.autoBackgroundImg == None): self.autoBackgroundImg = numpy.float32(frame) rawFrame = frame.copy() # First work out the region of interest by # subtracting the fixed background image # to create a mask. #print frame #print self._background_depth_img absDiff = cv2.absdiff(frame, self._background_depth_img) benMask, maskArea = filters.getBenMask(absDiff, 8) cv2.accumulateWeighted(frame, self.autoBackgroundImg, 0.05) # Convert the background image into the same format # as the main frame. #bg = self.autoBackgroundImg bg = cv2.convertScaleAbs(self.autoBackgroundImg, alpha=1.0) # Subtract the background from the frame image cv2.absdiff(frame, bg, frame) # Scale the difference image to make it more sensitive # to changes. cv2.convertScaleAbs(frame, frame, alpha=100) # Apply the mask so we only see the test subject. frame = cv2.multiply(frame, benMask, dst=frame, dtype=-1) if (maskArea <= self.cfg.getConfigInt('area_threshold')): bri = (0, 0, 0) else: # Calculate the brightness of the test subject. bri = filters.getMean(frame, benMask) # Add the brightness to the time series ready for analysis. self._ts.addSamp(bri[0]) self._ts.addImg(rawFrame) # Write timeseries to a file every 'output_framecount' frames. if (self._outputFrameCount >= self.cfg.getConfigInt('output_framecount')): # Write timeseries to file self._ts.writeToFile("%s/%s" % \ ( self.cfg.getConfigStr('output_directory'), self.cfg.getConfigStr('ts_fname') )) self._outputFrameCount = 0 else: self._outputFrameCount = self._outputFrameCount + 1 # Only do the analysis every 15 frames (0.5 sec), or whatever # is specified in configuration file analysis_framecount # parameter. if (self._frameCount < self.cfg.getConfigInt('analysis_framecount')): self._frameCount = self._frameCount + 1 else: # Look for peaks in the brightness (=movement). self._nPeaks, self._ts_time, self._rate = self._ts.findPeaks( ) #print "%d peaks in %3.2f sec = %3.1f bpm" % \ # (nPeaks,ts_time,rate) oldStatus = self._status if (maskArea > self.cfg.getConfigInt('area_threshold')): # Check for alarm levels if (self._rate > self.cfg.getConfigInt("rate_warn")): self._status = self.ALARM_STATUS_OK elif (self._rate > self.cfg.getConfigInt("rate_alarm")): self._status = self.ALARM_STATUS_WARN else: self._status = self.ALARM_STATUS_FULL else: self._status = self.ALARM_STATUS_NOT_FOUND if (oldStatus == self.ALARM_STATUS_OK and self._status == self.ALARM_STATUS_WARN) or \ (oldStatus == self.ALARM_STATUS_WARN and self._status == self.ALARM_STATUS_FULL): # Write timeseries to file self._ts.writeToFile("%s/%s" % \ ( self.cfg.getConfigStr('output_directory'), self.cfg.getConfigStr('alarm_ts_fname') ),bgImg=self._background_depth_img) # Collect the analysis results together and send them # to the web server. resultsDict = {} resultsDict['fps'] = "%3.0f" % self.fps resultsDict['bri'] = "%4.0f" % self._ts.mean resultsDict['area'] = "%6.0f" % maskArea resultsDict['nPeaks'] = "%d" % self._nPeaks resultsDict['ts_time'] = self._ts_time resultsDict['rate'] = "%d" % self._rate resultsDict['time_t'] = time.ctime() resultsDict['status'] = self._status self._ws.setAnalysisResults(resultsDict) # Write the results to file as a json string utils.writeJSON(resultsDict,"%s/%s" % \ (self._tmpdir, self.cfg.getConfigStr("data_fname"))) utils.writeLog(resultsDict,"%s/%s" % \ (self._tmpdir, "benFinder_alarms.log")) # Plot the graph of brightness, and save the images # to disk. self._ts.plotRawData( file=True, fname="%s/%s" % \ (self._tmpdir,self.cfg.getConfigStr("chart_fname"))) cv2.imwrite( "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("raw_image_fname")), rawFrame) cv2.imwrite( "%s/%s" % (self._tmpdir, self.cfg.getConfigStr("masked_image_fname")), frame) self._frameCount = 0 else: print "Null frame received - assuming end of file and exiting" break self._captureManager.exitFrame() @property def fps(self): return self._captureManager.fps @property def nPeaks(self): return self._nPeaks @property def ts_time(self): return self._ts_time @property def rate(self): return self._rate @property def rawImgFname(self): return self.cfg.getConfigStr("raw_image_fname") @property def maskedImgFname(self): return self.cfg.getConfigStr("masked_image_fname") @property def chartImgFname(self): return self.cfg.getConfigStr("chart_fname") def saveBgImg(self): """ Write a new background image to the appropriate file location.""" if (self._captureManager.hasEnteredFrame): self._captureManager.exitFrame() self._captureManager.enterFrame() print "Writing image to %s." % self.cfg.getConfigStr( "background_depth") self._captureManager.writeImage( "%s/%s" % (self._wkdir, self.cfg.getConfigStr("background_depth"))) print self._captureManager.frame print self._captureManager.frame.dtype self._captureManager.exitFrame() self.loadBgImg() def loadBgImg(self): print "Loading background image %s/%s." % \ (self._wkdir,self.cfg.getConfigStr("background_depth")) self._background_depth_img = cv2.imread("%s/%s" % \ (self._wkdir,self.cfg.getConfigStr("background_depth")), cv2.CV_LOAD_IMAGE_GRAYSCALE) # cv2.CV_LOAD_IMAGE_UNCHANGED) print self._background_depth_img print self._background_depth_img.dtype
class bentv_ui: # Basic Configuration configFname = "config.ini" configSection = "bentv" debug = False # Initialise some instance variables. screen = None font = None textLine1 = "BenTV_UI" textLine2 = "Waiting for Button Press to move camera" presetNo = 1 presetTxt = ['NULL','Behind Door', 'Corner', 'Chair', 'Bed'] # Alarms ALARM_STATUS_OK = 0 # All ok, no alarms. ALARM_STATUS_WARN = 1 # Warning status ALARM_STATUS_FULL = 2 # Full alarm status. ALARM_STATUS_NOT_FOUND = 3 # Benjamin not found in image # (area below config area_threshold parameter) statusStrs = ("OK","Warning","ALARM!!!","Ben Not Found") screenBGColours = ( (0,0,255), # Blue for all ok (128,128,0), # Yellow for warning (255,0,0), # Red for full alarm. (128,128,128) # Grey for not found. ) alarmStatus = 0 # Current alarm status def __init__(self): """Initialise the bentv_ui class - reads the configuration file and initialises the screen and GPIO monitor""" print "bentv.__init__()" configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath,self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self.hostname, self.ipaddr = self.getHostName() print self.hostname, self.ipaddr self.presetNo = 1 self.initScreen() self.initGPIO() def getIpAddr(self,ifname): """Return the IP Address of the given interface (e.g 'wlan0') from http://raspberrypi.stackexchange.com/questions/6714/how-to-get-the-raspberry-pis-ip-address-for-ssh. """ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa(fcntl.ioctl( s.fileno(), 0x8915, # SIOCGIFADDR struct.pack('256s', ifname[:15]) )[20:24]) def getHostName(self): """Returns the hostname and IP address of the wireless interface as a tuple. """ hostname = socket.gethostname() ipaddr = self.getIpAddr("wlan0") return (hostname,ipaddr) def initGPIO(self): """Initialise the GPIO pins - not we use GPIO pin numbers, not physical pin numbers on rpi.""" haveGPIO = True try: import RPi.GPIO as GPIO except: print "failed to import RPi.GPIO" haveGPIO = False pinNo = self.cfg.getConfigInt("gpiono") if (self.debug): print "gpioNo = %d" % pinNo if (haveGPIO): GPIO.setmode(GPIO.BCM) GPIO.setup(pinNo, GPIO.IN, pull_up_down=GPIO.PUD_UP) # very long debounce time to prevent presses while camera is moving. GPIO.add_event_detect(pinNo, GPIO.RISING, callback=self.moveCamera, bouncetime=1000) else: print "no GPIO - simulating camera move" self.moveCamera(1) def display_text(self): """ Write the given text onto the display area of the screen""" # Clear screen self.screen.fill(self.screenBGColours[self.alarmStatus]) # Line 1 text txtImg = self.font.render(self.textLine1, True,(255,255,255)) self.screen.blit(txtImg,(0,380)) # Line 1 time tnow = time.localtime(time.time()) txtStr = "%02d:%02d:%02d " % (tnow[3],tnow[4],tnow[5]) w = self.font.size(txtStr)[0] txtImg = self.font.render(txtStr, True,(255,255,255)) self.screen.blit(txtImg,(self.fbSize[0]-w,380)) # Line 2 text txtImg = self.smallFont.render(self.textLine2, True,(255,255,255)) self.screen.blit(txtImg,(0,400)) # Line 2 network info txtStr = "Host: %s, IP: %s " % (self.hostname, self.ipaddr) w = self.smallFont.size(txtStr)[0] txtImg = self.smallFont.render(txtStr, True, (255,255,255)) self.screen.blit(txtImg,(self.fbSize[0]-w,400)) pygame.display.update() def initScreen(self): """Initialise the display using the pygame library""" drivers = ['x11', 'fbcon', 'svgalib'] found = False disp_no = os.getenv("DISPLAY") if disp_no: print "I'm running under X display = {0}".format(disp_no) for driver in drivers: # Make sure that SDL_VIDEODRIVER is set if not os.getenv('SDL_VIDEODRIVER'): os.putenv('SDL_VIDEODRIVER', driver) try: pygame.display.init() print 'Using Driver: {0}.'.format(driver) except pygame.error: print 'Driver: {0} failed.'.format(driver) continue found = True break if not found: raise Exception('No suitable video driver found!') self.fbSize = (pygame.display.Info().current_w, pygame.display.Info().current_h) print "Framebuffer size: %d x %d" % self.fbSize if (disp_no): print "Using X11 window" winSize = (640,480) self.screen = pygame.display.set_mode(winSize) self.fbSize = winSize else: print "Using full screen framebuffer" self.screen = pygame.display.set_mode(self.fbSize, pygame.FULLSCREEN) print "blank screen..." self.screen.fill((0, 0, 255)) print "initialise fonts" pygame.font.init() self.font = pygame.font.Font(None,30) self.smallFont = pygame.font.Font(None,16) print "calling display_text()" self.display_text() print "initScreen complete" def moveCamera(self,pinNo): """Callback function when button is pressed""" print('moveCamera called by pin number %d. PresetNo=%d' % (pinNo,self.presetNo)) h = httplib2.Http(".cache") h.add_credentials(self.cfg.getConfigStr('uname'), self.cfg.getConfigStr('passwd')) #resp, content = h.request("http://192.168.1.24/preset.cgi?-act=goto&-status=1&-number=%d" % self.presetNo,"GET") resp, content = h.request("%s/%s%d" % (self.cfg.getConfigStr('camaddr'), self.cfg.getConfigStr('cammoveurl'), self.presetNo),"GET") print "moved to preset %d - content=%s" % (self.presetNo,content) self.textLine1 = "Camera Position %d (%s)" % (self.presetNo, self.presetTxt[self.presetNo]) self.presetNo += 1 if (self.presetNo > 4): self.presetNo = 1 def getBenFinderData(self): print "getBenfinderData" h = httplib2.Http(".cache") h.add_credentials(self.cfg.getConfigStr('uname'), self.cfg.getConfigStr('passwd')) requestStr = "%s:%s/%s" % \ (self.cfg.getConfigStr('benfinderserver'), self.cfg.getConfigStr('benfinderport'), self.cfg.getConfigStr('benfinderurl')) print requestStr try: resp, content = h.request(requestStr, "GET") dataDict = json.loads(content) self.alarmStatus = int(dataDict['status']) self.textLine1 = " Rate = %d bpm (status=%d - %s)" % \ (int(dataDict['rate']), int(dataDict['status']), self.statusStrs[int(dataDict['status'])] ) print dataDict['time_t'] self.textLine2 = " Fit Detector Time = %s " % dataDict['time_t'] print resp,content return True except: print "Error:",sys.exc_info()[0] self.textLine1 = "No Connection to Fit Detector" return False
class bentv_ui: # Basic Configuration configFname = "config.ini" configSection = "bentv" debug = False # Initialise some instance variables. screen = None font = None textLine1 = "Camera_Mode" textLine2 = "Waiting for Button Press to move camera" presetNo = 1 presetTxt = ['NULL', 'Behind Door', 'Corner', 'Chair', 'Bed'] # UI Modes CAMERA_MODE = 0 FITDECT_MODE = 1 # Alarms ALARM_STATUS_OK = 0 # All ok, no alarms. ALARM_STATUS_WARN = 1 # Warning status ALARM_STATUS_FULL = 2 # Full alarm status. ALARM_STATUS_NOT_FOUND = 3 # Benjamin not found in image # (area below config area_threshold parameter) statusStrs = ("OK", "Warning", "ALARM!!!", "Ben Not Found") screenBGColours = ( (0, 0, 255), # Blue for all ok (128, 128, 0), # Yellow for warning (255, 0, 0), # Red for full alarm. (128, 128, 128) # Grey for not found. ) alarmStatus = 0 # Current alarm status def __init__(self): """Initialise the bentv_ui class - reads the configuration file and initialises the screen and GPIO monitor""" print "bentv.__init__()" configPath = "%s/%s" % (os.path.dirname( os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath, self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self.debounce_ms = self.cfg.getConfigInt("debounce_ms") self.shortpress_ms = self.cfg.getConfigInt("shortpress_ms") self.hostname, self.ipaddr = self.getHostName() print self.hostname, self.ipaddr self.timeDown = 0.0 self.presetNo = 1 self.shortPress = False self.longPress = False self.initScreen() self.initGPIO() self.UIMode = self.CAMERA_MODE # Next line changes mode to start in # FITDECT_MODE. self.changeUIMode() # Initialises the messages. def getIpAddr(self, ifname): """Return the IP Address of the given interface (e.g 'wlan0') from http://raspberrypi.stackexchange.com/questions/6714/how-to-get-the-raspberry-pis-ip-address-for-ssh. """ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa( fcntl.ioctl( s.fileno(), 0x8915, # SIOCGIFADDR struct.pack('256s', ifname[:15]))[20:24]) def getHostName(self): """Returns the hostname and IP address of the wireless interface as a tuple. """ hostname = socket.gethostname() ipaddr = self.getIpAddr("wlan0") return (hostname, ipaddr) def initGPIO(self): """Initialise the GPIO pins - note we use GPIO pin numbers, not physical pin numbers on rpi.""" global haveGPIO pinNo = self.cfg.getConfigInt("gpiono") self.pinNo = pinNo if (self.debug): print "gpioNo = %d" % pinNo if (haveGPIO): GPIO.setmode(GPIO.BCM) GPIO.setup(pinNo, GPIO.IN, pull_up_down=GPIO.PUD_UP) # very long debounce time to prevent presses while camera is moving. #GPIO.add_event_detect(pinNo, # GPIO.FALLING, # callback=self.buttonCallback # ,bouncetime=100) else: print "no GPIO - simulating camera move" self.moveCamera(1) self.lastButtonVal = 1 self.lastButtonTime = time.time() def buttonCallback(self, pinNo): """ called on falling edge - it waits for rising edge to see how long the button press was. """ print "Button Down" self.timeDown = time.time() GPIO.wait_for_edge(pinNo, GPIO.RISING) print "Button Up" print "time of press = %f" % (time.time() - self.timeDown) def pollButtons(self): """poll the buttons, and set a variable to say if we have detected a single, double or long click.""" global haveGPIO if (haveGPIO): ip = GPIO.input(self.pinNo) tnow = time.time() if (ip != self.lastButtonVal): print "button state changed" if (ip): keyPressLength = (tnow - self.lastButtonTime) * 1000. #ms print "Keypress Length = %f sec" % (keyPressLength) if (keyPressLength < self.debounce_ms): print "Ignoring very short keypress" self.shortPress = False self.longPress = False elif (keyPressLength < self.shortpress_ms): print "short press" self.shortPress = True self.longPress = False else: self.shortPress = False self.longPress = True self.lastButtonVal = ip self.lastButtonTime = tnow else: pass # do nothing if we do not have GPIO access. def serviceUI(self): """Respond to button presses.""" if (self.longPress): if (self.UIMode == self.CAMERA_MODE): self.moveCamera(self.pinNo) elif (self.UIMode == self.FITDECT_MODE): self.setFitDectBackground() else: print "Unrecognised UIMode %d." % self.UIMode self.longPress = False if (self.shortPress): self.changeUIMode() self.shortPress = False def changeUIMode(self): """Change the UI mode - toggle between camera and fit detector""" if (self.UIMode == self.CAMERA_MODE): print "Entering FitDetector Mode" self.textLine1 = "Fit Detector Mode" self.textLine2 = " Press long button press to reset background. Short press to change mode." self.UIMode = self.FITDECT_MODE else: print "Entering Camera Mode" self.textLine1 = "Camera Mode" self.textLine2 = " Press long button press to move camera. Short press to change mode." self.UIMode = self.CAMERA_MODE self.alarmStatus = self.ALARM_STATUS_NOT_FOUND self.lastDisplayUpdateTime = time.time() #Force message to display for # a little while before being # overwritten. self.display_text() def display_text(self): """ Write the given text onto the display area of the screen""" # Clear screen self.screen.fill(self.screenBGColours[self.alarmStatus]) # Line 1 text txtImg = self.font.render(self.textLine1, True, (255, 255, 255)) self.screen.blit(txtImg, (0, 380)) # Line 1 time tnow = time.localtime(time.time()) txtStr = "%02d:%02d:%02d " % (tnow[3], tnow[4], tnow[5]) w = self.font.size(txtStr)[0] txtImg = self.font.render(txtStr, True, (255, 255, 255)) self.screen.blit(txtImg, (self.fbSize[0] - w, 380)) # Line 2 text txtImg = self.smallFont.render(self.textLine2, True, (255, 255, 255)) self.screen.blit(txtImg, (0, 400)) # Line 2 network info txtStr = "Host: %s, IP: %s " % (self.hostname, self.ipaddr) w = self.smallFont.size(txtStr)[0] txtImg = self.smallFont.render(txtStr, True, (255, 255, 255)) self.screen.blit(txtImg, (self.fbSize[0] - w, 400)) pygame.display.update() def initScreen(self): """Initialise the display using the pygame library""" drivers = ['x11', 'fbcon', 'svgalib'] found = False disp_no = os.getenv("DISPLAY") if disp_no: print "I'm running under X display = {0}".format(disp_no) for driver in drivers: # Make sure that SDL_VIDEODRIVER is set if not os.getenv('SDL_VIDEODRIVER'): os.putenv('SDL_VIDEODRIVER', driver) try: pygame.display.init() print 'Using Driver: {0}.'.format(driver) except pygame.error: print 'Driver: {0} failed.'.format(driver) continue found = True break if not found: raise Exception('No suitable video driver found!') self.fbSize = (pygame.display.Info().current_w, pygame.display.Info().current_h) print "Framebuffer size: %d x %d" % self.fbSize if (disp_no): print "Using X11 window" winSize = (640, 480) self.screen = pygame.display.set_mode(winSize) self.fbSize = winSize else: print "Using full screen framebuffer" self.screen = pygame.display.set_mode(self.fbSize, pygame.FULLSCREEN) print "blank screen..." self.screen.fill((0, 0, 255)) print "initialise fonts" pygame.font.init() self.font = pygame.font.Font(None, 30) self.smallFont = pygame.font.Font(None, 16) print "calling display_text()" self.display_text() print "initScreen complete" def moveCamera(self, pinNo): """Callback function when button is pressed""" print('moveCamera called by pin number %d. PresetNo=%d' % (pinNo, self.presetNo)) h = httplib2.Http(".cache") h.add_credentials(self.cfg.getConfigStr('uname'), self.cfg.getConfigStr('passwd')) #resp, content = h.request("http://192.168.1.24/preset.cgi?-act=goto&-status=1&-number=%d" % self.presetNo,"GET") resp, content = h.request( "%s/%s%d" % (self.cfg.getConfigStr('camaddr'), self.cfg.getConfigStr('cammoveurl'), self.presetNo), "GET") print "moved to preset %d - content=%s" % (self.presetNo, content) self.textLine1 = "Camera Position %d (%s)" % ( self.presetNo, self.presetTxt[self.presetNo]) self.presetNo += 1 if (self.presetNo > 4): self.presetNo = 1 def getBenFinderData(self): #print "getBenfinderData" h = httplib2.Http(".cache") h.add_credentials(self.cfg.getConfigStr('uname'), self.cfg.getConfigStr('passwd')) requestStr = "%s:%s/%s" % \ (self.cfg.getConfigStr('benfinderserver'), self.cfg.getConfigStr('benfinderport'), self.cfg.getConfigStr('benfinderurl')) #print requestStr try: resp, content = h.request(requestStr, "GET") dataDict = json.loads(content) self.alarmStatus = int(dataDict['status']) self.textLine1 = " Rate = %d bpm (status=%d - %s)" % \ (int(dataDict['rate']), int(dataDict['status']), self.statusStrs[int(dataDict['status'])] ) #print dataDict['time_t'] self.textLine2 = " Fit Detector Time = %s " % dataDict['time_t'] #print resp,content return True except: print "Error:", sys.exc_info()[0] self.textLine1 = "No Connection to Fit Detector" return False def setFitDectBackground(self): """Tell the fit detector to initialise its background image from the current image.""" print "setFitDectBackground()" h = httplib2.Http(".cache") h.add_credentials(self.cfg.getConfigStr('uname'), self.cfg.getConfigStr('passwd')) requestStr = "%s:%s/%s" % \ (self.cfg.getConfigStr('benfinderserver'), self.cfg.getConfigStr('benfinderport'), self.cfg.getConfigStr('benfinderbackgroundurl')) print requestStr try: resp, content = h.request(requestStr, "GET") print resp, content self.textLine1 = "Fit Detector Background Image Reset" self.textLine2 = " Press button to reset background. Long press to change mode." except: print "Error:", sys.exc_info()[0] self.textLine1 = "Error Initialising Fit Detector Background" self.textLine2 = " Press button to reset background. Long press to change mode." self.lastDisplayUpdateTime = time.time() #Force message to display for # a little while before being # overwritten. self.display_text() def run(self): """bentv main loop""" self.lastDisplayUpdateTime = time.time() while 1: tnow = time.time() self.pollButtons() self.serviceUI() if (tnow - self.lastDisplayUpdateTime >= 1.0): if (self.UIMode == self.FITDECT_MODE): self.getBenFinderData() if (tnow - self.lastDisplayUpdateTime >= 1.0): self.display_text() self.lastDisplayUpdateTime = tnow #print "main loop..." time.sleep(0.2)
class bentv_ui: # Basic Configuration configFname = "config.ini" configSection = "bentv" debug = False # Initialise some instance variables. screen = None font = None textLine1 = "Camera_Mode" textLine2 = "Waiting for Button Press to move camera" presetNo = 1 presetTxt = ['NULL', 'Behind Door', 'Corner', 'Chair', 'Bed'] # UI Modes CAMERA_MODE = 0 FITDECT_MODE = 1 # Alarms ALARM_STATUS_OK = 0 # All ok, no alarms. ALARM_STATUS_WARN = 1 # Warning status ALARM_STATUS_FULL = 2 # Full alarm status. ALARM_STATUS_NOT_FOUND = 3 # Benjamin not found in image # (area below config area_threshold parameter) statusStrs = ("OK", "Warning", "ALARM!!!", "Ben Not Found") screenBGColours = ( (0, 0, 255), # Blue for all ok (0) (128, 128, 0), # Yellow for warning (1) (255, 0, 0), # Red for full alarm. (2) (255, 0, 0), # Red for fall alarm. (3) (128, 128, 0), # Yellow for fault (4) (255, 0, 0), # Red for manual alarm. (5) (128, 128, 128), # Grey for mute. (6) ) alarmStatus = 0 # Current alarm status # Dimensions of the status bar at the bottom of the screen. statusBar_x = 0 statusBar_y = 380 statusbar_w = 640 statusbar_h = 100 alarmRatioThresh = 1 alarmRatio = 0 specRatio = 0 specPower = 0 alarmPhrase = "" dataTime = "" def __init__(self): """Initialise the bentv_ui class - reads the configuration file and initialises the screen and GPIO monitor""" print "bentv.__init__()" configPath = "%s/%s" % (os.path.dirname( os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath, self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self.debounce_ms = self.cfg.getConfigInt("debounce_ms") self.shortpress_ms = self.cfg.getConfigInt("shortpress_ms") self.hostname, self.ipaddr = self.getHostName() print self.hostname, self.ipaddr self.timeDown = 0.0 self.presetNo = 1 self.shortPress = False self.longPress = False self.initScreen() self.initGPIO() self.UIMode = self.CAMERA_MODE # Next line changes mode to start in # FITDECT_MODE. self.changeUIMode() # Initialises the messages. def getHostName(self): """Returns the hostname and IP address of the first physical (non loopback) network interface as a tuple, using the netifaces library.. """ hostname = socket.gethostname() ifList = netifaces.interfaces() print ifList ipAddr = "xxx.xxx.xxx.xxx" for ifName in ifList: print ifName if not ifName.startswith('lo'): print "non lo interface found ", ifName ifInfo = netifaces.ifaddresses(ifName).get( netifaces.AF_INET, []) print ifInfo if len(ifInfo) > 0: ipAddr = ifInfo[0]['addr'] print ipAddr return (hostname, ipAddr) def initGPIO(self): """Initialise the GPIO pins - note we use GPIO pin numbers, not physical pin numbers on rpi.""" global haveGPIO pinNo = self.cfg.getConfigInt("gpiono") self.pinNo = pinNo if (self.debug): print "gpioNo = %d" % pinNo if (haveGPIO): GPIO.setmode(GPIO.BCM) GPIO.setup(pinNo, GPIO.IN, pull_up_down=GPIO.PUD_UP) # very long debounce time to prevent presses while camera is moving. #GPIO.add_event_detect(pinNo, # GPIO.FALLING, # callback=self.buttonCallback # ,bouncetime=100) else: print "no GPIO - simulating camera move" self.moveCamera(1) self.lastButtonVal = 1 self.lastButtonTime = time.time() def buttonCallback(self, pinNo): """ called on falling edge - it waits for rising edge to see how long the button press was. """ print "Button Down" self.timeDown = time.time() GPIO.wait_for_edge(pinNo, GPIO.RISING) print "Button Up" print "time of press = %f" % (time.time() - self.timeDown) def pollButtons(self): """poll the buttons, and set a variable to say if we have detected a single, double or long click.""" global haveGPIO if (haveGPIO): ip = GPIO.input(self.pinNo) tnow = time.time() if (ip != self.lastButtonVal): print "button state changed" if (ip): keyPressLength = (tnow - self.lastButtonTime) * 1000. #ms print "Keypress Length = %f sec" % (keyPressLength) if (keyPressLength < self.debounce_ms): print "Ignoring very short keypress" self.shortPress = False self.longPress = False elif (keyPressLength < self.shortpress_ms): print "short press" self.shortPress = True self.longPress = False else: self.shortPress = False self.longPress = True self.lastButtonVal = ip self.lastButtonTime = tnow else: pass # do nothing if we do not have GPIO access. def serviceUI(self): """Respond to button presses.""" if (self.longPress): if (self.UIMode == self.CAMERA_MODE): self.moveCamera(self.pinNo) elif (self.UIMode == self.FITDECT_MODE): self.setFitDectBackground() else: print "Unrecognised UIMode %d." % self.UIMode self.longPress = False if (self.shortPress): self.changeUIMode() self.shortPress = False def changeUIMode(self): """Change the UI mode - toggle between camera and fit detector""" if (self.UIMode == self.CAMERA_MODE): print "Entering FitDetector Mode" self.textLine1 = "Fit Detector Mode" self.textLine2 = " Short press to change mode." self.UIMode = self.FITDECT_MODE else: print "Entering Camera Mode" self.textLine1 = "Camera Mode" self.textLine2 = " Press long button press to move camera. Short press to change mode." self.UIMode = self.CAMERA_MODE self.alarmStatus = self.ALARM_STATUS_NOT_FOUND self.lastDisplayUpdateTime = time.time() #Force message to display for # a little while before being # overwritten. self.drawStatusBar() def drawStatusBar(self): """ Write the given text onto the display area of the screen""" try: # Clear screen self.screen.fill(self.screenBGColours[self.alarmStatus]) # Line 1 text txtImg = self.font.render(self.textLine1, True, (255, 255, 255)) self.screen.blit(txtImg, (self.statusBar_x, self.statusBar_y)) # Line 1 time tnow = time.localtime(time.time()) txtStr = "%02d:%02d:%02d " % (tnow[3], tnow[4], tnow[5]) w = self.font.size(txtStr)[0] txtImg = self.font.render(txtStr, True, (255, 255, 255)) self.screen.blit(txtImg, (self.fbSize[0] - w, self.statusBar_y)) # Line 2 text txtImg = self.smallFont.render(self.textLine2, True, (255, 255, 255)) self.screen.blit(txtImg, (self.statusBar_x, self.statusBar_y + 20)) # Line 2 network info txtStr = "Host: %s, IP: %s " % (self.hostname, self.ipaddr) w = self.smallFont.size(txtStr)[0] txtImg = self.smallFont.render(txtStr, True, (255, 255, 255)) self.screen.blit(txtImg, (self.fbSize[0] - w, self.statusBar_y + 20)) #Draw the spectrum ratio bar graph in middle of status bar. rx = 300 ry = self.statusBar_y rw = 20 rh = 40 pygame.draw.rect(self.screen, (0, 0, 0), (rx, ry, rw, rh)) marginPc = 100 * self.specRatio / self.alarmRatioThresh if marginPc > 100: marginPc = 100 barh = rh * marginPc / 100 if barh < 2: barh = 2 #print marginPc,barh pygame.draw.rect(self.screen, (255, 0, 0), (rx, ry + rh - barh, rw, barh)) pygame.display.update() except: print "Error in DrawStatusBar()" def initScreen(self): """Initialise the display using the pygame library""" drivers = ['x11', 'fbcon', 'svgalib'] found = False disp_no = os.getenv("DISPLAY") if disp_no: print "I'm running under X display = {0}".format(disp_no) for driver in drivers: # Make sure that SDL_VIDEODRIVER is set if not os.getenv('SDL_VIDEODRIVER'): os.putenv('SDL_VIDEODRIVER', driver) try: pygame.display.init() print 'Using Driver: {0}.'.format(driver) except pygame.error: print 'Driver: {0} failed.'.format(driver) continue found = True break if not found: raise Exception('No suitable video driver found!') self.fbSize = (pygame.display.Info().current_w, pygame.display.Info().current_h) print "Framebuffer size: %d x %d" % self.fbSize if (disp_no): print "Using X11 window" winSize = (640, 480) self.screen = pygame.display.set_mode(winSize) self.fbSize = winSize else: print "Using full screen framebuffer" self.screen = pygame.display.set_mode(self.fbSize, pygame.FULLSCREEN) #print "using small screen" #winSize = (640,480) #self.screen = pygame.display.set_mode(winSize) #self.fbSize = winSize print "blank screen..." self.screen.fill((0, 0, 255)) print "initialise fonts" pygame.font.init() self.font = pygame.font.Font(None, 30) self.smallFont = pygame.font.Font(None, 16) print "calling drawStatusBar()" self.drawStatusBar() print "initScreen complete" def moveCamera(self, pinNo): """Callback function when button is pressed""" print('moveCamera called by pin number %d. PresetNo=%d' % (pinNo, self.presetNo)) try: h = httplib2.Http(".cache") h.add_credentials(self.cfg.getConfigStr('uname'), self.cfg.getConfigStr('passwd')) #resp, content = h.request("http://192.168.1.24/preset.cgi?-act=goto&-status=1&-number=%d" % self.presetNo,"GET") resp, content = h.request( "%s/%s%d" % (self.cfg.getConfigStr('camaddr'), self.cfg.getConfigStr('cammoveurl'), self.presetNo), "GET") print "moved to preset %d - content=%s" % (self.presetNo, content) except: print "Exception moving camera", sys.exc_info()[0] self.textLine1 = "Camera Position %d (%s)" % ( self.presetNo, self.presetTxt[self.presetNo]) self.presetNo += 1 if (self.presetNo > 4): self.presetNo = 1 def getOpenSeizureDetectorData(self): """ Use HTTP GET request to retrieve seizure detector data from an OpenSeizureDetector web interface. """ #print "getOpenSeizureDetectorData" h = httplib2.Http(".cache") h.add_credentials(self.cfg.getConfigStr('uname'), self.cfg.getConfigStr('passwd')) requestStr = "%s:%s/%s" % \ (self.cfg.getConfigStr('benfinderserver'), self.cfg.getConfigStr('benfinderport'), self.cfg.getConfigStr('benfinderurl')) #print requestStr try: resp, content = h.request(requestStr, "GET") dataDict = json.loads(content) self.alarmStatus = int(dataDict['alarmState']) self.specPower = int(dataDict['specPower']) self.roiPower = int(dataDict['roiPower']) self.alarmThresh = int(dataDict['alarmThresh']) self.alarmRatioThresh = int(dataDict['alarmRatioThresh']) self.alarmPhrase = dataDict['alarmPhrase'] self.dataTime = dataDict['dataTime'] if (self.roiPower > self.alarmThresh): self.specRatio = 10 * self.roiPower / self.specPower else: self.specRatio = 0 #print "specPower=%d, roiPower=%d, specRatio=%d" % \ # (specPower,roiPower,specRatio) self.textLine1 = " Ratio = %d / %d (%s)" % \ (self.specRatio,self.alarmRatioThresh, self.alarmPhrase) #print dataDict['time_t'] self.textLine2 = " Fit Detector Time = %s " % self.dataTime #print resp,content return True except: print "getOpenSeizureDetectorData Error:", sys.exc_info()[0] print "getOpenSeizureDetectorData Error" self.textLine1 = "No Connection to Fit Detector" return False def run(self): """bentv main loop""" self.lastDisplayUpdateTime = time.time() while 1: tnow = time.time() self.pollButtons() self.serviceUI() if (tnow - self.lastDisplayUpdateTime >= 1.0): if (self.UIMode == self.FITDECT_MODE): self.getOpenSeizureDetectorData() if (tnow - self.lastDisplayUpdateTime >= 1.0): self.drawStatusBar() self.lastDisplayUpdateTime = tnow #print "main loop..." time.sleep(0.2)
class runServer(object): configFname = "config.ini" configSection = "server" MAXLEN = 300 def __init__(self,port = None): print "runServer.__init__()" print os.path.realpath(__file__) configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath,self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self._wkdir = self.cfg.getConfigStr("working_directory") if (self.debug): print "working_directory=%s\n" % self._wkdir self._tmpdir = self.cfg.getConfigStr("tmpdir") if (self.debug): print "tmpdir=%s\n" % self._tmpdir if (port == None): port = '/dev/ttyUSB0' print "Opening Serial Connection on %s" % port self.ser = serial.Serial(port,9600,timeout=1) print "Waiting for serial comms to settle..." time.sleep(2) print "Reading first line of data, and ignoring it." line = self.ser.readline() # throw away any part lines print "line=%s" % line self.start() print "waiting for some data..." while(self.ser.inWaiting() < 10): print "waiting - inWaiting()=%d" % self.ser.inWaiting() time.sleep(1) print "wait over!" print "ignoring a few lines for start command to register..." for n in range(0,5): line = self.ser.readline() # throw away any part lines print "line=%s" % line #Initialise data lists. self.t=[] # initialize the data lists self.d1=[] self.d2=[] self.d3=[] self.d4=[] self.d5=[] self.d6=[] # Start web server self._ws = webServer.WebServer(self) webServer.setRoutes(self._ws) # Run our main loop. self.run() def run(self): """Run the main loop.""" while(True): line = self.ser.readline() # read a line of text mylist = line.split('\r')[0].split(",") # parse it into CSV tokens if (mylist[0]=='data'): print mylist now = float(mylist[1])/1000 # time now in seconds self.t.append(float(mylist[1])/1000) # from first element as milliseconds self.d1.append(float(mylist[2])) # six data elements added to lists self.d2.append(float(mylist[3])) self.d3.append(float(mylist[4])) self.d4.append(float(mylist[5])) self.d5.append(float(mylist[6])) #Trim the lists to avoid using up all the memory! lenLists = len(self.t) if (lenLists>self.MAXLEN): del self.t[0:(lenLists-self.MAXLEN)] del self.d1[0:(lenLists-self.MAXLEN)] del self.d2[0:(lenLists-self.MAXLEN)] del self.d3[0:(lenLists-self.MAXLEN)] del self.d4[0:(lenLists-self.MAXLEN)] del self.d5[0:(lenLists-self.MAXLEN)] if(self.ser.inWaiting() < 100): # redraw only if you are caught up plt.clf() # clear the figure plt.plot(self.t,self.d1) # plot a line for each set of data plt.plot(self.t,self.d2) plt.plot(self.t,self.d3) plt.plot(self.t,self.d4) plt.plot(self.t,self.d5) #plt.axis([now-300,now,min(d1)-50,max(d1)+50]) plt.axis([now-300,now,0,1000]) plt.xlabel("Time Since Boot [s]") plt.grid(b=True, which='both', color='0.65',linestyle='-') #plt.draw() plt.savefig('www/out.png') elif (mylist[0]=='Set'): self.settingsStr = line # used by 'settings' function. self.haveSettings = True else: if (len(line.split('\n')[0])>0): print "Message %s" % line.split('\n')[0] def setSetPoint(self,setpoint): print "setSetPoint(%d)" % setpoint self.ser.write("setpoint=%d" % setpoint) def setKp(self,gain): print "setKp(%d)" % gain self.ser.write("kp=%d" % gain) def setKi(self,gain): print "setKi(%d)" % gain self.ser.write("ki=%d" % gain) def setKd(self,gain): print "setKd(%d)" % gain self.ser.write("kd=%d" % gain) def start(self): print "Sending start command" self.ser.write("start") print "returning to main loop...." def stop(self): print "sending stop command" self.ser.write("stop") def pumpstart(self): print "Sending start command" self.ser.write("pump=on") print "returning to main loop...." def pumpstop(self): print "sending stop command" self.ser.write("pump=off") def settings(self): self.haveSettings = False # Flag - set by main loop if settings received. print "Requesting settings" self.ser.write("settings") print "Waiting for settings to be returned..." # wait for main loop to set haveSettings. while (not self.haveSettings): pass print "found settings: %s" % self.settingsStr return self.settingsStr
class bentv_ui: # Basic Configuration configFname = "config.ini" configSection = "bentv" debug = False # Initialise some instance variables. screen = None font = None textLine1 = "Camera_Mode" textLine2 = "Waiting for Button Press to move camera" presetNo = 1 presetTxt = ['NULL','Behind Door', 'Corner', 'Chair', 'Bed'] # UI Modes CAMERA_MODE = 0 FITDECT_MODE = 1 # Alarms ALARM_STATUS_OK = 0 # All ok, no alarms. ALARM_STATUS_WARN = 1 # Warning status ALARM_STATUS_FULL = 2 # Full alarm status. ALARM_STATUS_NOT_FOUND = 3 # Benjamin not found in image # (area below config area_threshold parameter) statusStrs = ("OK","Warning","ALARM!!!","Ben Not Found") screenBGColours = ( (0,0,255), # Blue for all ok (128,128,0), # Yellow for warning (255,0,0), # Red for full alarm. (128,128,128) # Grey for not found. ) alarmStatus = 0 # Current alarm status def __init__(self): """Initialise the bentv_ui class - reads the configuration file and initialises the screen and GPIO monitor""" print "bentv.__init__()" configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath,self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self.debounce_ms = self.cfg.getConfigInt("debounce_ms") self.shortpress_ms = self.cfg.getConfigInt("shortpress_ms") self.hostname, self.ipaddr = self.getHostName() print self.hostname, self.ipaddr self.timeDown = 0.0 self.presetNo = 1 self.shortPress = False self.longPress = False self.initScreen() self.initGPIO() self.UIMode = self.CAMERA_MODE # Next line changes mode to start in # FITDECT_MODE. self.changeUIMode() # Initialises the messages. def getIpAddr(self,ifname): """Return the IP Address of the given interface (e.g 'wlan0') from http://raspberrypi.stackexchange.com/questions/6714/how-to-get-the-raspberry-pis-ip-address-for-ssh. """ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa(fcntl.ioctl( s.fileno(), 0x8915, # SIOCGIFADDR struct.pack('256s', ifname[:15]) )[20:24]) def getHostName(self): """Returns the hostname and IP address of the wireless interface as a tuple. """ hostname = socket.gethostname() ipaddr = self.getIpAddr("wlan0") return (hostname,ipaddr) def initGPIO(self): """Initialise the GPIO pins - note we use GPIO pin numbers, not physical pin numbers on rpi.""" global haveGPIO pinNo = self.cfg.getConfigInt("gpiono") self.pinNo = pinNo if (self.debug): print "gpioNo = %d" % pinNo if (haveGPIO): GPIO.setmode(GPIO.BCM) GPIO.setup(pinNo, GPIO.IN, pull_up_down=GPIO.PUD_UP) # very long debounce time to prevent presses while camera is moving. #GPIO.add_event_detect(pinNo, # GPIO.FALLING, # callback=self.buttonCallback # ,bouncetime=100) else: print "no GPIO - simulating camera move" self.moveCamera(1) self.lastButtonVal = 1 self.lastButtonTime = time.time() def buttonCallback(self,pinNo): """ called on falling edge - it waits for rising edge to see how long the button press was. """ print "Button Down" self.timeDown = time.time() GPIO.wait_for_edge(pinNo,GPIO.RISING) print "Button Up" print "time of press = %f" % (time.time()-self.timeDown) def pollButtons(self): """poll the buttons, and set a variable to say if we have detected a single, double or long click.""" global haveGPIO if (haveGPIO): ip = GPIO.input(self.pinNo) tnow = time.time() if (ip != self.lastButtonVal): print "button state changed" if (ip): keyPressLength = (tnow - self.lastButtonTime)*1000. #ms print "Keypress Length = %f sec" % (keyPressLength) if (keyPressLength<self.debounce_ms): print "Ignoring very short keypress" self.shortPress = False self.longPress = False elif (keyPressLength<self.shortpress_ms): print "short press" self.shortPress = True self.longPress = False else: self.shortPress = False self.longPress = True self.lastButtonVal = ip self.lastButtonTime = tnow else: pass # do nothing if we do not have GPIO access. def serviceUI(self): """Respond to button presses.""" if (self.longPress): if (self.UIMode == self.CAMERA_MODE): self.moveCamera(self.pinNo) elif (self.UIMode == self.FITDECT_MODE): self.setFitDectBackground() else: print "Unrecognised UIMode %d." % self.UIMode self.longPress = False if (self.shortPress): self.changeUIMode() self.shortPress = False def changeUIMode(self): """Change the UI mode - toggle between camera and fit detector""" if (self.UIMode == self.CAMERA_MODE): print "Entering FitDetector Mode" self.textLine1 = "Fit Detector Mode" self.textLine2 = " Press long button press to reset background. Short press to change mode." self.UIMode = self.FITDECT_MODE else: print "Entering Camera Mode" self.textLine1 = "Camera Mode" self.textLine2 = " Press long button press to move camera. Short press to change mode." self.UIMode = self.CAMERA_MODE self.alarmStatus = self.ALARM_STATUS_NOT_FOUND self.lastDisplayUpdateTime = time.time() #Force message to display for # a little while before being # overwritten. self.display_text() def display_text(self): """ Write the given text onto the display area of the screen""" # Clear screen self.screen.fill(self.screenBGColours[self.alarmStatus]) # Line 1 text txtImg = self.font.render(self.textLine1, True,(255,255,255)) self.screen.blit(txtImg,(0,380)) # Line 1 time tnow = time.localtime(time.time()) txtStr = "%02d:%02d:%02d " % (tnow[3],tnow[4],tnow[5]) w = self.font.size(txtStr)[0] txtImg = self.font.render(txtStr, True,(255,255,255)) self.screen.blit(txtImg,(self.fbSize[0]-w,380)) # Line 2 text txtImg = self.smallFont.render(self.textLine2, True,(255,255,255)) self.screen.blit(txtImg,(0,400)) # Line 2 network info txtStr = "Host: %s, IP: %s " % (self.hostname, self.ipaddr) w = self.smallFont.size(txtStr)[0] txtImg = self.smallFont.render(txtStr, True, (255,255,255)) self.screen.blit(txtImg,(self.fbSize[0]-w,400)) pygame.display.update() def initScreen(self): """Initialise the display using the pygame library""" drivers = ['x11', 'fbcon', 'svgalib'] found = False disp_no = os.getenv("DISPLAY") if disp_no: print "I'm running under X display = {0}".format(disp_no) for driver in drivers: # Make sure that SDL_VIDEODRIVER is set if not os.getenv('SDL_VIDEODRIVER'): os.putenv('SDL_VIDEODRIVER', driver) try: pygame.display.init() print 'Using Driver: {0}.'.format(driver) except pygame.error: print 'Driver: {0} failed.'.format(driver) continue found = True break if not found: raise Exception('No suitable video driver found!') self.fbSize = (pygame.display.Info().current_w, pygame.display.Info().current_h) print "Framebuffer size: %d x %d" % self.fbSize if (disp_no): print "Using X11 window" winSize = (640,480) self.screen = pygame.display.set_mode(winSize) self.fbSize = winSize else: print "Using full screen framebuffer" self.screen = pygame.display.set_mode(self.fbSize, pygame.FULLSCREEN) print "blank screen..." self.screen.fill((0, 0, 255)) print "initialise fonts" pygame.font.init() self.font = pygame.font.Font(None,30) self.smallFont = pygame.font.Font(None,16) print "calling display_text()" self.display_text() print "initScreen complete" def moveCamera(self,pinNo): """Callback function when button is pressed""" print('moveCamera called by pin number %d. PresetNo=%d' % (pinNo,self.presetNo)) h = httplib2.Http(".cache") h.add_credentials(self.cfg.getConfigStr('uname'), self.cfg.getConfigStr('passwd')) #resp, content = h.request("http://192.168.1.24/preset.cgi?-act=goto&-status=1&-number=%d" % self.presetNo,"GET") resp, content = h.request("%s/%s%d" % (self.cfg.getConfigStr('camaddr'), self.cfg.getConfigStr('cammoveurl'), self.presetNo),"GET") print "moved to preset %d - content=%s" % (self.presetNo,content) self.textLine1 = "Camera Position %d (%s)" % (self.presetNo, self.presetTxt[self.presetNo]) self.presetNo += 1 if (self.presetNo > 4): self.presetNo = 1 def getBenFinderData(self): #print "getBenfinderData" h = httplib2.Http(".cache") h.add_credentials(self.cfg.getConfigStr('uname'), self.cfg.getConfigStr('passwd')) requestStr = "%s:%s/%s" % \ (self.cfg.getConfigStr('benfinderserver'), self.cfg.getConfigStr('benfinderport'), self.cfg.getConfigStr('benfinderurl')) #print requestStr try: resp, content = h.request(requestStr, "GET") dataDict = json.loads(content) self.alarmStatus = int(dataDict['status']) self.textLine1 = " Rate = %d bpm (status=%d - %s)" % \ (int(dataDict['rate']), int(dataDict['status']), self.statusStrs[int(dataDict['status'])] ) #print dataDict['time_t'] self.textLine2 = " Fit Detector Time = %s " % dataDict['time_t'] #print resp,content return True except: print "Error:",sys.exc_info()[0] self.textLine1 = "No Connection to Fit Detector" return False def setFitDectBackground(self): """Tell the fit detector to initialise its background image from the current image.""" print "setFitDectBackground()" h = httplib2.Http(".cache") h.add_credentials(self.cfg.getConfigStr('uname'), self.cfg.getConfigStr('passwd')) requestStr = "%s:%s/%s" % \ (self.cfg.getConfigStr('benfinderserver'), self.cfg.getConfigStr('benfinderport'), self.cfg.getConfigStr('benfinderbackgroundurl')) print requestStr try: resp, content = h.request(requestStr, "GET") print resp,content self.textLine1 = "Fit Detector Background Image Reset" self.textLine2 = " Press button to reset background. Long press to change mode." except: print "Error:",sys.exc_info()[0] self.textLine1 = "Error Initialising Fit Detector Background" self.textLine2 = " Press button to reset background. Long press to change mode." self.lastDisplayUpdateTime = time.time() #Force message to display for # a little while before being # overwritten. self.display_text() def run(self): """bentv main loop""" self.lastDisplayUpdateTime = time.time() while 1: tnow = time.time() self.pollButtons() self.serviceUI() if (tnow-self.lastDisplayUpdateTime >= 1.0): if (self.UIMode == self.FITDECT_MODE): self.getBenFinderData() if (tnow-self.lastDisplayUpdateTime >= 1.0): self.display_text() self.lastDisplayUpdateTime = tnow #print "main loop..." time.sleep(0.2)
def __init__(self,save=False, inFile = None): print "benFinder.__init__()" print os.path.realpath(__file__) configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath,self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self._wkdir = self.cfg.getConfigStr("working_directory") if (self.debug): print "working_directory=%s\n" % self._wkdir self._tmpdir = self.cfg.getConfigStr("tmpdir") if (self.debug): print "tmpdir=%s\n" % self._tmpdir # Check if we are running from live kinect or a file. if (inFile): device = depth.CV_CAP_FILE else: device = depth.CV_CAP_FREENECT # Initialise the captureManager self._captureManager = CaptureManager( device, None, True, inFile=inFile) self._captureManager.channel = depth.CV_CAP_OPENNI_DEPTH_MAP # If we are runnign from a file, use the first frame as the # background image. if (inFile): self.saveBgImg() # If we have asked to save the background image, do that, and exit, # otherwise initialise the seizure detector. if (save): self.saveBgImg() else: self.loadBgImg() self.autoBackgroundImg = None self._status = self.ALARM_STATUS_OK self._ts = TimeSeries(tslen=self.cfg.getConfigInt("timeseries_length")) self._frameCount = 0 self._outputFrameCount = 0 self._nPeaks = 0 self._ts_time = 0 self._rate = 0 self._ws = webServer.benWebServer(self) self._ws.setBgImg("%s/%s" % (self._tmpdir, self.cfg.getConfigStr("background_depth"))) self._ws.setChartImg("%s/%s" % (self._tmpdir, self.cfg.getConfigStr("chart_fname"))) self._ws.setRawImg("%s/%s" % (self._tmpdir, self.cfg.getConfigStr("raw_image_fname"))) self._ws.setMaskedImg("%s/%s" % (self._tmpdir, self.cfg.getConfigStr("masked_image_fname"))) self._ws.setDataFname("%s/%s" % (self._tmpdir, self.cfg.getConfigStr("data_fname"))) self._ws.setAnalysisResults({}) webServer.setRoutes(self._ws) self.run()
class BenFinder(object): configFname = "config.ini" configSection = "benFinder" ALARM_STATUS_OK = 0 # All ok, no alarms. ALARM_STATUS_WARN = 1 # Warning status ALARM_STATUS_FULL = 2 # Full alarm status. ALARM_STATUS_NOT_FOUND = 3 # Benjamin not found in image # (area below config area_threshold parameter) def __init__(self,save=False, inFile = None): print "benFinder.__init__()" print os.path.realpath(__file__) configPath = "%s/%s" % (os.path.dirname(os.path.realpath(__file__)), self.configFname) print configPath self.cfg = ConfigUtil(configPath,self.configSection) self.debug = self.cfg.getConfigBool("debug") if (self.debug): print "Debug Mode" self._wkdir = self.cfg.getConfigStr("working_directory") if (self.debug): print "working_directory=%s\n" % self._wkdir self._tmpdir = self.cfg.getConfigStr("tmpdir") if (self.debug): print "tmpdir=%s\n" % self._tmpdir # Check if we are running from live kinect or a file. if (inFile): device = depth.CV_CAP_FILE else: device = depth.CV_CAP_FREENECT # Initialise the captureManager self._captureManager = CaptureManager( device, None, True, inFile=inFile) self._captureManager.channel = depth.CV_CAP_OPENNI_DEPTH_MAP # If we are runnign from a file, use the first frame as the # background image. if (inFile): self.saveBgImg() # If we have asked to save the background image, do that, and exit, # otherwise initialise the seizure detector. if (save): self.saveBgImg() else: self.loadBgImg() self.autoBackgroundImg = None self._status = self.ALARM_STATUS_OK self._ts = TimeSeries(tslen=self.cfg.getConfigInt("timeseries_length")) self._frameCount = 0 self._outputFrameCount = 0 self._nPeaks = 0 self._ts_time = 0 self._rate = 0 self._ws = webServer.benWebServer(self) self._ws.setBgImg("%s/%s" % (self._tmpdir, self.cfg.getConfigStr("background_depth"))) self._ws.setChartImg("%s/%s" % (self._tmpdir, self.cfg.getConfigStr("chart_fname"))) self._ws.setRawImg("%s/%s" % (self._tmpdir, self.cfg.getConfigStr("raw_image_fname"))) self._ws.setMaskedImg("%s/%s" % (self._tmpdir, self.cfg.getConfigStr("masked_image_fname"))) self._ws.setDataFname("%s/%s" % (self._tmpdir, self.cfg.getConfigStr("data_fname"))) self._ws.setAnalysisResults({}) webServer.setRoutes(self._ws) self.run() def run(self): """Run the main loop.""" while(True): self._captureManager.enterFrame() frame = self._captureManager.frame if frame is not None: if (self.autoBackgroundImg == None): self.autoBackgroundImg = numpy.float32(frame) rawFrame = frame.copy() # First work out the region of interest by # subtracting the fixed background image # to create a mask. #print frame #print self._background_depth_img absDiff = cv2.absdiff(frame,self._background_depth_img) benMask,maskArea = filters.getBenMask(absDiff,8) cv2.accumulateWeighted(frame, self.autoBackgroundImg,0.05) # Convert the background image into the same format # as the main frame. #bg = self.autoBackgroundImg bg = cv2.convertScaleAbs(self.autoBackgroundImg, alpha=1.0) # Subtract the background from the frame image cv2.absdiff(frame,bg,frame) # Scale the difference image to make it more sensitive # to changes. cv2.convertScaleAbs(frame,frame,alpha=100) # Apply the mask so we only see the test subject. frame = cv2.multiply(frame,benMask,dst=frame,dtype=-1) if (maskArea <= self.cfg.getConfigInt('area_threshold')): bri=(0,0,0) else: # Calculate the brightness of the test subject. bri = filters.getMean(frame,benMask) # Add the brightness to the time series ready for analysis. self._ts.addSamp(bri[0]) self._ts.addImg(rawFrame) # Write timeseries to a file every 'output_framecount' frames. if (self._outputFrameCount >= self.cfg.getConfigInt('output_framecount')): # Write timeseries to file self._ts.writeToFile("%s/%s" % \ ( self.cfg.getConfigStr('output_directory'), self.cfg.getConfigStr('ts_fname') )) self._outputFrameCount = 0 else: self._outputFrameCount = self._outputFrameCount + 1 # Only do the analysis every 15 frames (0.5 sec), or whatever # is specified in configuration file analysis_framecount # parameter. if (self._frameCount < self.cfg.getConfigInt('analysis_framecount')): self._frameCount = self._frameCount +1 else: # Look for peaks in the brightness (=movement). self._nPeaks,self._ts_time,self._rate = self._ts.findPeaks() #print "%d peaks in %3.2f sec = %3.1f bpm" % \ # (nPeaks,ts_time,rate) oldStatus = self._status if (maskArea > self.cfg.getConfigInt('area_threshold')): # Check for alarm levels if (self._rate > self.cfg.getConfigInt( "rate_warn")): self._status= self.ALARM_STATUS_OK elif (self._rate > self.cfg.getConfigInt( "rate_alarm")): self._status= self.ALARM_STATUS_WARN else: self._status= self.ALARM_STATUS_FULL else: self._status = self.ALARM_STATUS_NOT_FOUND if (oldStatus == self.ALARM_STATUS_OK and self._status == self.ALARM_STATUS_WARN) or \ (oldStatus == self.ALARM_STATUS_WARN and self._status == self.ALARM_STATUS_FULL): # Write timeseries to file self._ts.writeToFile("%s/%s" % \ ( self.cfg.getConfigStr('output_directory'), self.cfg.getConfigStr('alarm_ts_fname') ),bgImg=self._background_depth_img) # Collect the analysis results together and send them # to the web server. resultsDict = {} resultsDict['fps'] = "%3.0f" % self.fps resultsDict['bri'] = "%4.0f" % self._ts.mean resultsDict['area'] = "%6.0f" % maskArea resultsDict['nPeaks'] = "%d" % self._nPeaks resultsDict['ts_time'] = self._ts_time resultsDict['rate'] = "%d" % self._rate resultsDict['time_t'] = time.ctime() resultsDict['status'] = self._status self._ws.setAnalysisResults(resultsDict) # Write the results to file as a json string utils.writeJSON(resultsDict,"%s/%s" % \ (self._tmpdir, self.cfg.getConfigStr("data_fname"))) utils.writeLog(resultsDict,"%s/%s" % \ (self._tmpdir, "benFinder_alarms.log")) # Plot the graph of brightness, and save the images # to disk. self._ts.plotRawData( file=True, fname="%s/%s" % \ (self._tmpdir,self.cfg.getConfigStr("chart_fname"))) cv2.imwrite("%s/%s" % (self._tmpdir, self.cfg.getConfigStr( "raw_image_fname")), rawFrame) cv2.imwrite("%s/%s" % (self._tmpdir,self.cfg.getConfigStr( "masked_image_fname")), frame) self._frameCount = 0 else: print "Null frame received - assuming end of file and exiting" break self._captureManager.exitFrame() @property def fps(self): return self._captureManager.fps @property def nPeaks(self): return self._nPeaks @property def ts_time(self): return self._ts_time @property def rate(self): return self._rate @property def rawImgFname(self): return self.cfg.getConfigStr("raw_image_fname") @property def maskedImgFname(self): return self.cfg.getConfigStr("masked_image_fname") @property def chartImgFname(self): return self.cfg.getConfigStr("chart_fname") def saveBgImg(self): """ Write a new background image to the appropriate file location.""" if (self._captureManager.hasEnteredFrame): self._captureManager.exitFrame() self._captureManager.enterFrame() print "Writing image to %s." % self.cfg.getConfigStr("background_depth") self._captureManager.writeImage("%s/%s" % (self._wkdir, self.cfg.getConfigStr("background_depth") )) print self._captureManager.frame print self._captureManager.frame.dtype self._captureManager.exitFrame() self.loadBgImg() def loadBgImg(self): print "Loading background image %s/%s." % \ (self._wkdir,self.cfg.getConfigStr("background_depth")) self._background_depth_img = cv2.imread("%s/%s" % \ (self._wkdir,self.cfg.getConfigStr("background_depth")), cv2.CV_LOAD_IMAGE_GRAYSCALE) # cv2.CV_LOAD_IMAGE_UNCHANGED) print self._background_depth_img print self._background_depth_img.dtype