예제 #1
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up config entry."""

    session = aiohttp_client.async_get_clientsession(hass)
    hass.data.setdefault(DOMAIN, {})
    printer = SyncThru(entry.data[CONF_URL],
                       session,
                       connection_mode=ConnectionMode.API)

    async def async_update_data() -> SyncThru:
        """Fetch data from the printer."""
        try:
            async with async_timeout.timeout(10):
                await printer.update()
        except SyncThruAPINotSupported as api_error:
            # if an exception is thrown, printer does not support syncthru
            _LOGGER.info(
                "Configured printer at %s does not provide SyncThru JSON API",
                printer.url,
                exc_info=api_error,
            )
            raise api_error
        else:
            # if the printer is offline, we raise an UpdateFailed
            if printer.is_unknown_state():
                raise UpdateFailed(
                    f"Configured printer at {printer.url} does not respond.")
            return printer

    coordinator: DataUpdateCoordinator = DataUpdateCoordinator(
        hass,
        _LOGGER,
        name=DOMAIN,
        update_method=async_update_data,
        update_interval=timedelta(seconds=30),
    )
    hass.data[DOMAIN][entry.entry_id] = coordinator
    await coordinator.async_config_entry_first_refresh()
    if isinstance(coordinator.last_exception, SyncThruAPINotSupported):
        # this means that the printer does not support the syncthru JSON API
        # and the config should simply be discarded
        return False

    device_registry = dr.async_get(hass)
    device_registry.async_get_or_create(
        config_entry_id=entry.entry_id,
        configuration_url=printer.url,
        connections=device_connections(printer),
        identifiers=device_identifiers(printer),
        model=printer.model(),
        name=printer.hostname(),
    )

    hass.config_entries.async_setup_platforms(entry, PLATFORMS)
    return True
예제 #2
0
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
    """Set up config entry."""

    session = aiohttp_client.async_get_clientsession(hass)
    hass.data.setdefault(DOMAIN, {})
    printer = SyncThru(entry.data[CONF_URL], session)

    async def async_update_data() -> SyncThru:
        """Fetch data from the printer."""
        try:
            async with async_timeout.timeout(10):
                await printer.update()
        except ValueError as value_error:
            # if an exception is thrown, printer does not support syncthru
            raise UpdateFailed(
                f"Configured printer at {printer.url} does not respond. "
                "Please make sure it supports SyncThru and check your configuration."
            ) from value_error
        else:
            if printer.is_unknown_state():
                raise ConfigEntryNotReady
            return printer

    coordinator: DataUpdateCoordinator = DataUpdateCoordinator(
        hass,
        _LOGGER,
        name=DOMAIN,
        update_method=async_update_data,
        update_interval=timedelta(seconds=30),
    )
    hass.data[DOMAIN][entry.entry_id] = coordinator
    await coordinator.async_config_entry_first_refresh()

    device_registry = await dr.async_get_registry(hass)
    device_registry.async_get_or_create(
        config_entry_id=entry.entry_id,
        connections=device_connections(printer),
        identifiers=device_identifiers(printer),
        model=printer.model(),
        name=printer.hostname(),
    )

    hass.config_entries.async_setup_platforms(entry, PLATFORMS)
    return True
예제 #3
0
class SyncthruHTMLTest(unittest.TestCase):

    server = None
    server_control = None  # type: Server
    port = 0
    url = "http://localhost:80"
    syncthru = None  # type: SyncThru

    def setUp(self) -> None:
        # Create an arbitrary subclass of TCP Server as the server to be started
        # Here, it is an Simple HTTP file serving server
        handler = SyncThruRequestHandler

        max_retries = 10
        r = 0
        while not self.server:
            try:
                # Connect to any open port
                self.server = SyncThruServer((ADDRESS, 0), handler)
            except OSError:
                if r < max_retries:
                    r += 1
                else:
                    raise
                time.sleep(1)

        self.server_control = Server(self.server)
        self.port = self.server_control.get_port()
        self.url = "{}:{}".format(ADDRESS, self.port)
        # Start test server before running any tests
        self.server_control.start_server()

        async def fetch():
            async with aiohttp.ClientSession() as session:
                self.syncthru = SyncThru(
                    self.url, session, connection_mode=ConnectionMode.HTML
                )
                await self.syncthru.update()

        loop = asyncio.get_event_loop()
        loop.run_until_complete(fetch())

    def test_location(self) -> None:
        self.assertEqual(self.syncthru.location(), RAW_HTML["identity"]["location"])

    def test_model_name(self) -> None:
        self.assertEqual(self.syncthru.model(), RAW_HTML["identity"]["model_name"])

    def test_hostname(self) -> None:
        self.assertEqual(self.syncthru.hostname(), RAW_HTML["identity"]["host_name"])

    def test_mac_address(self) -> None:
        self.assertEqual(self.syncthru.mac_address(), RAW_HTML["identity"]["mac_addr"])

    def test_toner_filter(self) -> None:
        self.assertDictEqual(
            self.syncthru.toner_status(True),
            {"black": {"opt": 1, "remaining": 66, "newError": ""}},
        )

    def test_input_tray_filter(self) -> None:
        self.assertDictEqual(
            self.syncthru.input_tray_status(True),
            {
                "tray_1": {
                    "opt": 1,
                    "newError": "",
                }
            },
        )
예제 #4
0
class SyncthruAPITest(unittest.TestCase):

    server = None
    server_control = None  # type: Server
    port = 0
    url = "http://localhost:80"
    syncthru = None  # type: SyncThru

    def setUp(self) -> None:
        # Create an arbitrary subclass of TCP Server as the server to be started
        # Here, it is an Simple HTTP file serving server
        handler = SyncThruRequestHandler

        max_retries = 10
        r = 0
        while not self.server:
            try:
                # Connect to any open port
                self.server = SyncThruServer((ADDRESS, 0), handler)
            except OSError:
                if r < max_retries:
                    r += 1
                else:
                    raise
                time.sleep(1)

        self.server_control = Server(self.server)
        self.port = self.server_control.get_port()
        self.url = "{}:{}".format(ADDRESS, self.port)
        # Start test server before running any tests
        self.server_control.start_server()

        async def fetch():
            async with aiohttp.ClientSession() as session:
                self.syncthru = SyncThru(
                    self.url, session, connection_mode=ConnectionMode.API
                )
                await self.syncthru.update()

        loop = asyncio.get_event_loop()
        loop.run_until_complete(fetch())

    def test_online(self) -> None:
        self.assertTrue(self.syncthru.is_online())

    def test_status_normal(self) -> None:
        self.assertEqual(self.syncthru.device_status(), SyncthruState.NORMAL)

    def test_status_details(self) -> None:
        self.assertEqual(self.syncthru.device_status_details(), "Sleeping...")

    def test_model(self) -> None:
        self.assertEqual(self.syncthru.model(), RAW["identity"]["model_name"])

    def test_toner_filter(self) -> None:
        self.assertDictEqual(
            self.syncthru.toner_status(True),
            {"black": {"opt": 1, "remaining": 58, "cnt": 229, "newError": ""}},
        )

    def test_toner_no_filter(self) -> None:
        empty = {"opt": 0, "remaining": 0, "cnt": 0, "newError": ""}
        self.assertDictEqual(
            self.syncthru.toner_status(False),
            {
                "yellow": empty,
                "magenta": empty,
                "cyan": empty,
                "black": {"opt": 1, "remaining": 58, "cnt": 229, "newError": ""},
            },
        )

    def test_input_tray_filter(self) -> None:
        self.assertDictEqual(
            self.syncthru.input_tray_status(True),
            {
                "tray_1": {
                    "capa": 150,
                    "newError": "",
                    "opt": 1,
                    "paper_size1": 4,
                    "paper_size2": 0,
                    "paper_type1": 2,
                    "paper_type2": 0,
                }
            },
        )

    def test_input_tray_no_filter(self) -> None:
        self.assertDictEqual(
            self.syncthru.input_tray_status(False),
            {
                "tray_1": {
                    "capa": 150,
                    "newError": "",
                    "opt": 1,
                    "paper_size1": 4,
                    "paper_size2": 0,
                    "paper_type1": 2,
                    "paper_type2": 0,
                },
                "tray_2": {
                    "capa": 0,
                    "newError": "",
                    "opt": 0,
                    "paper_size1": 0,
                    "paper_size2": 0,
                    "paper_type1": 2,
                    "paper_type2": 0,
                },
                "tray_3": {
                    "capa": 0,
                    "newError": "",
                    "opt": 0,
                    "paper_size1": 0,
                    "paper_size2": 0,
                    "paper_type1": 2,
                    "paper_type2": 0,
                },
                "tray_4": {
                    "capa": 0,
                    "newError": "",
                    "opt": 2,
                    "paper_size1": 0,
                    "paper_size2": 0,
                    "paper_type1": 2,
                    "paper_type2": 0,
                },
                "tray_5": {
                    "opt": 0,
                    "paper_size1": 0,
                    "paper_size2": 0,
                    "paper_type1": 0,
                    "paper_type2": 0,
                    "capa": 0,
                    "newError": "0",
                },
                "mp": {
                    "opt": 0,
                    "paper_size1": 0,
                    "paper_size2": 0,
                    "paper_type1": 2,
                    "paper_type2": 0,
                    "capa": 0,
                    "newError": "",
                },
                "manual": {
                    "opt": 0,
                    "paper_size1": 0,
                    "paper_size2": 0,
                    "paper_type1": 2,
                    "paper_type2": 0,
                    "capa": 0,
                    "newError": "",
                },
            },
        )

    def test_output_tray(self) -> None:
        self.assertEqual(
            self.syncthru.output_tray_status(),
            {0: {"capacity": 100, "name": 1, "status": ""}},
        )

    def test_drum_status_filter(self) -> None:
        self.assertEqual(self.syncthru.drum_status(True), {})

    def test_drum_status_no_filter(self) -> None:
        self.assertEqual(
            self.syncthru.drum_status(False),
            {
                "black": {"newError": "", "opt": 0, "remaining": 0},
                "cyan": {"newError": "", "opt": 0, "remaining": 100},
                "magenta": {"newError": "", "opt": 0, "remaining": 100},
                "yellow": {"newError": "", "opt": 0, "remaining": 100},
            },
        )

    def test_location(self) -> None:
        self.assertEqual(self.syncthru.location(), RAW["identity"]["location"])

    def test_serial_number(self) -> None:
        self.assertEqual(self.syncthru.serial_number(), RAW["identity"]["serial_num"])

    def test_hostname(self) -> None:
        self.assertEqual(self.syncthru.hostname(), RAW["identity"]["host_name"])

    def test_cap(self) -> None:
        self.assertEqual(self.syncthru.capability(), RAW["capability"])

    def tearDown(self) -> None:
        self.server_control.stop_server()