Source code for terminusgps.wialon.items.unit

from urllib.parse import quote_plus

from terminusgps.wialon import flags
from terminusgps.wialon.items.base import WialonBase


[docs] class WialonUnit(WialonBase):
[docs] def create( self, creator_id: str | int, name: str, hw_type_id: str | int ) -> int | None: """ Creates a new Wialon unit. :param creator_id: A Wialon user id. :type creator_id: :py:obj:`str` | :py:obj:`int` :param name: A name for the unit. :type name: :py:obj:`str` :param hw_type_id: A Wialon hardware type ID. :type hw_type_id: :py:obj:`str` | :py:obj:`int` :raises ValueError: If ``creator_id`` is a :py:obj:`str` but not a digit. :raises ValueError: If ``hw_type_id`` is a :py:obj:`str` but not a digit. :returns: An id for the new unit. :rtype: :py:obj:`int` | :py:obj:`None` """ if isinstance(creator_id, str) and not creator_id.isdigit(): raise ValueError(f"'creator_id' must be a digit, got '{creator_id}'.") if isinstance(hw_type_id, str) and not hw_type_id.isdigit(): raise ValueError(f"'hw_type_id' must be a digit, got '{hw_type_id}'.") response = self.session.wialon_api.core_create_unit( **{ "creatorId": creator_id, "name": name, "hwTypeId": hw_type_id, "dataFlags": flags.DATAFLAG_UNIT_BASE, } ) return ( int(response.get("item", {}).get("id")) if response and response.get("item") else None )
[docs] def populate(self) -> None: super().populate() response = self.session.wialon_api.core_search_item( **{ "id": self.id, "flags": sum( [flags.DATAFLAG_UNIT_ADVANCED_PROPERTIES, flags.DATAFLAG_UNIT_IMAGE] ), } ) if response: item = response.get("item", {}) self._imei_number = item.get("uid") self._active = item.get("act", False) self._image_uri = item.get("uri")
def get_position(self) -> dict | None: return self.session.wialon_api.core_search_item( **{"id": self.id, "flags": flags.DATAFLAG_UNIT_POSITION} ) @property def position(self) -> dict | None: """Current GPS position of the unit.""" return self.get_position() @property def exists(self) -> bool: """Whether or not the unit exists in Wialon.""" return bool( self.session.wialon_api.core_search_item( **{"id": self.id, "flags": flags.DATAFLAG_UNIT_BASE} ).get("item", False) ) @property def available_commands(self) -> dict: """Assigned commands to the unit.""" return self.session.wialon_api.core_get_hw_cmds( **{"deviceTypeId": 0, "unitId": self.id} ) @property def image_uri(self) -> str: """An image URI for the unit.""" return self._image_uri @property def imei_number(self) -> int | None: """The unit's IMEI number.""" if self._imei_number: return int(self._imei_number) @property def active(self) -> bool: """Whether or not the unit is active.""" if self._active: return bool(self._active) return False
[docs] def execute_command( self, name: str, link_type: str, timeout: int = 5, flags: int = 0, param: dict | None = None, ) -> None: """ Executes a command on the unit. :param name: A Wialon command name. :type name: :py:obj:`str` :param link_type: A protocol to use for the Wialon command. :type link_type: :py:obj:`str` :param timeout: How long (in seconds) to wait before timing out command execution. Default is ``5``. :type timeout: :py:obj:`int` :param flags: Flags to pass to the Wialon command execution. :type flags: :py:obj:`int` :param param: Additional parameters to execute the command with. :type param: :py:obj:`dict` | :py:obj:`None` :returns: Nothing. :rtype: :py:obj:`None` """ self.session.wialon_api.unit_exec_cmd( **{ "itemId": self.id, "commandName": name, "linkType": link_type, "timeout": timeout, "flags": flags, "param": param if param else {}, } )
[docs] def set_access_password(self, password: str) -> None: """ Sets a new access password for the unit. :param password: A new access password. :type name: :py:obj:`str` :raises WialonError: If something goes wrong with Wialon. :returns: Nothing. :rtype: :py:obj:`None` """ self.session.wialon_api.unit_update_access_password( **{"itemId": self.id, "accessPassword": password} )
[docs] def activate(self) -> None: """ Activates the unit. :raises WialonError: If something goes wrong with Wialon. :returns: Nothing. :rtype: :py:obj:`None` """ self.session.wialon_api.unit_set_active( **{"itemId": self.id, "active": int(True)} )
[docs] def deactivate(self) -> None: """ Deactivates the unit. :raises WialonError: If something goes wrong with Wialon. :returns: Nothing. :rtype: :py:obj:`None` """ self.session.wialon_api.unit_set_active( **{"itemId": self.id, "active": int(False)} )
[docs] def assign_phone(self, phone: str) -> None: """ Assigns a phone number to the unit. :param phone: A phone number beginning with a country code. :type phone: :py:obj:`str` :raises WialonError: If something goes wrong with Wialon. :returns: Nothing. :rtype: :py:obj:`None` """ self.session.wialon_api.unit_update_phone( **{"itemId": self.id, "phoneNumber": quote_plus(phone)} )
[docs] def get_phone_numbers(self) -> list[str]: """ Retrieves all phone numbers assigned to the unit. This includes any attached drivers, custom/admin fields or otherwise assigned phone numbers. :raises WialonError: If something goes wrong with Wialon. :returns: A list of phone numbers. :rtype: :py:obj:`list` """ phone_numbers: list[str] = [] phones_0: list[str] | None = self._get_driver_phone_numbers() phones_1: list[str] | None = self._get_cfield_phone_numbers() phones_2: list[str] | None = self._get_afield_phone_numbers() if phones_0 is not None: phone_numbers.extend(phones_0) if phones_1 is not None: phone_numbers.extend(phones_1) if phones_2 is not None: phone_numbers.extend(phones_2) return list(dict.fromkeys(phone_numbers)) # Removes duplicate phone numbers
[docs] def clean_phone_numbers(self, phones: list[str]) -> list[str]: """Takes a list of phone numbers and returns a list of clean phone numbers.""" return [ clean_num for num in phones for clean_num in (num.split(",") if "," in num else [num]) ]
def _get_afield_phone_numbers(self, key: str = "to_number") -> list[str] | None: """ Retrives any phone numbers saved in an admin field by key. :param key: An admin field key. Default is ``"to_number"``. :type key: :py:obj:`str` :raises WialonError: If something goes wrong with Wialon. :returns: A list of phone numbers, if the unit has admin phone number fields. :rtype: :py:obj:`list` | :py:obj:`None` """ for field_name, field_val in self.afields.items(): if field_name == key: return self.clean_phone_numbers([field_val]) def _get_cfield_phone_numbers(self, key: str = "to_number") -> list[str] | None: """ Retrives any phone numbers saved in a custom field by key. :param key: A custom field key. Default is ``"to_number"``. :type key: :py:obj:`str` :raises WialonError: If something goes wrong with Wialon. :returns: A list of phone numbers, if the unit has custom phone number fields. :rtype: :py:obj:`list` | :py:obj:`None` """ for field_name, field_val in self.cfields.items(): if field_name == key: return self.clean_phone_numbers([field_val]) def _get_driver_phone_numbers(self) -> list[str] | None: """ Retrieves any phone numbers assigned to drivers attached to the unit. :raises WialonError: If something goes wrong with Wialon. :returns: A list of phone numbers, if the unit has attached drivers with phone numbers. :rtype: :py:obj:`list` | :py:obj:`None` """ response = self.session.wialon_api.resource_get_unit_drivers( **{"unitId": self.id} ) if response: dirty_phones = [driver[0].get("ph") for driver in response.values()] return self.clean_phone_numbers(dirty_phones)