### Manual Installation using Git Clone Source: https://github.com/custom-components/pyscript/blob/master/docs/installation.md Install the current GitHub master version by cloning the repository and copying the files to your Home Assistant configuration directory. ```bash mkdir SOME_LOCAL_WORKSPACE cd SOME_LOCAL_WORKSPACE git clone https://github.com/custom-components/pyscript.git mkdir -p YOUR_HASS_CONFIG_DIRECTORY/custom_components cp -pr pyscript/custom_components/pyscript YOUR_HASS_CONFIG_DIRECTORY/custom_components ``` -------------------------------- ### Install Dependencies and Pre-commit Hooks Source: https://github.com/custom-components/pyscript/blob/master/tests/README.md Install the necessary testing requirements and set up pre-commit hooks. Pre-commit helps ensure code quality before commits. ```bash python -m pip install -r tests/requirements_test.txt pre-commit install ``` -------------------------------- ### Manual Installation using Zip Source: https://github.com/custom-components/pyscript/blob/master/docs/installation.md Use this method to manually install Pyscript by downloading the zip file from the latest release. Ensure you navigate to your Home Assistant configuration directory. ```bash cd YOUR_HASS_CONFIG_DIRECTORY # same place as configuration.yaml mkdir -p custom_components/pyscript cd custom_components/pyscript unzip hass-custom-pyscript.zip ``` -------------------------------- ### Example: Setting input_number Value Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Demonstrates various equivalent ways to call the 'set_value' service on an 'input_number' entity, including the shorthand positional argument. ```python service.call("input_number", "set_value", entity_id="input_number.test", value=13) input_number.set_value(entity_id="input_number.test", value=13) input_number.test.set_value(value=13) input_number.test.set_value(13) ``` -------------------------------- ### Monitoring All Service Calls Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md This example shows how to trigger a function on any service call to log all received event data. Use **kwargs to capture all parameters initially. ```python from homeassistant.const import EVENT_CALL_SERVICE @event_trigger(EVENT_CALL_SERVICE) def monitor_service_calls(**kwargs): log.info(f"got EVENT_CALL_SERVICE with kwargs={kwargs}") ``` -------------------------------- ### Monitoring Specific Service Calls Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md This example filters service calls to only trigger on 'lights.turn_on'. It uses a string expression to match the domain and service, and captures specific service data. ```python from homeassistant.const import EVENT_CALL_SERVICE @event_trigger(EVENT_CALL_SERVICE, "domain == 'lights' and service == 'turn_on'") def monitor_light_turn_on_service(service_data=None): log.info(f"lights.turn_on service called with service_data={service_data}") ``` -------------------------------- ### Included YAML Configuration for Applications Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Example of a 'pyscript/config.yaml' file that includes application-specific configurations. This structure separates application settings from the main Pyscript configuration. ```yaml allow_all_imports: true apps: my_app1: # any settings for my_app1 go here my_app2: # any settings for my_app2 go here ``` -------------------------------- ### Manage Trigger Functions with a List Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Store dynamically created trigger functions in a list. This example shows how to populate a list by calling a factory function within a loop. ```python input_boolean_test_triggers = [] for i in range(1, 4): input_boolean_test_triggers.append(state_trigger_factory(f"test{i}", "on")) ``` -------------------------------- ### Example YAML Configuration for PyScript Apps Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md This YAML defines settings for two PyScript applications, `auto_lights` and `motion_light`, demonstrating nested configurations and global settings. Use this structure to configure your applications without modifying their code. ```yaml pyscript: allow_all_imports: true apps: auto_lights: - room: living level: 60 some_list: - 1 - 20 - room: dining level: 80 some_list: - 1 - 20 motion_light: - sensor: rear_left light: rear_flood - sensor: side_yard light: side_flood - sensor: front_patio light: front_porch global: setting1: 10 setting2: true ``` -------------------------------- ### Write a Basic PyScript Service Source: https://github.com/custom-components/pyscript/blob/master/docs/tutorial.md Define a Python function decorated with @service to create a custom Home Assistant service. This example demonstrates logging and conditional service calls or event firing. ```python @service def hello_world(action=None, id=None): """hello_world example using pyscript.""" log.info(f"hello world: got action {action} id {id}") if action == "turn_on" and id is not None: light.turn_on(entity_id=id, brightness=255) elif action == "fire" and id is not None: event.fire(id, param1=12, param2=80) ``` -------------------------------- ### Async TCP Client Connection in PyScript Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md An example demonstrating how to establish an asynchronous client connection to a TCP server using 'asyncio.open_connection'. This avoids blocking the event loop for network communication. ```python import asyncio Reader, Writer = None, None @time_trigger('startup') def do_client_connection(): global Reader, Writer Reader, Writer = asyncio.open_connection('127.0.0.1', 8956) def client_send(message): if not Writer: raise("Client is not connected") Writer.write(message.encode()) Writer.drain() return Reader.readline().decode() ``` -------------------------------- ### Basic Webhook Trigger Example Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md A simple example of a webhook trigger that logs received payload data and an additional keyword argument. This snippet is triggered by a POST request to a specific webhook ID. ```python @webhook_trigger("myid", kwargs={"extra": 10}) def webhook_test(payload, extra): log.info(f"It ran! {payload}, {extra}") ``` -------------------------------- ### PyScript Alert Setup Source: https://github.com/custom-components/pyscript/wiki/Comparing-Pyscript-to-Home-Assistant-Automations This snippet shows how to register a custom alert using PyScript's decorator-based approach. It defines an alert with a name, condition, interval, and notification messages. ```python if wait['trigger_type'] == 'state': condition_met = False state.set( alert_entity, "off", count=0, start_ts=0 ) log.info(f'Alert {config["name"]} Finished') registered_triggers.append(alert) @time_trigger('startup') def alert_startup(): make_alert({ "name": "dishwasher_done", "condition": "input_select.dishwasher_status == 'clean'", "interval": 30, "notifier": "house_notify_script", "message": "The dishwasher is done. Please empty it.", "message_more": "This dishwasher has been done for {alert_time} minutes. I have told you {alert_count} times already. Please empty it." }) ``` -------------------------------- ### Say Weather Using Rendered Template Source: https://github.com/custom-components/pyscript/wiki/Rendering-Templates-Example This function demonstrates calling the `render_template` helper to get the current weather state and then using the TTS integration to speak the message. ```python def say_weather(): message = render_template("Hello! It is {{ states('weather.home') }}!") tts.google_translate_say(message=message) ``` -------------------------------- ### Call a Service and Return Response Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Call a service and capture its response by setting `return_response=True`. This feature is available starting in HASS 2023.7. ```python service_response = myservice.flash_light(light_name="front", light_color="red", return_response=True) ``` -------------------------------- ### MQTT Trigger with Conditional Logic Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Example of using `@mqtt_trigger` with a topic, a payload expression, and a time-based trigger. This snippet turns a light on and off based on motion detection within specific time ranges. ```python @mqtt_trigger('zigbee2mqtt/motion.carport', "payload_obj['occupancy'] != None") @time_active("range(sunset - 30m, sunrise - 30m)") def carport_motion(): light.turn_on(entity_id="light.carport") task.sleep(300) light.turn_off(entity_id="light.carport") ``` -------------------------------- ### Run Function Once on Startup/Reload with @time_trigger Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Use @time_trigger without arguments to automatically run a function once when the application starts or reloads. This is useful for initialization tasks. ```python ```python @time_trigger def run_on_startup_or_reload(): """This function runs automatically once on startup or reload""" pass ``` ``` -------------------------------- ### YAML Configuration with Secrets for PyScript App Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md This YAML example shows how to use `!secret` to inject sensitive information like API keys or URLs into PyScript application configuration. The `service_checker` app uses a plain string for `service_name` and secrets for `url` and `api_key`. ```yaml pyscript: allow_all_imports: true apps: service_checker: - service_name: my_service url: !secret my_secret_url api_key: !secret my_secret_api_key ``` -------------------------------- ### Startup and Shutdown Triggers Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Use 'startup' to trigger on HASS start/reload and 'shutdown' to trigger on HASS shutdown/reload. ```python "startup" ``` ```python "shutdown" ``` -------------------------------- ### Get Current Task Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Retrieves the task ID of the currently executing task. ```APIDOC ## task.current_task() ### Description Returns the task id of the current task. ### Returns - **task_id** (asyncio.Task) - The ID of the current task. ``` -------------------------------- ### Open PyScript Jupyter Tutorial Notebook Source: https://github.com/custom-components/pyscript/blob/master/docs/tutorial.md Use the jupyter notebook command to open the downloaded tutorial notebook. ```bash jupyter notebook pyscript_tutorial.ipynb ``` -------------------------------- ### Get Current PyScript Global Context Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Retrieve the name of the currently active global context. This function is useful for understanding the execution scope. ```python pyscript.get_global_ctx() ``` -------------------------------- ### Download PyScript Jupyter Tutorial Notebook Source: https://github.com/custom-components/pyscript/blob/master/docs/tutorial.md Use wget to download the PyScript Jupyter tutorial notebook for interactive learning. ```bash wget https://github.com/craigbarratt/hass-pyscript-jupyter/raw/master/pyscript_tutorial.ipynb ``` -------------------------------- ### Iterating Over Application Configuration in PyScript Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md This Python code snippet demonstrates how to iterate through `pyscript.app_config` in an application's main file to set up triggers or logic based on the provided configuration. The `**inst` syntax unpacks each configuration dictionary as keyword arguments. ```python def setup_triggers(room=None, level=None, some_list=None): # # define some trigger functions etc # pass for inst in pyscript.app_config: setup_triggers(**inst) ``` -------------------------------- ### Create and Activate Virtual Environment Source: https://github.com/custom-components/pyscript/blob/master/tests/README.md Create a Python virtual environment and activate it. Ensure your Python version is 3.7 or higher. This isolates project dependencies. ```bash python -m venv venv source venv/bin/activate ``` -------------------------------- ### Activate Virtual Environment (Repeat) Source: https://github.com/custom-components/pyscript/blob/master/tests/README.md Remember to activate the virtual environment in new shell sessions before running tests or development commands. ```bash source venv/bin/activate ``` -------------------------------- ### YAML Configuration for Multiple Automations Source: https://github.com/custom-components/pyscript/wiki/Writing-an-App-in-Pyscript This YAML configuration defines how to use the 'motion_lights' app multiple times. Each entry specifies the entity IDs for motion detection, the light to control, and the delay timer. ```yaml pyscript: apps: motion_lights: - motion_id: binary_sensor.room1 light_id: light.room1 time_id: input_number.room1 - motion_id: binary_sensor.room2 light_id: light.room2 time_id: input_number.room2 ``` -------------------------------- ### Call a Service with Parameters Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Invoke a service with specific parameters using its name as a Python function. Parameter values can be any Python expression. ```python myservice.flash_light(light_name="front", light_color="red") ``` -------------------------------- ### PyScript @time_active with Time Range Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Example of using @time_active with a 'range' specification to execute a function only during specific hours. This snippet also includes @state_trigger and @state_active for combined conditional logic. ```python @state_trigger("binary_sensor.motion_detected == 'on'") # trigger on motion detection @state_active("input_boolean.motion_light_automation == 'on'") # but only if the automation is enabled @time_active("range(8:00, 22:00)") # but only during the day def motion_controlled_light(**kwargs): log.info(f"got motion. turning on the lights") light.turn_on(entity_id="light.hallway") ``` -------------------------------- ### Python Time Trigger Example Source: https://github.com/custom-components/pyscript/wiki/Time-Trigger-Example Use this snippet to schedule a Python function to run at a specific time each day. Ensure the 'time_trigger' decorator is imported and the desired time is formatted correctly. ```python """ Time test script """ @time_trigger("once(17:15:00)") def time_trigger_test(): """Trigger at 5:15pm every test example using pyscript.""" log.info(f"Time Trigger test:") ``` -------------------------------- ### State Trigger with 'from': Home Assistant vs Pyscript Source: https://github.com/custom-components/pyscript/wiki/Comparing-Pyscript-to-Home-Assistant-Automations Shows how to specify a 'from' state in a Home Assistant state trigger and its Pyscript equivalent. Pyscript incorporates the 'from' state logic directly into the trigger condition. ```yaml - alias: some automation trigger: platform: state entity_id: binary_sensor.test to: 'on' from: 'off' action: - service: homeassistant.turn_on entity_id: switch.test ``` ```python @state_trigger('binary_sensor.test == "on" and binary_sensor.test.old == "off"') def turn_on(): switch.test.turn_on() ``` -------------------------------- ### YAML Configuration with Application Settings Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Configure Pyscript and define settings for specific applications like 'my_app1' and 'my_app2'. Application configurations are nested under the 'apps' key. ```yaml pyscript: allow_all_imports: true apps: my_app1: # any settings for my_app1 go here my_app2: # any settings for my_app2 go here ``` -------------------------------- ### Get State Variable Value Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Retrieve the value of a state variable by its string name using `state.get()`. A `NameError` is raised if the name is not found. For nested attributes like `DOMAIN.entity.attr`, an `AttributeError` is raised if the attribute does not exist. ```python state.get(name) ``` -------------------------------- ### Template Condition: Home Assistant vs Pyscript Source: https://github.com/custom-components/pyscript/wiki/Comparing-Pyscript-to-Home-Assistant-Automations Demonstrates a Home Assistant template condition and its Pyscript equivalent. Pyscript allows combining multiple state triggers and conditions using decorators. ```yaml - alias: some automation trigger: platform: state entity_id: binary_sensor.test to: "on" condition: condition: template value_template: "{{ is_state('input_boolean.test', 'on') }}" action: - service: homeassistant.turn_on entity_id: switch.test ``` ```python @state_trigger('binary_sensor.test == "on"') @state_active('input_boolean.test == "on"') def turn_on(): switch.test.turn_on() ``` -------------------------------- ### Webhook Trigger with HMAC Signature Validation Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Example demonstrating how to validate an HMAC signature for incoming webhook requests. It requires importing `hmac` and `hashlib`, defining a secret key, and accessing the request object to read headers and the raw body. ```python import hmac import hashlib SECRET = b"shared-secret" @webhook_trigger("github") def gh(payload, request): sig = request.headers.get("X-Hub-Signature-256", "") body = await request.read() expected = "sha256=" + hmac.new(SECRET, body, hashlib.sha256).hexdigest() if not hmac.compare_digest(sig, expected): log.warning("bad signature, ignoring") return log.info(f"verified webhook: {payload}") ``` -------------------------------- ### Get State Variable Attributes Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Use `state.getattr()` to retrieve a dictionary of attribute values for a given state variable name. It returns `None` if the state variable does not exist. In versions prior to 1.0.0, `state.get_attr()` was used and is still supported but logs a warning. ```python state.getattr(name) ``` -------------------------------- ### Use Async I/O with aiohttp in PyScript Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Presents the best practice for fetching URLs in PyScript using the 'aiohttp' library for asynchronous I/O, which completely avoids blocking the main event loop without needing 'task.executor'. ```python import aiohttp # Best - uses async I/O to avoid blocking the main event loop url = "https://raw.githubusercontent.com/custom-components/pyscript/master/README.md" async with aiohttp.ClientSession() as session: async with session.get(url) as resp: print(resp.status) print(resp.text()) ``` -------------------------------- ### Checking Light State Before Turning On Source: https://github.com/custom-components/pyscript/blob/master/docs/tutorial.md Improve automation by checking if the light is already on before attempting to turn it on, preventing redundant actions. This snippet integrates with the task.unique pattern. ```python ```python @state_trigger("security.rear_motion == '1' or security.side_motion == '1'") @time_active("range(sunset - 20min, sunrise + 20min)") def motion_light_rear(): """Turn on rear light for 5 minutes when there is motion and it's dark""" task.unique("motion_light_rear") log.info(f"triggered; turning on the light") if light.outside_rear != "on": light.turn_on(entity_id="light.outside_rear", brightness=255) task.sleep(300) light.turn_off(entity_id="light.outside_rear") ``` ``` -------------------------------- ### Check for Service Existence Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Use `service.has_service()` to verify if a specific Home Assistant service exists. It returns `True` if the service is available, and `False` otherwise. ```python service.has_service(domain, name) ``` -------------------------------- ### Clone Pyscript Repository Source: https://github.com/custom-components/pyscript/blob/master/tests/README.md Clone the Pyscript repository from GitHub. This is the first step in setting up your local development environment. ```bash git clone https://github.com/custom-components/pyscript.git cd pyscript ``` -------------------------------- ### PyScript Configuration Source: https://github.com/custom-components/pyscript/wiki/"Making-Home-Assistant's-Presence-Detection-not-so-Binary"-Remix Configure the pyscript application in Home Assistant's configuration.yaml. This section specifies the person entity to track. ```yaml pyscript: apps: person_tracker: - person: person.tony_stark ``` -------------------------------- ### Persist State in PyScript Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Illustrates how to make state variables persistent across Home Assistant restarts using 'state.persist'. This ensures that specific state values are preserved. ```python state.persist('pyscript.last_light_on') @state_trigger('binary_sensor.motion == "on"') def turn_on_lights(): light.turn_on('light.overhead') pyscript.last_light_on = "light.overhead" ``` -------------------------------- ### State Trigger: Home Assistant vs Pyscript Source: https://github.com/custom-components/pyscript/wiki/Comparing-Pyscript-to-Home-Assistant-Automations Compares Home Assistant YAML state trigger with its Pyscript equivalent. Pyscript uses a decorator-based approach for state triggers. ```yaml - alias: some automation trigger: platform: state entity_id: binary_sensor.test to: 'on' action: - service: homeassistant.turn_on entity_id: switch.test ``` ```python @state_trigger('binary_sensor.test == "on"') def turn_on(): switch.test.turn_on() ``` -------------------------------- ### Monitor all service calls with pyscript Source: https://github.com/custom-components/pyscript/wiki/Event-based-triggers Logs all service calls made in Home Assistant. Ensure `EVENT_CALL_SERVICE` is imported from `homeassistant.const`. ```python from homeassistant.const import EVENT_CALL_SERVICE @event_trigger(EVENT_CALL_SERVICE) def monitor_service_events(domain=None, service=None, service_data=None): log.info(f"{domain}.{service} called with service_data={service_data}") ``` -------------------------------- ### Original PyScript Automation Source: https://github.com/custom-components/pyscript/wiki/Writing-an-App-in-Pyscript This is a basic PyScript automation that turns on a light when motion is detected and turns it off after a specified delay. It uses hardcoded entity IDs. ```python import @state_trigger("binary_sensor.room1 == 'on'") def motion_light(): task.unique("motion_light") if light.room1 != "on": light.turn_on(entity_id="light.room1") task.sleep(float(input_number.room1)) light.turn_off(entity_id="light.room1") ``` -------------------------------- ### List All PyScript Global Contexts Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Display a list of all available global contexts, with the current context highlighted. This helps in managing multiple isolated execution environments. ```python pyscript.list_global_ctx() ``` -------------------------------- ### Python Service Script for Binary Sensor Check Source: https://github.com/custom-components/pyscript/wiki/Simple-Service-Example Use this script as a service to test logic based on a binary sensor's state. It logs 'fail' if the 'workday' sensor is 'on', and 'pass' otherwise. ```python """ Service script """ @service def test(): if binary_sensor.workday == 'on': log.info(f"Service Trigger test: fail") pass else: log.info(f"Service Trigger test: pass") pass ``` -------------------------------- ### Run Pyscript Tests with Coverage Source: https://github.com/custom-components/pyscript/blob/master/tests/README.md Execute tests and generate a coverage report, highlighting missing lines. This helps in assessing test completeness. ```bash pytest --cov=custom_components/pyscript --cov-report term-missing ``` -------------------------------- ### Thermostat Script: First Person Returns Home Source: https://github.com/custom-components/pyscript/wiki/Thermostat-adjustment-using-Occupancy This function is triggered when the first person returns home. It waits for the last person to leave or a timeout, then sets the thermostat's high and low temperatures based on Dark Sky forecast data. Ensure Dark Sky integration is active. ```python ```python @state_trigger("group.device_trackers == 'home'") def themostat_left(): trig_info = task.wait_until( state_trigger="group.device_trackers == 'not_home'", timeout=30 ) if trig_info["trigger_type"] == "timeout": pass else: """Set High Temp""" if float(sensor.dark_sky_daytime_high_temperature_0d) > 85.0: hightemp = 75 elif float(sensor.dark_sky_daytime_high_temperature_0d) < 85.0: hightemp = 85 """Set Low Temp""" if float(sensor.dark_sky_overnight_low_temperature_0d) > 50.0: lowtemp = 55 elif float(sensor.dark_sky_overnight_low_temperature_0d) < 50.0: lowtemp = 65 """Send the actual command to the thermostat""" climate.set_temperature(entity_id="climate.radio_thermostat_company_of_america_ct101_thermostat_iris_mode",target_temp_low=lowtemp,target_temp_high=hightemp,hvac_mode="heat_cool") pass ``` ``` -------------------------------- ### Registering a Service with YAML Description Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Use the @service decorator to register a Python function as a Home Assistant service. The docstring can be used to provide a detailed YAML service description. ```python @service def hello_world(action=None, id=None): """yaml name: Service example description: hello_world service example using pyscript. fields: action: description: turn_on turns on the light, fire fires an event example: turn_on required: true selector: select: options: - turn_on - fire id: description: id of light, or name of event to fire example: kitchen.light required: true selector: text: """ log.info(f"hello world: got action {action}") if action == "turn_on" and id is not None: light.turn_on(entity_id=id, brightness=255) elif action == "fire" and id is not None: event.fire(id) ``` -------------------------------- ### Say Weather Using PyScript's Direct Syntax Source: https://github.com/custom-components/pyscript/wiki/Rendering-Templates-Example An alternative to rendering Home Assistant templates, this function uses PyScript's f-string capabilities to directly embed state values, offering a more concise approach. ```python def say_weather(): message = f"Hello! It is {weather.home}!" tts.google_translate_say(message=message) ``` -------------------------------- ### Monitor specific service calls (e.g., light domain) with pyscript Source: https://github.com/custom-components/pyscript/wiki/Event-based-triggers Logs service calls only for the 'light' domain. The `domain` argument is omitted as it's fixed. Best practice is to import and use the constant `EVENT_CALL_SERVICE`. ```python @event_trigger("call_service", "domain == 'light'") def monitor_lights_service_events(service=None, service_data=None): log.info(f"light.{service} called with service_data={service_data}") ``` -------------------------------- ### Thermostat Day Script (Workday) Source: https://github.com/custom-components/pyscript/wiki/Thermostat-Adjustment-using-Time-Trigger Triggers at 7:30 AM on workdays to set thermostat temperatures based on forecast high and low temperatures. Requires workday sensor and Dark Sky forecast data. ```python """ Thermostat day script """ @time_trigger("once(7:30:00)") def thermostat_work_day(): """Trigger at 7:30am every""" """Only trigger on workday""" if binary_sensor.workday == 'on': """Set High Temp""" if float(sensor.dark_sky_daytime_high_temperature_0d) > 85.0: hightemp = 75 elif float(sensor.dark_sky_daytime_high_temperature_0d) < 85.0: hightemp = 85 """Set Low Temp""" if float(sensor.dark_sky_overnight_low_temperature_0d) > 50.0: lowtemp = 55 elif float(sensor.dark_sky_overnight_low_temperature_0d) < 50.0: lowtemp = 65 """Send the actual command to the thermostat""" climate.set_temperature(entity_id="climate.radio_thermostat_company_of_america_ct101_thermostat_iris_mode",target_temp_low=lowtemp,target_temp_high=hightemp,hvac_mode="heat_cool") ``` -------------------------------- ### Avoid Blocking I/O in PyScript Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Demonstrates the incorrect way to fetch a URL using the 'requests' library, which blocks the main event loop. This approach should be avoided. ```python import requests # Do not fetch URLs this way! url = "https://raw.githubusercontent.com/custom-components/pyscript/master/README.md" resp = requests.get(url) ``` -------------------------------- ### Basic Motion-Activated Light Trigger Source: https://github.com/custom-components/pyscript/blob/master/docs/tutorial.md Use state_trigger and time_active to turn on a light when motion is detected during dark hours. The function turns on the light, waits for 5 minutes, and then turns it off. ```python ```python @state_trigger("security.rear_motion == '1' or security.side_motion == '1'") @time_active("range(sunset - 20min, sunrise + 15min)") def motion_light_rear(): """Turn on rear light for 5 minutes when there is motion and it's dark""" log.info(f"triggered; turning on the light") light.turn_on(entity_id="light.outside_rear", brightness=255) task.sleep(300) light.turn_off(entity_id="light.outside_rear") ``` ``` -------------------------------- ### Calling Services on State Variables Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Services registered by a domain can be called as methods on a state variable. This simplifies service calls that target a specific entity. ```python service.call("DOMAIN", "SERVICE", entity_id="DOMAIN.ENTITY", other_param=123) DOMAIN.SERVICE(entity_id="DOMAIN.ENTITY", other_param=123) DOMAIN.ENTITY.SERVICE(other_param=123) ``` -------------------------------- ### Configure Logger for PyScript Source: https://github.com/custom-components/pyscript/blob/master/docs/tutorial.md Configure the Home Assistant logger to display info-level messages from custom_components.pyscript. This is necessary to see log output from your scripts. ```yaml logger: default: info logs: custom_components.pyscript: info ``` -------------------------------- ### Converted PyScript App Code Source: https://github.com/custom-components/pyscript/wiki/Writing-an-App-in-Pyscript This Python code converts the original automation into a reusable app. It includes a factory function `make_motion_light` that generates specific automation functions based on configuration, and a startup trigger to process the app configuration. ```python # we'll use this later registered_triggers = [] # First, we define a function that makes more functions. def make_motion_light(config): # this is the original code modified to # substituting in the variables from YAML. # compare it line by line with the original code # replace the hardcoded entity ID with the value from config @state_trigger(f"{config['motion_id']} == 'on'") def motion_light(): # we want a unique task for each separate app, so lets use # a unique name based on some config data task.unique(f"motion_light_{config['motion_id']}") # because our light entity is in a variable we'll have to # use the longer form to get the state if state.get(config['light_id']) != "on": # substitute in the value from config light.turn_on(entity_id=config['light_id']) # substitute from config task.sleep(float(state.get(config['time_id']))) # substitute from config light.turn_off(entity_id=config['light_id']) # now that we've made a function specifically for this config item # we need to register it in the global scope so pyscript sees it. # the easiest way to do that is add it to a global list. registered_triggers.append(motion_light) # now we just need the startup trigger @time_trigger('startup') def motion_light_startup(): for app in pyscript.app_config: make_motion_light(app) ``` -------------------------------- ### Compute Sunrise and Sunset using HASS Helpers Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Use this snippet to calculate sunrise and sunset times using Home Assistant's built-in sun helper functions. Requires HA 2021.5 or later. ```python import homeassistant.helpers.sun as sun import datetime location = sun.get_astral_location(hass) sunrise = location[0].sunrise(datetime.datetime.today()).replace(tzinfo=None) sunset = location[0].sunset(datetime.datetime.today()).replace(tzinfo=None) print(f"today sunrise = {sunrise}, sunset = {sunset}") ``` -------------------------------- ### Configure Logging Levels in YAML Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Configure default and specific logging levels for PyScript components in your Home Assistant configuration. Changes typically require a HASS restart. ```yaml logger: default: info logs: custom_components.pyscript.file: info custom_components.pyscript.file.my_script.my_function: debug ``` -------------------------------- ### Import Built-in Event Constant Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Import the constant for a built-in event type from homeassistant.const. ```python from homeassistant.const import EVENT_CALL_SERVICE ``` -------------------------------- ### Run Specific Pyscript Test File Source: https://github.com/custom-components/pyscript/blob/master/tests/README.md Run tests from a specific file, such as 'tests/test_function.py'. This is useful for targeted testing. ```bash pytest tests/test_function.py ``` -------------------------------- ### Thermostat Day Script (Non-Workday) Source: https://github.com/custom-components/pyscript/wiki/Thermostat-Adjustment-using-Time-Trigger Triggers at 8:30 AM on non-workdays to set thermostat temperatures based on forecast high and low temperatures. Requires workday sensor and Dark Sky forecast data. ```python @time_trigger("once(8:30:00)") def thermostat_nonwork_day(): """Trigger at 8:30am every""" if binary_sensor.workday != 'on': """Set High Temp""" if float(sensor.dark_sky_daytime_high_temperature_0d) > 85.0: hightemp = 75 elif float(sensor.dark_sky_daytime_high_temperature_0d) < 85.0: hightemp = 85 """Set Low Temp""" if float(sensor.dark_sky_overnight_low_temperature_0d) > 50.0: lowtemp = 55 elif float(sensor.dark_sky_overnight_low_temperature_0d) < 50.0: lowtemp = 65 """Send the actual command to the thermostat""" climate.set_temperature(entity_id="climate.radio_thermostat_company_of_america_ct101_thermostat_iris_mode",target_temp_low=lowtemp,target_temp_high=hightemp,hvac_mode="heat_cool") ``` -------------------------------- ### Template Trigger: Home Assistant vs Pyscript Source: https://github.com/custom-components/pyscript/wiki/Comparing-Pyscript-to-Home-Assistant-Automations Compares a Home Assistant template trigger with its Pyscript equivalent. Pyscript's state trigger can directly evaluate state conditions, simplifying template triggers. ```yaml - alias: some automation trigger: platform: template value_template: "{{ is_state('binary_sensor.test', 'on') }}" action: - service: homeassistant.turn_on entity_id: switch.test ``` ```python @state_trigger('binary_sensor.test == "on"') def turn_on(): switch.test.turn_on() ``` -------------------------------- ### Python Representation of `pyscript.app_config` for `auto_lights` Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md This Python list represents the `pyscript.app_config` variable within the `auto_lights` application's main file, derived from the corresponding YAML configuration. It shows how structured YAML data is made available to the application code. ```python [ {"room": "living", "level": 60, "some_list": [1, 20]}, {"room": "dining", "level": 80, "some_list": [1, 20]}, ] ``` -------------------------------- ### Call a Home Assistant Service Source: https://github.com/custom-components/pyscript/blob/master/docs/reference.md Invoke a Home Assistant service using `service.call()`. You can specify whether the call should be blocking and if the response should be returned. Note that the `limit` parameter for blocking timeouts is no longer supported. ```python service.call(domain, name, blocking=False, return_response=False, **kwargs) ``` -------------------------------- ### Configure Pyscript with YAML Source: https://github.com/custom-components/pyscript/blob/master/docs/configuration.md Use this YAML configuration to enable all imports, expose the 'hass' variable globally, and switch to legacy decorators if needed. This configuration is added to your `/configuration.yaml` file. ```yaml pyscript: allow_all_imports: true hass_is_global: true legacy_decorators: true ```