{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Device" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Device types" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The DeviceManager supports different types of devices. At the time of writing this example, these are the supported device types:\n", "\n", "- USB: `USBDevice`\n", "- Ethernet/LAN: `LANDevice`\n", "\n", "All currently supported device types can be found in the `DeviceType` enumeration. If you want to extend the DeviceManager-project by another device type, it is absolutely essential, to add this type to the `DeviceType`-enumeration. Otherwise the device scanners and manager will not support that device type." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[, ]" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from device_manager import DeviceType\n", "\n", "list(DeviceType)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The USB-devices are represented by the class `USBDevice` and ethernet-devices are represented by the `LANDevice`-class. Both are subclasses of the abstract base class `Device`." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from device_manager import USBDevice, LANDevice\n", "\n", "usb_device = USBDevice()\n", "lan_device = LANDevice()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `DeviceType` enumeration is used at different places in the code, especially in from of `DeviceTypeDict`s. Those are dictionaries, that are using a `DeviceType` as key. You can find them in the classes `DeviceScanner` or `DeviceManager`. Using a `DeviceTypeDict` is very easy, because you do not have to pass a `DeviceTpe`-object as key, you could also use a string, a `Device`-type or `Device`-object. Internally the `DeviceType`-constructor is used for this feature:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "'usb' := DeviceType.USB\n", "USBDevice := DeviceType.USB\n", "USBDevice() := DeviceType.USB\n" ] } ], "source": [ "print(\"'usb' :=\", DeviceType(\"usb\"))\n", "print(\"USBDevice :=\", DeviceType(USBDevice))\n", "print(\"USBDevice() :=\", DeviceType(USBDevice()))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you already have a `Device`-object, you could also use its `device_type`-property, to get the corresponding `DeviceType`-object:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "usb_device.device_type" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basic functionality" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Device properties\n", "\n", "As already mentioned above, all device types are based on the abstract class `Device`. All `Device`-objects have proprties for its main address/port and for additional aliases, if any." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "lan_device.address = \"192.168.10.12\"\n", "lan_device.address_aliases = [\"192.168.10.13\", \"mydevice.domain.com\"]\n", "\n", "usb_device.address = \"/devices/pci0000:00/0000:00:02.0/usb1\"\n", "usb_device.address_aliases = \"/dev/bus/usb/001/001\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All devices have a property returning their corresponding `DeviceType`." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "lan_device.device_type: DeviceType.LAN\n", "usb_device.device_type: DeviceType.USB\n" ] } ], "source": [ "print(\"lan_device.device_type:\", lan_device.device_type)\n", "print(\"usb_device.device_type:\", usb_device.device_type)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Additionally, each device has a `unique_identifier`-property, which contains the device's unique identifiers, as the name suggests. This property can be used, to compare different `Device`-objects. If their `unique_identifier`s are equal, you can be sure it is the same device, which may have multiple connections." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Serialization functions\n", "\n", "All devices are serializable into a python dictionary. This is used by the `DeviceManager`, for example, which uses those dictionaries to serialize its devices into a JSON file.\n", "\n", "The serialization functions can also be used, to have a look into the `Device`-objects. All relevant properties of the device, that are not `None`, are contained by the dictionary:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'type': 'usb',\n", " 'address': '/devices/pci0000:00/0000:00:02.0/usb1',\n", " 'address_aliases': ['/dev/bus/usb/001/001']}" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "usb_device.to_dict()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Proper device types" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### USB devices\n", "\n", "USB devices are represented by the `USBDevice`-class. Besides the inherited attributes, the `USBDevice` contains further attributes:\n", "\n", "- `vendor_id` (`int`): The manufacturer code, assigned by the USB committee (USB-IF)\n", "- `product_id` (`int`): The product/model code, assigned by the device's manufacturer\n", "- `revision_id` (`int`): The revision code\n", "- `serial` (`str`): The device's serial number" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'type': 'usb',\n", " 'address': '/devices/pci0000:00/0000:00:02.0/usb1',\n", " 'address_aliases': ['/dev/bus/usb/001/001'],\n", " 'vendor_id': 14627,\n", " 'product_id': 4816,\n", " 'revision_id': 256,\n", " 'serial': '0123456789AB'}" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "usb_device.vendor_id = 0x3923\n", "usb_device.product_id = 0x12d0\n", "usb_device.revision_id = 0x0100\n", "usb_device.serial = \"0123456789AB\"\n", "\n", "usb_device.to_dict()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Because the USBDevice is an usb device, the `device_type`-property always returns `DeviceType.USB`. As `unique_identifier` the `USBDevice`-class uses its `vendor_id`, `product_id` and `serial`." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'vendor_id': 14627, 'product_id': 4816, 'serial': '0123456789AB'}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "usb_device.unique_identifier" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To easily recognize the connected usb devices, you can look at the attributes `vendor_name` and `product_name`. These properties look up the `vendor_id` and `product_id` of the device to get the manufacturer and model name:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Vendor (0x3923): National Instruments Corp.\n", "Product (0x12D0): DAQPad-6507\n" ] } ], "source": [ "print(\"Vendor (0x{:04X}):\".format(usb_device.vendor_id), usb_device.vendor_name)\n", "print(\"Product (0x{:04X}):\".format(usb_device.product_id), usb_device.product_name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Ethernet/LAN devices\n", "\n", "Ethernet devices are represented by the class `LANDevice`. It only has one additional attribute, which is the `mac_address` (the device's physical address). This is also the device's `unique_identifier`." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'type': 'lan',\n", " 'address': '192.168.10.12',\n", " 'address_aliases': ['192.168.10.13', 'mydevice.domain.com'],\n", " 'mac_address': '01:23:45:67:89:AB'}" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lan_device.mac_address = \"01-23-45-67-89-ab\"\n", "\n", "lan_device.to_dict()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As seen in the code lines above, the device automatically converts the device's mac address into a standardized format. This is done, to keep the devices comparable. The mac address is always stored with colon-seperators (`:`) and uppercase-hexadecimal components." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'mac_address': '01:23:45:67:89:AB'}" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lan_device.unique_identifier" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.1" }, "nbsphinx": { "execute": "never" } }, "nbformat": 4, "nbformat_minor": 4 }