class Plugin(indigo.PluginBase): def __init__(self, pluginId, pluginDisplayName, pluginVersion, pluginPrefs): indigo.PluginBase.__init__(self, pluginId, pluginDisplayName, pluginVersion, pluginPrefs) self.updater = GitHubPluginUpdater(self) def __del__(self): indigo.PluginBase.__del__(self) def startup(self): indigo.server.log("----- startup called ------") indigo.server.log("Checking for update") ActiveVersion = str(self.pluginVersion) CurrentVersion = str(self.updater.getVersion()) if ActiveVersion == CurrentVersion: indigo.server.log("Running the current version of Security Camera") else: indigo.server.log("The current version of Security Camera is " + str(CurrentVersion) + " and the running version " + str(ActiveVersion) + ".") indigo.server.log("WARNING !: Upgrading to this version will require recreating all existing cameras.") SnapshotDir = indigo.activePlugin.pluginPrefs["SnapshotDirectory"] MainDir = indigo.activePlugin.pluginPrefs["MainDirectory"] #Main dir test MainDirTest = os.path.isdir(MainDir) if MainDirTest is False: indigo.server.log("Home image directory not found. Creating...") os.makedirs(MainDir) indigo.server.log("Created: " + MainDir) #Snapshot Test SnapshotDirTest = os.path.isdir(SnapshotDir) if SnapshotDirTest is False: indigo.server.log("Snapshot image directory not found. Creating...") os.makedirs(SnapshotDir) indigo.server.log("Created: " + SnapshotDir) def shutdown(self): indigo.server.log(u"shutdown called") def validatePrefsConfigUi(self, valuesDict): MainDir = valuesDict["MainDirectory"] ArchiveDir = MainDir + "/Archive" #Main Dir Test MainDirTest = os.path.isdir(MainDir) if MainDirTest is False: indigo.server.log("Home image directory not found. Creating...") os.makedirs(MainDir) indigo.server.log("Created: " + MainDir) #archive dir test ArchiveDirTest = os.path.isdir(ArchiveDir) if ArchiveDirTest is False: indigo.server.log("Archive image directory not found. Creating...") os.makedirs(ArchiveDir) indigo.server.log("Created: " + ArchiveDir) return True def didDeviceCommPropertyChange(self, origDev, newDev): return False def deviceStartComm(self, dev): CameraName = dev.pluginProps["CameraName"] #url = dev.pluginProps["CameraAddress"] <remove> dev.stateListOrDisplayStateIdChanged() localPropsCopy = dev.pluginProps MainDir = indigo.activePlugin.pluginPrefs["MainDirectory"] #IMDir = indigo.activePlugin.pluginPrefs["IMDirectory"] CameraDir = MainDir + "/" + CameraName NotActiveImage = CameraDir + "/NotActive.jpg" CameraDirTest = os.path.isdir(CameraDir) if CameraDirTest is False: indigo.server.log("Camera image directory not found. Creating...") os.makedirs(CameraDir) NotActiveImageTest = os.path.isfile(NotActiveImage) if NotActiveImageTest is False: img = Image.new("RGB", (200, 200), "grey") draw = ImageDraw.Draw(img) font = ImageFont.truetype("Verdana.ttf", 24) center = 100 - ((len(CameraName)*13)/2) draw.text((center, 75),CameraName,(255,255,255),font=font) center = 100 - ((len("Not Active")*12)/2) draw.text((center, 100),"Not Active",(255,255,255),font=font) img.save(NotActiveImage) indigo.server.log("Not Active Image not found. Creating...") if dev.states["CameraState"] != "Off": dev.updateStateOnServer("CameraState", value="On") dev.stateListOrDisplayStateIdChanged() return True ################################################################################ # # Main looping thread # ################################################################################ def runConcurrentThread(self): CarouselCount = 0 CarouselTimer = 0 MainDir = indigo.activePlugin.pluginPrefs["MainDirectory"] DebugMode = indigo.activePlugin.pluginPrefs["Debug"] self.debug = DebugMode try: for device in indigo.devices.iter("self"): CameraName = device.pluginProps["CameraName"] CameraState = device.states["CameraState"] tw = threading.Thread(name=CameraName, target=CameraThread, args=(device.id, MainDir)) tw.start() indigo.server.log("Thread started for " + CameraName + " camera. id: " + str(tw.ident)) #Debug Mode indigo.server.log("Starting main loop") while True: self.sleep(1) ################################################################################ # Setup ################################################################################ MainDir = indigo.activePlugin.pluginPrefs["MainDirectory"] RecordingCount = int(indigo.activePlugin.pluginPrefs["RecordingCount"]) RecordingPause = indigo.activePlugin.pluginPrefs["RecordingPause"] CarouselCameraPause = str(indigo.activePlugin.pluginPrefs["CarouselCameraPause"]) ################################################################################ # Recording setup ################################################################################ try: if RecordingPause == "False": #set record loop frame if RecordingCount > 29: RecordingCount = 0 else: RecordingCount = RecordingCount + 1 RecordingFrame = str(RecordingCount) indigo.activePlugin.pluginPrefs["RecordingFrame"] = RecordingFrame indigo.activePlugin.pluginPrefs["RecordingCount"] = RecordingCount except Exception as errtxt: indigo.server.log("Record Setup " + str(errtxt)) ################################################################################ # Create image carousel ################################################################################ #indigo.server.log("Carousel Paused: " + CarouselCameraPause) try: CarouselCount = int(indigo.activePlugin.pluginPrefs["CarouselCount"]) if CarouselCameraPause == "false": #indigo.server.log("Starting Carousel") CarouselTimer = RunCarousel(MainDir, CarouselCount, CarouselTimer) except Exception as errtxt: indigo.server.log("Carousel: " + str(errtxt)) ################################################################################ # Set Master Image ################################################################################ #indigo.server.log("Starting Master Image") try: MasterID = int(indigo.activePlugin.pluginPrefs["MasterCamera"]) #indigo.server.log(str(MasterID)) if MasterID != "": MasterImage() except Exception as errtxt: indigo.server.log("Unable to run Master Image: " + str(MasterID)) except self.StopThread: indigo.server.log("thread stopped") pass ################################################################################ # # Plugin menus # ################################################################################ def checkForUpdate(self): ActiveVersion = str(self.pluginVersion) CurrentVersion = str(self.updater.getVersion()) if ActiveVersion == CurrentVersion: indigo.server.log("Running the most recent version of Security Camera") else: indigo.server.log("The current version of Security Camera is " + str(CurrentVersion) + " and the running version " + str(ActiveVersion) + ".") def updatePlugin(self): ActiveVersion = str(self.pluginVersion) CurrentVersion = str(self.updater.getVersion()) if ActiveVersion == CurrentVersion: indigo.server.log("Already running the most recent version of Security Camera") else: indigo.server.log("The current version of Security Camera is " + str(CurrentVersion) + " and the running version " + str(ActiveVersion) + ".") self.updater.update() ################################################################################ # # Plugin actions # ################################################################################ def StopCamera(self, pluginAction): ## add code to stop thread CameraDevice = indigo.devices[pluginAction.deviceId] CameraName = CameraDevice.pluginProps["CameraName"] indigo.server.log("Stop Camera action called:" + CameraName) CameraDevice.updateStateOnServer("CameraState", value="Off") def StartCamera(self, pluginAction): ## add code to start thread CameraDevice = indigo.devices[pluginAction.deviceId] CameraName = CameraDevice.pluginProps["CameraName"] indigo.server.log("Start Camera action called:" + CameraName) CameraDevice.updateStateOnServer("CameraState", value="On") CameraDevice.updateStateOnServer("OfflineSeconds", value="On") def ToggleCamera(self, pluginAction): ## add code to start/stop thread CameraDevice = indigo.devices[pluginAction.deviceId] CameraName = CameraDevice.pluginProps["CameraName"] CameraState = CameraDevice.states["CameraState"] localPropsCopy = CameraDevice.pluginProps if CameraState == "On": indigo.server.log("Stop Camera action called:" + CameraName) CameraDevice.updateStateOnServer("CameraState", value="Off") else: indigo.server.log("Start Camera action called:" + CameraName) CameraDevice.updateStateOnServer("CameraState", value="On") CameraDevice.updateStateOnServer("OfflineSeconds", value="0") def MasterCamera(self, pluginAction): indigo.activePlugin.pluginPrefs["MasterCamera"] = pluginAction.deviceId indigo.activePlugin.pluginPrefs["RecordingFlag"] = 0 CameraDevice = indigo.devices[pluginAction.deviceId] CameraName = CameraDevice.pluginProps["CameraName"] try: MasterImage() except Exception as errtxt: LogMessage = CameraName + " Master: " + str(errtxt) indigo.server.log(LogMessage) def MotionOn(self, pluginAction): CameraDevice = indigo.devices[pluginAction.deviceId] CameraName = CameraDevice.pluginProps["CameraName"] Motion = CameraDevice.pluginProps["Motion"] props = CameraDevice.pluginProps indigo.server.log("Start motion action called:" + CameraName) props['Motion'] = True CameraDevice.replacePluginPropsOnServer(props) def MotionOff(self, pluginAction): CameraDevice = indigo.devices[pluginAction.deviceId] CameraName = CameraDevice.pluginProps["CameraName"] Motion = CameraDevice.pluginProps["Motion"] props = CameraDevice.pluginProps indigo.server.log("Stop motion action called:" + CameraName) props['Motion'] = False CameraDevice.replacePluginPropsOnServer(props) def ToggleMotion(self, pluginAction): CameraDevice = indigo.devices[pluginAction.deviceId] CameraName = CameraDevice.pluginProps["CameraName"] Motion = CameraDevice.pluginProps["Motion"] props = CameraDevice.pluginProps try: if Motion == True: indigo.server.log("Stop motion action called:" + CameraName) props['Motion'] = False CameraDevice.replacePluginPropsOnServer(props) else: indigo.server.log("Start motion action called:" + CameraName) props['Motion'] = True CameraDevice.replacePluginPropsOnServer(props) except Exception as errtxt: LogMessage = CameraName + "Toggle Motion: " + str(errtxt) indigo.server.log(LogMessage) def RecordCamera(self, pluginAction): try: CameraDevice = indigo.devices[pluginAction.deviceId] CameraName = CameraDevice.pluginProps["CameraName"] CameraDevice.updateStateOnServer("RecordSeconds", value=0) SavedDir = time.strftime("%m %d %Y %H.%M.%S") MainDir = indigo.activePlugin.pluginPrefs["MainDirectory"] SourceDir = MainDir + "/" + CameraName RecordingDir = MainDir + "/" + CameraName + "/" + SavedDir filecounter = 0 time.sleep(20) os.makedirs(RecordingDir) src_files = getSortedDir(SourceDir, "img", 0, 30) for file_name in src_files: filecounter = filecounter + 1 try: shutil.copy(file_name, RecordingDir) except Exception as errtxt: indigo.server.log(str(errtxt)) sortedList = getSortedDir(SourceDir, "img", 3, 4) CurrentImage = sortedList[0] for num in reversed(range(2, 10)): LeadingNum = "0" + str(num) Current = LeadingNum[-2:] LeadingPrev = "0" + str(num - 1) Previous = LeadingPrev[-2:] PrevValue = CameraDevice.states["Recording" + Previous] PrevNewValue = CameraDevice.states["NewRecording" + Previous] CameraDevice.updateStateOnServer("Recording" + Current, value=PrevValue) CameraDevice.updateStateOnServer("NewRecording" + Current, value=PrevNewValue) ThumbTo = SourceDir +"/thumb" + Current + ".jpg" ThumbFrom = SourceDir +"/thumb" + Previous + ".jpg" try: os.rename(ThumbFrom, ThumbTo) except Exception as errtxt: indigo.server.log("Thumb: " + str(errtxt)) CurrentThumb = SourceDir + "/Thumb01.jpg" shutil.copy (CurrentImage, CurrentThumb) CameraDevice.updateStateOnServer("Recording01", value=SavedDir) CameraDevice.updateStateOnServer("NewRecording01", value="New") except Exception as errtxt: indigo.server.log(CameraName + " Record: " + str(errtxt)) def ToggleCarousel(self, pluginAction): ToggleCarousel = indigo.activePlugin.pluginPrefs["CarouselOn"] if ToggleCarousel == "true": indigo.activePlugin.pluginPrefs["CarouselOn"] = "false" else: indigo.activePlugin.pluginPrefs["CarouselOn"] = "true" def ToggleCarouselCamera(self, pluginAction): ToggleCarousel = indigo.activePlugin.pluginPrefs["CarouselCameraPause"] if ToggleCarousel == "true": indigo.activePlugin.pluginPrefs["CarouselCameraPause"] = "false" else: indigo.activePlugin.pluginPrefs["CarouselCameraPause"] = "true" def NextCarouselCamera(self, pluginAction): MainDir = indigo.activePlugin.pluginPrefs["MainDirectory"] CarouselCount = int(indigo.activePlugin.pluginPrefs["CarouselCount"]) indigo.activePlugin.pluginPrefs["CarouselCount"] = CarouselCount + 1 RunCarousel(MainDir, CarouselCount, 5) def ToggleResolution(self, pluginAction): ToggleResolution = indigo.activePlugin.pluginPrefs["LowRes"] if ToggleResolution == "true": indigo.activePlugin.pluginPrefs["LowRes"] = "false" else: indigo.activePlugin.pluginPrefs["LowRes"] = "true" def PlayRecording(self, pluginAction): try: CameraDevice = indigo.devices[pluginAction.deviceId] CameraName = CameraDevice.pluginProps["CameraName"] RecordingID = pluginAction.props["PlaySelect"] Recording = CameraName + "/" + CameraDevice.states["Recording" + RecordingID] indigo.activePlugin.pluginPrefs["RecordingPause"] = "False" for device in indigo.devices.iter("self"): device.updateStateOnServer("Playing", value="Play") indigo.activePlugin.pluginPrefs["RecordingFrame"] = "0" indigo.activePlugin.pluginPrefs["RecordingCount"] = "0" indigo.activePlugin.pluginPrefs["RecordingFlag"] = 1 indigo.activePlugin.pluginPrefs["PlayRecording"] = Recording indigo.server.log("Play recording action called:" + CameraName) CameraDevice.updateStateOnServer("NewRecording" + RecordingID, value="") except Exception as errtxt: indigo.server.log(CameraName + " Play: " + str(errtxt)) def Snapshot(self, pluginAction): device = indigo.devices[pluginAction.deviceId] CameraName = device.pluginProps["CameraName"] SnapshotDir = indigo.activePlugin.pluginPrefs["SnapshotDirectory"] SnapshotImage = SnapshotDir + "/Snap001.jpg" Quality = int(pluginAction.props["Quality"]) CameraAddress = "http://" + device.pluginProps["CameraAddress"] CameraUser = device.pluginProps["uname"] CameraPwd = device.pluginProps["pwd"] Digest = device.pluginProps["Digest"] Rotation = device.pluginProps["CameraRotation"] Brightness = device.pluginProps["Brightness"] Contrast = device.pluginProps["Contrast"] Sharpness = device.pluginProps["Sharpness"] BorderWidth = int(device.pluginProps["BorderWidth"])*2 BorderColor = device.pluginProps["BorderColor"] ImageWidth = 640 ImageHeight = 480 nowtime = datetime.datetime.now() displaytime = str(nowtime).split(".")[0] labelText = CameraName + " : " + displaytime #indigo.server.log("Capture Image") #indigo.server.log(CameraAddress) img=getURLImage(CameraAddress,CameraUser,CameraPwd, Digest) #indigo.server.log("Set Size") img.thumbnail((ImageWidth, ImageHeight)) #indigo.server.log(Brightness +":"+ Contrast +":"+ Sharpness) img=editImage(img, int(Rotation), float(Brightness), float(Contrast), float(Sharpness), False) #indigo.server.log("Add black bars") img=addBorder(img, ImageWidth, ImageHeight, "black") #indigo.server.log("Add Text") img=addLabel(img, labelText) #indigo.server.log("Add Border") img=addBorder(img, ImageWidth + BorderWidth, ImageHeight + BorderWidth, BorderColor) #save image history for num in reversed(range(1, 5)): fromfile = "Snap00" + str(num) fromfile = SnapshotDir + "/" + fromfile + ".jpg" tofile = "Snap00" + str(num+1) tofile = SnapshotDir + "/" + tofile + ".jpg" if os.path.isfile(fromfile): os.rename(fromfile, tofile) try: img.save(SnapshotImage,optimize=True,quality=Quality) except Exception as errtxt: indigo.server.log(str(errtxt)) def GIF(self, pluginAction): CameraDevice = indigo.devices[pluginAction.deviceId] CameraName = CameraDevice.pluginProps["CameraName"] SnapshotDir = indigo.activePlugin.pluginPrefs["SnapshotDirectory"] MainDir = indigo.activePlugin.pluginPrefs["MainDirectory"] SourceDir = MainDir + "/" + CameraName +"/" DestName = SnapshotDir + "/" + CameraName + ".gif" sortedList = getSortedDir(SourceDir, "img", 0, 30) images = [Image.open(fn) for fn in sortedList] writeGif(DestName, images, duration=1) indigo.server.log("done giffing") def PauseRecording(self, pluginAction): RecordingPaused = indigo.activePlugin.pluginPrefs["RecordingPause"] PlayState = "" if RecordingPaused == "False": indigo.activePlugin.pluginPrefs["RecordingPause"] = "True" PlayState = "Pause" else: indigo.activePlugin.pluginPrefs["RecordingPause"] = "False" PlayState = "Play" for device in indigo.devices.iter("self"): device.updateStateOnServer("Playing", value=PlayState) def FrameBackward(self, pluginAction): RecordingCount = int(indigo.activePlugin.pluginPrefs["RecordingCount"]) #set record loop frame if RecordingCount < 0: RecordingCount = 20 else: RecordingCount = RecordingCount - 1 RecordingFrame = str(RecordingCount) indigo.activePlugin.pluginPrefs["RecordingFrame"] = RecordingFrame indigo.activePlugin.pluginPrefs["RecordingCount"] = RecordingCount def FrameForward(self, pluginAction): RecordingCount = int(indigo.activePlugin.pluginPrefs["RecordingCount"]) #set record loop frame if RecordingCount > 20: RecordingCount = 0 else: RecordingCount = RecordingCount + 1 RecordingFrame = str(RecordingCount) indigo.activePlugin.pluginPrefs["RecordingFrame"] = RecordingFrame indigo.activePlugin.pluginPrefs["RecordingCount"] = RecordingCount def Mosaic(self, pluginAction): CameraDevice = indigo.devices[pluginAction.deviceId] CameraName = CameraDevice.pluginProps["CameraName"] try: GetMosaic(CameraDevice) except Exception as errtxt: indigo.server.log(CameraName + " Mosaic: " + str(errtxt)) def CameraCommand(self, pluginAction): ReturnVariable = pluginAction.props["ReturnVariable"] CameraAddress = "http://" + device.pluginProps["CameraAddress"] CameraUser = device.pluginProps["uname"] CameraPwd = device.pluginProps["pwd"] ReturnVariable = ReturnVariable.replace(" ", "_") try: ReturnVar = indigo.variables[ReturnVariable] except Exception as errtxt: indigo.server.log(str(errtxt)) indigo.variable.create(ReturnVariable) indigo.server.log(ReturnVariable + " created") #indigo.server.log("start url Command") if digest: try: response = requests.get(CameraAddress, auth=HTTPDigestAuth(CameraUser, CameraPwd), timeout=(1, 3)) indigo.variable.updateValue(ReturnVariable, value=str(returnvalue)) except: indigo.variable.updateValue(ReturnVariable, value="Command Failed") else: try: response = requests.get(CameraAddress, auth=(CameraUser, CameraPwd), timeout=(1, 3)) indigo.variable.updateValue(ReturnVariable, value=str(returnvalue)) except: indigo.variable.updateValue(ReturnVariable, value="Command Failed") def DeleteRecording(self, pluginAction): CameraDevice = indigo.devices[pluginAction.deviceId] CameraName = CameraDevice.pluginProps["CameraName"] Months = pluginAction.props["DeleteMonths"] Days = int(Months) * 30 MainDir = indigo.activePlugin.pluginPrefs["MainDirectory"] ArchiveDir = MainDir + "/" + "Archive" + "/" + CameraName OldDirs = [] today = date.today() StartPath = MainDir + "/" + CameraName for root, dirs, files in os.walk(StartPath): for FileName in dirs: filedate = date.fromtimestamp(os.path.getmtime(os.path.join(root, FileName))) if (today - filedate).days >= Days: CurrentDir = StartPath + "/" + FileName shutil.copytree(CurrentDir,ArchiveDir+ "/" + FileName) shutil.rmtree(CurrentDir) indigo.server.log("Archived videos older than " + Months + " months:" + CameraName)
class Plugin(indigo.PluginBase): ######################################## def __init__(self, pluginId, pluginDisplayName, pluginVersion, pluginPrefs): super(Plugin, self).__init__(pluginId, pluginDisplayName, pluginVersion, pluginPrefs) self.debug = False self.updater = GitHubPluginUpdater(self) ######################################### # Plugin startup and shutdown ######################################### def startup(self): self.debugLog(u"startup called") def shutdown(self): self.debugLog(u"shutdown called") def didDeviceCommPropertyChange(self, origDev, newDev): return False ######################################### # Main Loop ######################################### def runConcurrentThread(self): try: ######################################### # Variable Setup ######################################### timeremaining = 0 refreshduration = 5 refreshcycle = refreshduration repeat = "" shuffle = "" logdevice = self.logger while True: for device in indigo.devices.iter("self"): ######################################### # Main Code ######################################### state = device.states["state"] if state == "playing": timeremaining = timeremaining - 1000 device.updateStateOnServer("timeremaining", value=timeremaining) consec, conmin = convertms(timeremaining) device.updateStateOnServer("timeremainingtext", value=str(conmin) + ":" + str(consec).zfill(2)) else: device.updateStateOnServer("timeremainingtext", value="0") refreshcycle = refreshcycle + 1 #Check for status of player every five seconds if timeremaining < 0 or refreshcycle > refreshduration: spotifykey = device.pluginProps["SpotifyKey"] refreshkey = device.pluginProps["RefreshKey"] refreshcycle = 0 playingsong = False playerstate = False try: playerstate = GetPlayerState( self.logger, device, spotifykey) except Exception as errtxt: self.logger.debug("error 85:" + str(errtxt)) #indigo.server.log(str(playerstate)) #indigo.server.log("A:" + getspotifydevice(device)) #indigo.server.log("1:" + str(playerstate['isplaying'])) if getspotifydevice( self.logger, device) != "Device Not Found" and (str( playerstate['result']) == "True") and (str( playerstate['isplaying']) == "True"): spotifydevice = playerstate['spotifydevice'] keyValueList = [{ 'key': 'state', 'value': 'playing' }] #device.updateStateOnServer("state", "playing") contextmeta = playerstate[ 'spotifycontexturi'].split(":") #indigo.server.log(playlistmeta[2]) #indigo.server.log(playlistmeta[4]) #indigo.server.log(str(contextmeta)) #indigo.server.log(playerstate['spotifycontexttype']) GetContextDetail(self.logger, device, playerstate['spotifycontexttype'], spotifykey, contextmeta) #Check volume if int(playerstate['spotifyvolume']) != int( device.states["volume"]): keyValueList.append({ 'key': 'volume', 'value': playerstate['spotifyvolume'] }) #device.updateStateOnServer("volume", playerstate['spotifyvolume']) #Check repeat if playerstate['repeat'] != device.states["repeat"]: if device.states["repeat"] == "off": keyValueList.append({ 'key': 'repeat', 'value': 'context' }) #device.updateStateOnServer("repeat", value="context") else: keyValueList.append({ 'key': 'repeat', 'value': 'off' }) #device.updateStateOnServer("repeat", value="off") #Check shuffle if str(playerstate['shuffle']) != str( device.states["shuffle"]): if str(device.states["shuffle"]) == "False": keyValueList.append({ 'key': 'shuffle', 'value': 'True' }) #device.updateStateOnServer("shuffle", value="True") else: keyValueList.append({ 'key': 'shuffle', 'value': 'False' }) #device.updateStateOnServer("shuffle", value="False") #Update song information playingsong = GetCurrentSong( self.logger, device, spotifykey) if playingsong['result'] != "False": timeremaining = playingsong[ 'duration'] - playingsong['progress'] consec, conmin = convertms( playingsong['duration']) keyValueList.append({ 'key': 'durationtext', 'value': str(conmin) + ":" + str(consec).zfill(2) }) if playingsong['track'] != device.states[ "c_track"]: UpdateCurrentSong(self.logger, device, playingsong) else: self.logger.debug(u"Get playing song failed") device.updateStatesOnServer(keyValueList) else: if getspotifydevice(self.logger, device) != "Device Not Found": device.updateStateOnServer("state", value="paused") self.sleep(1) except self.StopThread: indigo.server.log("thread stopped") pass ################################################################################ # Plugin menus ################################################################################ def checkForUpdate(self): ActiveVersion = str(self.pluginVersion) CurrentVersion = str(self.updater.getVersion()) if ActiveVersion == CurrentVersion: indigo.server.log("Running the most recent version of Indify") else: indigo.server.log("The current version of Indify is " + str(CurrentVersion) + " and the running version " + str(ActiveVersion) + ".") def updatePlugin(self): ActiveVersion = str(self.pluginVersion) CurrentVersion = str(self.updater.getVersion()) if ActiveVersion == CurrentVersion: indigo.server.log( "Already running the most recent version of Indify") else: indigo.server.log("The current version of Indify is " + str(CurrentVersion) + " and the running version " + str(ActiveVersion) + ".") self.updater.update() def RefreshKey(self): indigo.server.log("?? Refresh Key") #RefreshKey(device, refreshkey) ############################################################################ # Plugin Actions object callbacks ############################################################################ #015 def toggle(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] state = device.states["state"] spotifydevice = getspotifydevice(self.logger, device) if state == "playing": response = callspotifycommand( self.logger, "015", device, "put", "https://api.spotify.com/v1/me/player/pause") if response != "Error": device.updateStateOnServer("state", value="paused") else: response = callspotifycommand( self.logger, "015", device, "put", "https://api.spotify.com/v1/me/player/", { "device_ids": [spotifydevice], "play": True }) if response != "Error": device.updateStateOnServer("state", value="playing") #016 def play(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifydevice = getspotifydevice(self.logger, device) response = callspotifycommand(self.logger, "016", device, "put", "https://api.spotify.com/v1/me/player/", { "device_ids": [spotifydevice], "play": True }) if response != "Error": device.updateStateOnServer("state", value="playing") #017 def pause(self, pluginAction): device = indigo.devices[pluginAction.deviceId] response = callspotifycommand( self.logger, "017", device, "put", "https://api.spotify.com/v1/me/player/pause") if response != "Error": device.updateStateOnServer("state", value="paused") #018 def next(self, pluginAction): device = indigo.devices[pluginAction.deviceId] state = device.states["state"] if state == "playing": response = callspotifycommand( self.logger, "018", device, "post", "https://api.spotify.com/v1/me/player/next") #019 def previous(self, pluginAction): device = indigo.devices[pluginAction.deviceId] state = device.states["state"] if state == "playing": response = callspotifycommand( self.logger, "019", device, "post", "https://api.spotify.com/v1/me/player/previous") #020 def playuri(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifyuri = pluginAction.props["spotifyuri"] uribody = {"context_uri": spotifyuri} response = callspotifycommand( self.logger, "020", device, "put", "https://api.spotify.com/v1/me/player/play", uribody) def repeat(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] repeat = device.states["repeat"] if repeat == "off": device.updateStateOnServer("repeat", value="context") ChangeRepeat(self.logger, device, spotifykey, "context") else: device.updateStateOnServer("repeat", value="off") ChangeRepeat(self.logger, device, spotifykey, "off") def shuffle(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] shuffle = device.states["shuffle"] if shuffle == "False": device.updateStateOnServer("shuffle", value="True") ChangeShuffle(self.logger, device, spotifykey, "True") else: device.updateStateOnServer("shuffle", value="False") ChangeShuffle(self.logger, device, spotifykey, "False") def setvolume(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] newvolume = int(pluginAction.props["setpercent"]) SetVolume(self.logger, device, spotifykey, newvolume) device.updateStateOnServer("volume", value=newvolume) def increasevolume(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] oldvolume = int(device.states['volume']) increasepercent = int(pluginAction.props["increasepercent"]) if int(oldvolume) < 100: newvolume = oldvolume + increasepercent SetVolume(self.logger, device, spotifykey, newvolume) device.updateStateOnServer("volume", value=newvolume) def decreasevolume(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] oldvolume = device.states['volume'] decreasepercent = int(pluginAction.props["decreasepercent"]) if int(oldvolume) > 0: newvolume = oldvolume - decreasepercent SetVolume(self.logger, device, spotifykey, newvolume) device.updateStateOnServer("volume", value=newvolume) def loadplaylistpage(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] state = device.states["state"] itemsperpage = int(device.pluginProps["PlaylistsPerPage"]) pagenumber = int(pluginAction.props["pagenumber"]) LoadPlayListPage(self.logger, device, spotifykey, pagenumber, itemsperpage) def nextplaylistpage(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] playlistpage = int(device.states["playlistpage"]) itemsperpage = int(device.pluginProps["PlaylistsPerPage"]) pagenumber = playlistpage + 1 LoadPlayListPage(self.logger, device, spotifykey, pagenumber, itemsperpage) def previousplaylistpage(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] playlistpage = int(device.states["playlistpage"]) itemsperpage = int(device.pluginProps["PlaylistsPerPage"]) pagenumber = playlistpage - 1 LoadPlayListPage(self.logger, device, spotifykey, pagenumber, itemsperpage) def selectplaylist(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] selectedplaylist = int(pluginAction.props["selectedplaylist"]) playlistid = device.states["playlistid_" + str(selectedplaylist)] playlistuser = device.states["playlistuser_" + str(selectedplaylist)] LoadPlaylistDetail(self.logger, device, spotifykey, playlistuser, playlistid) itemsperpage = int(device.pluginProps["TracksPerPage"]) LoadTrackPage(self.logger, device, playlistuser, playlistid, spotifykey, 1, itemsperpage) def loadtrackspage(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] pagenumber = int(pluginAction.props["trackpagenumber"]) playlistid = device.states["playlistid"] playlistuser = device.states["playlistuserid"] itemsperpage = int(device.pluginProps["TracksPerPage"]) LoadTrackPage(self.logger, device, playlistuser, playlistid, spotifykey, pagenumber, itemsperpage) def nexttrackspage(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] trackpage = int(device.states["trackpage"]) playlistid = device.states["playlistid"] playlistuser = device.states["playlistuserid"] itemsperpage = int(device.pluginProps["TracksPerPage"]) pagenumber = trackpage + 1 LoadTrackPage(self.logger, device, playlistuser, playlistid, spotifykey, pagenumber, itemsperpage) def previoustrackspage(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifykey = device.pluginProps["SpotifyKey"] trackpage = int(device.states["trackpage"]) playlistid = device.states["playlistid"] playlistuser = device.states["playlistuserid"] itemsperpage = int(device.pluginProps["TracksPerPage"]) pagenumber = trackpage - 1 LoadTrackPage(self.logger, device, playlistuser, playlistid, spotifykey, pagenumber, itemsperpage) #020 def getspotifydevices(self, filter, valuesDict, typeId, devId): device = indigo.devices[devId] refreshkey = device.pluginProps["SpotifyKey"] keysuccess = "False" spotifydevicearray = [] try: spotifykey = device.pluginProps["SpotifyKey"] spotifyurl = "https://api.spotify.com/v1/me/player/devices" spotifyheader = {"Authorization": "Bearer " + spotifykey} response = requests.get(spotifyurl, headers=spotifyheader, timeout=(1, 6)) data = json.loads(response.text) for spotifydevices in data['devices']: spotifydevice = (spotifydevices['name'], spotifydevices['name']) spotifydevicearray.append(spotifydevice) except: indigo.server.log("error 020: Refreshing Spotify Key") keysuccess = RefreshKey(self.logger, device, refreshkey) if keysuccess == "True": self.logger.debug("New Key Aquired") else: #### add code to retry device lookup without getting into crazy loop #### set spotify state to offline #### wait 30 seconds and try again spotifydevicearray.append(("0", "Error in Spotify key Lookup")) return spotifydevicearray #020 def playselectedplaylist(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifydevice = getspotifydevice(self.logger, device) spotifydata = { "context_uri": "spotify:user:"******"playlistuserid"] + ":playlist:" + device.states["playlistid"], "device_ids": [spotifydevice] } response = callspotifycommand( self.logger, "020", device, "put", "https://api.spotify.com/v1/me/player/play", spotifydata) if response != "Error": device.updateStateOnServer("state", value="playing") #021 def playplaylist(self, pluginAction): device = indigo.devices[pluginAction.deviceId] spotifydevice = getspotifydevice(self.logger, device) selectedplaylist = int(pluginAction.props["PlaySelectedPlaylist"]) playlistid = device.states["playlistid_" + str(selectedplaylist)] playlistuser = device.states["playlistuser_" + str(selectedplaylist)] spotifydata = { "context_uri": "spotify:user:"******":playlist:" + playlistid, "device_ids": [spotifydevice] } response = callspotifycommand( self.logger, "021", device, "put", "https://api.spotify.com/v1/me/player/play", spotifydata) if response != "Error": device.updateStateOnServer("state", value="playing") def validatespotifyid(self, valuesDict, typeId, devId): device = indigo.devices[devId] device.replacePluginPropsOnServer(valuesDict) indigo.server.log("Updating Spotify device list")
class Plugin(indigo.PluginBase): ######################################## def __init__(self, pluginId, pluginDisplayName, pluginVersion, pluginPrefs): super(Plugin, self).__init__(pluginId, pluginDisplayName, pluginVersion, pluginPrefs) self.debug = False self.updater = GitHubPluginUpdater(self) ######################################### # Plugin startup and shutdown ######################################### def startup(self): self.debugLog(u"startup called") def shutdown(self): self.debugLog(u"shutdown called") def didDeviceCommPropertyChange(self, origDev, newDev): return False def deviceStartComm(self, dev): Directory = dev.pluginProps["Directory"] #Main Dir Test DirTest = os.path.isdir(Directory) if DirTest is False: indigo.server.log("Button directory not found.") os.makedirs(Directory) indigo.server.log("Created: " + Directory) ######################################### # Main Loop ######################################### def runConcurrentThread(self): try: while True: for device in indigo.devices.iter("self"): ######################################### # Variable Setup ######################################### #try: ButtonName = device.name ButtonFile = ButtonName.replace(" ", "_") + ".png" Directory = device.pluginProps["Directory"] ButtonCoordX = int(device.pluginProps["ButtonCoordX"]) ButtonCoordY = int(device.pluginProps["ButtonCoordY"]) CanvasX = int(device.pluginProps["CanvasX"]) CanvasY = int(device.pluginProps["CanvasY"]) CanvasR = int(device.pluginProps["CanvasR"]) CanvasG = int(device.pluginProps["CanvasG"]) CanvasB = int(device.pluginProps["CanvasB"]) CanvasT = int(device.pluginProps["CanvasT"]) ButtonX = int(device.pluginProps["ButtonX"]) ButtonY = int(device.pluginProps["ButtonY"]) ButtonR = int(device.pluginProps["ButtonR"]) ButtonG = int(device.pluginProps["ButtonG"]) ButtonB = int(device.pluginProps["ButtonB"]) ButtonT = int(device.pluginProps["ButtonT"]) GrowY = device.pluginProps["growy"] GrowX = device.pluginProps["growx"] #except: #pass ######################################### # Main Code ######################################### #indigo.server.log("creating image " + GrowY) ##Create Canvas img = canvas(CanvasX,CanvasY) img = box(img,0,0,CanvasX,CanvasY,CanvasR,CanvasG,CanvasB,CanvasT) ##Left and right movement if GrowX == "growleft": Bx = CanvasX elif GrowX == "growright": Bx = 0 elif ButtonCoordX < 0: Bx = ButtonX ButtonCoordX = 1 elif ButtonCoordX >= (CanvasX-ButtonX): ButtonCoordX = CanvasX Bx = CanvasX - ButtonX else: Bx = ButtonCoordX + ButtonX ##Up and down movement if GrowY == "growup": By = CanvasY elif GrowY == "growdown": By = 0 elif ButtonCoordY < 0: By = ButtonY ButtonCoordY = 1 elif ButtonCoordY >= (CanvasY-ButtonY): ButtonCoordY = CanvasY By = CanvasY - ButtonY else: By = ButtonCoordY + ButtonY img = box(img,ButtonCoordX,ButtonCoordY,Bx,By,ButtonR,ButtonG,ButtonB,ButtonT) img.save(Directory + ButtonFile,quality=15,optimize=True) self.sleep(.25) except self.StopThread: indigo.server.log("thread stopped") pass ################################################################################ # Plugin menus ################################################################################ def checkForUpdate(self): ActiveVersion = str(self.pluginVersion) CurrentVersion = str(self.updater.getVersion()) if ActiveVersion == CurrentVersion: indigo.server.log("Running the most recent version of Dynamic Button") else: indigo.server.log("The current version of Dynamic Button is " + str(CurrentVersion) + " and the running version " + str(ActiveVersion) + ".") def updatePlugin(self): ActiveVersion = str(self.pluginVersion) CurrentVersion = str(self.updater.getVersion()) if ActiveVersion == CurrentVersion: indigo.server.log("Already running the most recent version of Dynamic Button") else: indigo.server.log("The current version of Dynamic Button is " + str(CurrentVersion) + " and the running version " + str(ActiveVersion) + ".") self.updater.update() ######################################### # Plugin Actions object callbacks ######################################### def toggle(self, pluginAction): dev = indigo.devices[pluginAction.deviceId] state = dev.states["state"] if state == "on": dev.updateStateOnServer("state", value="off") else: dev.updateStateOnServer("state", value="on") def MoveButton(self, pluginAction): dev = indigo.devices[pluginAction.deviceId] CanvasX = int(dev.pluginProps["CanvasX"]) CanvasY = int(dev.pluginProps["CanvasY"]) ButtonCoordX = int(dev.pluginProps["ButtonCoordX"]) ButtonCoordY = int(dev.pluginProps["ButtonCoordY"]) growud = dev.pluginProps["growy"] growlr = dev.pluginProps["growx"] percentpixel = pluginAction.props["percentpixel"] relativeto = pluginAction.props["relative"] usevariables = pluginAction.props["usevariables"] if usevariables == False: MoveX = float(pluginAction.props["MoveX"]) MoveY = float(pluginAction.props["MoveY"]) else: try: varMoveX = int(pluginAction.props["MoveX"]) MoveX = float(indigo.variables[varMoveX].value) except: MoveX = 0 try: varMoveY = int(pluginAction.props["MoveY"]) MoveY = float(indigo.variables[varMoveY].value) except: MoveY = 0 ## Move button via % change if percentpixel == "percent": if relativeto == "current": NewCoordx = ButtonCoordX + (CanvasX * float(MoveX/100)) NewCoordy = ButtonCoordY + (CanvasY * float(MoveY/100)) else: if MoveX <= 0: NewCoordx = ButtonCoordX else: NewCoordx = (CanvasX * float((MoveX/100))) if MoveY <= 0: NewCoordy = ButtonCoordY else: NewCoordy = (CanvasY * float((MoveY/100))) ## Move button via pixel change else: if relativeto == "current": NewCoordx = ButtonCoordX + MoveX NewCoordy = ButtonCoordY + MoveY else: if MoveX <= 0: NewCoordx = ButtonCoordX else: NewCoordx = MoveX if MoveY <= 0: NewCoordy = ButtonCoordY else: NewCoordy = MoveY if NewCoordx < 0: NewCoordx = 0 elif NewCoordx > CanvasX: NewCoordx = CanvasX if NewCoordy < 0: NewCoordy = 0 elif NewCoordy > CanvasY: NewCoordy = CanvasY if growud == "growup": NewCoordy = CanvasY - NewCoordy if growlr == "growleft": NewCoordx = CanvasX - NewCoordx localPropsCopy = dev.pluginProps localPropsCopy["ButtonCoordY"] = str(int(NewCoordy)) dev.replacePluginPropsOnServer(localPropsCopy) localPropsCopy["ButtonCoordX"] = str(int(NewCoordx)) dev.replacePluginPropsOnServer(localPropsCopy) def ButtonColor(self, pluginAction): dev = indigo.devices[pluginAction.deviceId] usevariables = pluginAction.props["usevariables"] if usevariables == False: ButtonR = pluginAction.props["buttonr"] ButtonG = pluginAction.props["buttong"] ButtonB = pluginAction.props["buttonb"] ButtonT = pluginAction.props["buttont"] else: try: ButtonR = indigo.variables[int(pluginAction.props["buttonr"])].value except: ButtonR = 0 try: ButtonG = indigo.variables[int(pluginAction.props["buttong"])].value except: ButtonG = 0 try: ButtonB = indigo.variables[int(pluginAction.props["buttonb"])].value except: ButtonB = 0 try: ButtonT = indigo.variables[int(pluginAction.props["buttont"])].value except: ButtonT = 0 localPropsCopy = dev.pluginProps localPropsCopy["ButtonR"] = ButtonR dev.replacePluginPropsOnServer(localPropsCopy) localPropsCopy["ButtonG"] = ButtonG dev.replacePluginPropsOnServer(localPropsCopy) localPropsCopy["ButtonB"] = ButtonB dev.replacePluginPropsOnServer(localPropsCopy) localPropsCopy["ButtonT"] = ButtonT dev.replacePluginPropsOnServer(localPropsCopy) def CanvasColor(self, pluginAction): dev = indigo.devices[pluginAction.deviceId] usevariables = pluginAction.props["usevariables"] if usevariables == False: CanvasR = pluginAction.props["canvasr"] CanvasG = pluginAction.props["canvasg"] CanvasB = pluginAction.props["canvasb"] CanvasT = pluginAction.props["canvast"] else: try: CanvasR = indigo.variables[int(pluginAction.props["canvasr"])].value except: CanvasR = 0 try: CanvasG = indigo.variables[int(pluginAction.props["canvasg"])].value except: CanvasG = 0 try: CanvasB = indigo.variables[int(pluginAction.props["canvasb"])].value except: CanvasB = 0 try: CanvasT = indigo.variables[int(pluginAction.props["canvast"])].value except: CanvasT = 0 localPropsCopy = dev.pluginProps localPropsCopy["CanvasR"] = CanvasR dev.replacePluginPropsOnServer(localPropsCopy) localPropsCopy["CanvasG"] = CanvasG dev.replacePluginPropsOnServer(localPropsCopy) localPropsCopy["CanvasB"] = CanvasB dev.replacePluginPropsOnServer(localPropsCopy) localPropsCopy["CanvasT"] = CanvasT dev.replacePluginPropsOnServer(localPropsCopy)