APsystems APS ECU R local inverters data pull

Just for that sake, i’m running too pretty stable. I still keep track of ‘how old is my sensor data’ and it only hiccups in the morning and recovers by itself without intervention. Didnt have to restart anything (no ECU nor HA) . I’m fine with current state of this integration.

Great. Thanks for the update. Mine has been really stable as well. I get a few hiccups of invalid data from the ECU, but only very occasionally. The turn off/on at sunset/sunrise seems to help a lot too, since those were mostly overnight for me.

Same here, stable now and sunset/sunrise switches query with a small delay. Noticed firmware ECU_R_1.2.15009 on the ECU now ?! Still no release notes. I wonder if 009 at the end is part of the version.

playing with other cards, less space consuming:
image

That looks great. What card did you use for that?

built image myself, then the rest is easy config

still looking at other ideas too :slight_smile:

Hey Kyle,

At tweakers we are now looking at the data that is going to the EMA cloud. First analysis is that three listeners are needed (presumably 1 status and 2 load balancers). Then also an adjustment to route the domain to the HA so that the listeners pick it up there. It then seems to be possible to work cloud independently if you wish. So I imagine that this is optional, it would be some sort of proxy - receiving data the regular way and make a switch so that it can be forwarded to the cloud if preferred.

I’ve looked through the forum some. Looks like you are thinking of a man in the middle approach? Interesting idea.

I’d think that would have to run outside of home assistant to be able to listen on the appropriate ports, and then easiest route would be to use mqtt to push the values into HA (or any other home automation system).

If you get the protocol figured out, I should be able to help in coding a process to listen for updates from the ECU if you need help doing that.

Something like that. Although I was more looking at the Webhooks API from HA, which would be less complicated implementation environment if that would suffice.
The data itself doesnt look complicated, but we still need to ‘confirm’ ok to the ECU for each timestamp we got data from it. WE’ll have to play with that and possibly a way to handle other comms that ecu attempts (like firmware updates).
Best approach is to ‘rewrite’ all packets the listener gets to ecu cloud url and only use real metric when needed.

Today I’m going to measure to see what challenges we have with this concept. In itself, the data can be forwarded 1 on 1 to the cloud, which is simple in itself. They might notice that a different type of referrer comes in (at least no ECU-R or other product from the APS production line). You will not notice this on the front-end, only the transport layer. (I put the AT + and OKs aside, sometimes I am a bit rusty in my memory, the UART in the ESP controls the connection setup and are no part of the dataframe). You will no longer encounter this with a wired connection. And indeed how do we deal with firmware updates and the change of data upload URL as I noticed. I have not seen this confirmed by others, by the way.

So , having grabbed a day of data in python proxy script and a pretty good idea what data we have, there is a few design questions to solve:

  1. do we want it cut off from cloud completely?
    for me this is not needed now, but could be good to have whenever they decide to go bankrupt or whatever.
  2. there is no daily running total. It only reports the increments each 5 minutes. Can HA do running totals on a day or do we need to built that in python script.
  3. if ECU for what ever reason starts throwing older data points, we need to detect and not send to HA
  4. there is no zigbee signal % data
  5. listener on 3 ports, in one python… seems doable, but i didnt get it

Also the local setup on your own network is kind of special (making DNS records adjustments)
so all in all , it’s not really easy to realize i’m afraid.

  1. This morning I saw that Off cloud is possible. The fixed parameters that I send on the three ports are accepted by the ECU, even though the ECU sends two other data frames to 8997 when the inverters are started up and going offline.

  2. Two things that should indeed be kept up to date. A. running total for the daily KwH. B. Timestamp of the last data received (in case of HA restart). This will allow the ECU buffer to empty properly so that the running totals are correct.

  3. The previous point is important for the running totals. missing data points must be inserted into the database.

  4. Still to be determined with certainty. I see parameters that increase with signal strength.

  5. The proxy function has four ports to which read and write actions are required.

Fortunately, the number of lines of code required is very limited. Especially since port 8997 is actually very simple to manage.

Challenges are the ability for users to redirect via the hosts file or local DNS for both proxy and off cloud. Another challenge is getting firmware updates from the cloud (if you want them at all). If it ain’t broke don’t fix it. But as we’ve seen, a firmware upgrade is important for internal server moves.

point 2 can be addressed by doing daily total in de python script itself. Then missed updates to HA will not break running total on the day and no need to back fill HA with in between points.

@HAEdwin this is from my ECU-R with 8 * YC1000 inverters

A : SumPower (float x100)
B : SumEnergy (float x1000000) ???
C : ??? (float x10)
D : Timestamp
E : Number of inverters in set
F : State
G : InverterID
H : Inverter Type
I : ??? (integer)
J : Frequency x10
K : Temperature
L : ChannelNo
M : ??? (float)
N : Voltage
O,P : ??? (integer x10 or x100)
Q : ??? (float x1000000)
R : Energy ?? (float x1000000)
S : Power (float x100)

BTW:
Try make TCP connection on port 4540 on lan interface (not wifi) and send those commands:
get_ecu_id | get_version | get_eth0_mac | get_time | test_led
:wink:

Wow interesting, how did you find out that you can use that port and commands? How stable is the ECU when sending these commands? Will it be possible to block traffic to the cloud and still keep the ECU-R running? A lot to examine closer :slight_smile:

From disassembled firmware :wink:
But for your needs I haven’t found the command to get the current state of Power,Energy etc. :neutral_face:
Maybe query_result. But in my case, I always get the result: Failed

First line: APS18A1262 (1262 is the checksum = string length), take a look at the protocol sheets in this thread (YC600 en QS1 are known, YC1000 was missing). What is your purpose? Also to integrate data with HA?

Length, indeed. I forgot to mark on the picture
Yes I’m thinking to integrate with HA
Well, but due to the instability of WiFi, I’m also looking for how to get data to HA. I don’t like the idea of blocking the cloud. Sometimes I like to look at EcuAPP on my phone :slight_smile: Of course, you can make an option in TCP proxy whether to send to the cloud or not.

I just tried query_result on port 4540 and got a very similar string that you posted above. I haven’t spent the time to decode it yet, but if it’s what you listed above that’s fantastic and hopefully more reliable than our other method, but @Wadzio you aren’t getting data with query_result?

When decoding the firmware did you find any other commands?

Tried several times and always had Failed.
The analysis of the firmware shows that we should receive string: APS18xxx. Maybe my ECU is broken? Or maybe because I was doing query_result always in the evening (at night :slightly_smiling_face:)? I have to try tomorrow during the day while the plant produces electricity.
And when did you query, was it day or night?

It doesn’t have too many commands. There are several to set (EcuID, EthMAC, InverterId, initialize NOR memory partition, set time). But I will not give it for now, probably too dangerous :slightly_smiling_face:
Safe seems to be:
get_ecu_id | get_eth0_mac | query_result | query_protection | get_area | get_version | get_time | reboot | Internal_version | test_led | get_channel