示例#1
0
def on_message(client, userdata, msg):
    auth = {
        'username': dataMap["mqtt"]["user"],
        'password': dataMap["mqtt"]["password"]
    }
    topic = str(msg.topic)
    payload = (msg.payload).decode("utf-8")
    state = int(payload)
    print((topic) + " : " + (payload))
    for info in dataMap["fritzBoxMain"]["switches"]:
        if info["setTopic"] == topic:
            command = info["command"]
            print(command + ": " + str(state))
            fc = FritzConnection(dataMap["fritzBoxMain"]["ip"],
                                 password=dataMap["fritzBoxMain"]["password"])
            fc.call_action(command, 'SetEnable', NewEnable=state)
            state = str(int(fc.call_action(command, 'GetInfo')["NewEnable"]))
            print("State: " + state)
            try:
                publish.single(info["getTopic"],
                               payload=state,
                               hostname=dataMap["mqtt"]["serverIP"],
                               auth=auth)
            except Exception as e:
                print('Failed: ' + str(e))
            print("published")
示例#2
0
def main():
  try:
    with open(os.environ['CONFIG_PATH'], 'r') as f:
      conf = yaml.safe_load(f.read())
  except:
    print("Error getting config file")
    exit()

  fc = FritzConnection(conf['fritzbox']['address'])
  if conf['ipv6']['enabled']:
    if conf['ipv6']['target'] == '':
      print('IPv6 is enabled but not target host has been set.')
      exit()

    ipv6_prefix = ':'.join(fc.call_action('WANIPConn1', 'X_AVM_DE_GetIPv6Prefix')['NewIPv6Prefix'].split(':')[0:4])

    external_ipv6 = f"{ ipv6_prefix }:{ conf['ipv6']['target'] }"
  else:
    external_ipv6 = ''

  # print(external_ipv6)
  external_ipv4 = fc.call_action('WANIPConn1', 'GetExternalIPAddress')['NewExternalIPAddress']

  if 'namecheap' in conf:
    c = ncc.NamecheapClient(conf['namecheap'])
  elif 'cloudflare' in conf:
    c = cfc.CloudFlareClient(conf['cloudflare'])
  else:
    exit()

  existing = c.get_dns_records(conf['domain'])

  c.set_dns_records(conf['records'], existing, external_ipv4, external_ipv6)
示例#3
0
    def fritz_tools_init(self) -> str | None:
        """Initialize FRITZ!Box Tools class."""

        try:
            connection = FritzConnection(
                address=self._host,
                port=self._port,
                user=self._username,
                password=self._password,
                timeout=60.0,
                pool_maxsize=30,
            )
        except FritzSecurityError:
            return ERROR_AUTH_INVALID
        except FritzConnectionException:
            return ERROR_CANNOT_CONNECT
        except Exception:  # pylint: disable=broad-except
            _LOGGER.exception("Unexpected exception")
            return ERROR_UNKNOWN

        self._model = connection.call_action("DeviceInfo:1",
                                             "GetInfo")["NewModelName"]

        if ("X_AVM-DE_UPnP1" in connection.services
                and not connection.call_action("X_AVM-DE_UPnP1",
                                               "GetInfo")["NewEnable"]):
            return ERROR_UPNP_NOT_CONFIGURED

        return None
示例#4
0
 def __init__(self,
              address='192.168.178.1',
              user='******',
              password='******',
              knownCallId=0):
     """
     Parameters
     ----------
         address : str
             IP of FritzBox
         user : str
             FritzBox credential
         password : str
             FritzBox credential
         knownCallId : str | int
             ID of the last processed call (process only newer)
     """
     self.CHECKCALLLIST_INITDATA = {
         'address': address,
         'password': password,
         'user': user,
         'knownCallId': knownCallId
     }
     self.connection = FritzConnection(address=address,
                                       user=user,
                                       password=password)
     self.knownCallId = int(knownCallId)
def print_values():
    server = os.environ['fritzbox_ip']
    if 'fritzbox_port' in os.environ:
        port = os.environ['fritzbox_port']
    else:
        port = None
    if 'fritzbox_user' in os.environ:
        user = os.environ['fritzbox_user']
    else:
        user = None
    if 'fritzbox_password' in os.environ:
        password = os.environ['fritzbox_password']
    else:
        password = None

    try:
        conn = FritzConnection(address=server,
                               port=port,
                               user=user,
                               password=password)
    except Exception as e:
        sys.exit("Couldn't get connection uptime", e)

    uptime = conn.call_action('WANIPConn', 'GetStatusInfo')['NewUptime']
    print('uptime.value %.2f' % (int(uptime) / 86400.0))
示例#6
0
    def setup(self) -> None:
        """Set up FritzboxTools class."""
        self.connection = FritzConnection(
            address=self.host,
            port=self.port,
            user=self.username,
            password=self.password,
            timeout=60.0,
            pool_maxsize=30,
        )

        if not self.connection:
            _LOGGER.error("Unable to establish a connection with %s",
                          self.host)
            return

        self.fritz_status = FritzStatus(fc=self.connection)
        info = self.connection.call_action("DeviceInfo:1", "GetInfo")
        if not self._unique_id:
            self._unique_id = info["NewSerialNumber"]

        self._model = info.get("NewModelName")
        self._current_firmware = info.get("NewSoftwareVersion")

        self._update_available, self._latest_firmware = self._update_device_info(
        )
    def _try_connect(self):
        """Try to connect and check auth."""
        self._fritzbox_phonebook = FritzBoxPhonebook(
            host=self._host,
            username=self._username,
            password=self._password,
            phonebook_id=self._phonebook_id,
            prefixes=self._prefixes,
        )

        try:
            self._fritzbox_phonebook.init_phonebook()
            self._phonebook_ids = self._fritzbox_phonebook.get_phonebook_ids()

            fritz_connection = FritzConnection(address=self._host,
                                               user=self._username,
                                               password=self._password)
            device_info = fritz_connection.call_action(
                FRITZ_SERVICE_DEVICE_INFO, FRITZ_ACTION_GET_INFO)
            self._serial_number = device_info[FRITZ_ATTR_SERIAL_NUMBER]

            return RESULT_SUCCESS
        except RequestsConnectionError:
            return RESULT_NO_DEVIES_FOUND
        except FritzSecurityError:
            return RESULT_INSUFFICIENT_PERMISSIONS
        except FritzConnectionException:
            return RESULT_INVALID_AUTH
示例#8
0
def print_uptime():
    try:
        conn = FritzConnection(address=os.environ['fritzbox_ip'])
    except Exception as e:
        sys.exit("Couldn't get connection uptime")

    uptime = conn.call_action('WANIPConnection', 'GetStatusInfo')['NewUptime']
    print('uptime.value %.2f' % (int(uptime) / 86400.0))
def print_values():
    try:
        conn = FritzConnection()
    except Exception as e:
        sys.exit("Couldn't get connection uptime")

    uptime = conn.call_action('WANIPConnection', 'GetStatusInfo')['NewUptime']
    print('uptime.value %.2f' % (int(uptime) / 86400.0))
def print_values():
    try:
        conn = FritzConnection(address=os.environ['fritzbox_ip'])
    except Exception as e:
        sys.exit("Couldn't get connection uptime")

    uptime = conn.call_action('WANIPConnection', 'GetStatusInfo')['NewUptime']
    print('uptime.value %.2f' % (int(uptime) / 86400.0))
示例#11
0
    def __init__(
        self,
        password,
        username = DEFAULT_USERNAME,
        host = DEFAULT_HOST,
        port=DEFAULT_PORT,
        profile_on = DEFAULT_PROFILE_ON,
        profile_off = DEFAULT_PROFILE_OFF,
        device_list = DEFAULT_DEVICES,
        use_port = DEFAULT_USE_PORT,
        use_deflections = DEFAULT_USE_DEFLECTIONS,
        use_wifi = DEFAULT_USE_WIFI,
        use_devices = DEFAULT_USE_DEVICES,
    ):
        # pylint: disable=import-error
        from fritzconnection import FritzConnection
        from fritzconnection.lib.fritzstatus import FritzStatus
        from fritz_switch_profiles import FritzProfileSwitch

        # general timeout for all requests to the router. Some calls need quite some time.
        self.connection = FritzConnection(
            address=host, port=port, user=username, password=password, timeout=30.0
        )

        if device_list != DEFAULT_DEVICES:
            self.profile_switch = FritzProfileSwitch(
                "http://" + host, username, password
            )

        self.fritzstatus = FritzStatus(fc=self.connection)
        self.ha_ip = get_local_ip()
        self.profile_on = profile_on
        self.profile_off = profile_off
        self.profile_last_updated = time.time()
        self.device_list = device_list

        self.username = username
        self.password = password
        self.port = port
        self.host = host

        self.use_wifi = use_wifi
        self.use_port = use_port
        self.use_deflections = use_deflections
        self.use_devices = use_devices

        self._unique_id = self.connection.call_action("DeviceInfo:1", "GetInfo")[
            "NewSerialNumber"
        ]
        self._device_info = self._fetch_device_info()
示例#12
0
class FritzDevice():
    def __init__(self, host, user, password) -> None:
        self.host = host
        self.serial = "n/a"
        self.model = "n/a"

        try:
            self.fc = FritzConnection(address=host,
                                      user=user,
                                      password=password)
        except ConnectionError as e:
            logger.critical(f'unable to connect to {host}: {str(e)}',
                            exc_info=True)
            sys.exit(1)

        self.capabilities = FritzCapabilities(self)

        self.getDeviceInfo()

        if self.capabilities.empty():
            logger.critical(
                f'Device {host} has no detected capabilities. Exiting. ')
            sys.exit(1)

    def getDeviceInfo(self):
        try:
            device_info = self.fc.call_action('DeviceInfo', 'GetInfo')
            self.serial = device_info['NewSerialNumber']
            self.model = device_info['NewModelName']

        except (FritzServiceError, FritzActionError):
            logger.error(
                f'Fritz Device {self.host} does not provide basic device info (Service: DeviceInfo1, Action: GetInfo). serial number and model name will be unavailable.',
                exc_info=True)
示例#13
0
    def setup(self):
        """Set up FritzboxTools class."""
        self.connection = FritzConnection(
            address=self.host,
            port=self.port,
            user=self.username,
            password=self.password,
            timeout=60.0,
        )

        self.fritzstatus = FritzStatus(fc=self.connection)
        if self._unique_id is None:
            self._unique_id = self.connection.call_action(
                "DeviceInfo:1", "GetInfo")["NewSerialNumber"]

        self._device_info = self._fetch_device_info()
示例#14
0
文件: common.py 项目: liann1991/core
    def setup(self) -> None:
        """Set up FritzboxTools class."""
        self.connection = FritzConnection(
            address=self.host,
            port=self.port,
            user=self.username,
            password=self.password,
            timeout=60.0,
            pool_maxsize=30,
        )

        if not self.connection:
            _LOGGER.error("Unable to establish a connection with %s",
                          self.host)
            return

        _LOGGER.debug(
            "detected services on %s %s",
            self.host,
            list(self.connection.services.keys()),
        )

        self.fritz_hosts = FritzHosts(fc=self.connection)
        self.fritz_status = FritzStatus(fc=self.connection)
        info = self.connection.call_action("DeviceInfo:1", "GetInfo")

        _LOGGER.debug(
            "gathered device info of %s %s",
            self.host,
            {
                **info,
                "NewDeviceLog": "***omitted***",
                "NewSerialNumber": "***omitted***",
            },
        )

        if not self._unique_id:
            self._unique_id = info["NewSerialNumber"]

        self._model = info.get("NewModelName")
        self._current_firmware = info.get("NewSoftwareVersion")

        self._update_available, self._latest_firmware = self._update_device_info(
        )
        self.device_is_router = "WANIPConn1" in self.connection.services
示例#15
0
    def setup(self):
        """Set up FritzboxTools class."""
        self.connection = FritzConnection(
            address=self.host,
            port=self.port,
            user=self.username,
            password=self.password,
            timeout=60.0,
        )

        self.fritz_status = FritzStatus(fc=self.connection)
        info = self.connection.call_action("DeviceInfo:1", "GetInfo")
        if self._unique_id is None:
            self._unique_id = info["NewSerialNumber"]

        self.model = info.get("NewModelName")
        self.sw_version = info.get("NewSoftwareVersion")
        self.mac = self.unique_id
def retrieveSmartHomeTemps():
    smartHomeData = []
    config = FritzboxConfig()

    try:
      connection = FritzConnection(address=config.server, password=config.password, use_tls=config.useTls)
    except Exception as e:
      sys.exit("Couldn't get temperature: " + str(e))

    for i in range(0, 20):
      try:
        data = connection.call_action('X_AVM-DE_Homeauto1', 'GetGenericDeviceInfos', arguments={'NewIndex': i})
        if (data['NewTemperatureIsEnabled']):
          smartHomeData.append(data)
      except Exception as e:
        # smart home device index does not exist, so we stop here
        break

    return smartHomeData
示例#17
0
def print_values():
    try:
        conn = FritzConnection()
    except Exception as e:
        sys.exit("Couldn't get WAN traffic")

    down_traffic = conn.call_action('WANCommonInterfaceConfig', 'GetTotalBytesReceived')['NewTotalBytesReceived']
    print ('down.value %d' % down_traffic)

    up_traffic = conn.call_action('WANCommonInterfaceConfig', 'GetTotalBytesSent')['NewTotalBytesSent']
    print ('up.value %d' % up_traffic)

    max_down_traffic = conn.call_action('WANCommonInterfaceConfig', 'GetCommonLinkProperties')[
        'NewLayer1DownstreamMaxBitRate']
    print ('maxdown.value %d' % max_down_traffic)

    max_up_traffic = conn.call_action('WANCommonInterfaceConfig', 'GetCommonLinkProperties')[
        'NewLayer1UpstreamMaxBitRate']
    print ('maxup.value %d' % max_up_traffic)
示例#18
0
 def get_connection(self):
     if self.services == '':
         return FritzConnection(address=self.address,
                                port=self.port,
                                user=self.user,
                                password=self.password,
                                protocol='https',
                                path='tr064/',
                                descfiles=['tr64desc.xml'])
     else:
         _logger.debug('We have following JSON: %s' % self[0].services)
         return FritzConnection(address=self.address,
                                port=self.port,
                                user=self.user,
                                password=self.password,
                                protocol='https',
                                path='tr064/',
                                descfiles=['tr64desc.xml'],
                                services_json=self.services)
示例#19
0
def get_values():
    try:
        conn = FritzConnection(address='192.168.178.1')
    except Exception as e:
        print("cannot connect to fritzbox")

    info = conn.call_action('WANCommonIFC', 'GetAddonInfos')

    collection = []

    currentDownstream = info["NewByteReceiveRate"]
    collection.append(get_json("WANTraffic", currentDownstream, "fritzbox", "down", "current"))
    currentUpstream = info["NewByteSendRate"]
    collection.append(get_json("WANTraffic", currentUpstream, "fritzbox", "up", "current"))
    totalDownstream = int(info["NewX_AVM_DE_TotalBytesReceived64"])
    collection.append(get_json("WANTraffic", totalDownstream, "fritzbox", "down", "total"))
    totalUpstream =  int(info["NewX_AVM_DE_TotalBytesSent64"])
    collection.append(get_json("WANTraffic", totalUpstream, "fritzbox", "up", "total"))

    return collection
示例#20
0
 def fbGetFc(self):
     if (isNotBlank(self.user) and isNotBlank(self.password)):
         #  first try with fritz status
         if (self.fcStatus):
             self.fc = self.fcStatus.fc
         if (self.fc is None):
             self.fc = FritzConnection(address=self.host,
                                       user=self.user,
                                       password=self.password)
         return self.fc
     else:
         raise Exception("ConfigError - Password and User required")
示例#21
0
def print_values():
    try:
        conn = FritzConnection(address=os.environ['fritzbox_ip'])
    except Exception as e:
        sys.exit("Couldn't get WAN traffic")

    down_traffic = conn.call_action(
        'WANCommonInterfaceConfig',
        'GetTotalBytesReceived')['NewTotalBytesReceived']
    print('down.value %d' % down_traffic)

    up_traffic = conn.call_action('WANCommonInterfaceConfig',
                                  'GetTotalBytesSent')['NewTotalBytesSent']
    print('up.value %d' % up_traffic)

    if not os.environ.get('traffic_remove_max'):
        max_down_traffic = conn.call_action(
            'WANCommonInterfaceConfig',
            'GetCommonLinkProperties')['NewLayer1DownstreamMaxBitRate']
        print('maxdown.value %d' % max_down_traffic)

        max_up_traffic = conn.call_action(
            'WANCommonInterfaceConfig',
            'GetCommonLinkProperties')['NewLayer1UpstreamMaxBitRate']
        print('maxup.value %d' % max_up_traffic)
示例#22
0
    def __init__(self, host, user, password) -> None:
        self.host = host
        self.serial = "n/a"
        self.model = "n/a"

        try:
            self.fc = FritzConnection(address=host,
                                      user=user,
                                      password=password)
        except ConnectionError as e:
            logger.critical(f'unable to connect to {host}: {str(e)}',
                            exc_info=True)
            sys.exit(1)

        self.capabilities = FritzCapabilities(self)

        self.getDeviceInfo()

        if self.capabilities.empty():
            logger.critical(
                f'Device {host} has no detected capabilities. Exiting. ')
            sys.exit(1)
示例#23
0
    def _probe(self) -> Optional[ValueSet]:
        connection = FritzConnection(address=self._address, password=self._pass, timeout=10)
        new_data = {}
        service_name = 'WANCommonInterfaceConfig:1'
        if service_name not in connection.services:
            # Use legacy fallback
            service_name = 'WANCommonIFC1'
        output = connection.call_action(service_name, 'GetTotalBytesReceived')
        new_data['recv_bytes_sec'] = output['NewTotalBytesReceived']

        output = connection.call_action(service_name, 'GetTotalBytesSent')
        new_data['sent_bytes_sec'] = output['NewTotalBytesSent']

        data = ValueSet()
        for key, value in new_data.items():
            last_stats = self._stats.get(key)
            self._stats[key] = value
            if last_stats is not None:
                time_delta = int(time.time() - self._last_time)
                data.add(Value(max(0, (value - last_stats) / time_delta), name=key))

        self._last_time = time.time()
        return data
示例#24
0
    def setup(self) -> None:
        """Set up FritzboxTools class."""
        self.connection = FritzConnection(
            address=self.host,
            port=self.port,
            user=self.username,
            password=self.password,
            timeout=60.0,
        )

        self.fritz_status = FritzStatus(fc=self.connection)
        info = self.connection.call_action("DeviceInfo:1", "GetInfo")
        if not self._unique_id:
            self._unique_id = info["NewSerialNumber"]

        self._model = info.get("NewModelName")
        self._sw_version = info.get("NewSoftwareVersion")

        self.fritz_profiles = {
            profile: FritzProfileSwitch("http://" + self.host, self.username,
                                        self.password, profile)
            for profile in get_all_profiles(self.host, self.username,
                                            self.password)
        }
示例#25
0
class FritzDevice(object):

    fc = None
    ip = None
    password = None

    def __init__(self, ip, password):
        from fritzconnection import FritzConnection
        self.fc = FritzConnection(address=ip, password=password)
        self.ip = ip
        self.password = password

    def get_data(self, service, action):
        return self.fc.call_action(service, action)

    @property
    def services(self):
        import fritzconnection as _fc
        return _fc.print_api(address=self.ip, password=self.password)
示例#26
0
 def __init__(self, ff_config):
     self.fc = FritzConnection(address=ff_config["fb_address"],
                               user=ff_config["fb_user"],
                               password=ff_config["fb_pass"])
     self.fs = FritzStatus(self.fc)
     self.fh = FritzHomeAutomation(self.fc)
     self.ic = []
     for iconfig in ff_config["influxdb_connections"]:
         if is_influx2_db(iconfig):
             self.ic.append(
                 InfluxDBClient(url=iconfig["url"], token=iconfig["token"]))
         else:
             self.ic.append(
                 influxdb.InfluxDBClient(host=iconfig["address"],
                                         port=iconfig["port"],
                                         username=iconfig["user"],
                                         password=iconfig["pass"],
                                         database=iconfig["database"]))
     self.config = ff_config
示例#27
0
def get_list_from_device(conn: fritzconnection.FritzConnection) -> list:
    """
    Fetches the logfile from the connected device
    and turns it into a list of LogEntry objects.

    Args:
        conn (fritzconnection.FritzConnection): Connection object to connect to.

    Returns:
        log_entries (list): List of LogEntry objects created
        from the devices' logfile, sorted by timestamp.
    """

    log_dict = conn.call_action("DeviceInfo1", "GetDeviceLog")
    log_lines = log_dict.get("NewDeviceLog", "").split("\n")

    log_entries = []

    for line in log_lines:
        log_entries.append(classes.LogEntry(logstring=line, msg_offset=18))

    log_entries.sort(key=lambda entry: entry.timestamp)

    return log_entries
示例#28
0
def print_values():
    server = os.environ['fritzbox_ip']
    if 'fritzbox_port' in os.environ:
        port = os.environ['fritzbox_port']
    else:
        port = None
    if 'fritzbox_user' in os.environ:
        user = os.environ['fritzbox_user']
    else:
        user = None
    if 'fritzbox_password' in os.environ:
        password = os.environ['fritzbox_password']
    else:
        password = None

    try:
        conn = FritzConnection(address=os.environ['fritzbox_ip'],
                               port=port,
                               user=user,
                               password=password)
    except Exception as e:
        sys.exit("Couldn't get WAN traffic")

    down_traffic = conn.call_action(
        'WANCommonIFC', 'GetTotalBytesReceived')['NewTotalBytesReceived']
    print('down.value %d' % down_traffic)

    up_traffic = conn.call_action('WANCommonIFC',
                                  'GetTotalBytesSent')['NewTotalBytesSent']
    print('up.value %d' % up_traffic)

    if not os.environ.get('traffic_remove_max'):
        max_down_traffic = conn.call_action(
            'WANCommonIFC',
            'GetCommonLinkProperties')['NewLayer1DownstreamMaxBitRate']
        print('maxdown.value %d' % max_down_traffic)

        max_up_traffic = conn.call_action(
            'WANCommonIFC',
            'GetCommonLinkProperties')['NewLayer1UpstreamMaxBitRate']
        print('maxup.value %d' % max_up_traffic)
示例#29
0
class FritzBoxTools(update_coordinator.DataUpdateCoordinator):
    """FrtizBoxTools class."""
    def __init__(
        self,
        hass: HomeAssistant,
        password: str,
        username: str = DEFAULT_USERNAME,
        host: str = DEFAULT_HOST,
        port: int = DEFAULT_PORT,
    ) -> None:
        """Initialize FritzboxTools class."""
        super().__init__(
            hass=hass,
            logger=_LOGGER,
            name=f"{DOMAIN}-{host}-coordinator",
            update_interval=timedelta(seconds=30),
        )

        self._devices: dict[str, FritzDevice] = {}
        self._options: MappingProxyType[str, Any] | None = None
        self._unique_id: str | None = None
        self.connection: FritzConnection = None
        self.fritz_hosts: FritzHosts = None
        self.fritz_status: FritzStatus = None
        self.hass = hass
        self.host = host
        self.password = password
        self.port = port
        self.username = username
        self._mac: str | None = None
        self._model: str | None = None
        self._current_firmware: str | None = None
        self._latest_firmware: str | None = None
        self._update_available: bool = False

    async def async_setup(self,
                          options: MappingProxyType[str, Any] | None = None
                          ) -> None:
        """Wrap up FritzboxTools class setup."""
        self._options = options
        await self.hass.async_add_executor_job(self.setup)

    def setup(self) -> None:
        """Set up FritzboxTools class."""
        self.connection = FritzConnection(
            address=self.host,
            port=self.port,
            user=self.username,
            password=self.password,
            timeout=60.0,
            pool_maxsize=30,
        )

        if not self.connection:
            _LOGGER.error("Unable to establish a connection with %s",
                          self.host)
            return

        self.fritz_status = FritzStatus(fc=self.connection)
        info = self.connection.call_action("DeviceInfo:1", "GetInfo")
        if not self._unique_id:
            self._unique_id = info["NewSerialNumber"]

        self._model = info.get("NewModelName")
        self._current_firmware = info.get("NewSoftwareVersion")

        self._update_available, self._latest_firmware = self._update_device_info(
        )

    @callback
    async def _async_update_data(self) -> None:
        """Update FritzboxTools data."""
        try:
            self.fritz_hosts = FritzHosts(fc=self.connection)
            await self.async_scan_devices()
        except (FritzSecurityError, FritzConnectionException) as ex:
            raise update_coordinator.UpdateFailed from ex

    @property
    def unique_id(self) -> str:
        """Return unique id."""
        if not self._unique_id:
            raise ClassSetupMissing()
        return self._unique_id

    @property
    def model(self) -> str:
        """Return device model."""
        if not self._model:
            raise ClassSetupMissing()
        return self._model

    @property
    def current_firmware(self) -> str:
        """Return current SW version."""
        if not self._current_firmware:
            raise ClassSetupMissing()
        return self._current_firmware

    @property
    def latest_firmware(self) -> str | None:
        """Return latest SW version."""
        return self._latest_firmware

    @property
    def update_available(self) -> bool:
        """Return if new SW version is available."""
        return self._update_available

    @property
    def mac(self) -> str:
        """Return device Mac address."""
        if not self._unique_id:
            raise ClassSetupMissing()
        return self._unique_id

    @property
    def devices(self) -> dict[str, FritzDevice]:
        """Return devices."""
        return self._devices

    @property
    def signal_device_new(self) -> str:
        """Event specific per FRITZ!Box entry to signal new device."""
        return f"{DOMAIN}-device-new-{self._unique_id}"

    @property
    def signal_device_update(self) -> str:
        """Event specific per FRITZ!Box entry to signal updates in devices."""
        return f"{DOMAIN}-device-update-{self._unique_id}"

    def _update_hosts_info(self) -> list[HostInfo]:
        """Retrieve latest hosts information from the FRITZ!Box."""
        try:
            return self.fritz_hosts.get_hosts_info(
            )  # type: ignore [no-any-return]
        except Exception as ex:  # pylint: disable=[broad-except]
            if not self.hass.is_stopping:
                raise HomeAssistantError("Error refreshing hosts info") from ex
        return []

    def _update_device_info(self) -> tuple[bool, str | None]:
        """Retrieve latest device information from the FRITZ!Box."""
        version = self.connection.call_action(
            "UserInterface1", "GetInfo").get("NewX_AVM-DE_Version")
        return bool(version), version

    async def async_scan_devices(self, now: datetime | None = None) -> None:
        """Wrap up FritzboxTools class scan."""
        await self.hass.async_add_executor_job(self.scan_devices, now)

    def scan_devices(self, now: datetime | None = None) -> None:
        """Scan for new devices and return a list of found device ids."""
        _LOGGER.debug("Checking devices for FRITZ!Box router %s", self.host)

        _default_consider_home = DEFAULT_CONSIDER_HOME.total_seconds()
        if self._options:
            consider_home = self._options.get(CONF_CONSIDER_HOME,
                                              _default_consider_home)
        else:
            consider_home = _default_consider_home

        new_device = False
        for known_host in self._update_hosts_info():
            if not known_host.get("mac"):
                continue

            dev_mac = known_host["mac"]
            dev_name = known_host["name"]
            dev_ip = known_host["ip"]
            dev_home = known_host["status"]
            dev_wan_access = True
            if dev_ip:
                wan_access = self.connection.call_action(
                    "X_AVM-DE_HostFilter:1",
                    "GetWANAccessByIP",
                    NewIPv4Address=dev_ip,
                )
                if wan_access:
                    dev_wan_access = not wan_access.get("NewDisallow")

            dev_info = Device(dev_mac, dev_ip, dev_name, dev_wan_access)

            if dev_mac in self._devices:
                self._devices[dev_mac].update(dev_info, dev_home,
                                              consider_home)
            else:
                device = FritzDevice(dev_mac, dev_name)
                device.update(dev_info, dev_home, consider_home)
                self._devices[dev_mac] = device
                new_device = True

        dispatcher_send(self.hass, self.signal_device_update)
        if new_device:
            dispatcher_send(self.hass, self.signal_device_new)

        _LOGGER.debug("Checking host info for FRITZ!Box router %s", self.host)
        self._update_available, self._latest_firmware = self._update_device_info(
        )

    async def async_trigger_firmware_update(self) -> bool:
        """Trigger firmware update."""
        results = await self.hass.async_add_executor_job(
            self.connection.call_action, "UserInterface:1",
            "X_AVM-DE_DoUpdate")
        return cast(bool, results["NewX_AVM-DE_UpdateState"])

    async def async_trigger_reboot(self) -> None:
        """Trigger device reboot."""
        await self.hass.async_add_executor_job(self.connection.call_action,
                                               "DeviceConfig1", "Reboot")

    async def async_trigger_reconnect(self) -> None:
        """Trigger device reconnect."""
        await self.hass.async_add_executor_job(self.connection.call_action,
                                               "WANIPConn1",
                                               "ForceTermination")

    async def service_fritzbox(self, service_call: ServiceCall,
                               config_entry: ConfigEntry) -> None:
        """Define FRITZ!Box services."""
        _LOGGER.debug("FRITZ!Box router: %s", service_call.service)

        if not self.connection:
            raise HomeAssistantError("Unable to establish a connection")

        try:
            if service_call.service == SERVICE_REBOOT:
                _LOGGER.warning(
                    'Service "fritz.reboot" is deprecated, please use the corresponding button entity instead'
                )
                await self.hass.async_add_executor_job(
                    self.connection.call_action, "DeviceConfig1", "Reboot")
                return

            if service_call.service == SERVICE_RECONNECT:
                _LOGGER.warning(
                    'Service "fritz.reconnect" is deprecated, please use the corresponding button entity instead'
                )
                await self.hass.async_add_executor_job(
                    self.connection.call_action,
                    "WANIPConn1",
                    "ForceTermination",
                )
                return

            if service_call.service == SERVICE_CLEANUP:
                device_hosts_list: list = await self.hass.async_add_executor_job(
                    self.fritz_hosts.get_hosts_info)

        except (FritzServiceError, FritzActionError) as ex:
            raise HomeAssistantError("Service or parameter unknown") from ex
        except FritzConnectionException as ex:
            raise HomeAssistantError("Service not supported") from ex

        entity_reg: EntityRegistry = (
            await self.hass.helpers.entity_registry.async_get_registry())

        ha_entity_reg_list: list[
            RegistryEntry] = self.hass.helpers.entity_registry.async_entries_for_config_entry(
                entity_reg, config_entry.entry_id)
        entities_removed: bool = False

        device_hosts_macs = {device["mac"] for device in device_hosts_list}

        for entry in ha_entity_reg_list:
            if (not _cleanup_entity_filter(entry)
                    or entry.unique_id.split("_")[0] in device_hosts_macs):
                continue
            _LOGGER.info("Removing entity: %s", entry.name
                         or entry.original_name)
            entity_reg.async_remove(entry.entity_id)
            entities_removed = True

        if entities_removed:
            self._async_remove_empty_devices(entity_reg, config_entry)

    @callback
    def _async_remove_empty_devices(self, entity_reg: EntityRegistry,
                                    config_entry: ConfigEntry) -> None:
        """Remove devices with no entities."""

        device_reg = async_get(self.hass)
        device_list = async_entries_for_config_entry(device_reg,
                                                     config_entry.entry_id)
        for device_entry in device_list:
            if not async_entries_for_device(
                    entity_reg,
                    device_entry.id,
                    include_disabled_entities=True,
            ):
                _LOGGER.info("Removing device: %s", device_entry.name)
                device_reg.async_remove_device(device_entry.id)
示例#30
0
class FritzBoxTools:
    """FrtizBoxTools class."""
    def __init__(
        self,
        hass: HomeAssistant,
        password: str,
        username: str = DEFAULT_USERNAME,
        host: str = DEFAULT_HOST,
        port: int = DEFAULT_PORT,
    ) -> None:
        """Initialize FritzboxTools class."""
        self._cancel_scan: CALLBACK_TYPE | None = None
        self._devices: dict[str, Any] = {}
        self._options: MappingProxyType[str, Any] | None = None
        self._unique_id: str | None = None
        self.connection: FritzConnection = None
        self.fritz_hosts: FritzHosts = None
        self.fritz_profiles: dict[str, FritzProfileSwitch] = {}
        self.fritz_status: FritzStatus = None
        self.hass = hass
        self.host = host
        self.password = password
        self.port = port
        self.username = username
        self._mac: str | None = None
        self._model: str | None = None
        self._sw_version: str | None = None

    async def async_setup(self) -> None:
        """Wrap up FritzboxTools class setup."""
        await self.hass.async_add_executor_job(self.setup)

    def setup(self) -> None:
        """Set up FritzboxTools class."""
        self.connection = FritzConnection(
            address=self.host,
            port=self.port,
            user=self.username,
            password=self.password,
            timeout=60.0,
        )

        self.fritz_status = FritzStatus(fc=self.connection)
        info = self.connection.call_action("DeviceInfo:1", "GetInfo")
        if not self._unique_id:
            self._unique_id = info["NewSerialNumber"]

        self._model = info.get("NewModelName")
        self._sw_version = info.get("NewSoftwareVersion")

        self.fritz_profiles = {
            profile: FritzProfileSwitch("http://" + self.host, self.username,
                                        self.password, profile)
            for profile in get_all_profiles(self.host, self.username,
                                            self.password)
        }

    async def async_start(self, options: MappingProxyType[str, Any]) -> None:
        """Start FritzHosts connection."""
        self.fritz_hosts = FritzHosts(fc=self.connection)
        self._options = options
        await self.hass.async_add_executor_job(self.scan_devices)

        self._cancel_scan = async_track_time_interval(
            self.hass, self.scan_devices,
            timedelta(seconds=TRACKER_SCAN_INTERVAL))

    @callback
    def async_unload(self) -> None:
        """Unload FritzboxTools class."""
        _LOGGER.debug("Unloading FRITZ!Box router integration")
        if self._cancel_scan is not None:
            self._cancel_scan()
            self._cancel_scan = None

    @property
    def unique_id(self) -> str:
        """Return unique id."""
        if not self._unique_id:
            raise ClassSetupMissing()
        return self._unique_id

    @property
    def model(self) -> str:
        """Return device model."""
        if not self._model:
            raise ClassSetupMissing()
        return self._model

    @property
    def sw_version(self) -> str:
        """Return SW version."""
        if not self._sw_version:
            raise ClassSetupMissing()
        return self._sw_version

    @property
    def mac(self) -> str:
        """Return device Mac address."""
        if not self._unique_id:
            raise ClassSetupMissing()
        return self._unique_id

    @property
    def devices(self) -> dict[str, Any]:
        """Return devices."""
        return self._devices

    @property
    def signal_device_new(self) -> str:
        """Event specific per FRITZ!Box entry to signal new device."""
        return f"{DOMAIN}-device-new-{self._unique_id}"

    @property
    def signal_device_update(self) -> str:
        """Event specific per FRITZ!Box entry to signal updates in devices."""
        return f"{DOMAIN}-device-update-{self._unique_id}"

    def _update_info(self) -> list[HostInfo]:
        """Retrieve latest information from the FRITZ!Box."""
        return self.fritz_hosts.get_hosts_info()

    def scan_devices(self, now: datetime | None = None) -> None:
        """Scan for new devices and return a list of found device ids."""
        _LOGGER.debug("Checking devices for FRITZ!Box router %s", self.host)

        if self._options:
            consider_home = self._options.get(
                CONF_CONSIDER_HOME, DEFAULT_CONSIDER_HOME.total_seconds())
        else:
            consider_home = DEFAULT_CONSIDER_HOME

        new_device = False
        for known_host in self._update_info():
            if not known_host.get("mac"):
                continue

            dev_mac = known_host["mac"]
            dev_name = known_host["name"]
            dev_ip = known_host["ip"]
            dev_home = known_host["status"]

            dev_info = Device(dev_mac, dev_ip, dev_name)

            if dev_mac in self._devices:
                self._devices[dev_mac].update(dev_info, dev_home,
                                              consider_home)
            else:
                device = FritzDevice(dev_mac, dev_name)
                device.update(dev_info, dev_home, consider_home)
                self._devices[dev_mac] = device
                new_device = True

        dispatcher_send(self.hass, self.signal_device_update)
        if new_device:
            dispatcher_send(self.hass, self.signal_device_new)

    async def service_fritzbox(self, service: str) -> None:
        """Define FRITZ!Box services."""
        _LOGGER.debug("FRITZ!Box router: %s", service)

        if not self.connection:
            raise HomeAssistantError("Unable to establish a connection")

        try:
            if service == SERVICE_REBOOT:
                await self.hass.async_add_executor_job(
                    self.connection.call_action, "DeviceConfig1", "Reboot")
            elif service == SERVICE_RECONNECT:
                await self.hass.async_add_executor_job(
                    self.connection.call_action,
                    "WANIPConn1",
                    "ForceTermination",
                )
        except (FritzServiceError, FritzActionError) as ex:
            raise HomeAssistantError("Service or parameter unknown") from ex
        except FritzConnectionException as ex:
            raise HomeAssistantError("Service not supported") from ex
示例#31
0
                    help="Code to be received")
parser.add_argument('--fritzbox_ip', dest='fritzbox_ip', type=str,
                    help="IP address of Fritzbox")
parser.add_argument('--fritzbox_password', dest='fritzbox_password', type=str,
                    help="Password of Fritzbox")
parser.add_argument('--fritzbox_phone', dest='fritzbox_phone', type=str,
                    help="Phone number to call")
args = parser.parse_args()

item_address = "http://" + args.openhab_ip + ":8080/rest/items/" + args.item
signal.signal(signal.SIGINT, exithandler)
rfdevice = RFDevice(args.gpio)
rfdevice.enable_rx()

if args.fritzbox_ip:
    fritz_connection = FritzConnection(address=args.fritzbox_ip, password=args.fritzbox_password)
    logging.info("Established connection to Fritzbox")

timestamp = None
logging.info("Listening for codes on GPIO " + str(args.gpio))
while True:
    if rfdevice.rx_code_timestamp != timestamp:
        timestamp = rfdevice.rx_code_timestamp
        logging.info(str(rfdevice.rx_code) +
                     " [pulselength " + str(rfdevice.rx_pulselength) +
                     ", protocol " + str(rfdevice.rx_proto) + "]")
        if(str(rfdevice.rx_code) == args.code):
            logging.info("Sending RestAPI Post to Openhab")
            resp = requests.post(item_address, data='ON', headers={'Content-Type': 'text/plain', 'Accept': 'application/json'})
            if fritz_connection:
                arg = {'NewX_AVM-DE_PhoneNumber': args.fritzbox_phone}
示例#32
0
from fritzconnection import FritzConnection
import inspect,os
import time
import datetime
import setproctitle
setproctitle.setproctitle('py3-publishFritzbox')




path = (os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))))
with open(path+'/config.yaml') as f:
  dataMap = yaml.safe_load(f)

auth = {'username':dataMap["mqtt"]["user"], 'password':dataMap["mqtt"]["password"]}
fc = FritzConnection(dataMap["fritzBoxMain"]["ip"],password=dataMap["fritzBoxMain"]["password"])

for info in dataMap["fritzBoxMain"]["switches"]:
  wlan = str(  int( fc.call_action(info["command"], 'GetInfo')["NewEnable"] )  )
  publish.single(info["getTopic"], payload=wlan, hostname=dataMap["mqtt"]["serverIP"], auth=auth)

"""
state = fc.call_action('WLANConfiguration2', 'GetInfo')
wlan2 = state["NewEnable"]
state = fc.call_action('WLANConfiguration3', 'GetInfo')
wlan3 = state["NewEnable"]
#fc.call_action('WLANConfiguration1', 'SetEnable', NewEnable=1)
#fc.call_action('WLANConfiguration2', 'SetEnable', NewEnable=1)