---
# System prepended metadata

title: Site View
tags: [Control Tower]

---

# Overview
## Useful links
- Chart libraries
    - [**HighCharts**](https://www.highcharts.com)
        - Used on Production Unit and Drill Down
    - [**ApexCharts**](https://apexcharts.com)
        - Used on Stewardship, Effluent, Utilities, Steam Balance and Electricity Usage
- APIs
    - [**Financial Modeling Prep**](https://site.financialmodelingprep.com)
    - [**Azure Maps - Weather**](https://learn.microsoft.com/en-us/rest/api/maps/weather?view=rest-maps-2023-06-01)
    - [**Cognite Data Fusion - API**](https://api-docs.cognite.com/20230101/tag/Time-series)
- Data sources
    - Multiple timeseries
    - IncidentDOM Data Model
    - TurnaroundSOL Data Model
    - Static data

## Environments
| Environment | Data from | Cognite Project |
| ----------- | --------- | --------------- |
| dev         | dev       | celanese-dev    |
| qa          | prod      | celanese        |
| prod        | prod      | celanese        |

## Development Improvements Roadmap
- [x] ~~Update chart components to use HighCharts instead of Apex~~
- [ ] Update components to make their own requests when `refreshStarted` is updated
    - **Current status:** *partially done* (Stewardship, Flares, Steam Balance's Vents, Production Units and Drill Down)
        - Remaining will be covered in [User Story 52129: [UX] Site View - Implement Skeleton Loading](https://dev.azure.com/CelaneseCorporation/Digital%20Plant/_boards/board/t/14.%20Business%20Team/Stories/?workitem=52129)
    - Currently, most requests are made on DataProvider and the responses are shared accross components through DataContext. The app was initially developed this way to guarantee that all components would refresh at the same time, but it's no longer needed because the Context is now sharing a `refreshStarted` state which is updated every 2 minutes with the current timestamp value when new requests are made, and the components can listen to its change and refresh their own data simultaneously. The initial approach is not performatic because DataContext is used on the app level, even when the Site View Dashboard is not open (e.g.: Production Unit Drill Down is open), the dashboard request are still made. Also, when the request for a single timeseries breaks, all sections that get data from DataContext are affected.
- [ ] Improve refresh logic
    - **Current status:** *partially done* (Stewardship, Production Units and Drill Down)
    - For charts and tables that show historical data (e.g.: from past weeks, months or years), there's no need to refresh everything every 2-minutes. Ideally, the first request (when the page is loaded) gets all the data, and the refresh requests only retrieves the latest values.

## Troubleshooting
**01.** Production Unit is not showing up on the published environments, but appear when running locally.
- Re-run deployment pipeline.



# Site View

## Stewardship
#### Relevant User Stories
- [Stewardship - Update tables with FDM - 2023](https://dev.azure.com/CelaneseCorporation/Digital%20Plant/_workitems/edit/36763)
- [Stewardship - Review requests](https://dev.azure.com/CelaneseCorporation/Digital%20Plant/_workitems/edit/51500)

## DMW
#### Relevant User Stories
- [Demineralized Water (DMW)](https://dev.azure.com/CelaneseCorporation/Digital%20Plant/_workitems/edit/34797)

## Effluent
#### Relevant User Stories
- [Effluent](https://dev.azure.com/CelaneseCorporation/Digital%20Plant/_workitems/edit/34798)

## Flares
#### Relevant User Stories
- [Flares](https://dev.azure.com/CelaneseCorporation/Digital%20Plant/_workitems/edit/34799)
- [Flares and Vents - Timer restarts every time the page is updated](https://dev.azure.com/CelaneseCorporation/Digital%20Plant/_workitems/edit/48309/)

## Utilities
#### Relevant User Stories

## Steam Balance
#### Relevant User Stories
- [Flares and Vents - Timer restarts every time the page is updated](https://dev.azure.com/CelaneseCorporation/Digital%20Plant/_workitems/edit/48309/)

### Production Unit

## Production Unit Drill Down

# Shared Logics
### Stopwatch
- **Business logic:**
    - When a timeseries values are above a certain threshold for an hour, a stopwatch must be activated starting at the moment the timeseries completes 1 hour above its maximum value.
    - For the stopwatch to be deactivated, the timeseries values must stay below the threshold for 6 consecutive minutes.

**Endpoint:** `/api/common/stopwatch`
- **On page first load:**
  - When the page is loaded for the first time or refreshed, a request is made to Cognite to retrieve all the datapoints for the last 30 days for a certain timeseries;
  - Within this range, a search for the latest interval where the timeseries datapoint values were below the threshold for at least 6 minutes is made;
  - If there was an interval in the past one hour, then the page will not be loaded for the first time with an active stopwatch;
  - If the latest interval was over an hour ago and the datapoints have been above the threshold in the past hour, then the page will load with an active stopwatch counting from `the time the interval ended + one hour` until `now`
      - E.g.: 
          - If it's 6:00 now, and the latest interval in which the timeseries values were below the threshold was from 2:30 to 2:40, this means that the timeseries started being above the threshold at `2:40`
          - The stopwatch only activates after 1 hour, so it will be counting from `3:40` until `6:00` (now), so the page will load with the stopwatch counting 2h20m
* **On every 2 minute refresh**:
    * If there is an active stopwatch...
        * A 6-minute retroactive search is made to check if the timeseries values have been continuously below the threshold for the past 6 minutes;
        * If they have, then the stopwatch will be deactivated
    * If there is not an active stopwatch...
        * A 1-hour retroactive search is made to check if the timeseries values have been continuously above the threshold for the past hour;
        * If they have, then the stopwatch will be activated starting at the time it completes one hour above the threshold

### Time limit
If the latest datapoint of a certain timeseries was over 30 minutes ago, the KPI will show N/A instead of the value. This does not apply to charts.