Delta 50.4 MW solar PV Reading

Anyone can help with data collection from 50.4 MW solar PV Inverter?. As per the spec, it says RS 485 support with Modbus, the site owner wants to upload the data to pvoutput, I have been asked to find tools/scripts for the same.

Can script/app that reads data from Delta 50.4 MW solar PV and export to PVOutput?

It is possible. Although I never saw a Delta inverter it should be pretty straight forward once you have modbus register map. (Delta should provide it)

Thank you, I do not find any relevant info online as well.

Let´s try figure it out. Do you have access to the inverter? If so, are you able to plug a RS485/USB adapter and try some commands on a notebook?

Hi @jrbenito, I just got a small (6-panel) system turned on today, and I’d like to monitor it :slight_smile: . It’s also a Delta. Delta Solivia 3.8. I managed to get the operation manual from Tesla for it, and it does have a RS485 section in the manual. Do you have any suggestions/pointers for places to start? So far the only good source I’ve found is https://github.com/lvzon/soliviamonitor

1 Like

Hi @bdunavant,

Are you fellow diver?

Some questions:

  1. can I have manual? If not, it does says anything about modbus?
  2. did you try code you pointed?

BRs,
Benito.

@jrbenito Yes I am a diver :slight_smile: . My profile pic is from a shark dive with Stuart Cove bahamas. I live near Washington, DC though, so I rarely get a chance to go outside of vacations.

  1. Absolutely, lemme see if I can directly message it to you.
  2. I have not yet. I’m a complete novice here and barely understand what RS485 is. I work in tech, but figured I’d should do more research before I start poking at a system that generates electricity :stuck_out_tongue:

-Brian D

Hi @bdunavant,

I had the assumption of Stuart Cove based on the shark behind you. I still have to go there.

  1. ok, if not, ping me and I send you my personal e-mail.

  2. Got it and you are absolutely right. Well, just for clarifying RS-485 is a serial interface specification mainly used in industrial applications. It is safe to interface it with your notebook/desktop through a proper adapter (cheap one will do) you plug into your USB port. Since it is a differential interface (level swing between + and - on both wires), it will not fry anything if you plug wires A and B inverted (while it will not work properly). However, caution is always required, do not connect inverter side with inverter turned on, switch off first - better yet, follow the manual, my ABB has even order to screws I should fasten first to guarantee its IP level protection.

Now, I asked if manual says anything about modbus because Modbus is protocol implemented over RS-485 interface that is well-known. If your inverter has no modbus this means it might use vendor´s specific protocol (like ABB uses Aurora protocol) and this means more work. However, since some people already tried as you pointed, the heavy lift might be already done.

BR

1 Like

@jrbenito . Sorry for the delay. I don’t see a way to PM here. I’m happy to email it to you though.

Delta also has the manuals on their website apparently. It’s not the exact file that Tesla gave me, but I think this is the same model. http://www.delta-americas.com/Products/CategoryListT1.aspx?CID=0505&PID=1759&hl=en-US&Name=Soliiva%20TL%20Series%20(3.0/3.8/52./6.6/7.6kw)

Hi to open the message link, go to the PV ladder at top of your screen and enter name of system you want to pm in the find box-- top right of screen click on the name in the list and it brings up there system, then middle of screen in blue is a message link, click and send message Jim

1 Like

Hi,

I read the link and there is no mention to any protocol but there is a very detailed interface description. Now I would suggest you get a RS-485 USB adapter, plug it to RS485-1 on your inverter, enable termination jumper (position on - since I presume you have only one inverter). Go to inverter´s menu and modify its device ID to 2 or something else (some RS485 programs use ID 1 to themselves). Now let´s test the solution on github to see if, at least, we get the same output.

BRs
Benito.

I’m assuming this one would be fine?
https://www.usbgear.com/USB-RS485-AT.html

I know Tesla has something installed in it to send wireless data to themselves to monitor it. Is it possible they are already using that port? I’ll try to take a picture of the inverter and the insides tonight.

It should be fine but I bit expensive I think. I have this one https://goo.gl/sqQKzj
simpler model, very cheap but does the job too.

Yes, they are probably using this port and in this case you may not be able to read inverter together with Tesla. It is possible to read the RS485 bus as master while other master (Tesla) is not doing it but how can you be sure you are not going to clash on databus? It maybe possible to spy on, just listen to Tesla asking data and inverter answering but will require software modification (that github alone will not do).

Take the picture and we try figure out what to do.

I wasn’t able to get the cover off with my 4mm hex wrench. I had a Torx bit one size too small, and one size too big, heh. I’ll have to buy one of those too, heh. Here’s the outside though. You can see the wireless antenna sticking out the bottom. If that traffic isn’t encrypted, i could possibly snoop that as it goes through my network.

Hi,

We always have the “right” bit one size small or big :wink: By the way, very nice/clean installation.

To where that antena sends information to?

The antenna there sends the information to this device which is plugged into my router. The back has what is possibly private info, so I’ll email you that picture rather than posting it here.

Here’s the inside :slight_smile: . I sent a bunch of other closer angles of parts to your email.

I’m working on python script for downloading 15 min production data from mysolarcity.com and adding live output to pvoutput.org.
Do you still interested in monitoring of your system via pvoutput.org?

Very interested in python script. Is it available.

Tesla is discontinuing MySolarCity.com - as message reads “Your MySolarCity.com account and MySolarCity mobile app are transitioning to Tesla.com account and Tesla mobile app on August 1, 2019”
Here is the script so far. In the light of above I’m not planing future work on it.

# Tesla is discontinuing MySolarCity.com as of August 1, 2019
# Enjoy until exists
#
# Download daily production data from mysolarcity.com at the beginning of the next day
# Download 15 min production data from mysolarcity.com and post to pvoutput.org
#
# The example installation  is with 2 inverters, posts to 2 systems on pvoutput.org
# 
# Requires:
# selenium for py
# Firefox (to be able to download files without UI pop-up questions)
#
# File name convention as for Windows host
# 
# Task needs to be scheduled on Windows host for 15 min execution
#
# No debugging set
# 
# Copyright 2019 Boby Borisov 
# 
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
import os
import time
from datetime import date, datetime, timedelta 
from selenium import webdriver
from selenium.webdriver.firefox.options import Options
import csv
import urllib.request, urllib.parse, urllib.error
# SolarCity
SC_USER = "<mysolarcity email>"
SC_PASSWORD = "<mysolarcity password>"
INSTALLATION_ID = "<mysolarcity installation id - visible when you "share" daily output>"
INVERTER={}
INVERTER[1] = "<inverter 1 id - visible in downloaded daily output file>"
INVERTER[2] = "<inverter 2 id - visible in downloaded daily output file>"
MSC_LINK1 = "https://mysolarcity.com/solarcity-api/powerguide/v1.0/installations/"
MSC_LINK2 = "/summary?StartTime="
MSC_LINK3 = ":00&EndTime="
MSC_LINK4 = ":59&Period=QuarterHour"
MSC_FILE = "\summary.csv"
# PVOutput
PVOUTPUT_ID={}
PVOUTPUT_ID[1] = "<pvoutput system ID for inverter1>"
PVOUTPUT_ID[2] = "<pvoutput system ID for inverter2>"
PVOUTPUT_KEY = "<pvoutput api write key>"
# Script Constants
SC_DATA = "C:\\solarcitydata"
SC_LOGOUT_TIMEOUT = 3
SC_LOGIN_TIMEOUT = 3
MSC_TIMEOUT = 12
PAGE_LOAD_TIMEOUT = 15
PV_STATUS = "\pv_status.csv"
# Firefox Options for downloading files
options = Options();
options.set_preference("browser.download.folderList",2)
options.set_preference("browser.download.dir", SC_DATA)
options.set_preference("browser.download.manager.showWhenStarting", False)
options.set_preference("browser.helperApps.neverAsk.saveToDisk", "text/csv")
options.headless = True
# Get 15min file from MySolarCity.com
def get_solarcity_data(time_b,time_e):
    if os.path.isfile(SC_DATA+MSC_FILE):
        os.remove(SC_DATA+MSC_FILE)
    MSC_LINK = MSC_LINK1+INSTALLATION_ID+MSC_LINK2+time_b+MSC_LINK3+time_e+MSC_LINK4
    print(MSC_LINK)
    driver = webdriver.Firefox(options=options)
    driver.set_page_load_timeout(PAGE_LOAD_TIMEOUT)
    try:
        driver.get('https://login.solarcity.com/logout')
        time.sleep(SC_LOGOUT_TIMEOUT)
        driver.get('https://login.solarcity.com/account/SignIn')
        time.sleep(SC_LOGIN_TIMEOUT)
        driver.find_element_by_id("username").clear()
        driver.find_element_by_id("username").send_keys(SC_USER)
        password = driver.find_element_by_id("password")
        password.send_keys(SC_PASSWORD)
        password.submit()
        time.sleep(MSC_TIMEOUT)
        driver.get(MSC_LINK)
    except: pass
    driver.quit()
    if os.path.exists("geckodriver.log"): os.remove("geckodriver.log")
#Get Yesterday's 15min file from MySolarCity.com 
yesterday = date.today() - timedelta(days=1)
if os.path.isfile(SC_DATA+"\solarcity "+yesterday.strftime("%Y%m%d")+".csv"): pass
else:
    print("get yesterday's file")
    get_solarcity_data(yesterday.strftime("%Y-%m-%d")+"T00:00",yesterday.strftime("%Y-%m-%d")+"T23:59")
    if os.path.isfile(SC_DATA+MSC_FILE):
        os.rename(SC_DATA+MSC_FILE,SC_DATA+"\solarcity "+yesterday.strftime("%Y%m%d")+".csv")
#Post live output to PVOutput.org
def post_pvoutput (d,t,v1,v6,apikey,sid):
        headers = {}
        headers["X-Pvoutput-Apikey"] = apikey
        headers["X-Pvoutput-SystemId"] = sid
        data = {}
        data["d"] = d
        data["t"] = t
        data["v1"] = v1
        data["v6"] = v6
        data["c1"] = "1"        
        data = urllib.parse.urlencode(data).encode('utf-8')
        request = urllib.request.Request('https://pvoutput.org/service/r2/addstatus.jsp', data, headers)
        try:
            response = urllib.request.urlopen(request)
            print (sid,data,response.read())
            return True
        except:
            print (sid,data,"Error")
            return False
#Get/Post 15min production
datetimed = datetime.now() - timedelta(minutes=15)
dated = datetimed.strftime("%Y-%m-%d")
timee = datetimed.strftime("%H")+":"
minutes = int(datetimed.strftime("%M"))
if minutes < 15:
    timee += "14"
else:
    if minutes < 30:
        timee += "29"
    else:
        if minutes < 45:
            timee += "44"
        else:
            timee += "59"
timee = datetimed.strftime("%Y-%m-%d")+"T"+timee
with open(SC_DATA+PV_STATUS, 'r') as f:
    csvread = csv.reader(f)
    lastpvo = list(csvread)
    j=1
    while j < len(INVERTER)+1:
        if datetimed > datetime.strptime(lastpvo[j][0]+lastpvo[j][1],"%Y%m%d%H:%M"):
           datetimed = datetime.strptime(lastpvo[j][0]+lastpvo[j][1],"%Y%m%d%H:%M")
        j += 1
datetimed = datetimed + timedelta(minutes=15)
timeb = datetimed.strftime("%H")+":"
minutes = int(datetimed.strftime("%M"))
if minutes < 15:
    timeb += "00"
else:
    if minutes < 30:
        timeb += "15"
    else:
        if minutes < 45:
            timeb += "30"
        else:
            timeb += "45"
timeb = datetimed.strftime("%Y-%m-%d")+"T"+timeb
if datetime.strptime(timeb,"%Y-%m-%dT%H:%M") < datetime.strptime(timee,"%Y-%m-%dT%H:%M"):
    get_solarcity_data(timeb,timee)
    if os.path.isfile(SC_DATA+MSC_FILE):
        with open(SC_DATA+MSC_FILE, 'r') as f:
            csvread = csv.reader(f)
            sclist = list(csvread)
            j=1
            while j < len(INVERTER)+1:
                i=1
                while i < len(sclist):
                    if sclist[i][2] == INVERTER[j]:
                        if post_pvoutput(datetime.strftime(datetime.strptime(sclist[i][0],"%Y-%m-%dT%H:%M:%S"),"%Y%m%d"),datetime.strftime(datetime.strptime(sclist[i][0],"%Y-%m-%dT%H:%M:%S"),"%H:%M"),str(int(float(sclist[i][4])*1000)),str(int(float(sclist[2][6]))),PVOUTPUT_KEY,PVOUTPUT_ID[j]):
                            lastpvo[j][0] = datetime.strftime(datetime.strptime(sclist[i][0],"%Y-%m-%dT%H:%M:%S"),"%Y%m%d")
                            lastpvo[j][1] = datetime.strftime(datetime.strptime(sclist[i][0],"%Y-%m-%dT%H:%M:%S"),"%H:%M")
                        else:
                            i = len(sclist)
                    i += 1
                print(INVERTER[j],lastpvo[j])
                j += 1
    else:
        print ("no 15min file")
    f = open(SC_DATA+PV_STATUS, 'w')
    j=0
    while j < len(INVERTER)+1:
        f.write(lastpvo[j][0]+","+lastpvo[j][1]+"\n")
        j += 1
    f.close()
else:
    print (timeb,timee, "15min not passed yet")