Skip to main content
Electricity pylons at sunset
  • Software

Renewable Energy Forecasting for Energy Integration

UL Solutions provides customized, location-specific renewable energy forecasting services for transmission system operators, asset owners and balancing authorities.

Contact us

UL Solutions renewable generation forecasts and long-range analysis of variable renewable power help you manage grid operations, balance energy contribution from traditional and renewable energy sources, and understand impacts on grid reliability, cost and operation.

Proven technology and experience

  • We offer over 25 years of experience in wind and solar forecasting.
  • UL Solutions provides energy forecasts for 47% of the installed wind capacity in the U.S. and Canada.
  • Power forecast provider for over 65% of grid-tied solar capacity in North America.  
  • Provider of renewable energy forecasting services for over 145 GW of centralized and distributed wind and solar generation capacity across the world, including two-thirds of the grid-tied capacity in North America.

 

Value to our customers

Collaboration icon

Customer-centric

Our staff is highly responsive to unique needs and technical requirements and offers 24/7 on-call support.

Icon of a gear inside someone's mind

Experienced

Over 20 years of experience and currently providing forecasts for over 2,500 centralized wind and solar generation facilities globally and nearly 600,000 distributed rooftop photovoltaic (PV) installations.

Icon of a wrench and gear in front of a computer window

Customizable

Our forecasting system is robust and can simulate data to meet a breadth of customers technical requirements.

 

 

Passing inspection report icon

Proven technology

Our localized, plant-specific power forecasts exceed customer’s accuracy expectations in competitive scenarios and our methods consistently remain at the forefront of scientific research.

Icon of a locked padlock

Secure

We meet the strict cybersecurity data and infrastructure requirements of over half the RTOs/ISOs in North America and other transmission system operators and load dispatch centers throughout the world.

 

 

Forecasting, tailored to your needs

We are committed to your success and prepared to offer a range of services. If a forecasting solution would benefit your business, let us help you define and deliver a solution optimized for your needs.

Several computer monitors lined up in a control room

Grid operators/utilities

Forecasts, spanning minutes, hours, and weeks in advance, tailored to meet the economic and reliability requirements that are required by your organization. Let us help you with short-term to long-range analyses of variable power from renewables impact grid reliability, cost and operations. Our forecasting solutions can conform to your requirements and meet your evolving grid challenges.

Power plant control room operator working at his desk

Asset owners/operators

Schedule wind/solar power for sale, understand weather variables and extremes that influence energy production, understand the power output you should have received when a plant has been curtailed, or determine when to schedule construction activities, crane operations, and blade installations to avoid periods of high winds or other weather conditions beyond safe operating conditions.

 

Forecasting approach

Icon of filtering data

Input data

  • Global and regional numerical weather prediction (NWP) model data
  • Satellite data
  • Nearby meteorological and sensor data
Icon of an arrow pointing down
Icon of filtering data

Ensemble of forecast methods

  • Machine learning, statistical and physics-based models
  • Wind or solar-specific
Icon of an arrow pointing down
Icon depicting an increasing bar graph

Optimized ensemble algorithm

  • Machine learning algorithms weight individual forecasts according to historical performance and look-ahead time
  • Produces composite forecasts based on best ensemble members for each look-ahead time
Icon of an arrow pointing down
Icon of a computer with an upward trending line graph

Power production models

  • Delivery of data to customers through primary and secondary delivery mechanisms
  • Optional performance reports, monthly meetings, scope changes, and evolving ways to create, display and deliver results
  • Translates met forecast to power forecast
  • Statistical or physics-based
Icon of an arrow pointing down
Icon depicting a wind turbine

Wind/solar power forecast

  • Delivery of data to customers through primary and secondary delivery mechanisms
  • Optional performance reports, monthly meetings, scope changes, and evolving ways to create, display and deliver results

 

Electrical engineer while working laptop while looking at a power station at dusk

Types of forecasts


Deterministic predictions

  • Our "best estimate" forecast
  • MW production for a specific time interval (e.g., five minutes or hourly)
  • Deterministic forecasts minimize error as measured by a performance metric that will optimize the use of the data for the customer's application.

Probabilistic predictions

  • Used most often to convey forecast uncertainty
  • Offered as a range of probability of exceedance (POE) values and confidence bands that cover the full probability distribution of MW outcomes.

Event forecasts

  • Ramps, high wind/temp shut down, icing, snow on PV panels, etc.
  • Probability of event in specific windows of time
  • Can include customer-defined scenarios, e.g., probability of 40%, 50% or 60% MW decrease within a particular transmission zone over a 60-minute period
  • Includes situational awareness of even tracking through graphics of alerts
Icon of a stopwatch and a calendar
Time horizons for all types of forecasts

Each forecast type can be created and delivered at a time horizon and granularity defined by our customers. Forecasts can be updated at a frequency as often as every five minutes. The prediction intervals can be as granular as five minutes or any sub-hourly interval and span out as far as several weeks into the future.

 

Our forcasting services


Power forecasting

UL Solutions power forecasting services predict future wind and solar power production over the next several minutes out as far as the next several weeks. If you are an asset owner or utility responsible for scheduling or maximizing the profitability of wind or solar power market transactions, or if you are a system operator or utility looking to maintain a reliable transmission grid, our technology experts can optimize and customize the power forecasting services to align exactly with your needs and requirements. Forecasts are tuned to the exact location of the wind and solar plants, and we will optimize the use of all the on-site measurement data available to us to enhance forecasting quality, but we can still produce highly valuable forecasts even when no on-site measurement data is available. Our suite of advanced statistical and machine learning models’ forecasts is optimized for our customer’s application-specific needs.

Sunrise on a solar farm

Weather variables

Wind farm during a storm

Understanding changes in weather variables like temperature, wind speed and direction, irradiance and precipitation can create challenges to renewable plant management and grid optimization. UL Solutions provides weather variable forecasts that can be used as inputs into load forecasting models, situational awareness products, and other weather-sensitive applications. Our weather variable forecasts can be used to optimize energy sales and system reliability and provide advanced warning of changing renewables output and swings in load demands.

Forecasting for extremes

Extreme weather events mean something different for each of our customers and the unique challenges they face in their daily operations. UL Solutions creates forecasts of extremes that match your definition. Often forecasting for extremes focuses on events that cause significant or sudden renewable generation variability, cutouts or conditions that can impact plant or grid operations. These forecasts can be presented as the probability of an extreme event, event alerts, custom graphical outputs and scenarios of potential megawatt (MW) losses. From icing on turbine blades to snow on panels, extreme temperature impacts, to regional generation ramps, UL Solutions can create a forecast for your extremes.

Lightning storm in the distance

Historical hindcasts and forecasts

Two engineers having a discussion in front of a wind farm

 

Hindcasts — sometimes called a forecast of foregone energy or forecast of generation potential — are wind and solar generation predictions over a historical period (e.g., previous day, week or month) based on the resource potential. This is especially helpful if a plant was curtailed, and you need to understand how much energy could have been produced had the plant been operating at full capacity without imposed limits.

Construction forecasting

 

Developers and asset owners can optimally schedule construction activities, crane operations, blade installations, or repairs and avoid periods of high winds or other weather conditions beyond safe operating conditions with construction forecasting services. This forecast includes important information about wind, visibility, precipitation and fog.

The inside of a wind turbine

Grid solutions and renewable simulations

Wind map depiction

UL Solutions' demonstrated ability to model the atmosphere and its impact on the local, regional or global energy industry and estimate the potential generation from a planned solar or wind plant sets us apart from the competition. We can help you by:

  • Simulating the existing, planned future or hypothetical wind and solar plant generation and variability on multiple time scales, spanning monthly generation to second-by-second generation.
  • Creating synthetic power forecasts for the same plants to assist with optimal power scheduling approaches or to inform schedulers how predictable generation might be at plants prior to the plant’s construction.
  • Determining expected coincident generation from other existing or future centralized or distributed resources.
  • Quantifying impacts from anthropogenic climate change on future increased variability or changes in wind and solar resources, wind and solar generation, changes in weather-driven events bringing icing, extreme winds, high or low temperatures, etc.
X

Get connected with our sales team

Thanks for your interest in our products and services. Let's collect some information so we can connect you with the right person.

Please wait…
'; let submitButton = $('form.mktoForm .mktoButtonWrap .mktoButton'); submitButton.prop("disabled", true); submitButton.append(loadingHTML); // Ocp-Apim-Subscription-Key: '***'. var $ocpKey = drupalSettings.ul_marketo_validate_key; var $ocpUrl = drupalSettings.ul_marketo_validate_url; var $ocpEnv = drupalSettings.ul_marketo_validate_env; if (submitCount > 1 || isResponseSuccess == true) { isResponseHandled = true; form.submittable(true); if (paramsDebug.debug == 1) { console.log("NO.10 submitCount > 1: form.submit() "); } submitButton.click(); } else { var email = form.vals().Email; var phone = (form.vals().Phone) ? (form.vals().Phone) : '18472728800'; var country = (form.vals().Country) ? (form.vals().Country) : 'United States'; var countryCode = (phone == '18472728800') ? 'US' : getCountryCode(country); var $emailMsg = drupalSettings.ul_marketo_validate.email; var $phoneMsg = drupalSettings.ul_marketo_validate.phone; if (paramsDebug.debug == 1) { console.log("paramsDebug:"); console.log(paramsDebug); } sendingData = JSON.stringify({ 'Input_Email': email, 'Input_Phone': phone, 'Input_ISO2_Country_Code': countryCode }); if (paramsDebug.debug == 1) { console.log('URL, debug missing button:'); console.log($ocpUrl); console.log("Sending Data to API service (ajax):"); console.log(sendingData); } // API call for validate email/phone/country. var sendDate = (new Date()).getTime(); var responseTimeMs = sendDate; // Start a timer to handle a 3-second response timeout setTimeout(function() { if (!isResponseHandled) { isResponseHandled = true; // Handle the assumed "success" due to timeout here if (paramsDebug.debug == 1) { console.log('No response within timeout, proceeding with default validation success.'); } $('#ValidMsgEmail').remove(); $('#ValidMsgPhone').remove(); // set form to be submittable here $('#valSpinner').remove(); submitButton.prop("disabled", false); // Setup status as Timeout instead of Unknown. emailAddressStatus = "Timeout"; phoneNumberStatus = "Timeout"; phoneNumberValidated = "Timeout"; form.vals({ "emailAddressStatus": emailAddressStatus, "phoneNumberStatus": phoneNumberStatus, "phoneNumberValidated": phoneNumberValidated, }); form.submittable(true); isResponseSuccess = true; if (paramsDebug.debug == 1) { let receiveDate = (new Date()).getTime(); responseTimeMs = (receiveDate - sendDate) / 1000; console.log("setTimeout: " + responseTimeMs + " seconds."); } submitButton.click(); } }, paramsDebug.timeout * 1000); //END setTimeout $.ajax({ url: $ocpUrl, type: 'POST', data: sendingData, headers: { 'Content-Type': 'application/json', 'Ocp-Apim-Subscription-Key': $ocpKey, }, success: function (response) { $('#valSpinner').remove(); submitButton.prop("disabled", false); phoneNumberValidated = response.Validated_Phone_Number; if (!isResponseHandled) { isResponseHandled = true; // **** Handle the validation response if (paramsDebug.debug == 1) { console.log("API Response Data: "); console.log(response); } var emailCode = response.Email_Validation_Status_Number; var phoneCode = response.Phone_Validation_Status_Number; // Add values into two status fields. if (emailValidCode.hasOwnProperty(emailCode)) { emailAddressStatus = emailValidCode[emailCode]; } else { // API error code doesn't exist, set defaul. emailAddressStatus = emailValidCode['300']; } if (phoneValidCode.hasOwnProperty(phoneCode)) { phoneNumberStatus = phoneValidCode[phoneCode]; } else { // API error code doesn't exist, set defaul. phoneNumberStatus = phoneValidCode['301']; } if (emailAddressStatus.indexOf("email_not") != -1) { emailAddressStatus = 'Invalid'; } else if(emailAddressStatus == 'valid') { emailAddressStatus = 'Valid'; } if (phoneNumberStatus.indexOf('invalid_') != -1) { phoneNumberStatus = 'Invalid'; } else if(phoneNumberStatus == 'valid') { phoneNumberStatus = 'Valid'; } if (paramsDebug.debug == 1) { console.log('form.emailAddressStatus ' + emailAddressStatus); console.log('form.phoneNumberStatus ' + phoneNumberStatus); console.log('form.phoneNumberValidated ' + phoneNumberValidated); } if (validEmailCode.includes(emailCode) && validPhoneCode.includes(phoneCode)) { // Remove the loading spinner. $('#ValidMsgEmail').remove(); $('#ValidMsgPhone').remove(); $('#valSpinner').remove(); submitButton.prop("disabled", false); if (paramsDebug.debug == 1) { console.log("NO.1.1 VALID OK submitCount = " + submitCount); } isResponseSuccess = true; form.vals({ "emailAddressStatus": emailAddressStatus, "phoneNumberStatus": phoneNumberStatus, "phoneNumberValidated": phoneNumberValidated, }); form.submittable(true); submitButton.click(); } // API valid code is not "valid". else { form.submittable(false); if (paramsDebug.debug == 1) { console.log("NO.1.2 Submittable false : count= " + submitCount + " validateOrigin " + validateOrigin + " isResponseSuccess " + isResponseSuccess ); } // Set the invalid message in language translation. var msgEmailStatus = ""; if (!validEmailCode.includes(emailCode)) { if (emailCode == '300' || emailCode == '400') { msgEmailStatus = $emailMsg.email_not_valid; } else if (emailCode == '310' || emailCode == '500' ) { msgEmailStatus = $emailMsg.email_not_accept; } else { msgEmailStatus = "Unknown"; } if (paramsDebug.debug == 1) { console.log("NOT validEmailCode: " + msgEmailStatus); } errEmail = ''; $('#Email').after(errEmail); form.submittable(false); } // Set the invalid message in language translation. var msgPhoneStatus = "" if (!validPhoneCode.includes(phoneCode)) { msgPhoneStatus = $phoneMsg[phoneValidCode[phoneCode]]; if (paramsDebug.debug == 1) { console.log("NOT validPhoneCode: " + msgPhoneStatus); } errPhone = ''; $('#Phone').after(errPhone); form.submittable(false); } if (paramsDebug.debug == 1) { console.log(msgEmailStatus); console.log(msgPhoneStatus); } // Remove the loading spinner. $('#valSpinner').remove(); submitButton.prop("disabled", false); if (paramsDebug.debug == 1) { console.log("NO.1.6 Submittable false, count= " + submitCount); } form.vals({ "emailAddressStatus": emailAddressStatus, "phoneNumberStatus": phoneNumberStatus, "phoneNumberValidated": phoneNumberValidated, }); // 2nd API call and subit form. if (submitCount >= 1) { $('#ValidMsgEmail').remove(); $('#ValidMsgPhone').remove(); isResponseSuccess = true; form.submittable(true); if (paramsDebug.debug == 1) { console.log("NO.1.8 : 2nd Submit:: submittable=true && count=1 : " + submitCount); } if (submitCount==1) { submitButton.click(); } } } //END if{} else{}. }//END if (!isResponseHandled) // Calculate the time comsumed for the API call. if (paramsDebug.debug == 1) { let receiveDate = (new Date()).getTime(); responseTimeMs = (receiveDate - sendDate) / 1000; console.log("NO.1.9 : AJAX success: Time for API call: " + responseTimeMs + " seconds."); } submitCount++; }, //END success: function(); // API call error response. error: function (error) { $('#valSpinner').remove(); submitButton.prop("disabled", false); if (!isResponseHandled) { isResponseHandled = true; $('#valSpinner').remove(); submitButton.prop("disabled", false); // 2nd API call and subit form. if ( submitCount >= 1 ) { $('#ValidMsgEmail').remove(); $('#ValidMsgPhone').remove(); form.submittable(true); isResponseSuccess = true; if ( submitCount == 1 ) { form.submittable(true); } } // Handle AJAX error if (paramsDebug.debug == 1) { console.log('**** 2 ajax error. submitCount = ' + submitCount); console.log(error); } // Calculate the time comsumed for the API call. if (paramsDebug.debug == 1) { let receiveDate = (new Date()).getTime(); responseTimeMs = (receiveDate - sendDate) / 1000; console.log("NO.2.3 AJAX error: Time for API call: " + responseTimeMs + " seconds."); } } submitCount++; // Error status 500, then submit the form. submitButton.click(); } //END error: function(); }); //END $.ajax; if (isResponseSuccess) { if (paramsDebug.debug == 1) { console.log("NO.8.0 submittable(true)"); } form.submittable(true); } } //END: if (submitCount > 1) else // Setup the form.vals and form.submittable; form.vals({ "emailAddressStatus": emailAddressStatus, "phoneNumberStatus": phoneNumberStatus, "phoneNumberValidated": phoneNumberValidated, }); } //END: if (validateOrigin && (marketoBundle)) else { // For Event form and Newsletter form. if (validateOrigin === true){ form.submittable(true); } } }); //END form.onValidate() // Success callback() form.onSuccess(function(values, followUpUrl){ // Debug Phone/Email validation. if (paramsDebug.debug == 1) { console.log("NO.9.1 onSuccess: submittable = " + form.submittable()); console.log(form.getValues()); } // Track analytics. if (typeof dataLayer !== 'undefined'){ dataLayer.push({ event: drplMkto.dataLayerEvent, mktoFormId: form.getId(), 'FormValues': cleanFormVals(form.getValues()), 'FormFields': form.allFieldsFilled(), 'Submittable': form.submittable() }); } // If function exists, delete UTM cookie: if(typeof _deleteUtmCookie === "function"){ _deleteUtmCookie(); } // Marketo Modal "Thank You" message: if(use_post_submit_mssg){ $('html, body').animate({ scrollTop: 0 }, 'slow'); $('.mkto-presubmit').addClass('hidden'); $('.mktoModalContent').addClass('mkto_thnx_center'); $('.mktoModalMask').addClass('not_clicable'); $('.mkto-postsubmit').removeClass('hidden'); $('.mktoButton').removeAttr('disabled').text(drupalSettings.marketo.button_text); $('.mktoForm')[0].reset(); grecaptcha.reset(); } // Else, redirect user: else { window.location.href = drplMkto.success_url; } // IMPORTANT: Return false to prevent further code execution. return false; }); //END form.onSuccess. }); })(jQuery, drupalSettings.marketo);