You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							175 lines
						
					
					
						
							5.5 KiB
						
					
					
				
			
		
		
	
	
							175 lines
						
					
					
						
							5.5 KiB
						
					
					
				| import os
 | |
| import subprocess
 | |
| from pathlib import Path
 | |
| 
 | |
| from cereal import log
 | |
| from selfdrive.hardware.base import HardwareBase
 | |
| 
 | |
| NM = 'org.freedesktop.NetworkManager'
 | |
| NM_CON_ACT = NM + '.Connection.Active'
 | |
| NM_DEV_WL = NM + '.Device.Wireless'
 | |
| NM_AP = NM + '.AccessPoint'
 | |
| DBUS_PROPS = 'org.freedesktop.DBus.Properties'
 | |
| 
 | |
| MM = 'org.freedesktop.ModemManager1'
 | |
| MM_MODEM = MM + ".Modem"
 | |
| MM_MODEM_SIMPLE = MM + ".Modem.Simple"
 | |
| MM_SIM = MM + ".Sim"
 | |
| 
 | |
| MM_MODEM_STATE_CONNECTED = 11
 | |
| 
 | |
| TIMEOUT = 10
 | |
| 
 | |
| NetworkType = log.ThermalData.NetworkType
 | |
| NetworkStrength = log.ThermalData.NetworkStrength
 | |
| 
 | |
| # https://developer.gnome.org/ModemManager/unstable/ModemManager-Flags-and-Enumerations.html#MMModemAccessTechnology
 | |
| MM_MODEM_ACCESS_TECHNOLOGY_UMTS = 1 << 5
 | |
| MM_MODEM_ACCESS_TECHNOLOGY_LTE = 1 << 14
 | |
| 
 | |
| 
 | |
| class Tici(HardwareBase):
 | |
|   def __init__(self):
 | |
|     import dbus  # pylint: disable=import-error
 | |
| 
 | |
|     self.bus = dbus.SystemBus()
 | |
|     self.nm = self.bus.get_object(NM, '/org/freedesktop/NetworkManager')
 | |
|     self.mm = self.bus.get_object(MM, '/org/freedesktop/ModemManager1')
 | |
| 
 | |
|   def get_os_version(self):
 | |
|     with open("/VERSION") as f:
 | |
|       return f.read().strip()
 | |
| 
 | |
|   def get_sound_card_online(self):
 | |
|     return os.system("pulseaudio --check") == 0
 | |
| 
 | |
|   def reboot(self, reason=None):
 | |
|     subprocess.check_output(["sudo", "reboot"])
 | |
| 
 | |
|   def uninstall(self):
 | |
|     Path("/data/__system_reset__").touch()
 | |
|     os.sync()
 | |
|     self.reboot()
 | |
| 
 | |
|   def get_serial(self):
 | |
|     return self.get_cmdline()['androidboot.serialno']
 | |
| 
 | |
|   def get_network_type(self):
 | |
|     try:
 | |
|       primary_connection = self.nm.Get(NM, 'PrimaryConnection', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)
 | |
|       primary_connection = self.bus.get_object(NM, primary_connection)
 | |
|       tp = primary_connection.Get(NM_CON_ACT, 'Type', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)
 | |
| 
 | |
|       if tp in ['802-3-ethernet', '802-11-wireless']:
 | |
|         return NetworkType.wifi
 | |
|       elif tp in ['gsm']:
 | |
|         modem = self.get_modem()
 | |
|         access_t = modem.Get(MM_MODEM, 'AccessTechnologies', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)
 | |
|         if access_t >= MM_MODEM_ACCESS_TECHNOLOGY_LTE:
 | |
|           return NetworkType.cell4G
 | |
|         elif access_t >= MM_MODEM_ACCESS_TECHNOLOGY_UMTS:
 | |
|           return NetworkType.cell3G
 | |
|         else:
 | |
|           return NetworkType.cell2G
 | |
|     except Exception:
 | |
|       pass
 | |
| 
 | |
|     return NetworkType.none
 | |
| 
 | |
|   def get_modem(self):
 | |
|     objects = self.mm.GetManagedObjects(dbus_interface="org.freedesktop.DBus.ObjectManager", timeout=TIMEOUT)
 | |
|     modem_path = list(objects.keys())[0]
 | |
|     return self.bus.get_object(MM, modem_path)
 | |
| 
 | |
|   def get_wlan(self):
 | |
|     wlan_path = self.nm.GetDeviceByIpIface('wlan0', dbus_interface=NM, timeout=TIMEOUT)
 | |
|     return self.bus.get_object(NM, wlan_path)
 | |
| 
 | |
|   def get_sim_info(self):
 | |
|     modem = self.get_modem()
 | |
|     sim_path = modem.Get(MM_MODEM, 'Sim', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)
 | |
| 
 | |
|     if sim_path == "/":
 | |
|       return {
 | |
|         'sim_id': '',
 | |
|         'mcc_mnc': None,
 | |
|         'network_type': ["Unknown"],
 | |
|         'sim_state': ["ABSENT"],
 | |
|         'data_connected': False
 | |
|       }
 | |
|     else:
 | |
|       sim = self.bus.get_object(MM, sim_path)
 | |
|       return {
 | |
|         'sim_id': str(sim.Get(MM_SIM, 'SimIdentifier', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)),
 | |
|         'mcc_mnc': str(sim.Get(MM_SIM, 'OperatorIdentifier', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)),
 | |
|         'network_type': ["Unknown"],
 | |
|         'sim_state': ["READY"],
 | |
|         'data_connected': modem.Get(MM_MODEM, 'State', dbus_interface=DBUS_PROPS, timeout=TIMEOUT) == MM_MODEM_STATE_CONNECTED,
 | |
|       }
 | |
| 
 | |
|   def get_subscriber_info(self):
 | |
|     return ""
 | |
| 
 | |
|   def get_imei(self, slot):
 | |
|     if slot != 0:
 | |
|       return ""
 | |
| 
 | |
|     return str(self.get_modem().Get(MM_MODEM, 'EquipmentIdentifier', dbus_interface=DBUS_PROPS, timeout=TIMEOUT))
 | |
| 
 | |
|   def parse_strength(self, percentage):
 | |
|       if percentage < 25:
 | |
|         return NetworkStrength.poor
 | |
|       elif percentage < 50:
 | |
|         return NetworkStrength.moderate
 | |
|       elif percentage < 75:
 | |
|         return NetworkStrength.good
 | |
|       else:
 | |
|         return NetworkStrength.great
 | |
| 
 | |
|   def get_network_strength(self, network_type):
 | |
|     network_strength = NetworkStrength.unknown
 | |
| 
 | |
|     try:
 | |
|       if network_type == NetworkType.none:
 | |
|         pass
 | |
|       elif network_type == NetworkType.wifi:
 | |
|         wlan = self.get_wlan()
 | |
|         active_ap_path = wlan.Get(NM_DEV_WL, 'ActiveAccessPoint', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)
 | |
|         if active_ap_path != "/":
 | |
|           active_ap = self.bus.get_object(NM, active_ap_path)
 | |
|           strength = int(active_ap.Get(NM_AP, 'Strength', dbus_interface=DBUS_PROPS, timeout=TIMEOUT))
 | |
|           network_strength = self.parse_strength(strength)
 | |
|       else:  # Cellular
 | |
|         modem = self.get_modem()
 | |
|         strength = int(modem.Get(MM_MODEM, 'SignalQuality', dbus_interface=DBUS_PROPS, timeout=TIMEOUT)[0])
 | |
|         network_strength = self.parse_strength(strength)
 | |
|     except Exception:
 | |
|       pass
 | |
| 
 | |
|     return network_strength
 | |
| 
 | |
|   # We don't have a battery, so let's use some sane constants
 | |
|   def get_battery_capacity(self):
 | |
|     return 100
 | |
| 
 | |
|   def get_battery_status(self):
 | |
|     return ""
 | |
| 
 | |
|   def get_battery_current(self):
 | |
|     return 0
 | |
| 
 | |
|   def get_battery_voltage(self):
 | |
|     return 0
 | |
| 
 | |
|   def get_battery_charging(self):
 | |
|     return True
 | |
| 
 | |
|   def set_battery_charging(self, on):
 | |
|     pass
 | |
| 
 | |
|   def get_usb_present(self):
 | |
|     # Not sure if relevant on tici, but the file exists
 | |
|     return self.read_param_file("/sys/class/power_supply/usb/present", lambda x: bool(int(x)), False)
 | |
| 
 | |
|   def get_current_power_draw(self):
 | |
|     return (self.read_param_file("/sys/class/hwmon/hwmon1/power1_input", int) / 1e6)
 | |
| 
 |