With the Internet of Things (IoT) revolution, a lot of commonplace devices are able to generate very meaningful data--for example, electric vehicle chargers, which are able to return information about charge duration, energy provided, and even greenhouse gas offsets and driver zip codes.  The beauty of the PI System is that it allows you to compare data from sources like that, and nearly any other data source imaginable, in a single, efficient infrastructure.  But that of course begs the question: how might one interface such an IoT device with the PI System?


In the case of electric vehicle chargers--specifically, ChargePoint (Electric Vehicle Charging By ChargePoint) chargers, this can be easily done with PowerShell, a free automation framework invented by Microsoft and distributed for free on all Windows machines.  Your interface and web servers and PI Servers already have PowerShell installed, and thus if you want to start ingesting this data into the PI System, all you need is the right script.


The below script which was developed allows you to input your ChargePoint username (typically your email), and your password--and it allows you to furthermore encrypt your password into a meaningless alphanumeric string, so that your password isn't written in plain text in the script.  Using those credentials, then, the script signs into ChargePoint's online management portal and downloads a 7-day history of charging activity, as a text file that can easily be parsed by the Universal File and Stream Loading (https://techsupport.osisoft.com/Products/PI-Interfaces-and-PI-Connectors/PI-Interface-for-Universal-File-and-Stream-Load…).


All you need to do, then, is copy this text into a text file, rename that file to have a .ps1 extension--which is the extension used by PowerShell--add your credentials, and then run the script (you can right-click it and select "Run with PowerShell", or select "Edit" to open the PowerShell ISE, where you can make changes to the code more easily, as well as running the code).


(Note: if you're running PowerShell for the first time, you'll likely have to change your Execution Policy (Using the Set-ExecutionPolicy Cmdlet) by running PowerShell as an Administrator, then running the command


    set-executionpolicy remotesigned


After you answer the prompt with "yes", this will allow PowerShell scripts to run.


The script can then be scheduled to run automatically as a Windows Scheduled Task (Weekend Scripter: Use the Windows Task Scheduler to Run a Windows PowerShell Script - Hey, Scripting Guy! Blog - Site Ho…), executing every day or so, guaranteeing that you have a continuously live stream of charging data.


I hope this script proves useful for folks who are interested in adding charger data to their PI Systems!  At the very least, this script could prove a valuable starting point for your research.  On that note, then, a disclaimer: this script was developed independently from ChargePoint, and it thus depends on ChargePoint not altering the fundamentals of their signin process, and on them leaving their data access URLs in place.  Should ChargePoint change their login process, this script will no longer work; it's thus provided as-is, so that, should future changes occur, it can be modified or built upon to accommodate those changes.


Happy scripting!




# ***********************************************************************


# *

# * All sample code is provided by OSIsoft for illustrative purposes only.

# * These examples have not been thoroughly tested under all conditions.

# * OSIsoft provides no guarantee nor implies any reliability,

# * serviceability, or function of these programs.





# ************************************************************************


Write-host "Downloading ChargePoint Data"


# Specify the location for the output files

$MyDestinationFolderName = "DownloadedChargePointData"

$MyDestinationFileName = "ChargePointUsageTable.csv"


# Specify a string for how many days of data you want returned with each query; either 7 or 30

$MyNumberOfDays = "30"; #7 or 30, as a string


# Create the target folder if it does not exist

$MyDestinationFolder = "C:\" + $MyDestinationFolderName + "\"

If(!(Test-Path -Path $MyDestinationFolder)) {

    New-Item -ItemType directory -Path $MyDestinationFolder



# --------------------------------------------------------------------------------------


# Set the ChargePoint username !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

$MyUsername = ""


## To encrypt a password, run just this section of code, then copy the value of encryptedStringAsPlainText and use it to set the value of the $encryptedStringAsPlainText variable

#$PlainPassword = Read-Host -Prompt "Enter password"

#$SecurePassword = $PlainPassword | ConvertTo-SecureString -AsPlainText -Force

#$encryptedStringAsPlainText = convertfrom-securestring -secureString $SecurePassword -key (1..16)




# For the password, decrypt the encrypted password

$encryptedStringAsPlainText = "This will be a long alphanumeric string generated by the above code; paste the encrypted string here"

$SecureString = $encryptedStringAsPlainText | convertto-securestring -key (1..16)

$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList 'nulldomain,nulluser',$SecureString

$MyPassword = $Credentials.GetNetworkCredential().password


# --------------------------------------------------------------------------------------


# Arrive at the web page

$MyURL1 = "https://na.chargepoint.com/home"

$MyWebRequest1 = Invoke-WebRequest $MyURL1 -SessionVariable MySessionVariable -Method Get


# --------------------------------------------------------------------------------------


# Sset your time zone

$MyTimeZone = ""

Foreach ($Word in ([System.TimeZone]::CurrentTimeZone).StandardName.Split(" "))


    $MyTimeZone = $MyTimeZone + $Word.Substring(0,1)


#$MyTimeZone = "CST"

# Build a string of parameters that will be sent in a web request; these contain your login information

$MyInitialFormData = "user_name=" + $MyUsername + "&user_password=" + $MyPassword + "&recaptcha_response_field=&timezone_offset=360&timezone=" + $MyTimeZone + "&timezone_name="

# Send the login request, containing the username and password data

$MyURL2 = "https://na.chargepoint.com/users/validate"

$MyWebRequest2 = Invoke-WebRequest $MyURL2 -WebSession $MySessionVariable -Method POST -Body $MyInitialFormData

write-host "Authentication status:" $MyWebRequest2.Content.ToString()


# --------------------------------------------------------------------------------------


# Perform the data request

$MyURL3 = "https://na.chargepoint.com/report/analysisChartsTableData?reportName=energy&reportBy=time&exportData=csv&filterOptions=%5B%7B%22fieldName%22%3A%22vehicleChargeMacAddress%22%2C%22operator%22%3A%22CONTAINS%22%2C%22value%22%3A%22%22%2C%22type%22%3A%22text%22%7D%2C%7B%22fieldName%22%3A%22vehicleChargeCompanyName%22%2C%22operator%22%3A%22CONTAINS%22%2C%22value%22%3A%22%22%2C%22type%22%3A%22text%22%7D%2C%7B%22fieldName%22%3A%22vehicleChargeDeviceName%22%2C%22operator%22%3A%22CONTAINS%22%2C%22value%22%3A%22%22%2C%22type%22%3A%22text%22%7D%2C%7B%22fieldName%22%3A%22vehicleChargeDeviceSerialNo%22%2C%22operator%22%3A%22CONTAINS%22%2C%22value%22%3A%22%22%2C%22type%22%3A%22text%22%7D%5D&filterJoinType=All&startDate=undefined&endDate=undefined&reportPeriod=last" + $MyNumberOfDays + "Days&sSortDir_0=desc&sortColumnId=vehicleChargeBillingTransactionTime"

$MyWebRequest3 = Invoke-WebRequest $MyURL3 -WebSession $MySessionVariable -Method GET


# Clean the data; remove any special characters

$MyData = $MyWebRequest3.Content -replace """", ""


# Write the contents to a file

Out-File ("C:\" + $MyDestinationFolderName + "\" + $MyDestinationFileName) -InputObject $MyData -Encoding ascii

write-host "Finished attempting to download file."


# --------------------------------------------------------------------------------------


# Sign out

$MyURL4 = "https://na.chargepoint.com/logout"

$MyWebRequest4 = Invoke-WebRequest $MyURL4 -WebSession $MySessionVariable -Method GET

write-host "Signout complete."


# --------------------------------------------------------------------------------------


# Remove web session variable

Remove-Variable MySessionVariable