class GoProHelper: def __init__(self, passwd): self.camera = GoProHero(password=passwd, log_level=logging.CRITICAL) def Status(self): s = self.camera.status() if s['raw'] == {}: s = {'power': 'off', 'batt1': 0} return s def RecordStart(self): self.camera.command('record', 'on') def RecordStop(self): self.camera.command('record', 'off')
status_flag = 0 #within threshold value val = 0 #setup GPIO.setup(LED, GPIO.OUT) rangefinder = Ultrasonic(TRIG, ECHO, thresh) camera = GoProHero(password='******') #connect to camera #========================================================= while(1): try: status_flag = rangefinder.threshold() GPIO.output(LED, status_flag) status = camera.status() if(status_flag == 1 and status['record'] != 'on'): camera.command('record','on') os.system('aplay ' + filename) #print('recording') elif(status['record'] != 'off' and status_flag == 0): camera.command('record','off') except KeyboardInterrupt: GPIO.cleanup() rangefinder.close() camera.command('record','off') raise except: print("You need to run as ROOT asshole") exit(-1)
class GoProProxy: maxRetries = 3 # init def __init__(self, log_level=logging.INFO): # setup log log_file = '/var/log/gopro-proxy.log' log_format = '%(asctime)s %(message)s' logging.basicConfig(format=log_format, level=log_level) # file logging fh = logging.FileHandler(log_file) fh.setLevel(log_level) fh.setFormatter(logging.Formatter(log_format)) logger = logging.getLogger() logger.setLevel(log_level) logger.addHandler(fh) # setup camera self.camera = GoProHero() self.snapshots = os.environ.get('GOPRO_SNAPSHOTS', True) # setup wireless interface = os.environ.get('GOPRO_WIFI_INTERFACE', None) self.wireless = Wireless(interface) # connect to the camera's network def connect(self, camera): func_str = 'GoProProxy.connect({}, {})'.format( camera.ssid, camera.password) # jump to a new network only if needed if self.wireless.current() != camera.ssid: self.wireless.connect( ssid=camera.ssid, password=camera.password) # evaluate connection request if self.wireless.current() == camera.ssid: # reconfigure the password in the camera instance self.camera.password(camera.password) logging.info('{}{}{}'.format(Fore.CYAN, func_str, Fore.RESET)) return True else: logging.info('{}{} - network not found{}'.format( Fore.YELLOW, func_str, Fore.RESET)) return False # send command def sendCommand(self, command): result = False # make sure we are connected to the right camera if self.connect(command.camera): # try to send the command, a few times if needed i = 0 while i < self.maxRetries and result is False: result = self.camera.command(command.command, command.value) i += 1 else: # mini-status update if we couldn't connect command.camera.last_attempt = timezone.now() command.camera.summary = 'notfound' # did we successfully talk to the camera? self.updateCounters(command.camera, result) command.camera.save() # save result command.time_completed = timezone.now() command.save() # get status def getStatus(self, camera): # make sure we are connected to the right camera camera.last_attempt = timezone.now() connected = self.connect(camera) # could we find the camera? if connected: # update counters camera.last_update = camera.last_attempt self.updateCounters(camera, True) # try to get the camera's status status = self.camera.status() camera.summary = status['summary'] # extend existing status if possible if camera.status != '': # allows us to retain knowledge of settings when powered off try: old_status = json.loads(camera.status) if old_status != '': old_status.update(status) status = old_status except ValueError: logging.info('{}{} - existing status malformed{}'.format( Fore.YELLOW, 'GoProProxy.getStatus()', Fore.RESET)) # save status to camera camera.status = json.dumps(status) # grab snapshot when the camera is powered on if self.snapshots is True and 'power' in status \ and status['power'] == 'on': camera.save() image = self.camera.image() if image is not False: camera.image = image camera.image_last_update = camera.last_attempt else: # update counters self.updateCounters(camera, False) # update status camera.summary = 'notfound' # save result camera.save() def updateCounters(self, camera, success): camera.connection_attempts += 1 if success is not True: camera.connection_failures += 1 # main loop def run(self): logging.info('{}GoProProxy.run(){}'.format(Fore.GREEN, Fore.RESET)) logging.info('Wifi interface: {}, wifi driver: {}'.format( self.wireless.interface(), self.wireless.driver())) logging.info('Attempt snapshots: {}'.format(self.snapshots)) # keep running until we land on Mars # keep the contents of this loop short (limit to one cmd/status or one # status) so that we can quickly catch KeyboardInterrupt, SystemExit while 'people' != 'on Mars': # PRIORITY 1: send command for the current network on if possible commands = Command.objects.filter( time_completed__isnull=True, camera__ssid__exact=self.wireless.current()) if len(commands) > 0: self.sendCommand(commands[0]) # get the status now because it is cheap if self.wireless.current() == commands[0].camera.ssid: self.getStatus(commands[0].camera) # PRIORITY 2: send the oldest command still in the queue else: commands = Command.objects.filter( time_completed__isnull=True).order_by('-date_added') if len(commands) > 0: self.sendCommand(commands[0]) # get the status now because it is cheap if self.wireless.current() == commands[0].camera.ssid: self.getStatus(commands[0].camera) # PRIORITY 3: check status of the most stale camera else: cameras = Camera.objects.all().order_by('last_attempt') if len(cameras) > 0: self.getStatus(cameras[0]) # protect the cpu in the event that there was nothing to do time.sleep(0.1)
class Controller: def __init__(self, password, ip_address): self.password = password self.ip_address = ip_address self.camera = GoProHero(password=self.password, ip=self.ip_address) def power_off(self): self.camera.command('power', 'sleep') #url = "http://{0}/gp/gpControl/command/system/sleep".format(self.ip_address) #r = requests.get(url) def power_on(self): self.camera.command('power', 'on') def delete_last(self): url = "http://{0}/gp/gpControl/command/storage/delete/last".format(self.ip_address) r = requests.get(url) def delete_all(self): url = "http://{0}/gp/gpControl/command/storage/delete/all".format(self.ip_address) r = requests.get(url) def tag_moment(self): url = "http://{0}/gp/gpControl/command/storage/tag_moment".format(self.ip_address) r = requests.get(url) def preview(self): self.camera.command('preview', 'on') def enable_mode(self, mode): # Mode options: # 'video', 'still', 'burst', 'timelapse' self.camera.command('mode', mode) def start_video(self): #self.camera.command('mode', 'video') url = "http://{0}/camera/SH?t={1}&p=%01".format(self.ip_address, self.password) r = requests.get(url) #self.camera.command('record', 'on') def stop_video(self): url = "http://{0}/camera/SH?t={1}&p=%00".format(self.ip_address, self.password) r = requests.get(url) #self.camera.command('record', 'off') def beep(self, number_of_beeps): self.camera.command('locate', 'on') time.sleep(number_of_beeps) self.camera.command('locate', 'off') def looping(self, duration): if duration == 5 or duration == 20 or duration == 60 or duration == 120: cmd_string = "{} minutes".format(duration) self.camera.command('looping', cmd_string) else: print "Value must be 5, 20, 60, or 120 minutes" def looping_off(self): self.camera.command('looping', 'off') def print_status(self, option): status = self.camera.status() return status[option]
#! /bin/python import subprocess as sp from goprohero import GoProHero import urllib from time import sleep import threading camera = GoProHero(password='******') camera.command('power', 'on') while True: status = camera.status() if (len(status) > 4): # When the camera is on, there are more than 4 keys break camera.command('preview', 'on') camera.command('mode', 'still') status = camera.status() battery = status["batt1"] if battery < 20: print("Low battery") # startingimgnum = status["npics"] #TODO: See if this works startingimgnum = 2454 + status[ "npics"] #No longer needs to be changed. Getting starting number dynamically # todo: 2454 is hardcoded, what does it mean, and can i get that number dynamically too? def getPicture(url, filename): urllib.urlretrieve(url, filename) # sp.call(["target_spotter", filename])
class GoPro(threading.Thread): def __init__(self, parent, goproinfo, network): threading.Thread.__init__(self) self.info = goproinfo self.camera = GoProHero(password=self.info.getPassword(), log_level=logging.CRITICAL) self.storage = Storage() self.status = goprostatus.GoProStatus() self.files = goprofiles.GoProFiles() self.recordings = goprorecordings.GoProRecordings() self.gui = GoProGUI(parent, self.info.getSSID(), lambda: self.addObjective('snap'), lambda: self.addObjective('transfer'), self.status.clearObjectives) self.network = network self.exitVar = False self.load() self.files.unmount(self.info.getUSBid(), self.info.getUSBserial(), self.info.getModel()) print self.info.getSSID() + ': Initialized' def addObjective(self, objective): self.status.addObjective(objective) def run(self): actions = { 'record': self.record, 'snap': self.snap, 'transfer': self.transfer } actionThread = threading.Thread() while not self.exitVar: self.save() self.files.mount(self.info.getUSBid(), self.info.getUSBserial(), self.info.getModel()) self.status.setName(self.gui.getName()) self.gui.setUnsaved(self.recordings.isEmpty()) self.gui.setMounted(self.files.isMounted()) self.gui.setRecording(self.status.isRecording()) self.gui.displayObjectives(self.status.getObjectives()) action, args = self.status.decodeObjective() if action in actions and not actionThread.isAlive(): actionThread = threading.Thread(target=actions[action], args=(args,)) actionThread.start() time.sleep(0.1) def record(self, args): if args[0] == 'on' and self.status.isRecording() == False and self.gui.shouldRecord(): if not self.command(['mode video', 'record on']): self.status.completeObjective() return self.status.isRecording(True) self.recordings.stage(' '.join(args[1:]), self.status.getName()) elif args[0] == 'off' and self.status.isRecording() == True: time.sleep(1) if not self.command(['record off']): self.status.completeObjective() return self.status.isRecording(False) self.recordings.commit() self.status.completeObjective() def transfer(self, args): if self.files.isMounted() and not self.recordings.isEmpty(): patterns = self.files.findMatchingFiles(self.recordings.getRecordings()) correctPattern = self.gui.confirmPattern(self.recordings.getRecordings(), patterns) self.files.trackAllExcept(correctPattern) self.save() successfulIndices = self.files.copy(self.recordings.getRecordings(), correctPattern) self.files.trackAll() self.save() for i in reversed(successfulIndices): self.recordings.delete(i) self.status.completeObjective() def snap(self, args): try: self.connect() _, image = self.camera.image().split(',') if not os.path.isdir('tmp'): os.mkdir('tmp') file = open('tmp/image.png', 'wb') file.write(image.decode('base64')) file.close() os.system('eog tmp/image.png &') except: pass finally: self.disconnect() self.status.completeObjective() def connect(self): self.network.connect(self.info.getSSID(), self.info.getPassword()) def disconnect(self): self.network.disconnect() def testConnection(self): self.connect() self.disconnect() def cameraStatus(self, param): status = self.camera.status() if param in status: return status[param] def command(self, commands): try: self.connect() for com in commands: decoded = com.split(' ') self.camera.command(decoded[0], decoded[1]) time.sleep(1) if self.cameraStatus(decoded[0]) != decoded[1]: raise NetworkError(self.info.getSSID()) return True except NetworkError: print self.info.getSSID() + ': There was an error when connecting to the camera' finally: self.disconnect() return False def exit(self): self.exitVar = True def save(self): result = 'PART::RECORDINGS\n' result += self.recordings.pack() + '\n' result += 'PART::STATUS\n' result += self.status.pack() + '\n' result += 'PART::FILES\n' result += self.files.pack() + '\n' result += 'PART::GUI\n' result += self.gui.pack() self.storage.save(self.info.getSSID(), result) def load(self): info = self.storage.load(self.info.getSSID()) result = {} currentPart = '' if not info: return for line in info.split('\n'): if 'PART' in line: currentPart = line[6:] result[currentPart] = '' continue result[currentPart] += line + '\n' self.recordings = goprorecordings.unpack(result['RECORDINGS'].strip('\n')) self.status = goprostatus.unpack(result['STATUS'].strip('\n')) self.files = goprofiles.unpack(result['FILES'].strip('\n')) self.gui.load(result['GUI'].strip('\n')) def grid(self, **kwargs): self.gui.grid(**kwargs)