Blog Post

Database Design for Tracking Solar Production

,

We had a solar system installed at our house this year. I’m excited to see how this performs, as our estimates and research shows this ought to be a good financial decision for us over time. While the hardware that came with the system includes some monitoring and reporting, I wanted to track things independently to be sure that I have the data. I know many of these companies might not be as prepared for an issue as I would like, and if they lose some of my historical data, I’m not sure they care.

I decided to set up a small database, which will need an import process along with reporting and this is the first in a series of posts on how I’m addressing the database design. In this post, I’ll look at the initial tables I created.

Estimated Production Table

My system included some estimated levels of production for the year, and I will be able to record the actual levels each day. I decided to track these two sets of data separately for a couple reasons.

First, the estimates are monthly, and they do not vary. While I could just stick this data in the same table, it’s a lot of wasted data. Not a lot of space, but still, I decided to be efficient here. The estimates I have are a total for each month, with the math done to give me a daily power level. I decided to create this table:

CREATE TABLE [dbo].[SolarPowerEstimate](
     [TrackingKey] [int] IDENTITY(1,1) NOT NULL,
     [trackingmonth] [tinyint] NULL,
     [estimate_month] [numeric](6, 2) NULL,
     [estimate_daily] [numeric](4, 2) NULL,
  CONSTRAINT [SolarPowerPK] PRIMARY KEY CLUSTERED
(
     [TrackingKey] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

This table has a PK just to keep things simple, and then I have a month number, which tracks for which month I have an estimate. There should only be 12 months in this table, as the estimate is supposed to repeat each year. I included the numeric values for the month and daily levels.

The data in this table looks like this:

2022-04-24 18_19_13-solartracking.sql - ARISTOTLE_SQL2017.way0utwest (ARISTOTLE_Steve (54))_ - Micro

I can join this with my actual production to compare how well things are working.

Actual Production

For Actual production, there is a value for each day. As a result, I need a date and a numeric value. I decided to separate out the date into separate parts, as I can always combine those, but this is really a data warehouse structure for me and I want to quickly join this with my estimate. I also expect to do some reporting by month, so having the month separated out (and the year) is a quick way to join data without needing a function.

CREATE TABLE   [dbo].[solarpoweractual](
     [TrackingKey] [int] IDENTITY(1,1) NOT NULL,
     [trackingyear] [smallint] NULL,
     [trackingmonth] [tinyint] NULL,
     [trackingday] [tinyint] NULL,
     [actual_daily] [numeric](10, 4) NULL,
  CONSTRAINT [SolarPowerActualPK] PRIMARY KEY CLUSTERED
(
     [TrackingKey] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

This  table will be populated with numbers for the date parts and then the production value. Right now, I see data like this:

2022-04-24 18_22_39-solartracking.sql - ARISTOTLE_SQL2017.way0utwest (ARISTOTLE_Steve (54))_ - Micro

I’ll go over reporting and how I use this data in another post, but there is one more table I need for this system.

Staging Imports

I can download data daily, but I really don’t care about the flows of the data each day. The data is reported each 15 minutes, but that’s a bit granular for me. Instead, I want to download monthly data. If I do that, I get a row for each day of the month, but some days are 0 if they are in the future. The current day is also incomplete until the sun goes down, so I may need to update that data regularly.

Rather then try to parse the data and build a complex ETL process, I’m aiming for an ELT, with a T that moves data from a staging table to my actual table with an upsert process.

The csv I get from my monitoring system is a date and a numeric value, so I built a staging table like this:

CREATE TABLE [dbo].[SolarStaging](
     [Time] [date] NOT NULL,
     [System_Production_Wh] [varchar](50) NOT NULL
) ON [PRIMARY]
GO

My aim here is to truncate this table, load the entire CSV, and then transform data as needed.

Summary

That’s the basics of my solar tracking database. I have a place to land new data, a table for the estimates I have for each month of the year, and then a table that is essentially a fact table of actual values.

I’ll add more details on how I load data, as well as how to analyze the data over time.

Original post (opens in new tab)
View comments in original post (opens in new tab)

Rate

You rated this post out of 5. Change rating

Share

Share

Rate

You rated this post out of 5. Change rating