import os
from seeq import spy
import pandas as pd
import numpy as np
# Set the compatibility option so that you maximize the chance that SPy will remain compatible with your notebook/script
spy.options.compatibility = 193
# Log into Seeq Server if you're not using Seeq Data Lab:
spy.login(url='http://localhost:34216', credentials_file='../credentials.key', force=False)
Asset Trees 4: Creating Accelerator Templates
The Seeq platform provides the basis for doing all sorts of analytics – leveraging Seeq Workbench, Seeq Organizer, Seeq Data Lab – with Seeq Cortex providing data connection and calculation capabilities.
It can be useful for the Seeq community of partners and users to create
accelerators that deploy proven, standardized analytic approaches in
rapid fashion using SPy’s asset/workbook/topic templating capabilities
in spy.assets
. For example, an expert in monitoring and optimizing
large-scale HVAC installations might develop an Accelerator Template
to deploy a set of useful calculations, visualizations and reports or
dashboards that can handle variations in manufacturer, configuration etc
and provide immediate value that can be expanded and built upon over
time.
This notebook illustrates how to use spy.assets
infrastructure to
create Accelerator Templates. If you haven’t used it before, it is
recommended that you first explore the following:
Asset Trees 2 - Templates to learn about the
spy.assets
infrastructure to create asset trees with calculationsAsset Trees 3 - Report and Dashboard Templates to learn how to create workbooks and topics (reports/dashboards)
This notebook will use the HVAC example data that is installed by default with the Seeq system.
“Requirements”
The most important concept with Accelerator Templates is Requirements. A Requirement specifies an “input” to the template – something that must be provided in order for the template to function. For example, if the template needs an ambient temperature signal in order to calculate an operational efficiency metric, that temperature signal is a Requirement. Furthermore, the operating limits may need to be provided, or perhaps the manufacturer/model of the equipment. These Requirements are the things that vary from installation to installation. The template can be written to adjust to these variations as long as it has the inputs it needs.
Requirements are specified in a class like so:
from seeq.spy.assets import Asset
class HVAC_Monitoring_Requirements(Asset):
@Asset.Requirement()
def Compressor_Power(self, metadata):
"""
Compressor Power as measured at the power supply of the equipment
itself.
"""
return {
'Type': 'Signal',
'Unit Of Measure Family': 'kW'
}
@Asset.Requirement()
def Temperature(self, metadata):
"""
The ambient *external* temperature as measured in a neutral location
away from HVAC inlet/outlet sites.
> Note that this value may be derived from equipment sensors with a
> suitable coefficient to account for location bias.
"""
return {
'Type': 'Signal',
'Unit Of Measure Family': 'F',
'Optional': True
}
Similar to @Asset.Attribute
, Requirements are specified as functions
within a Python class, decorated with @Asset.Requirement
. The
documentation for the function is useful to describe the expectations
for the Requirement. For example, the Temperature
signal that is
supplied to meet one of the Requirements above must be an external
temperature that is not affected by the operation of the HVAC unit.
The return value is a Python dictionary that further constrains the
input. In this case, Temperature
must be a Signal whose unit of
measure is compatible with F
(so, either Fahrenheit, Celsius or
Kelvin).
Temperature
is also marked with 'Optional'
equal to True
.
This means that the template can handle the case where an adequate
temperature signal cannot be supplied. The template may not be able to
provide as many calculations, or perhaps those calculations will be less
accurate.
Analytics!
Now let’s create a simple class that makes use of these two
requirements. In this example, an Inefficient Operation
condition is
calculated by comparing Compressor Power
and Temperature
against
hard-coded limits. (Such limits should likely be determined by
manufacturer specifications or process control limits, but for now we’ll
keep it simple.)
Note how this new HVAC_Monitoring
class is derived from the
HVAC_Monitoring_Requirements
. This allows the
Inefficient Operation
calculation to refer to the members of the
requirements class.
class HVAC_Monitoring(HVAC_Monitoring_Requirements):
@Asset.Attribute()
def Inefficient_Operation(self, metadata):
"""
A condition that is present whenever the HVAC is running in ostensibly
unnecessary environmental situations, resulting in inefficient use of power.
Examples:
* Ambient temperature is within control bounds and does not warrant
cooling
* Environmental conditions are such that HVAC system is operating outside
of its range of capabilities
"""
if not self.Temperature():
return None
return {
'Type': 'Condition',
'Formula Parameters': {
'$power': self.Compressor_Power(),
'$temp': self.Temperature()
},
'Formula': '$power > 20 kW and $temp < 60 F'
}
Input Tree
The template is applied to an existing input tree. This tree must already be constructed, in whatever way makes sense for a particular use case. It may be different in each application of the template – different hierarchy, different organization. The template will be applied to the tree as it is constructed, and any roll-ups will correspond to the particular hierarchy present in the input tree.
In this example, we will use the Example asset tree that comes with
Seeq. So we assemble a metadata DataFrame by doing
spy.search(recursive=True)
.
# Grab the whole tree as the basis of the metadata DataFrame
metadata_df = spy.search({
'Path': 'Example'
}, recursive=True)
# Reduce the number of columns (just for readability)
metadata_df = metadata_df[['ID', 'Path', 'Asset', 'Name', 'Type']]
# This call prepares the metadata DataFrame by adding 'Build Path' and
# 'Build Asset' columns. You can also specify a new root_asset_name, which
# is often desired so that you can differentiate the output tree from the
# input tree.
spy.assets.prepare(metadata_df, root_asset_name='HVAC Monitoring')
# Specify the Build Template. We want to target all leaf "Area" assets (for now)
metadata_df.at[metadata_df['Build Asset'].str.startswith('Area '), 'Build Template'] = 'HVAC_Monitoring'
metadata_df.head()
Build and Push
As with other uses of spy.assets
, we must now build and then push
the results.
build_df = spy.assets.build(HVAC_Monitoring, metadata_df)
push_results_df = spy.push(metadata=build_df)
If you click on the workbook link, you should see a new
HVAC Monitoring
tree in the Data tab with the expected hierarchy
and an Inefficient Operation
condition under each Area.
Brochures
Once you have an accelerator created, you can generate a brochure that advertises the cool analytics that the accelerator provides.
Execute the spy.assets.brochure()
function like so:
html = spy.assets.brochure(HVAC_Monitoring, output='html')
# Write it to a file so we can view it in the browser
os.makedirs('Output', exist_ok=True)
with open('Output/hvac_monitoring_brochure.html', 'w') as f:
f.write(html)
API Reference Links
seeq.spy.assets