Muhammad Waseem · Sep 13 5m read

Sustainable energy data by calling API from the major Independent System Operators (ISOs) in the United States with the help of PEX and Embedded Python


Hi Community,

In this article I will demonstrate the functionality of my app iris-energy-isodata .  
Application is accessing energy data (production, demand and supply)  from the major Independent System Operators (ISOs) in the United States to ensure sustainable consumption and production patterns (SDG's 12)

Application is using python library isodata , Production EXtension PEX  along with Embedded Python.  Special Thanks to @Guillaume Rongier for the template  template for guidance

Below is the list of Independent System Operators(ISOs)

  1.  California ISO (caiso)
  2.  PJM (pjm)
  3.   ISO New England (isone)

And below are the details of energies 

  1. Natural Gas 
  2. Solar       
  3. Imports     
  4. Wind        
  5. Large Hydro 
  6. Nuclear     
  7. Batteries   
  8. Geothermal  
  9. Biomass     
  10. Small hydro 
  11. Biogas      
  12. Coal       

So let's start

First of all we have to start the production.

Our production contains 3 Business Services (Every ISO's has its own service) 
Business service importing BusinessService class which is inherited from  Ens.BusinessService and isodata python library.
Below python code of business service Isodata.CaliforniaService is calling get_latest_fuel_mix() function to get detail productions of energies, get_demand_today() function to get today  demand and get_supply_today() function to get today supply.

from grongier.pex import BusinessService
import isodata

#Event to get data and pass to process
def on_task(self) -> PostClass:
     #selecting ISO's
     iso = isodata.get_iso('caiso')
     caiso = iso()
     #Get production details of the entergies
     getdata = str(caiso.get_latest_fuel_mix())
     #Get today Demand
     demandpd = caiso.get_demand_today()
     demand = str(demandpd['Demand'].iloc[0])
     #Get today Supply
     supplypd = caiso.get_supply_today()
     supply = str(supplypd['Supply'].iloc[0])
     post = PostClass.from_dict(value['data'])
     post.fuel_mix = getdata
     post.demand = demand+" NW" = supply+" NW"
     return post

Business Process

Business process importing BusinessProcess class which is inherited from  Ens.BusinessProcess. Getting message from service and based on the title passing to the operation.
Below is the python code of Business Process (Isodata.FilterRoutingRule)

from grongier.pex import BusinessProcess
from message import PostMessage
from obj import PostClass
import iris

class FilterPostRoutingRule(BusinessProcess):
    This process receive a PostMessage and send to operation based on the title
    def on_init(self):
        if not hasattr(self,'target'):
   = "Isodata.CaliforniaOperation"
    def iris_to_python(self, request:'iris.dc.Demo.PostMessage'):
        request = PostMessage(post=PostClass(title=request.Post.Title,                                             
        return self.on_python_message(request)

    def on_python_message(self, request: PostMessage):
        #based on the title from message, routing to the operation
        if 'caiso'.upper() in
            target = "Isodata.CaliforniaOperation"
        elif 'ercot'.upper() in
            target = "Isodata.TexasOperation"
        elif 'nyiso'.upper() in
            target = "Isodata.NewYorkOperation"
        elif 'spp'.upper() in
            target = "Isodata.SouthWestOperation"
        elif 'pjm'.upper() in
            target = "Isodata.PjmOperation"
        elif 'miso'.upper() in
            target = "Isodata.MidcontinentOperation"
        elif 'isone'.upper() in
            target = "Isodata.IsoneOperation"
        if target is not None:
            rsp = iris.cls('Ens.StringResponse')._New(f"{}")
            return rsp


Business Operation

Business Operation importing BusinessOperation class which is inherited from Ens.BusinessOperation.
Business Operation is receiving message from Business process and writing the message details to the file based on the message title.
Below is the python code of Business Operation (Isodata.CaliforniaOperation)

from grongier.pex import BusinessOperation, Utils
import iris
import os
import datetime
import smtplib
from email.mime.text import MIMEText

class FileOperation(BusinessOperation):
    This operation receive a PostMessage and write down in the right company
    .txt all the important information and the time of the operation
    def on_init(self):
        if hasattr(self,'path'):

    def on_message(self, request):
        ts = title = fuel_mix =  demand = supply = ""
        fuel_mix =
        demand =
        supply =

        if ( is not None):
            title =
            ts = datetime.datetime.fromtimestamp(

        line = ts+" : "+title
        filename = title+".txt"
        self.put_line(filename, line)
        self.put_line(filename, "")
        self.put_line(filename, fuel_mix)
        self.put_line(filename, "")
        self.put_line(filename, demand)
        self.put_line(filename, "")
        self.put_line(filename, supply)
        self.put_line(filename, " * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *")

    def put_line(self,filename,string):
            with open(filename, "a",encoding="utf-8") as outfile:
        except Exception as e:
            raise e


Below is the message details which contains ISO name, Total production, details of energies, today demand and supply



0 113
Discussion (2)1
Log in or sign up to continue