@@ -1802,37 +1802,37 @@ def deregister_service(self, service: str, namespace: str | None = None) -> bool
18021802 return self .AD .services .deregister_service (namespace , * service .split ("/" ), __name = self .name )
18031803
18041804 def list_services (self , namespace : str = "global" ) -> list [dict [str , str ]]:
1805- """List all services available within AD
1806-
1807- Using this function, an App can request all available services within AD
1805+ """List all services available within AppDaemon
18081806
18091807 Args:
1810- namespace(str, optional): If a `namespace` is provided, AppDaemon will request
1811- the services within the given namespace. On the other hand, if no namespace is given,
1812- AppDaemon will use the last specified namespace or the default namespace.
1813- To get all services across AD, pass `global`. See the section on `namespaces <APPGUIDE.html#namespaces>`__
1814- for a detailed description. In most cases, it is safe to ignore this parameter.
1808+ namespace(str, optional): If a ``namespace`` is provided, this function will return services only in that
1809+ namespace. Otherwise, the default value for ``namespace`` is ``global``, which will return services
1810+ across all namespaces. See the section on `namespaces <APPGUIDE.html#namespaces>`__ for more
1811+ information.
18151812
18161813 Returns:
18171814 List of dictionary with keys ``namespace``, ``domain``, and ``service``.
18181815
18191816 Examples:
1820- >>> self.list_services(namespace="global")
1817+ >>> services = self.list_services()
1818+
1819+ >>> services = self.list_services("default")
1820+
1821+ >>> services = self.list_services("mqtt")
18211822
18221823 """
18231824
18241825 self .logger .debug ("list_services: %s" , namespace )
1825- return self .AD .services .list_services (namespace ) # retrieve services
1826+ return self .AD .services .list_services (namespace )
18261827
1827- @overload
1828+ @overload # This overload provides the type hints for the Hass-specific version of this method
18281829 async def call_service (
18291830 self ,
18301831 service : str ,
18311832 namespace : str | None = None ,
1832- timeout : int | float | None = None ,
1833- return_result : bool = True ,
1833+ timeout : str | int | float | None = None ,
18341834 callback : Callable | None = None ,
1835- hass_timeout : float = 10 ,
1835+ hass_timeout : str | int | float | None = None ,
18361836 suppress_log_messages : bool = False ,
18371837 ** data ,
18381838 ) -> Any : ...
@@ -1842,82 +1842,90 @@ async def call_service(
18421842 self ,
18431843 service : str ,
18441844 namespace : str | None = None ,
1845- timeout : int | float | None = None , # Used by utils.sync_decorator
1846- ** data : Any | None ,
1845+ timeout : str | int | float | None = None , # Used by utils.sync_decorator
1846+ callback : Callable [[Any ], Any ] | None = None ,
1847+ ** data : dict [str , Any ] | None ,
18471848 ) -> Any :
18481849 """Calls a Service within AppDaemon.
18491850
1850- This function can call any service and provide any required parameters.
1851- By default, there are standard services that can be called within AD. Other
1852- services that can be called, are dependent on the plugin used, or those registered
1853- by individual apps using the `register_service` api.
1854- In a future release, all available services can be found using AD's Admin UI.
1855- For `listed services`, the part before the first period is the ``domain``,
1856- and the part after is the `service name`. For instance, `light/turn_on`
1857- has a domain of `light` and a service name of `turn_on`.
1858-
1859- The default behaviour of the call service api is not to wait for any result, typically
1860- known as "fire and forget". If it is required to get the results of the call, keywords
1861- "return_result" or "callback" can be added.
1862-
1863- Args:
1864- service (str): The service name.
1865- namespace(str, optional): If a `namespace` is provided, AppDaemon will change
1866- the state of the given entity in the given namespace. On the other hand,
1867- if no namespace is given, AppDaemon will use the last specified namespace
1868- or the default namespace. See the section on `namespaces <APPGUIDE.html#namespaces>`__
1869- for a detailed description. In most cases, it is safe to ignore this parameter.
1870- return_result(str, option): If `return_result` is provided and set to `True` AD will attempt
1871- to wait for the result, and return it after execution. In the case of Home Assistant calls that do not
1872- return values this may seem pointless, but it does force the call to be synchronous with respect to Home Assistant
1873- whcih can in turn highlight slow performing services if they timeout or trigger thread warnings.
1874- callback: The non-async callback to be executed when complete.
1875- hass_timeout (Home Assistant Specific): time in seconds to wait for Home Assistant's
1876- response for this specific service call. If not specified defaults to the value of
1877- the ``q_timeout`` parameter in the HASS plugin configuration, which itself defaults
1878- to 30 seconds. See `Some Notes on Service Calls <APPGUIDE.html#some-notes-on-service-calls>`__
1879- suppress_log_messages (Home Assistant Specific, False): if set to ``True`` Appdaemon will suppress
1880- logging of warnings for service calls to Home Assistant, specifically timeouts and
1881- non OK statuses. Use this flag and set it to ``True`` to supress these log messages
1882- if you are performing your own error checking as described
1883- `here <APPGUIDE.html#some-notes-on-service-calls>`__
1884- **data: Each service has different parameter requirements. This argument
1885- allows you to specify a comma-separated list of keyword value pairs, e.g.,
1886- `entity_id = light.office_1`. These parameters will be different for
1887- every service and can be discovered using the developer tools. Most all
1888- service calls require an ``entity_id``.
1889-
1890- Returns:
1891- Result of the `call_service` function if any, see `service call notes <APPGUIDE.html#some-notes-on-service-calls>`__ for more details.
1851+ Services represent specific actions, and are generally registered by plugins or provided by AppDaemon itself.
1852+ The app calls the service only by referencing the service with a string in the format ``<domain>/<service>``, so
1853+ there is no direct coupling between apps and services. This allows any app to call any service, even ones from
1854+ other plugins.
1855+
1856+ Services often require additional parameters, such as ``entity_id``, which AppDaemon will pass to the service
1857+ call as appropriate, if used when calling this function. This allows arbitrary data to be passed to the service
1858+ calls.
1859+
1860+ Apps can also register their own services using their ``self.regsiter_service`` method.
1861+
1862+ Args:
1863+ service (str): The service name in the format `<domain>/<service>`. For example, `light/turn_on`.
1864+ namespace (str, optional): It's safe to ignore this parameter in most cases because the default namespace
1865+ will be used. However, if a `namespace` is provided, the service call will be made in that namespace. If
1866+ there's a plugin associated with that namespace, it will do the service call. If no namespace is given,
1867+ AppDaemon will use the app's namespace, which can be set using the ``self.set_namespace`` method. See
1868+ the section on `namespaces <APPGUIDE.html#namespaces>`__ for more information.
1869+ timeout (str | int | float, optional): The internal AppDaemon timeout for the service call. If no value is
1870+ specified, the default timeout is 60s. The default value can be changed using the
1871+ ``appdaemon.internal_function_timeout`` config setting.
1872+ callback (callable): The non-async callback to be executed when complete. It should accept a single
1873+ argument, which will be the result of the service call. This is the recommended method for calling
1874+ services which might take a long time to complete. This effectively bypasses the ``timeout`` argument
1875+ because it only applies to this function, which will return immediately instead of waiting for the
1876+ result if a `callback` is specified.
1877+ hass_timeout (str | int | float, optional): Only applicable to the Hass plugin. Sets the amount of time to
1878+ wait for a response from Home Assistant. If no value is specified, the default timeout is 10s. The
1879+ default value can be changed using the ``ws_timeout`` setting the in the Hass plugin configuration in
1880+ ``appdaemon.yaml``. Even if no data is returned from the service call, Home Assistant will still send an
1881+ acknowledgement back to AppDaemon, which this timeout applies to. Note that this is separate from the
1882+ ``timeout``. If ``timeout`` is shorter than this one, it will trigger before this one does.
1883+ suppress_log_messages (bool, optional): Only applicable to the Hass plugin. If this is set to ``True``,
1884+ Appdaemon will suppress logging of warnings for service calls to Home Assistant, specifically timeouts
1885+ and non OK statuses. Use this flag and set it to ``True`` to supress these log messages if you are
1886+ performing your own error checking as described `here <APPGUIDE.html#some-notes-on-service-calls>`__
1887+ service_data (dict, optional): Used as an additional dictionary to pass arguments into the ``service_data``
1888+ field of the JSON that goes to Home Assistant. This is useful if you have a dictionary that you want to
1889+ pass in that has a key like ``target`` which is otherwise used for the ``target`` argument.
1890+ **data: Any other keyword arguments get passed to the service call as ``service_data``. Each service takes
1891+ different parameters, so this will vary from service to service. For example, most services require
1892+ ``entity_id``. The parameters for each service can be found in the actions tab of developer tools in
1893+ the Home Assistant web interface.
1894+
1895+ Returns:
1896+ Result of the `call_service` function if any, see
1897+ `service call notes <APPGUIDE.html#some-notes-on-service-calls>`__ for more details.
18921898
18931899 Examples:
18941900 HASS
1901+ ^^^^
18951902
1896- >>> self.call_service("light/turn_on", entity_id = "light.office_lamp", color_name = "red")
1897- >>> self.call_service("notify/notify", title = "Hello", message = "Hello World")
1898- >>> self.call_service(
1903+ >>> self.call_service("light/turn_on", entity_id= "light.office_lamp", color_name= "red")
1904+ >>> self.call_service("notify/notify", title= "Hello", message= "Hello World")
1905+ >>> events = self.call_service(
18991906 "calendar/get_events",
19001907 entity_id="calendar.home",
19011908 start_date_time="2024-08-25 00:00:00",
19021909 end_date_time="2024-08-27 00:00:00",
1903- return_result=True,
1904- hass_timeout=10
1905- )
1910+ )["result]["response"]["calendar.home"]["events"]
19061911
19071912 MQTT
1913+ ^^^^
19081914
1909- >>> call_service("mqtt/subscribe", topic="homeassistant/living_room/light", qos=2)
1910- >>> call_service("mqtt/publish", topic="homeassistant/living_room/light", payload="on")
1915+ >>> self. call_service("mqtt/subscribe", topic="homeassistant/living_room/light", qos=2)
1916+ >>> self. call_service("mqtt/publish", topic="homeassistant/living_room/light", payload="on")
19111917
19121918 Utility
1919+ ^^^^^^^
1920+
1921+ It's important that the ``namespace`` arg is set to ``admin`` for these services, as they do not exist
1922+ within the default namespace, and apps cannot exist in the ``admin`` namespace. If the namespace is not
1923+ specified, calling the method will raise an exception.
19131924
1914- >>> call_service("app/restart", app="notify_app", namespace="appdaemon ")
1915- >>> call_service("app/stop", app="lights_app", namespace="appdaemon ")
1916- >>> call_service("app/reload", namespace="appdaemon ")
1925+ >>> self. call_service("app/restart", app="notify_app", namespace="admin ")
1926+ >>> self. call_service("app/stop", app="lights_app", namespace="admin ")
1927+ >>> self. call_service("app/reload", namespace="admin ")
19171928
1918- For Utility, it is important that the `namespace` arg is set to ``appdaemon``
1919- as no app can work within that `namespace`. If namespace is not specified,
1920- calling this function will raise an error.
19211929 """
19221930 self .logger .debug ("call_service: %s, %s" , service , data )
19231931 self ._check_service (service )
@@ -1932,7 +1940,18 @@ async def call_service(
19321940 for e in eid :
19331941 self ._check_entity (namespace , e )
19341942
1935- return await self .AD .services .call_service (namespace , * service .split ("/" , 2 ), name = self .name , data = data )
1943+ domain , service_name = service .split ("/" , 2 )
1944+ coro = self .AD .services .call_service (
1945+ namespace = namespace ,
1946+ domain = domain ,
1947+ service = service_name ,
1948+ data = data
1949+ )
1950+ if callback is None :
1951+ return await coro
1952+ else :
1953+ task = self .AD .loop .create_task (coro )
1954+ task .add_done_callback (lambda f : callback (f .result ()))
19361955
19371956 # Sequences
19381957
0 commit comments