#!/usr/bin/python """ __version__ = "$Revision: 1.5 $" __date__ = "$Date: 2004/04/30 16:26:12 $" """ import os import time import x10 from VideoCapture import Device from PythonCard import dialog, model from wxPython import wx # A few constants RETRY = 5 RateSeconds = {'sec': 1, 'min': 60, 'hour': 3600} class MyBackground(model.Background): def on_initialize(self, event): self.components.StopButton.enabled = False self.components.PauseButton.enabled = False self.components.PathField.text = os.path.realpath(os.path.curdir) self.components.NameField.text = 'Frame' self.components.StatusField.text = 'Ready' self.X10WarmUp = self.components.WarmUpSpinner.value self.State = 'stop' self.Frame = 0 self.CameraInit = False self.Timer = wx.wxTimer(self.components.StatusField, -1) # Pass VideoCapture config options def on_menuEditFilter_select(self, event): self.cam.displayCaptureFilterProperties() def on_menuEditPin_select(self, event): self.cam.displayCapturePinProperties() def on_NonStopCheckBox_mouseClick(self, event): #Couldn't resist the name! NewVal = not self.components.NonStopCheckBox.checked # Shorter Lines self.components.FrameSpinner.enabled = NewVal def on_X10Box_mouseClick(self, event): # If we aren't using X10 there's no need for a warm up period. NewVal = self.components.X10Box.checked self.components.PortChoice.enabled = NewVal self.components.HouseChoice.enabled = NewVal self.components.UnitChoice.enabled = NewVal self.components.WarmUpSpinner.enabled = NewVal if self.components.WarmUpSpinner.enabled: self.components.WarmUpSpinner.value = self.X10WarmUp else: self.X10WarmUp = self.components.WarmUpSpinner.value self.components.WarmUpSpinner.value = 0 def on_PathButton_mouseClick(self, event): #Stolen from Find Files dir = self.components.PathField.text if not os.path.isdir(dir): dir = '.' result = dialog.directoryDialog(self, 'Choose a directory', dir) if result.accepted: self.components.PathField.text = result.path def on_GoButton_mouseClick(self, event): "Begin image capture" self.Frame = 0 if not os.path.isdir(self.components.PathField.text): # Don't start if we don't have a valid save directory result = dialog.alertDialog(self, 'Bad Path Name', 'ERROR!') return self.DisableAll() self.State = 'sleep' self.components.StatusField.text = self.State self.Timer.Start(100) # Just to get started self.components.GoButton.enabled = False self.components.StopButton.enabled = True self.components.PauseButton.enabled = True def on_StopButton_mouseClick(self, event): "Stop taking pictures" self.State = 'stop' self.Timer.Stop() self.components.StatusField.text = 'Frame %d' % self.Frame self.EnableAll() self.components.GoButton.enabled = True self.components.StopButton.enabled = False self.components.PauseButton.enabled = False def on_PauseButton_mouseClick(self, event): "Pause/Unpause picute taking, hold image count" if self.State == 'pause': # Restart self.State = 'sleep' self.DisableAll() self.Timer.Start(100) else: # Pause self.Timer.Stop() self.State = 'pause' self.components.StatusField.text = 'Pause [%d]' % self.Frame self.EnableAll() self.components.GoButton.enabled = False self.components.StopButton.enabled = True self.components.PauseButton.enabled = True def on_StatusField_timer(self, event): "Main timer for picture taking" self.Timer.Stop() # If the camera isn't initialized, turn it on now. if not self.CameraInit: self.components.StatusField.text = 'Starting Webcam' self.cam = Device(showVideoWindow=0) self.cam.getImage() # First try often fails... self.CameraInit = True # Coming out of sleep. Wait for warm up if required. if self.State == 'sleep': if self.components.X10Box.checked: Command = '%s%s On' % (self.components.HouseChoice.stringSelection, self.components.UnitChoice.stringSelection) print Command self.components.StatusField.text = 'X10: %s' % Command x10.sendCommands(self.components.PortChoice.stringSelection, Command) # Lights on. self.components.StatusField.text = 'Warming Up' self.State = 'warm' print "Warming Up" Delay = max(100, self.components.WarmUpSpinner.value * 1000) self.Timer.Start(Delay) # Done warming up, take the picture. elif self.State == 'warm': self.components.StatusField.text = 'Taking Pictue' Stamp = self.components.TimeStampBox.checked and 3 or 0 Name = '%s-%06d.jpg' % (self.components.NameField.text, self.Frame) # Six digits ought to be enough. File = os.path.join(self.components.PathField.text, Name) if not self.components.OverWriteBox.checked: while os.path.isfile(File): # Preventing file overwrite. Allows stoping/starting. self.Frame += 1 Name = '%s-%06d.jpg' % (self.components.NameField.text, self.Frame) File = os.path.join(self.components.PathField.text, Name) for i in range(RETRY): # Sometimes the camera freakes out and fails a few times # in a row. This will keep trying RETRY times. img = self.cam.getImage(timestamp=Stamp, boldfont=1) if img: try: img.save(File) except IOError: # Probably out of space. result = dialog.alertDialog(self, 'Cannot write: %s\nPaused' % File, 'ERROR!') self.on_PauseButton_mouseClick(event) # Not good return print time.asctime() print "Saved: %s" % File break else: Error = self.components.StatusField.text + '.' self.components.StatusField.text = Error print "Retry" if self.components.X10Box.checked: # Shut off the light. Command = '%s%s Off' % (self.components.HouseChoice.stringSelection, self.components.UnitChoice.stringSelection) print Command self.components.StatusField.text = 'X10: %s' % Command x10.sendCommands(self.components.PortChoice.stringSelection, Command) self.Frame += 1 print self.Frame # Check to see if the required number of frames have been captured. if not self.components.NonStopCheckBox.checked and \ self.Frame >= self.components.FrameSpinner.value: print "Done" self.on_StopButton_mouseClick(event) # Poor return else: print "Sleeping" self.components.StatusField.text = 'Sleeping [%d]' % self.Frame self.State = 'sleep' Lost = max(100, self.components.WarmUpSpinner.value * 1000) Delay = self.components.RateSpinner.value * \ RateSeconds[self.components.RateChoice.stringSelection] * 1000 self.Timer.Start(Delay - Lost) def DisableAll(self): """Shut down everything to prevent the user from changing options on the fly. A bit of a hack.""" Disable = [self.components.RateSpinner, self.components.RateChoice, self.components.WarmUpSpinner, self.components.FrameSpinner, self.components.TimeStampBox, self.components.OverWriteBox, self.components.PortChoice, self.components.HouseChoice, self.components.UnitChoice, self.components.NonStopCheckBox, self.components.X10Box, self.components.PathField, self.components.PathButton, self.components.NameField, ] for Component in Disable: Component.enabled = False self.menuBar.setEnabled('menuEditFilter', False) self.menuBar.setEnabled('menuEditPin', False) def EnableAll(self): "Turn everything back on during pause and stop." Enable = [self.components.RateSpinner, self.components.RateChoice, self.components.TimeStampBox, self.components.OverWriteBox, self.components.FrameSpinner, self.components.NonStopCheckBox, self.components.X10Box, self.components.PathField, self.components.PathButton, self.components.NameField, ] for Component in Enable: Component.enabled = True Enable = [self.components.WarmUpSpinner, self.components.PortChoice, self.components.HouseChoice, self.components.UnitChoice, ] for Component in Enable: Component.enabled = self.components.X10Box.checked self.menuBar.setEnabled('menuEditFilter', True) self.menuBar.setEnabled('menuEditPin', True) if __name__ == '__main__': app = model.Application(MyBackground) app.MainLoop()