@@ -1802,37 +1802,37 @@ def deregister_service(self, service: str, namespace: str | None = None) -> bool
1802
1802
return self .AD .services .deregister_service (namespace , * service .split ("/" ), __name = self .name )
1803
1803
1804
1804
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
1808
1806
1809
1807
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.
1815
1812
1816
1813
Returns:
1817
1814
List of dictionary with keys ``namespace``, ``domain``, and ``service``.
1818
1815
1819
1816
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")
1821
1822
1822
1823
"""
1823
1824
1824
1825
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 )
1826
1827
1827
- @overload
1828
+ @overload # This overload provides the type hints for the Hass-specific version of this method
1828
1829
async def call_service (
1829
1830
self ,
1830
1831
service : str ,
1831
1832
namespace : str | None = None ,
1832
- timeout : int | float | None = None ,
1833
- return_result : bool = True ,
1833
+ timeout : str | int | float | None = None ,
1834
1834
callback : Callable | None = None ,
1835
- hass_timeout : float = 10 ,
1835
+ hass_timeout : str | int | float | None = None ,
1836
1836
suppress_log_messages : bool = False ,
1837
1837
** data ,
1838
1838
) -> Any : ...
@@ -1842,82 +1842,90 @@ async def call_service(
1842
1842
self ,
1843
1843
service : str ,
1844
1844
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 ,
1847
1848
) -> Any :
1848
1849
"""Calls a Service within AppDaemon.
1849
1850
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.
1892
1898
1893
1899
Examples:
1894
1900
HASS
1901
+ ^^^^
1895
1902
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(
1899
1906
"calendar/get_events",
1900
1907
entity_id="calendar.home",
1901
1908
start_date_time="2024-08-25 00:00:00",
1902
1909
end_date_time="2024-08-27 00:00:00",
1903
- return_result=True,
1904
- hass_timeout=10
1905
- )
1910
+ )["result]["response"]["calendar.home"]["events"]
1906
1911
1907
1912
MQTT
1913
+ ^^^^
1908
1914
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")
1911
1917
1912
1918
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.
1913
1924
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 ")
1917
1928
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.
1921
1929
"""
1922
1930
self .logger .debug ("call_service: %s, %s" , service , data )
1923
1931
self ._check_service (service )
@@ -1932,7 +1940,18 @@ async def call_service(
1932
1940
for e in eid :
1933
1941
self ._check_entity (namespace , e )
1934
1942
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 ()))
1936
1955
1937
1956
# Sequences
1938
1957
0 commit comments