I’m not using the Epever but I am using the PZEM-016 and I believe I’ve figured out the MQTT part of the Elfin EW11.
To send a request, send a buffer type Modbus TCP command configured per the Modbus TCP protocol to the subscribe topic you configured it to in the EW11, in my case down/EW11
This website Modbus TCP Protocol with Command Examples is a great guide for creating your “buffer” message.
For example, for my device, I wanted 10 registers 0x0000 -0x0009 with command 0x04. Given Modbus TCP Protocol it looked like this:
0x01 0x02 0x00 0x00 0x00 0x06 0x01 0x04 0x00 0x00 0x00 0x0A
With labeling for understanding the structure:
[0x01 0x02] Trans ID (see website for others)
[0x00 0x00] Protocol Id (always the same)
[0x00 0x06] Message Length - bytes count beyond these bytes, 6 in my case
[0x01] Unit Id/Slave Address
[0x04] Function Code
[0x00 0x00] Starting Register Address
[0x00 0x0A] Register Count -in this case 10 (hex 0A)
I use node red so in a function node I did the following and sent it to the MQTT node with the topic set to down/EW11
msg.payload = Buffer.from('01020000000601040000000A', 'hex');
return msg;
After sending the command the response will come through on the publish topic, in my case up/EW11
The response will have the following structure (based on my use case)
0x01 0x02 0x00 0x00 0x00 0x17 0x01 0x04 0x14 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
Response with labeling for understanding the structure (zeros for register values are dummy values for demonstration purposes):
[0x01 0x02] Trans ID (see website for others)
[0x00 0x00] Protocol Id (always the same)
[0x00 0x17] Message Length - bytes count beyond these bytes (hex17 in my case)
[0x01] Unit Id/Slave Address
[0x04] Function Code
[0x14] Number of bytes more (based on request, in my case Hex 14, or Dec 20)
[0x00 0x00] Register value for address 0x0000
[0x00 0x00] Register value for address 0x0001
[0x00 0x00] Register value for address 0x0002
[0x00 0x00] Register value for address 0x0003
[0x00 0x00] Register value for address 0x0004
[0x00 0x00] Register value for address 0x0005
[0x00 0x00] Register value for address 0x0006
[0x00 0x00] Register value for address 0x0007
[0x00 0x00] Register value for address 0x0008
[0x00 0x00] Register value for address 0x0009
For converting the buffer values returned I use node-red. In my case for the integer values I do the following in a function node (23 is just a dummy value in this case):
return { payload: msg.payload.readInt16BE(23)} ; // 23 is the buffer byte number offset
For larger numbers that cover multiple registers, it is a bit more complex. A function node with two outputs could look as follows (19, 21 are just dummy values in this case for demonstrating multiple registers):
var rawData = new ArrayBuffer(4);
var intView = new Uint16Array(rawData);
var fltView = new Uint32Array(rawData);
intView[0] = msg.payload.readInt16BE(19); // low # is byte number offset
intView[1] = msg.payload.readInt16BE(21); // high # is byte number offset
msgA = { payload: fltViewA[0]}; // four byte integer with no decimal
msgB = { payload: (Math.round((fltView[0]*.1) * 10) / 10)}; // Converts to Float with one decimal
return [ msgA, msgB ];
I hope that helps anyone who’s been mystified by the MQTT part of the EW11 as much as I have been!
Edit: It’s also worth noting that no matter the source of the Modbus Command up/EW11
always returns the response as well.