# Solar system from APsystems

**URL:** <https://community.homey.app/t/solar-system-from-apsystems/74759>\
**Category:** Questions & Help\
**Created:** [January 8, 2023, 1:12pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759 "2023-01-08T13:12:33Z")\
**Posts on this page:** 20\
**Page:** 4

<div class="post-metadata">

**Author:** ![Dick\_J](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/dick_j/32/79161_2.png) [@Dick\_J](https://community.homey.app/u/Dick_J)\
**Post date:** [April 10, 2025, 5:29pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/65 "2025-04-10T17:29:48Z")

</div>

I’m trying to access the API. Requested an API key and -secret from AP-Systems and got that without any issues. Also without an invoice 😉  
I’m not a developer, just tinkering and googling a lot.  
Thus far I seem to be able to send a request to the web API, but the only result I get is '[200[ (which is ‘success’) and then ‘code 4000’, which is ‘request parameter exception’.  
I got in touch with APsystems again, found that the timestamp should be in milliseconds, but no luck yet with retrieving JSON info from the APS site.  
This is a snippet from my code, feel free to correct this.

> #Variabelen  
> base\_url = “[https://api.apsystemsema.com:9282](https://api.apsystemsema.com:9282)”  
> nonce = str(uuid.uuid4()).replace(‘-’,‘’)  
> ts = int((time.time()\*1000))  
> timestamp = str(ts)
> 
> #request\_path = f"user/api/v2/systems/details/{sid}"
> 
> request\_path = f"user/api/v2/systems/details/{sid}"  
> string\_to\_sign = f"{timestamp}/{nonce}/{api\_key}/{request\_path}/GET/HmacSHA256"  
> string\_bytes = string\_to\_sign.encode(‘utf-8’)  
> api\_bytes = api\_secret.encode(‘utf-8’)  
> encrypted = hmac.new(api\_bytes, msg = string\_bytes, digestmod = hashlib.sha256).digest()  
> signature = str(base64.b64encode(encrypted)).replace(‘b’,‘’)  
> print("Hmac: ", signature)
> 
> header = {  
> ‘X-CA-AppId’: api\_key,  
> ‘X-CA-Timestamp’: timestamp,  
> ‘X-CA-Nonce’: nonce,  
> ‘X-CA-Signature-Method’: ‘HmacSHA256’,  
> ‘X-CA-Signature’: signature  
> }
> 
> url = f"{base\_url}/{request\_path}"  
> print (url)
> 
> response = requests.get(url = url, headers = header)  
> response.raise\_for\_status() # Controleer op HTTP-fouten  
> print(response)
> 
> if response.status\_code == 200:  
> print(“Succes:”, response.json())  
> print(“Headers:”, response.headers)  
> print(response.url)  
> solar\_data = response.json()  
> else:  
> print(“Fout:”, response.status\_code, response.text)

---

<div class="post-metadata">

**Author:** ![Rob\_G](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rob_g/32/79108_2.png) [@Rob\_G](https://community.homey.app/u/Rob_G)\
**Post date:** [April 10, 2025, 6:23pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/67 "2025-04-10T18:23:29Z")

</div>

I posted the API manual after getting an API key (for free from within my APSystems app). I can successfully connect to the ECU, but I get a (described) error because I couldn’t get the hashed data right. So, it seems this route work…if I can get some help with the code 😉

---

<div class="post-metadata">

**Author:** ![Rob\_G](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rob_g/32/79108_2.png) [@Rob\_G](https://community.homey.app/u/Rob_G)\
**Post date:** [April 10, 2025, 6:39pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/68 "2025-04-10T18:39:01Z")

</div>

Hi @Dick_J , thanks for posting your code. Did you run this in a HomeyScript? I copy/pasted it in a script on my Homey, but unfortunately it won’t run because of various errors on functions. I think Homey runs node.js. Where did you run this on?

---

<div class="post-metadata">

**Author:** ![Dick\_J](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/dick_j/32/79161_2.png) [@Dick\_J](https://community.homey.app/u/Dick_J)\
**Post date:** [April 10, 2025, 7:26pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/69 "2025-04-10T19:26:20Z")

</div>

Hi Rob, I ran this in visual studio code, in Python . I got a piece of code from AP systems as well, this was written for Postman (?). See pictures. This is a bit like JavaScript

 ![D2EA90D3@E91B8468.CA78F76700000000](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/f/a/fab98df6194c787c0156765bac3887e8a87fc4da.png)  
 ![3A7A318C@B420A15D.CA78F76700000000](https://us1.discourse-cdn.com/flex025/uploads/athom/original/3X/5/1/5199e67ef22bd6654d76ec0cb96fc01500fef6d2.png)

---

<div class="post-metadata">

**Author:** ![Rob\_G](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rob_g/32/79108_2.png) [@Rob\_G](https://community.homey.app/u/Rob_G)\
**Post date:** [April 10, 2025, 7:49pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/70 "2025-04-10T19:49:56Z")

</div>

Hi @Dick_J I see. That’s why it won’t run 🙂

I can’t get it converted to JS on Homey’s node implementation, because it lacks the functions you use. I got the code to connect, working, but the hashing I don’t know.

---

<div class="post-metadata">

**Author:** ![Dick\_J](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/dick_j/32/79161_2.png) [@Dick\_J](https://community.homey.app/u/Dick_J)\
**Post date:** [April 11, 2025, 6:36am UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/71 "2025-04-11T06:36:42Z")

</div>

That’s also where my problem is I think

---

<div class="post-metadata">

**Author:** ![Rob\_G](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rob_g/32/79108_2.png) [@Rob\_G](https://community.homey.app/u/Rob_G)\
**Post date:** [April 20, 2025, 6:38pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/72 "2025-04-20T18:38:21Z")

</div>

Hi @Dick_J Did you ever got your Python code to work?

---

<div class="post-metadata">

**Author:** ![Patrick\_Van\_Deursen](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/patrick_van_deursen/32/56539_2.png) [@Patrick\_Van\_Deursen](https://community.homey.app/u/Patrick_Van_Deursen)\
**Post date:** [April 20, 2025, 7:15pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/73 "2025-04-20T19:15:29Z")

</div>

some action going on here: [AP Systems support · Issue #68 · DiedB/Homey-SolarPanels · GitHub](https://github.com/DiedB/Homey-SolarPanels/issues/68#issuecomment-2816217791), though no conclusions there yet

---

<div class="post-metadata">

**Author:** ![Dick\_J](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/dick_j/32/79161_2.png) [@Dick\_J](https://community.homey.app/u/Dick_J)\
**Post date:** [April 22, 2025, 7:10pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/74 "2025-04-22T19:10:30Z")

</div>

Hi Rob, unfortunately not. There must be something going wrong with calculating the signature. I moved over to the app development environment, and there it worked, but of course it uses JavaScript. Crypto is not supported in Homey script, so this doesn’t work there.  
I called out to Diederik (see reply from Patrick), because there’s already something that works.

> // Requirements  
> const Homey = require(“homey”);  
> const crypto = require(“crypto”);  
> const { v4: uuidv4 } = require(“uuid”);  
> const fetch = require(“node-fetch”); // Voor Node.js, anders browser fetch
> 
> // Signature data  
> const api\_key = Homey.env.CLIENT\_ID;  
> const api\_secret = Homey.env.CLIENT\_SECRET;  
> const sid = Homey.env.CLIENT\_SID;  
> const signature\_method = “HmacSHA256”;  
> const nonce = uuidv4().replace(/-/g, “”);  
> const ts = Date.now();  
> const timestamp = ts.toString();
> 
> // Request data  
> const base\_url = “[https://api.apsystemsema.com:9282](https://api.apsystemsema.com:9282)”;  
> const request\_path = “/user/api/v2/systems/details/” + sid;  
> const http\_method = “GET”;
> 
> // Create string to sign  
> var urlSegments = request\_path.split(“/”);  
> var lastSegment = urlSegments[urlSegments.length - 1];  
> const stringToSign = `${timestamp}/${nonce}/${api_key}/${lastSegment}/${http_method}/${signature_method}`;
> 
> // Calculate signature  
> const hmacSha256 = crypto.createHmac(“sha256”, api\_secret);  
> hmacSha256.update(stringToSign);  
> const signature = hmacSha256.digest(“base64”);
> 
> //Create headers  
> const header = {  
> “X-CA-AppId”: api\_key,  
> “X-CA-Timestamp”: timestamp,  
> “X-CA-Nonce”: nonce,  
> “X-CA-Signature-Method”: “HmacSHA256”,  
> “X-CA-Signature”: signature,  
> };
> 
> // Create the full url  
> const url = base\_url + request\_path;  
> console.log(getpower);
> 
> // Make a GET request  
> fetch(url, { headers: header })  
> .then((response) =\> {  
> if (!response.ok) {  
> throw new Error(“Network response was not ok”);  
> }  
> return response.json();  
> })  
> .then((data) =\> {  
> console.log(data);  
> })  
> .catch((error) =\> {  
> console.error(“Error:”, error);  
> });
> 
> class Driver extends Homey.Driver {  
> async onPair(session) {  
> const devices = “AP Systems”
> 
> }  
> }
> 
> module.exports = Driver;

---

<div class="post-metadata">

**Author:** ![Rob\_G](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rob_g/32/79108_2.png) [@Rob\_G](https://community.homey.app/u/Rob_G)\
**Post date:** [April 22, 2025, 7:25pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/75 "2025-04-22T19:25:31Z")

</div>

Thanks @Dick_J . Guess we have to wait for better code 😉

---

<div class="post-metadata">

**Author:** ![Steven\_Bareman](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/steven_bareman/32/31404_2.png) [@Steven\_Bareman](https://community.homey.app/u/Steven_Bareman)\
**Post date:** [April 27, 2025, 6:49pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/76 "2025-04-27T18:49:43Z")

</div>

I found this web link with a option to switch on and off with a flow card. (I did not test this already)

> **[Je APsystems micro-omvormers slim uitzetten via web of Home Assistant...](https://doe-duurzaam.nl/artikel/je-apsystems-micro-omvormers-slim-uitzetten-via-web-of-home-assistant/)**
>
> How-to: je APsystems micro-omvormers slim aansturen en uitschakelen via web of Home Assistant bij negatieve dynamische energieprijzen.

---

<div class="post-metadata">

**Author:** ![doyouevencomputer](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/doyouevencomputer/32/126741_2.png) [@doyouevencomputer](https://community.homey.app/u/doyouevencomputer)\
**Post date:** [April 28, 2025, 3:57am UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/77 "2025-04-28T03:57:07Z")

</div>

I’m not a Homey user, but I stumbled upon this thread searching for how to get the API to work from the manual referenced.

After some trial and error, I was able to get data back using this python script. Hopefully that helps you out.

```auto
import hashlib
import hmac
import base64
import uuid
import time
import requests,urllib
import config

# Replace these with your actual API details
APP_ID = config.app_id
APP_SECRET = config.secret
API_BASE = "https://api.apsystemsema.com:9282"
REQUEST_PATH = "/user/api/v2/systems/details/"+config.sid
API_URL = API_BASE+REQUEST_PATH
HTTP_METHOD = "GET" # or "POST", "DELETE", depending on the API call
SIGNATURE_METHOD = "HmacSHA256" # or "HmacSHA1"

# Generate the required headers and signature
def generate_signature():
   # timestamp = str(int(time.time()))
    timestamp = str(int(time.time() * 1000))
    nonce = str(uuid.uuid4()).replace("-", "")
    
    path_part = REQUEST_PATH.rsplit("/",1)[1]
    # Build the string to sign
    string_to_sign = f"{timestamp}/{nonce}/{APP_ID}/{path_part}/{HTTP_METHOD}/{SIGNATURE_METHOD}"
    
    # Create the signature using HMAC with SHA256 or SHA1
    if SIGNATURE_METHOD == "HmacSHA256":
        signature = hmac.new(APP_SECRET.encode("utf-8"), string_to_sign.encode("utf-8"), hashlib.sha256).digest()
    elif SIGNATURE_METHOD == "HmacSHA1":
        signature = hmac.new(APP_SECRET.encode("utf-8"), string_to_sign.encode("utf-8"), hashlib.sha1).digest()
    else:
        raise ValueError("Unsupported signature method")

    # Base64 encode the signature
    return base64.b64encode(signature).decode("utf-8"), timestamp, nonce

# Make the API request with the required headers
def make_api_request():
    signature, timestamp, nonce = generate_signature()

    headers = {
        "X-CA-AppId": APP_ID,
        "X-CA-Timestamp": timestamp,
        "X-CA-Nonce": nonce,
        "X-CA-Signature-Method": SIGNATURE_METHOD,
        "X-CA-Signature": signature
    }

    # Send the request
    response = requests.get(API_URL, headers=headers)
    
    # Handle response
    if response.status_code == 200:
        print("Request successful:", response.json())
    else:
        print(f"Request failed with status code {response.status_code}:", response.text)

# Run the request
make_api_request()

```

---

<div class="post-metadata">

**Author:** ![Rob\_G](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rob_g/32/79108_2.png) [@Rob\_G](https://community.homey.app/u/Rob_G)\
**Post date:** [May 3, 2025, 9:16am UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/78 "2025-05-03T09:16:21Z")

</div>

Hi @doyouevencomputer I tried your code and yes, I do get a response from the APSystems API. However, the response is OK (200) with subcode 4000, which is a “Request parameter exception”.  
Same result as @Dick_J I guess.

When you say that “I was able to get data back using this python script”, do you mean you got back actual data, or did you also get the 4000 code?

---

<div class="post-metadata">

**Author:** ![doyouevencomputer](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/doyouevencomputer/32/126741_2.png) [@doyouevencomputer](https://community.homey.app/u/doyouevencomputer)\
**Post date:** [May 3, 2025, 11:41am UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/79 "2025-05-03T11:41:17Z")

</div>

I get data back, I copied the code from this post just to be sure, here is what I get back:

Request successful: {‘code’: 0, ‘data’: {‘timezone’: ‘US/Central’, ‘ecu’: [‘XXXXXXXXXXXXX’], ‘create\_date’: ‘2023-02-28’, ‘type’: 1, ‘sid’: ‘XXXXXXXXXXXXXXXX’, ‘capacity’: ‘18.72’}}

My config.py file in the same directory looks like this

secret = “0123456789ab”. # 12 char string  
app\_id = “0123456789abcdef0123456789abcdef” # 32 char string

If either of these are wrong (same length but change 1 character), I get the 4000 response.

I got the app\_id and secret from the [https://www.apsystemsema.com](https://www.apsystemsema.com) portal under Setting \> OpenAPI Service \> Developer Authorization.

Interestingly, under “Historical Call Statistics” I still see 0 for all months even though I was using the above code with many other endpoints to get various details:

Here are some others that require your sid and/or ecu:

```auto
REQUEST_PATH = "/user/api/v2/systems/details/"+config.sid
REQUEST_PATH = "/user/api/v2/systems/inverters/"+config.sid
REQUEST_PATH = "/user/api/v2/systems/summary/"+config.sid
REQUEST_PATH = f"/user/api/v2/systems/{config.sid}/devices/ecu/summary/{config.ecu}"

```

If you’ve only ever got a 4000 error, maybe you could try to generate new app\_id/creds values. If the call stats history isn’t working, maybe neither is a prompt that you are locked out or been disabled?

---

<div class="post-metadata">

**Author:** ![Rob\_G](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rob_g/32/79108_2.png) [@Rob\_G](https://community.homey.app/u/Rob_G)\
**Post date:** [May 3, 2025, 5:15pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/80 "2025-05-03T17:15:29Z")

</div>

@doyouevencomputer Thanks for the update! I’ll look into the credentials.

---

<div class="post-metadata">

**Author:** ![Rob\_G](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rob_g/32/79108_2.png) [@Rob\_G](https://community.homey.app/u/Rob_G)\
**Post date:** [May 3, 2025, 6:59pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/81 "2025-05-03T18:59:22Z")

</div>

@doyouevencomputer I got it working!

The error I made was that I interpreted “RequestPath” to be a piece of the URL, where is should be just the last part (after the last slash).

So it works. Now, I have to figure out how the command “Get Energy in Period for a Particular System” works. This (and other commands) uses extra parameters, but it is not really described how to send these.

Thanks for now!

---

<div class="post-metadata">

**Author:** ![Dick\_J](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/dick_j/32/79161_2.png) [@Dick\_J](https://community.homey.app/u/Dick_J)\
**Post date:** [May 5, 2025, 3:29pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/82 "2025-05-05T15:29:06Z")

</div>

Functioning depends on the series of your ECU

---

<div class="post-metadata">

**Author:** ![Dick\_J](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/dick_j/32/79161_2.png) [@Dick\_J](https://community.homey.app/u/Dick_J)\
**Post date:** [May 5, 2025, 3:31pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/83 "2025-05-05T15:31:45Z")

</div>

That is something I have not figured out yet, maybe I’ll ask AP for this. Ending the url with ?energy\_level:yearly doesn’t work.  
Unfortunately, my internet connector (Delta fiber) is now down for the last week, so I have paused my efforts.

---

<div class="post-metadata">

**Author:** ![Steven\_Bareman](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/steven_bareman/32/31404_2.png) [@Steven\_Bareman](https://community.homey.app/u/Steven_Bareman)\
**Post date:** [May 5, 2025, 3:53pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/84 "2025-05-05T15:53:39Z")

</div>

Yes, i see. My ECU is not from the right series, so it is not working 😕 hopfully there wil be a app some day or a other solution

---

<div class="post-metadata">

**Author:** ![Dick\_J](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/dick_j/32/79161_2.png) [@Dick\_J](https://community.homey.app/u/Dick_J)\
**Post date:** [May 8, 2025, 7:01pm UTC](https://community.homey.app/t/solar-system-from-apsystems/74759/85 "2025-05-08T19:01:21Z")

</div>

Okay, so to send parameters with your request, add a question mark and then parameter name and value. Like:  
/user/api/v2/systems/ **SID** /devices/inverter/batch/energy/ **ECUID**?energy\_level=power&date\_range=2025-05-08  
or:  
/user/api/v2/systems/energy/ **ECUID**?energy\_level=hourly&date\_range=2025-05-08

[Previous page](https://community.homey.app/t/solar-system-from-apsystems/74759.md?page=3)

[Next page](https://community.homey.app/t/solar-system-from-apsystems/74759.md?page=5)
