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")
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)
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
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))
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
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))
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()
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)
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()
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
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
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)
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)
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
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")
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)
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 _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
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) }
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)
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
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
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)
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)
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
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}
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)