Time of Use (TOU) Pricing ========================== The Navien NWP500 supports Time of Use (TOU) pricing schedules, allowing the water heater to optimize heating based on electricity rates that vary throughout the day. The Navien mobile app integrates with the OpenEI (Open Energy Information) API to retrieve utility rate information. Overview -------- Time of Use pricing enables: * **Cost optimization**: Heat water during off-peak hours when electricity rates are lower * **Demand response**: Reduce energy consumption during peak rate periods * **Custom schedules**: Configure up to 16 different time periods with varying rates * **Seasonal support**: Different schedules for different months of the year * **Weekday/weekend support**: Separate schedules for weekdays and weekends The system uses utility rate data from OpenEI to configure heating schedules based on your location and utility provider. OpenEI API Integration ---------------------- The Navien mobile app queries the OpenEI Utility Rates API to retrieve current electricity rate information for the user's location, then presents available rate plans and configures TOU schedules. API Endpoint ~~~~~~~~~~~~ .. code-block:: text GET https://api.openei.org/utility_rates Query Parameters ~~~~~~~~~~~~~~~~ The following parameters are used to query utility rates: .. list-table:: :widths: 20 15 65 :header-rows: 1 * - Parameter - Type - Description * - ``version`` - integer - API version (currently ``7``) * - ``format`` - string - Response format (``json``) * - ``api_key`` - string - OpenEI API key (embedded in Navien app) * - ``detail`` - string - Level of detail (``full`` for complete rate structure) * - ``address`` - string - ZIP code or address to search * - ``sector`` - string - Customer sector (``Residential``, ``Commercial``, etc.) * - ``orderby`` - string - Sort field (``startdate`` for most recent rates) * - ``direction`` - string - Sort direction (``desc`` for descending) * - ``limit`` - integer - Maximum number of results (``100``) Example Request ~~~~~~~~~~~~~~~ .. code-block:: text GET https://api.openei.org/utility_rates?version=7&format=json&api_key=YOUR_API_KEY&detail=full&address=94903§or=Residential&orderby=startdate&direction=desc&limit=100 Response Format ~~~~~~~~~~~~~~~ The API returns a JSON response with an array of utility rate plans: .. code-block:: json { "items": [ { "label": "67575942fe4f0b50f5027994", "uri": "https://apps.openei.org/IURDB/rate/view/67575942fe4f0b50f5027994", "approved": true, "is_default": false, "utility": "Pacific Gas & Electric Co", "eiaid": 14328, "name": "E-1 -Residential Service Baseline Region Y", "startdate": 1727766000, "sector": "Residential", "servicetype": "Bundled", "description": "This schedule is applicable to single-phase and polyphase residential service...", "energyratestructure": [ [ { "max": 10.5, "unit": "kWh daily", "rate": 0.40206 }, { "max": 42, "unit": "kWh daily", "rate": 0.50323 } ] ], "energyweekdayschedule": [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1] ], "energyweekendschedule": [ [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1] ] } ] } Response Fields """"""""""""""""""" .. list-table:: :widths: 25 15 60 :header-rows: 1 * - Field - Type - Description * - ``utility`` - string - Name of the utility company * - ``eiaid`` - integer - EIA (Energy Information Administration) utility ID * - ``name`` - string - Rate plan name * - ``startdate`` - integer - Unix timestamp when rate plan becomes effective * - ``energyratestructure`` - array - Tiered rate structure by season and tier * - ``energyweekdayschedule`` - array - 24-hour schedule by month (0=off-peak, 1=on-peak) * - ``energyweekendschedule`` - array - 24-hour weekend schedule by month * - ``mincharge`` - float - Minimum daily charge * - ``fixedchargeunits`` - string - Units for fixed charges (e.g., ``$/month``) Rate Structure ~~~~~~~~~~~~~~ The ``energyratestructure`` field contains tiered pricing: * Each outer array element represents a season or month * Each inner array element represents a usage tier * ``rate`` field contains the price per kWh * ``max`` field indicates the upper limit for that tier (optional) Hour-by-Hour Schedules ~~~~~~~~~~~~~~~~~~~~~~ The ``energyweekdayschedule`` and ``energyweekendschedule`` arrays map rate periods: * 12 elements (one per month) * Each month has 24 elements (one per hour) * Values map to indices in ``energyratestructure`` * ``0`` typically represents off-peak, ``1`` represents on-peak TOU API Methods --------------- The library provides methods for working with TOU information through both REST API and MQTT. REST API: Get TOU Info ~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python async def get_tou_info( mac_address: str, additional_value: str, controller_id: str, user_type: str = "O" ) -> TOUInfo Retrieves stored TOU configuration from the Navien cloud API. **Parameters:** * ``mac_address``: Device MAC address * ``additional_value``: Additional device identifier * ``controller_id``: Controller serial number * ``user_type``: User type (default: ``"O"`` for owner) **Returns:** ``TOUInfo`` object containing: .. code-block:: python @dataclass class TOUInfo: register_path: str # Path where TOU data is stored source_type: str # Source of rate data (e.g., "openei") controller_id: str # Controller serial number manufacture_id: str # Manufacturer ID name: str # Rate plan name utility: str # Utility company name zip_code: int # ZIP code schedule: List[TOUSchedule] # TOU schedule periods REST API: Convert TOU Rate Plans ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python async def convert_tou( source_data: List[Dict[str, Any]], source_type: str = "openei", source_version: int = 7 ) -> List[ConvertedTOUPlan] Sends raw OpenEI rate plan data to the Navien backend for conversion into device-ready TOU schedules with season/week bitfields and scaled pricing. **Parameters:** * ``source_data``: List of OpenEI rate plan dictionaries (from ``OpenEIClient.fetch_rates()``) * ``source_type``: Data source type (default: ``"openei"``) * ``source_version``: OpenEI API version (default: ``7``) **Returns:** List of ``ConvertedTOUPlan`` objects, each containing: * ``utility``: Utility company name * ``name``: Rate plan name * ``schedule``: List of ``TOUSchedule`` with device-ready intervals REST API: Apply TOU Rate Plan ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python async def update_tou( mac_address: str, additional_value: str, tou_info: Dict[str, Any], source_data: Dict[str, Any], zip_code: str, register_path: str = "wifi", source_type: str = "openei", user_type: str = "O" ) -> TOUInfo Applies a converted TOU rate plan to a device. **Parameters:** * ``mac_address``: Device MAC address * ``additional_value``: Additional device identifier * ``tou_info``: Converted TOU schedule (from ``convert_tou()``) * ``source_data``: Original OpenEI rate plan dictionary * ``zip_code``: Service area zip code * ``register_path``: Connection type (``"wifi"`` or ``"bt"``) **Returns:** ``TOUInfo`` object with the applied configuration. OpenEI Client ~~~~~~~~~~~~~ .. code-block:: python from nwp500 import OpenEIClient async with OpenEIClient() as client: # List utilities for a zip code utilities = await client.list_utilities("94903") # List rate plans (optionally filtered by utility) plans = await client.list_rate_plans("94903", utility="Pacific Gas") # Get a specific rate plan plan = await client.get_rate_plan("94903", "EV Rate A") The ``OpenEIClient`` reads the API key from the ``OPENEI_API_KEY`` environment variable or accepts it as a constructor parameter. Get a free key at https://openei.org/services/api/signup/ MQTT: Configure TOU Schedule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python async def configure_tou_schedule( device: Device, controller_serial_number: str, periods: List[Dict[str, Any]], enabled: bool = True ) -> None Configures the TOU schedule directly on the device via MQTT. **Parameters:** * ``device``: Device object from API * ``controller_serial_number``: Controller serial number (obtain via device info) * ``periods``: List of TOU period dictionaries (up to 16 periods) * ``enabled``: Whether to enable TOU scheduling (default: ``True``) MQTT: Enable/Disable TOU ~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python async def set_tou_enabled( device: Device, enabled: bool ) -> None Enables or disables TOU operation without changing the schedule. **Parameters:** * ``device``: Device object * ``enabled``: ``True`` to enable TOU, ``False`` to disable MQTT: Request TOU Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python async def request_tou_settings( device: Device, controller_serial_number: str ) -> None Requests the current TOU configuration from the device. **Parameters:** * ``device``: Device object * ``controller_serial_number``: Controller serial number The device will respond on the topic: .. code-block:: text cmd/{deviceType}/{deviceId}/res/tou/rd Building TOU Periods -------------------- Helper Methods ~~~~~~~~~~~~~~ The library provides helper functions for building TOU period configurations: build_tou_period() """""""""""""""""" .. code-block:: python def build_tou_period( season_months: Union[List[int], range], week_days: List[str], start_hour: int, start_minute: int, end_hour: int, end_minute: int, price_min: float, price_max: float, decimal_point: int = 5 ) -> Dict[str, Any] Creates a TOU period configuration dictionary. **Parameters:** * ``season_months``: List of months (1-12) when this period applies * ``week_days``: List of day names (e.g., ``["Monday", "Tuesday"]``) * ``start_hour``: Start hour (0-23) * ``start_minute``: Start minute (0-59) * ``end_hour``: End hour (0-23) * ``end_minute``: End minute (0-59) * ``price_min``: Minimum electricity price ($/kWh) * ``price_max``: Maximum electricity price ($/kWh) * ``decimal_point``: Number of decimal places for price encoding (default: 5) **Returns:** Dictionary with encoded TOU period data ready for MQTT transmission. encode_price() """""""""""""" .. code-block:: python def encode_price(price: float, decimal_point: int = 5) -> int Encodes a floating-point price into an integer for transmission. **Example:** .. code-block:: python from nwp500 import encode_price # Encode $0.45000 per kWh encoded = encode_price(0.45, decimal_point=5) # Returns: 45000 decode_price() """""""""""""" .. code-block:: python def decode_price(encoded_price: int, decimal_point: int = 5) -> float Decodes an integer price back to floating-point. **Example:** .. code-block:: python from nwp500 import decode_price # Decode price from device price = decode_price(45000, decimal_point=5) # Returns: 0.45 encode_week_bitfield() """""""""""""""""""""" .. code-block:: python def encode_week_bitfield(day_names: List[str]) -> int Encodes a list of day names into a bitfield. **Valid day names:** * ``"Monday"`` (bit 6, value 64) * ``"Tuesday"`` (bit 5, value 32) * ``"Wednesday"`` (bit 4, value 16) * ``"Thursday"`` (bit 3, value 8) * ``"Friday"`` (bit 2, value 4) * ``"Saturday"`` (bit 1, value 2) * ``"Sunday"`` (bit 7, value 128) **Example:** .. code-block:: python from nwp500 import encode_week_bitfield # Weekdays only bitfield = encode_week_bitfield([ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" ]) # Returns: 0b1111100 = 124 decode_week_bitfield() """""""""""""""""""""" .. code-block:: python def decode_week_bitfield(bitfield: int) -> List[str] Decodes a bitfield back into a list of day names. **Example:** .. code-block:: python from nwp500 import decode_week_bitfield # Decode weekday bitfield days = decode_week_bitfield(62) # Returns: ["Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"] Usage Examples ============== Example 1: Simple TOU Schedule ------------------------------ Configure two rate periods - off-peak and peak pricing: .. code-block:: python import asyncio from nwp500 import NavienAPIClient, NavienAuthClient, NavienMqttClient, build_tou_period async def configure_simple_tou(): async with NavienAuthClient("user@example.com", "password") as auth_client: # Get device api_client = NavienAPIClient(auth_client=auth_client) device = await api_client.get_first_device() # Connect MQTT and get controller serial mqtt_client = NavienMqttClient(auth_client) await mqtt_client.connect() # Request device info to get controller serial number feature_future = asyncio.Future() def capture_feature(feature): if not feature_future.done(): feature_future.set_result(feature) await mqtt_client.subscribe_device_feature(device, capture_feature) await mqtt_client.request_device_info(device) feature = await asyncio.wait_for(feature_future, timeout=15) controller_serial = feature.controllerSerialNumber # Define off-peak period (midnight to 2 PM, weekdays) off_peak = build_tou_period( season_months=range(1, 13), # All months week_days=["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"], start_hour=0, start_minute=0, end_hour=14, end_minute=59, price_min=0.12, # $0.12/kWh price_max=0.12, decimal_point=5 ) # Define peak period (3 PM to 8 PM, weekdays) peak = build_tou_period( season_months=range(1, 13), week_days=["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"], start_hour=15, start_minute=0, end_hour=20, end_minute=59, price_min=0.35, # $0.35/kWh price_max=0.35, decimal_point=5 ) # Configure TOU schedule await mqtt_client.configure_tou_schedule( device=device, controller_serial_number=controller_serial, periods=[off_peak, peak], enabled=True ) print("TOU schedule configured successfully") await mqtt_client.disconnect() asyncio.run(configure_simple_tou()) Example 2: Complex Seasonal Schedule ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Configure different rates for summer and winter: .. code-block:: python async def configure_seasonal_tou(): async with NavienAuthClient("user@example.com", "password") as auth_client: api_client = NavienAPIClient(auth_client=auth_client) device = await api_client.get_first_device() mqtt_client = NavienMqttClient(auth_client) await mqtt_client.connect() # ... get controller_serial (same as Example 1) ... # Summer off-peak (June-September, all day except 2-8 PM) summer_off_peak = build_tou_period( season_months=[6, 7, 8, 9], week_days=["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"], start_hour=0, start_minute=0, end_hour=13, end_minute=59, price_min=0.15, price_max=0.15, decimal_point=5 ) # Summer peak (June-September, 2-8 PM) summer_peak = build_tou_period( season_months=[6, 7, 8, 9], week_days=["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"], start_hour=14, start_minute=0, end_hour=20, end_minute=59, price_min=0.45, price_max=0.45, decimal_point=5 ) # Winter rates (October-May) winter_off_peak = build_tou_period( season_months=[10, 11, 12, 1, 2, 3, 4, 5], week_days=["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"], start_hour=0, start_minute=0, end_hour=13, end_minute=59, price_min=0.10, price_max=0.10, decimal_point=5 ) winter_peak = build_tou_period( season_months=[10, 11, 12, 1, 2, 3, 4, 5], week_days=["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"], start_hour=17, start_minute=0, end_hour=21, end_minute=59, price_min=0.28, price_max=0.28, decimal_point=5 ) # Configure all periods await mqtt_client.configure_tou_schedule( device=device, controller_serial_number=controller_serial, periods=[summer_off_peak, summer_peak, winter_off_peak, winter_peak], enabled=True ) await mqtt_client.disconnect() asyncio.run(configure_seasonal_tou()) Example 3: Retrieve Current TOU Settings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Query the device for its current TOU configuration: .. code-block:: python from nwp500 import decode_week_bitfield, decode_price async def check_tou_settings(): async with NavienAuthClient("user@example.com", "password") as auth_client: api_client = NavienAPIClient(auth_client=auth_client) device = await api_client.get_first_device() mqtt_client = NavienMqttClient(auth_client) await mqtt_client.connect() # ... get controller_serial (same as Example 1) ... # Set up response handler response_topic = f"cmd/{device.device_info.device_type}/{mqtt_client.config.client_id}/res/tou/rd" def on_tou_response(topic: str, message: dict): response = message.get("response", {}) enabled = response.get("reservationUse") periods = response.get("reservation", []) print(f"TOU Enabled: {enabled}") print(f"Number of periods: {len(periods)}") for i, period in enumerate(periods, 1): days = decode_week_bitfield(period.get("week", 0)) price_min = decode_price( period.get("priceMin", 0), period.get("decimalPoint", 0) ) price_max = decode_price( period.get("priceMax", 0), period.get("decimalPoint", 0) ) print(f"\nPeriod {i}:") print(f" Days: {', '.join(days)}") print(f" Time: {period['startHour']:02d}:{period['startMinute']:02d} " f"- {period['endHour']:02d}:{period['endMinute']:02d}") print(f" Price: ${price_min:.5f} - ${price_max:.5f}/kWh") await mqtt_client.subscribe(response_topic, on_tou_response) # Request current settings await mqtt_client.request_tou_settings(device, controller_serial) # Wait for response await asyncio.sleep(5) await mqtt_client.disconnect() asyncio.run(check_tou_settings()) Example 4: Toggle TOU On/Off ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Enable or disable TOU operation: .. code-block:: python async def toggle_tou(enable: bool): async with NavienAuthClient("user@example.com", "password") as auth_client: api_client = NavienAPIClient(auth_client=auth_client) device = await api_client.get_first_device() mqtt_client = NavienMqttClient(auth_client) await mqtt_client.connect() # Enable or disable TOU await mqtt_client.set_tou_enabled(device, enabled=enable) print(f"TOU {'enabled' if enable else 'disabled'}") await mqtt_client.disconnect() # Enable TOU asyncio.run(toggle_tou(True)) # Disable TOU asyncio.run(toggle_tou(False)) Example 5: Apply Rate Plan from OpenEI ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Use the ``OpenEIClient`` and ``convert_tou()``/``update_tou()`` methods to browse, convert, and apply a rate plan from OpenEI. This is the same workflow the Navien mobile app uses: .. code-block:: python import asyncio from nwp500 import ( NavienAPIClient, NavienAuthClient, NavienMqttClient, OpenEIClient, ) async def apply_openei_rate_plan(): async with NavienAuthClient("user@example.com", "password") as auth: api_client = NavienAPIClient(auth_client=auth) device = await api_client.get_first_device() # 1. Browse available rate plans async with OpenEIClient() as openei: rates = await openei.fetch_rates("94903") items = rates.get("items", []) # 2. Convert all plans to device format converted = await api_client.convert_tou(source_data=items) # 3. Find the plan you want plan = next(p for p in converted if "EV" in p.name) # 4. Build tou_info dict for update tou_info = { "name": plan.name, "utility": plan.utility, "schedule": [s.model_dump() for s in plan.schedule], "zipCode": "94903", } # 5. Find matching source data source = next( i for i in items if i.get("name") == plan.name ) # 6. Apply to device result = await api_client.update_tou( mac_address=device.device_info.mac_address, additional_value=str(device.device_info.additional_value), tou_info=tou_info, source_data=source, zip_code="94903", ) print(f"Applied: {result.name} ({result.utility})") # 7. Enable TOU via MQTT mqtt_client = NavienMqttClient(auth) await mqtt_client.connect() await mqtt_client.set_tou_enabled(device, enabled=True) await mqtt_client.disconnect() asyncio.run(apply_openei_rate_plan()) **Notes:** * Set the ``OPENEI_API_KEY`` environment variable before running * Get a free key at https://openei.org/services/api/signup/ * ``convert_tou()`` handles the complex format conversion server-side * The ``update_tou()`` method stores the plan in the Navien cloud * Use ``set_tou_enabled()`` to activate TOU mode on the device MQTT Message Format ------------------- TOU Control Topic ~~~~~~~~~~~~~~~~~ To configure TOU settings, publish to: .. code-block:: text cmd/{deviceType}/{macAddress}/ctrl/tou/rd Message payload: .. code-block:: json { "cmd": "tou", "controllerId": "controller-serial-number", "operation": { "reservationUse": 2, "reservation": [ { "season": 4095, "week": 62, "startHour": 0, "startMinute": 0, "endHour": 14, "endMinute": 59, "priceMin": 12000, "priceMax": 12000, "decimalPoint": 5 } ] }, "requestTopic": "cmd/{deviceType}/{macAddress}/ctrl/tou/rd", "responseTopic": "cmd/{deviceType}/{clientId}/res/tou/rd" } Field Descriptions """""""""""""""""" .. list-table:: :widths: 25 15 60 :header-rows: 1 * - Field - Type - Description * - ``reservationUse`` - integer - ``0`` = disabled, ``2`` = enabled * - ``season`` - integer - Bitfield of months (bit 0 = Jan, ... bit 11 = Dec). ``4095`` = all months * - ``week`` - integer - Bitfield of days (bit 7 = Sun, bit 6 = Mon, ... bit 1 = Sat; bit 0 unused). ``124`` = weekdays * - ``startHour`` - integer - Start hour (0-23) * - ``startMinute`` - integer - Start minute (0-59) * - ``endHour`` - integer - End hour (0-23) * - ``endMinute`` - integer - End minute (0-59) * - ``priceMin`` - integer - Encoded minimum price (see ``encode_price()``) * - ``priceMax`` - integer - Encoded maximum price (see ``encode_price()``) * - ``decimalPoint`` - integer - Number of decimal places in price encoding TOU Response Topic ~~~~~~~~~~~~~~~~~~ The device responds on: .. code-block:: text cmd/{deviceType}/{clientId}/res/tou/rd Response payload matches the control payload format. TOU Status in Device State ~~~~~~~~~~~~~~~~~~~~~~~~~~~ The device status includes TOU-related fields: .. code-block:: json { "touStatus": 1, "touOverrideStatus": 2 } * ``touStatus``: ``1`` if TOU scheduling is enabled/active, ``0`` if disabled/inactive * ``touOverrideStatus``: ``2`` (ON) = TOU schedule is operating normally, ``1`` (OFF) = user has overridden TOU to force immediate heating See :doc:`../reference/protocol/device_status` for more details. Best Practices -------------- 1. **Obtain controller serial number first** The controller serial number is required for TOU operations. Request it via device info before configuring TOU. 2. **Limit number of periods** The device supports up to 16 TOU periods. Design schedules efficiently to stay within this limit. 3. **Use appropriate decimal precision** Use ``decimal_point=5`` for most rate plans, which provides precision down to $0.00001/kWh. 4. **Validate overlapping periods** Ensure time periods don't overlap within the same day and month combination. 5. **Test with simulation** Use ``set_tou_enabled(False)`` to disable TOU temporarily for testing without losing the schedule. 6. **Monitor response topics** Always subscribe to response topics before sending commands to confirm successful configuration. 7. **Handle timeouts gracefully** Use ``asyncio.wait_for()`` with appropriate timeouts when waiting for device responses. Limitations ----------- * Maximum 16 TOU periods per configuration * Time resolution limited to minutes (no seconds) * Price encoding limited by decimal point precision * Cannot specify different rates for individual days within a period * No support for variable rate structures (e.g., tiered rates) - only flat rate per period Further Reading --------------- * :doc:`../reference/python_api/api_client` - API client documentation and ``get_tou_info()`` method * :doc:`../reference/python_api/mqtt_client` - MQTT client and TOU configuration methods * :doc:`../reference/protocol/mqtt_protocol` - MQTT message formats including TOU commands * :doc:`../reference/protocol/device_status` - Device status fields including ``touStatus`` * `OpenEI Utility Rates API `__ - Official OpenEI API documentation * `OpenEI IURDB `__ - Interactive Utility Rate Database Related Examples ---------------- * ``examples/tou_schedule_example.py`` - Complete working example of manual TOU configuration * ``examples/tou_openei_example.py`` - Retrieve TOU schedules from OpenEI API and configure device CLI Commands ~~~~~~~~~~~~ The CLI provides commands for the full TOU workflow: .. code-block:: bash # List utilities and rate plans for a zip code nwp500 tou rates 94903 nwp500 tou rates 94903 --utility "Pacific Gas" # View converted rate plan details nwp500 tou plan 94903 "EV Rate A" # Apply a rate plan to the water heater nwp500 tou apply 94903 "EV Rate A" nwp500 tou apply 94903 "EV Rate A" --enable # also enable TOU For questions or issues related to TOU functionality, please refer to the project repository.