ha.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import os
  2. from homeassistant_api import Client
  3. from langchain.tools import BaseTool
  4. from homeassistant_api.errors import EndpointNotFoundError
  5. ha_client = Client(
  6. os.environ.get('HA_URL', 'http://localhost:8123'),
  7. os.environ.get('HA_API_KEY', '')
  8. )
  9. class HALightControl(BaseTool):
  10. name = "Control the lights in the room"
  11. description = (
  12. "use this tool when you need to turn on or off the light in the room. "
  13. "given the light entity name and an action like turnon or turnoff, this tool will turn the lights on or off. "
  14. "To use the tool you must provide exactly two of the following parameters "
  15. "['entity_name', 'action']"
  16. )
  17. return_direct = False
  18. def _run(
  19. self,
  20. action: str,
  21. entity_name: str,
  22. ):
  23. light = ha_client.get_domain("light")
  24. if entity_name:
  25. entity = "light.{entity_name}".format(entity_name=entity_name)
  26. if action == "turnon":
  27. light.turn_on(entity_id=entity)
  28. return "{entity_name} turned on".format(entity_name=entity_name)
  29. elif action == "turnoff":
  30. light.turn_off(entity_id=entity)
  31. return "{entity_name} turned off".format(entity_name=entity_name)
  32. return ""
  33. def _arun(self, query: str):
  34. raise NotImplementedError("This tool does not support async")
  35. class HASensorReading(BaseTool):
  36. name = "Home Assistant Sensor Reading Tool"
  37. description = (
  38. "use this tool when you need to read data from a sensor."
  39. "To use the tool you must provide exactly the following parameter "
  40. "'entity_name'"
  41. )
  42. return_direct = False
  43. def _get_entity_name(self, entity_name: str):
  44. # is entity_name starts with sensor. then return it as is
  45. if entity_name.startswith("sensor."):
  46. return entity_name
  47. return f"sensor.{entity_name}"
  48. def _run(
  49. self,
  50. entity_name: str,
  51. ):
  52. entity = self._get_entity_name(entity_name)
  53. try:
  54. sensor = ha_client.get_entity(entity_id=entity)
  55. state = sensor.get_state()
  56. except EndpointNotFoundError as e:
  57. return "No sensor found with name {entity_name}".format(entity_name=entity_name)
  58. except Exception as e:
  59. return "An error occurred while trying to get the sensor {entity_name}".format(entity_name=entity_name)
  60. return state
  61. def _arun(self, query: str):
  62. raise NotImplementedError("This tool does not support async")
  63. class HATempHumReading(HASensorReading):
  64. name = "Room temperature and humidity readings"
  65. description = (
  66. "use this tool when you need to get room temperature and humidity readings. "
  67. "To use the tool you must provide exactly the following parameter "
  68. "'entity_name'"
  69. )
  70. class HAGeolocation(HASensorReading):
  71. name = "Home Assistant Geolocation Tool"
  72. description = (
  73. "use this tool when you need to get geolocation of an entity, person, object. "
  74. "To use the tool you must provide exactly the following parameter "
  75. "'entity_name'"
  76. )
  77. def _get_entity_name(self, entity_name: str):
  78. return "sensor.{entity_name}_geocoded_location".format(entity_name=entity_name)