From e4e04f3a1d7828cf74413322b87d5bad32d484d0 Mon Sep 17 00:00:00 2001 From: Iwan van Staveren Date: Sun, 26 Apr 2026 17:30:54 +0200 Subject: [PATCH 1/2] ``` Discussion 142 feat: add convenience methods for classic inverter control ``` --- examples/settings_example_classic.py | 29 ++++++++-------- growattServer/base_api.py | 50 ++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 13 deletions(-) diff --git a/examples/settings_example_classic.py b/examples/settings_example_classic.py index 14c64a7..d020ea7 100644 --- a/examples/settings_example_classic.py +++ b/examples/settings_example_classic.py @@ -70,19 +70,22 @@ on_off = inverter_info["onOff"] print(f"Inverter on/off status: {'on' if on_off == '1' else 'off'}") -# Turn inverter on +# Turn inverter on using the convenience method print(f"Turning on inverter: {device_sn}") +response = api.set_classic_inverter_on_off(device_sn, enabled=True) +print(response) + +# Turn inverter off +print(f"Turning off inverter: {device_sn}") +response = api.set_classic_inverter_on_off(device_sn, enabled=False) +print(response) + +# Set active power rate to 50% (limits output power to 50% of rated capacity) +print(f"Setting active power rate to 50% for inverter: {device_sn}") +response = api.set_classic_inverter_active_power_rate(device_sn, power_rate=50) +print(response) -# Set up the default parameters -default_parameters = { - "action": "inverterSet", - "serialNum": device_sn, -} - -parameters = { - "paramId": "pv_on_off", - "command_1": "0001", # 0001 to turn on, 0000 to turn off - "command_2": "", # Empty string for command_2 as not used -} -response = api.update_classic_inverter_setting(default_parameters, parameters) +# Set active power rate back to 100% (full power output) +print(f"Setting active power rate to 100% for inverter: {device_sn}") +response = api.set_classic_inverter_active_power_rate(device_sn, power_rate=100) print(response) diff --git a/growattServer/base_api.py b/growattServer/base_api.py index 4449496..e851e92 100644 --- a/growattServer/base_api.py +++ b/growattServer/base_api.py @@ -1402,3 +1402,53 @@ def update_classic_inverter_setting(self, default_parameters, parameters): params=settings_parameters) return response.json() + + def set_classic_inverter_active_power_rate(self, serial_number, power_rate): + """ + Set the active power rate (output power limit) for a classic inverter. + + Args: + serial_number: Inverter serial number. + power_rate: Active power rate as percentage (0-100). + + Returns: + dict: Server JSON response. + + """ + default_parameters = { + "action": "inverterSet", + "serialNum": serial_number, + } + + parameters = { + "paramId": "pv_active_p_rate", + "command_1": str(power_rate), + "command_2": "", + } + + return self.update_classic_inverter_setting(default_parameters, parameters) + + def set_classic_inverter_on_off(self, serial_number, enabled): + """ + Turn a classic inverter on or off. + + Args: + serial_number: Inverter serial number. + enabled: True to turn on, False to turn off. + + Returns: + dict: Server JSON response. + + """ + default_parameters = { + "action": "inverterSet", + "serialNum": serial_number, + } + + parameters = { + "paramId": "pv_on_off", + "command_1": "0001" if enabled else "0000", + "command_2": "", + } + + return self.update_classic_inverter_setting(default_parameters, parameters) From a520c65e31aa1aadaa23ccc00eb5d1dc599097a6 Mon Sep 17 00:00:00 2001 From: Iwan van Staveren Date: Sun, 26 Apr 2026 18:46:30 +0200 Subject: [PATCH 2/2] Discussion 142 docs: add classic inverter control methods to API reference table --- docs/shinephone.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/shinephone.md b/docs/shinephone.md index 6b6ca2a..d2084f4 100644 --- a/docs/shinephone.md +++ b/docs/shinephone.md @@ -65,6 +65,8 @@ Any methods that may be useful. | `api.update_noah_settings(serial_number, setting_type, parameters)` | serial_number: String, setting_type: String, parameters: Dict/Array | Apply the provided parameters for the specified setting on the specified Noah device. see: [details](./shinephone/noah_settings.md) | | `api.update_classic_inverter_setting(default_parameters, parameters)` | default_parameters: Dict, parameters: Dict/Array | Applies settings for specified system based on serial number. This function is only going to work for classic inverters. | | `api.classic_inverter_info(device_sn)` | device_sn: String | Get classic inverter information (including on/off status) by scraping the inverter settings page. Returns a dict with fields like `onOff`, `deviceModel`, `status`, `fwVersion`, `sn`, `alias`, etc. Note: this works by parsing HTML, not a JSON API. | +| `api.set_classic_inverter_active_power_rate(serial_number, power_rate)` | serial_number: String, power_rate: Int (0-100) | Set the active power rate (output power limit) for a classic inverter. Power rate is a percentage of the inverter's rated capacity (e.g., 50 = 50% output). | +| `api.set_classic_inverter_on_off(serial_number, enabled)` | serial_number: String, enabled: Bool | Turn a classic inverter on (`enabled=True`) or off (`enabled=False`). When off, the inverter stops producing power completely. | ### Variables @@ -102,4 +104,4 @@ This is based on the endpoints used on the mobile app and could be changed witho The settings for the Plant and Inverter have been reverse engineered by using the ShinePhone Android App and the NetCapture SSL application together to inspect the API calls that are made by the application and the parameters that are provided with it. -See: [Reverse Engineered](./shinephone/reverse_engineering.md) \ No newline at end of file +See: [Reverse Engineered](./shinephone/reverse_engineering.md)