Skip to content

Commit

Permalink
Add ModBus write command
Browse files Browse the repository at this point in the history
  • Loading branch information
s10l committed Feb 13, 2023
1 parent bacde24 commit 2a1d4b9
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 13 deletions.
61 changes: 60 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# deye-logger-at-cmd

Update: Please send a request to Deye to update your inverter firmware at least to 1.53. After the update you where able to change WiFi mode and credentials.
> Update 2023-02-13: Got feedback from users that Deye is now rolling out the update automatically. Please make sure that your device is registered in Solarman or update it manually (offline).
> Update 2023-01-11: Please send a request to Deye to update your inverter firmware at least to 1.53. After the update you where able to change WiFi mode and credentials.
Deye based micro inverters use a built-in WLAN module for quick configuration.

Expand Down Expand Up @@ -101,3 +103,60 @@ Explanation
0401 is the playload, i that case 04 is the number of MPPT and 01 is number of ac phases (you need to know how to interpret the register.)
7B44 is the crc16
```

### Sending ModBus write command

> You may damage or destroy the device or other equipment and seriously injure or kill yourself or others. Be warned herewith.
`main -t <ip of the logger>:48899 -xmbw <Start_Register+Length+Value_Length+Value>`

```
main -t <ip of the logger>:48899 -xmbw 00280001020064
2022/11/11 12:39:26 * Connecting :0 -> <ip of the logger>:48899...
2022/11/11 12:39:29 +ok=01100028000181C1
```

Explanation of -xmbw
```
0028 is the start address (Active power regulation)
0001 is the number of registers (1)
02 is the length of the value (2 bytes)
0064 is the value (0x0064 -> 100)
```

## Structure of commands

### Read commands

```
DATAGRAM := ATCMD + MODBUSLEN + SEPERATOR + MODBUSMSG + MODBUSCRC + NEWLINE
ATCMD := AT+INVDATA=
MODBUSLEN := len(MODBUSMSG + MODBUSCRC)
MODBUSCRC := crc(MODBUSMSG)
SEPERATOR := ,
MODBUSMSG := SLAVE + FCODE + STARTADDR + REGSIZE
SLAVE := 01
FCODE := 03
STARTADDR := FFFF
REGSIZE := 0001
VALUELEN := len(VALUE)
VALUE := 0000
NEWLINE := \n
```

### Write commands
```
DATAGRAM := ATCMD + MODBUSLEN + SEPERATOR + MODBUSMSG + MODBUSCRC + NEWLINE
ATCMD := AT+INVDATA=
MODBUSLEN := len(MODBUSMSG + MODBUSCRC)
MODBUSCRC := crc(MODBUSMSG)
SEPERATOR := ,
MODBUSMSG := SLAVE + FCODE + STARTADDR + REGSIZE + VALUELEN + VALUE
SLAVE := 01
FCODE := 10
STARTADDR := FFFF
REGSIZE := 0001
VALUELEN := len(VALUE)
VALUE := 0000
NEWLINE := \n
```
65 changes: 53 additions & 12 deletions src/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package main

//https://www.rabbitmq.com/tutorials/tutorial-one-go.html
import (
"bufio"
"encoding/binary"
Expand All @@ -21,11 +20,12 @@ var (
fSource = flag.String("xs", "", "Local source address")
fWifiCfgCode = flag.String("xc", "WIFIKIT-214028-READ", "WiFi configuration code [WIFIKIT-214028-READ or HF-A11ASSISTHREAD]")
fAtCmd = flag.String("xat", "", "Send AT command instead of credentials")
fModBus = flag.String("xmb", "", "Send Modbus read register instead of credentials [00120001] -> Read register 0x0012, length = 1")
fModBus = flag.String("xmb", "", "Send Modbus read register instead of credentials [00120001] -> Read register = 0x0012, length = 0x0001")
fModBusW = flag.String("xmbw", "", "Send Modbus write register instead of credentials [00280001020064] -> Write register = 0x0028, length = 0x0001, value length = 0x02, value = 0x0064")
fVerbose = flag.Bool("xv", false, "Outputs all communication with the logger")

lAddress, rAddress *net.UDPAddr
handler Handler = credentialsHandler
handler Handler = nil
)

func init() {
Expand All @@ -52,24 +52,54 @@ func init() {
log.Fatal(err)
}

if fAtCmd != nil && *fAtCmd != "" && fModBus != nil && *fModBus != "" {
fmt.Println("You can't use xat and xmb at the same time")
flag.Usage()
os.Exit(1)
checkForArgConflicts := func() {
if handler != nil {
fmt.Println("You can't use xat, xmb or xmbw at the same time")
fmt.Println()
flag.Usage()
os.Exit(1)
}
}

if fAtCmd != nil && *fAtCmd != "" {
handler = atCommandHandler
} else if fModBus != nil && *fModBus != "" {
}

if fModBus != nil && *fModBus != "" {
checkForArgConflicts()

if len(*fModBus) != 8 {
fmt.Println("xmb needs first register address and length")
fmt.Println("First register 0x0012")
fmt.Println("Length 0x0001")
fmt.Println("-> 00120001")
fmt.Println()
flag.Usage()
os.Exit(1)
}
handler = modBusHandler
handler = modBusReadHandler
}

if fModBusW != nil && *fModBusW != "" {
checkForArgConflicts()

if len(*fModBusW) < 14 {
fmt.Println("xmbw needs first register address, length, value length, and value")
fmt.Println("First register 0x0028")
fmt.Println("Length 0x0001")
fmt.Println("Value length 0x02")
fmt.Println("Value 0x0064")
fmt.Println("-> 00280001020064")
fmt.Println()
flag.Usage()
os.Exit(1)
}

handler = modBusWriteHandler
}

if handler == nil {
handler = credentialsHandler
}
}

Expand Down Expand Up @@ -139,20 +169,31 @@ func atCommandHandler(conn *net.UDPConn) {
log.Println(*response)
}

func modBusHandler(conn *net.UDPConn) {
func modBusReadHandler(conn *net.UDPConn) {
prefix := "0103" // Slave ID + Function
cmd := fmt.Sprintf("%s%s", prefix, (*fModBus))
modBusHandler(conn, prefix, cmd)
}

func modBusWriteHandler(conn *net.UDPConn) {
prefix := "0110" // Slave ID + Function
cmd := fmt.Sprintf("%s%s", prefix, (*fModBusW))
modBusHandler(conn, prefix, cmd)
}

func modBusHandler(conn *net.UDPConn, prefix string, cmd string) {
data, err := hex.DecodeString(cmd)
if err != nil {
log.Fatal(err)
}
crc := Modbus(data)
msg := fmt.Sprintf("%s%s", cmd, hex.EncodeToString(crc))
msglen := len(msg) / 2

tresponse := send(conn, fmt.Sprintf("AT+INVDATA=8,%s%s\n", cmd, hex.EncodeToString(crc)), 1, 5, true)
tresponse := send(conn, fmt.Sprintf("AT+INVDATA=%d,%s\n", msglen, msg), 1, 5, true)

response := strings.ReplaceAll(*tresponse, string([]byte{0x10}), "")
log.Println(response)

}

func credentialsHandler(conn *net.UDPConn) {
Expand Down

0 comments on commit 2a1d4b9

Please sign in to comment.