]> git.sven.stormbind.net Git - sven/scripts.git/blob - home/enverbridge.py
04cbe0e8d365c6d22f772762bda467ac7847fc72
[sven/scripts.git] / home / enverbridge.py
1 #!/usr/bin/env python3
2
3 # This script can be used to configure the Inverter IDs
4 # on an Envertech EnverBridge device. This is a replacement
5 # for the "SetID" programm provided as a Win32 executable at
6 # http://www.envertec.com/uploads/bigfiles/Set%20ID.zip
7 # Tested online with the EnverBridge 202 and a EVT 560 module
8 # inverter.
9 #
10 # Logic seems the be the following:
11 # Take the inverter id, append the char 9 to 16 of the 16 char
12 # serial number. Do this for every pair of serial numbers.
13 # Sent this string in one UDP paket to the broadcast address on
14 # port 8765. Wait for a response paket to the broadcast address
15 # on port 8764.
16
17 import argparse
18 import socket
19 import sys
20 import re
21
22 parser = argparse.ArgumentParser()
23 parser.add_argument("-b",
24                     "--bid",
25                     action="store",
26                     type=int,
27                     dest="bid",
28                     required=True,
29                     help="Serial Number of your EnverBridge")
30 parser.add_argument("miids", nargs="+", help="MIIDs of your MicroInverter")
31 args = parser.parse_args()
32
33
34 def validateMIID(miids):
35     error = False
36     idpattern = re.compile(r"^CN[0-9]{14}$")
37     for id in miids:
38         print("Validating MIID", id)
39         if not idpattern.search(id):
40             print("Error: Invalid MIID", id)
41             error = True
42
43     if error:
44         print("Validation error, check your MIIDs, exiting")
45         sys.exit(23)
46
47
48 def buildMIIDList(miids):
49     msg = ""
50     for id in miids:
51         msg = msg + id[8:16]
52     return msg
53
54
55 validateMIID(args.miids)
56
57 # assemble message string and convert to bytes
58 message = str(args.bid) + buildMIIDList(args.miids)
59 message = message.encode()
60 print('Sending to EnverBridge with ID', args.bid)
61
62 # Create a UDP client socket w/ broadcast
63 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
64 sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, True)
65
66 # Create a UDP server socket we bind to to listen for broadcasts
67 ssock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
68 ssock.bind(('', 8764))
69
70 try:
71     # Send data via broadcast to port 8765
72     print('Sending {!r}'.format(message))
73     server_address = ('<broadcast>', 8765)
74     sent = sock.sendto(message, server_address)
75
76     # Receive response on port 8764
77     print('Waiting to receive')
78     data, server = ssock.recvfrom(8764)
79     print('Received {!r}'.format(data))
80
81 finally:
82     print('Closing sockets')
83     sock.close()
84     ssock.close()