Domestic photovoltaic installations are becoming more and more popular these days, promising green and self produced energy at an affordable price.
If you have some pannels at home, chances are they're hooked up to a monitoring device that allows you to know how much power you're producing/buying/selling to the grid. Mine came with an Elios4You module, produced by 4-noks, an old device still pretty popular in Europe.
I assume, since you're spending some time on Hackster, that having the companion app as the only way to "speak" to the module is not enough for you... being able to consume the raw data that the module spits out allows much deeper integration with the home automation system and generally more freedom - we can create routines based on current production, turn on/off appliances, make plots and derive averages.
Well, if your module already exposes some sort of API or allows MQTT/Zigbee integration, you can stop here. No need to go further. But, if yours - like mine - only allows connections via the proprietary app, join the ride. Might be interesting.
What will we doWe'll try to find a way to talk with the monitoring module, to hopefully be able to ask for production data and, maybe, to control the built-in relay (if available).
The following procedure will be focused on the aformentioned Elios4You module, since that's what I got on hands, but should be adaptable to a variety of unencrypted ones.
Sniffing TCP communicationsAs said, the module comes with a companion app, available to iOS and Android users. Let's assume you have it installed and properly configured on your smartphone.
First thing first, let's understand how the app talks with the module by sniffing TCP communications in the local network. We will use Wireshark. Once installed, run it, select the network adapter (WiFi or Ethernet), set it in promiscuous mode and start capturing; you will see a bunch of packets being sent between your network devices. Since there are usually too many packets being distribuited for us to comfortably read through them, we'll need to filter them out by IP.
If you don't know the IP of the module and your smartphone, you can find them listed in your router admin page, usually at 192.168.1.1.
The module I'm using has IP 192.168.1.10, whilst my phone is under 19.168.1.32. The filter will therefore be
ip.addr == 192.168.1.10 and ip.addr == 192.168.1.32
Now, if the app is running and receiving data from the module, you should see packets being sent from and to the module: some are requests, followed by an answer.
We are interested in seing what the request for raw production data looks like. If we refresh the app, we can see two new packets appearing in Wireshark: one short (89 bytes) from the phone to the module, and a longer answer (912 bytes) from the module to the app.
Clicking on the 912 bytes packet opens the detail windows, and under the data section we can clearly read words like Produced Power, Consumed Energy...
Bingo! That's what we're looking for!
So let's see what caused the module to send out these informations. The previous packet, the one long 89 bytes, has a short data section, and only sends out @dat to port 5001 of the module. That should be it.
Moreover, from the packets list we can see that the module only uses port 5001; that's the port we will be targeting to when connecting with the module.
To test if the command @dat is the correct one, we can use the beloved PuTTY: open a new raw connection with the module (IP 192.168.1.10 for me) on the port we found earlier (port 5001), type @dat, press enter. The terminal reports the answer as follows:
That's it! We succesfully reyrieved production and consumption values from the module, even if the manufacturer didn't provide any API.
In the same way, we can now trace back all the commands we're interested in. For the Elios4You module, these are some other ones that might be useful:
- @dat: requests for monitoring data (produced, sold, consumed and bougth power and energy)
- @hwr: returns hardware info
- @inf: returns software versions and informations
- @REL 0 0: turns off the built-in relay
- @REL 0 1: turns on the built-in relay
Obviously the method only works if the module does not require authentication nor encryption, so that we can see the exchanged data in clear text whilst sniffing. The procedure won't work on every PV monitoring device, but giving it a try won't hurt.
Using the received data in Node-RedOnce understood the simple communication protocol used by the module, we can consume the data however we want. A common platform used in home automation is the well-known Node-RED.
Simply drag and drop an injection, a TCP an a couple function nodes, set your module IP and port, and you're done.
If you're interested in giving it a try in Node-RED, here is the exported flow Json.
[
{
"id": "efa534c6.7a12d8",
"type": "tcp request",
"z": "e8fcaf60.71772",
"server": "192.168.1.10",
"port": "5001",
"out": "time",
"splitc": "300",
"name": "Elios4You",
"x": 220,
"y": 50,
"wires": [
[
"d8cf8d71.418c8"
]
]
},
{
"id": "8167b67a.15a378",
"type": "inject",
"z": "e8fcaf60.71772",
"name": "",
"topic": "",
"payload": "",
"payloadType": "date",
"repeat": "",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 65,
"y": 50,
"wires": [
[
"e125251f.edfc98"
]
],
"l": false
},
{
"id": "d8cf8d71.418c8",
"type": "function",
"z": "e8fcaf60.71772",
"name": "decode",
"func": "var buffer = Buffer.from(msg.payload);\nvar parsed = buffer.toString();\nvar lines = parsed.split('\\n');\n\nmsg.payload = {};\n\nfor(var i = 0; i < lines.length; i++) {\n var line = lines[i].split(';');\n \n if (line.length > 1){\n var name = line[1].toString();\n name = name.replace(/ /g, '_');\n name = name.toLowerCase();\n msg.payload[name] = line[2] + \" \" + line[3];\n }\n}\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 370,
"y": 50,
"wires": [
[
"78085084.4dc",
"20c844b0.c9d77c"
]
]
},
{
"id": "78085084.4dc",
"type": "debug",
"z": "e8fcaf60.71772",
"name": "",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload.produced_power",
"targetType": "msg",
"x": 595,
"y": 50,
"wires": []
},
{
"id": "e125251f.edfc98",
"type": "function",
"z": "e8fcaf60.71772",
"name": "dat",
"func": "msg.payload = \"@dat\\r\";\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 120,
"y": 50,
"wires": [
[
"efa534c6.7a12d8"
]
],
"l": false
}
]
The flow outputs a Json objects whos payload contains all the incoming values.
Every internet-enabled device should be now able to request for production data. Even using a simple ESP board will do the trick!
That's itThis wraps it up.
Not an in-depth, long or difficult project at all, but hopefully it will turn out handy for the ones interested in making their PV plant a bit "smarter".
Cheers!
Comments
Please log in or sign up to comment.