Export the battery level/charge state
This commit is contained in:
parent
0dc3cb5f3a
commit
e647e20426
20
README.md
20
README.md
|
@ -155,6 +155,26 @@ org.freedesktop.tuhi1.Device
|
||||||
The physical dimensions (width, height) in µm
|
The physical dimensions (width, height) in µm
|
||||||
Read-only
|
Read-only
|
||||||
|
|
||||||
|
Property: BatteryPercent (u)
|
||||||
|
The last known battery charge level in percent. This charge level is
|
||||||
|
only valid when the BatteryState is other than Unknown.
|
||||||
|
Read-only
|
||||||
|
|
||||||
|
Property: BatteryState (u)
|
||||||
|
An enum describing the battery state. Permitted enum values are
|
||||||
|
|
||||||
|
0: Unknown
|
||||||
|
1: Charging
|
||||||
|
2: Discharging
|
||||||
|
|
||||||
|
'Unknown' may refer to a state that could not be read, a state
|
||||||
|
that has not yet been updated, or a state that has not updated within
|
||||||
|
a daemon-internal time period. Thus, a device that is connected but
|
||||||
|
does not regularly send battery updates may eventually switch to
|
||||||
|
'Unknown'.
|
||||||
|
|
||||||
|
Read-only
|
||||||
|
|
||||||
Property: DrawingsAvailable (at)
|
Property: DrawingsAvailable (at)
|
||||||
An array of timestamps of the available drawings. The timestamp of
|
An array of timestamps of the available drawings. The timestamp of
|
||||||
each drawing can be used as argument to GetJSONData(). Timestamps are
|
each drawing can be used as argument to GetJSONData(). Timestamps are
|
||||||
|
|
|
@ -163,6 +163,14 @@ class TuhiKeteDevice(_DBusObject):
|
||||||
def drawings_available(self):
|
def drawings_available(self):
|
||||||
return self.property('DrawingsAvailable')
|
return self.property('DrawingsAvailable')
|
||||||
|
|
||||||
|
@GObject.Property
|
||||||
|
def battery_percent(self):
|
||||||
|
return self.property('BatteryPercent')
|
||||||
|
|
||||||
|
@GObject.Property
|
||||||
|
def battery_state(self):
|
||||||
|
return self.property('BatteryState')
|
||||||
|
|
||||||
def pair(self):
|
def pair(self):
|
||||||
logger.debug(f'{self}: Pairing')
|
logger.debug(f'{self}: Pairing')
|
||||||
# FIXME: Pair() doesn't return anything useful yet, so we wait until
|
# FIXME: Pair() doesn't return anything useful yet, so we wait until
|
||||||
|
@ -199,6 +207,10 @@ class TuhiKeteDevice(_DBusObject):
|
||||||
self.notify('drawings-available')
|
self.notify('drawings-available')
|
||||||
elif 'Listening' in changed_props:
|
elif 'Listening' in changed_props:
|
||||||
self.notify('listening')
|
self.notify('listening')
|
||||||
|
elif 'BatteryPercent' in changed_props:
|
||||||
|
self.notify('battery-percent')
|
||||||
|
elif 'BatteryState' in changed_props:
|
||||||
|
self.notify('battery-state')
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f'{self.address} - {self.name}'
|
return f'{self.address} - {self.name}'
|
||||||
|
@ -923,6 +935,16 @@ class TuhiKeteShell(cmd.Cmd):
|
||||||
for device in self._manager.devices:
|
for device in self._manager.devices:
|
||||||
if parsed_args.address is None or parsed_args.address == device.address:
|
if parsed_args.address is None or parsed_args.address == device.address:
|
||||||
print(device)
|
print(device)
|
||||||
|
charge_strs = {
|
||||||
|
0: 'unknown',
|
||||||
|
1: 'charging',
|
||||||
|
2: 'discharging'
|
||||||
|
}
|
||||||
|
try:
|
||||||
|
charge_str = charge_strs[device.battery_state]
|
||||||
|
except KeyError:
|
||||||
|
charge_str = 'invalid'
|
||||||
|
print(f'\tBattery level: {device.battery_percent}%, {charge_str}')
|
||||||
print('\tAvailable drawings:')
|
print('\tAvailable drawings:')
|
||||||
for d in device.drawings_available:
|
for d in device.drawings_available:
|
||||||
t = time.localtime(d)
|
t = time.localtime(d)
|
||||||
|
|
34
tuhi/base.py
34
tuhi/base.py
|
@ -12,6 +12,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import enum
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
from gi.repository import GObject
|
from gi.repository import GObject
|
||||||
|
@ -34,6 +35,12 @@ class TuhiDevice(GObject.Object):
|
||||||
real device) with the frontend DBusServer object that exports the device
|
real device) with the frontend DBusServer object that exports the device
|
||||||
over Tuhi's DBus interface
|
over Tuhi's DBus interface
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
class BatteryState(enum.Enum):
|
||||||
|
UNKNOWN = 0
|
||||||
|
CHARGING = 1
|
||||||
|
DISCHARGING = 2
|
||||||
|
|
||||||
__gsignals__ = {
|
__gsignals__ = {
|
||||||
# Signal sent when an error occurs on the device itself.
|
# Signal sent when an error occurs on the device itself.
|
||||||
# Argument is a Wacom*Exception
|
# Argument is a Wacom*Exception
|
||||||
|
@ -49,6 +56,8 @@ class TuhiDevice(GObject.Object):
|
||||||
assert uuid is not None or paired is False
|
assert uuid is not None or paired is False
|
||||||
self.paired = paired
|
self.paired = paired
|
||||||
self._uuid = uuid
|
self._uuid = uuid
|
||||||
|
self._battery_state = TuhiDevice.BatteryState.UNKNOWN
|
||||||
|
self._battery_percent = 0
|
||||||
|
|
||||||
bluez_device.connect('connected', self._on_bluez_device_connected)
|
bluez_device.connect('connected', self._on_bluez_device_connected)
|
||||||
bluez_device.connect('disconnected', self._on_bluez_device_disconnected)
|
bluez_device.connect('disconnected', self._on_bluez_device_disconnected)
|
||||||
|
@ -93,6 +102,23 @@ class TuhiDevice(GObject.Object):
|
||||||
def listening(self):
|
def listening(self):
|
||||||
return self._tuhi_dbus_device.listening
|
return self._tuhi_dbus_device.listening
|
||||||
|
|
||||||
|
@GObject.Property
|
||||||
|
def battery_percent(self):
|
||||||
|
return self._battery_percent
|
||||||
|
|
||||||
|
@battery_percent.setter
|
||||||
|
def battery_percent(self, value):
|
||||||
|
self._battery_percent = value
|
||||||
|
|
||||||
|
@GObject.Property
|
||||||
|
def battery_state(self):
|
||||||
|
return self._battery_state
|
||||||
|
|
||||||
|
@battery_state.setter
|
||||||
|
def battery_state(self, value):
|
||||||
|
print('setting battery state on tuhidevice')
|
||||||
|
self._battery_state = value
|
||||||
|
|
||||||
def connect_device(self):
|
def connect_device(self):
|
||||||
self._bluez_device.connect_device()
|
self._bluez_device.connect_device()
|
||||||
|
|
||||||
|
@ -104,6 +130,7 @@ class TuhiDevice(GObject.Object):
|
||||||
self._wacom_device.connect('done', self._on_fetching_finished, bluez_device)
|
self._wacom_device.connect('done', self._on_fetching_finished, bluez_device)
|
||||||
self._wacom_device.connect('button-press-required', self._on_button_press_required)
|
self._wacom_device.connect('button-press-required', self._on_button_press_required)
|
||||||
self._wacom_device.connect('notify::uuid', self._on_uuid_updated, bluez_device)
|
self._wacom_device.connect('notify::uuid', self._on_uuid_updated, bluez_device)
|
||||||
|
self._wacom_device.connect('battery-status', self._on_battery_status, bluez_device)
|
||||||
|
|
||||||
self._wacom_device.start(not self.paired)
|
self._wacom_device.start(not self.paired)
|
||||||
self.pairing_mode = False
|
self.pairing_mode = False
|
||||||
|
@ -138,6 +165,13 @@ class TuhiDevice(GObject.Object):
|
||||||
def _on_listening_updated(self, dbus_device, pspec):
|
def _on_listening_updated(self, dbus_device, pspec):
|
||||||
self.notify('listening')
|
self.notify('listening')
|
||||||
|
|
||||||
|
def _on_battery_status(self, wacom_device, percent, is_charging, bluez_device):
|
||||||
|
if is_charging:
|
||||||
|
self.battery_state = TuhiDevice.BatteryState.CHARGING
|
||||||
|
else:
|
||||||
|
self.battery_state = TuhiDevice.BatteryState.DISCHARGING
|
||||||
|
self.battery_percent = percent
|
||||||
|
|
||||||
|
|
||||||
class Tuhi(GObject.Object):
|
class Tuhi(GObject.Object):
|
||||||
__gsignals__ = {
|
__gsignals__ = {
|
||||||
|
|
|
@ -53,6 +53,12 @@ INTROSPECTION_XML = '''
|
||||||
<property type='b' name='Listening' access='read'>
|
<property type='b' name='Listening' access='read'>
|
||||||
<annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='true'/>
|
<annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='true'/>
|
||||||
</property>
|
</property>
|
||||||
|
<property type='u' name='BatteryPercent' access='read'>
|
||||||
|
<annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='true'/>
|
||||||
|
</property>
|
||||||
|
<property type='b' name='BatteryState' access='read'>
|
||||||
|
<annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='true'/>
|
||||||
|
</property>
|
||||||
<property type='at' name='DrawingsAvailable' access='read'>
|
<property type='at' name='DrawingsAvailable' access='read'>
|
||||||
<annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='true'/>
|
<annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='true'/>
|
||||||
</property>
|
</property>
|
||||||
|
@ -146,7 +152,11 @@ class TuhiDBusDevice(_TuhiDBus):
|
||||||
self._listening = False
|
self._listening = False
|
||||||
self._listening_client = None
|
self._listening_client = None
|
||||||
self._dbusid = self._register_object(connection)
|
self._dbusid = self._register_object(connection)
|
||||||
|
self._battery_percent = 0
|
||||||
|
self._battery_state = device.battery_state
|
||||||
device.connect('notify::paired', self._on_device_paired)
|
device.connect('notify::paired', self._on_device_paired)
|
||||||
|
device.connect('notify::battery-percent', self._on_battery_percent)
|
||||||
|
device.connect('notify::battery-state', self._on_battery_state)
|
||||||
device.connect('device-error', self._on_device_error)
|
device.connect('device-error', self._on_device_error)
|
||||||
|
|
||||||
@GObject.Property
|
@GObject.Property
|
||||||
|
@ -169,6 +179,30 @@ class TuhiDBusDevice(_TuhiDBus):
|
||||||
def paired(self, paired):
|
def paired(self, paired):
|
||||||
self._paired = paired
|
self._paired = paired
|
||||||
|
|
||||||
|
@GObject.Property
|
||||||
|
def battery_percent(self):
|
||||||
|
return self._battery_percent
|
||||||
|
|
||||||
|
@battery_percent.setter
|
||||||
|
def battery_percent(self, value):
|
||||||
|
if self._battery_percent == value:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._battery_percent = value
|
||||||
|
self.properties_changed({'BatteryPercent': GLib.Variant.new_uint32(value)})
|
||||||
|
|
||||||
|
@GObject.Property
|
||||||
|
def battery_state(self):
|
||||||
|
return self._battery_state
|
||||||
|
|
||||||
|
@battery_state.setter
|
||||||
|
def battery_state(self, value):
|
||||||
|
if self._battery_state == value:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._battery_state = value
|
||||||
|
self.properties_changed({'BatteryState': GLib.Variant.new_uint32(value.value)})
|
||||||
|
|
||||||
def remove(self):
|
def remove(self):
|
||||||
self.connection.unregister_object(self._dbusid)
|
self.connection.unregister_object(self._dbusid)
|
||||||
self._dbusid = None
|
self._dbusid = None
|
||||||
|
@ -221,6 +255,10 @@ class TuhiDBusDevice(_TuhiDBus):
|
||||||
return ts
|
return ts
|
||||||
elif propname == 'Listening':
|
elif propname == 'Listening':
|
||||||
return GLib.Variant.new_boolean(self.listening)
|
return GLib.Variant.new_boolean(self.listening)
|
||||||
|
elif propname == 'BatteryPercent':
|
||||||
|
return GLib.Variant.new_uint32(self.battery_percent)
|
||||||
|
elif propname == 'BatteryState':
|
||||||
|
return GLib.Variant.new_uint32(self.battery_state.value)
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -235,6 +273,12 @@ class TuhiDBusDevice(_TuhiDBus):
|
||||||
return
|
return
|
||||||
self.paired = device.paired
|
self.paired = device.paired
|
||||||
|
|
||||||
|
def _on_battery_percent(self, device, pspec):
|
||||||
|
self.battery_percent = device.battery_percent
|
||||||
|
|
||||||
|
def _on_battery_state(self, device, pspec):
|
||||||
|
self.battery_state = device.battery_state
|
||||||
|
|
||||||
def _on_device_error(self, device, exception):
|
def _on_device_error(self, device, exception):
|
||||||
logger.info('An error occured while synching the device')
|
logger.info('An error occured while synching the device')
|
||||||
if self.listening:
|
if self.listening:
|
||||||
|
|
|
@ -106,6 +106,9 @@ class WacomDevice(GObject.Object):
|
||||||
(GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT, )),
|
(GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT, )),
|
||||||
'button-press-required':
|
'button-press-required':
|
||||||
(GObject.SIGNAL_RUN_FIRST, None, ()),
|
(GObject.SIGNAL_RUN_FIRST, None, ()),
|
||||||
|
# battery level in %, boolean for is-charging
|
||||||
|
"battery-status":
|
||||||
|
(GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_INT, GObject.TYPE_BOOLEAN)),
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, device, uuid=None):
|
def __init__(self, device, uuid=None):
|
||||||
|
@ -544,6 +547,7 @@ class WacomDevice(GObject.Object):
|
||||||
logger.debug(f'device is plugged in and charged at {battery}%')
|
logger.debug(f'device is plugged in and charged at {battery}%')
|
||||||
else:
|
else:
|
||||||
logger.debug(f'device is discharging: {battery}%')
|
logger.debug(f'device is discharging: {battery}%')
|
||||||
|
self.emit('battery-status', battery, charging)
|
||||||
if self.is_slate():
|
if self.is_slate():
|
||||||
self.width = w = self.get_dimensions('width')
|
self.width = w = self.get_dimensions('width')
|
||||||
self.height = h = self.get_dimensions('height')
|
self.height = h = self.get_dimensions('height')
|
||||||
|
|
Loading…
Reference in New Issue