def scan(self, enable=True, filters=None): """ enable: enable/disable scanning filters: dict with scan filters, see bluez 'SetDiscoveryFilter' API: 'UUIDs': list with UUID strings 'Transport': string 'le', 'bredr' or 'auto' """ if enable: if filters and isinstance(filters, dict): # convert to Variants (for supported) if "UUIDs" in filters and not isinstance( filters["UUIDs"], Variant): filters["UUIDs"] = Variant("as", filters["UUIDs"]) if "Transport" in filters and not isinstance( filters["Transport"], Variant): filters["Transport"] = Variant("s", filters["Transport"]) bz.callBluezFunction(self._proxy.SetDiscoveryFilter, filters) try: bz.callBluezFunction(self._proxy.StartDiscovery) except bz.BluezInProgressError: pass else: try: bz.callBluezFunction(self._proxy.StopDiscovery) except bz.BluezFailedError: pass return bz.getBluezPropOrNone(self._proxy, "Discovering", fail_ret=False)
def activate_context(self, apn='internet', user='******', pwd='', protocol='ip'): self.dbg('activate_context', apn=apn, user=user, protocol=protocol) connmgr = self.dbus.interface(I_CONNMGR) ctx_path = connmgr.AddContext('internet') ctx = systembus_get(ctx_path) ctx.SetProperty('AccessPointName', Variant('s', apn)) ctx.SetProperty('Username', Variant('s', user)) ctx.SetProperty('Password', Variant('s', pwd)) ctx.SetProperty('Protocol', Variant('s', protocol)) # Activate can only be called after we are attached ctx.SetProperty('Active', Variant('b', True)) MainLoop.wait(lambda: ctx.GetProperties()['Active'] == True) self.log('context activated', path=ctx_path, apn=apn, user=user, properties=ctx.GetProperties()) return ctx_path
def detach(self): self.dbg('detach') connmgr = self.dbus.interface(I_CONNMGR) connmgr.SetProperty('RoamingAllowed', Variant('b', False)) connmgr.SetProperty('Powered', Variant('b', False)) connmgr.DeactivateAll() connmgr.ResetContexts() # Requires Powered=false
def attach(self, allow_roaming=False): self.dbg('attach') if self.is_attached(): self.detach() connmgr = self.dbus.interface(I_CONNMGR) connmgr.SetProperty('RoamingAllowed', Variant('b', allow_roaming)) connmgr.SetProperty('Powered', Variant('b', True))
def sendSms(self, id:str, nummer: str, message: str): proxy = self.__proxys[id] sms_api = proxy["org.freedesktop.ModemManager1.Modem.Messaging"] from pydbus import Variant sms_path = sms_api.Create( {"Number": Variant('s', nummer), "Text": Variant('s', message)}) proxy_sms = self.bus.get(".ModemManager1", sms_path) test_sms = proxy_sms["org.freedesktop.ModemManager1.Sms"] test_sms.Send() sms_api.Delete(sms_path)
def notify(self, title, body, actions, icon, replace=True): """ Create new or update existing notification. Args: track (`clay.gp.Track`): The track that you want to send the notification for actions (`list`): A list with the actions that you want the notification to react to. """ if not ENABLED: return actions_ = [] for action in actions: if action not in self._actions: logger.error("Can't find action: {}".format(action)) continue actions_.append(action) actions_.append(self._actions[action][0]) self._notify( title, body, replace, actions=actions_, hints={"action-icons": Variant('b', 1)}, # only display icons icon=icon if icon is not None else 'audio-headphones')
def t1_func(): for obj in [remote, remote_iface]: assert (obj.Foo == "foo") assert (obj.Foobar == "foobar") obj.Foobar = "barfoo" assert (obj.Foobar == "barfoo") obj.Foobar = "foobar" assert (obj.Foobar == "foobar") obj.Bar = "rab" remote.Foobar = "barfoo" try: remote.Get("net.lew21.pydbus.tests.publish_properties", "Bar") assert (False) except GLib.GError: pass try: remote.Set("net.lew21.pydbus.tests.publish_properties", "Foo", Variant("s", "haxor")) assert (False) except GLib.GError: pass assert (remote.GetAll("net.lew21.pydbus.tests.publish_properties") == { 'Foobar': 'barfoo', 'Foo': 'foo' }) remote.Quit()
def Write(self, value): """Sends a command to the Bluetooth device. Args: value(bytearray): the raw data to send to the GATT service. """ self._write_service.WriteValue(value, {'Type': Variant('s', 'command')})
def deactivate_context(self, ctx_id): self.dbg('deactivate_context', path=ctx_id) ctx = systembus_get(ctx_id) ctx.SetProperty('Active', Variant('b', False)) MainLoop.wait(lambda: ctx.GetProperties()['Active'] == False) self.dbg('deactivate_context active=false, removing', path=ctx_id) connmgr = self.dbus.interface(I_CONNMGR) connmgr.RemoveContext(ctx_id) self.log('context deactivated', path=ctx_id)
def set_bool(self, name, bool_val, iface=I_MODEM): # to make sure any pending signals are received before we send out more DBus requests MainLoop.poll() val = bool(bool_val) self.log('Setting', name, val) self.interface(iface).SetProperty(name, Variant('b', val)) MainLoop.wait(self.property_is, name, bool_val)
def create(label: str, alias: Optional[str] = None) -> str: properties = { 'org.freedesktop.Secret.Collection.Label': Variant.new_string(label) } # gnome-keyring can raise this, with "Only the 'default' alias is supported". with expect_error('g-dbus-error-quark', Gio.DBusError.NOT_SUPPORTED): path, prompt_path = proxy().CreateCollection( properties, alias or '') if path == '/': path = Prompt.complete(prompt_path) return Collection.by_path(path)
def get_variant(type_hint, value): """Return a variant data type. The type of a variant is specified with a type hint. Example: v1 = get_variant(Bool, True) v2 = get_variant(List[Int], [1,2,3]) :param type_hint: a type hint :param value: a value of the variant :return: an instance of Variant """ return Variant(get_dbus_type(type_hint), value)
def write(self, value, options=None, offset=0, length=0): if options is None: options = {} if self._proxy: if isinstance(value, bytes): v_obj = value v_enc = value else: if isinstance(value, self.fmt): v_obj = value v_enc = value.encode() else: v_obj = self.fmt(value) v_enc = v_obj.encode() if "length" in options: length = options["length"] del options["length"] if length: if not isinstance(length, int): raise TypeError("Length key in 'options' must be 'int'") if len(v_enc) > length: v_enc = v_enc[:length] else: raise ValueError("Length must be < encoded length") if offset > 0: if len(v_enc) <= offset: raise ValueError("Offset is bigger than encoded length") v_enc = v_enc[offset:] options["offset"] = Variant("q", offset) self.logger.debug("Write: {} {} {}".format(v_enc, str(v_obj), self.fmt.__name__)) self._proxy.WriteValue(v_enc, options) elif self.service.device and self.service.device.services_resolved: raise bzerror.BluezDoesNotExistError(f"{self.name} not found") else: raise bzerror.BluezFailedError( f"Failed to write {self.name}, database not resolved")
def read(self, options=None, raw=False, native=True, offset=0, length=0, timeout=30): if options is None: options = {} if "timeout" in options: to = options["timeout"] del options["timeout"] else: to = timeout if (offset and "offset" not in options): options["offset"] = Variant("q", offset) if self._proxy: try: v = bzerror.callBluezFunction(self._proxy.ReadValue, options, timeout=to) except bzerror.DBusTimeoutError: return None self.logger.debug("Read: {} {} {}".format(v, type(v), self.fmt.__name__)) if raw: return v else: try: v_dec = self.fmt.decode(v) except Exception as e: raise bzerror.BluezFormatDecodeError( "{}: {}, got: {}".format(self, str(e), str(v))) return v_dec elif self.service.device and self.service.device.services_resolved: raise bzerror.BluezDoesNotExistError(f"{self.name} not found") raise bzerror.BluezFailedError( f"Failed to read {self.name}, database not resolved")
def _get_interfaces_and_properties(self, path): object_ = self._objects[path] proxy = self.get(path) xml = proxy["org.freedesktop.DBus.Introspectable"].Introspect() node_info = Gio.DBusNodeInfo.new_for_xml(xml) interfaces = node_info.interfaces interfaces_and_properties = {} for iface in interfaces: interfaces_and_properties[iface.name] = {} for prop in iface.properties: try: value = getattr(object_, prop.name) variant = Variant(prop.signature, value) interfaces_and_properties[iface.name][prop.name] = variant except: pass return interfaces_and_properties
def Metadata(self): try: track = player.get_current_track() except AttributeError: track = None if track is None: return {} return { 'mpris:trackid': Variant('o', '/org/clay/' + str(track.store_id)), 'mpris:artUrl': Variant('s', track.artist_art_url), 'xesam:title': Variant('s', track.title), 'xesam:artist': Variant('s', track.artist.name), 'xesam:album': Variant('s', track.album_name), 'xesam:url': Variant('s', track.cached_url), }
root = bus.get("org.ofono", '/') print(root.Introspect()) modems = sorted(root.GetModems()) pprint.pprint(modems) pump() first_modem_path = modems[0][0] print('\n- first modem %r' % first_modem_path) modem = bus.get("org.ofono", first_modem_path) modem.PropertyChanged.connect(propchanged) print(modem.Introspect()) print(modem.GetProperties()) print('\n- set Powered = True') modem.SetProperty('Powered', Variant('b', True)) print('call returned') print('- pump dbus events') pump() pump() print('sleep 1') time.sleep(1) pump() print('- modem properties:') print(modem.GetProperties()) print('\n- set Powered = False') modem.SetProperty('Powered', Variant('b', False)) print('call returned')
def Metadata(self): song = self.app.current_song if type(song) == Song: logging.info("New song ID: " + str(song.id)) return { "mpris:trackid": Variant("o", "/org/tuijam/GM_" + str(song.id).replace("-", "_")), "mpris:artUrl": Variant("s", song.albumArtRef), "xesam:title": Variant("s", song.title), "xesam:artist": Variant("as", [song.artist]), "xesam:album": Variant("s", song.album), "xesam:url": Variant("s", song.stream_url), } elif type(song) == YTVideo: return { "mpris:trackid": Variant("o", "/org/tuijam/YT_" + str(song.id).replace("-", "_")), "mpris:artUrl": Variant("s", song.thumbnail), "xesam:title": Variant("s", song.title), "xesam:artist": Variant("as", [song.channel]), "xesam:album": Variant("s", ""), "xesam:url": Variant("s", song.stream_url), } else: return {}
def Metadata(self) -> Dict[str, Variant]: if self.current_playback["item"] is None: return { "mpris:trackid": Variant('o', "/org/mpris/MediaPlayer2/TrackList/NoTrack") } item = self.current_playback["item"] metadata = { "mpris:trackid": Variant('o', track_id_to_path(item["uri"])), "mpris:length": Variant('x', ms_to_us(item["duration_ms"])), "mpris:artUrl": Variant('s', item["album"]["images"][0]["url"]), "xesam:album": Variant('s', item["album"]["name"]), "xesam:albumArtist": Variant('as', [artist["name"] for artist in item["album"]["artists"]]), "xesam:artist": Variant('as', [artist["name"] for artist in item["artists"]]), "xesam:contentCreated": Variant('s', item["album"]["release_date"]), "xesam:discNumber": Variant('i', item["disc_number"]), "xesam:title": Variant('s', item["name"]), "xesam:trackNumber": Variant('i', item["track_number"]), "xesam:url": Variant('s', item["external_urls"]["spotify"]), } return metadata
def get_metadata(track): """ Returns the metadata for a specific track """ if not track: return { 'mpris:trackid': Variant('s', MPRIS2.notrack), 'mpris:artUrl': Variant('s', "file://"), 'mpris:title': Variant('s', 'None'), 'mpris:artist': Variant('s', 'None'), 'mpris:album': Variant('s', 'None'), 'mpris:url': Variant('s', 'https://') } else: return { 'mpris:trackid': Variant('s', track.queue_id), 'mpris:artUrl': Variant('s', track.artist_art_url), 'xesam:title': Variant('s', track.title), 'xesam:artist': Variant('s', track.artist), 'xesam:album': Variant('s', track.album_name), 'xesam:url': Variant('s', track.cached_url if track.cached_url else 'https://') }