Skip to content

Instantly share code, notes, and snippets.

@M66B

M66B/sdm120.py Secret

Last active May 11, 2023 11:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save M66B/dd0cdb534ed4455e0d63c30bfce91ac4 to your computer and use it in GitHub Desktop.
Save M66B/dd0cdb534ed4455e0d63c30bfce91ac4 to your computer and use it in GitHub Desktop.
sdm120.py
#!/usr/bin/env python3
#sudo raspi-config
#Interface options > Serial port > Disable shell
#sudo apt-get install pip
#pip install minimalmodbus requests
#chmod +x /home/pi/sdm120.py
#sudo touch /var/log/sdm120.log
#sudo chown pi /var/log/sdm120.log
#sudo crontab -e
#*/5 * * * * /home/pi/sdm120.py >>/var/log/sdm120.log 2>&1
#grep CRON /var/log/syslog
import os
import minimalmodbus
import serial
import requests
import datetime
import json
import glob
port = '/dev/ttyS0'
device = 1
apikey = '...'
systemid = '...'
path = '/run/shm/sdm120/'
pvoutput = 'https://pvoutput.org/service/r2/addstatus.jsp'
hc = 'https://hc-ping.com/...' #https://healthchecks.io/
#https://minimalmodbus.readthedocs.io/en/stable/usage.html
instrument = minimalmodbus.Instrument(port, device)
instrument.serial.baudrate = 9600
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_NONE
instrument.serial.stopbits = 1
instrument.serial.timeout = 0.1
instrument.mode = minimalmodbus.MODE_RTU
#instrument.debug = True
#30001 Voltage Volts 0000
#30007 Current Amps 0006
#30013 Active Power Watts 000C
#30019 Apparent Power VoltAmps 0012
#30025 Reactive Power VAr 0018
#30031 Power Factor None 001E
#30037 Phase Angle Degrees 0024
#30071 Frequency Hz 0046
#30073 Import Active Energy kWh 0048
#30075 Export Active Energy kWh 004A
#30077 Import Reactive Energy kVArh 004C
#30079 Export Reactive Energy kVArh 004E
#30085 Total system power demand W 0054
#30087 Maximum total system power demand W 0056
#30089 Import system power demand W 0058
#30091 Maximum Import system power demand W 005A
#30093 Export system power demand W 005C
#30095 Maximum Export system power demand W 005E
#30259 Current demand Amps 0102
#30265 Maximum current demand Amps 0108
#30343 Total Active Energy kWh 0156
#30345 Total Reactive Energy kVArh 0158
v = instrument.read_float(0x0000, 4, 2)
c = instrument.read_float(0x0006, 4, 2)
p = instrument.read_float(0x000C, 4, 2)
a = instrument.read_float(0x001E, 4, 2)
f = instrument.read_float(0x0046, 4, 2)
i = instrument.read_float(0x0048, 4, 2)
e = instrument.read_float(0x004A, 4, 2)
t = instrument.read_float(0x0156, 4, 2)
now = datetime.datetime.now()
headers = {
'X-Pvoutput-Apikey': apikey,
'X-Pvoutput-SystemId': systemid,
'Content-Type': 'application/x-www-form-urlencoded',
}
#https://pvoutput.org/help/api_specification.html#id1
data = {
'd': now.strftime('%Y%m%d'),
't': now.strftime('%H:%M'),
'v1': e * 1000,
'v3': i * 1000,
'v6': v,
'v7': c,
'v8': f,
'v9': p,
'v10': i,
'v11': e,
'v12': a * 100,
'c1': '1',
}
json_object = json.dumps(data, indent=2)
os.makedirs(path, exist_ok=True)
name = path + 'data_' + now.strftime('%Y%m%d_%H%M') + '.json'
with open(name, 'w') as fout:
fout.write(json_object)
files = glob.glob(path + 'data_*.json')
for file in files:
with open(file, 'r') as fin:
data = json.load(fin)
try:
response = requests.post(pvoutput, headers=headers, data=data)
if response.status_code == 200:
os.remove(file)
else:
response.raise_for_status()
except Exception as ex:
print(name)
print(ex)
raise
if hc:
requests.get(hc)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment