Exemplo n.º 1
0
	def format_list_column_entry (self, columndefs, columndata):
		"""
		Return a list item formatted to comply with the column definitions.
		
		Arguments:
			columndefs:				(list) maximum spaces per column
			columndata:				(list) the data to enter into the columns
			
		Returns:
			list representative of the column configuration
		"""
		
		try:
			colidx = 0
			output = ""
			
			for c in columndata	:
				length = columndefs[colidx]
				if len(str(c)) > (length):
					# Shorten the value so it fits, it should be tabs * 4 - 1 to leave a space between columns
					x = (length) - 1 # Shorten by one extra for space between columns
					x = x - 3 # Shorted by 3 more so we can add '...' to let the user know its been truncated
					c = c[0:x] + "..."

				column = u"{}".format(c).ljust(length)
				output += column

				colidx = colidx + 1

			return output
		
		except Exception as e:
			self.logger.error (ex.stack_trace(e))			
Exemplo n.º 2
0
    def list_extensions(self,
                        filter="",
                        valuesDict=None,
                        typeId="",
                        targetId=0):
        """
		Return a custom list of extensions - will not include extensions that don't have a userman account so it may be incomplete.
		"""

        try:
            listData = [("default", "No data")]
            if not 'server' in valuesDict: return listData
            if valuesDict['server'] == '': return listData

            server = indigo.devices[int(valuesDict['server'])]
            result = self.invoke_api(server, 'userman', '', '', 'extensions')
            if result:
                listData = []
                for extension_num, userman in result.iteritems():
                    listData.append((extension_num, extension_num))

        except Exception as e:
            self.logger.error(ex.stack_trace(e))

        return listData
Exemplo n.º 3
0
    def update_state(self, dev):
        try:
            status = self.update_address_status(dev)
            keyValueList = []
            onOffState = True  # Assume on until decided otherwise

            # Only analyze conditions that will set the onstate to off
            if dev.pluginProps['ison'] == 'notready' and status == 'Ready':
                onOffState = False
            elif dev.pluginProps['ison'] == 'ready' and status != 'Ready':
                onOffState = False
            elif dev.pluginProps['ison'] == 'dnd' and 'DND ' not in status:
                onOffState = False
            elif dev.pluginProps['ison'] == 'notdnd' and 'DND ' in status:
                onOffState = False
            elif dev.pluginProps['ison'] == 'cf' and 'CF ' not in status:
                onOffState = False
            elif dev.pluginProps['ison'] == 'notcf' and 'CF ' in status:
                onOffState = False
            elif dev.pluginProps['ison'] == 'cfu' and 'CFU ' not in status:
                onOffState = False
            elif dev.pluginProps['ison'] == 'notcfu' and 'CFU ' in status:
                onOffState = False
            elif dev.pluginProps['ison'] == 'cfb' and 'CFB ' not in status:
                onOffState = False
            elif dev.pluginProps['ison'] == 'notcfb' and 'CFB ' in status:
                onOffState = False

            keyValueList.append({'key': 'onOffState', 'value': onOffState})
            dev.updateStatesOnServer(keyValueList)

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 4
0
    def actionControlDimmerRelay(self, action, dev):
        try:
            if dev.deviceTypeId == 'CallFlow':
                return self.device_control_flow(action, dev)

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 5
0
    def action_dnd(self, action):
        try:
            method = 'donotdisturb'

            dev = indigo.devices[action.deviceId]
            server = int(dev.pluginProps["server"])
            if not server in indigo.devices:
                self.logger.error(
                    u"PBX Server {} is not in the Indigo device list, was it removed?  {} action cannot complete"
                    .format(server, dev.name))
                return

            server = indigo.devices[server]
            params = {}

            if action.pluginTypeId == 'dndEnable':
                params["status"] = 'enabled'
            else:
                params["status"] = False

            result = self.invoke_api(server, method,
                                     dev.pluginProps["extension"],
                                     json.dumps(params))

            self.update_extension_status(dev)

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 6
0
	def add_record (self, record, valuesDict):
		"""
		Add record to the current record name that was passed on initialization.
		
		Arguments:
			record:				(list) field data in the same order as the structure passed during init
			valuesDict			(dict) dictionary of form values
		"""
	
		try:
			self.set_form_records (valuesDict)
			
			rec = {}
			rec["jkey"] = self.create_unique_key()
			
			for i in range (0, len(record)):
				rec[self.structure[i]] = record[i]
				
			self.records.append (rec)		
			valuesDict = self.apply_form_records(valuesDict)
			
			
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
			
		return valuesDict
Exemplo n.º 7
0
	def apply_form_records (self, valuesDict):
		"""
		JSON encode the current record set into the larger record set and save it to valuesDict.
		
		Arguments:
			valuesDict				(dict) dictionary of form values to read from and write to
			
		Returns:
			dict					valuesDict modified
		"""
		
		try:
			currentrecords = self.records
			self.set_form_records (valuesDict) # Always refresh in case another process updated a record
			
			if not JSON_FIELD in valuesDict:
				allrecords = {}
				valuesDict[JSON_FIELD] = json.dumps(allrecords)
				
			allrecords = json.loads(valuesDict[JSON_FIELD])	
			allrecords[self.recordName] = currentrecords
				
			valuesDict[JSON_FIELD] = json.dumps(allrecords)	
		
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
			
		return valuesDict
Exemplo n.º 8
0
    def apply_form_records(self, valuesDict):
        """
		JSON encode the current record set into the larger record set and save it to valuesDict.
		
		Arguments:
			valuesDict				(dict) dictionary of form values to read from and write to
			
		Returns:
			dict					valuesDict modified
		"""

        try:
            currentrecords = self.records
            self.set_form_records(
                valuesDict
            )  # Always refresh in case another process updated a record

            if not JSON_FIELD in valuesDict:
                allrecords = {}
                valuesDict[JSON_FIELD] = json.dumps(allrecords)

            allrecords = json.loads(valuesDict[JSON_FIELD])
            allrecords[self.recordName] = currentrecords

            valuesDict[JSON_FIELD] = json.dumps(allrecords)

        except Exception as e:
            self.logger.error(ex.stack_trace(e))

        return valuesDict
Exemplo n.º 9
0
	def __init__(self, plugin, name = '', structure = [], obj = None):
		"""
		Start the factory with references back to the base plugin.
		
		Arguments:
		plugin: 			Indigo plugin
		name:				(str) JSON record name
		structure:			(list) JSON record structure
		"""
	
		try:
			if plugin is None: return # pre-loading before init
			
			self.logger = logging.getLogger ("Plugin.{}".format(self.__class__.__name__.replace("_","")))
			
			self.plugin = plugin	# References the Indigo plugin
			self.records = [] # All JSON records for this type
			
			if not "jkey" in structure: structure.append("jkey")
			
			self.structure = structure # Record structure for this data type
			self.recordName = name
			
			self.obj = obj
		
			self.logger.debug ("{} {} loaded".format(__modname__, __version__))
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
Exemplo n.º 10
0
    def add_record(self, record, valuesDict):
        """
		Add record to the current record name that was passed on initialization.
		
		Arguments:
			record:				(list) field data in the same order as the structure passed during init
			valuesDict			(dict) dictionary of form values
		"""

        try:
            self.set_form_records(valuesDict)

            rec = {}
            rec["jkey"] = self.create_unique_key()

            for i in range(0, len(record)):
                rec[self.structure[i]] = record[i]

            self.records.append(rec)
            valuesDict = self.apply_form_records(valuesDict)

        except Exception as e:
            self.logger.error(ex.stack_trace(e))

        return valuesDict
Exemplo n.º 11
0
    def __init__(self, plugin, name='', structure=[], obj=None):
        """
		Start the factory with references back to the base plugin.
		
		Arguments:
		plugin: 			Indigo plugin
		name:				(str) JSON record name
		structure:			(list) JSON record structure
		"""

        try:
            if plugin is None: return  # pre-loading before init

            self.logger = logging.getLogger("Plugin.{}".format(
                self.__class__.__name__.replace("_", "")))

            self.plugin = plugin  # References the Indigo plugin
            self.records = []  # All JSON records for this type

            if not "jkey" in structure: structure.append("jkey")

            self.structure = structure  # Record structure for this data type
            self.recordName = name

            self.obj = obj

            self.logger.debug("{} {} loaded".format(__modname__, __version__))

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 12
0
	def ssh (self, props, activity):
		"""
		Establish SSH to remote computer and return the prompt.
		"""
		try:
			if not props["localhost"]:
				s = pxssh.pxssh()
				if not s.login (props["computerip"], props["username"], props["password"]):
					self.logger.error ("SSH session failed to login to '{}'.  Check your IP, username and password and make sure you can SSH to that computer from the Indigo server.".format(props['credentials'][0]))
					return False
					
				#rootprompt = re.compile('.*[$#]')	
				#i = self.expect(["(?i)are you sure you want to continue connecting", "(?i)(?:password)|(?:passphrase for key)", "(?i)permission denied", "(?i)terminal type", "(?i)connection closed by remote host"], timeout=20)
				#indigo.server.log(u'{}'.format(i))
				s.sendline('sudo -s')
				s.sendline(props["password"])
				
				return s
			
			else:
				self.logger.error ("{} the Indigo computer is not currently supported".format(activity))
		
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
			
		return None	
Exemplo n.º 13
0
    def list_call_flows(self,
                        filter="",
                        valuesDict=None,
                        typeId="",
                        targetId=0):
        """
		Build a custom list based on the information in the filter field.
		"""

        try:
            listData = [("default", "No data")]
            if not 'server' in valuesDict: return listData
            if valuesDict['server'] == '': return listData

            server = indigo.devices[int(valuesDict['server'])]
            result = self.invoke_api(server, 'daynight', '', '', '')
            if result:
                listData = []
                for r in result:
                    listData.append((r['ext'], r['dest']))

        except Exception as e:
            self.logger.error(ex.stack_trace(e))

        return listData
Exemplo n.º 14
0
    def update_address(self, dev):
        try:
            if dev.deviceTypeId == 'Server':
                props = dev.pluginProps
                props['address'] = props['ipaddress']
                dev.replacePluginPropsOnServer(props)

            if dev.deviceTypeId == 'CallFlow':
                server = int(dev.pluginProps["server"])
                if not server in indigo.devices:
                    self.logger.error(
                        u"PBX Server {} is not in the Indigo device list, was it removed?  {} action cannot complete"
                        .format(server, dev.name))
                    return
                server = indigo.devices[server]

                props = dev.pluginProps
                props['address'] = server.name
                dev.replacePluginPropsOnServer(props)

            if dev.deviceTypeId == 'Extension':
                server = int(dev.pluginProps["server"])
                if not server in indigo.devices:
                    self.logger.error(
                        u"PBX Server {} is not in the Indigo device list, was it removed?  {} action cannot complete"
                        .format(server, dev.name))
                    return
                server = indigo.devices[server]

                props = dev.pluginProps

                if props['method'] == 'ext':
                    props['address'] = u'Ext {} on {}'.format(
                        props['extension'], server.name)

                elif props['method'] == 'status':
                    props['address'] = self.update_address_status(dev)

                elif props['method'] == 'fwd':
                    status = self.update_address_status(dev)
                    if 'CF ' in status:
                        status = u'CF to {}'.format(
                            dev.states['cfunconditionalNumber'])
                    elif 'CFU ' in status:
                        status = u'CFU to {}'.format(
                            dev.states['cfunavailableNumber'])
                    elif 'CFB ' in status:
                        status = u'CFB to {}'.format(
                            dev.states['cfbusyNumber'])

                    props['address'] = status

                dev.replacePluginPropsOnServer(props)

                self.update_state(dev)

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 15
0
	def sample_computer_data (self, dev):
		try:
			keyValueList = []
			
			profile = self.sample_computer_profile(dev)
			#indigo.server.log(unicode(profile))
			
			keyValueList.append({'key':'name', 'value':profile['Computer Name']})
			
			keyValueList.append({'key':'model', 'value':u'{} ({})'.format(profile['Model Name'], profile['Model ID'])})
			keyValueList.append({'key':'cpu_model', 'value':profile['CPU']})
			keyValueList.append({'key':'cpu_speed', 'value':profile['CPU Speed']})
			keyValueList.append({'key':'serial', 'value':profile['Serial Number']})
			
			keyValueList.append({'key':'cpu', 'value':profile['CPU Utilization']})
			keyValueList.append({'key':'cpu_count', 'value':profile['Processors']})	
			keyValueList.append({'key':'cpu_cores', 'value':profile['Cores']})
			
			mem = psutil.virtual_memory()
			keyValueList.append({'key':'memory', 'value':mem.total  / 1024 / 1024})
			keyValueList.append({'key':'memory_available', 'value':mem.available / 1024 / 1024})
			keyValueList.append({'key':'memory_percent', 'value':profile['Memory Utilization']})
			
			
			disk = psutil.disk_usage('/')
			keyValueList.append({'key':'disk', 'value':disk.total  / 1024 / 1024})
			keyValueList.append({'key':'disk_available', 'value':disk.free  / 1024 / 1024})
			keyValueList.append({'key':'disk_percent', 'value':disk.percent})
			
			# Not supported in the 1.x that comes with macOS, need to wait until a newer version is out
			#temps = psutil.sensors_temperatures()
			#fans = psutil.sensors_fans()
			#batt = psutil.sensors_battery()
			
			boot = datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")
			keyValueList.append({'key':'last_boot', 'value':boot})
			
			cmd = [ 'sw_vers', '-productVersion']
			ver = subprocess.Popen( cmd, stdout=subprocess.PIPE ).communicate()[0]
			ver = ver.replace("\n","")
			keyValueList.append({'key':'macOS', 'value':ver})
			
			keyValueList.append({'key':'last_sample', 'value':datetime.now().strftime("%Y-%m-%d %H:%M:%S")})
			
			#/usr/sbin/system_profiler SPHardwareDataType | fgrep 'Serial' | awk '{print $NF}'
			
			if dev.pluginProps['state'] == 'cpu': keyValueList.append({'key':'sensorValue', 'value':profile['CPU Utilization'], 'uiValue': u'{}%'.format(profile['CPU Utilization'])})
			if dev.pluginProps['state'] == 'memory_percent': keyValueList.append({'key':'sensorValue', 'value':profile['Memory Utilization'], 'uiValue': u'{}%'.format(profile['Memory Utilization'])})
				
			props = dev.pluginProps
			props['address'] = u'CPU: {}% | Mem: {}%'.format(profile['CPU Utilization'], profile['Memory Utilization'])
			dev.replacePluginPropsOnServer (props)
			
			if keyValueList: dev.updateStatesOnServer(keyValueList)
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
Exemplo n.º 16
0
	def format_list_column_entry_tabs (self, columndefs, columndata):
		"""
		Return a list item formatted to comply with the column definitions.
		
		Arguments:
			columndefs:				(list) maximum tabs (4 spaces) per column
			columndata:				(list) the data to enter into the columns
			
		Returns:
			list representative of the column configuration
		"""
		
		try:
			colidx = 0
			output = ""
			
			for c in columndata	:
				tabs = columndefs[colidx]
				if len(str(c)) > (tabs * 4):
					# Shorten the value so it fits, it should be tabs * 4 - 1 to leave a space between columns
					x = (tabs * 4) - 1 # Shorten by one extra for space between columns
					x = x - 3 # Shorted by 3 more so we can add '...' to let the user know its been truncated
					c = c[0:x] + "..."

				if len(str(c)) > 23:
					tabs = tabs - 6
				elif len(str(c)) > 19:
					tabs = tabs - 5
				elif len(str(c)) > 15:
					tabs = tabs - 4
				elif len(str(c)) > 11:
					tabs = tabs - 3
				elif len(str(c)) > 7:
					tabs = tabs - 2
				elif len(str(c)) > 3:
					tabs = tabs - 1
					
				if tabs < 1: tabs = 1 # Failsafe in case we got messed up
				
				tabstring = ""

				for i in range (0, tabs):
					tabstring += "\t"

				column = u"{}{}".format(c, tabstring)
				output += column

				colidx = colidx + 1

			return output
		
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
			
Exemplo n.º 17
0
	def commander_field_changed (self, valuesDict, typeId, devId = ''):
		"""
		Triggers form actions.
		"""
		
		try:
			errorsDict = indigo.Dict()
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))	
			
		return (valuesDict, errorsDict)					
Exemplo n.º 18
0
    def device_field_changed(self, valuesDict, typeId, devId):
        """
		Callback method invoked on device forms, primary method.
		"""

        try:
            errorsDict = indigo.Dict()

        except Exception as e:
            self.logger.error(ex.stack_trace(e))

        return (valuesDict, errorsDict)
Exemplo n.º 19
0
    def get_server_extensions(self, dev):
        try:
            method = 'userman'
            params = {}

            extensions = self.invoke_api(dev, method)
            for e in extensions:
                for field, info in e.iteritems():
                    indigo.server.log(unicode(u"{}: {}".format(field, info)))

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 20
0
	def shutdown_computer (self, dev, method, props = {}):
		try:
			if not props: props = dev.pluginProps
			
			s = self.ssh (props, "Shutting down")
			if s:		
				s.sendline ('sudo shutdown -h now')
				
				s.prompt() 
				s.logout()
				
		except Exception as e:
			self.logger.error (ex.stack_trace(e))	
Exemplo n.º 21
0
    def clear_form_records(self, valuesDict):
        """
		Empty the current record name in the JSON records and start it fresh.
		"""

        try:
            self.set_form_records(valuesDict)
            self.records = []
            self.apply_form_records(valuesDict)

        except Exception as e:
            self.logger.error(ex.stack_trace(e))

        return valuesDict
Exemplo n.º 22
0
	def clear_form_records (self, valuesDict):
		"""
		Empty the current record name in the JSON records and start it fresh.
		"""
		
		try:
			self.set_form_records (valuesDict)
			self.records = []
			self.apply_form_records (valuesDict)
		
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
			
		return valuesDict
Exemplo n.º 23
0
	def get_saved_credential (self, name = '', ip = ''):
		try:
			credentials = self.pluginPrefs['credentials']
			
			for c in credentials:
				item = base64.b64decode(c).split("||")
				if not name == '' and item[0] == name:
					return item
				elif not ip == '' and item[1] == ip:
					return item	
					
			return False
					
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
Exemplo n.º 24
0
	def sleepComputer (self, dev, method, props = {}):
		#cmd = " -e 'sleep'"
		#cmd = self.encapsulateCmd (dev, cmd, "Finder", "Finder", props)
		#result = self.runOsa (cmd)
		
		try:
			s = self.ssh (props, "Sleeping")
			if s:		
				s.sendline ('pmset sleepnow')
				
				s.prompt() 
				s.logout()
				
		except Exception as e:
			self.logger.error (ex.stack_trace(e))	
Exemplo n.º 25
0
	def validateDeviceConfigUi (self, valuesDict, typeId, devId):
		try:
			errorDict = indigo.Dict()
			dev = indigo.devices[devId]
		
			# While we are here add this device to polling if that is enabled
			if typeId == 'maccmd' or typeId == 'epsmc':
				self.configurePolling (dev, valuesDict)
				self.configurePollingMusic (dev, valuesDict)
				#indigo.server.log(unicode(self.itunespollinglist))
		
		except Exception as e:
			self.logger.error (ex.stack_trace(e))	
			
		return (True, valuesDict, errorDict)	
Exemplo n.º 26
0
	def getActionConfigUiValues(self, valuesDict, typeId, devId):
		"""
		Indigo function called prior to the form loading in case we need to do pre-calculations.
		"""
		
		try:
			errorsDict = indigo.Dict()
			
			# Set new device defaults
			if not 'credentials' in valuesDict: valuesDict['credentials'] = 'manual'
			if not 'onCommand' in valuesDict: valuesDict['onCommand'] = 'runapp'
						
		except Exception as e:
			self.logger.error (ex.stack_trace(e))	
			
		return (valuesDict, errorsDict)					
Exemplo n.º 27
0
    def device_control_flow(self, action, dev):
        try:
            keyValueList = []

            dev = indigo.devices[action.deviceId]
            server = int(dev.pluginProps["server"])
            if not server in indigo.devices:
                self.logger.error(
                    u"PBX Server {} is not in the Indigo device list, was it removed?  {} action cannot complete"
                    .format(server, dev.name))
                return

            server = indigo.devices[server]
            params = {}

            forceState = ''

            if action.deviceAction == indigo.kDimmerRelayAction.Toggle:
                if dev.onState:
                    forceState = 'off'
                else:
                    forceState = 'on'

            if action.deviceAction == indigo.kDimmerRelayAction.TurnOn or forceState == 'on':
                params["state"] = 'NIGHT'
                keyValueList.append({'key': 'onOffState', 'value': True})
            elif action.deviceAction == indigo.kDimmerRelayAction.TurnOff or forceState == 'off':
                params["state"] = 'DAY'
                keyValueList.append({'key': 'onOffState', 'value': False})
            elif unicode(action.deviceAction) == u'RequestStatus':
                self.update_call_flow_status(dev)
                return
            else:
                indigo.server.error(u'Unknown Call Flow action {}'.format(
                    action.deviceAction))
                return

            result = self.invoke_api(server, 'daynight',
                                     dev.pluginProps['callflow'],
                                     json.dumps(params), '')

            self.update_call_flow_status(dev)

            if keyValueList: dev.updateStatesOnServer(keyValueList)

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 28
0
	def actionControlDevice(self, action, dev):
		try:
			if dev.deviceTypeId == 'maccmd':
				if action.deviceAction == indigo.kDimmerRelayAction.TurnOn:
					self.command_turn_on(dev)
				
				elif action.deviceAction == indigo.kDimmerRelayAction.TurnOff:
					self.command_turn_off(dev)	
				
				elif action.deviceAction == indigo.kDimmerRelayAction.Toggle:
					if dev.onState:
						self.command_turn_off(dev)	
					else:
						self.command_turn_on(dev)

		except Exception as e:
			self.logger.error (ex.stack_trace(e))	
Exemplo n.º 29
0
	def update_computer (self, dev, method, props = {}):
		try:
			if not props: props = dev.pluginProps
			
			s = self.ssh (props, "Update")
			if s:		
				s.sendline ('sudo softwareupdate -iaR')
				
				try:
					s.prompt(timeout=1200) 
					s.logout()
				except Exception as ex:
					pass # if we rebooted then it may time out	
				
				
		except Exception as e:
			self.logger.error (ex.stack_trace(e))				
Exemplo n.º 30
0
	def list_computer_states (self, filter="", valuesDict=None, typeId="", targetId=0): 
		"""
		Return the list of computer states.
		"""
		
		try:
			listData = []
			
			listData.append (('cpu', "CPU Usage"))
			listData.append (('memory_available', "Memory Available"))
			listData.append (('memory_percent', "Memory Used %"))
			listData.append (('disk_available', "Disk Available"))
			listData.append (('disk_percent', "Disk Used %"))
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
			
		return listData				
Exemplo n.º 31
0
	def _create_hash_key (self, keyString):
		"""
		Create a 256K hash key from the provided string.
		
		Aguments:
			keyString:			(str) string to use for unique hash value
			
		Returns:
			string				value of hashed keyString
		"""
			
		try:
			hashKey = hashlib.sha256(keyString.encode('ascii', 'ignore')).digest().encode("hex")  # [0:16]
			return hashKey	
				
		except Exception as e:
			self.logger.error (ex.stack_trace(e))	
			return ""
Exemplo n.º 32
0
	def create_unique_key (self):
		"""
		Create a unique identifier (key) using the date and time to the millisecond plus a random number to ensure uniqueness.
		
		Returns:
			string				value of hashed keyString
		"""
		
		try:
			d = indigo.server.getTime()
			key = self._create_hash_key (d.strftime("%Y-%m-%d %H:%M:%S %f") + str(randint(1000, 1000001)))
			key = key[0:16]
			return key
		
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
			
		return ""
Exemplo n.º 33
0
    def _create_hash_key(self, keyString):
        """
		Create a 256K hash key from the provided string.
		
		Aguments:
			keyString:			(str) string to use for unique hash value
			
		Returns:
			string				value of hashed keyString
		"""

        try:
            hashKey = hashlib.sha256(keyString.encode(
                'ascii', 'ignore')).digest().encode("hex")  # [0:16]
            return hashKey

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
            return ""
Exemplo n.º 34
0
    def action_cf(self, action):
        try:
            method = 'callforward'

            dev = indigo.devices[action.deviceId]
            server = int(dev.pluginProps["server"])
            if not server in indigo.devices:
                self.logger.error(
                    u"PBX Server {} is not in the Indigo device list, was it removed?  {} action cannot complete"
                    .format(server, dev.name))
                return

            server = indigo.devices[server]
            params = {}

            if action.pluginTypeId == 'callForwarding':
                if action.props['cfenabled']:
                    params['CF'] = int(action.props['cfnumber'])
                if action.props['cfuenabled']:
                    params['CFU'] = int(action.props['cfunumber'])
                if action.props['cfuenabled']:
                    params['CFB'] = int(action.props['cfbnumber'])
            elif action.pluginTypeId == 'cfDisableAll':
                params['CF'] = False
                params['CFB'] = False
                params['CFU'] = False
            elif action.pluginTypeId == 'cfDisableUC':
                params['CF'] = False
            elif action.pluginTypeId == 'cfDisableBusy':
                params['CFB'] = False
            elif action.pluginTypeId == 'cfDisableUA':
                params['CFU'] = False

            #indigo.server.log(unicode(json.dumps(params)))

            result = self.invoke_api(server, method,
                                     dev.pluginProps["extension"],
                                     json.dumps(params))

            self.update_extension_status(dev)

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 35
0
	def __init__(self, plugin):
		"""
		Start the factory with references back to the base plugin.
		
		Arguments:
		plugin: 			Indigo plugin
		"""
	
		try:
			if plugin is None: return # pre-loading before init
			
			self.logger = logging.getLogger ("Plugin.{}".format(self.__class__.__name__.replace("_","")))
			
			self.plugin = plugin	# References the Indigo plugin
		
			self.logger.debug ("{} {} loaded".format(__modname__, __version__))
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
Exemplo n.º 36
0
    def update_address_status(self, dev):
        """
		Determine the phone status and return it.
		"""

        try:
            status = ''

            if dev.states['dnd.enabled']: status += 'DND '
            if dev.states['cfunconditional.enabled']: status += 'CF '
            if dev.states['cfbusy.enabled']: status += 'CFB '
            if dev.states['cfunavailable.enabled']: status += 'CFU '

            if status == '': status = 'Ready'

            return status

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 37
0
	def action_list_changed (self, valuesDict, typeId):	
		"""
		Drop down list was changed, enable/disable edit fields.
		"""
		
		try:
			errorsDict = indigo.Dict()
			if not 'action' in valuesDict: return (valuesDict, errorsDict)
			
			if valuesDict['action'] == 'delete':
				valuesDict['showfields'] = False
			elif valuesDict['action'] == 'add':
				valuesDict['showfields'] = True
			else:
				valuesDict['showfields'] = False
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))	
			
		return (valuesDict, errorsDict)	
Exemplo n.º 38
0
    def create_unique_key(self):
        """
		Create a unique identifier (key) using the date and time to the millisecond plus a random number to ensure uniqueness.
		
		Returns:
			string				value of hashed keyString
		"""

        try:
            d = indigo.server.getTime()
            key = self._create_hash_key(
                d.strftime("%Y-%m-%d %H:%M:%S %f") +
                str(randint(1000, 1000001)))
            key = key[0:16]
            return key

        except Exception as e:
            self.logger.error(ex.stack_trace(e))

        return ""
Exemplo n.º 39
0
	def set_form_records (self, valuesDict):
		"""
		Look for the presense of the JSON_FIELD in the form data and retrieve it or create a blank dictionary.  This can be called
		from a child process to force the record list into the variable so it can be iterated.
		"""
		
		try:
			if not JSON_FIELD in valuesDict:
				allrecords = {}
				valuesDict[JSON_FIELD] = json.dumps(allrecords)
			
			allrecords = json.loads(valuesDict[JSON_FIELD])
			
			if not self.recordName in allrecords:
				allrecords[self.recordName] = []
			
			self.records = allrecords[self.recordName]
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
Exemplo n.º 40
0
    def set_form_records(self, valuesDict):
        """
		Look for the presense of the JSON_FIELD in the form data and retrieve it or create a blank dictionary.  This can be called
		from a child process to force the record list into the variable so it can be iterated.
		"""

        try:
            if not JSON_FIELD in valuesDict:
                allrecords = {}
                valuesDict[JSON_FIELD] = json.dumps(allrecords)

            allrecords = json.loads(valuesDict[JSON_FIELD])

            if not self.recordName in allrecords:
                allrecords[self.recordName] = []

            self.records = allrecords[self.recordName]

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 41
0
    def timer_update_extension_status(self, serverId):
        try:
            delay = int(indigo.devices[serverId].pluginProps['frequency'])

            while True:
                for dev in indigo.devices.iter(self.pluginId):
                    if dev.deviceTypeId == 'Extension' and dev.pluginProps[
                            'server'] == str(serverId):
                        self.update_extension_status(dev)

                    elif dev.deviceTypeId == 'CallFlow':
                        self.update_call_flow_status(dev)

                time.sleep(delay)
                #self.timer_update_extension_status()

        except self.StopThread:
            pass

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 42
0
    def get_status(self, dev, method):
        try:
            if dev.deviceTypeId == 'Server':
                result = self.invoke_api(dev, method)

            elif dev.deviceTypeId == 'Extension':
                server = int(dev.pluginProps["server"])
                if not server in indigo.devices:
                    self.logger.error(
                        u"PBX Server {} is not in the Indigo device list, was it removed?  {} action cannot complete"
                        .format(server, dev.name))
                    return

                server = indigo.devices[server]
                result = self.invoke_api(server, method,
                                         dev.pluginProps["extension"])

                return result

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 43
0
	def list_commands (self, filter="", valuesDict=None, typeId="", targetId=0): 
		"""
		Return the list of all commands.
		"""
		
		try:
			listData = []
			listData.append (('none', '- Do Nothing -'))
			listData.append (('runapp', 'Run Application'))
			listData.append (('quitapp', 'Quit Application'))
			listData.append (('showmessage', 'Display Notification Message'))
			listData.append (('screensaver', 'Start Screensaver'))
			listData.append (('restart', 'Restart Computer'))
			listData.append (('sleep', 'Sleep Computer'))
			listData.append (('shutdown', 'Turn Off Computer'))
			listData.append (('update', 'Install Software Updates'))
			listData.append (('builtin', 'iTunes'))
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
			
		return listData				
Exemplo n.º 44
0
	def list_credentials (self, filter="", valuesDict=None, typeId="", targetId=0): 
		"""
		Build a custom list of the saved credentials.
		"""
		
		try:
			listData = []
			if filter == 'device': listData = [('manual', 'Manual Login')]
			credentials = self.pluginPrefs['credentials']
			if not credentials: return listData
			
			for c in credentials:
				keyString = base64.b64decode(c)
				#indigo.server.log(u'{}'.format(keyString))
				item = keyString.split("||")
				
				if item[0] != '': listData.append ((item[0], u'{} ({})'.format(item[0], item[1])))
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
			
		return listData		
Exemplo n.º 45
0
	def save_credential (self, name, ip, user, password):
		try:
			credentials = self.pluginPrefs['credentials']
			newcredentials = []
			
			for c in credentials:
				item = base64.b64decode(c).split("||")
				if not name == '' and item[0] == name:
					return False
					
				newcredentials.append(c)

			item = u'{}||{}||{}||{}'.format(name, ip, user, password)
			newcredentials.append(base64.b64encode(bytes(item)))				
					
			self.pluginPrefs['credentials'] = newcredentials
			
			return True
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
			return False
Exemplo n.º 46
0
    def update_call_flow_status(self, dev):
        try:
            keyValueList = []

            server = int(dev.pluginProps["server"])
            if not server in indigo.devices:
                self.logger.error(
                    u"PBX Server {} is not in the Indigo device list, was it removed?  {} action cannot complete"
                    .format(server, dev.name))
                return

            result = self.invoke_api(indigo.devices[server], 'daynight',
                                     dev.pluginProps['callflow'], '', '')
            if result:
                #indigo.server.log(unicode(result))

                if result['state'] == 'DAY':
                    keyValueList.append({
                        'key': 'onOffState',
                        'value': False,
                        'uiValue': 'DAY'
                    })
                    dev.updateStateImageOnServer(
                        indigo.kStateImageSel.TimerOff)
                else:
                    keyValueList.append({
                        'key': 'onOffState',
                        'value': True,
                        'uiValue': 'NIGHT'
                    })
                    dev.updateStateImageOnServer(indigo.kStateImageSel.TimerOn)

            if keyValueList: dev.updateStatesOnServer(keyValueList)

            self.update_address(dev)

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 47
0
	def list_computer_info (self, filter="", valuesDict=None, typeId="", targetId=0): 
		"""
		Return the list of computer stats.
		"""
		
		try:
			listData = []
			if targetId == 0: return listData
			
			dev = indigo.devices[targetId]
			
			listData.append (('name', 'Name:\t\t\t\t{}'.format(dev.states['name'])))
			listData.append (('macOS', 'macOS Version:\t\t{}'.format(dev.states['macOS'])))
			listData.append (('model', 'Model:\t\t\t\t{}'.format(dev.states['model'])))
			listData.append (('cpu_model', 'CPU Info:\t\t\t{} {}'.format(dev.states['cpu_model'], dev.states['cpu_speed'])))
			#listData.append (('serial', 'Serial Number:\t\t{}'.format(dev.states['serial'])))
			listData.append (('serial', 'Serial Number:\t\t{}'.format('XXXXXXXXXX')))
						
			listData.append (('cpu', 'CPU Utilization:\t\t{}%'.format(dev.states['cpu'])))
			listData.append (('cpu_count', 'CPU Count:\t\t\t{}'.format(dev.states['cpu_count'])))
			listData.append (('cpu_cores', 'CPU Cores:\t\t\t{}'.format(dev.states['cpu_cores'])))
			
			listData.append (('memory', 'Memory:\t\t\t\t{} MB'.format("{:,}".format(dev.states['memory']))))
			listData.append (('memory_available', 'Memory Available:\t\t{} MB'.format("{:,}".format(dev.states['memory_available']))))
			listData.append (('memory_percent', 'Memory Used:\t\t{}%'.format(dev.states['memory_percent'])))
			
			listData.append (('disk', 'Pri Drive Capacity:\t\t{} MB'.format("{:,}".format(dev.states['disk']))))
			listData.append (('disk_available', 'Pri Drive Available:\t{} MB'.format("{:,}".format(dev.states['disk_available']))))
			listData.append (('disk_percent', 'Pri Drive Used:\t\t{}%'.format(dev.states['disk_percent'])))
			
			listData.append (('last_boot', 'Last Reboot:\t\t\t{}'.format(dev.states['last_boot'])))
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))
			
		return listData	
Exemplo n.º 48
0
	def update_saved_credential (self, name, newname, ip, user, password):
		try:
			credentials = self.pluginPrefs['credentials']
			newcredentials = []
			
			for c in credentials:
				item = base64.b64decode(c).split("||")
				if item[0] == newname and name != newname:
					return False
			
			for c in credentials:
				item = base64.b64decode(c).split("||")
				if (not name == '' and item[0] == name) or (not ip == '' and item[1] == ip):
					item = u'{}||{}||{}||{}'.format(newname, ip, user, password)
					newcredentials.append(base64.b64encode(bytes(item)))
				else:
					newcredentials.append(c)
					
			self.pluginPrefs['credentials'] = newcredentials
			
			return True
			
		except Exception as e:
			self.logger.error (ex.stack_trace(e))	
Exemplo n.º 49
0
	def command_turn_off (self, dev, props = {}):
		try:
			self._command (dev, 'off', props)

		except Exception as e:
			self.logger.error (ex.stack_trace(e))			
Exemplo n.º 50
0
	def find_applescript (self):
		try:				
			self.logger.info ('### PLEASE WAIT WHILE YOUR DATABASE IS EXAMINED FOR EMBEDDED APPLESCRIPT, THIS MAY TAKE A MOMENT ###')
			
			# Make copy of the DB
			from shutil import copyfile
			
			dbdir = '{}/Databases/'.format(indigo.server.getInstallFolderPath())
			src = u'{}{}.indiDb'.format(dbdir, indigo.server.getDbName())
			dst = u'{}{}-mccopy.indiDb'.format(dbdir, indigo.server.getDbName())
			
			copyfile(src, dst)
			
			# Parse the DB
			output = '\nThe following items have an embedded AppleScript:\n\n'
			dbdir = '{}/Databases/'.format(indigo.server.getInstallFolderPath())
			xml = cElementTree.iterparse(u'{}{}-mccopy.indiDb'.format(dbdir, indigo.server.getDbName()))
			for event, elem in xml:
				type = ''
				folderId = ''
				id = ''
				name = ''
				script = ''
				isas = False
			
				if elem.tag == "ActionGroup":
					type = 'Action Group'

					for ActionGroup in elem:
						if ActionGroup.tag == 'FolderID': folderId = ActionGroup.text
						if ActionGroup.tag == 'Name': name = ActionGroup.text
						if ActionGroup.tag == 'ID': id = ActionGroup.text
					
						if ActionGroup.tag == 'ActionSteps':
							for ActionSteps in ActionGroup:
								if ActionSteps.tag == 'Action':
									for Action in ActionSteps:
										if Action.tag == 'AppleScriptSCPT':
											isas = True
										if isas and Action.tag == 'ScriptSource':
											script = Action.text
										
				if elem.tag == "Trigger":
					type = 'Trigger'
				
					for Trigger in elem:
						if Trigger.tag == 'FolderID': folderId = Trigger.text
						if Trigger.tag == 'Name': name = Trigger.text
						if Trigger.tag == 'ID': id = Trigger.text	
					
						if Trigger.tag == 'ActionGroup':			
							for ActionGroup in Trigger:
								if ActionGroup.tag == 'FolderID': folderId = ActionGroup.text
								if ActionGroup.tag == 'Name': name = ActionGroup.text
								if ActionGroup.tag == 'ID': id = ActionGroup.text
					
								if ActionGroup.tag == 'ActionSteps':
									for ActionSteps in ActionGroup:
										if ActionSteps.tag == 'Action':
											for Action in ActionSteps:
												if Action.tag == 'AppleScriptSCPT':
													isas = True
												if isas and Action.tag == 'ScriptSource':
													script = Action.text
												
				if elem.tag == "TDTrigger":
					type = 'Schedule'
				
					for Schedule in elem:
						if Schedule.tag == 'FolderID': folderId = Schedule.text
						if Schedule.tag == 'Name': name = Schedule.text
						if Schedule.tag == 'ID': id = Schedule.text	
					
						if Schedule.tag == 'ActionGroup':			
							for ActionGroup in Schedule:
								if ActionGroup.tag == 'FolderID': folderId = ActionGroup.text
								if ActionGroup.tag == 'Name': name = ActionGroup.text
								if ActionGroup.tag == 'ID': id = ActionGroup.text
					
								if ActionGroup.tag == 'ActionSteps':
									for ActionSteps in ActionGroup:
										if ActionSteps.tag == 'Action':
											for Action in ActionSteps:
												if Action.tag == 'AppleScriptSCPT':
													isas = True
												if isas and Action.tag == 'ScriptSource':
													script = Action.text												
						
				if isas and name != '':
					#item = base64.b64decode(script)
			
					#indigo.server.log(u'{}: {} - \n{}'.format(type, name, script))
					#indigo.server.log(u'{}: {}'.format(type, name))
					output += u'{}: {}\n'.format(type, name)
				
					#break
			
			self.logger.info(u'{}'.format(output))
					
			# Remove our DB copy
			os.remove(dst)
					
		except Exception as e:
			self.logger.error (ex.stack_trace(e))			
Exemplo n.º 51
0
    def update_extension_status(self, dev):
        try:
            keyValueList = []

            result = self.get_status(dev, 'callforward')
            if result:
                #indigo.server.log(unicode(result))

                if not result['CF']:
                    keyValueList.append({
                        'key': 'cfunconditional',
                        'value': 'disabled'
                    })
                    keyValueList.append({
                        'key': 'cfunconditionalNumber',
                        'value': ''
                    })
                else:
                    keyValueList.append({
                        'key': 'cfunconditional',
                        'value': 'enabled'
                    })
                    keyValueList.append({
                        'key': 'cfunconditionalNumber',
                        'value': result['CF']
                    })

                if not result['CFB']:
                    keyValueList.append({'key': 'cfbusy', 'value': 'disabled'})
                    keyValueList.append({'key': 'cfbusyNumber', 'value': ''})
                else:
                    keyValueList.append({'key': 'cfbusy', 'value': 'enabled'})
                    keyValueList.append({
                        'key': 'cfbusyNumber',
                        'value': result['CFB']
                    })

                if not result['CFU']:
                    keyValueList.append({
                        'key': 'cfunavailable',
                        'value': 'disabled'
                    })
                    keyValueList.append({
                        'key': 'cfunavailableNumber',
                        'value': ''
                    })
                else:
                    keyValueList.append({
                        'key': 'cfunavailable',
                        'value': 'enabled'
                    })
                    keyValueList.append({
                        'key': 'cfunavailableNumber',
                        'value': result['CFU']
                    })

            result = self.get_status(dev, 'donotdisturb')
            if result:
                #indigo.server.log(unicode(result))

                if result["status"] == "enabled" or result[
                        "status"] == "YES":  # YES when this is turned on via a phone
                    keyValueList.append({'key': 'dnd', 'value': 'enabled'})
                else:
                    keyValueList.append({'key': 'dnd', 'value': 'disabled'})

            result = self.get_status(dev, 'callwaiting')
            if result:
                #indigo.server.log(unicode(result))

                if result[0] == "ENABLED":
                    keyValueList.append({
                        'key': 'callwaiting',
                        'value': 'enabled'
                    })
                else:
                    keyValueList.append({
                        'key': 'callwaiting',
                        'value': 'disabled'
                    })

            if keyValueList: dev.updateStatesOnServer(keyValueList)

            self.update_address(dev)

        except Exception as e:
            self.logger.error(ex.stack_trace(e))
Exemplo n.º 52
0
	def _command (self, dev, method = 'on', props = {}):
		try:
			if not props: props = dev.pluginProps
			onState = True
			if method == 'off': onState = False
		
			# We aren't writing props back, so fill in with saved credentials to pass around
			if 'credentials' in props and props['credentials'] != 'manual':
				item = self.get_saved_credential (props['credentials'])
				if item:
					props['name'] = item[0]
					props['computerip'] = item[1]
					props['username'] = item[2]
					props['password'] = item[3]
					
			command = props["{}Command".format(method)]
								
			if command == "none":
				return
				
			elif command == "runapp":
				self.openApp (dev, method, props)
				if not dev is None: 
					dev.updateStateOnServer("onOffState", onState)
					self.configurePolling (dev, props)
					
			elif command == "quitapp":
				self.quitApp (dev, method, props)
				if not dev is None: 
					dev.updateStateOnServer("onOffState", onState)
					self.configurePolling (dev, props)
					
			elif command == "sleep":
				self.sleepComputer (dev, method, props)
				if not dev is None: 
					dev.updateStateOnServer("onOffState", onState)
					self.configurePolling (dev, props)
					
			elif command == "restart":
				self.restart_computer (dev, method, props)
				if not dev is None: 
					dev.updateStateOnServer("onOffState", onState)
					self.configurePolling (dev, props)
					
			elif command == "update":
				thread.start_new_thread (self.update_computer, (dev, method, props))
				
			elif command == "shutdown":
				self.shutdown_computer (dev, method, props)
				if not dev is None: 
					dev.updateStateOnServer("onOffState", onState)
					self.configurePolling (dev, props)			
					
			elif command == "screensaver":
				self.screenSaver (dev, method, props)
				if not dev is None: 
					dev.updateStateOnServer("onOffState", onState)
					self.configurePolling (dev, props)
					
			elif command == "showmessage":
				self.send_message (dev, method, props)
				
			elif command == "builtin":
				if props["{}Standard".format(method)] == "playpause":
					self.playPause (dev, method, props)
				if props["{}Standard".format(method)] == "playlist":
					self.playList (dev, method, props)
				if props["{}Standard".format(method)] == "startitunes":
					self.startStopiTunes (dev, "start", props)
				if props["{}Standard".format(method)] == "stopitunes":
					self.startStopiTunes (dev, "stop", props)
			
				# Since this was an ON command, turn it on
				if not dev is None:
					dev.updateStateOnServer("onOffState", onState)
					self.configurePolling (dev, props)

		except Exception as e:
			self.logger.error (ex.stack_trace(e))	
Exemplo n.º 53
0
    def invoke_api(self, dev, method, suffix='', body='', sub='users'):
        """
		Calls the FreePBX API and returns the results.
		
		Arguments:
			dev				(device) the server device where the IP address will be used
			method			(string) the core API method to call
			suffix			(string) generally the extension or list ID if we want granular details
			body			(json dict) to execute or change an API call
			sub				(string) sub folder under the method to direct to
		"""

        try:
            if not suffix == '': suffix = '/' + suffix

            if body == '':
                verb = 'GET'
            else:
                verb = 'PUT'

            #url = 'http://{}/admin/rest.php/rest/donotdisturb/users'.format(dev.pluginProps["ipaddress"])
            url = '{}/restapi/rest.php/rest/{}/{}{}'.format(
                dev.pluginProps["ipaddress"], method, sub, suffix)
            token = dev.pluginProps["token"]
            key = dev.pluginProps["key"]
            #body = ''

            d = indigo.server.getTime()
            keyString = d.strftime("%Y-%m-%d %H:%M:%S %f") + str(
                randint(1000, 1000001))
            nonce = hashlib.sha1(keyString.encode('ascii',
                                                  'ignore')).digest().encode(
                                                      "hex")  # [0:16]

            keyString = '{}:{}'.format(url, verb.lower())
            hash_a = hashlib.sha256(keyString.encode(
                'ascii', 'ignore')).digest().encode("hex")

            keyString = '{}:{}'.format(token, nonce)
            hash_b = hashlib.sha256(keyString.encode(
                'ascii', 'ignore')).digest().encode("hex")

            #keyString = '{}'.format(body.encode('base64'))
            keyString = base64.b64encode(bytes(body))
            #indigo.server.log(u"Body Encode64: {}".format(keyString))
            #hash_c = hashlib.sha256(keyString.encode('ascii', 'ignore')).digest().encode("hex")
            hash_c = hashlib.sha256(keyString).digest().encode("hex")
            #hash_d = hashlib.sha256(body.encode('ascii', 'ignore')).digest().encode("hex")
            #indigo.server.log(u"Body C: {}".format(hash_c))
            #indigo.server.log(u"Body D: {}".format(hash_d))
            #return

            keyString = '{}:{}:{}'.format(hash_a, hash_b, hash_c)
            data = hashlib.sha256(keyString.encode(
                'ascii', 'ignore')).digest().encode("hex")

            signature = hmac.new(
                str(key), str(data), hashlib.sha256).hexdigest(
                )  # Py 2.x, in Py 3.x we'll need to use bytes instead
            #signature = hmac.new(str(key), str(hash_c), hashlib.sha256).hexdigest()

            #indigo.server.log(u"Body C: {}".format(hash_c))
            #indigo.server.log(u"Token Key: {}".format(key))
            #indigo.server.log(u"Signature: {}".format(signature))
            #indigo.server.log(u"Nonce: {}".format(nonce))
            #indigo.server.log(u"Token: {}".format(token))

            if body == '':
                headers = {
                    'Signature': signature,
                    'Nonce': nonce,
                    'Token': token
                }
                ret = requests.get(u"http://{}".format(url), headers=headers)
            else:
                headers = {
                    'Signature': signature,
                    'Nonce': nonce,
                    'Token': token,
                    'Content-Type': 'application/json'
                }
                ret = requests.put(u"http://{}".format(url),
                                   data=body,
                                   headers=headers)
                #headers = {'Signature': signature, 'Nonce': nonce, 'Token': token}
                #ret = requests.put(u"http://{}".format(url), json=body, headers=headers)

            #ret = urlopen(Request(url, headers))
            #ret = requests.get(u"http://{}".format(url), headers=headers)
            #ret = requests.get(url, headers=headers, auth=HTTPBasicAuth('101','12345')) # change 12345 to the known 29 password
            #ret = requests.get(url, headers=headers, auth=HTTPDigestAuth('101','12345'))

            #indigo.server.log(url)

            if ret.status_code == 200:
                self.logger.debug(
                    u"Success on FreePBX RestAPI on {}: {}".format(
                        dev.name, ret.text))
                if not ret.text == '':
                    results = json.loads(ret.text)
                    return results
                else:
                    return {'status': 'no response, successful operation'}

                #for r in results:
                #	for extension, status in r.iteritems():
                #		extdata = extension.split("/")
                #		indigo.server.log(unicode(extdata))

            elif ret.status_code == 403:
                self.logger.error(
                    u"Access forbidden to FreePBX RestAPI on {}: {}".format(
                        dev.name, ret.text))
            elif ret.status_code == "404":
                self.logger.error(
                    u"Invalid response to FreePBX RestAPI on {}: {}".format(
                        dev.name, ret.text))
            else:
                self.logger.error(
                    u"Invalid response to FreePBX RestAPI on {}: {}".format(
                        dev.name, ret.text))

            #indigo.server.log(u"{}".format(ret))

        except Exception as e:
            self.logger.error(ex.stack_trace(e))

        return False