{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from seeq import spy\n",
    "\n",
    "# Set the compatibility option so that you maximize the chance that SPy will remain compatible with your notebook/script\n",
    "spy.options.compatibility = 193"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Logged in to <strong>http://localhost:34216</strong> as <strong>agent_api_key</strong>.<br>Seeq Server Version: <strong>R66.0.0-SNAPSHOT</strong><br>Seeq SDK Module Version: <strong>66.0.0</strong> @ C:\\git\\crab\\sdk\\pypi\\seeq\\sdk<br>Seeq SPy Module Version: <strong>193.0</strong> @ C:\\git\\crab\\sdk\\pypi\\seeq\\spy</div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Log into Seeq Server if you're not using Seeq Data Lab:\n",
    "spy.login(url='http://localhost:34216', credentials_file='../credentials.key', force=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "# Asset Trees 3: Report and Dashboard Templates\n",
    "\n",
    "This tutorial leverages the capabilities of the **spy.assets** templates (as described in [Asset Trees 2 - Templates](Asset%20Trees%202%20-%20Templates.ipynb)) and **spy.workbooks** templates (as described in [Workbook Templates](Workbook%20Templates.ipynb)) to show you how to create Displays, Analysis Workbooks/Worksheets and Organizer Topics for your asset tree.\n",
    "\n",
    "First, some definitions:\n",
    "\n",
    "- **Display**: The definition of a visualization that can be rendered in Seeq Workbench. A Display can be a Trend, XY Plot, Treemap or Table. Technically speaking, a Display corresponds to what Seeq refers to internally as a **Workstep**.\n",
    "- **Document**: In Seeq Organizer, each \"worksheet\" on the left-hand side of the display is called a Topic _Document_. Documents have rich text, images, and embedded content (called _Displays_ in this context) with associated Date Ranges and Asset Selections.\n",
    "- **Asset**: An organizing unit / container that typically encapsulates Signals, Conditions, Scalars. They can also encapsulate the aforementioned Display and Document definitions.\n",
    "\n",
    "## Leveraging Purpose-Built Asset Trees\n",
    "\n",
    "With the **spy.assets** module, you can quickly create an asset tree that is specific to a particular purpose. By default, the tree will be \"sandboxed\" to a single Workbook so that it isn't exposed to the rest of your colleagues. We are going to create an asset tree that captures all of the data we need, and then we're going to add *Topic Documents* and *Displays*."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "First let's create a simple asset tree using the built-in Example data representing HVAC systems within three different facilties. It is recommended that you review the [Asset Trees 2 - Templates](Asset%20Trees%202%20-%20Templates.ipynb) documentation if haven't seen this technique yet.\n",
    "\n",
    "Let's assemble the \"ingredients\" of our tree: the signal metadata with which we will populate asset attributes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Query successful</div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">Name</td><td style=\"background-color: #EEFFEE; text-align: left;\">Datasource Name</td><td style=\"background-color: #EEFFEE; text-align: right;\">Time</td><td style=\"background-color: #EEFFEE; text-align: right;\">Count</td><td style=\"background-color: #EEFFEE; text-align: right;\">Pages</td><td style=\"background-color: #EEFFEE; text-align: left;\">Result</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">/Area [ABCDEG]_.*/</td><td style=\"text-align: left; vertical-align: top;\">Example Data</td><td style=\"vertical-align: top;\">00:00:00.05</td><td style=\"text-align: right; vertical-align: top;\">37</td><td style=\"text-align: right; vertical-align: top;\">1</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Name</th>\n",
       "      <th>Description</th>\n",
       "      <th>Type</th>\n",
       "      <th>Value Unit Of Measure</th>\n",
       "      <th>Datasource Name</th>\n",
       "      <th>Archived</th>\n",
       "      <th>Build Path</th>\n",
       "      <th>Build Asset</th>\n",
       "      <th>Facility</th>\n",
       "      <th>Section</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0EF58FC2-8C7F-6290-BEE8-1BE39219249E</td>\n",
       "      <td>Area A_Compressor Power</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>kW</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>None</td>\n",
       "      <td>North America</td>\n",
       "      <td>Facility 1</td>\n",
       "      <td>Section A</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0EF58FC2-85EA-F970-941E-20CF2C149E2D</td>\n",
       "      <td>Area A_Compressor Stage</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>string</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>None</td>\n",
       "      <td>North America</td>\n",
       "      <td>Facility 1</td>\n",
       "      <td>Section A</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0EF58FC2-82CE-FB10-95A4-EFA2E6D878DB</td>\n",
       "      <td>Area A_Optimizer</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>None</td>\n",
       "      <td>North America</td>\n",
       "      <td>Facility 1</td>\n",
       "      <td>Section A</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0EF58FC2-83AA-66B0-8B9F-E021808A2620</td>\n",
       "      <td>Area A_Relative Humidity</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>%</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>None</td>\n",
       "      <td>North America</td>\n",
       "      <td>Facility 1</td>\n",
       "      <td>Section A</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0EF58FC2-8206-77F0-8519-ECD251B886A6</td>\n",
       "      <td>Area A_Temperature</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>°F</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>None</td>\n",
       "      <td>North America</td>\n",
       "      <td>Facility 1</td>\n",
       "      <td>Section A</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     ID                      Name  \\\n",
       "0  0EF58FC2-8C7F-6290-BEE8-1BE39219249E   Area A_Compressor Power   \n",
       "1  0EF58FC2-85EA-F970-941E-20CF2C149E2D   Area A_Compressor Stage   \n",
       "2  0EF58FC2-82CE-FB10-95A4-EFA2E6D878DB          Area A_Optimizer   \n",
       "3  0EF58FC2-83AA-66B0-8B9F-E021808A2620  Area A_Relative Humidity   \n",
       "4  0EF58FC2-8206-77F0-8519-ECD251B886A6        Area A_Temperature   \n",
       "\n",
       "   Description          Type Value Unit Of Measure Datasource Name  Archived  \\\n",
       "0          NaN  StoredSignal                    kW    Example Data     False   \n",
       "1          NaN  StoredSignal                string    Example Data     False   \n",
       "2          NaN  StoredSignal                   NaN    Example Data     False   \n",
       "3          NaN  StoredSignal                     %    Example Data     False   \n",
       "4          NaN  StoredSignal                    °F    Example Data     False   \n",
       "\n",
       "  Build Path    Build Asset    Facility    Section  \n",
       "0       None  North America  Facility 1  Section A  \n",
       "1       None  North America  Facility 1  Section A  \n",
       "2       None  North America  Facility 1  Section A  \n",
       "3       None  North America  Facility 1  Section A  \n",
       "4       None  North America  Facility 1  Section A  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "metadata_df = spy.search({'Name': '/Area [ABCDEG]_.*/', 'Datasource Name': 'Example Data'})\n",
    "\n",
    "# Assign a blank Build Path because we are creating a top-level node\n",
    "metadata_df['Build Path'] = None\n",
    "\n",
    "# There will only be one Build Asset -- all other sub-assets will be created by Components in our class definitions\n",
    "metadata_df['Build Asset'] = 'North America'\n",
    "\n",
    "# Assign each of the Example data's \"Areas\" to one of two \"Facilities\"\n",
    "metadata_df['Facility'] = pd.Series(np.nan, metadata_df.index, dtype=object)\n",
    "metadata_df.loc[metadata_df['Name'].str.match(r'Area [ABC].*'), 'Facility'] = 'Facility 1'\n",
    "metadata_df.loc[metadata_df['Name'].str.match(r'Area [DEG].*'), 'Facility'] = 'Facility 2'\n",
    "\n",
    "# Let's call the areas \"Sections\"\n",
    "metadata_df['Section'] = 'Section ' + metadata_df['Name'].str.extract(r'Area (\\w).*')\n",
    "\n",
    "metadata_df.head(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Next we will define an asset tree that organizes our signals into a *region* (`North America`), two *facilities*, and several *sections*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "from seeq.spy.assets import Asset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "#\n",
    "# As you will see later in this notebook, we will be using Python class inheritance to build more\n",
    "# capability off of these \"base\" classes.\n",
    "#\n",
    "# The asset hierarchy will be structured as Region >> Facility >> Section.\n",
    "#\n",
    "\n",
    "class Section(Asset):\n",
    "    #\n",
    "    # Each section has three Attributes: two signals measuring ambient conditions (Temperature,\n",
    "    # Humidity) and one measure the operating state of equipment (Power).\n",
    "    #\n",
    "    @Asset.Attribute()\n",
    "    def Temperature(self, metadata):\n",
    "        return metadata[metadata['Name'].str.endswith('Temperature')]\n",
    "\n",
    "    @Asset.Attribute()\n",
    "    def Humidity(self, metadata):\n",
    "        return metadata[metadata['Name'].str.endswith('Humidity')]\n",
    "\n",
    "    @Asset.Attribute()\n",
    "    def Compressor_Power(self, metadata):\n",
    "        return metadata[metadata['Name'].str.endswith('Power')]\n",
    "\n",
    "\n",
    "class Facility(Asset):\n",
    "    #\n",
    "    # Each Facility has a set of Components representing each Section. The \"Section\" column\n",
    "    # differentiates the metadata for each one.\n",
    "    #\n",
    "    @Asset.Component()\n",
    "    def Sections(self, metadata):\n",
    "        return self.build_components(Section, metadata, column_name='Section')\n",
    "\n",
    "\n",
    "class Region(Asset):\n",
    "    #\n",
    "    # Similarly, each Region has a set of Facilities.\n",
    "    #\n",
    "    @Asset.Component()\n",
    "    def Facilities(self, metadata):\n",
    "        return self.build_components(Facility, metadata, column_name='Facility')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Now that we have defined our asset classes and the hierarchy, we can execute the `spy.assets.build` to create a DataFrame of metadata to be pushed into Seeq."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Successfully built 1 assets and 18 attributes.</div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">Build Path</td><td style=\"background-color: #EEFFEE; text-align: left;\">Build Asset</td><td style=\"background-color: #EEFFEE; text-align: left;\">Build Template</td><td style=\"background-color: #EEFFEE; text-align: left;\">Build Result</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: right; vertical-align: top;\">None</td><td style=\"text-align: left; vertical-align: top;\">North America</td><td style=\"text-align: left; vertical-align: top;\">Region</td><td style=\"text-align: left; vertical-align: top;\">Success</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Description</th>\n",
       "      <th>Type</th>\n",
       "      <th>Value Unit Of Measure</th>\n",
       "      <th>Datasource Name</th>\n",
       "      <th>Archived</th>\n",
       "      <th>Facility</th>\n",
       "      <th>Section</th>\n",
       "      <th>Referenced Name</th>\n",
       "      <th>Reference</th>\n",
       "      <th>Name</th>\n",
       "      <th>Asset</th>\n",
       "      <th>Asset Object</th>\n",
       "      <th>Path</th>\n",
       "      <th>Template</th>\n",
       "      <th>Build Result</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0EF58FC2-8C7F-6290-BEE8-1BE39219249E</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>kW</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>Facility 1</td>\n",
       "      <td>Section A</td>\n",
       "      <td>Area A_Compressor Power</td>\n",
       "      <td>True</td>\n",
       "      <td>Compressor Power</td>\n",
       "      <td>Section A</td>\n",
       "      <td>North America &gt;&gt; Facility 1 &gt;&gt; Section A</td>\n",
       "      <td>North America &gt;&gt; Facility 1</td>\n",
       "      <td>Section</td>\n",
       "      <td>Success</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0EF58FC2-83AA-66B0-8B9F-E021808A2620</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>%</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>Facility 1</td>\n",
       "      <td>Section A</td>\n",
       "      <td>Area A_Relative Humidity</td>\n",
       "      <td>True</td>\n",
       "      <td>Humidity</td>\n",
       "      <td>Section A</td>\n",
       "      <td>North America &gt;&gt; Facility 1 &gt;&gt; Section A</td>\n",
       "      <td>North America &gt;&gt; Facility 1</td>\n",
       "      <td>Section</td>\n",
       "      <td>Success</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0EF58FC2-8206-77F0-8519-ECD251B886A6</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>°F</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>Facility 1</td>\n",
       "      <td>Section A</td>\n",
       "      <td>Area A_Temperature</td>\n",
       "      <td>True</td>\n",
       "      <td>Temperature</td>\n",
       "      <td>Section A</td>\n",
       "      <td>North America &gt;&gt; Facility 1 &gt;&gt; Section A</td>\n",
       "      <td>North America &gt;&gt; Facility 1</td>\n",
       "      <td>Section</td>\n",
       "      <td>Success</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Asset</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>Section A</td>\n",
       "      <td>Section A</td>\n",
       "      <td>North America &gt;&gt; Facility 1 &gt;&gt; Section A</td>\n",
       "      <td>North America &gt;&gt; Facility 1</td>\n",
       "      <td>Section</td>\n",
       "      <td>Success</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0EF58FC2-85A1-7590-AA5F-C66CA82059F8</td>\n",
       "      <td>NaN</td>\n",
       "      <td>StoredSignal</td>\n",
       "      <td>kW</td>\n",
       "      <td>Example Data</td>\n",
       "      <td>False</td>\n",
       "      <td>Facility 1</td>\n",
       "      <td>Section B</td>\n",
       "      <td>Area B_Compressor Power</td>\n",
       "      <td>True</td>\n",
       "      <td>Compressor Power</td>\n",
       "      <td>Section B</td>\n",
       "      <td>North America &gt;&gt; Facility 1 &gt;&gt; Section B</td>\n",
       "      <td>North America &gt;&gt; Facility 1</td>\n",
       "      <td>Section</td>\n",
       "      <td>Success</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                     ID  Description          Type  \\\n",
       "0  0EF58FC2-8C7F-6290-BEE8-1BE39219249E          NaN  StoredSignal   \n",
       "1  0EF58FC2-83AA-66B0-8B9F-E021808A2620          NaN  StoredSignal   \n",
       "2  0EF58FC2-8206-77F0-8519-ECD251B886A6          NaN  StoredSignal   \n",
       "3                                   NaN          NaN         Asset   \n",
       "4  0EF58FC2-85A1-7590-AA5F-C66CA82059F8          NaN  StoredSignal   \n",
       "\n",
       "  Value Unit Of Measure Datasource Name Archived    Facility    Section  \\\n",
       "0                    kW    Example Data    False  Facility 1  Section A   \n",
       "1                     %    Example Data    False  Facility 1  Section A   \n",
       "2                    °F    Example Data    False  Facility 1  Section A   \n",
       "3                   NaN             NaN      NaN         NaN        NaN   \n",
       "4                    kW    Example Data    False  Facility 1  Section B   \n",
       "\n",
       "            Referenced Name Reference              Name      Asset  \\\n",
       "0   Area A_Compressor Power      True  Compressor Power  Section A   \n",
       "1  Area A_Relative Humidity      True          Humidity  Section A   \n",
       "2        Area A_Temperature      True       Temperature  Section A   \n",
       "3                       NaN       NaN         Section A  Section A   \n",
       "4   Area B_Compressor Power      True  Compressor Power  Section B   \n",
       "\n",
       "                               Asset Object                         Path  \\\n",
       "0  North America >> Facility 1 >> Section A  North America >> Facility 1   \n",
       "1  North America >> Facility 1 >> Section A  North America >> Facility 1   \n",
       "2  North America >> Facility 1 >> Section A  North America >> Facility 1   \n",
       "3  North America >> Facility 1 >> Section A  North America >> Facility 1   \n",
       "4  North America >> Facility 1 >> Section B  North America >> Facility 1   \n",
       "\n",
       "  Template Build Result  \n",
       "0  Section      Success  \n",
       "1  Section      Success  \n",
       "2  Section      Success  \n",
       "3  Section      Success  \n",
       "4  Section      Success  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "build_df = spy.assets.build(Region, metadata_df)\n",
    "build_df.head(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "We can push this into Seeq and see the resulting asset tree under the `North America` node on the Seeq Workbench _Data_ tab."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Pushed successfully to datasource <strong>Seeq Data Lab [Datasource ID: Seeq Data Lab]</strong> and scoped to workbook ID <strong>0EF5BE2E-E000-7550-9998-A9C5FFE8A636</strong><br>Click the following link to see what you pushed in Seeq:<br><a href=\"http://localhost:34216/0EF5BE2D-2738-FFA0-81E0-D2B058859C4D/workbook/0EF5BE2E-E000-7550-9998-A9C5FFE8A636/worksheet/0EF5BE2E-E050-EE60-924D-A0F34A0B6572\" target=\"_blank\">http://localhost:34216/0EF5BE2D-2738-FFA0-81E0-D2B058859C4D/workbook/0EF5BE2E-E000-7550-9998-A9C5FFE8A636/worksheet/0EF5BE2E-E050-EE60-924D-A0F34A0B6572</a></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "pushed_df = spy.push(metadata=build_df, workbook='SPy Documentation Examples >> Report and Dashboard Templates')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## Defining Displays\n",
    "\n",
    "We can also define the worksheets that will appear in our workbook instead of just letting SPy create a default worksheet. We do this using the Workbook Template concept, which is explored thoroughly in [Workbook Templates](Workbook%20Templates.ipynb). This documentation includes a saved-off set of templates for this tutorial, which we will load like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Success</div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "worksheet.parameters = {\n",
      "    \"8A4F0E26-8A0C-4127-9E11-B67E031C6049 [Signal] Example >> Cooling Tower 1 >> Area A >> Temperature\": None,\n",
      "    \"B9CDE282-7A1A-4E28-A173-12E7347AB891 [Signal] Example >> Cooling Tower 1 >> Area A >> Relative Humidity\": None,\n",
      "    \"4B40EAFC-91ED-4AB0-8199-F21AF40A8350 [Asset] Example >> Cooling Tower 1 >> Area A\": None,\n",
      "    \"E97BBE1D-F227-4AD7-ADAC-15B54FC50DB3 [Signal] Example >> Cooling Tower 1 >> Area A >> Compressor Power\": None\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "workbooks = spy.workbooks.load('./Support Files/Report and Dashboard Templates.zip',\n",
    "                               as_template_with_label=f'{spy.user.username} Report and Dashboard Templates Example 1')\n",
    "\n",
    "# Let's look at the template code for the Display we want\n",
    "print(workbooks['Analysis Template'].worksheets['Trend'].code)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "document.parameters = {\n",
      "    \"facility\": None,\n",
      "    \"sections\": [\n",
      "        {\n",
      "            \"section\": None,\n",
      "            \"BFA05D82-D900-44B0-95C8-4AE8B26F01BE [Embedded Content] Users >> mark-derbecker@seeq-com >> Report and Dashboard Templates >> Analysis Template >> Trend\": None\n",
      "        }\n",
      "    ]\n",
      "}\n"
     ]
    }
   ],
   "source": [
    "# And let's do the same for the Topic Document\n",
    "print(workbooks['Topic Template'].documents['Facility Template'].code)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "#\n",
    "# Note here that each of these new classes inherits from the classes defined above.\n",
    "# I.e.: Section_With_Displays inherits the attributes defined by the Section class,\n",
    "#       Facility_With_Displays overrides the Sections component from the base Facility class,\n",
    "#       Region_With_Displays overrides the Facilities component from the base Region class.\n",
    "#\n",
    "class Section_With_Displays(Section):\n",
    "    @Asset.Display()\n",
    "    def Ambient_Conditions(self, metadata, analysis):\n",
    "        # The \"analysis\" variable that is passed in is the Analysis Workbook template that we loaded\n",
    "        # and will pass in as part of the spy.assets.build(workbooks) argument. We can access any of\n",
    "        # its worksheets as templates.\n",
    "        #\n",
    "        # We will make a copy of the Trend worksheet template, passing in self.fqn (which stands\n",
    "        # for Fully Qualified Name) as the label for the template instance which will differentiate\n",
    "        # one asset's template instance from another.\n",
    "        worksheet = analysis.worksheets['Trend'].copy(self.fqn)\n",
    "\n",
    "        # Named the worksheet for the Facility and Section.\n",
    "        worksheet.name = self.parent.definition['Name'] + ', ' + self.definition['Name']\n",
    "\n",
    "        # Now we fill in the template's parameters using the boilerplate code that was printed earlier.\n",
    "        worksheet.parameters = {\n",
    "            \"4B40EAFC-91ED-4AB0-8199-F21AF40A8350 [Asset] Example >> Area A\": self,\n",
    "            \"8A4F0E26-8A0C-4127-9E11-B67E031C6049 [Signal] Example >> Cooling Tower 1 >> Area A >> Temperature\":\n",
    "                self.Temperature(),\n",
    "            \"B9CDE282-7A1A-4E28-A173-12E7347AB891 [Signal] Example >> Cooling Tower 1 >> Area A >> Relative Humidity\":\n",
    "                self.Humidity(),\n",
    "            \"E97BBE1D-F227-4AD7-ADAC-15B54FC50DB3 [Signal] Example >> Cooling Tower 1 >> Area A >> Compressor Power\":\n",
    "                self.Compressor_Power()\n",
    "        }\n",
    "\n",
    "        # We can return either a worksheet or a workstep from this function. You would return a\n",
    "        # worksheet if you want a separate worksheet for every asset. Return a workstep if you\n",
    "        # want to reuse the same worksheet for every asset.\n",
    "        return worksheet\n",
    "\n",
    "\n",
    "class Facility_With_Displays(Facility):\n",
    "    @Asset.Component()\n",
    "    def Sections(self, metadata):\n",
    "        # We have to override the base class here so that we call build_components with our new derived\n",
    "        # class, Section_With_Displays.\n",
    "        return self.build_components(Section_With_Displays, metadata, 'Section')\n",
    "\n",
    "\n",
    "class Region_With_Displays(Region):\n",
    "    @Asset.Component()\n",
    "    def Facilities(self, metadata):\n",
    "        return self.build_components(Facility_With_Displays, metadata, 'Facility')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Now we can build and push the results into Seeq. The `SPy Documentation Examples >> Report and Dashboard Templates` Analysis Workbook now has worksheets for each Facility / Section combination and with specifically-styled trend lines for each attribute."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Pushed successfully to datasource <strong>Seeq Data Lab [Datasource ID: Seeq Data Lab]</strong> and scoped to workbook ID <strong>0EF5BE2E-E000-7550-9998-A9C5FFE8A636</strong><br>Click the following link to see what you pushed in Seeq:<br><a href=\"http://localhost:34216/0EF5BE2D-2738-FFA0-81E0-D2B058859C4D/workbook/0EF5BE2E-E000-7550-9998-A9C5FFE8A636/worksheet/0EF5BE2E-E050-EE60-924D-A0F34A0B6572\" target=\"_blank\">http://localhost:34216/0EF5BE2D-2738-FFA0-81E0-D2B058859C4D/workbook/0EF5BE2E-E000-7550-9998-A9C5FFE8A636/worksheet/0EF5BE2E-E050-EE60-924D-A0F34A0B6572</a></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "build_df = spy.assets.build(Region_With_Displays, metadata_df, workbooks=workbooks, errors='raise')\n",
    "pushed_df = spy.push(metadata=build_df, workbook='SPy Documentation Examples >> Report and Dashboard Templates')"
   ]
  },
  {
   "attachments": {
    "ReportAndDashboardTemplates1.png": {
     "image/png": "[encoded data, 188688 characters]"
    }
   },
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "## Defining Organizer Topics\n",
    "\n",
    "Now we can augment our classes further to define Organizer Topic Documents that include the Displays that we defined above. We will create a Topic Document for each Facility, and we are going to use _mustache sections_ as described in [Workbook Templates](Workbook%20Templates.ipynb) to create repeating elements (for each Section).\n",
    "\n",
    "Here's what the Topic Document Template looked like when we authored it in Organizer:\n",
    "\n",
    "![ReportAndDashboardTemplates1.png](attachment:ReportAndDashboardTemplates1.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "#\n",
    "# Again, we use class inheritance here to build on what came before. Everything that was available\n",
    "# in the classes above is available here as well.\n",
    "#\n",
    "class Facility_With_Topics(Facility_With_Displays):\n",
    "    @Asset.Document()\n",
    "    def My_Facility(self, metadata, topic):\n",
    "        # Similar to our code above that defines an Analysis Worksheet, here we make a copy of\n",
    "        # Topic Document template and give it the name of the Facility.\n",
    "        document = topic.documents['Facility Template'].copy(self.fqn)\n",
    "\n",
    "        document.name = self['Name']\n",
    "\n",
    "        document.parameters = {\n",
    "            # Grab the last character, since \"Facility\" is already in the template\n",
    "            \"facility\": self['Name'][-1],\n",
    "\n",
    "            \"sections\": [\n",
    "                {\n",
    "                    # Grab the last character, since \"Section\" is already in the template\n",
    "                    \"section\": section['Name'][-1],\n",
    "\n",
    "                    \"BFA05D82-D900-44B0-95C8-4AE8B26F01BE [Embedded Content] Users >> mark-derbecker@seeq-com >> Report and Dashboard Templates >> Analysis Template >> Trend\":\n",
    "                        section.Ambient_Conditions()\n",
    "                }\n",
    "                # This is the typical way that you will iterate over all the child assets that are\n",
    "                # defined by a Component function. This \"list comprehension\" creates a dictionary\n",
    "                # (as defined directly above) for each asset in the \"for\" loop below.\n",
    "                for section in self.Sections().assets()\n",
    "            ]\n",
    "        }\n",
    "\n",
    "    @Asset.Component()\n",
    "    def Sections(self, metadata):\n",
    "        # Again we must override the base class to use the new Component classes.\n",
    "        return self.build_components(Section_With_Displays, metadata, 'Section')\n",
    "\n",
    "\n",
    "class Region_With_Topics(Region_With_Displays):\n",
    "    @Asset.Component()\n",
    "    def Facilities(self, metadata):\n",
    "        return self.build_components(Facility_With_Topics, metadata, 'Facility')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Again we can build the assets and push into Seeq. You will now see an Organizer Topic in the `SPy Documentation Examples` folder called `Report and Dashboard Templates`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div style=\"background-color: #EEFFEE;color:black; text-align: left;\">Push successful</div><table class=\"tex2jax_ignore\" style=\"color:black;\"><tr><td style=\"background-color: #EEFFEE;\"></td><td style=\"background-color: #EEFFEE; text-align: left;\">ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">Name</td><td style=\"background-color: #EEFFEE; text-align: left;\">Type</td><td style=\"background-color: #EEFFEE; text-align: left;\">Workbook Type</td><td style=\"background-color: #EEFFEE; text-align: left;\">Count</td><td style=\"background-color: #EEFFEE; text-align: left;\">Time</td><td style=\"background-color: #EEFFEE; text-align: left;\">Errors</td><td style=\"background-color: #EEFFEE; text-align: left;\">Result</td><td style=\"background-color: #EEFFEE; text-align: left;\">Pushed Workbook ID</td><td style=\"background-color: #EEFFEE; text-align: left;\">URL</td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">0EF5BE2E-E000-7550-9998-A9C5FFE8A636</td><td style=\"text-align: left; vertical-align: top;\">Report and Dashboard Templates</td><td style=\"text-align: left; vertical-align: top;\">Workbook</td><td style=\"text-align: left; vertical-align: top;\">Analysis</td><td style=\"text-align: right; vertical-align: top;\">28</td><td style=\"vertical-align: top;\">00:00:01.99</td><td style=\"text-align: right; vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">0EF5BE2E-E000-7550-9998-A9C5FFE8A636</td><td style=\"text-align: left; vertical-align: top;\"><a target=\"_blank\" href=\"http://localhost:34216/0EF5BE2D-2738-FFA0-81E0-D2B058859C4D/workbook/0EF5BE2E-E000-7550-9998-A9C5FFE8A636/worksheet/0EF5BE2E-F59A-71E0-9BFD-5C089160C99F\">link</a></td></tr><tr style=\"background-color: #EEFFEE;\"><td style=\"vertical-align: top;\">1</td><td style=\"text-align: left; vertical-align: top;\">14079DF9-319F-4181-AEC1-9A4D48EF310B agent_api_key Report and Dashboard Templates Example 1</td><td style=\"text-align: left; vertical-align: top;\">Report and Dashboard Templates</td><td style=\"text-align: left; vertical-align: top;\">Workbook</td><td style=\"text-align: left; vertical-align: top;\">Topic</td><td style=\"text-align: right; vertical-align: top;\">6</td><td style=\"vertical-align: top;\">00:00:01.25</td><td style=\"text-align: right; vertical-align: top;\">0</td><td style=\"text-align: left; vertical-align: top;\">Success</td><td style=\"text-align: left; vertical-align: top;\">0EF5BE2F-0CC6-FBC0-BFF8-F40C11C6275B</td><td style=\"text-align: left; vertical-align: top;\"><a target=\"_blank\" href=\"http://localhost:34216/0EF5BE2D-2738-FFA0-81E0-D2B058859C4D/workbook/0EF5BE2F-0CC6-FBC0-BFF8-F40C11C6275B/worksheet/0EF5BE2F-0DC9-E860-BBBD-667FF6099014\">link</a></td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "build_df = spy.assets.build(Region_With_Topics, metadata_df, workbooks=workbooks, errors='raise')\n",
    "pushed_df = spy.push(metadata=build_df, workbook='SPy Documentation Examples >> Report and Dashboard Templates')\n",
    "\n",
    "# Show the inner Push Workbooks status object's display instead of the metadata push status,\n",
    "# since it has links to the Topic.\n",
    "pushed_df.spy.status.inner['Push Workbooks'].display()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.11",
   "language": "python",
   "name": "python311"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
