Query API using curl?
I'm trying to set up some scripts to pull data from the OpenAPI to save and work with locally. My preferred method would be to use curl as I'm not very familiar with python at the moment. Does anyone have some simple examples of authenticating and querying using curl? Once I'm able to connect I think I'll be able to get what I want but I'm struggling with the initial steps.

Thanks in advance
Re: Query API using curl?
Sorry to dig up an old topic, but have you found a solution?
I'm looking for the same thing, only I want to specifically address the "export_limit_power" and change it at will.

My contract with the electric company that buys from me, has an upper kwh limit, so what I'm looking for is a way to have Home Assistant lowering my production to the limit when I'm producing too much or not consuming enough.
User avatar
Site Admin
Re: Query API using curl?
I can't find the post but I'm sure I've seen a post that states the register that you can write to using the Home Assistant Modbus integration to directly set the export limit.
Community Admin / FoxESS Elite Professional

Image Did I help you? Feel free to leave me a tip
Image Book a zoom meeting for remote consultancy or help
Image Switch to Octopus and earn £50
Image Get a heatpump from Octopus and earn £100
Image Subscribe to my YouTube channel

Fox ESS Tri Inverter Installation
2 x KH Hybird Inverters (Parallel Mode)
1 x H1 Gen1
24 x HV2600 (62.4kWh)
32 x 490w across 4 arrays
Dual Tesla Household
Heatpump & Low Carbon Housebuild
Re: Query API using curl?
Here you go this is the address and topic it’s on https://foxesscommunity.com/viewtopic.php?p=8082#p8082

And looks like someone tried it and works here https://foxesscommunity.com/viewtopic.php?p=8737#p8737
Re: Query API using curl?
TY Will and Dave, but I don't have a clue on how to read and write registers using modbus.
I already have (partial) modbus connectivity, and am using FoxESS - Modbus integration, but I cant figure out how to read or write in specific registers.
(I say partial BC my device is unsupported, so I had to trick the integration).

Is there another integration I can use to read/write?
Re: Query API using curl?
If you have the integration running (even partially), it exposes a number of services that you can use as actions.

To test it for example in HA go to Developer Tools, Actions, start to type Foxess - Modbus and choose the ‘read registers’ option.

Then select your inverter, enter the Start Address 41012, count 2 and input - click perform action and you should see a response.

You can then use these actions in automations and read the registers back into helper input numbers, equally you can also write to the inverter using the write registers service.
Re: Query API using curl?
Dave Foster wrote: Wed Sep 24, 2025 4:04 pm If you have the integration running (even partially), it exposes a number of services that you can use as actions.

To test it for example in HA go to Developer Tools, Actions, start to type Foxess - Modbus and choose the ‘read registers’ option.

Then select your inverter, enter the Start Address 41012, count 2 and input - click perform action and you should see a response.

You can then use these actions in automations and read the registers back into helper input numbers, equally you can also write to the inverter using the write registers service.
OMG you're amazing. I didn't even knew about dev tools.

1st try, with only 1 read I got

Code: Select all

values:
  "41012": 30000
So then, I wen to foxesscloud and changed the value to "23456"

2nd try:

Code: Select all

values:
  "41012": 23456
Success! This is exactly the pointer I need.

Then I tested "foxess_modbus.write_registers" setting it to 20000 and when I read it, it was 20000

Code: Select all

values:
  "41012": 20000
Now I just have to figure out how to turn this into an action that I can call when solar production is too high, but I believe I can do it from this point.

You're the best man! Cheers
Re: Query API using curl?
If it helps anyone in the future, this is the automation I've ended up doing:

Code: Select all

alias: Limite Solar 4kW
triggers:
  - minutes: /5
    trigger: time_pattern
actions:
  - data:
      inverter: ***redacted***
      values: "{{ varcalc }}"
      start_address: 41012
    action: foxess_modbus.write_registers
variables:
  MaxExportLimit: 3900
  current_power: "{{ states('sensor.active_power') | int(0) }}"
  varcalc: "{{ MaxExportLimit - current_power}}"
mode: single
A little back story: I have an older solar inverter from another brand with the respective battery, operating independently from this new one, and because I don't want to go above 4kW, i'm reading the total injection to the grid on my sensor "sensor.active_power" and subtracting enough from the new inverter so the total export stays below 3900.
I don't go to the trouble of actually measuring how much fox is injecting because the older system is not capable of going above 3k, meaning I only need to adjust the new one if I'm not consuming enough in house.

Again. Thank you all for you assitance on this.
Re: Query API using curl?
If I am reading you correctly, I don't think you need to adjust the export limit dynamically at all. The Fox inverter reads the total export to the grid (from both inverters).

When you set an export limit on the Fox inverter, it applies to the total. So, if you just set the export limit to 3900, this will do what you want.

For example, if you existing solar is exporting 2kW, your Fox inverter will be limited to 1.9kW after your house load has been met.
H1-6.0-E hybrid inverter
6 x HV2600 v2 batteries
16 x JA Solar 405w panels
7 x Tigo TS4-A-O optimisers
Re: Query API using curl?
tony.matthews1 wrote: Wed Sep 24, 2025 6:49 pm If I am reading you correctly, I don't think you need to adjust the export limit dynamically at all. The Fox inverter reads the total export to the grid (from both inverters).

When you set an export limit on the Fox inverter, it applies to the total. So, if you just set the export limit to 3900, this will do what you want.

For example, if you existing solar is exporting 2kW, your Fox inverter will be limited to 1.9kW after your house load has been met.
The problem is that my fox inverter is not connected to the main circuit breaker from the electric company, instead is installed on my mancave which is away from the main house, so it has no way to measure anything except what it's producing and injecting on that spot.

But yes, if that's how they work, that would be way simpler.
Re: Query API using curl?
Update on the code. I was simply subtracting the current injection to the grid from my set maximum limit, meaning I was getting very low numbers and the injection was jumping around like crazy.
I came to the obvious conclusion (duh) that I needed to know the current max value from the inverter, so I simply created a helper of the type input number in HO and used it as a global variable. That solved my issue and now I also have a tile in my energy tab showing me my inverter current max inject power.

Heres the corrected automation if anyone wants it:

Code: Select all

alias: Limite Solar 4kW
description: ""
triggers:
  - minutes: /1
    trigger: time_pattern
conditions:
  - condition: template
    value_template: |
      {{ states('sensor.active_power')|int(0) > LimiteMax or
         states('sensor.active_power')|int(0) < LimiteMin }}
actions:
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ states('input_number.maxexportatual') == 'unknown' }}"
        sequence:
          - target:
              entity_id: input_number.maxexportatual
            data:
              value: 4000
            action: input_number.set_value
  - data:
      inverter: ****removed****
      values: "{{ varcalc2 | int }}"
      start_address: 41012
    action: foxess_modbus.write_registers
  - target:
      entity_id: input_number.maxexportatual
    data:
      value: "{{ varcalc2 | int }}"
    action: input_number.set_value
variables:
  LimiteMax: 4000
  LimiteMin: 3800
  MaxExportLimit: 3900
  current_power: "{{ states('sensor.active_power') | int(0) }}"
  max_export_atual: "{{ states('input_number.maxexportatual') | default('4000') | int }}"
  varcalc: "{{ MaxExportLimit - current_power + max_export_atual }}"
  varcalc2: |-
    {% if varcalc < 500 %}
      500
    {% elif varcalc > 5300 %}
      5300
    {% else %}
      {{ varcalc }}
    {% endif %}
mode: single
It checks if the current injection is below 3800 or above 4000 and only runs if it is, and finaly checks if the variable being written is below 500 or above 5300 and if it is, it writes those values instead.
Post Reply