React bindings for the OpenSolar SDK (OsSdk).
Use the following command to install:
npm install --save @opensolar/ossdk-react
If you are migration from ossdk-react
you can find instructions below. The package ossdk-react
is deprecated in favour of this package.
- Update
package.json
: change the dependency fromossdk-react
to@opensolar/ossdk-react
- Update imports: change imports from
import OsSdkView from 'ossdk-react'
toimport OsSdkView from '@opensolar/ossdk-react'
The key component to embed the OpenSolar SDK within your app is OsSdkView
.
import React, { Component } from 'react'
import OsSdkView from '@opensolar/ossdk-react'
class Example extends Component {
render() {
return (
<OsSdkView
key={'unique-identifier-within-page'}
osToken={'Token or empty if using SSO'}
osScriptLocation={'https://app.opensolar.com/sdk/v1.0/min.js'}
osSdkKey={'my-sdk-key'}
projectData={[{identifier: '123-main-st-uuid'}]}
projectIdentifiersToken={'xyz'}
onLoad={(ossdk) => {
clearSignalHandlers(ossdk);
ossdk.studio.objectSelected.add((object) => {
console.log("objectSelected", object);
});
}}
onRemove={(ossdk) => {
clearSignalHandlers(ossdk);
}}
/>
)
}
}
- osSdkKey: (string, requried): Key supplied by OpenSolar. Required in order to use the SDK.
- key: (string, required): Unique key used by React which is used to control when the component should be reloaded. Value should be unique within the React context.
- height: (number, optional) Height of the component, in pixels. Defaults to 600px. Note: Width is always 100% of the container width.
- toolbar: (ReactElement, optional): Toolbar to display at the top of the OsSdkView.
- osToken: (string, optional): OsSdk token which has been securely generated using an OsSdk Signing Key. Used for authentication against SDK. Leave this out if using SSO.
- projectIdentifiersToken: (string, optional): Additional token, only used to grant additional project access permissions when using SalesForce SSO. When authenticating with OsSdk Tokens the project permissions should be added there, and projectIdentifiersToken should be omitted.
- osScriptLocation: (string, required): URL to the SDK script. Set based on target environment which will be provided as appropriate. Usually: https://api.opensolar.com/sdk/v1.0/min.js
-
projectData: (object, required): Dictionary containing data that is used to initialize the design (and can be used to update the same properties when returning to an existing design). Including:
- Required fields:
- identifier (string, unique, required): Unique identifier of the project.
- lon (float, required): Used to start design at correct location
- lat (float, required): See lon.
- Optional fields:
- address (string, optional)
- locality (string, optional)
- state (string, optional): 2-letter state.
- zip (string, optional)
- country_iso2 (string, optional): 2-letter Country ISO.
- Required fields:
-
sdkConfig: (object, required if using SSO): Configuration options passed to the SDK. Options include:
-
view_overrides
: Customize UI elements including showing/hiding. See below for available options. -
login_configs_override
: SSO Configuration. Only available in localhost during development. For online/production use this must be configured by OpenSolar and associated with theosSdkKey
value, see above. Contact OpenSolar Support to setup.
-
-
extraScriptParams: (string, deprecated): Options for configuring the SDK, as a query that can be appended to a URL. Supports the same config variables as
sdkConfig
but is deprecated in favor ofsdkConfig
. -
onMessage: (function, optional): Handler for showing messages generated by OsSdk in your container app. message.severity can be:
success
,error
,debug
. Example:onMessage={(message, err) => { let messageText = message.text + (err && err?.message ? ": " + err.message : ""); if (message.severity !== "debug") { yourShowAlertMessage(messageText, message.severity); } if (err) console.warn(err); }}
-
onLoad: (function, optional): Handler which fires after ossdk is initialized. Add handlers so your app can respond to events generated by OsSdk. See below for all available methods. Example:
// In the example below, the following functions are defined by your app: // - setCurrentRole // - setHasUnsavedChanges // - setSelected // - setSystem onLoad={(ossdk) => { // Clear signal handlers first to ensure that there are no lingering handlers from a previous sdk instance. // Sometimes they may not cleanup handlers if they do not exit as expected, e.g. when the iframe is removed // rather than simply removing the sdk react component. clearSignalHandlers(ossdk) ossdk.current_org.id.add((state) => { setOrgId(state); }, { now: true }) ossdk.auth.current_role.add((state) => { setCurrentRole(state); }, { now: true }) ossdk.project_form.dirty_fields.add((state) => { setHasUnsavedChanges(state.length > 0); }, { now: true }) ossdk.studio.objectSelected.add((object) => { setSelected(object) if (object?.type === "OsSystem") { setSystem(object) } }); ossdk.studio.objectAdded.add((object) => { console.log("objectAdded", object) }); ossdk.studio.objectChanged.add((object, attributeName) => { if (object?.type === "OsSystem") { setSystem(object) } }) ossdk.studio.objectRemoved.add((object) => { console.log("objectRemoved", object) }) ossdk.studio.sceneLoaded.add(() => {setIsStudioReady(true) }) ossdk.studio.queueProcessed.add((progress) => { setProgress(progress)} ) }}
-
onRemove: (function, optional): Clean up and remove handlers when component is removed from the DOM. Sample:
onRemove={(ossdk) => { clearSignalHandlers(ossdk); }}
-
auth
- ossdk.auth.current_role
- ossdk.auth.logout
- ossdk.auth.refreshToken
- ossdk.auth.setProjectIdentifiersToken
-
current_org
-
flows
- ossdk.flows.createOrUpdateProject
- ossdk.flows.generateDocument
-
project_form
- ossdk.project_form.active
- ossdk.project_form.discard
- ossdk.project_form.dirty_fields
- ossdk.project_form.getDesignData
- ossdk.project_form.save
- ossdk.project_form.save_state
- ossdk.project_form.save_state.value
- ossdk.project_form.system_count.value
- ossdk.project_form.system_summaries.value
- ossdk.project_form.setValues
- ossdk.project_form.values
-
resources
- ossdk.resources.projects
-
route
- ossdk.route.goto
- ossdk.route.path
- ossdk.route.path.value
- ossdk.route.route.add
- ossdk.route.route
- ossdk.route.route.remove
- ossdk.route.route.value
-
studio
- ossdk.studio.callFunction
- ossdk.studio.executeCommand
- ossdk.studio.getLoadedData
- ossdk.studio.getSelectedSystemData
- ossdk.studio.getSystemImageUrl
- ossdk.studio.setComponents
- ossdk.studio.autoDesignRunAndLoadFromEquipment
- ossdk.studio.objectSelected
- ossdk.studio.objectAdded
- ossdk.studio.objectChanged
- ossdk.studio.objectRemoved
- ossdk.studio.sceneLoaded
- ossdk.studio.queueProcessed
const { loaded, ossdk } = useOsSdk();
ossdk.auth.refreshToken(newToken);
// setOrgId is defined by your Container App
onLoad={(ossdk) => {
ossdk.current_org.id.add((state) => { setOrgId(state) }, { now: true })
})
Save Design to OpenSolar Database
ossdk.project_form
.save()
.then(() => console.log("Project saved"))
.catch((e) => console.error("Failed to save project", e))
Discard changes and revert to design from database.
ossdk.project_form
.discard()
.then(() => console.log("Project discarded"))
.catch((e) => console.error("Failed to discard project", e))
Set hardware explicitly for the current system. Note: "Panel" type hardware can be set here but still need to be placed manually.
Arguments:
-
components: { code: string, quantity?: number }[]
. Components and quantities to add. -
keepExistingComponents?: Boolean
(optional, default: false). By default this will clear all components of the current system before adding the specified components. -
systemUuid?: string
. Optionally update a specific system. If omitted it will update the currently selected system.
ossdk.studio.setComponents([
{ code: "Q.PEAK DUO BLK ML-G10+ 400" },
{ code: "IQ6-60-2-INT" },
{ code: "Tesla Powerwall 2.0" },
{ code: "ENV-S-WM-230", quantity: 4 },
])
Handling queueProcessed signals:
ossdk.studio.queueProcessed.add((progress) => {
console.log(progress)
} )
Sample progress
payload:
{
// list of system uuids with calcs in progress
systemCalcsInProgressUuids: ['abc','def'],
// scene is loading
sceneLoadingInProgress: false,
// any views are loading including any 3D data loading
viewsLoadingInProgress: false,
// any system calcs are awaiting or in progress
systemCalcsInProgress: false,
// auto-design is in progress
autoDesignEphemeralInProgress:false,
// any full calcs are in progress
fullCalcsInProgress: false,
// false if any other work is in progress except for fullCalcsInProgress
// because this is not handled by studio in the front-end, it is a separate
// background/back-end process that is relevant to track but not actually
// something being "done" in studio.
idle: true
}
Get fields on the OS "Project" record such as: id, address, zip, state, country_iso2, lon, lat
console.log(ossdk.project_form.values.address)
Design data as JSON, including all aspects of designs, shading simulations & calculations. e.g.
- Annual output can be accessed at
designData.object.children[0].userData.output.annual
- Panel quantity at
designData.object.children[0].userData.moduleQuantity
ossdk.project_form.getDesignData().then((designData) => {
console.log(designData)
})
const view_overrides = {
"header": { "show": true },
"homepage": { "show": true },
"forms.project.header": { "show": true },
"forms.project.save_status": { "show": true },
"studio.systems": { "show": true },
"studio.tab_panels.summary": { "show": true },
"studio.systems.overview": { "show": true },
"studio.tabs.panels.add": { "show": true },
"studio.systems.add_new_system": { "show": true },
"studio.systems.duplicate_system": { "show": true },
"studio.tabs.summary": { "show": true },
"studio.tabs.panels": { "show": true },
"studio.tabs.panels.select_panel_type": { "show": true },
"studio.tabs.panels.buildable_panels": { "show": true },
"studio.tabs.panels.select_dc_optimizer": { "show": true },
"studio.tabs.selected_panel_group.basic_settings": { "show": true },
"studio.tabs.selected_panel_group.advanced_settings": { "show": true },
"studio.tabs.selected_panel_group.shading": { "show": true },
"studio.tabs.selected_panel_group.buildable_panels": { "show": true },
"studio.tabs.selected_panel_group.tools": { "show": true },
"studio.tabs.selected_panel_group.tools.FillRectangle": { "show": true },
"studio.tabs.selected_panel_group.tools.FillFacet": { "show": true },
"studio.tabs.selected_panel_group.tools.SelectFacet": { "show": true },
"studio.tabs.selected_panel_group.tools.Duplicate": { "show": true },
"studio.tabs.selected_panel_group.tools.AutoString": { "show": true },
"studio.tabs.selected_panel_group.tools.Delete": { "show": true },
"studio.tabs.mounting": { "show": true },
"studio.tabs.inverters": { "show": true },
"studio.tabs.batteries": { "show": true },
"studio.tabs.others": { "show": true },
"studio.tabs.pricing": { "show": true },
"studio.tabs.payment_options": { "show": true },
"studio.tabs.scaffolding": { "show": true },
"studio.tabs.incentives": { "show": true },
"studio.select_design_mode": { "show": true },
"studio.select_design_mode.2D": { "show": true },
"studio.select_design_mode.3D": { "show": true },
"studio.select_design_mode.Manual": { "show": true },
"studio.advanced": { "show": true },
"studio.advanced.DesignGuides": { "show": true },
"studio.advanced.Restart": { "show": true },
"studio.advanced.Recalculate": { "show": true },
"studio.advanced.DownloadDxf": { "show": true },
"studio.view_controls": { "show": true },
"studio.view_controls.ViewShadeButton": { "show": true },
"studio.view_controls.AlignMapButton": { "show": true },
"studio.view_controls.StreetViewButton": { "show": true },
"studio.view_controls.ZoomOutButton": { "show": true },
"studio.view_controls.ZoomInButton": { "show": true },
"studio.view_controls.MeasureHeightButton": { "show": true },
"studio.view_controls.DownloadSnapshotsButton": { "show": true },
"studio.view_selector": { "show": true }
}