diff --git a/.dockerignore b/.dockerignore index 1356e64a258262a6c1b684536e28f5d13ddf3988..f9619601908b43d5d90c9befea5aa6ef6a732fa9 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,11 +1,10 @@ -# temporal for refactor -/src.*/ -# development ignore -/config.yaml -/predictor_config.txt -/data/ -/data/models/ -/.vscode/ +.travis.yaml +.openapi-generator-ignore +README.md +tox.ini +git_push.sh +test-requirements.txt +setup.py # Byte-compiled / optimized / DLL files __pycache__/ @@ -17,6 +16,7 @@ __pycache__/ # Distribution / packaging .Python +env/ build/ develop-eggs/ dist/ @@ -28,12 +28,9 @@ lib64/ parts/ sdist/ var/ -wheels/ -share/python-wheels/ *.egg-info/ .installed.cfg *.egg -MANIFEST # PyInstaller # Usually these files are written by a python script from a template @@ -48,17 +45,15 @@ pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ -.nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml -*.cover -*.py,cover +*,cover .hypothesis/ -.pytest_cache/ -cover/ +venv/ +.python-version # Translations *.mo @@ -66,96 +61,12 @@ cover/ # Django stuff: *.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy # Sphinx documentation docs/_build/ # PyBuilder -.pybuilder/ target/ -# Jupyter Notebook +#Ipython Notebook .ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ \ No newline at end of file diff --git a/.env.gen b/.env.gen new file mode 100644 index 0000000000000000000000000000000000000000..e4d009524cffa3782d4e262d8e0d80b10b04afd8 --- /dev/null +++ b/.env.gen @@ -0,0 +1,106 @@ +# Reference documentation https://docs.docker.com/compose/environment-variables/ +# Focus default variables as production, to allow direct download and run in production +# Required external variables that must be defined externally are those that have no value + +#### Environments managed #### +# this is the default environment if needed uncomment and adjust +# some conventions on environment prefixes +# - development: purpouse is to cache build and start the setup locally using cache images exposing dev ports (i.e 3306, 5432, 8086, ...) for debug and development purposes. It is the default behaviour (local:run-build-cache) +# - release: purpouse is to generate images (that do not use BUILDKIT_INLINE_CACHE 1) tagged for the clients/pilots usage (release:run-build-release) +# - prod: purpose is to generate non building docker-compose that uses the release to deploy on generic client (prod:run-release) +# - test: the purpouse is to test from the cache images the correct behaviour without exposing ports (test:run-cache) +# types of building +# - run-build-cache: it focuses in the generation of images with BUILDKIT_INLINE_CACHE 1 for its usage in the cache-from for subsequent build, for each compose-file in compose-file build it finds build/cache the same name to add it to the build, it will use cache from. +# - run-build-release: it focuses in the generation of images for distribution it avoid using BUILDKIT_INLINE_CACHE 1 to reduce the size, it will use cache from. +# - build-cache: it focuses in the generation of images with BUILDKIT_INLINE_CACHE 1 for its usage in the cache-from for subsequent build, for each compose-file in compose-file build it finds build/cache the same name to add it to the build, it will use cache from. +# - build-release: it focuses in the generation of images for distribution it avoid using BUILDKIT_INLINE_CACHE 1 to reduce the size, it will not use cache from. +# - run-cache: it runs using cache images +# - run-release: it runs using release images +# default enviroment +# __ENVIRONMENTS=development:run-build-cache +# to add more enviroments use split with ";" +__ENVIRONMENTS=development:run-build-cache;prod:run-release;release:build-release + +#### Modules managed #### +# this will create individual docker composes that enables the individual usage of the modules through the docker-compose command and specific env files i.e. +# __MODULES=traefik;step-ca +# will enable the following docker-compose commands +# docker-compose --env-file .env/modules/traefik/prod ----project-directory . up -d +# __MODULES=traefik;step-ca +__MODULES=psl + +#### default environment #### +# __DEFAULT_ENVIRONMENT=.envs/global/prod + +#### default environment #### +# __DEFAULT_DEVELOPMENT_ENVIRONMENT=.envs/global/development + +#### default release environment #### +# __DEFAULT_RELEASE_ENVIRONMENT=.envs/global/release + +#### Common image related #### +DOCKER_REGISTRY_CACHE_PREFIX=cache.euve.digital.tecnalia.dev:5000 +DOCKER_REGISTRY_CACHE_VERSION=latest + +#### Common Build related #### +# DOCKER_BUILDKIT and COMPOSE_DOCKER_CLI_BUILD do not have effect here, we leave them as documentation +# DOCKER_BUILDKIT=1 +# COMPOSE_DOCKER_CLI_BUILD=1 + +### Common Traefik related ### +TRAEFIK_NETWORK_NAME=traefik_network +TRAEFIK_HTTPS_ENTRYPOINT_NAME=websecure +# TRAEFIK_HTTP_ENTRYPOINT_NAME=web + +#### Common Production related #### +ADMIN_USER=admin +ADMIN_PASSWORD=projectPassword +# to calculate password hash `openssl passwd -apr1 $ADMIN_PASSWORD` +# ADMIN_PASSWORD_HASH='$apr1$chTuJ7f9$.Ul8E16QYHtydKw.ehzZC.' +# to calculate password bcrypt hash `sudo apt-get update; sudo apt-get install -y apache2-utils; htpasswd -bnBC 12 "" $ADMIN_PASSWORD | tr -d ':\n'` +# ADMIN_PASSWORD_BCRYPT_HASH='$2y$12$NxJ.FkLgDZWWjc15y9bhX./GOTp67krCxWPanJLyCjofKyIN.zS96' +# HTTPS_PORT must be 443 if you use step-ca +HTTPS_PORT=443 +# server host is configured during the sync based on _ENV_LOCAL_ and _ENV_DEPLOY, _ENV_LOCAL_ will be used for test and release unless _ENV_RELEASE_ or _ENV_TEST_ specified +# SERVER_HOST=project.org +SERVER_HOST=ci.piacere.digital.tecnalia.dev + +#### Platform Specific #### +TZ=Madrid +INFLUXD_ORG=piacere + +#### Common docker-compose related #### +# https://docs.docker.com/compose/reference/envvars/#compose_file#compose_project_name +# these are docker-compose related environment variables +COMPOSE_PROJECT_NAME=psl +# _ENV_LOCAL_COMPOSE_FILE_BASE= # These are oriented for local vagrant usually it contains local traefik configuration, dev services, etc +# _ENV_RELEASE_COMPOSE_FILE_BASE= # These are oriented for tagging relevant images for upload to official release repositories +# _ENV_DEPLOY_COMPOSE_FILE_BASE= # These are oriented for final deployment it contains production traefik configuration, etc +# _ENV_TEST_COMPOSE_FILE_BASE= # These are oriented for testing +# COMPOSE_FILE_BASE= # (MANDATORY) These are those main services of the project, that will apply to all the scenarios + +COMPOSE_FILE_BASE= + +COMPOSE_FILE= +# COMPOSE_FILE Is generated automatically + +__psl__COMPOSE_FILE_BASE=docker-compose.yaml +__psl__COMPOSE_FILE_BASE_NETWORK=docker-compose-traefik-network-external.yaml + +__psl__PSL_BASE_PATH= + +__psl_development__SERVER_HOST=192.168.56.1.nip.io + +__psl__IMAGE_PSL=optima-piacere-docker-dev.artifact.tecnalia.com/wp6/psl:y3 +__psl__IMAGE_PSL_CACHE=optima-piacere-docker-dev.artifact.tecnalia.com/wp6/psl:y3 + +__psl_development__COMPOSE_FILE_BASE_DEV=docker-compose-dev.yaml + +__psl_release__COMPOSE_FILE_BASE_PIACERE_BUILD=piacere-build/docker-compose.yaml +__psl_release__COMPOSE_FILE_BASE_PIACERE_RELEASE=release/docker-compose.yaml +__psl_release__COMPOSE_FILE_BASE_ARTIFACTORY=docker-compose-artifactory.yaml +__psl_release__COMPOSE_FILE_BASE_TRAEFIK_NETWORK=docker-compose-traefik-network-internal.yaml + + + + diff --git a/.envs/global/development b/.envs/global/development new file mode 100644 index 0000000000000000000000000000000000000000..5bd7694dff5dac039353622464b5fe56f3f6b073 --- /dev/null +++ b/.envs/global/development @@ -0,0 +1,12 @@ +DOCKER_REGISTRY_CACHE_PREFIX=cache.euve.digital.tecnalia.dev:5000 +DOCKER_REGISTRY_CACHE_VERSION=latest +ADMIN_USER=admin +ADMIN_PASSWORD=projectPassword +HTTPS_PORT=443 +SERVER_HOST=192.168.56.1.nip.io +INFLUXD_ORG=piacere +COMPOSE_PROJECT_NAME=psl +PSL_BASE_PATH= +IMAGE_PSL=optima-piacere-docker-dev.artifact.tecnalia.com/wp6/psl:y3 +IMAGE_PSL_CACHE=optima-piacere-docker-dev.artifact.tecnalia.com/wp6/psl:y3 +COMPOSE_FILE=docker-compose.yaml:docker-compose-traefik-network-external.yaml:docker-compose-dev.yaml:build/docker-compose.yaml:build/inline-cache/docker-compose.yaml:build/image/docker-compose.yaml diff --git a/.envs/global/prod b/.envs/global/prod new file mode 100644 index 0000000000000000000000000000000000000000..8f2f40c36312a2971085ee7d7989e31abd9d833f --- /dev/null +++ b/.envs/global/prod @@ -0,0 +1,8 @@ +ADMIN_USER=admin +ADMIN_PASSWORD=projectPassword +HTTPS_PORT=443 +SERVER_HOST=ci.piacere.digital.tecnalia.dev +INFLUXD_ORG=piacere +COMPOSE_PROJECT_NAME=psl +IMAGE_PSL=optima-piacere-docker-dev.artifact.tecnalia.com/wp6/psl:y3 +COMPOSE_FILE=docker-compose.yaml:docker-compose-traefik-network-external.yaml:release/docker-compose.yaml diff --git a/.envs/global/release b/.envs/global/release new file mode 100644 index 0000000000000000000000000000000000000000..d4ed63eb97775c2ac0457f70e8dcf83e7617b9d0 --- /dev/null +++ b/.envs/global/release @@ -0,0 +1,11 @@ +TRAEFIK_NETWORK_NAME=traefik_network +ADMIN_USER=admin +ADMIN_PASSWORD=projectPassword +HTTPS_PORT=443 +SERVER_HOST=ci.piacere.digital.tecnalia.dev +INFLUXD_ORG=piacere +COMPOSE_PROJECT_NAME=psl +PSL_BASE_PATH= +IMAGE_PSL=optima-piacere-docker-dev.artifact.tecnalia.com/wp6/psl:y3 +IMAGE_PSL_CACHE=optima-piacere-docker-dev.artifact.tecnalia.com/wp6/psl:y3 +COMPOSE_FILE=docker-compose.yaml:docker-compose-traefik-network-external.yaml:piacere-build/docker-compose.yaml:release/docker-compose.yaml:docker-compose-artifactory.yaml:docker-compose-traefik-network-internal.yaml:build/docker-compose.yaml diff --git a/.envs/modules/psl/development b/.envs/modules/psl/development new file mode 100644 index 0000000000000000000000000000000000000000..5bd7694dff5dac039353622464b5fe56f3f6b073 --- /dev/null +++ b/.envs/modules/psl/development @@ -0,0 +1,12 @@ +DOCKER_REGISTRY_CACHE_PREFIX=cache.euve.digital.tecnalia.dev:5000 +DOCKER_REGISTRY_CACHE_VERSION=latest +ADMIN_USER=admin +ADMIN_PASSWORD=projectPassword +HTTPS_PORT=443 +SERVER_HOST=192.168.56.1.nip.io +INFLUXD_ORG=piacere +COMPOSE_PROJECT_NAME=psl +PSL_BASE_PATH= +IMAGE_PSL=optima-piacere-docker-dev.artifact.tecnalia.com/wp6/psl:y3 +IMAGE_PSL_CACHE=optima-piacere-docker-dev.artifact.tecnalia.com/wp6/psl:y3 +COMPOSE_FILE=docker-compose.yaml:docker-compose-traefik-network-external.yaml:docker-compose-dev.yaml:build/docker-compose.yaml:build/inline-cache/docker-compose.yaml:build/image/docker-compose.yaml diff --git a/.envs/modules/psl/prod b/.envs/modules/psl/prod new file mode 100644 index 0000000000000000000000000000000000000000..8f2f40c36312a2971085ee7d7989e31abd9d833f --- /dev/null +++ b/.envs/modules/psl/prod @@ -0,0 +1,8 @@ +ADMIN_USER=admin +ADMIN_PASSWORD=projectPassword +HTTPS_PORT=443 +SERVER_HOST=ci.piacere.digital.tecnalia.dev +INFLUXD_ORG=piacere +COMPOSE_PROJECT_NAME=psl +IMAGE_PSL=optima-piacere-docker-dev.artifact.tecnalia.com/wp6/psl:y3 +COMPOSE_FILE=docker-compose.yaml:docker-compose-traefik-network-external.yaml:release/docker-compose.yaml diff --git a/.envs/modules/psl/release b/.envs/modules/psl/release new file mode 100644 index 0000000000000000000000000000000000000000..d4ed63eb97775c2ac0457f70e8dcf83e7617b9d0 --- /dev/null +++ b/.envs/modules/psl/release @@ -0,0 +1,11 @@ +TRAEFIK_NETWORK_NAME=traefik_network +ADMIN_USER=admin +ADMIN_PASSWORD=projectPassword +HTTPS_PORT=443 +SERVER_HOST=ci.piacere.digital.tecnalia.dev +INFLUXD_ORG=piacere +COMPOSE_PROJECT_NAME=psl +PSL_BASE_PATH= +IMAGE_PSL=optima-piacere-docker-dev.artifact.tecnalia.com/wp6/psl:y3 +IMAGE_PSL_CACHE=optima-piacere-docker-dev.artifact.tecnalia.com/wp6/psl:y3 +COMPOSE_FILE=docker-compose.yaml:docker-compose-traefik-network-external.yaml:piacere-build/docker-compose.yaml:release/docker-compose.yaml:docker-compose-artifactory.yaml:docker-compose-traefik-network-internal.yaml:build/docker-compose.yaml diff --git a/.gitignore b/.gitignore index 19d53a930ddc202ab361ff2cfd822966c433551f..358b090616c391adc59e547c35920ff43a0fbe45 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ /data/models/ /.vscode/ /requirement-stable.txt +# open api ignore +/.openapi-generator/ # Byte-compiled / optimized / DLL files __pycache__/ @@ -18,7 +20,7 @@ __pycache__/ # Distribution / packaging .Python -build/ +# build/ develop-eggs/ dist/ downloads/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8ea2a21f23d2c25ec696d9fc23f2c71c7b89b4b8..87d08ff72b29b00bf03b5f3150ea1b6365af9544 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,19 +1,122 @@ -sonarqube-check: - image: - name: sonarsource/sonar-scanner-cli:latest - entrypoint: [""] - variables: - SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache - GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task - cache: - key: "${CI_JOB_NAME}" - paths: - - .sonar/cache - script: - - sonar-scanner - allow_failure: true - only: - - main # or the name of your main branch - tags: - - docker - +include: + - project: piacere/private/t23-ci-setup + ref: main + file: + - gitlab-ci-scripts/utils.gitlab-ci.yml + + # Image tag variables generation job ------------- + # Stage: variable-generation --------------------- + - gitlab-ci-scripts/generate-variables.gitlab-ci.yml + + # Downstream t23-ci-setup pipeline trigger job --- + # Stage: integration-tests-publish-deploy -------- + - gitlab-ci-scripts/trigger-downstream.gitlab-ci.yml + + +variables: + COMPONENT_WP: wp6 + PSL_IMAGE_NAME: psl + + IMAGE_NAMES: "$PSL_IMAGE_NAME" + +stages: + - variable-generation + # - quality + # - unit-tests TODO: Fix tests + - build + # - security + - integration-tests-publish-deploy + +# Quality jobs ---------------------- + +#sonarqube-check: +# TODO fails +# image: +# name: sonarsource/sonar-scanner-cli:latest +# entrypoint: [""] +# stage: quality +# variables: +# SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache +# GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task +# cache: +# key: "${CI_JOB_NAME}" +# paths: +# - .sonar/cache +# script: +# - sonar-scanner +# allow_failure: true +# tags: +# - docker + +# Build jobs ---------------------- + +.build-docker-compose: + # image: docker/compose:1.29.2 # this is too old + image: docker:23.0.1 + stage: build + services: + # - docker:20.10.21-dind # not sure if this is the latest + - docker:dind + variables: + GIT_DEPTH: 1 + GIT_SUBMODULE_STRATEGY: recursive + GIT_SUBMODULE_DEPTH: 1 + DOCKER_BUILDKIT: 1 + COMPOSE_DOCKER_CLI_BUILD: 1 + DOCKER_COMPOSE_PATH: "." + DOCKER_COMPOSE_ENV_FILE_CACHE: ".envs/global/release" + DOCKER_COMPOSE_ENV_FILE: ".envs/global/release" + before_script: + - !reference [.artifactory-login] + script: + - apk add docker-compose + - cd $DOCKER_COMPOSE_PATH + - docker-compose --env-file $DOCKER_COMPOSE_ENV_FILE_CACHE --project-directory ./ pull || true + - docker-compose --env-file $DOCKER_COMPOSE_ENV_FILE_CACHE --project-directory ./ config + - docker-compose --env-file $DOCKER_COMPOSE_ENV_FILE --project-directory ./ build + - docker-compose --env-file $DOCKER_COMPOSE_ENV_FILE --project-directory ./ push + - docker-compose --env-file $DOCKER_COMPOSE_ENV_FILE --project-directory ./ config | grep image + tags: + - docker + +build-temp-docker-compose: + extends: + - .build-docker-compose + variables: + IMAGE_PSL: "$TMP_IMAGE_PSL" + +build-release-docker-compose: + extends: + - .build-docker-compose + when: manual + +# Security job in tests stage------------------------ + +# security-trivy-psl: +# stage: security +# variables: +# TMP_IMAGE: "$TMP_IMAGE_PSL" +# trigger: !reference [.trigger-security-trivy] +# needs: +# - job: build-temp-docker-compose +# - job: generate-variables +# artifacts: true + +# Tests jobs ------------------------ + +# TODO: Tests are failing. There is a problem with imports + +# run-unit-tests: +# image: python:3.9 +# stage: unit-tests +# before_script: +# - pip install tox +# script: +# - tox +# tags: +# - docker + +# Deploy job ------------------------ + +# this is done in stage integration-tests-publish-deploy +# in jobs from t23-ci-setup diff --git a/.openapi-generator/FILES b/.openapi-generator/FILES deleted file mode 100644 index 53f3dac5cbd5a4d3f8d7bdac9f58c434b3a6336d..0000000000000000000000000000000000000000 --- a/.openapi-generator/FILES +++ /dev/null @@ -1,20 +0,0 @@ -.dockerignore -.travis.yml -README.md -git_push.sh -setup.py -src/psl/__init__.py -src/psl/__main__.py -src/psl/controllers/__init__.py -src/psl/controllers/security_controller_.py -src/psl/controllers/self_learning_controller.py -src/psl/encoder.py -src/psl/models/__init__.py -src/psl/models/base_model_.py -src/psl/models/error.py -src/psl/openapi/openapi.yaml -src/psl/test/__init__.py -src/psl/typing_utils.py -src/psl/util.py -test-requirements.txt -tox.ini diff --git a/.openapi-generator/VERSION b/.openapi-generator/VERSION deleted file mode 100644 index e230c8396d197bfcd0fdd0a0aab2f34c59498f83..0000000000000000000000000000000000000000 --- a/.openapi-generator/VERSION +++ /dev/null @@ -1 +0,0 @@ -5.3.0 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 9ddd7c13eb121337faa169e120cb72182e7588d2..0d9c69132ee91baf49ff73687ee61147147ad358 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.9-alpine3.12 +FROM python:3.9-slim-bullseye RUN mkdir -p /usr/src/app WORKDIR /usr/src/app @@ -6,14 +6,18 @@ WORKDIR /usr/src/app COPY requirements.txt /usr/src/app/ RUN \ - apk add --no-cache gcc libffi-dev musl-dev zlib-dev jpeg-dev g++ make cairo-dev openblas-dev lapack-dev qt5-qtbase-dev &&\ - ln -s /usr/lib/qt5/bin/qmake /usr/bin/qmake &&\ - CFLAGS="-g0 -Wl,--strip-all -I/usr/include:/usr/local/include -L/usr/lib:/usr/local/lib" pip3 install --no-cache-dir --compile --global-option=build_ext -r requirements.txt &&\ - apk del gcc libffi-dev musl-dev zlib-dev jpeg-dev g++ make cairo-dev openblas-dev lapack-dev qt5-qtbase-dev &&\ - rm -rf ~/.cache - -RUN \ - apk add --no-cache openblas libstdc++ libgomp libjpeg libxcb cairo qt5-qtbase +apt-get update -eany \ + && apt-get upgrade -y --no-install-recommends \ + && apt-get install -y --no-install-recommends \ + gcc \ + libcairo2-dev \ +&& pip3 install -r requirements.txt \ + && apt-get remove -y \ + gcc \ + libcairo2-dev \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf ~/.cache COPY /src/clients /usr/src/app/clients diff --git a/Dockerfile-alpine b/Dockerfile-alpine new file mode 100644 index 0000000000000000000000000000000000000000..ba6f7ef53237c87204fbb4733ee2b65520bf0164 --- /dev/null +++ b/Dockerfile-alpine @@ -0,0 +1,34 @@ +FROM python:3.9-alpine3.12 + +RUN mkdir -p /usr/src/app +WORKDIR /usr/src/app + +COPY requirements.txt /usr/src/app/ + +RUN \ + apk add --no-cache gcc libffi-dev musl-dev zlib-dev jpeg-dev g++ make cairo-dev openblas-dev lapack-dev qt5-qtbase-dev &&\ + ln -s /usr/lib/qt5/bin/qmake /usr/bin/qmake &&\ + CFLAGS="-g0 -Wl,--strip-all -I/usr/include:/usr/local/include -L/usr/lib:/usr/local/lib" pip3 install --no-cache-dir --compile --global-option=build_ext -r requirements.txt &&\ + apk del gcc libffi-dev musl-dev zlib-dev jpeg-dev g++ make cairo-dev openblas-dev lapack-dev qt5-qtbase-dev &&\ + rm -rf ~/.cache + +RUN \ + apk add --no-cache openblas libstdc++ libgomp libjpeg libxcb cairo qt5-qtbase + +COPY /src/clients /usr/src/app/clients + +RUN \ + pip3 install --no-cache-dir --compile --global-option=build_ext -e clients/sh_client + +COPY /src/psl /usr/src/app/psl + +EXPOSE 8080 + +ENV PSL__REPOSITORY__FILE=/data/deployments_data \ + PSL__PREDICTOR_ADAPTER__MODELS_PATH=/data/models + +VOLUME /data + +ENTRYPOINT ["python3"] + +CMD ["-m", "psl"] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..a043ebb460993cc3910eccc085b4eb218e16abde --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2022 Tecnalia + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md index 8ce3d9396bec23295535681540d25ede19449d58..8827180ff27c095539de86ef6d2e115308e1976c 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ Use your favourite IDE, or editing tool. This program requires a conection to influxdb and to self healing therefore you need to provide the conection details in config.yaml or using environment variables i.e. ``` -export PSL__INFLUXDB__CONNECTION__URL=http://pmc-influxdb:8086 +export PSL__INFLUXDB__CONNECTION__URL=http://pm-influxdb:8086 export PSL__SH_CLIENT_ADAPTER__URL=http://sh-gateway:8080/services/shbackend export PSL_INFLUXDB_ORG=piacere export PSL_INFLUXDB_USERNAME=piacere diff --git a/build/docker-compose.yaml b/build/docker-compose.yaml new file mode 100644 index 0000000000000000000000000000000000000000..cde914a50030715ff8f2763753380c6152c8fc12 --- /dev/null +++ b/build/docker-compose.yaml @@ -0,0 +1,7 @@ +services: + psl: + build: + context: ${PSL_BASE_PATH}. + dockerfile: Dockerfile + cache_from: + - ${IMAGE_PSL_CACHE:?err} diff --git a/build/image/docker-compose.yaml b/build/image/docker-compose.yaml new file mode 100644 index 0000000000000000000000000000000000000000..95d049426cddde907d2a8a976341e47086aab6ed --- /dev/null +++ b/build/image/docker-compose.yaml @@ -0,0 +1,3 @@ +services: + psl: + image: ${DOCKER_REGISTRY_CACHE_PREFIX}/piacere/psl:${DOCKER_REGISTRY_CACHE_VERSION:?err} diff --git a/build/inline-cache/docker-compose.yaml b/build/inline-cache/docker-compose.yaml new file mode 100644 index 0000000000000000000000000000000000000000..012f29118fbcf12ed8c4529373a669706ca1fc51 --- /dev/null +++ b/build/inline-cache/docker-compose.yaml @@ -0,0 +1,7 @@ +services: + psl: + build: + cache_from: + - ${DOCKER_REGISTRY_CACHE_PREFIX}/piacere/psl:${DOCKER_REGISTRY_CACHE_VERSION:?err} + args: + BUILDKIT_INLINE_CACHE: 1 # For multistage docker diff --git a/docker-compose-artifactory.yaml b/docker-compose-artifactory.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5f66061a67800081fa673be0810b31c96614f35e --- /dev/null +++ b/docker-compose-artifactory.yaml @@ -0,0 +1,5 @@ +services: + psl: + build: + labels: + com.jfrog.artifactory.retention.maxCount: 6 diff --git a/docker-compose-dev.yaml b/docker-compose-dev.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7f276a0b726f9d030bd6e023d9d1cfccd3fecd7c --- /dev/null +++ b/docker-compose-dev.yaml @@ -0,0 +1,4 @@ +services: + psl: + environment: + PSL__LOGGING__LEVEL: "DEBUG" diff --git a/docker-compose-traefik-aliases.yaml b/docker-compose-traefik-aliases.yaml new file mode 100644 index 0000000000000000000000000000000000000000..94df84cbd51063229c4c7f9e97500d1621c91d6e --- /dev/null +++ b/docker-compose-traefik-aliases.yaml @@ -0,0 +1,6 @@ +services: + traefik: + networks: + traefik_network: + aliases: + - psl.${SERVER_HOST} diff --git a/docker-compose-traefik-network-external.yaml b/docker-compose-traefik-network-external.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6149618e9408dec1168a12175ab70e38c67cc86c --- /dev/null +++ b/docker-compose-traefik-network-external.yaml @@ -0,0 +1,4 @@ +networks: + traefik_network: + name: traefik_network + external: true diff --git a/docker-compose-traefik-network-internal.yaml b/docker-compose-traefik-network-internal.yaml new file mode 100644 index 0000000000000000000000000000000000000000..0d7a2cf849a8488fdbe66d2cd423e4777a3e2bce --- /dev/null +++ b/docker-compose-traefik-network-internal.yaml @@ -0,0 +1,3 @@ +networks: + traefik_network: + name: ${TRAEFIK_NETWORK_NAME:?err} diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000000000000000000000000000000000000..04443cc90b4f1618a7f78844ede7d4bdc48ea74c --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,24 @@ +services: + psl: + restart: always + environment: + PSL__INFLUXDB__CONNECTION__URL: http://pm-influxdb:8086 # https://influxdb.pm.${SERVER_HOST:?err}:${HTTPS_PORT:?err} + PSL__SH_CLIENT_ADAPTER__URL: http://sh-gateway:8080/services/shbackend #https://sh.${SERVER_HOST:?err}:${HTTPS_PORT:?err}/services/shbackend + PSL__INFLUXDB__CONNECTION__ORG: "${INFLUXD_ORG:?err}" + PSL__INFLUXDB__CONNECTION__USERNAME: "${ADMIN_USER:?err}" + PSL__INFLUXDB__CONNECTION__PASSWORD: "${ADMIN_PASSWORD:?err}" + PSL__INFLUXDB__CONNECTION__TOKEN: "${ADMIN_PASSWORD:?err}" + PSL__INFLUXDB__CONNECTION__SSL: "True" + PSL__INFLUXDB__CONNECTION__VERIFY_SSL: "False" + networks: + traefik_network: + labels: + - "traefik.enable=true" + - "traefik.docker.network=traefik_network" + - "traefik.http.routers.psl.rule=Host(`psl.${SERVER_HOST:?err}`)" + - "traefik.http.routers.psl.entrypoints=websecure" + volumes: + - psl_data:/data + +volumes: + psl_data: diff --git a/influxdb/dashboards/all_input_metrics.json b/influxdb/dashboards/all_input_metrics.json new file mode 100644 index 0000000000000000000000000000000000000000..f55c9e587ca95bcb6312a5e2fc6714c047e7a31f --- /dev/null +++ b/influxdb/dashboards/all_input_metrics.json @@ -0,0 +1,343 @@ +{ + "meta": { + "version": "1", + "type": "dashboard", + "name": "all input metrics-Template", + "description": "template created from dashboard: all input metrics" + }, + "content": { + "data": { + "type": "dashboard", + "attributes": { + "name": "all input metrics", + "description": "" + }, + "relationships": { + "label": { + "data": [] + }, + "cell": { + "data": [ + { + "type": "cell", + "id": "090f20cffae99000" + }, + { + "type": "cell", + "id": "091bf8e4c5e99000" + } + ] + }, + "variable": { + "data": [ + { + "type": "variable", + "id": "091ad8610e70a000" + }, + { + "type": "variable", + "id": "091ad90b9730a000" + } + ] + } + } + }, + "included": [ + { + "id": "090f20cffae99000", + "type": "cell", + "attributes": { + "x": 0, + "y": 0, + "w": 12, + "h": 4 + }, + "relationships": { + "view": { + "data": { + "type": "view", + "id": "090f20cffae99000" + } + } + } + }, + { + "id": "091bf8e4c5e99000", + "type": "cell", + "attributes": { + "x": 0, + "y": 4, + "w": 12, + "h": 4 + }, + "relationships": { + "view": { + "data": { + "type": "view", + "id": "091bf8e4c5e99000" + } + } + } + }, + { + "type": "view", + "id": "090f20cffae99000", + "attributes": { + "name": "\"${v.variable}\"", + "properties": { + "shape": "chronograf-v2", + "queries": [ + { + "text": "import \"strings\"\r\nmeasurement = strings.split(v: v.variable, t: \"_\")[0]\r\nfield = strings.replace(v: v.variable, t: measurement + \"_\", u: \"\", i: 1)\r\nif measurement == \"cpu\" then\r\n from(bucket: \"bucket\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"deployment_id\"] == v.deployment_id )\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\r\n |> filter(fn: (r) => r[\"_field\"] == field )\r\n |> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\r\n |> map(fn: (r) => ({ r with\r\n _field: r._measurement + \"_\" + r._field\r\n }))\r\n |> keep(columns: [\"_time\", \"_field\",\"_value\"])\r\n |> aggregateWindow(every: 1m, fn: mean, createEmpty: false)\r\nelse if measurement == \"disk\" then\r\n from(bucket: \"bucket\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"deployment_id\"] == v.deployment_id )\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"disk\" )\r\n |> filter(fn: (r) => r[\"_field\"] == field )\r\n |> filter(fn: (r) => r[\"path\"] == \"/\")\r\n |> map(fn: (r) => ({ r with\r\n _field: r._measurement + \"_\" + r._field\r\n }))\r\n |> keep(columns: [\"_time\", \"_field\",\"_value\"])\r\n |> aggregateWindow(every: 1m, fn: mean, createEmpty: false)\r\nelse\r\n from(bucket: \"bucket\")\r\n |> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n |> filter(fn: (r) => r[\"deployment_id\"] == v.deployment_id )\r\n |> filter(fn: (r) => r[\"_measurement\"] == \"mem\")\r\n |> filter(fn: (r) => r[\"_field\"] == field )\r\n |> map(fn: (r) => ({ r with\r\n _field: r._measurement + \"_\" + r._field\r\n }))\r\n |> keep(columns: [\"_time\", \"_field\",\"_value\"])\r\n |> aggregateWindow(every: 1m, fn: mean, createEmpty: false)\r\n\r\n\r\n\r\n\r\n\r\n", + "editMode": "advanced", + "name": "", + "builderConfig": { + "buckets": [], + "tags": [ + { + "key": "_measurement", + "values": [], + "aggregateFunctionType": "filter" + } + ], + "functions": [ + { + "name": "mean" + } + ], + "aggregateWindow": { + "period": "auto", + "fillValues": false + } + } + } + ], + "axes": { + "x": { + "bounds": [ + "", + "" + ], + "label": "", + "prefix": "", + "suffix": "", + "base": "10", + "scale": "linear" + }, + "y": { + "bounds": [ + "", + "" + ], + "label": "", + "prefix": "", + "suffix": "", + "base": "10", + "scale": "linear" + } + }, + "type": "xy", + "legend": {}, + "geom": "line", + "colors": [ + { + "id": "08c3469f-33ae-404b-876f-d05ec0913e47", + "type": "scale", + "hex": "#31C0F6", + "name": "Nineteen Eighty Four", + "value": 0 + }, + { + "id": "5cbfcd6f-407a-41d7-9d3e-2eb1987bead3", + "type": "scale", + "hex": "#A500A5", + "name": "Nineteen Eighty Four", + "value": 0 + }, + { + "id": "c5dfaa8b-92ae-416b-aa46-71f4718e8c24", + "type": "scale", + "hex": "#FF7E27", + "name": "Nineteen Eighty Four", + "value": 0 + } + ], + "note": "", + "showNoteWhenEmpty": false, + "xColumn": "_time", + "generateXAxisTicks": null, + "xTotalTicks": 0, + "xTickStart": 0, + "xTickStep": 0, + "yColumn": "_value", + "generateYAxisTicks": null, + "yTotalTicks": 0, + "yTickStart": 0, + "yTickStep": 0, + "shadeBelow": false, + "position": "overlaid", + "timeFormat": "", + "hoverDimension": "", + "legendColorizeRows": false, + "legendOpacity": 0, + "legendOrientationThreshold": 0 + } + } + }, + { + "type": "view", + "id": "091bf8e4c5e99000", + "attributes": { + "name": "all metrics (Clone)", + "properties": { + "shape": "chronograf-v2", + "queries": [ + { + "text": "cpu = from(bucket: \"bucket\")\r\n|> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n|> filter(fn: (r) => r[\"deployment_id\"] == v.deployment_id )\r\n|> filter(fn: (r) => r[\"_measurement\"] == \"cpu\")\r\n|> filter(fn: (r) => r[\"_field\"] == \"usage_idle\" or r[\"_field\"] == \"usage_system\" or r[\"_field\"] == \"usage_user\" )\r\n|> filter(fn: (r) => r[\"cpu\"] == \"cpu-total\")\r\n|> map(fn: (r) => ({ r with\r\n _field: r._measurement + \"_\" + r._field\r\n}))\r\n|> keep(columns: [\"_time\", \"_field\",\"_value\"])\r\n|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)\r\n\r\ndisk = from(bucket: \"bucket\")\r\n|> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n|> filter(fn: (r) => r[\"deployment_id\"] == v.deployment_id )\r\n|> filter(fn: (r) => r[\"_measurement\"] == \"disk\" )\r\n|> filter(fn: (r) => r[\"_field\"] == \"used_percent\" or r[\"_field\"] == \"free\")\r\n|> filter(fn: (r) => r[\"path\"] == \"/\")\r\n|> map(fn: (r) => ({ r with\r\n _field: r._measurement + \"_\" + r._field\r\n}))\r\n|> keep(columns: [\"_time\", \"_field\",\"_value\"])\r\n|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)\r\n\r\nmem = from(bucket: \"bucket\")\r\n|> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n|> filter(fn: (r) => r[\"deployment_id\"] == v.deployment_id )\r\n|> filter(fn: (r) => r[\"_measurement\"] == \"mem\")\r\n|> filter(fn: (r) => r[\"_field\"] == \"used_percent\" or r[\"_field\"] == \"free\" )\r\n|> map(fn: (r) => ({ r with\r\n _field: r._measurement + \"_\" + r._field\r\n}))\r\n|> keep(columns: [\"_time\", \"_field\",\"_value\"])\r\n|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)\r\n\r\nunion(tables: [cpu, disk, mem])\r\n\r\n\r\n\r\n", + "editMode": "advanced", + "name": "", + "builderConfig": { + "buckets": [], + "tags": [ + { + "key": "_measurement", + "values": [], + "aggregateFunctionType": "filter" + } + ], + "functions": [ + { + "name": "mean" + } + ], + "aggregateWindow": { + "period": "auto", + "fillValues": false + } + } + } + ], + "axes": { + "x": { + "bounds": [ + "", + "" + ], + "label": "", + "prefix": "", + "suffix": "", + "base": "10", + "scale": "linear" + }, + "y": { + "bounds": [ + "", + "" + ], + "label": "", + "prefix": "", + "suffix": "", + "base": "10", + "scale": "linear" + } + }, + "type": "xy", + "legend": {}, + "geom": "line", + "colors": [ + { + "id": "08c3469f-33ae-404b-876f-d05ec0913e47", + "type": "scale", + "hex": "#31C0F6", + "name": "Nineteen Eighty Four", + "value": 0 + }, + { + "id": "5cbfcd6f-407a-41d7-9d3e-2eb1987bead3", + "type": "scale", + "hex": "#A500A5", + "name": "Nineteen Eighty Four", + "value": 0 + }, + { + "id": "c5dfaa8b-92ae-416b-aa46-71f4718e8c24", + "type": "scale", + "hex": "#FF7E27", + "name": "Nineteen Eighty Four", + "value": 0 + } + ], + "note": "", + "showNoteWhenEmpty": false, + "xColumn": "_time", + "generateXAxisTicks": null, + "xTotalTicks": 0, + "xTickStart": 0, + "xTickStep": 0, + "yColumn": "_value", + "generateYAxisTicks": null, + "yTotalTicks": 0, + "yTickStart": 0, + "yTickStep": 0, + "shadeBelow": false, + "position": "overlaid", + "timeFormat": "", + "hoverDimension": "", + "legendColorizeRows": false, + "legendOpacity": 0, + "legendOrientationThreshold": 0 + } + } + }, + { + "id": "091ad8610e70a000", + "type": "variable", + "attributes": { + "name": "deployment_id", + "arguments": { + "type": "query", + "values": { + "query": "import \"influxdata/influxdb/schema\"\r\n\r\nschema.tagValues(bucket: \"bucket\", tag: \"deployment_id\")\r\n", + "language": "flux" + } + }, + "selected": [] + }, + "relationships": { + "label": { + "data": [] + } + } + }, + { + "id": "091ad90b9730a000", + "type": "variable", + "attributes": { + "name": "variable", + "arguments": { + "type": "constant", + "values": [ + "cpu_usage_idle", + "cpu_usage_system", + "cpu_usage_user", + "disk_free", + "disk_used_percent", + "mem_free", + "mem_used_percent", + "availability" + ] + }, + "selected": [ + "cpu_usage_idle" + ] + }, + "relationships": { + "label": { + "data": [] + } + } + } + ] + }, + "labels": [] +} \ No newline at end of file diff --git a/influxdb/dashboards/psl_variable_analysis.json b/influxdb/dashboards/psl_variable_analysis.json new file mode 100644 index 0000000000000000000000000000000000000000..35e42853807d2ae4d68561bfe2f8a990323465fc --- /dev/null +++ b/influxdb/dashboards/psl_variable_analysis.json @@ -0,0 +1,470 @@ +{ + "meta": { + "version": "1", + "type": "dashboard", + "name": "psl variable analysis-Template", + "description": "template created from dashboard: psl variable analysis" + }, + "content": { + "data": { + "type": "dashboard", + "attributes": { + "name": "psl variable analysis", + "description": "" + }, + "relationships": { + "label": { + "data": [] + }, + "cell": { + "data": [ + { + "type": "cell", + "id": "091ad721f7e99000" + }, + { + "type": "cell", + "id": "091ad721fc699000" + }, + { + "type": "cell", + "id": "091ad721fda99000" + } + ] + }, + "variable": { + "data": [ + { + "type": "variable", + "id": "091ad8610e70a000" + }, + { + "type": "variable", + "id": "091ad90b9730a000" + } + ] + } + } + }, + "included": [ + { + "id": "091ad721f7e99000", + "type": "cell", + "attributes": { + "x": 0, + "y": 8, + "w": 12, + "h": 4 + }, + "relationships": { + "view": { + "data": { + "type": "view", + "id": "091ad721f7e99000" + } + } + } + }, + { + "id": "091ad721fc699000", + "type": "cell", + "attributes": { + "x": 0, + "y": 4, + "w": 12, + "h": 4 + }, + "relationships": { + "view": { + "data": { + "type": "view", + "id": "091ad721fc699000" + } + } + } + }, + { + "id": "091ad721fda99000", + "type": "cell", + "attributes": { + "x": 0, + "y": 0, + "w": 12, + "h": 4 + }, + "relationships": { + "view": { + "data": { + "type": "view", + "id": "091ad721fda99000" + } + } + } + }, + { + "type": "view", + "id": "091ad721f7e99000", + "attributes": { + "name": "anomaly and drift", + "properties": { + "shape": "chronograf-v2", + "queries": [ + { + "text": "from(bucket: \"bucket\")\r\n|> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n|> filter(fn: (r) => r[\"_measurement\"] == \"psl\")\r\n|> filter(fn: (r) => r[\"_field\"] == v.variable + \"_anomaly\" or r[\"_field\"] == v.variable + \"_drift\")\r\n|> filter(fn: (r) => r[\"deployment_id\"] == v.deployment_id)\r\n|> keep(columns: [\"_time\", \"_field\",\"_value\"])\r\n|> aggregateWindow(every: 1m, fn: last, createEmpty: false)\r\n|> map(fn: (r) => ({\r\n r with\r\n _value:\r\n if r._value then 1\r\n else 0\r\n}))\r\n", + "editMode": "advanced", + "name": "", + "builderConfig": { + "buckets": [], + "tags": [ + { + "key": "_measurement", + "values": [], + "aggregateFunctionType": "filter" + } + ], + "functions": [ + { + "name": "mean" + } + ], + "aggregateWindow": { + "period": "auto", + "fillValues": false + } + } + } + ], + "axes": { + "x": { + "bounds": [ + "", + "" + ], + "label": "", + "prefix": "", + "suffix": "", + "base": "10", + "scale": "linear" + }, + "y": { + "bounds": [ + "0", + "1" + ], + "label": "", + "prefix": "", + "suffix": "", + "base": "2", + "scale": "linear" + } + }, + "type": "xy", + "legend": {}, + "geom": "line", + "colors": [ + { + "id": "17673c24-77b4-4337-8775-b136210f59c7", + "type": "scale", + "hex": "#31C0F6", + "name": "Nineteen Eighty Four", + "value": 0 + }, + { + "id": "1cb8ce4b-a263-4ba7-9443-e39042afa498", + "type": "scale", + "hex": "#A500A5", + "name": "Nineteen Eighty Four", + "value": 0 + }, + { + "id": "09af4c3e-ac17-4acc-bbae-5f2d1286b681", + "type": "scale", + "hex": "#FF7E27", + "name": "Nineteen Eighty Four", + "value": 0 + } + ], + "note": "", + "showNoteWhenEmpty": false, + "xColumn": "_time", + "generateXAxisTicks": null, + "xTotalTicks": 0, + "xTickStart": 0, + "xTickStep": 0, + "yColumn": "_value", + "generateYAxisTicks": null, + "yTotalTicks": 0, + "yTickStart": 0, + "yTickStep": 0, + "shadeBelow": false, + "position": "overlaid", + "timeFormat": "", + "hoverDimension": "", + "legendColorizeRows": false, + "legendOpacity": 0, + "legendOrientationThreshold": 0 + } + } + }, + { + "type": "view", + "id": "091ad721fc699000", + "attributes": { + "name": "mae", + "properties": { + "shape": "chronograf-v2", + "queries": [ + { + "text": "from(bucket: \"bucket\")\n|> range(start: v.timeRangeStart, stop: v.timeRangeStop)\n|> filter(fn: (r) => r[\"_measurement\"] == \"psl\")\n|> filter(fn: (r) => r[\"_field\"] == v.variable + \"_mean_absolute_error\")\n|> filter(fn: (r) => r[\"deployment_id\"] == v.deployment_id)\n|> keep(columns: [\"_time\", \"_field\",\"_value\"])\n|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)\n", + "editMode": "advanced", + "name": "", + "builderConfig": { + "buckets": [], + "tags": [ + { + "key": "_measurement", + "values": [], + "aggregateFunctionType": "filter" + } + ], + "functions": [ + { + "name": "mean" + } + ], + "aggregateWindow": { + "period": "auto", + "fillValues": false + } + } + } + ], + "axes": { + "x": { + "bounds": [ + "", + "" + ], + "label": "", + "prefix": "", + "suffix": "", + "base": "10", + "scale": "linear" + }, + "y": { + "bounds": [ + "", + "" + ], + "label": "", + "prefix": "", + "suffix": "", + "base": "2", + "scale": "linear" + } + }, + "type": "xy", + "legend": {}, + "geom": "line", + "colors": [ + { + "id": "17673c24-77b4-4337-8775-b136210f59c7", + "type": "scale", + "hex": "#31C0F6", + "name": "Nineteen Eighty Four", + "value": 0 + }, + { + "id": "1cb8ce4b-a263-4ba7-9443-e39042afa498", + "type": "scale", + "hex": "#A500A5", + "name": "Nineteen Eighty Four", + "value": 0 + }, + { + "id": "09af4c3e-ac17-4acc-bbae-5f2d1286b681", + "type": "scale", + "hex": "#FF7E27", + "name": "Nineteen Eighty Four", + "value": 0 + } + ], + "note": "", + "showNoteWhenEmpty": false, + "xColumn": "_time", + "generateXAxisTicks": null, + "xTotalTicks": 0, + "xTickStart": 0, + "xTickStep": 0, + "yColumn": "_value", + "generateYAxisTicks": null, + "yTotalTicks": 0, + "yTickStart": 0, + "yTickStep": 0, + "shadeBelow": false, + "position": "overlaid", + "timeFormat": "", + "hoverDimension": "", + "legendColorizeRows": false, + "legendOpacity": 0, + "legendOrientationThreshold": 0 + } + } + }, + { + "type": "view", + "id": "091ad721fda99000", + "attributes": { + "name": "prediction vs exactly used input value", + "properties": { + "shape": "chronograf-v2", + "queries": [ + { + "text": "from(bucket: \"bucket\")\r\n|> range(start: v.timeRangeStart, stop: v.timeRangeStop)\r\n|> filter(fn: (r) => r[\"_measurement\"] == \"psl\")\r\n|> filter(fn: (r) => r[\"_field\"] == \"input_\" + v.variable or r[\"_field\"] == v.variable)\r\n|> filter(fn: (r) => r[\"deployment_id\"] == v.deployment_id)\r\n|> keep(columns: [\"_time\", \"_field\",\"_value\"])\r\n|> aggregateWindow(every: 1m, fn: mean, createEmpty: false)\r\n", + "editMode": "advanced", + "name": "", + "builderConfig": { + "buckets": [], + "tags": [ + { + "key": "_measurement", + "values": [], + "aggregateFunctionType": "filter" + } + ], + "functions": [ + { + "name": "mean" + } + ], + "aggregateWindow": { + "period": "auto", + "fillValues": false + } + } + } + ], + "axes": { + "x": { + "bounds": [ + "", + "" + ], + "label": "", + "prefix": "", + "suffix": "", + "base": "10", + "scale": "linear" + }, + "y": { + "bounds": [ + "", + "" + ], + "label": "", + "prefix": "", + "suffix": "", + "base": "10", + "scale": "linear" + } + }, + "type": "xy", + "legend": {}, + "geom": "line", + "colors": [ + { + "id": "08c3469f-33ae-404b-876f-d05ec0913e47", + "type": "scale", + "hex": "#31C0F6", + "name": "Nineteen Eighty Four", + "value": 0 + }, + { + "id": "5cbfcd6f-407a-41d7-9d3e-2eb1987bead3", + "type": "scale", + "hex": "#A500A5", + "name": "Nineteen Eighty Four", + "value": 0 + }, + { + "id": "c5dfaa8b-92ae-416b-aa46-71f4718e8c24", + "type": "scale", + "hex": "#FF7E27", + "name": "Nineteen Eighty Four", + "value": 0 + } + ], + "note": "", + "showNoteWhenEmpty": false, + "xColumn": "_time", + "generateXAxisTicks": null, + "xTotalTicks": 0, + "xTickStart": 0, + "xTickStep": 0, + "yColumn": "_value", + "generateYAxisTicks": null, + "yTotalTicks": 0, + "yTickStart": 0, + "yTickStep": 0, + "shadeBelow": false, + "position": "overlaid", + "timeFormat": "", + "hoverDimension": "", + "legendColorizeRows": false, + "legendOpacity": 0, + "legendOrientationThreshold": 0 + } + } + }, + { + "id": "091ad8610e70a000", + "type": "variable", + "attributes": { + "name": "deployment_id", + "arguments": { + "type": "query", + "values": { + "query": "import \"influxdata/influxdb/schema\"\r\n\r\nschema.tagValues(bucket: \"bucket\", tag: \"deployment_id\")\r\n", + "language": "flux" + } + }, + "selected": [] + }, + "relationships": { + "label": { + "data": [] + } + } + }, + { + "id": "091ad90b9730a000", + "type": "variable", + "attributes": { + "name": "variable", + "arguments": { + "type": "constant", + "values": [ + "cpu_usage_idle", + "cpu_usage_system", + "cpu_usage_user", + "disk_free", + "disk_used_percent", + "mem_free", + "mem_used_percent", + "availability" + ] + }, + "selected": [ + "cpu_usage_idle" + ] + }, + "relationships": { + "label": { + "data": [] + } + } + } + ] + }, + "labels": [] +} \ No newline at end of file diff --git a/influxdb/variables/deployment_id.json b/influxdb/variables/deployment_id.json new file mode 100644 index 0000000000000000000000000000000000000000..d8ded6ad9f670e037163bb2430247e0c17a3f5d6 --- /dev/null +++ b/influxdb/variables/deployment_id.json @@ -0,0 +1,35 @@ +{ + "meta": { + "version": "1", + "type": "variable", + "name": "deployment_id-Template", + "description": "template created from variable: deployment_id" + }, + "content": { + "data": { + "type": "variable", + "id": "091ad8610e70a000", + "attributes": { + "name": "deployment_id", + "arguments": { + "type": "query", + "values": { + "query": "import \"influxdata/influxdb/schema\"\r\n\r\nschema.tagValues(bucket: \"bucket\", tag: \"deployment_id\")\r\n", + "language": "flux" + } + }, + "selected": [] + }, + "relationships": { + "variable": { + "data": [] + }, + "label": { + "data": [] + } + } + }, + "included": [] + }, + "labels": [] +} \ No newline at end of file diff --git a/influxdb/variables/variable.json b/influxdb/variables/variable.json new file mode 100644 index 0000000000000000000000000000000000000000..56eaf7a32c783c44d3df41b519bf6ce51d54d947 --- /dev/null +++ b/influxdb/variables/variable.json @@ -0,0 +1,43 @@ +{ + "meta": { + "version": "1", + "type": "variable", + "name": "variable-Template", + "description": "template created from variable: variable" + }, + "content": { + "data": { + "type": "variable", + "id": "091ad90b9730a000", + "attributes": { + "name": "variable", + "arguments": { + "type": "constant", + "values": [ + "cpu_usage_idle", + "cpu_usage_system", + "cpu_usage_user", + "disk_free", + "disk_used_percent", + "mem_free", + "mem_used_percent", + "availability" + ] + }, + "selected": [ + "cpu_usage_idle" + ] + }, + "relationships": { + "variable": { + "data": [] + }, + "label": { + "data": [] + } + } + }, + "included": [] + }, + "labels": [] +} \ No newline at end of file diff --git a/openapi.yaml b/openapi.yaml index 16dbbdc8c6530d5637a432eb96a5eda2b7814bb0..f6c52d806047b2a1803e5a132b0584b7716aec8c 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -77,7 +77,6 @@ paths: summary: Adds a resource to be learn tags: - SelfLearning - x-openapi-router-controller: psl.controllers.self_learning_controller /deployments/{DeploymentID}: delete: description: Stops a deployment from being supervised with SelfLearning algorithms. @@ -132,7 +131,6 @@ paths: summary: Stops SelfLearning a Deployment tags: - SelfLearning - x-openapi-router-controller: psl.controllers.self_learning_controller components: parameters: DeploymentID: @@ -202,8 +200,13 @@ components: schemas: Deployment: description: Deployment - example: 123e4567-e89b-12d3-a456-426614174000 - type: string + example: + deployment_id: 123e4567-e89b-12d3-a456-426614174000 + properties: + deployment_id: + description: id of the deployment + type: string + type: object DeploymentID: example: 123e4567-e89b-12d3-a456-426614174000 description: Id of the deployment @@ -212,20 +215,15 @@ components: properties: timestamp: format: date-time - title: timestamp type: string message: description: User friendly message for the error. - title: message type: string class_name: description: Class of the underlying error. only visible in development environments - title: class_name type: string debug_message: description: Field with debug information, only visible in development environments - title: debug_message type: string - title: Error type: object diff --git a/piacere-build/docker-compose.yaml b/piacere-build/docker-compose.yaml new file mode 100644 index 0000000000000000000000000000000000000000..bd4f1e0c1c6f660d52a916b49e74f28dc9d66ad4 --- /dev/null +++ b/piacere-build/docker-compose.yaml @@ -0,0 +1,7 @@ +services: + psl: + build: + context: ${PSL_BASE_PATH}. + dockerfile: Dockerfile + args: + BUILDKIT_INLINE_CACHE: 1 # For multistage docker diff --git a/psl/test/test_self_learning_flow.py b/psl/test/test_self_learning_flow.py new file mode 100644 index 0000000000000000000000000000000000000000..cd49a881634a9db4b4675e9d00c0740638f1ade0 --- /dev/null +++ b/psl/test/test_self_learning_flow.py @@ -0,0 +1,9 @@ +from psl.flows import self_learning_flow +import urllib3 + +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + +while True: + valid_predictions, total_deployments, total_time = self_learning_flow.run() + if valid_predictions < total_deployments: + break diff --git a/release/docker-compose.yaml b/release/docker-compose.yaml new file mode 100644 index 0000000000000000000000000000000000000000..16948d0fecaf0ab56d0ffde15c692b8f7c8f0453 --- /dev/null +++ b/release/docker-compose.yaml @@ -0,0 +1,3 @@ +services: + psl: + image: ${IMAGE_PSL:?err} diff --git a/requirements.txt b/requirements.txt index 9f7fe39af29b8e3f3cb39e85b2b6f565b76b2e32..4881cc53da8468d720ec3101a65ea139dc9de5f1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,46 +1,55 @@ -itsdangerous==2.0.1 -connexion[swagger-ui] >= 2.6.0; python_version>="3.6" -# 2.3 is the last version that supports python 3.4-3.5 -connexion[swagger-ui] <= 2.3.0; python_version=="3.5" or python_version=="3.4" -# connexion requires werkzeug but connexion < 2.4.0 does not install werkzeug -# we must peg werkzeug versions below to fix connexion -# https://github.com/zalando/connexion/pull/1044 -werkzeug == 0.16.1; python_version=="3.5" or python_version=="3.4" -swagger-ui-bundle >= 0.0.2 -python_dateutil >= 2.6.0 -setuptools >= 21.0.0 -Flask == 1.1.2 - - -# Application specific -confuse==1.7.0 -# requires gcc apispec==5.1.1 apispec-webframeworks==0.5.2 arrow==1.1.1 -# requires additionally: libffi-dev, musl-dev +attrs==23.1.0 cairocffi==1.2.0 certifi==2021.10.8 +cffi==1.15.1 +charset-normalizer==3.1.0 +click==8.1.3 +clickclick==20.10.2 +confuse==1.7.0 +connexion==2.14.2 +cycler==0.11.0 +Flask==2.1.0 +idna==3.4 +importlib-metadata==6.6.0 +inflection==0.5.1 influxdb-client==1.21.0 iso8601==0.1.16 -# we try to fix scypi version as it creates problems -scipy==1.7.3 -# requires additionally: zlib-dev +itsdangerous==2.0.1 +Jinja2==3.1.2 +joblib==1.2.0 +jsonschema==4.17.3 +kiwisolver==1.4.4 +MarkupSafe==2.1.3 marshmallow==3.14.0 matplotlib==3.4.3 numpy==1.21.2 -# requires additionally: g++, make +packaging==23.1 pandas==1.3.3 -# requires additionally: cairo-dev +patsy==0.5.3 +Pillow==9.5.0 pycairo==1.20.1 -PyQt5==5.15.4 -# requires additionally: openblas-dev lapack-dev +pycparser==2.21 +PyJWT==2.3.0 +pyparsing==3.0.9 +pyrsistent==0.19.3 +python-dateutil==2.8.2 +pytz==2023.3 +PyYAML==6.0 +requests==2.31.0 river==0.9.0 +Rx==3.2.0 scikit-learn==1.0 +scipy==1.7.3 seaborn==0.11.2 six==1.16.0 statsmodels==0.13.2 +swagger-ui-bundle==0.0.9 +threadpoolctl==3.1.0 tqdm==4.62.3 urllib3==1.26.7 webargs==8.0.1 -pyjwt==2.3.0 \ No newline at end of file +Werkzeug==2.2.3 +zipp==3.15.0 \ No newline at end of file diff --git a/setup.py b/setup.py index 23787a26d4fe1bda8f04afd43a8f41d74ecab67c..3b72a3d7d33342246af9df7d087c71a6b1241f60 100644 --- a/setup.py +++ b/setup.py @@ -27,9 +27,9 @@ setup( url="", keywords=["OpenAPI", "PIACERE Performance SelfLearning"], install_requires=REQUIRES, - packages=find_packages("src\"), - package_dir={"": "src\"}, - package_data={'': ['src\/openapi/openapi.yaml']}, + packages=find_packages("src/"), + package_dir={"": "src/"}, + package_data={'': ['src/openapi/openapi.yaml']}, include_package_data=True, entry_points={ 'console_scripts': ['psl=psl.__main__:main']}, @@ -37,4 +37,3 @@ setup( No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) """ ) - diff --git a/src/psl/adapters/csv_to_metric_source.py b/src/psl/adapters/csv_to_metric_source.py index cf91fa30fc8f5c7668629e8aa023e439850909c9..ca8e86b7993b44ebd31cddb6af44f430967934e1 100644 --- a/src/psl/adapters/csv_to_metric_source.py +++ b/src/psl/adapters/csv_to_metric_source.py @@ -31,10 +31,11 @@ class CSVToMetricsSource(MetricSource): file_path, header=0, sep=";", skiprows=range(1, self.start_row), nrows=n ) # ',index_col='time' self.start_row += n + if data_frame.empty: + return data_frame data_frame[time_column_name] = pandas.to_datetime( data_frame[time_column_name] ).dt.tz_localize(None) - # this may be unecessary in next version data_frame.rename(columns={time_column_name: feat_name}, inplace=True) - data_frame = data_frame[[lab_name, feat_name]] + # we need to store the data in the influx for rendering purposes return data_frame diff --git a/src/psl/adapters/influxdb_to_influxdb.py b/src/psl/adapters/influxdb_to_influxdb.py index 660eb34d7d19085762d75c13046763dd6d0ac821..35577dcc9c73246697ec10bf5f48ec6e96b52010 100644 --- a/src/psl/adapters/influxdb_to_influxdb.py +++ b/src/psl/adapters/influxdb_to_influxdb.py @@ -9,7 +9,7 @@ import pandas influxdb_config = config["influxdb"] feat_name = influxdb_config["feat_name"].get() lab_name = influxdb_config["lab_name"].get() -focus_metric = influxdb_config["focus_metric"].get() +measurement_name = influxdb_config["measurement_name"].get() def get_conn_opts_from_influxdb_config(influxdb_config): @@ -24,46 +24,114 @@ conn_opts = get_conn_opts_from_influxdb_config(influxdb_config) bucket_name = influxdb_config["bucket_name"].get() -def save_prediction(prediction, prediction_datetime, deployment_id): +def save_prediction( + prediction, + lab_names, + prediction_datetime, + deployment_id, + doml_element_name, + doml_element_type, + host, + input_datetime + ): logging.debug( - "Saving predict {} for deployment {} into influxdb".format( - prediction, deployment_id + "Saving predict {} for deployment {}/{}/{}/{} into influxdb".format( + prediction, deployment_id, doml_element_name, doml_element_type, host ) ) with InfluxDBClient(**conn_opts) as client: - # try: point_settings = PointSettings() point_settings.add_default_tag("deployment_id", deployment_id) + point_settings.add_default_tag("doml_element_name", doml_element_name) + point_settings.add_default_tag("doml_element_type", doml_element_type) + point_settings.add_default_tag("host", host) write_api = client.write_api( write_options=SYNCHRONOUS, point_settings=point_settings ) - cpu_usage_idle = float(prediction[0]) - mean_absolute_error = float(prediction[1]) - anomaly = bool(prediction[2]) - drift = bool(prediction[3]) - # https://community.influxdata.com/t/storing-additional-timestamp-type-information-as-a-field/6082 - # influxdb no admite timestamps que ya me parecia raro - # .astype(int) / 10**9 + point = ( + Point(measurement_name) + .measurement(measurement_name) + .time(input_datetime) + ) + current_datetime = pandas.Timestamp.utcnow().replace(tzinfo=None) time_delta = prediction_datetime - current_datetime prediction_hours_in_advance = time_delta.total_seconds() / (60 * 60) - point = ( - Point("psl") - .measurement("psl") - .field("cpu_usage_idle", cpu_usage_idle) - .field("mean_absolute_error", mean_absolute_error) - .field("anomaly", anomaly) - .field("drift", drift) - .field("prediction_hours_in_advance", prediction_hours_in_advance) + + field_added = False + for index, lab_name in enumerate(lab_names): + try: + value = float(prediction[index][0]) + mean_absolute_error = float(prediction[index][1]) + anomaly = bool(prediction[index][2]) + drift = bool(prediction[index][3]) + (point + .field(lab_name, value) + .field("{}_mean_absolute_error".format(lab_name), mean_absolute_error) + .field("{}_anomaly".format(lab_name), anomaly) + .field("{}_drift".format(lab_name), drift) + .field("{}_prediction_hours_in_advance".format(lab_name), prediction_hours_in_advance)) + field_added = True + except Exception: + None + + if field_added: + try: + write_api.write(bucket=bucket_name, record=point) + except Exception: + logging.error( + "accesing influxdb for deployment_id: {}".format(deployment_id) + ) + return + + +def save_input(metrics, deployment_id, doml_element_name, doml_element_type, host, lab_names): + logging.debug( + "Saving input metrics for deployment {}/{}/{}/{} into influxdb".format( + deployment_id, doml_element_name, doml_element_type, host ) + ) + with InfluxDBClient(**conn_opts) as client: + point_settings = PointSettings() + point_settings.add_default_tag("deployment_id", deployment_id) + point_settings.add_default_tag("doml_element_name", doml_element_name) + point_settings.add_default_tag("doml_element_type", doml_element_type) + point_settings.add_default_tag("host", host) + + write_api = client.write_api( + write_options=SYNCHRONOUS, point_settings=point_settings + ) + + for index, row in metrics.iterrows(): + time = row[feat_name] + point = ( + Point(measurement_name) + .measurement(measurement_name) + .time(time) + ) - write_api.write(bucket=bucket_name, record=point) + field_added = False + for lab_name in lab_names: + value = None + try: + value = getattr(row, lab_name) + if pandas.isnull(value): + continue + float_value = float(value) + point.field("input_{}".format(lab_name), float_value) + field_added = True + except Exception: + None - # except Exception: - # logging.error( - # "accesing influxdb for deployment_id: {}".format(deployment_id) - # ) + if field_added: + try: + logging.debug("writing deployment_id {}/{}/{}/{} point: {}".format(deployment_id, doml_element_name, doml_element_type, host, point.to_line_protocol())) + write_api.write(bucket=bucket_name, record=point) + except Exception: + logging.error( + "accesing influxdb for deployment_id {}/{}/{}/{}".format(deployment_id, doml_element_name, doml_element_type, host) + ) return diff --git a/src/psl/adapters/influxdb_to_metric_source.py b/src/psl/adapters/influxdb_to_metric_source.py index cb9317b297f005dbafd58d067c7c3c5020a87324..fe41398ebf5d296aa3268def2c914a357aec3637 100644 --- a/src/psl/adapters/influxdb_to_metric_source.py +++ b/src/psl/adapters/influxdb_to_metric_source.py @@ -10,7 +10,6 @@ from operator import itemgetter influxdb_config = config["influxdb"] feat_name = influxdb_config["feat_name"].get() lab_name = influxdb_config["lab_name"].get() -focus_metric = influxdb_config["focus_metric"].get() def get_conn_opts_from_influxdb_config(influxdb_config): @@ -26,35 +25,76 @@ train_time_range_start = influxdb_config["train_time_range_start"].get() predict_time_range_start = influxdb_config["predict_time_range_start"].get() bucket_name = influxdb_config["bucket_name"].get() aggregate_sampling = influxdb_config["aggregate_sampling"].get() +telegraf_interval = influxdb_config["telegraf_interval"].get() QUERY_TEMPLATE = """ -from(bucket: "{bucket}") - |> range(start: {start}) +import "date" +import "system" + +bucket = "{bucket}" +start = {start} +deploymentId = "{deployment_id}" +telegrafInterval = {telegraf_interval} +discardLevel = int(v: duration(v: uint(v: telegrafInterval) + uint(v: 5s)))/1000000000 +aggregateSampling = {aggregate_sampling} +currentTime = system.time() +initialTime = date.sub(from: currentTime, d: duration(v: uint(v: -start) - uint(v: telegrafInterval) - uint(v: telegrafInterval))) + +deploymentData = from(bucket: bucket ) + |> range(start: start ) + |> filter(fn: (r) => r["deployment_id"] == deploymentId ) + +cpu = deploymentData |> filter(fn: (r) => r["_measurement"] == "cpu") - |> filter(fn: (r) => r["_field"] == "usage_idle" or r["_field"] == "usage_system" or r["_field"] == "usage_user") + |> filter(fn: (r) => r["_field"] == "usage_idle") |> filter(fn: (r) => r["cpu"] == "cpu-total") - |> filter(fn: (r) => r["deployment_id"] == "{deployment_id}") |> map(fn: (r) => ({{ r with - _field: r._measurement + "_" + r._field - }})) - |> keep(columns: ["_time", "_field","_value"]) - |> aggregateWindow(every: {aggregate_sampling}, fn: mean, createEmpty: false) - |> yield(name: "mean") -""" - + _field: r._measurement + "_" + "used_percent" + }})) + |> map(fn: (r) => ({{ r with + _value: 100.0 - float(v: r._value) + }})) + |> keep(columns: ["_time", "_field","_value","doml_element_name","doml_element_type","host"]) -# |> filter(fn: (r) => r["_field"] == "usage_idle") +disk = deploymentData + |> filter(fn: (r) => r["_measurement"] == "disk" ) + |> filter(fn: (r) => r["_field"] == "used_percent" ) + |> filter(fn: (r) => r["path"] == "/") + |> map(fn: (r) => ({{ r with + _field: r._measurement + "_" + r._field + }})) + |> keep(columns: ["_time", "_field","_value","doml_element_name","doml_element_type","host"]) -# |> filter(fn: (r) => r["_measurement"] == "cpu") -# |> filter(fn: (r) => r["_field"] == "usage_idle" or r["_field"] == "usage_system" or r["_field"] == "usage_user") -# |> filter(fn: (r) => r["cpu"] == "cpu-total") +mem = deploymentData + |> filter(fn: (r) => r["_measurement"] == "mem") + |> filter(fn: (r) => r["_field"] == "used_percent" ) + |> map(fn: (r) => ({{ r with + _field: r._measurement + "_" + r._field + }})) + |> keep(columns: ["_time", "_field","_value","doml_element_name","doml_element_type","host"]) -# |> filter(fn: (r) => r["_measurement"] == "disk") -# |> filter(fn: (r) => r["_field"] == "free" or r["_field"] == "used_percent") -# |> filter(fn: (r) => r["path"] == "/") +availability = deploymentData + |> filter(fn: (r) => r["_measurement"] == "system") + |> filter(fn: (r) => r["_field"] == "uptime") + |> elapsed() + |> map(fn: (r) => ({{ r with + _field: r._measurement + "_" + "availability_percent" + }})) + |> map(fn: (r) => ({{ r with + _value: if r.elapsed > discardLevel then 0 else 100 + }})) + |> aggregateWindow(every: telegrafInterval, fn: mean, createEmpty: true) // create empty to true create missing points of elements not submmiting metrics + |> range(start: initialTime) //we adjust initial time to remove some extra null added at the beginning + |> fill(column: "_value", value: 0.0) +// |> tail(n: 1000000,offset: 1) + |> keep(columns: ["_time", "_field","_value","doml_element_name","doml_element_type","host"]) -# |> filter(fn: (r) => r["_measurement"] == "mem") -# |> filter(fn: (r) => r["_field"] == "free" or r["_field"] == "used_percent") +union(tables: [cpu, disk, mem, availability]) + |> aggregateWindow(every: aggregateSampling, fn: mean, createEmpty: false) + |> group(columns: [ "_time","doml_element_name","doml_element_type","host","_field"]) + |> mean() + |> group(columns: ["doml_element_name","doml_element_type","host","_field"]) +""" def request_metrics_to_influxdb(time_range, deployment_id, number_of_records): logging.debug("requesting Influxdb for latest {} metrics".format(time_range)) @@ -63,46 +103,169 @@ def request_metrics_to_influxdb(time_range, deployment_id, number_of_records): "start": time_range, "deployment_id": str(deployment_id), "aggregate_sampling": aggregate_sampling, + "telegraf_interval": telegraf_interval, } query = QUERY_TEMPLATE.format(**query_data) with InfluxDBClient(**conn_opts) as client: try: query_api = client.query_api() data_frame = query_api.query_data_frame(query=query) - # the number of row multiply by each additional metric, we group by time + logging.debug("Influxdb query result: {}".format(data_frame)) + # we group by time and we get the last timestamp data_frame_grouped = data_frame.groupby("_time") - # we take the last number_of_records https://stackoverflow.com/a/52895848 + # drop the last timestamp as it does not contain availability data_frame = pandas.concat( deque(map(itemgetter(1), data_frame_grouped), maxlen=number_of_records) ) - data_frame_grouped = data_frame.groupby("_time") + # we group by time, doml_element_name, doml_element_type + data_frame_grouped = data_frame.groupby(["_time", "doml_element_name", "doml_element_type", "host"]) # we create a new dataframe data_frame = pandas.DataFrame( [ { + feat_name: pandas.to_datetime(time_doml_element_name[0], utc=True).replace(tzinfo=None), **dict(values[["_field", "_value"]].values), - feat_name: pandas.to_datetime(time).replace(tzinfo=None), + "doml_element_name": time_doml_element_name[1], + "doml_element_type": time_doml_element_name[2], + "host": time_doml_element_name[3], } - for time, values in data_frame_grouped + for time_doml_element_name, values in data_frame_grouped ] ) # predictor_utils.read_piacere_data establishes the index but the next step data_reparing dissable it # it also changes time to datetime but this is already done therefore I will skip it # predictor_utils.data_preparing changes _time to moment ... but why here and not when creating the pandas.DataFrame? + logging.debug("Output Data Frame: {}".format(data_frame)) + return data_frame + except Exception as error: + print(error) + logging.error( + "accesing influxdb for deployment_id: {}".format(deployment_id) + ) + return None + +QUERY_TEMPLATE_TRAINING = """ +import "date" +import "system" - # this may be unecessary in next version - data_frame.rename(columns={focus_metric: lab_name}, inplace=True) - data_frame = data_frame[[lab_name, feat_name]] +bucket = "{bucket}" +start = {start} +deploymentId = "{deployment_id}" +domlElementName = "{doml_element_name}" +domlElementType = "{doml_element_type}" +telegrafInterval = {telegraf_interval} +discardLevel = int(v: duration(v: uint(v: telegrafInterval) + uint(v: 5s)))/1000000000 +aggregateSampling = {aggregate_sampling} +currentTime = system.time() +initialTime = date.sub(from: currentTime, d: duration(v: uint(v: -start) - uint(v: telegrafInterval) - uint(v: telegrafInterval))) +deploymentData = from(bucket: bucket ) + |> range(start: start ) + |> filter(fn: (r) => r["deployment_id"] == deploymentId ) + |> filter(fn: (r) => r["doml_element_name"] == domlElementName ) + |> filter(fn: (r) => r["doml_element_type"] == domlElementType ) + +cpu = deploymentData + |> filter(fn: (r) => r["_measurement"] == "cpu") + |> filter(fn: (r) => r["_field"] == "usage_idle") + |> filter(fn: (r) => r["cpu"] == "cpu-total") + |> map(fn: (r) => ({{ r with + _field: r._measurement + "_" + "used_percent" + }})) + |> map(fn: (r) => ({{ r with + _value: 100.0 - float(v: r._value) + }})) + |> keep(columns: ["_time", "_field","_value"]) + +disk = deploymentData + |> filter(fn: (r) => r["_measurement"] == "disk" ) + |> filter(fn: (r) => r["_field"] == "used_percent" ) + |> filter(fn: (r) => r["path"] == "/") + |> map(fn: (r) => ({{ r with + _field: r._measurement + "_" + r._field + }})) + |> keep(columns: ["_time", "_field","_value"]) + +mem = deploymentData + |> filter(fn: (r) => r["_measurement"] == "mem") + |> filter(fn: (r) => r["_field"] == "used_percent" ) + |> map(fn: (r) => ({{ r with + _field: r._measurement + "_" + r._field + }})) + |> keep(columns: ["_time", "_field","_value"]) + +availability = deploymentData + |> filter(fn: (r) => r["_measurement"] == "system") + |> filter(fn: (r) => r["_field"] == "uptime") + |> elapsed() + |> map(fn: (r) => ({{ r with + _field: r._measurement + "_" + "availability_percent" + }})) + |> map(fn: (r) => ({{ r with + _value: if r.elapsed > discardLevel then 0 else 100 + }})) + |> aggregateWindow(every: telegrafInterval, fn: mean, createEmpty: true) // create empty to true create missing points of elements not submmiting metrics + |> range(start: initialTime) //we adjust initial time to remove some extra null added at the beginning + |> fill(column: "_value", value: 0.0) +// |> tail(n: 1000000,offset: 1) + |> keep(columns: ["_time", "_field","_value"]) + +union(tables: [cpu, disk, mem, availability]) + |> aggregateWindow(every: aggregateSampling, fn: mean, createEmpty: false) + |> group(columns: [ "_time", "_field"]) + |> mean() + |> group(columns: ["_field"]) + +""" + +def request_doml_element_name_metrics_to_influxdb(time_range, deployment_id, doml_element_name, doml_element_type, number_of_records): + logging.debug("requesting Influxdb for latest {} metrics for doml_element {}/{}/{}".format(time_range, deployment_id, doml_element_name, doml_element_type)) + query_data = { + "bucket": bucket_name, + "start": time_range, + "deployment_id": str(deployment_id), + "doml_element_name": str(doml_element_name), + "doml_element_type": str(doml_element_type), + "aggregate_sampling": aggregate_sampling, + "telegraf_interval": telegraf_interval, + } + query = QUERY_TEMPLATE_TRAINING.format(**query_data) + with InfluxDBClient(**conn_opts) as client: + try: + query_api = client.query_api() + data_frame = query_api.query_data_frame(query=query) + logging.debug("Influxdb query result: {}".format(data_frame)) + # we group by time and we get the last timestamp + data_frame_grouped = data_frame.groupby("_time") + # drop the last timestamp as it does not contain availability + data_frame = pandas.concat( + deque(map(itemgetter(1), data_frame_grouped), maxlen=number_of_records) + ) + # we group by time, host and doml_element_name + data_frame_grouped = data_frame.groupby("_time") + # we create a new dataframe + data_frame = pandas.DataFrame( + [ + { + feat_name: pandas.to_datetime(time, utc=True).replace(tzinfo=None), + **dict(values[["_field", "_value"]].values), + } + for time, values in data_frame_grouped + ] + ) + # predictor_utils.read_piacere_data establishes the index but the next step data_reparing dissable it + # it also changes time to datetime but this is already done therefore I will skip it + # predictor_utils.data_preparing changes _time to moment ... but why here and not when creating the pandas.DataFrame? + logging.debug("Output Data Frame: {}".format(data_frame)) return data_frame - except Exception: + except Exception as error: + print(error) logging.error( "accesing influxdb for deployment_id: {}".format(deployment_id) ) return None - class InfluxdbToMetricSource(MetricSource): def get_latest_metrics(self, deployment_id): logging.debug( @@ -115,12 +278,31 @@ class InfluxdbToMetricSource(MetricSource): ) return metrics - def get_latest_n_metrics(self, deployment_id, n): + def get_latest_n_metrics(self, deployment_id, doml_element_name, n): logging.debug( - "Accessing Influxdb for latest {} metrics of deployment: {}".format( - n, deployment_id + "Accessing Influxdb for latest {} metrics of deployment: {} {}".format( + n, deployment_id, doml_element_name ) ) metrics = request_metrics_to_influxdb(train_time_range_start, deployment_id, n) return metrics + + def get_latest_metrics_doml_element_name(self, deployment_id, doml_element_name, doml_element_type): + logging.debug( + "Accessing Influxdb for latest metrics of deployments: {}".format( + deployment_id + ) + ) + metrics = request_doml_element_name_metrics_to_influxdb(predict_time_range_start, deployment_id, doml_element_name, doml_element_type, 1) + return metrics + + def get_latest_n_metrics_doml_element_name(self, deployment_id, doml_element_name, doml_element_type, n): + logging.debug( + "Accessing Influxdb for latest {} metrics of deployment: {}/{}/{}".format( + n, deployment_id, doml_element_name, doml_element_type + ) + ) + + metrics = request_doml_element_name_metrics_to_influxdb(train_time_range_start, deployment_id, doml_element_name, doml_element_type, n) + return metrics diff --git a/src/psl/adapters/predictor_to_predictor.py b/src/psl/adapters/predictor_to_predictor.py index b07888af50873509444450918c94fea4926ef103..754ef8944b0b2133f24310a7198c1d7814a1dfa4 100644 --- a/src/psl/adapters/predictor_to_predictor.py +++ b/src/psl/adapters/predictor_to_predictor.py @@ -6,6 +6,7 @@ from psl.adapters.influxdb_to_metric_source import InfluxdbToMetricSource from psl.predictor.predictor import train from psl.predictor.predictor import predict from river import stream +import psl.adapters.influxdb_to_influxdb as influxdb predictor_adapter_config = config["predictor_adapter"] @@ -16,80 +17,98 @@ horizon = predictor_adapter_config["horizon"].get() feat_name = predictor_adapter_config["feat_name"].get() models_path = predictor_adapter_config["models_path"].get() monitored_vars = predictor_adapter_config["monitored_vars"].get() -cpu_usage_idle_monitored_var = monitored_vars[0] -lab_name = cpu_usage_idle_monitored_var["lab_name"] -window_anom_detect = cpu_usage_idle_monitored_var["window_anom_detect"] -delta = cpu_usage_idle_monitored_var["delta"] -anom_factor = cpu_usage_idle_monitored_var["anom_factor"] -threshold = cpu_usage_idle_monitored_var["threshold"] -monitored_var = cpu_usage_idle_monitored_var["monitored_var"] +lab_names = [monitored_var["lab_name"] for monitored_var in monitored_vars] +window_anom_detects = [monitored_var["window_anom_detect"] for monitored_var in monitored_vars] +deltas = [monitored_var["delta"] for monitored_var in monitored_vars] +anom_factors = [monitored_var["anom_factor"] for monitored_var in monitored_vars] +thresholds = [monitored_var["threshold"] for monitored_var in monitored_vars] +available_mods = [monitored_var["available"] for monitored_var in monitored_vars] +monitored_vars = [monitored_var["monitored_var"] for monitored_var in monitored_vars] -def train_deployment_id( + +def train_deployment_id_doml_element_name( deployment_id, + doml_element_name, + doml_element_type, metric_source=metric_source, path=models_path, force=False, latest_metrics=None, ): logging.debug("training model with: {}".format(type(metric_source).__name__)) - model_path = Path(path).joinpath(deployment_id) + model_path = Path(path).joinpath(deployment_id).joinpath(doml_element_name).joinpath(doml_element_type) if not force: - model_pkl_path = model_path.joinpath("model.pkl") + model_pkl_path = model_path.joinpath("cpuUP_model.pkl") if model_pkl_path.exists(): logging.debug("Training already present for: {}".format(deployment_id)) return if latest_metrics is None: - latest_metrics = metric_source.get_latest_n_metrics( - deployment_id, training_size + latest_metrics = metric_source.get_latest_n_metrics_doml_element_name( + deployment_id, doml_element_name, doml_element_type, training_size ) if latest_metrics is None: logging.error("No metrics for: {}".format(deployment_id)) return + model_path.mkdir(parents=True, exist_ok=True) + logging.debug("Training for: {}".format(latest_metrics)) training_done = train( latest_metrics, horizon, feat_name, - lab_name, + lab_names, model_path.as_posix() + "/", - window_anom_detect, - delta, + window_anom_detects, + deltas, + available_mods=available_mods, ) if training_done: logging.debug("Successfull training") else: - logging.error("Training was not completed for: {}".format(deployment_id)) + logging.error("Training was not completed for: {}/{}/{}".format(deployment_id, doml_element_name, doml_element_type)) def predict_deployment_id( - deployment_id, metric_source=metric_source, path=models_path, latest_metrics=None + deployment_id, + doml_element_name, + doml_element_type, + metric_source=metric_source, + path=models_path, + latest_metrics=None ): - model_path = Path(path).joinpath(deployment_id) - model_pkl_path = model_path.joinpath("model.pkl") + model_path = Path(path).joinpath(deployment_id).joinpath(doml_element_name).joinpath(doml_element_type) + model_pkl_path = model_path.joinpath("cpuUP_model.pkl") if not model_pkl_path.exists(): logging.error("No model present for {}".format(deployment_id)) return if latest_metrics is None: - latest_metrics = metric_source.get_latest_metrics(deployment_id) + latest_metrics = metric_source.get_latest_metrics_doml_element_name(deployment_id, doml_element_name, doml_element_type) if latest_metrics is None: - logging.error("No metrics for: {}".format(deployment_id)) + logging.error("latest_metrics is None for: {}".format(deployment_id)) + return + if latest_metrics.empty: + logging.error("latest_metrics is empty for: {}".format(deployment_id)) return + logging.debug("predicting for: {}".format(latest_metrics)) test_X = latest_metrics[[feat_name]] - test_Y = latest_metrics[[lab_name]] + test_Y = latest_metrics.loc[:, latest_metrics.columns != feat_name] for x, y in stream.iter_pandas(test_X, test_Y): predict_result = predict( x_data_instance=x, y_data_instance=y, horizon=horizon, feat_name=feat_name, - lab_name=lab_name, + lab_names=lab_names, path_models=model_path.as_posix() + "/", - window_anom_detect=window_anom_detect, - anom_factor=anom_factor, + window_anom_detects=window_anom_detects, + anom_factors=anom_factors, plott=False, - threshold=threshold, - monitored_var=monitored_var + thres_holds=thresholds, + monitored_variables=monitored_vars, + available_mods=available_mods, ) - logging.debug("prediction for: {} is {}".format(deployment_id,predict_result)) + logging.debug("appending: {}".format(latest_metrics[feat_name].iloc[0])) + predict_result.append(str(latest_metrics[feat_name].iloc[0])) + logging.debug("prediction for: {}/{}/{} is\n{}".format(deployment_id,doml_element_name,doml_element_type, predict_result)) return predict_result diff --git a/src/psl/adapters/sh_client_to_sh_client.py b/src/psl/adapters/sh_client_to_sh_client.py index dcb17161275c4a692abbe3bd0ddd02962427c377..31153cbb6d4b1a8a2cecb4e446c764ebd50affe7 100644 --- a/src/psl/adapters/sh_client_to_sh_client.py +++ b/src/psl/adapters/sh_client_to_sh_client.py @@ -17,7 +17,7 @@ sh_client_url = predictor_adapter_config["url"].get() sh_client_base64_secret = predictor_adapter_config["base64_secret"].get() sh_client_secret = base64.b64decode(sh_client_base64_secret) sh_client_verify_ssl = predictor_adapter_config["verify_ssl"].get() - +sh_client_enabled = predictor_adapter_config["enabled"].get() # https://auth0.com/blog/how-to-handle-jwt-in-python/ def getBearerToken(sh_client_secret): @@ -26,7 +26,6 @@ def getBearerToken(sh_client_secret): sh_client_bearer_token = getBearerToken(sh_client_secret) -print(sh_client_bearer_token) # Defining the host is optional and defaults to /services/shbackend # See configuration.py for a list of all supported configuration parameters. @@ -41,6 +40,8 @@ configuration.debug = True def notify_threshold_event(deployment_id): + if not sh_client_enabled: + return # Enter a context with an instance of the API client # ,"Authorization", configuration.get_api_key_with_prefix("Authorization") with sh_client.ApiClient(configuration, "Authorization", configuration.get_api_key_with_prefix("Authorization")) as api_client: diff --git a/src/psl/adapters/tmp.py b/src/psl/adapters/tmp.py deleted file mode 100644 index 52d4dc803a531f4a6cb1db8c2bbe9e7c64a3deb1..0000000000000000000000000000000000000000 --- a/src/psl/adapters/tmp.py +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - - -influxdb_config = config["influxdb"] -feat_name = influxdb_config["feat_name"].get() -lab_name = influxdb_config["lab_name"].get() -focus_metric = influxdb_config["focus_metric"].get() - - -def get_conn_opts_from_influxdb_config(influxdb_config): - # we configure the nested separator to one _, this may produce erros but I doubt that it will happen in this code - subview = influxdb_config["connection"] - # print('subview value retrival example: subview[\'password\']: ' + str(subview['password'].get())) - subviewItemsDict = {key: value.get() for key, value in subview.items()} - return subviewItemsDict - - -def save_prediction(prediction, deployment_id): - logging.debug("Saving predict {} for deployment {} into influxdb".format(prediction, deployment_id)) - print('save into influxdb') - query_data = { - "bucket": bucket_name, - "start": time_range, - "deployment_id": str(deployment_id), - "aggregate_sampling": aggregate_sampling, - } - query = QUERY_TEMPLATE.format(**query_data) - with InfluxDBClient(**conn_opts) as client: - try: - query_api = client.query_api() - data_frame = query_api.query_data_frame(query=query) - # the number of row multiply by each additional metric, we group by time - data_frame_grouped = data_frame.groupby("_time") - # we take the last number_of_records https://stackoverflow.com/a/52895848 - data_frame = pandas.concat( - deque(map(itemgetter(1), data_frame_grouped), maxlen=number_of_records) - ) - data_frame_grouped = data_frame.groupby("_time") - # we create a new dataframe - data_frame = pandas.DataFrame( - [ - { - **dict(values[["_field", "_value"]].values), - feat_name: pandas.to_datetime(time).replace(tzinfo=None), - } - for time, values in data_frame_grouped - ] - ) - # predictor_utils.read_piacere_data establishes the index but the next step data_reparing dissable it - # it also changes time to datetime but this is already done therefore I will skip it - # predictor_utils.data_preparing changes _time to moment ... but why here and not when creating the pandas.DataFrame? - - # this may be unecessary in next version - data_frame.rename(columns={focus_metric: lab_name}, inplace=True) - data_frame = data_frame[[lab_name, feat_name]] - - return data_frame - except Exception: - logging.error( - "accesing influxdb for deployment_id: {}".format(deployment_id) - ) - - return None - - -self.client = InfluxDBClient.from_config_file("config.ini") -[influx2] -url=http://localhost:8086 -org=my-org -token=my-token -timeout=6000 - -[tags] -id = 132-987-655 -customer = California Miner -data_center = ${env.data_center} - - -from influxdb_client import InfluxDBClient, Point -from influxdb_client .client.write_api import SYNCHRONOUS - -client = InfluxDBClient(url="http://localhost:8086", token="my-token", org="my-org") -write_api = client.write_api(write_options=SYNCHRONOUS) - -_point1 = Point("my_measurement").tag("location", "Prague").field("temperature", 25.3) -_point2 = Point("my_measurement").tag("location", "New York").field("temperature", 24.3) - -write_api.write(bucket="my-bucket", record=[_point1, _point2]) - -client.close() \ No newline at end of file diff --git a/src/psl/config.yaml b/src/psl/config.yaml index f2d1d172b5b2fabf34c78853f2760389a01d9edc..ea936b031b6b27a938a6f510ca2712afbcf98419 100644 --- a/src/psl/config.yaml +++ b/src/psl/config.yaml @@ -1,7 +1,8 @@ sh_client_adapter: - url: http://sh-backend:8081 # InfluxdbToMetricSource or CSVToMetricsSource + url: http://sh-backend:8081 base64_secret: MjFhOTY5YjFiYjZjZGM0YTlhZjM1OGYwZmU2MjE1ZTJiNTNmM2Q0OTdiMDhmNDQzNjRjZWQyZDM0YmI0YjkwMGI4ZDc0ZGE0MGM3Yzg0M2U2Y2Q0ZDE4MDcwNzc4ODQyMjczOWYyODNlY2RmOTQzNGQzOTc3NDc0MDdkNjlkN2I= verify_ssl: False + enabled: False predictor_adapter: metric_source_class_name: InfluxdbToMetricSource # InfluxdbToMetricSource or CSVToMetricsSource training_size: 200 @@ -9,102 +10,56 @@ predictor_adapter: feat_name: moment models_path: data/models monitored_vars: - - monitored_var: cpu_usage_idle - lab_name: _value - threshold: 70 - window_anom_detect: 50 - anom_factor: 4.0 - delta: 0.1 #Drifts - filters: - - _measurement: cpu - - _field: usage_idle - - cpu: cpu-total - - monitored_var: cpu_usage_system - lab_name: cpu_usage_system - threshold: 70.0 - window_anom_detect: 50 - anom_factor: 4.0 - delta: 0.1 #Drifts - filters: - - _measurement: cpu - - _field: usage_system - - cpu: cpu-total - - monitored_var: cpu_usage_user - lab_name: cpu_usage_user + - monitored_var: cpu_used_percent + available: true + lab_name: cpu_used_percent threshold: 70.0 window_anom_detect: 50 anom_factor: 4.0 delta: 0.1 #Drifts - filters: - - _measurement: cpu - - _field: usage_user - - cpu: cpu-total - - monitored_var: disk_free - lab_name: disk_free - threshold: 70.0 - window_anom_detect: 50 - anom_factor: 4.0 - delta: 0.1 #Drifts - filters: - - _measurement: disk - - _field: free - - path: / - monitored_var: disk_used_percent + available: true lab_name: disk_used_percent threshold: 70.0 window_anom_detect: 50 anom_factor: 4.0 delta: 0.1 #Drifts - filters: - - _measurement: disk - - _field: used_percent - - path: / - - monitored_var: mem_free - lab_name: mem_free - threshold: 70.0 - window_anom_detect: 50 - anom_factor: 4.0 - delta: 0.1 #Drifts - filters: - - _measurement: mem - - _field: free - monitored_var: mem_used_percent + available: true lab_name: mem_used_percent threshold: 70.0 window_anom_detect: 50 anom_factor: 4.0 delta: 0.1 #Drifts - filters: - - _measurement: mem - - _field: used_percent - - monitored_var: availability - lab_name: availability + - monitored_var: system_availability_percent + available: true + lab_name: system_availability_percent threshold: 70.0 window_anom_detect: 50 anom_factor: 4.0 delta: 0.1 #Drifts - filters: [] cvs: - file_path: test_input_data/usage_idle_data.csv + file_path: test_input_data/psl_data.csv time_column_name: _time feat_name: moment lab_name: _value influxdb: connection: - url: http://pmc-influxdb:8086 + url: http://pm-influxdb:8086 org: piacere username: piacere password: piacerePassword token: piacerePassword ssl: False verify_ssl: False - train_time_range_start: -40m - predict_time_range_start: -20s + train_time_range_start: -250m # 200 x aggregate_sampling + predict_time_range_start: -30m bucket_name: bucket - aggregate_sampling: 10s + aggregate_sampling: 60s feat_name: moment lab_name: _value - focus_metric: cpu_usage_idle + measurement_name: psl + telegraf_interval: 10s repository: file: data/deployments_data # relative to execution point runner: diff --git a/src/psl/controllers/self_learning_controller.py b/src/psl/controllers/self_learning_controller.py index 94595a4aa4fb2bc0e8df1ce13985470094cabe1b..36c4a442409151ffeb59b60af1b2dfcbf972c842 100644 --- a/src/psl/controllers/self_learning_controller.py +++ b/src/psl/controllers/self_learning_controller.py @@ -1,6 +1,7 @@ import connexion import six +from psl.models.deployment import Deployment # noqa: E501 from psl.models.error import Error # noqa: E501 from psl import util import psl.services.self_learning_service @@ -21,14 +22,16 @@ def deployments_deployment_iddelete(deployment_id): # noqa: E501 ) -def deployments_post(body): # noqa: E501 +def deployments_post(): # noqa: E501 """Adds a resource to be learn Adds a deployment to be supervised with SelfLearning algorithms. It requires and the identifier of the resource. The same resource identifier used by the performance self learning. The result of the addition will be an acknowledge with the indentifier of the added resource. # noqa: E501 - :param body: - :type body: str + :param deployment: + :type deployment: dict | bytes :rtype: str """ - return psl.services.self_learning_service.deployments_post(body) + if connexion.request.is_json: + deployment = Deployment.from_dict(connexion.request.get_json()) # noqa: E501 + return psl.services.self_learning_service.deployments_post(deployment) diff --git a/src/psl/flows/self_learning_flow.py b/src/psl/flows/self_learning_flow.py index 9b094e4ca3dc5fecfed6f591431b99c8991fc935..d7de47314bf601a7a6852e4e738a6375a37a7407 100644 --- a/src/psl/flows/self_learning_flow.py +++ b/src/psl/flows/self_learning_flow.py @@ -7,10 +7,18 @@ import psl.adapters.influxdb_to_influxdb as influxdb import pandas from psl.config import config import psl.adapters.sh_client_to_sh_client as sh_client - +import time +from psl.adapters.csv_to_metric_source import CSVToMetricsSource +from psl.adapters.influxdb_to_metric_source import InfluxdbToMetricSource ENCODING = 'utf-8' predictor_adapter_config = config["predictor_adapter"] +monitored_vars = predictor_adapter_config["monitored_vars"].get() +lab_names = [monitored_var["lab_name"] for monitored_var in monitored_vars] +thresholds = [monitored_var["threshold"] for monitored_var in monitored_vars] +metric_source_class_name = predictor_adapter_config["metric_source_class_name"].get() +metric_source = globals()[metric_source_class_name]() + monitored_vars = predictor_adapter_config["monitored_vars"].get() cpu_usage_idle_monitored_var = monitored_vars[0] cpu_usage_idle_threshold = cpu_usage_idle_monitored_var["threshold"] @@ -18,24 +26,63 @@ cpu_usage_idle_threshold = cpu_usage_idle_monitored_var["threshold"] def run(): logging.info("Running Self Learning Flow") + start_time = time.time() deployments = deployments_repository.get_all() + total_deployments = len(deployments) + valid_predictions = 0 for deployment_id in deployments.keys(): deployment_id = deployment_id.decode(ENCODING) - predictor.train_deployment_id(deployment_id) - prediction = None - with warnings.catch_warnings(): - # ignore all caught warnings - warnings.filterwarnings("ignore") - prediction = predictor.predict_deployment_id(deployment_id) - is_valid_prediction = False + logging.info("Processing Deployment: {}".format(deployment_id)) + latest_metrics = metric_source.get_latest_metrics(deployment_id) + + # group latest metrics by doml_element_name + if latest_metrics is None: + logging.info("No metrics found for deployment: {}".format(deployment_id)) + continue + logging.debug("latest_metrics for deployment {}:\n{}".format(deployment_id,latest_metrics)) + latest_metrics_groupby_doml_element_name = latest_metrics.groupby(["doml_element_name", "doml_element_type", "host"]) + # iterate over each doml_element_name + for [doml_element_name, doml_element_type, host] , doml_element_name_metrics in latest_metrics_groupby_doml_element_name: + influxdb.save_input(doml_element_name_metrics, deployment_id, doml_element_name, doml_element_type, host, lab_names) + # check if doml_element_name has training model + predictor.train_deployment_id_doml_element_name(deployment_id, doml_element_name, doml_element_type) + prediction = None + with warnings.catch_warnings(): + # ignore all caught warnings + warnings.filterwarnings("ignore") + prediction = predictor.predict_deployment_id(deployment_id, doml_element_name, doml_element_type, latest_metrics=doml_element_name_metrics) + is_valid_prediction = False + try: + prediction_datetime = pandas.to_datetime(prediction[-2]).replace(tzinfo=None) + input_datetime = pandas.to_datetime(prediction[-1]).replace(tzinfo=None) + is_valid_prediction = True + valid_predictions += 1 + except Exception: + logging.info("Prediction for deployment {} is invalid".format(deployment_id)) + if is_valid_prediction: + logging.info("Prediction for deployment {} is {} note that forecast time is given at GMT".format(deployment_id, prediction)) + influxdb.save_prediction(prediction, lab_names, prediction_datetime, deployment_id, doml_element_name, doml_element_type, host, input_datetime) + logging.info("Saved at: {}".format(input_datetime)) + check_thresholds(deployment_id, doml_element_name, prediction) + total_time = time.time() - start_time + logging.info("Self Learning Flow: Valid predictions {}, total deployments {}, time {} seconds".format(valid_predictions, total_deployments, total_time)) + return valid_predictions, total_deployments, total_time + + +def check_thresholds(deployment_id, doml_element_name, prediction): + for index, lab_name in enumerate(lab_names): + thresholds_ok = True try: - prediction_datetime = pandas.to_datetime(prediction[4]).replace(tzinfo=None) - is_valid_prediction = True + value = float(prediction[index][0]) + threshold = thresholds[index] + if value < threshold: + if thresholds_ok: + message = "{} element name {}".format(deployment_id, doml_element_name) + thresholds_ok = False + message = "{}\n{} threshold {} not satisfied by value {}".format(message, lab_name, threshold, value) except Exception: - logging.info("Prediction for deployment {} is invalid".format(deployment_id)) - if is_valid_prediction: - logging.info("Prediction for deployment {} is {} note that forecast time is given at GMT".format(deployment_id, prediction)) - influxdb.save_prediction(prediction, prediction_datetime, deployment_id) - if prediction[0] < cpu_usage_idle_threshold: - logging.warning("Prediction {} lower than threshold {}".format(prediction, cpu_usage_idle_threshold)) - sh_client.notify_threshold_event(deployment_id) + None + + if not thresholds_ok: + logging.warning("Thresholds not ok for deployment {} message will be sent to sh".format(deployment_id)) + sh_client.notify_threshold_event(deployment_id) diff --git a/src/psl/models/__init__.py b/src/psl/models/__init__.py index 310be3adf6a57f154db8ba1f1bcae517fe8f0895..02e4566a6a4b352fd16d5e4a60e2b6a5120d549f 100644 --- a/src/psl/models/__init__.py +++ b/src/psl/models/__init__.py @@ -3,4 +3,5 @@ # flake8: noqa from __future__ import absolute_import # import models into model package +from psl.models.deployment import Deployment from psl.models.error import Error diff --git a/src/psl/models/deployment.py b/src/psl/models/deployment.py new file mode 100644 index 0000000000000000000000000000000000000000..b2091336aa4d4f3a50a9ec879909cd74a2c3ddc3 --- /dev/null +++ b/src/psl/models/deployment.py @@ -0,0 +1,66 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from psl.models.base_model_ import Model +from psl import util + + +class Deployment(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + + Do not edit the class manually. + """ + + def __init__(self, deployment_id=None): # noqa: E501 + """Deployment - a model defined in OpenAPI + + :param deployment_id: The deployment_id of this Deployment. # noqa: E501 + :type deployment_id: str + """ + self.openapi_types = { + 'deployment_id': str + } + + self.attribute_map = { + 'deployment_id': 'deployment_id' + } + + self._deployment_id = deployment_id + + @classmethod + def from_dict(cls, dikt) -> 'Deployment': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Deployment of this Deployment. # noqa: E501 + :rtype: Deployment + """ + return util.deserialize_model(dikt, cls) + + @property + def deployment_id(self): + """Gets the deployment_id of this Deployment. + + id of the deployment # noqa: E501 + + :return: The deployment_id of this Deployment. + :rtype: str + """ + return self._deployment_id + + @deployment_id.setter + def deployment_id(self, deployment_id): + """Sets the deployment_id of this Deployment. + + id of the deployment # noqa: E501 + + :param deployment_id: The deployment_id of this Deployment. + :type deployment_id: str + """ + + self._deployment_id = deployment_id diff --git a/src/psl/openapi/openapi.yaml b/src/psl/openapi/openapi.yaml index e1b5b28df91df3a8d83f78be7c5c5b65a7be8592..34bc0237bf26b5ecbf64760f6e32bd4af374299c 100644 --- a/src/psl/openapi/openapi.yaml +++ b/src/psl/openapi/openapi.yaml @@ -206,8 +206,14 @@ components: schemas: Deployment: description: Deployment - example: 123e4567-e89b-12d3-a456-426614174000 - type: string + example: + deployment_id: 123e4567-e89b-12d3-a456-426614174000 + properties: + deployment_id: + description: id of the deployment + type: string + title: Deployment + type: object DeploymentID: description: Id of the deployment example: 123e4567-e89b-12d3-a456-426614174000 diff --git a/src/psl/predictor/predictor.py b/src/psl/predictor/predictor.py index f14949409d58f11775c418c2e231a02278bc7eeb..e8b5c716b4ecfca81a68c536646e7fc4da26701e 100644 --- a/src/psl/predictor/predictor.py +++ b/src/psl/predictor/predictor.py @@ -22,51 +22,40 @@ import traceback import warnings from datetime import timedelta -from river import linear_model as riv_linear -from river import compose -from river import datasets -from river import evaluate from river import metrics -from river import time_series -from river import tree -from river import preprocessing as prep from river import stream -from river import ensemble -from river.drift import EDDM,PageHinkley -from river import anomaly from sklearn.preprocessing import MinMaxScaler,StandardScaler from river import stats from river.drift import ADWIN -from river import utils -from river import optim -from sklearn import pipeline -from river import linear_model from river import time_series from collections import deque from river import neighbors -from river import neural_net as nn + +import numpy seed=48 -warnings.filterwarnings("ignore", category=FutureWarning) +warnings.filterwarnings('ignore') ###################### FUNCTIONS ###################### ####################################################### -def train(data,horizon,feat_name,lab_name,path_models,window_anom_detect,delta): +def train(data,horizon,feat_name,lab_names,path_models,window_anom_detects,deltas,available_mods): """ This method is called once in the monitoring phase. It receives training data[n instances], and is stored when the training phases finalizes. - :param data: pandas DataFrame with the training data. 200 instances approx. - First column '_value' with the real reading of the monitoring variable (e.g. 95.28). - Second column 'moment' (which is defined by the variable 'feat_name' of the 'predictor_config.txt' config file) with the DateTime (e.g. 2021-09-20 13:00:00) + :param data: pandas DataFrame with the training data. 200 instances approx. Columns: + ['cpu_usage_percent', 'disk_used_percent', 'mem_used_percent', 'system_availability_percent', 'moment'] + + Last column 'moment' (which is defined by the variable 'feat_name' of the 'predictor_config.txt' config file) with the DateTime (e.g. 2021-09-20 13:00:00) :param horizon: number of time steps ahead to make the prediction :param feat_name: name of the DataTime feature ('moment') - :param lab_name: name of the target feature ('_value') + :param lab_names: list of names of the target features. E.g.: ['cpu_usage_percent', 'disk_used_percent', 'mem_used_percent', 'system_availability_percent'] :param path_models: path to store and load variables, models, etc. - :param window_anom_detect: length of the window to store instances for different purposes - :param delta: value for the Drift detector + :param window_anom_detects: list with the length of the window for each monitoring variable to store instances for different purposes. E.g.: [50,50,50,50,50,50,50] + :param deltas: list with the parameters values for the Drift detector for each monitoring variable. E.g.: [0.1,0.1,0.1,0.1,0.1,0.1,0.1] + :param available_mods: list of True/False to indicate the modules that are available. E.g.: [cpu_usage_percent, disk_used_percent, mem_used_percent, system_availability_percent] --> [True,False,False,False] :return: True/False """ @@ -77,7 +66,7 @@ def train(data,horizon,feat_name,lab_name,path_models,window_anom_detect,delta): # data = piacere_utils.data_preparing(data, feat_name, time_column_name) X = pd.DataFrame(data[feat_name]) X.columns = [feat_name] - Y = data.loc[:, data.columns == lab_name] + Y = data.loc[:, data.columns != feat_name] #Scaling data scaler = MinMaxScaler() @@ -88,93 +77,380 @@ def train(data,horizon,feat_name,lab_name,path_models,window_anom_detect,delta): train_Y = Y #Model definition - model=time_series.SNARIMAX(p=0,d=0,q=0,regressor=(neighbors.KNNRegressor(n_neighbors=10,window_size=horizon))) + if available_mods[0]: + cpuUP_model=time_series.SNARIMAX(p=0,d=0,q=0,regressor=(neighbors.KNNRegressor(n_neighbors=10,window_size=horizon))) + if available_mods[1]: + memUP_model=time_series.SNARIMAX(p=0,d=0,q=0,regressor=(neighbors.KNNRegressor(n_neighbors=10,window_size=horizon))) + if available_mods[2]: + diskUP_model=time_series.SNARIMAX(p=0,d=0,q=0,regressor=(neighbors.KNNRegressor(n_neighbors=10,window_size=horizon))) + if available_mods[3]: + sysAP_model=time_series.SNARIMAX(p=0,d=0,q=0,regressor=(neighbors.KNNRegressor(n_neighbors=10,window_size=horizon))) ############# Training ######################### - observed_mean=0 - observed_std=0 + #CPU_USAGE_PERCENT + if available_mods[0]: + cpuUP_observed_mean=0 + cpuUP_observed_std=0 + cpuUP_tr_readings=deque(maxlen=window_anom_detects[0]) + #MEM_USED_PERCENT + if available_mods[1]: + memUP_observed_mean=0 + memUP_observed_std=0 + memUP_tr_readings=deque(maxlen=window_anom_detects[1]) + #DISK_USED_PERCENT + if available_mods[2]: + diskUP_observed_mean=0 + diskUP_observed_std=0 + diskUP_tr_readings=deque(maxlen=window_anom_detects[2]) + #SYSTEM_AVAILABILITY_PERCENT + if available_mods[3]: + sysAP_observed_mean=0 + sysAP_observed_std=0 + sysAP_tr_readings=deque(maxlen=window_anom_detects[3]) + tr=0 - tr_readings=deque(maxlen=window_anom_detect) for xr, yr in stream.iter_pandas(train_X,train_Y): - #Datos en formato con punto - int_part = str(yr[lab_name]).split('.')[0] - dec_part = str(yr[lab_name]).split('.')[1] - new_yr = float(int_part + "." + dec_part) + ##################### CPU_USAGE_PERCENT + if available_mods[0]: + + try: + #With dot format + int_part = str(yr[lab_names[0]]).split('.')[0] + dec_part = str(yr[lab_names[0]]).split('.')[1] + new_yr = float(int_part + "." + dec_part) + + cpuUP_model = cpuUP_model.learn_one(new_yr,xr) # Learning model training + + cpuUP_tr_readings.append(new_yr) + + if tr>=window_anom_detects[0]: + cpuUP_observed_mean = np.mean(cpuUP_tr_readings) + cpuUP_observed_std = np.std(cpuUP_tr_readings) + + except: + logging.debug("The value of the target variable is not a float64. It is: " + str(type(yr[lab_names[0]]))) + + ##################### MEM_USED_PERCENT + if available_mods[1]: + + try: + #With dot format + int_part = str(yr[lab_names[1]]).split('.')[0] + dec_part = str(yr[lab_names[1]]).split('.')[1] + new_yr = float(int_part + "." + dec_part) + + memUP_model = memUP_model.learn_one(new_yr, xr) # Learning model training + + memUP_tr_readings.append(new_yr) + + if tr >= window_anom_detects[1]: + memUP_observed_mean = np.mean(memUP_tr_readings) + memUP_observed_std = np.std(memUP_tr_readings) + except: + logging.debug("The value of the target variable is not a float64. It is: " + str(type(yr[lab_names[1]]))) + + ##################### DISK_USED_PERCENT + if available_mods[2]: + + try: + #With dot format + int_part = str(yr[lab_names[2]]).split('.')[0] + dec_part = str(yr[lab_names[2]]).split('.')[1] + new_yr = float(int_part + "." + dec_part) + + diskUP_model = diskUP_model.learn_one(new_yr, xr) # Learning model training + + diskUP_tr_readings.append(new_yr) - model = model.learn_one(new_yr,xr) # Learning model training + if tr >= window_anom_detects[2]: + diskUP_observed_mean = np.mean(diskUP_tr_readings) + diskUP_observed_std = np.std(diskUP_tr_readings) + except: + logging.debug("The value of the target variable is not a float64. It is: " + str(type(yr[lab_names[2]]))) - tr_readings.append(new_yr) + ##################### SYSTEM_AVAILABILITY_PERCENT + if available_mods[3]: - if tr>=window_anom_detect: - observed_mean = np.mean(tr_readings) - observed_std = np.std(tr_readings) + try: + #With dot format + int_part = str(yr[lab_names[3]]).split('.')[0] + dec_part = str(yr[lab_names[3]]).split('.')[1] + new_yr = float(int_part + "." + dec_part) + + sysAP_model = sysAP_model.learn_one(new_yr, xr) # Learning model training + + sysAP_tr_readings.append(new_yr) + + if tr >= window_anom_detects[3]: + sysAP_observed_mean = np.mean(sysAP_tr_readings) + sysAP_observed_std = np.std(sysAP_tr_readings) + except: + logging.debug("The value of the target variable is not a float64. It is: " + str(type(yr[lab_names[3]]))) tr+=1 ############# Creating variables for streaming ######################### - #Drift - drift_var = stats.Var() - drifts=[] - drift_detector = ADWIN(delta=delta) - x_sw=deque(maxlen=window_anom_detect) - y_sw=deque(maxlen=window_anom_detect) - #Performance - metric = metrics.MAE() - multi_step_preds = deque(maxlen=horizon) - #Anomalies - anomalies = [] - #For plotting - real_obs=[] - forecasts=[] - anoms_detected=[] - drifts_detected=[] - maes=[] - ############# Persistence ######################### + ##################### CPU_USAGE_PERCENT + if available_mods[0]: + #Drift + cpuUP_drift_var = stats.Var() + cpuUP_drifts=[] + cpuUP_drift_detector = ADWIN(delta=deltas[0]) + cpuUP_x_sw=deque(maxlen=window_anom_detects[0]) + cpuUP_y_sw=deque(maxlen=window_anom_detects[0]) + + #Performance + cpuUP_metric = metrics.MAE() + cpuUP_multi_step_preds = deque(maxlen=horizon) + + #Anomalies + cpuUP_anomalies = [] + + #For plotting + cpuUP_real_obs=[] + cpuUP_forecasts=[] + cpuUP_anoms_detected=[] + cpuUP_drifts_detected=[] + cpuUP_maes=[] + + ##################### MEM_USED_PERCENT + if available_mods[1]: + #Drift + memUP_drift_var = stats.Var() + memUP_drifts=[] + memUP_drift_detector = ADWIN(delta=deltas[1]) + memUP_x_sw=deque(maxlen=window_anom_detects[1]) + memUP_y_sw=deque(maxlen=window_anom_detects[1]) + + #Performance + memUP_metric = metrics.MAE() + memUP_multi_step_preds = deque(maxlen=horizon) + + #Anomalies + memUP_anomalies = [] + + #For plotting + memUP_real_obs=[] + memUP_forecasts=[] + memUP_anoms_detected=[] + memUP_drifts_detected=[] + memUP_maes=[] + + ##################### DISK_USED_PERCENT + if available_mods[2]: + #Drift + diskUP_drift_var = stats.Var() + diskUP_drifts=[] + diskUP_drift_detector = ADWIN(delta=deltas[2]) + diskUP_x_sw=deque(maxlen=window_anom_detects[2]) + diskUP_y_sw=deque(maxlen=window_anom_detects[2]) + + #Performance + diskUP_metric = metrics.MAE() + diskUP_multi_step_preds = deque(maxlen=horizon) + + #Anomalies + diskUP_anomalies = [] + + #For plotting + diskUP_real_obs=[] + diskUP_forecasts=[] + diskUP_anoms_detected=[] + diskUP_drifts_detected=[] + diskUP_maes=[] + + ##################### SYSTEM_AVAILABILITY_PERCENT + if available_mods[3]: + #Drift + sysAP_drift_var = stats.Var() + sysAP_drifts=[] + sysAP_drift_detector = ADWIN(delta=deltas[3]) + sysAP_x_sw=deque(maxlen=window_anom_detects[3]) + sysAP_y_sw=deque(maxlen=window_anom_detects[3]) + + #Performance + sysAP_metric = metrics.MAE() + sysAP_multi_step_preds = deque(maxlen=horizon) + + #Anomalies + sysAP_anomalies = [] + + #For plotting + sysAP_real_obs=[] + sysAP_forecasts=[] + sysAP_anoms_detected=[] + sysAP_drifts_detected=[] + sysAP_maes=[] + + ############# Persistence ################################## #Saving scaler with open(path_models+'scaler.pkl', 'wb') as f: pickle.dump(scaler, f) - #Saving model - with open(path_models+'model.pkl', 'wb') as f: - pickle.dump(model, f) - #Saving anomalies statistics - with open(path_models+'anom_stats.pkl', 'wb') as f: - anom_stats=[observed_mean,observed_std] - pickle.dump(anom_stats, f) - #Saving drift variables - with open(path_models+'drift_var.pkl', 'wb') as f: - pickle.dump(drift_var, f) - with open(path_models+'drifts.pkl', 'wb') as f: - pickle.dump(drifts, f) - with open(path_models+'drift_detector.pkl', 'wb') as f: - pickle.dump(drift_detector, f) - with open(path_models+'x_sw.pkl', 'wb') as f: - pickle.dump(x_sw, f) - with open(path_models+'y_sw.pkl', 'wb') as f: - pickle.dump(y_sw, f) - #Saving performance variable - with open(path_models+'metric.pkl', 'wb') as f: - pickle.dump(metric, f) - with open(path_models+'multi_step_preds.pkl', 'wb') as f: - pickle.dump(multi_step_preds, f) - #Saving anomalies - with open(path_models+'anomalies.pkl', 'wb') as f: - pickle.dump(anomalies, f) - #Saving plotting required variable - with open(path_models+'real_obs.pkl', 'wb') as f: - pickle.dump(real_obs, f) - with open(path_models+'forecasts.pkl', 'wb') as f: - pickle.dump(forecasts, f) - with open(path_models+'maes.pkl', 'wb') as f: - pickle.dump(maes, f) - with open(path_models+'anoms_detected.pkl', 'wb') as f: - pickle.dump(anoms_detected, f) - with open(path_models+'drifts_detected.pkl', 'wb') as f: - pickle.dump(drifts_detected, f) + + ##################### CPU_USAGE_PERCENT + if available_mods[0]: + #Saving model + with open(path_models+'cpuUP_model.pkl', 'wb') as f: + pickle.dump(cpuUP_model, f) + #Saving anomalies statistics + with open(path_models+'cpuUP_anom_stats.pkl', 'wb') as f: + cpuUP_anom_stats=[cpuUP_observed_mean,cpuUP_observed_std] + pickle.dump(cpuUP_anom_stats, f) + #Saving drift variables + with open(path_models+'cpuUP_drift_var.pkl', 'wb') as f: + pickle.dump(cpuUP_drift_var, f) + with open(path_models+'cpuUP_drifts.pkl', 'wb') as f: + pickle.dump(cpuUP_drifts, f) + with open(path_models+'cpuUP_drift_detector.pkl', 'wb') as f: + pickle.dump(cpuUP_drift_detector, f) + with open(path_models+'cpuUP_x_sw.pkl', 'wb') as f: + pickle.dump(cpuUP_x_sw, f) + with open(path_models+'cpuUP_y_sw.pkl', 'wb') as f: + pickle.dump(cpuUP_y_sw, f) + #Saving performance variable + with open(path_models+'cpuUP_metric.pkl', 'wb') as f: + pickle.dump(cpuUP_metric, f) + with open(path_models+'cpuUP_multi_step_preds.pkl', 'wb') as f: + pickle.dump(cpuUP_multi_step_preds, f) + #Saving anomalies + with open(path_models+'cpuUP_anomalies.pkl', 'wb') as f: + pickle.dump(cpuUP_anomalies, f) + #Saving plotting required variable + with open(path_models+'cpuUP_real_obs.pkl', 'wb') as f: + pickle.dump(cpuUP_real_obs, f) + with open(path_models+'cpuUP_forecasts.pkl', 'wb') as f: + pickle.dump(cpuUP_forecasts, f) + with open(path_models+'cpuUP_maes.pkl', 'wb') as f: + pickle.dump(cpuUP_maes, f) + with open(path_models+'cpuUP_anoms_detected.pkl', 'wb') as f: + pickle.dump(cpuUP_anoms_detected, f) + with open(path_models+'cpuUP_drifts_detected.pkl', 'wb') as f: + pickle.dump(cpuUP_drifts_detected, f) + + ##################### MEM_USED_PERCENT + if available_mods[1]: + #Saving model + with open(path_models+'memUP_model.pkl', 'wb') as f: + pickle.dump(memUP_model, f) + #Saving anomalies statistics + with open(path_models+'memUP_anom_stats.pkl', 'wb') as f: + memUP_anom_stats=[memUP_observed_mean,memUP_observed_std] + pickle.dump(memUP_anom_stats, f) + #Saving drift variables + with open(path_models+'memUP_drift_var.pkl', 'wb') as f: + pickle.dump(memUP_drift_var, f) + with open(path_models+'memUP_drifts.pkl', 'wb') as f: + pickle.dump(memUP_drifts, f) + with open(path_models+'memUP_drift_detector.pkl', 'wb') as f: + pickle.dump(memUP_drift_detector, f) + with open(path_models+'memUP_x_sw.pkl', 'wb') as f: + pickle.dump(memUP_x_sw, f) + with open(path_models+'memUP_y_sw.pkl', 'wb') as f: + pickle.dump(memUP_y_sw, f) + #Saving performance variable + with open(path_models+'memUP_metric.pkl', 'wb') as f: + pickle.dump(memUP_metric, f) + with open(path_models+'memUP_multi_step_preds.pkl', 'wb') as f: + pickle.dump(memUP_multi_step_preds, f) + #Saving anomalies + with open(path_models+'memUP_anomalies.pkl', 'wb') as f: + pickle.dump(memUP_anomalies, f) + #Saving plotting required variable + with open(path_models+'memUP_real_obs.pkl', 'wb') as f: + pickle.dump(memUP_real_obs, f) + with open(path_models+'memUP_forecasts.pkl', 'wb') as f: + pickle.dump(memUP_forecasts, f) + with open(path_models+'memUP_maes.pkl', 'wb') as f: + pickle.dump(memUP_maes, f) + with open(path_models+'memUP_anoms_detected.pkl', 'wb') as f: + pickle.dump(memUP_anoms_detected, f) + with open(path_models+'memUP_drifts_detected.pkl', 'wb') as f: + pickle.dump(memUP_drifts_detected, f) + + ##################### DISK_USED_PERCENT + if available_mods[2]: + #Saving model + with open(path_models+'diskUP_model.pkl', 'wb') as f: + pickle.dump(diskUP_model, f) + #Saving anomalies statistics + with open(path_models+'diskUP_anom_stats.pkl', 'wb') as f: + diskUP_anom_stats=[diskUP_observed_mean,diskUP_observed_std] + pickle.dump(diskUP_anom_stats, f) + #Saving drift variables + with open(path_models+'diskUP_drift_var.pkl', 'wb') as f: + pickle.dump(diskUP_drift_var, f) + with open(path_models+'diskUP_drifts.pkl', 'wb') as f: + pickle.dump(diskUP_drifts, f) + with open(path_models+'diskUP_drift_detector.pkl', 'wb') as f: + pickle.dump(diskUP_drift_detector, f) + with open(path_models+'diskUP_x_sw.pkl', 'wb') as f: + pickle.dump(diskUP_x_sw, f) + with open(path_models+'diskUP_y_sw.pkl', 'wb') as f: + pickle.dump(diskUP_y_sw, f) + #Saving performance variable + with open(path_models+'diskUP_metric.pkl', 'wb') as f: + pickle.dump(diskUP_metric, f) + with open(path_models+'diskUP_multi_step_preds.pkl', 'wb') as f: + pickle.dump(diskUP_multi_step_preds, f) + #Saving anomalies + with open(path_models+'diskUP_anomalies.pkl', 'wb') as f: + pickle.dump(diskUP_anomalies, f) + #Saving plotting required variable + with open(path_models+'diskUP_real_obs.pkl', 'wb') as f: + pickle.dump(diskUP_real_obs, f) + with open(path_models+'diskUP_forecasts.pkl', 'wb') as f: + pickle.dump(diskUP_forecasts, f) + with open(path_models+'diskUP_maes.pkl', 'wb') as f: + pickle.dump(diskUP_maes, f) + with open(path_models+'diskUP_anoms_detected.pkl', 'wb') as f: + pickle.dump(diskUP_anoms_detected, f) + with open(path_models+'diskUP_drifts_detected.pkl', 'wb') as f: + pickle.dump(diskUP_drifts_detected, f) + + ##################### SYSTEM_AVAILABILITY_PERCENT + if available_mods[3]: + #Saving model + with open(path_models+'sysAP_model.pkl', 'wb') as f: + pickle.dump(sysAP_model, f) + #Saving anomalies statistics + with open(path_models+'sysAP_anom_stats.pkl', 'wb') as f: + sysAP_anom_stats=[sysAP_observed_mean,sysAP_observed_std] + pickle.dump(sysAP_anom_stats, f) + #Saving drift variables + with open(path_models+'sysAP_drift_var.pkl', 'wb') as f: + pickle.dump(sysAP_drift_var, f) + with open(path_models+'sysAP_drifts.pkl', 'wb') as f: + pickle.dump(sysAP_drifts, f) + with open(path_models+'sysAP_drift_detector.pkl', 'wb') as f: + pickle.dump(sysAP_drift_detector, f) + with open(path_models+'sysAP_x_sw.pkl', 'wb') as f: + pickle.dump(sysAP_x_sw, f) + with open(path_models+'sysAP_y_sw.pkl', 'wb') as f: + pickle.dump(sysAP_y_sw, f) + #Saving performance variable + with open(path_models+'sysAP_metric.pkl', 'wb') as f: + pickle.dump(sysAP_metric, f) + with open(path_models+'sysAP_multi_step_preds.pkl', 'wb') as f: + pickle.dump(sysAP_multi_step_preds, f) + #Saving anomalies + with open(path_models+'sysAP_anomalies.pkl', 'wb') as f: + pickle.dump(sysAP_anomalies, f) + #Saving plotting required variable + with open(path_models+'sysAP_real_obs.pkl', 'wb') as f: + pickle.dump(sysAP_real_obs, f) + with open(path_models+'sysAP_forecasts.pkl', 'wb') as f: + pickle.dump(sysAP_forecasts, f) + with open(path_models+'sysAP_maes.pkl', 'wb') as f: + pickle.dump(sysAP_maes, f) + with open(path_models+'sysAP_anoms_detected.pkl', 'wb') as f: + pickle.dump(sysAP_anoms_detected, f) + with open(path_models+'sysAP_drifts_detected.pkl', 'wb') as f: + pickle.dump(sysAP_drifts_detected, f) return True @@ -183,25 +459,33 @@ def train(data,horizon,feat_name,lab_name,path_models,window_anom_detect,delta): traceback.print_exc() return False -def predict(x_data_instance,y_data_instance,horizon,feat_name,lab_name,path_models,window_anom_detect,anom_factor,plott,threshold,monitored_var): +def predict(x_data_instance,y_data_instance,horizon,feat_name,lab_names,path_models,window_anom_detects,anom_factors,plott,thres_holds,monitored_variables,available_mods): """ This method is called every time a new incoming data instance arrives in the monitoring phase. So we have to follow a test-then-train approach, where the model makes a prediction first, and afterwards learns the data instance. :param x_data_instance: a dictionary, e.g. {'moment': numpy.datetime64('2021-11-17T14:00:00.000000000')} with the time step of the current data instance - :param y_data_instance: a dictionary e.g. {'_value': 95.86} with the usage_idle current value. + :param y_data_instance: a dictionary with the current values of each monitoring variables. E.g.: {'cpu_usage_percent': 87.70834514071545, 'disk_used_percent': 3.0945516432548805, 'mem_used_percent': 8.929829751345423, 'system_availability_percent': 25.81267896446586} :param horizon: number of time steps ahead to make the prediction :param feat_name: name of the DataTime feature ('moment') - :param lab_name: name of the target feature ('_value') + :param lab_names: list of names of the target features. E.g.: ['cpu_usage_percent', 'disk_used_percent', 'mem_used_percent', 'system_availability_percent'] :param path_models: path to store and load variables, models, etc. - :param window_anom_detect: length of the window to store instances for different purposes - :param anom_factor: factor to detect anomalies + :param window_anom_detects: list with the lengths of the window to store instances for different purposes for each monitoring variable. E.g.: [50,50,50,50,50,50,50] + :param anom_factors: factor to detect anomalies. E.g.: [4.0,4.0,4.0,4.0,4.0,4.0,4.0] :param plott: True/False to have an overall view of the process until this time step - :param threshold: the value to be plotted as frontier for the monitored variable - :param monitored_var: variable to monitor (e.g. 'cpu_usage_idle') - - :return: output:[prediction,mae,anomaly True/False,drift True/False,time of the prediction] + :param thres_holds: list of values to be plotted as frontier for the monitored variables. E.g: [70,10,70,70,10,70,10] + :param monitored_variables: list of variables to monitor. E.g.: ['cpu_usage_percent', 'disk_used_percent', 'mem_used_percent', 'system_availability_percent', 'moment'] + :param available_mods: list of True/False to indicate the modules that are available. E.g.: [cpu_usage_percent, disk_used_percent, mem_used_percent, system_availability_percent] --> [True,False,False,True] + + :return: output: list of lists (results per monitored variable) + moment. E.g.: + [ + [prediction,mae,anomaly True/False,drift True/False,time of the prediction],-->cpu_usage_percent + [prediction,mae,anomaly True/False,drift True/False,time of the prediction],-->disk_used_percent + [prediction,mae,anomaly True/False,drift True/False,time of the prediction],-->mem_used_percent + [prediction,mae,anomaly True/False,drift True/False,time of the prediction],-->system_availability_percent + ,moment of the prediction + ] """ try: @@ -211,72 +495,275 @@ def predict(x_data_instance,y_data_instance,horizon,feat_name,lab_name,path_mode #Loading scaler with open(path_models+'scaler.pkl', 'rb') as f: scaler = pickle.load(f) - #Loading model - with open(path_models+'model.pkl', 'rb') as f: - model = pickle.load(f) - #Loading anomalies statistics - with open(path_models+'anom_stats.pkl', 'rb') as f: - anom_stats = pickle.load(f) - #Loading drift variables - with open(path_models+'drift_var.pkl', 'rb') as f: - drift_var = pickle.load(f) - with open(path_models+'drifts.pkl', 'rb') as f: - drifts = pickle.load(f) - with open(path_models+'drift_detector.pkl', 'rb') as f: - drift_detector = pickle.load(f) - with open(path_models+'drift_detector.pkl', 'rb') as f: - drift_detector = pickle.load(f) - with open(path_models+'x_sw.pkl', 'rb') as f: - x_sw = pickle.load(f) - with open(path_models+'y_sw.pkl', 'rb') as f: - y_sw = pickle.load(f) - #Loading performance variable - with open(path_models+'metric.pkl', 'rb') as f: - metric = pickle.load(f) - with open(path_models+'multi_step_preds.pkl', 'rb') as f: - multi_step_preds = pickle.load(f) - #Loading anomalies - with open(path_models+'anomalies.pkl', 'rb') as f: - anomalies = pickle.load(f) - - # Loading persisted variables required for plotting - # Real observations until this moment - with open(path_models + 'real_obs.pkl', 'rb') as f: - real_obs = pickle.load(f) - # Predictions until this moment - with open(path_models + 'forecasts.pkl', 'rb') as f: - forecasts = pickle.load(f) - # Mean Absolute Error (MAE) until this moment - with open(path_models + 'maes.pkl', 'rb') as f: - maes = pickle.load(f) - # Drifts detected until this moment - with open(path_models + 'drifts_detected.pkl', 'rb') as f: - drifts_detected = pickle.load(f) - # Anomalies detected until this moment - with open(path_models + 'anoms_detected.pkl', 'rb') as f: - anoms_detected = pickle.load(f) - - #Local Variables - observed_mean=anom_stats[0] - observed_std=anom_stats[1] - anom=False - drft=False + + ##################### CPU_USAGE_PERCENT + if available_mods[0]: + #Loading model + with open(path_models+'cpuUP_model.pkl', 'rb') as f: + cpuUP_model = pickle.load(f) + #Loading anomalies statistics + with open(path_models+'cpuUP_anom_stats.pkl', 'rb') as f: + cpuUP_anom_stats = pickle.load(f) + #Loading drift variables + with open(path_models+'cpuUP_drift_var.pkl', 'rb') as f: + cpuUP_drift_var = pickle.load(f) + with open(path_models+'cpuUP_drifts.pkl', 'rb') as f: + cpuUP_drifts = pickle.load(f) + with open(path_models+'cpuUP_drift_detector.pkl', 'rb') as f: + cpuUP_drift_detector = pickle.load(f) + with open(path_models+'cpuUP_x_sw.pkl', 'rb') as f: + cpuUP_x_sw = pickle.load(f) + with open(path_models+'cpuUP_y_sw.pkl', 'rb') as f: + cpuUP_y_sw = pickle.load(f) + #Loading performance variable + with open(path_models+'cpuUP_metric.pkl', 'rb') as f: + cpuUP_metric = pickle.load(f) + with open(path_models+'cpuUP_multi_step_preds.pkl', 'rb') as f: + cpuUP_multi_step_preds = pickle.load(f) + #Loading anomalies + with open(path_models+'cpuUP_anomalies.pkl', 'rb') as f: + cpuUP_anomalies = pickle.load(f) + + # Loading persisted variables required for plotting + # Real observations until this moment + with open(path_models + 'cpuUP_real_obs.pkl', 'rb') as f: + cpuUP_real_obs = pickle.load(f) + # Predictions until this moment + with open(path_models + 'cpuUP_forecasts.pkl', 'rb') as f: + cpuUP_forecasts = pickle.load(f) + # Mean Absolute Error (MAE) until this moment + with open(path_models + 'cpuUP_maes.pkl', 'rb') as f: + cpuUP_maes = pickle.load(f) + # Drifts detected until this moment + with open(path_models + 'cpuUP_drifts_detected.pkl', 'rb') as f: + cpuUP_drifts_detected = pickle.load(f) + # Anomalies detected until this moment + with open(path_models + 'cpuUP_anoms_detected.pkl', 'rb') as f: + cpuUP_anoms_detected = pickle.load(f) + + #Local Variables + cpuUP_observed_mean=cpuUP_anom_stats[0] + cpuUP_observed_std=cpuUP_anom_stats[1] + cpuUP_anom=False + cpuUP_drft=False + + ##################### MEM_USED_PERCENT + if available_mods[1]: + #Loading model + with open(path_models+'memUP_model.pkl', 'rb') as f: + memUP_model = pickle.load(f) + #Loading anomalies statistics + with open(path_models+'memUP_anom_stats.pkl', 'rb') as f: + memUP_anom_stats = pickle.load(f) + #Loading drift variables + with open(path_models+'memUP_drift_var.pkl', 'rb') as f: + memUP_drift_var = pickle.load(f) + with open(path_models+'memUP_drifts.pkl', 'rb') as f: + memUP_drifts = pickle.load(f) + with open(path_models+'memUP_drift_detector.pkl', 'rb') as f: + memUP_drift_detector = pickle.load(f) + with open(path_models+'memUP_x_sw.pkl', 'rb') as f: + memUP_x_sw = pickle.load(f) + with open(path_models+'memUP_y_sw.pkl', 'rb') as f: + memUP_y_sw = pickle.load(f) + #Loading performance variable + with open(path_models+'memUP_metric.pkl', 'rb') as f: + memUP_metric = pickle.load(f) + with open(path_models+'memUP_multi_step_preds.pkl', 'rb') as f: + memUP_multi_step_preds = pickle.load(f) + #Loading anomalies + with open(path_models+'memUP_anomalies.pkl', 'rb') as f: + memUP_anomalies = pickle.load(f) + + # Loading persisted variables required for plotting + # Real observations until this moment + with open(path_models + 'memUP_real_obs.pkl', 'rb') as f: + memUP_real_obs = pickle.load(f) + # Predictions until this moment + with open(path_models + 'memUP_forecasts.pkl', 'rb') as f: + memUP_forecasts = pickle.load(f) + # Mean Absolute Error (MAE) until this moment + with open(path_models + 'memUP_maes.pkl', 'rb') as f: + memUP_maes = pickle.load(f) + # Drifts detected until this moment + with open(path_models + 'memUP_drifts_detected.pkl', 'rb') as f: + memUP_drifts_detected = pickle.load(f) + # Anomalies detected until this moment + with open(path_models + 'memUP_anoms_detected.pkl', 'rb') as f: + memUP_anoms_detected = pickle.load(f) + + #Local Variables + memUP_observed_mean=memUP_anom_stats[0] + memUP_observed_std=memUP_anom_stats[1] + memUP_anom=False + memUP_drft=False + + ##################### DISK_USED_PERCENT + if available_mods[2]: + #Loading model + with open(path_models+'diskUP_model.pkl', 'rb') as f: + diskUP_model = pickle.load(f) + #Loading anomalies statistics + with open(path_models+'diskUP_anom_stats.pkl', 'rb') as f: + diskUP_anom_stats = pickle.load(f) + #Loading drift variables + with open(path_models+'diskUP_drift_var.pkl', 'rb') as f: + diskUP_drift_var = pickle.load(f) + with open(path_models+'diskUP_drifts.pkl', 'rb') as f: + diskUP_drifts = pickle.load(f) + with open(path_models+'diskUP_drift_detector.pkl', 'rb') as f: + diskUP_drift_detector = pickle.load(f) + with open(path_models+'diskUP_x_sw.pkl', 'rb') as f: + diskUP_x_sw = pickle.load(f) + with open(path_models+'diskUP_y_sw.pkl', 'rb') as f: + diskUP_y_sw = pickle.load(f) + #Loading performance variable + with open(path_models+'diskUP_metric.pkl', 'rb') as f: + diskUP_metric = pickle.load(f) + with open(path_models+'diskUP_multi_step_preds.pkl', 'rb') as f: + diskUP_multi_step_preds = pickle.load(f) + #Loading anomalies + with open(path_models+'diskUP_anomalies.pkl', 'rb') as f: + diskUP_anomalies = pickle.load(f) + + # Loading persisted variables required for plotting + # Real observations until this moment + with open(path_models + 'diskUP_real_obs.pkl', 'rb') as f: + diskUP_real_obs = pickle.load(f) + # Predictions until this moment + with open(path_models + 'diskUP_forecasts.pkl', 'rb') as f: + diskUP_forecasts = pickle.load(f) + # Mean Absolute Error (MAE) until this moment + with open(path_models + 'diskUP_maes.pkl', 'rb') as f: + diskUP_maes = pickle.load(f) + # Drifts detected until this moment + with open(path_models + 'diskUP_drifts_detected.pkl', 'rb') as f: + diskUP_drifts_detected = pickle.load(f) + # Anomalies detected until this moment + with open(path_models + 'diskUP_anoms_detected.pkl', 'rb') as f: + diskUP_anoms_detected = pickle.load(f) + + #Local Variables + diskUP_observed_mean=diskUP_anom_stats[0] + diskUP_observed_std=diskUP_anom_stats[1] + diskUP_anom=False + diskUP_drft=False + + ##################### SYSTEM_AVAILABILITY_PERCENT + if available_mods[3]: + #Loading model + with open(path_models+'sysAP_model.pkl', 'rb') as f: + sysAP_model = pickle.load(f) + #Loading anomalies statistics + with open(path_models+'sysAP_anom_stats.pkl', 'rb') as f: + sysAP_anom_stats = pickle.load(f) + #Loading drift variables + with open(path_models+'sysAP_drift_var.pkl', 'rb') as f: + sysAP_drift_var = pickle.load(f) + with open(path_models+'sysAP_drifts.pkl', 'rb') as f: + sysAP_drifts = pickle.load(f) + with open(path_models+'sysAP_drift_detector.pkl', 'rb') as f: + sysAP_drift_detector = pickle.load(f) + with open(path_models+'sysAP_x_sw.pkl', 'rb') as f: + sysAP_x_sw = pickle.load(f) + with open(path_models+'sysAP_y_sw.pkl', 'rb') as f: + sysAP_y_sw = pickle.load(f) + #Loading performance variable + with open(path_models+'sysAP_metric.pkl', 'rb') as f: + sysAP_metric = pickle.load(f) + with open(path_models+'sysAP_multi_step_preds.pkl', 'rb') as f: + sysAP_multi_step_preds = pickle.load(f) + #Loading anomalies + with open(path_models+'sysAP_anomalies.pkl', 'rb') as f: + sysAP_anomalies = pickle.load(f) + + # Loading persisted variables required for plotting + # Real observations until this moment + with open(path_models + 'sysAP_real_obs.pkl', 'rb') as f: + sysAP_real_obs = pickle.load(f) + # Predictions until this moment + with open(path_models + 'sysAP_forecasts.pkl', 'rb') as f: + sysAP_forecasts = pickle.load(f) + # Mean Absolute Error (MAE) until this moment + with open(path_models + 'sysAP_maes.pkl', 'rb') as f: + sysAP_maes = pickle.load(f) + # Drifts detected until this moment + with open(path_models + 'sysAP_drifts_detected.pkl', 'rb') as f: + sysAP_drifts_detected = pickle.load(f) + # Anomalies detected until this moment + with open(path_models + 'sysAP_anoms_detected.pkl', 'rb') as f: + sysAP_anoms_detected = pickle.load(f) + + #Local Variables + sysAP_observed_mean=sysAP_anom_stats[0] + sysAP_observed_std=sysAP_anom_stats[1] + sysAP_anom=False + sysAP_drft=False ############# Data Transformation ######################### #X transf_x = scaler.transform([[x_data_instance[feat_name]]])[0] x_dict = {feat_name: transf_x[0]} - #Y - int_part = str(y_data_instance[lab_name]).split('.')[0] - dec_part = str(y_data_instance[lab_name]).split('.')[1] - new_y = float(int_part + "." + dec_part) - real_obs.append(new_y) - - x_sw.append(x_dict) - y_sw.append(new_y) + #Y - ############# PREDICTING t + horizon ######################### + if available_mods[0]: + #### CPU_USAGE_PERCENT + try: + cpuUP_int_part = str(y_data_instance[lab_names[0]]).split('.')[0] + cpuUP_dec_part = str(y_data_instance[lab_names[0]]).split('.')[1] + cpuUP_new_y = float(cpuUP_int_part + "." + cpuUP_dec_part) + + cpuUP_real_obs.append(cpuUP_new_y) + + cpuUP_x_sw.append(x_dict) + cpuUP_y_sw.append(cpuUP_new_y) + except: + logging.debug("The value of the target variable {} cannot be transformed: {}".format(lab_names[0], y_data_instance[lab_names[0]])) + + if available_mods[1]: + #### MEM_USED_PERCENT + try: + memUP_int_part = str(y_data_instance[lab_names[1]]).split('.')[0] + memUP_dec_part = str(y_data_instance[lab_names[1]]).split('.')[1] + memUP_new_y = float(memUP_int_part + "." + memUP_dec_part) + + memUP_real_obs.append(memUP_new_y) + + memUP_x_sw.append(x_dict) + memUP_y_sw.append(memUP_new_y) + except: + logging.debug("The value of the target variable {} cannot be transformed: {}".format(lab_names[1], y_data_instance[lab_names[1]])) + + if available_mods[2]: + #### DISK_USED_PERCENT + try: + diskUP_int_part = str(y_data_instance[lab_names[2]]).split('.')[0] + diskUP_dec_part = str(y_data_instance[lab_names[2]]).split('.')[1] + diskUP_new_y = float(diskUP_int_part + "." + diskUP_dec_part) + + diskUP_real_obs.append(diskUP_new_y) + + diskUP_x_sw.append(x_dict) + diskUP_y_sw.append(diskUP_new_y) + except: + logging.debug("The value of the target variable {} cannot be transformed: {}".format(lab_names[2], y_data_instance[lab_names[2]])) + + if available_mods[3]: + #### SYSTEM_AVAILABILITY_PERCENT + try: + sysAP_int_part = str(y_data_instance[lab_names[3]]).split('.')[0] + sysAP_dec_part = str(y_data_instance[lab_names[3]]).split('.')[1] + sysAP_new_y = float(sysAP_int_part + "." + sysAP_dec_part) + + sysAP_real_obs.append(sysAP_new_y) + + sysAP_x_sw.append(x_dict) + sysAP_y_sw.append(sysAP_new_y) + except: + logging.debug("The value of the target variable {} cannot be transformed: {}".format(lab_names[3], y_data_instance[lab_names[3]])) + + ############# PREDICTING t + horizon ##################################################### future = [] df_x = pd.DataFrame.from_dict(x_data_instance, orient='index', columns=[feat_name]) @@ -289,125 +776,501 @@ def predict(x_data_instance,y_data_instance,horizon,feat_name,lab_name,path_mode fut_x_dict = {feat_name: scaler.transform([df_x.iloc[[0]][feat_name]])[0]} future.append(fut_x_dict) - y_pred = model.forecast(horizon=horizon, xs=future)[-1] # Predictions for the next [horizon] time steps. We take the last one because it its the one that we need - multi_step_preds.append(y_pred) - forecasts.append(y_pred) - - ############# VALIDATING ######################### - if len(multi_step_preds)==horizon: - metric = metric.update(new_y, multi_step_preds[0]) - maes.append(metric.get()) + #### CPU_USAGE_PERCENT + if available_mods[0]: + cpuUP_y_pred = cpuUP_model.forecast(horizon=horizon, xs=future)[-1] # Predictions for the next [horizon] time steps. We take the last one because it its the one that we need + cpuUP_multi_step_preds.append(cpuUP_y_pred) + cpuUP_forecasts.append(cpuUP_y_pred) + #### MEM_USED_PERCENT + if available_mods[1]: + memUP_y_pred = memUP_model.forecast(horizon=horizon, xs=future)[-1] # Predictions for the next [horizon] time steps. We take the last one because it its the one that we need + memUP_multi_step_preds.append(memUP_y_pred) + memUP_forecasts.append(memUP_y_pred) + #### DISK_USED_PERCENT + if available_mods[2]: + diskUP_y_pred = diskUP_model.forecast(horizon=horizon, xs=future)[-1] # Predictions for the next [horizon] time steps. We take the last one because it its the one that we need + diskUP_multi_step_preds.append(diskUP_y_pred) + diskUP_forecasts.append(diskUP_y_pred) + #### SYSTEM_AVAILABILITY_PERCENT + if available_mods[3]: + sysAP_y_pred = sysAP_model.forecast(horizon=horizon, xs=future)[-1] # Predictions for the next [horizon] time steps. We take the last one because it its the one that we need + sysAP_multi_step_preds.append(sysAP_y_pred) + sysAP_forecasts.append(sysAP_y_pred) + + ############# VALIDATING ##################################################### + #### CPU_USAGE_PERCENT + if available_mods[0]: + try: + if len(cpuUP_multi_step_preds)==horizon: + cpuUP_metric = cpuUP_metric.update(cpuUP_new_y, cpuUP_multi_step_preds[0]) + cpuUP_maes.append(cpuUP_metric.get()) + except: + logging.debug("The value of the target variable {} is not valid: {}".format(lab_names[0], y_data_instance[lab_names[0]])) + #### MEM_USED_PERCENT + if available_mods[1]: + try: + if len(memUP_multi_step_preds)==horizon: + memUP_metric = memUP_metric.update(memUP_new_y, memUP_multi_step_preds[0]) + memUP_maes.append(memUP_metric.get()) + except: + logging.debug("The value of the target variable {} is not valid: {}".format(lab_names[1], y_data_instance[lab_names[1]])) + #### DISK_USED_PERCENT + if available_mods[2]: + try: + if len(diskUP_multi_step_preds)==horizon: + diskUP_metric = diskUP_metric.update(diskUP_new_y, diskUP_multi_step_preds[0]) + diskUP_maes.append(diskUP_metric.get()) + except: + logging.debug("The value of the target variable {} is not valid: {}".format(lab_names[2], y_data_instance[lab_names[2]])) + #### SYSTEM_AVAILABILITY_PERCENT + if available_mods[3]: + try: + if len(sysAP_multi_step_preds)==horizon: + sysAP_metric = sysAP_metric.update(sysAP_new_y, sysAP_multi_step_preds[0]) + sysAP_maes.append(sysAP_metric.get()) + except: + logging.debug("The value of the target variable {} is not valid: {}".format(lab_names[3], y_data_instance[lab_names[3]])) ############# TRAINING/LEARNING ######################### - if len(y_sw) >= window_anom_detect: - - observed_mean = np.mean(y_sw) - observed_std = np.std(y_sw) - - #Anomalies treatment - if new_y > observed_mean + (anom_factor * observed_std) or new_y < observed_mean - (anom_factor * observed_std): - logging.info('Anomaly detected at t %s',str(x_data_instance[feat_name])) - anomalies.append(str(x_data_instance[feat_name])) - anom=True - anoms_detected.append(1) - else: - model = model.learn_one(new_y, x_dict) - anoms_detected.append(0) - else: - model = model.learn_one(new_y, x_dict) - anoms_detected.append(0) + #### CPU_USAGE_PERCENT + if available_mods[0]: + try: + if len(cpuUP_y_sw) >= window_anom_detects[0]: + + cpuUP_observed_mean = np.mean(cpuUP_y_sw) + cpuUP_observed_std = np.std(cpuUP_y_sw) + + #Anomalies treatment + if cpuUP_new_y > cpuUP_observed_mean + (anom_factors[0] * cpuUP_observed_std) or cpuUP_new_y < cpuUP_observed_mean - (anom_factors[0] * cpuUP_observed_std): + logging.info('CPU_USAGE_PERCENT: Anomaly detected at t %s',str(x_data_instance[feat_name])) + cpuUP_anomalies.append(str(x_data_instance[feat_name])) + cpuUP_anom=True + cpuUP_anoms_detected.append(1) + else: + cpuUP_model = cpuUP_model.learn_one(cpuUP_new_y, x_dict) + cpuUP_anoms_detected.append(0) + else: + cpuUP_model = cpuUP_model.learn_one(cpuUP_new_y, x_dict) + cpuUP_anoms_detected.append(0) + except: + logging.debug("The value of the target variable {} cannot train/learning: {}".format(lab_names[0], y_data_instance[lab_names[0]])) + + #### MEM_USED_PERCENT + if available_mods[1]: + try: + if len(memUP_y_sw) >= window_anom_detects[1]: + + memUP_observed_mean = np.mean(memUP_y_sw) + memUP_observed_std = np.std(memUP_y_sw) + + #Anomalies treatment + if memUP_new_y > memUP_observed_mean + (anom_factors[1] * memUP_observed_std) or memUP_new_y < memUP_observed_mean - (anom_factors[1] * memUP_observed_std): + logging.info('MEM_USED_PERCENT: Anomaly detected at t %s',str(x_data_instance[feat_name])) + memUP_anomalies.append(str(x_data_instance[feat_name])) + memUP_anom=True + memUP_anoms_detected.append(1) + else: + memUP_model = memUP_model.learn_one(memUP_new_y, x_dict) + memUP_anoms_detected.append(0) + else: + memUP_model = memUP_model.learn_one(memUP_new_y, x_dict) + memUP_anoms_detected.append(0) + except: + logging.debug("The value of the target variable {} cannot train/learning: {}".format(lab_names[1], y_data_instance[lab_names[1]])) + + #### DISK_USED_PERCENT + if available_mods[2]: + try: + if len(diskUP_y_sw) >= window_anom_detects[2]: + + diskUP_observed_mean = np.mean(diskUP_y_sw) + diskUP_observed_std = np.std(diskUP_y_sw) + + #Anomalies treatment + if diskUP_new_y > diskUP_observed_mean + (anom_factors[2] * diskUP_observed_std) or diskUP_new_y < diskUP_observed_mean - (anom_factors[2] * diskUP_observed_std): + logging.info('DISK USED_PERCENT: Anomaly detected at t %s',str(x_data_instance[feat_name])) + diskUP_anomalies.append(str(x_data_instance[feat_name])) + diskUP_anom=True + diskUP_anoms_detected.append(1) + else: + diskUP_model = diskUP_model.learn_one(diskUP_new_y, x_dict) + diskUP_anoms_detected.append(0) + else: + diskUP_model = diskUP_model.learn_one(diskUP_new_y, x_dict) + diskUP_anoms_detected.append(0) + except: + logging.debug("The value of the target variable {} cannot train/learning: {}".format(lab_names[2], y_data_instance[lab_names[2]])) + + #### SYSTEM_AVAILABILITY_PERCENT + if available_mods[3]: + try: + if len(sysAP_y_sw) >= window_anom_detects[3]: + + sysAP_observed_mean = np.mean(sysAP_y_sw) + sysAP_observed_std = np.std(sysAP_y_sw) + + #Anomalies treatment + if sysAP_new_y > sysAP_observed_mean + (anom_factors[3] * sysAP_observed_std) or sysAP_new_y < sysAP_observed_mean - (anom_factors[3] * sysAP_observed_std): + logging.info('SYSTEM_AVAILABILITY_PERCENT: Anomaly detected at t %s',str(x_data_instance[feat_name])) + sysAP_anomalies.append(str(x_data_instance[feat_name])) + sysAP_anom=True + sysAP_anoms_detected.append(1) + else: + sysAP_model = sysAP_model.learn_one(sysAP_new_y, x_dict) + sysAP_anoms_detected.append(0) + else: + sysAP_model = sysAP_model.learn_one(sysAP_new_y, x_dict) + sysAP_anoms_detected.append(0) + except: + logging.debug("The value of the target variable {} cannot train/learning: {}".format(lab_names[3], y_data_instance[lab_names[3]])) ############# DRIFT DETECTION ######################### - dif = new_y - multi_step_preds[0] - drift_var.update(dif) - sd = math.sqrt(drift_var.get()) - - # if drift_var.mean.n == 1: - # input_drift_detector = 0.5 # The expected error is the normalized mean error - - input_drift_detector = 0 - if sd > 0: - input_drift_detector = (dif + 3 * sd) / (6 * sd) - else: - input_drift_detector = 0.5 - - drift_detector.update(input_drift_detector) - - if drift_detector.change_detected: - logging.info('Drift detected at t %s', str(x_data_instance[feat_name])) - drifts.append(str(x_data_instance[feat_name])) - drft=True - - # Reset detector - drift_detector.reset() - drift_var = stats.Var() - - # Retrain the model with the latest instances - model = model.clone() - for h in range(0, window_anom_detect): - model = model.learn_one(y_sw[h], x_sw[h]) # Training with sliding window - - drifts_detected.append(1) - else: - drifts_detected.append(0) - + #### CPU_USAGE_PERCENT + if available_mods[0]: + try: + cpuUP_dif = cpuUP_new_y - cpuUP_multi_step_preds[0] + cpuUP_drift_var.update(cpuUP_dif) + cpuUP_sd = math.sqrt(cpuUP_drift_var.get()) + + # if drift_var.mean.n == 1: + # input_drift_detector = 0.5 # The expected error is the normalized mean error + + input_drift_detector = 0 + if cpuUP_sd > 0: + cpuUP_input_drift_detector = (cpuUP_dif + 3 * cpuUP_sd) / (6 * cpuUP_sd) + else: + cpuUP_input_drift_detector = 0.5 + + cpuUP_drift_detector.update(cpuUP_input_drift_detector) + + if cpuUP_drift_detector.change_detected: + logging.info('CPU_USAGE_PERCENT: Drift detected at t %s', str(x_data_instance[feat_name])) + cpuUP_drifts.append(str(x_data_instance[feat_name])) + cpuUP_drft=True + + # Reset detector + cpuUP_drift_detector.reset() + cpuUP_drift_var = stats.Var() + + # Retrain the model with the latest instances + cpuUP_model = cpuUP_model.clone() + for h in range(len(cpuUP_y_sw)): + cpuUP_model = cpuUP_model.learn_one(cpuUP_y_sw[h], cpuUP_x_sw[h]) # Training with sliding window + + cpuUP_drifts_detected.append(1) + else: + cpuUP_drifts_detected.append(0) + except: + logging.debug("The value of the target variable {} cannot drift: {}".format(lab_names[0], y_data_instance[lab_names[0]])) + + #### MEM_USED_PERCENT + if available_mods[1]: + try: + memUP_dif = memUP_new_y - memUP_multi_step_preds[0] + memUP_drift_var.update(memUP_dif) + memUP_sd = math.sqrt(memUP_drift_var.get()) + + # if drift_var.mean.n == 1: + # input_drift_detector = 0.5 # The expected error is the normalized mean error + + input_drift_detector = 0 + if memUP_sd > 0: + memUP_input_drift_detector = (memUP_dif + 3 * memUP_sd) / (6 * memUP_sd) + else: + memUP_input_drift_detector = 0.5 + + memUP_drift_detector.update(memUP_input_drift_detector) + + if memUP_drift_detector.change_detected: + logging.info('MEM_USED_PERCENT: Drift detected at t %s', str(x_data_instance[feat_name])) + memUP_drifts.append(str(x_data_instance[feat_name])) + memUP_drft=True + + # Reset detector + memUP_drift_detector.reset() + memUP_drift_var = stats.Var() + + # Retrain the model with the latest instances + memUP_model = memUP_model.clone() + for h in range(len(memUP_y_sw)): + memUP_model = memUP_model.learn_one(memUP_y_sw[h], memUP_x_sw[h]) # Training with sliding window + + memUP_drifts_detected.append(1) + else: + memUP_drifts_detected.append(0) + except: + logging.debug("The value of the target variable {} cannot drift: {}".format(lab_names[1], y_data_instance[lab_names[1]])) + + #### DISK_USED_PERCENT + if available_mods[2]: + try: + diskUP_dif = diskUP_new_y - diskUP_multi_step_preds[0] + diskUP_drift_var.update(diskUP_dif) + diskUP_sd = math.sqrt(diskUP_drift_var.get()) + + # if drift_var.mean.n == 1: + # input_drift_detector = 0.5 # The expected error is the normalized mean error + + input_drift_detector = 0 + if diskUP_sd > 0: + diskUP_input_drift_detector = (diskUP_dif + 3 * diskUP_sd) / (6 * diskUP_sd) + else: + diskUP_input_drift_detector = 0.5 + + diskUP_drift_detector.update(diskUP_input_drift_detector) + + if diskUP_drift_detector.change_detected: + logging.info('DISK USED PERCENT: Drift detected at t %s', str(x_data_instance[feat_name])) + diskUP_drifts.append(str(x_data_instance[feat_name])) + diskUP_drft=True + + # Reset detector + diskUP_drift_detector.reset() + diskUP_drift_var = stats.Var() + + # Retrain the model with the latest instances + diskUP_model = diskUP_model.clone() + for h in range(len(diskUP_y_sw)): + diskUP_model = diskUP_model.learn_one(diskUP_y_sw[h], diskUP_x_sw[h]) # Training with sliding window + + diskUP_drifts_detected.append(1) + else: + diskUP_drifts_detected.append(0) + except: + logging.debug("The value of the target variable {} cannot drift: {}".format(lab_names[2], y_data_instance[lab_names[2]])) + + #### SYSTEM_AVAILABILITY_PERCENT + if available_mods[3]: + try: + sysAP_dif = sysAP_new_y - sysAP_multi_step_preds[0] + sysAP_drift_var.update(sysAP_dif) + sysAP_sd = math.sqrt(sysAP_drift_var.get()) + + # if drift_var.mean.n == 1: + # input_drift_detector = 0.5 # The expected error is the normalized mean error + + input_drift_detector = 0 + if sysAP_sd > 0: + sysAP_input_drift_detector = (sysAP_dif + 3 * sysAP_sd) / (6 * sysAP_sd) + else: + sysAP_input_drift_detector = 0.5 + + sysAP_drift_detector.update(sysAP_input_drift_detector) + + if sysAP_drift_detector.change_detected: + logging.info('SYSTEM_AVAILABILITY_PERCENT: Drift detected at t %s', str(x_data_instance[feat_name])) + sysAP_drifts.append(str(x_data_instance[feat_name])) + sysAP_drft=True + + # Reset detector + sysAP_drift_detector.reset() + sysAP_drift_var = stats.Var() + + # Retrain the model with the latest instances + sysAP_model = sysAP_model.clone() + for h in range(len(sysAP_y_sw)): + sysAP_model = sysAP_model.learn_one(sysAP_y_sw[h], sysAP_x_sw[h]) # Training with sliding window + + sysAP_drifts_detected.append(1) + else: + sysAP_drifts_detected.append(0) + except: + logging.debug("The value of the target variable {} cannot drift: {}".format(lab_names[3], y_data_instance[lab_names[3]])) ############# Persistence ######################### - #Saving model - with open(path_models+'model.pkl', 'wb') as f: - pickle.dump(model, f) - #Saving anomalies statistics - with open(path_models+'anom_stats.pkl', 'wb') as f: - anom_stats=[observed_mean,observed_std] - pickle.dump(anom_stats, f) - #Saving drift variables - with open(path_models+'drift_var.pkl', 'wb') as f: - pickle.dump(drift_var, f) - with open(path_models+'drifts.pkl', 'wb') as f: - pickle.dump(drifts, f) - with open(path_models+'drift_detector.pkl', 'wb') as f: - pickle.dump(drift_detector, f) - with open(path_models+'x_sw.pkl', 'wb') as f: - pickle.dump(x_sw, f) - with open(path_models+'y_sw.pkl', 'wb') as f: - pickle.dump(y_sw, f) - #Saving performance variable - with open(path_models+'metric.pkl', 'wb') as f: - pickle.dump(metric, f) - with open(path_models+'multi_step_preds.pkl', 'wb') as f: - pickle.dump(multi_step_preds, f) - #Saving anomalies - with open(path_models+'anomalies.pkl', 'wb') as f: - pickle.dump(anomalies, f) - #Saving information for plotting - with open(path_models+'real_obs.pkl', 'wb') as f: - pickle.dump(real_obs, f) - with open(path_models+'forecasts.pkl', 'wb') as f: - pickle.dump(forecasts, f) - with open(path_models+'maes.pkl', 'wb') as f: - pickle.dump(maes, f) - with open(path_models+'anoms_detected.pkl', 'wb') as f: - pickle.dump(anoms_detected, f) - with open(path_models+'drifts_detected.pkl', 'wb') as f: - pickle.dump(drifts_detected, f) - - if plott: - predictor_utils.plot_integration_results(path_models,threshold,monitored_var) + #### CPU_USAGE_PERCENT + if available_mods[0]: + #Saving model + with open(path_models+'cpuUP_model.pkl', 'wb') as f: + pickle.dump(cpuUP_model, f) + #Saving anomalies statistics + with open(path_models+'cpuUP_anom_stats.pkl', 'wb') as f: + cpuUP_anom_stats=[cpuUP_observed_mean,cpuUP_observed_std] + pickle.dump(cpuUP_anom_stats, f) + #Saving drift variables + with open(path_models+'cpuUP_drift_var.pkl', 'wb') as f: + pickle.dump(cpuUP_drift_var, f) + with open(path_models+'cpuUP_drifts.pkl', 'wb') as f: + pickle.dump(cpuUP_drifts, f) + with open(path_models+'cpuUP_drift_detector.pkl', 'wb') as f: + pickle.dump(cpuUP_drift_detector, f) + with open(path_models+'cpuUP_x_sw.pkl', 'wb') as f: + pickle.dump(cpuUP_x_sw, f) + with open(path_models+'cpuUP_y_sw.pkl', 'wb') as f: + pickle.dump(cpuUP_y_sw, f) + #Saving performance variable + with open(path_models+'cpuUP_metric.pkl', 'wb') as f: + pickle.dump(cpuUP_metric, f) + with open(path_models+'cpuUP_multi_step_preds.pkl', 'wb') as f: + pickle.dump(cpuUP_multi_step_preds, f) + #Saving anomalies + with open(path_models+'cpuUP_anomalies.pkl', 'wb') as f: + pickle.dump(cpuUP_anomalies, f) + #Saving information for plotting + with open(path_models+'cpuUP_real_obs.pkl', 'wb') as f: + pickle.dump(cpuUP_real_obs, f) + with open(path_models+'cpuUP_forecasts.pkl', 'wb') as f: + pickle.dump(cpuUP_forecasts, f) + with open(path_models+'cpuUP_maes.pkl', 'wb') as f: + pickle.dump(cpuUP_maes, f) + with open(path_models+'cpuUP_anoms_detected.pkl', 'wb') as f: + pickle.dump(cpuUP_anoms_detected, f) + with open(path_models+'cpuUP_drifts_detected.pkl', 'wb') as f: + pickle.dump(cpuUP_drifts_detected, f) + + #### MEM_USED_PERCENT + if available_mods[1]: + #Saving model + with open(path_models+'memUP_model.pkl', 'wb') as f: + pickle.dump(memUP_model, f) + #Saving anomalies statistics + with open(path_models+'memUP_anom_stats.pkl', 'wb') as f: + memUP_anom_stats=[memUP_observed_mean,memUP_observed_std] + pickle.dump(memUP_anom_stats, f) + #Saving drift variables + with open(path_models+'memUP_drift_var.pkl', 'wb') as f: + pickle.dump(memUP_drift_var, f) + with open(path_models+'memUP_drifts.pkl', 'wb') as f: + pickle.dump(memUP_drifts, f) + with open(path_models+'memUP_drift_detector.pkl', 'wb') as f: + pickle.dump(memUP_drift_detector, f) + with open(path_models+'memUP_x_sw.pkl', 'wb') as f: + pickle.dump(memUP_x_sw, f) + with open(path_models+'memUP_y_sw.pkl', 'wb') as f: + pickle.dump(memUP_y_sw, f) + #Saving performance variable + with open(path_models+'memUP_metric.pkl', 'wb') as f: + pickle.dump(memUP_metric, f) + with open(path_models+'memUP_multi_step_preds.pkl', 'wb') as f: + pickle.dump(memUP_multi_step_preds, f) + #Saving anomalies + with open(path_models+'memUP_anomalies.pkl', 'wb') as f: + pickle.dump(memUP_anomalies, f) + #Saving information for plotting + with open(path_models+'memUP_real_obs.pkl', 'wb') as f: + pickle.dump(memUP_real_obs, f) + with open(path_models+'memUP_forecasts.pkl', 'wb') as f: + pickle.dump(memUP_forecasts, f) + with open(path_models+'memUP_maes.pkl', 'wb') as f: + pickle.dump(memUP_maes, f) + with open(path_models+'memUP_anoms_detected.pkl', 'wb') as f: + pickle.dump(memUP_anoms_detected, f) + with open(path_models+'memUP_drifts_detected.pkl', 'wb') as f: + pickle.dump(memUP_drifts_detected, f) + + #### DISK USED_PERCENT + if available_mods[2]: + #Saving model + with open(path_models+'diskUP_model.pkl', 'wb') as f: + pickle.dump(diskUP_model, f) + #Saving anomalies statistics + with open(path_models+'diskUP_anom_stats.pkl', 'wb') as f: + diskUP_anom_stats=[diskUP_observed_mean,diskUP_observed_std] + pickle.dump(diskUP_anom_stats, f) + #Saving drift variables + with open(path_models+'diskUP_drift_var.pkl', 'wb') as f: + pickle.dump(diskUP_drift_var, f) + with open(path_models+'diskUP_drifts.pkl', 'wb') as f: + pickle.dump(diskUP_drifts, f) + with open(path_models+'diskUP_drift_detector.pkl', 'wb') as f: + pickle.dump(diskUP_drift_detector, f) + with open(path_models+'diskUP_x_sw.pkl', 'wb') as f: + pickle.dump(diskUP_x_sw, f) + with open(path_models+'diskUP_y_sw.pkl', 'wb') as f: + pickle.dump(diskUP_y_sw, f) + #Saving performance variable + with open(path_models+'diskUP_metric.pkl', 'wb') as f: + pickle.dump(diskUP_metric, f) + with open(path_models+'diskUP_multi_step_preds.pkl', 'wb') as f: + pickle.dump(diskUP_multi_step_preds, f) + #Saving anomalies + with open(path_models+'diskUP_anomalies.pkl', 'wb') as f: + pickle.dump(diskUP_anomalies, f) + #Saving information for plotting + with open(path_models+'diskUP_real_obs.pkl', 'wb') as f: + pickle.dump(diskUP_real_obs, f) + with open(path_models+'diskUP_forecasts.pkl', 'wb') as f: + pickle.dump(diskUP_forecasts, f) + with open(path_models+'diskUP_maes.pkl', 'wb') as f: + pickle.dump(diskUP_maes, f) + with open(path_models+'diskUP_anoms_detected.pkl', 'wb') as f: + pickle.dump(diskUP_anoms_detected, f) + with open(path_models+'diskUP_drifts_detected.pkl', 'wb') as f: + pickle.dump(diskUP_drifts_detected, f) + + #### SYSTEM_AVAILABILITY_PERCENT + if available_mods[3]: + #Saving model + with open(path_models+'sysAP_model.pkl', 'wb') as f: + pickle.dump(sysAP_model, f) + #Saving anomalies statistics + with open(path_models+'sysAP_anom_stats.pkl', 'wb') as f: + sysAP_anom_stats=[sysAP_observed_mean,sysAP_observed_std] + pickle.dump(sysAP_anom_stats, f) + #Saving drift variables + with open(path_models+'sysAP_drift_var.pkl', 'wb') as f: + pickle.dump(sysAP_drift_var, f) + with open(path_models+'sysAP_drifts.pkl', 'wb') as f: + pickle.dump(sysAP_drifts, f) + with open(path_models+'sysAP_drift_detector.pkl', 'wb') as f: + pickle.dump(sysAP_drift_detector, f) + with open(path_models+'sysAP_x_sw.pkl', 'wb') as f: + pickle.dump(sysAP_x_sw, f) + with open(path_models+'sysAP_y_sw.pkl', 'wb') as f: + pickle.dump(sysAP_y_sw, f) + #Saving performance variable + with open(path_models+'sysAP_metric.pkl', 'wb') as f: + pickle.dump(sysAP_metric, f) + with open(path_models+'sysAP_multi_step_preds.pkl', 'wb') as f: + pickle.dump(sysAP_multi_step_preds, f) + #Saving anomalies + with open(path_models+'sysAP_anomalies.pkl', 'wb') as f: + pickle.dump(sysAP_anomalies, f) + #Saving information for plotting + with open(path_models+'sysAP_real_obs.pkl', 'wb') as f: + pickle.dump(sysAP_real_obs, f) + with open(path_models+'sysAP_forecasts.pkl', 'wb') as f: + pickle.dump(sysAP_forecasts, f) + with open(path_models+'sysAP_maes.pkl', 'wb') as f: + pickle.dump(sysAP_maes, f) + with open(path_models+'sysAP_anoms_detected.pkl', 'wb') as f: + pickle.dump(sysAP_anoms_detected, f) + with open(path_models+'sysAP_drifts_detected.pkl', 'wb') as f: + pickle.dump(sysAP_drifts_detected, f) - output=[np.round(y_pred,2),np.round(metric.get(),2),anom,drft,future_t]#[prediction,mae,anomalies,drifts,future_t] + if plott: + predictor_utils.plot_integration_results(path_models,thres_holds,monitored_variables) + + #OUTPUT + # output=[[np.round(cpuUP_y_pred,2),np.round(cpuUP_metric.get(),2),cpuUP_anom,cpuUP_drft], + # [np.round(sysAP_y_pred, 2), np.round(sysAP_metric.get(), 2), sysAP_anom, sysAP_drft], + # [np.round(cpuUU_y_pred, 2), np.round(cpuUU_metric.get(), 2), cpuUU_anom, cpuUU_drft], + # future_t] + + output=[] + if available_mods[0]: + output.append([np.round(cpuUP_y_pred, 2), np.round(cpuUP_metric.get(), 2), cpuUP_anom, cpuUP_drft]) + if available_mods[1]: + output.append([np.round(memUP_y_pred, 2), np.round(memUP_metric.get(), 2), memUP_anom, memUP_drft]) + if available_mods[2]: + output.append([np.round(diskUP_y_pred, 2), np.round(diskUP_metric.get(), 2), diskUP_anom, diskUP_drft]) + if available_mods[3]: + output.append([np.round(sysAP_y_pred, 2), np.round(sysAP_metric.get(), 2), sysAP_anom, sysAP_drft]) + + output.append(future_t) return output except: logging.error('It seems that the prediction process has raised an error.') traceback.print_exc() - output=[0,0,False,False,'No future time'] + output=[0,0,0,False,False,False,'No future time'] return output ###################### MAIN ###################################### -# Gorka's monitoring simulation: USAGE_IDLE monitoring variable +# Gorka's monitoring simulation ################################################################## @@ -420,19 +1283,19 @@ if __name__ == "__main__": path=config.get('Global', 'path') time_column_nam = config.get('Global', 'time_column_name') feat_nam = config.get('Global', 'feat_name') - lab_nam = config.get('Global', 'lab_name') n_tr_instances = int(config.get('Global', 'n_training_instances')) horiz = int(config.get('Global', 'horizon'))#Number of time steps ahead to make the prediction (10) path_mods=config.get('Global', 'path_models') log_level=config.get('Global', 'log_level') - cpu_usage_idle=config.get('Global', 'cpu_usage_idle') - cpu_usage_system=config.get('Global', 'cpu_usage_system') - cpu_usage_user=config.get('Global', 'cpu_usage_user') - mem_free=config.get('Global', 'mem_free') - mem_used_percent=config.get('Global', 'mem_used_percent') - disk_free=config.get('Global', 'disk_free') - disk_used_percent=config.get('Global', 'disk_used_percent') + file_nam = config.get('Global', 'file_name') + + cpu_usage_percent=predictor_utils.to_bool(config.get('Global', 'cpu_usage_percent')) + mem_used_percent=predictor_utils.to_bool(config.get('Global', 'mem_used_percent')) + disk_used_percent=predictor_utils.to_bool(config.get('Global', 'disk_used_percent')) + system_availability_percent=predictor_utils.to_bool(config.get('Global', 'system_availability_percent')) + + available_modules=[cpu_usage_percent,mem_used_percent,disk_used_percent,system_availability_percent] if log_level=='DEBUG': logging.basicConfig(level=logging.DEBUG) @@ -445,59 +1308,105 @@ if __name__ == "__main__": elif log_level=='INFO': logging.basicConfig(level=logging.INFO) - #CPU_USAGE_IDLE - if cpu_usage_idle: - cpuUI_w_anom_detect = int(config.get('CPU-usage_idle', 'window_anom_detect')) - cpuUI_delta = float(config.get('CPU-usage_idle', 'delta')) - cpuUI_file_nam=config.get('CPU-usage_idle', 'file_name') - cpuUI_anom_fact = float(config.get('CPU-usage_idle', 'anom_factor')) - threshold = float(config.get('CPU-usage_idle', 'threshold')) - monitored_var = config.get('CPU-usage_idle', 'monitored_var') - ''' - #CPU_USAGE_SYSTEM - cpuUS_w_anom_detect = int(config.get('CPU-usage_system', 'window_anom_detect')) - cpuUS_delta = float(config.get('CPU-usage_system', 'delta')) - cpuUS_file_nam=config.get('CPU-usage_system', 'file_name') - #CPU_USAGE_USER - cpuUU_w_anom_detect = int(config.get('CPU-usage_user', 'window_anom_detect')) - cpuUU_delta = float(config.get('CPU-usage_user', 'delta')) - cpuUU_file_nam=config.get('CPU-usage_user', 'file_name') - #MEM_FREE - memF_w_anom_detect = int(config.get('MEM-free', 'window_anom_detect')) - memF_delta = float(config.get('MEM-free', 'delta')) - memF_file_nam=config.get('MEM-free', 'file_name') + w_anom_detects=[] + deltas=[] + file_nams=[] + anom_facts=[] + thresholds=[] + monitored_vars=[] + lab_nams=[] + + #CPU_USAGE_PERCENT + cpuUP_w_anom_detect = int(config.get('CPU-usage_percent', 'window_anom_detect')) + w_anom_detects.append(cpuUP_w_anom_detect) + + cpuUP_delta = float(config.get('CPU-usage_percent', 'delta')) + deltas.append(cpuUP_delta) + + cpuUP_anom_fact = float(config.get('CPU-usage_percent', 'anom_factor')) + anom_facts.append(cpuUP_anom_fact) + + cpuUP_threshold = float(config.get('CPU-usage_percent', 'threshold')) + thresholds.append(cpuUP_threshold) + + cpuUP_monitored_var = config.get('CPU-usage_percent', 'monitored_var') + monitored_vars.append(cpuUP_monitored_var) + + cpuUP_lab_nam = config.get('CPU-usage_percent', 'lab_name') + lab_nams.append(cpuUP_lab_nam) + #MEM_USED_PERCENT memUP_w_anom_detect = int(config.get('MEM-used_percent', 'window_anom_detect')) + w_anom_detects.append(memUP_w_anom_detect) + memUP_delta = float(config.get('MEM-used_percent', 'delta')) - memUP_file_nam=config.get('MEM-used_percent', 'file_name') - #DISK_FREE - diskF_w_anom_detect = int(config.get('DISK-free', 'window_anom_detect')) - diskF_delta = float(config.get('DISK-free', 'delta')) - diskF_file_nam=config.get('DISK-free', 'file_name') + deltas.append(memUP_delta) + + memUP_anom_fact = float(config.get('MEM-used_percent', 'anom_factor')) + anom_facts.append(memUP_anom_fact) + + memUP_threshold = float(config.get('MEM-used_percent', 'threshold')) + thresholds.append(memUP_threshold) + + memUP_monitored_var = config.get('MEM-used_percent', 'monitored_var') + monitored_vars.append(memUP_monitored_var) + + memUP_lab_nam = config.get('MEM-used_percent', 'lab_name') + lab_nams.append(memUP_lab_nam) + #DISK_USED_PERCENT diskUP_w_anom_detect = int(config.get('DISK-used_percent', 'window_anom_detect')) + w_anom_detects.append(diskUP_w_anom_detect) + diskUP_delta = float(config.get('DISK-used_percent', 'delta')) - diskUP_file_nam=config.get('DISK-used_percent', 'file_name') - #AVAILABILITY] - aval_w_anom_detect = int(config.get('AVAILABILITY', 'window_anom_detect')) - aval_delta = float(config.get('AVAILABILITY', 'delta')) - aval_file_nam=config.get('AVAILABILITY', 'file_name') - ''' - #CPU_USAGE_IDLE Data simulation - data=predictor_utils.read_piacere_data(path,cpuUI_file_nam,time_column_nam) + deltas.append(diskUP_delta) + + diskUP_anom_fact = float(config.get('DISK-used_percent', 'anom_factor')) + anom_facts.append(diskUP_anom_fact) + + diskUP_threshold = float(config.get('DISK-used_percent', 'threshold')) + thresholds.append(diskUP_threshold) + + diskUP_monitored_var = config.get('DISK-used_percent', 'monitored_var') + monitored_vars.append(diskUP_monitored_var) + + diskUP_lab_nam = config.get('DISK-used_percent', 'lab_name') + lab_nams.append(diskUP_lab_nam) + + #SYSTEM_AVAILABILITY_PERCENT + sysAP_w_anom_detect = int(config.get('SYSTEM-availability-percent', 'window_anom_detect')) + w_anom_detects.append(sysAP_w_anom_detect) + + sysAP_delta = float(config.get('SYSTEM-availability-percent', 'delta')) + deltas.append(sysAP_delta) + + sysAP_anom_fact = float(config.get('SYSTEM-availability-percent', 'anom_factor')) + anom_facts.append(sysAP_anom_fact) + + sysAP_threshold = float(config.get('SYSTEM-availability-percent', 'threshold')) + thresholds.append(sysAP_threshold) + + sysAP_monitored_var = config.get('SYSTEM-availability-percent', 'monitored_var') + monitored_vars.append(sysAP_monitored_var) + + sysAP_lab_nam = config.get('SYSTEM-availability-percent', 'lab_name') + lab_nams.append(sysAP_lab_nam) + #Data simulation + data=predictor_utils.read_piacere_data(path,file_nam,time_column_nam) data=predictor_utils.data_preparing(data,feat_nam,time_column_nam) + train_data=data[0:n_tr_instances] test_data=data[n_tr_instances:] - #CPU_USAGE_IDLE Training - tr_done=train(train_data,horiz,feat_nam,lab_nam,path_mods,cpuUI_w_anom_detect,cpuUI_delta) + #Training + tr_done=train(train_data,horiz,feat_nam,lab_nams,path_mods,w_anom_detects,deltas,available_modules) if tr_done: logging.info('Successfull training') - #CPU_USAGE_IDLE Testing/Predicting + #Testing/Predicting test_X = test_data[[feat_nam]] test_X=test_X[n_tr_instances:] - test_Y = test_data.loc[:, test_data.columns == lab_nam] + test_Y = test_data.loc[:, test_data.columns != feat_nam] test_Y = test_Y[n_tr_instances:] cont=0 @@ -507,7 +1416,7 @@ if __name__ == "__main__": if cont==test_X.shape[0]-1:#Plot is generated at the end of the process, but can be passed 'plotting=True' when necessary, e.g. every day plotting = True - usage_idle_out=predict(x,y,horiz,feat_nam,lab_nam,path_mods,cpuUI_w_anom_detect,cpuUI_anom_fact,plotting,threshold,monitored_var) + out=predict(x,y,horiz,feat_nam,lab_nams,path_mods,w_anom_detects,anom_facts,plotting,thresholds,monitored_vars,available_modules) logging.info(str(x[feat_nam])) - logging.info(usage_idle_out) + logging.info(out) cont+=1 diff --git a/src/psl/predictor/predictor_config.txt b/src/psl/predictor/predictor_config.txt index 152592c902c022ccd1d9780530ee211f127cd5d8..80669371676a0c230206b50abcd4bab7cd5f8c94 100644 --- a/src/psl/predictor/predictor_config.txt +++ b/src/psl/predictor/predictor_config.txt @@ -1,25 +1,25 @@ [Global] -path=C:\\Users\\106811\\PycharmProjects\\ml-for-ds\\data\\ +path=C:\\Users\\106811\\PycharmProjects\\psl\\test_input_data\\ +file_name=psl_data.csv path_models=C:\\Users\\106811\\PycharmProjects\\ml-for-ds\\models\\ n_training_instances=200 horizon=10 -lab_name=_value time_column_name=_time feat_name=moment log_level=INFO cpu_usage_idle=True -cpu_usage_system=False -cpu_usage_user=False -mem_free=False -mem_used_percent=False -disk_free=False -disk_used_percent=False +cpu_usage_system=True +cpu_usage_user=True +mem_free=True +mem_used_percent=True +disk_free=True +disk_used_percent=True [CPU-usage_idle] -file_name=2021-11-24-09-36_usage_idle_data.csv threshold=70.0 +lab_name=cpu_usage_idle monitored_var=cpu_usage_idle #Anomalies window_anom_detect=50 @@ -29,14 +29,68 @@ delta=0.1 [CPU-usage_system] +threshold=10.0 +lab_name=cpu_usage_system +monitored_var=cpu_usage_system +#Anomalies +window_anom_detect=50 +anom_factor=4.0 +#Drifts +delta=0.1 + [CPU-usage_user] +threshold=10.0 +lab_name=cpu_usage_user +monitored_var=cpu_usage_user +#Anomalies +window_anom_detect=50 +anom_factor=4.0 +#Drifts +delta=0.1 + [MEM-free] +threshold=10.0 +lab_name=mem_free +monitored_var=mem_free +#Anomalies +window_anom_detect=50 +anom_factor=4.0 +#Drifts +delta=0.1 + [MEM-used_percent] +threshold=10.0 +lab_name=mem_used_percent +monitored_var=mem_used_percent +#Anomalies +window_anom_detect=50 +anom_factor=4.0 +#Drifts +delta=0.1 + [DISK-free] +threshold=10.0 +lab_name=disk_free +monitored_var=disk_free +#Anomalies +window_anom_detect=50 +anom_factor=4.0 +#Drifts +delta=0.1 + [DISK-used_percent] +threshold=10.0 +lab_name=disk_used_percent +monitored_var=disk_used_percent +#Anomalies +window_anom_detect=50 +anom_factor=4.0 +#Drifts +delta=0.1 + [AVAILABILITY] diff --git a/src/psl/predictor/predictor_utils.py b/src/psl/predictor/predictor_utils.py index 09bae1d018d76facee24ab25ffdfb778bc1efa58..45459aa2ae7860dec34cbe9b5f9258591c930716 100644 --- a/src/psl/predictor/predictor_utils.py +++ b/src/psl/predictor/predictor_utils.py @@ -140,54 +140,344 @@ def data_preparing(dat,f_name,t_name): # # plt.savefig(path_out+lab_name) -def plot_integration_results(path_models,th,name): +def plot_integration_results(path_models,ths,names): #Loading persisted variables required for plotting + + #################################################### CPU_USAGE_IDLE + + #Real observations until this moment + with open(path_models + 'cpuUI_real_obs.pkl', 'rb') as f: + cpuUI_real_obs = pickle.load(f) + #Predictions until this moment + with open(path_models + 'cpuUI_forecasts.pkl', 'rb') as f: + cpuUI_forecasts = pickle.load(f) + #Mean Absolute Error (MAE) until this moment + with open(path_models + 'cpuUI_maes.pkl', 'rb') as f: + cpuUI_maes = pickle.load(f) + #Drifts detected until this moment + with open(path_models + 'cpuUI_drifts_detected.pkl', 'rb') as f: + cpuUI_drifts_detected = pickle.load(f) + #Anomalies detected until this moment + with open(path_models + 'cpuUI_anoms_detected.pkl', 'rb') as f: + cpuUI_anoms_detected = pickle.load(f) + + # Plot the results + fig, ax = plt.subplots(figsize=(10, 6)) + ax.grid(alpha=0.75) + ax.plot(cpuUI_real_obs, lw=3, color='blue', alpha=0.8, label='Ground truth') + ax.plot(cpuUI_forecasts, lw=3, color='green', alpha=0.8, label='Prediction') + + ax.plot(np.zeros(len(cpuUI_forecasts)), label='Drifts detected',linestyle='--', color='k') + for d in range(len(cpuUI_drifts_detected)): + if cpuUI_drifts_detected[d]==1: + ax.axvline(d, lw=1, color='k', alpha=0.8,linestyle='--') + + ax.plot(np.zeros(len(cpuUI_forecasts)), label='Anomalies detected',linestyle=':', color='k') + for a in range(len(cpuUI_anoms_detected)): + if cpuUI_anoms_detected[a]==1: + ax.axvline(a, lw=1, color='k', alpha=0.8,linestyle=':') + + # ax.plot(np.zeros(len(forecasts)), label='Threshold',linestyle='--', color='red') + ax.axhline(ths[0], lw=1, color='red', alpha=0.8,linestyle='--') + + ax.legend(loc='lower right') + cpuUI_res=np.round(np.nanmean(cpuUI_maes),3) + cpuUI_std_res=np.round(np.nanstd(cpuUI_maes),3) + ax.set_title('CPU_USAGE_IDLE - MAE+-std: '+str(cpuUI_res)+' +- '+str(cpuUI_std_res)) + plt.show() + + print('CPU_USAGE_IDLE - MAE+-std: '+str(cpuUI_res)+' +- '+str(cpuUI_std_res)) + + plt.savefig(path_models+names[0]+'.png') + + #################################################### CPU_USAGE_SYSTEM + + #Real observations until this moment + with open(path_models + 'cpuUS_real_obs.pkl', 'rb') as f: + cpuUS_real_obs = pickle.load(f) + #Predictions until this moment + with open(path_models + 'cpuUS_forecasts.pkl', 'rb') as f: + cpuUS_forecasts = pickle.load(f) + #Mean Absolute Error (MAE) until this moment + with open(path_models + 'cpuUS_maes.pkl', 'rb') as f: + cpuUS_maes = pickle.load(f) + #Drifts detected until this moment + with open(path_models + 'cpuUS_drifts_detected.pkl', 'rb') as f: + cpuUS_drifts_detected = pickle.load(f) + #Anomalies detected until this moment + with open(path_models + 'cpuUS_anoms_detected.pkl', 'rb') as f: + cpuUS_anoms_detected = pickle.load(f) + + + # Plot the results + fig, ax = plt.subplots(figsize=(10, 6)) + ax.grid(alpha=0.75) + ax.plot(cpuUS_real_obs, lw=3, color='blue', alpha=0.8, label='Ground truth') + ax.plot(cpuUS_forecasts, lw=3, color='green', alpha=0.8, label='Prediction') + + ax.plot(np.zeros(len(cpuUS_forecasts)), label='Drifts detected',linestyle='--', color='k') + for d in range(len(cpuUS_drifts_detected)): + if cpuUS_drifts_detected[d]==1: + ax.axvline(d, lw=1, color='k', alpha=0.8,linestyle='--') + + ax.plot(np.zeros(len(cpuUS_forecasts)), label='Anomalies detected',linestyle=':', color='k') + for a in range(len(cpuUS_anoms_detected)): + if cpuUS_anoms_detected[a]==1: + ax.axvline(a, lw=1, color='k', alpha=0.8,linestyle=':') + + # ax.plot(np.zeros(len(forecasts)), label='Threshold',linestyle='--', color='red') + ax.axhline(ths[1], lw=1, color='red', alpha=0.8,linestyle='--') + + ax.legend(loc='lower right') + cpuUS_res=np.round(np.nanmean(cpuUS_maes),3) + cpuUS_std_res=np.round(np.nanstd(cpuUS_maes),3) + ax.set_title('CPU_USAGE_SYSTEM - MAE+-std: '+str(cpuUS_res)+' +- '+str(cpuUS_std_res)) + plt.show() + + print('CPU_USAGE_SYSTEM - MAE+-std: '+str(cpuUS_res)+' +- '+str(cpuUS_std_res)) + + plt.savefig(path_models+names[1]+'.png') + + #################################################### CPU_USAGE_USER + + #Real observations until this moment + with open(path_models + 'cpuUU_real_obs.pkl', 'rb') as f: + cpuUU_real_obs = pickle.load(f) + #Predictions until this moment + with open(path_models + 'cpuUU_forecasts.pkl', 'rb') as f: + cpuUU_forecasts = pickle.load(f) + #Mean Absolute Error (MAE) until this moment + with open(path_models + 'cpuUU_maes.pkl', 'rb') as f: + cpuUU_maes = pickle.load(f) + #Drifts detected until this moment + with open(path_models + 'cpuUU_drifts_detected.pkl', 'rb') as f: + cpuUU_drifts_detected = pickle.load(f) + #Anomalies detected until this moment + with open(path_models + 'cpuUU_anoms_detected.pkl', 'rb') as f: + cpuUU_anoms_detected = pickle.load(f) + + + # Plot the results + fig, ax = plt.subplots(figsize=(10, 6)) + ax.grid(alpha=0.75) + ax.plot(cpuUU_real_obs, lw=3, color='blue', alpha=0.8, label='Ground truth') + ax.plot(cpuUU_forecasts, lw=3, color='green', alpha=0.8, label='Prediction') + + ax.plot(np.zeros(len(cpuUU_forecasts)), label='Drifts detected',linestyle='--', color='k') + for d in range(len(cpuUU_drifts_detected)): + if cpuUU_drifts_detected[d]==1: + ax.axvline(d, lw=1, color='k', alpha=0.8,linestyle='--') + + ax.plot(np.zeros(len(cpuUU_forecasts)), label='Anomalies detected',linestyle=':', color='k') + for a in range(len(cpuUU_anoms_detected)): + if cpuUU_anoms_detected[a]==1: + ax.axvline(a, lw=1, color='k', alpha=0.8,linestyle=':') + + # ax.plot(np.zeros(len(forecasts)), label='Threshold',linestyle='--', color='red') + ax.axhline(ths[2], lw=1, color='red', alpha=0.8,linestyle='--') + + ax.legend(loc='lower right') + cpuUU_res=np.round(np.nanmean(cpuUU_maes),3) + cpuUU_std_res=np.round(np.nanstd(cpuUU_maes),3) + ax.set_title('CPU_USAGE_USER - MAE+-std: '+str(cpuUU_res)+' +- '+str(cpuUU_std_res)) + plt.show() + + print('CPU_USAGE_USER - MAE+-std: '+str(cpuUU_res)+' +- '+str(cpuUU_std_res)) + + plt.savefig(path_models+names[2]+'.png') + + #################################################### MEM_FREE + + #Real observations until this moment + with open(path_models + 'memF_real_obs.pkl', 'rb') as f: + memF_real_obs = pickle.load(f) + #Predictions until this moment + with open(path_models + 'memF_forecasts.pkl', 'rb') as f: + memF_forecasts = pickle.load(f) + #Mean Absolute Error (MAE) until this moment + with open(path_models + 'memF_maes.pkl', 'rb') as f: + memF_maes = pickle.load(f) + #Drifts detected until this moment + with open(path_models + 'memF_drifts_detected.pkl', 'rb') as f: + memF_drifts_detected = pickle.load(f) + #Anomalies detected until this moment + with open(path_models + 'memF_anoms_detected.pkl', 'rb') as f: + memF_anoms_detected = pickle.load(f) + + + # Plot the results + fig, ax = plt.subplots(figsize=(10, 6)) + ax.grid(alpha=0.75) + ax.plot(memF_real_obs, lw=3, color='blue', alpha=0.8, label='Ground truth') + ax.plot(memF_forecasts, lw=3, color='green', alpha=0.8, label='Prediction') + + ax.plot(np.zeros(len(memF_forecasts)), label='Drifts detected',linestyle='--', color='k') + for d in range(len(memF_drifts_detected)): + if memF_drifts_detected[d]==1: + ax.axvline(d, lw=1, color='k', alpha=0.8,linestyle='--') + + ax.plot(np.zeros(len(memF_forecasts)), label='Anomalies detected',linestyle=':', color='k') + for a in range(len(memF_anoms_detected)): + if memF_anoms_detected[a]==1: + ax.axvline(a, lw=1, color='k', alpha=0.8,linestyle=':') + + # ax.plot(np.zeros(len(forecasts)), label='Threshold',linestyle='--', color='red') + ax.axhline(ths[3], lw=1, color='red', alpha=0.8,linestyle='--') + + ax.legend(loc='lower right') + memF_res=np.round(np.nanmean(memF_maes),3) + memF_std_res=np.round(np.nanstd(memF_maes),3) + ax.set_title('MEM FREE - MAE+-std: '+str(memF_res)+' +- '+str(memF_std_res)) + plt.show() + + print('MEM FREE - MAE+-std: '+str(memF_res)+' +- '+str(memF_std_res)) + + plt.savefig(path_models+names[3]+'.png') + + #################################################### MEM_USED_PERCENT + + #Real observations until this moment + with open(path_models + 'memUP_real_obs.pkl', 'rb') as f: + memUP_real_obs = pickle.load(f) + #Predictions until this moment + with open(path_models + 'memUP_forecasts.pkl', 'rb') as f: + memUP_forecasts = pickle.load(f) + #Mean Absolute Error (MAE) until this moment + with open(path_models + 'memUP_maes.pkl', 'rb') as f: + memUP_maes = pickle.load(f) + #Drifts detected until this moment + with open(path_models + 'memUP_drifts_detected.pkl', 'rb') as f: + memUP_drifts_detected = pickle.load(f) + #Anomalies detected until this moment + with open(path_models + 'memUP_anoms_detected.pkl', 'rb') as f: + memUP_anoms_detected = pickle.load(f) + + + # Plot the results + fig, ax = plt.subplots(figsize=(10, 6)) + ax.grid(alpha=0.75) + ax.plot(memUP_real_obs, lw=3, color='blue', alpha=0.8, label='Ground truth') + ax.plot(memUP_forecasts, lw=3, color='green', alpha=0.8, label='Prediction') + + ax.plot(np.zeros(len(memUP_forecasts)), label='Drifts detected',linestyle='--', color='k') + for d in range(len(memUP_drifts_detected)): + if memUP_drifts_detected[d]==1: + ax.axvline(d, lw=1, color='k', alpha=0.8,linestyle='--') + + ax.plot(np.zeros(len(memUP_forecasts)), label='Anomalies detected',linestyle=':', color='k') + for a in range(len(memUP_anoms_detected)): + if memUP_anoms_detected[a]==1: + ax.axvline(a, lw=1, color='k', alpha=0.8,linestyle=':') + + # ax.plot(np.zeros(len(forecasts)), label='Threshold',linestyle='--', color='red') + ax.axhline(ths[4], lw=1, color='red', alpha=0.8,linestyle='--') + + ax.legend(loc='lower right') + memUP_res=np.round(np.nanmean(memUP_maes),3) + memUP_std_res=np.round(np.nanstd(memUP_maes),3) + ax.set_title('MEM USED_PERCENT - MAE+-std: '+str(memUP_res)+' +- '+str(memUP_std_res)) + plt.show() + + print('MEM USED_PERCENT - MAE+-std: '+str(memUP_res)+' +- '+str(memUP_std_res)) + + plt.savefig(path_models+names[4]+'.png') + + #################################################### DISK_FREE + + #Real observations until this moment + with open(path_models + 'diskF_real_obs.pkl', 'rb') as f: + diskF_real_obs = pickle.load(f) + #Predictions until this moment + with open(path_models + 'diskF_forecasts.pkl', 'rb') as f: + diskF_forecasts = pickle.load(f) + #Mean Absolute Error (MAE) until this moment + with open(path_models + 'diskF_maes.pkl', 'rb') as f: + diskF_maes = pickle.load(f) + #Drifts detected until this moment + with open(path_models + 'diskF_drifts_detected.pkl', 'rb') as f: + diskF_drifts_detected = pickle.load(f) + #Anomalies detected until this moment + with open(path_models + 'diskF_anoms_detected.pkl', 'rb') as f: + diskF_anoms_detected = pickle.load(f) + + + # Plot the results + fig, ax = plt.subplots(figsize=(10, 6)) + ax.grid(alpha=0.75) + ax.plot(diskF_real_obs, lw=3, color='blue', alpha=0.8, label='Ground truth') + ax.plot(diskF_forecasts, lw=3, color='green', alpha=0.8, label='Prediction') + + ax.plot(np.zeros(len(diskF_forecasts)), label='Drifts detected',linestyle='--', color='k') + for d in range(len(diskF_drifts_detected)): + if diskF_drifts_detected[d]==1: + ax.axvline(d, lw=1, color='k', alpha=0.8,linestyle='--') + + ax.plot(np.zeros(len(diskF_forecasts)), label='Anomalies detected',linestyle=':', color='k') + for a in range(len(diskF_anoms_detected)): + if diskF_anoms_detected[a]==1: + ax.axvline(a, lw=1, color='k', alpha=0.8,linestyle=':') + + # ax.plot(np.zeros(len(forecasts)), label='Threshold',linestyle='--', color='red') + ax.axhline(ths[5], lw=1, color='red', alpha=0.8,linestyle='--') + + ax.legend(loc='lower right') + diskF_res=np.round(np.nanmean(diskF_maes),3) + diskF_std_res=np.round(np.nanstd(diskF_maes),3) + ax.set_title('DISK FREE - MAE+-std: '+str(diskF_res)+' +- '+str(diskF_std_res)) + plt.show() + + print('DISK FREE - MAE+-std: '+str(diskF_res)+' +- '+str(diskF_std_res)) + + plt.savefig(path_models+names[5]+'.png') + + #################################################### DISK_USED_PERCENT + #Real observations until this moment - with open(path_models + 'real_obs.pkl', 'rb') as f: - real_obs = pickle.load(f) + with open(path_models + 'diskUP_real_obs.pkl', 'rb') as f: + diskUP_real_obs = pickle.load(f) #Predictions until this moment - with open(path_models + 'forecasts.pkl', 'rb') as f: - forecasts = pickle.load(f) + with open(path_models + 'diskUP_forecasts.pkl', 'rb') as f: + diskUP_forecasts = pickle.load(f) #Mean Absolute Error (MAE) until this moment - with open(path_models + 'maes.pkl', 'rb') as f: - maes = pickle.load(f) + with open(path_models + 'diskUP_maes.pkl', 'rb') as f: + diskUP_maes = pickle.load(f) #Drifts detected until this moment - with open(path_models + 'drifts_detected.pkl', 'rb') as f: - drifts_detected = pickle.load(f) + with open(path_models + 'diskUP_drifts_detected.pkl', 'rb') as f: + diskUP_drifts_detected = pickle.load(f) #Anomalies detected until this moment - with open(path_models + 'anoms_detected.pkl', 'rb') as f: - anoms_detected = pickle.load(f) + with open(path_models + 'diskUP_anoms_detected.pkl', 'rb') as f: + diskUP_anoms_detected = pickle.load(f) # Plot the results fig, ax = plt.subplots(figsize=(10, 6)) ax.grid(alpha=0.75) - ax.plot(real_obs, lw=3, color='blue', alpha=0.8, label='Ground truth') - ax.plot(forecasts, lw=3, color='green', alpha=0.8, label='Prediction') + ax.plot(diskUP_real_obs, lw=3, color='blue', alpha=0.8, label='Ground truth') + ax.plot(diskUP_forecasts, lw=3, color='green', alpha=0.8, label='Prediction') - ax.plot(np.zeros(len(forecasts)), label='Drifts detected',linestyle='--', color='k') - for d in range(len(drifts_detected)): - if drifts_detected[d]==1: + ax.plot(np.zeros(len(diskUP_forecasts)), label='Drifts detected',linestyle='--', color='k') + for d in range(len(diskUP_drifts_detected)): + if diskUP_drifts_detected[d]==1: ax.axvline(d, lw=1, color='k', alpha=0.8,linestyle='--') - ax.plot(np.zeros(len(forecasts)), label='Anomalies detected',linestyle=':', color='k') - for a in range(len(anoms_detected)): - if anoms_detected[a]==1: + ax.plot(np.zeros(len(diskUP_forecasts)), label='Anomalies detected',linestyle=':', color='k') + for a in range(len(diskUP_anoms_detected)): + if diskUP_anoms_detected[a]==1: ax.axvline(a, lw=1, color='k', alpha=0.8,linestyle=':') # ax.plot(np.zeros(len(forecasts)), label='Threshold',linestyle='--', color='red') - ax.axhline(th, lw=1, color='red', alpha=0.8,linestyle='--') + ax.axhline(ths[6], lw=1, color='red', alpha=0.8,linestyle='--') ax.legend(loc='lower right') - res=np.round(np.nanmean(maes),3) - std_res=np.round(np.nanstd(maes),3) - ax.set_title('MAE+-std: '+str(res)+' +- '+str(std_res)) + diskUP_res=np.round(np.nanmean(diskUP_maes),3) + diskUP_std_res=np.round(np.nanstd(diskUP_maes),3) + ax.set_title('DISK USED PERCENT - MAE+-std: '+str(diskUP_res)+' +- '+str(diskUP_std_res)) plt.show() - print('MAE+-std: '+str(res)+' +- '+str(std_res)) + print('DISK USED PERCENT - MAE+-std: '+str(diskUP_res)+' +- '+str(diskUP_std_res)) - plt.savefig(path_models+name+'.png') + plt.savefig(path_models+names[6]+'.png') # def generate_outliers(labels): # diff --git a/src/psl/services/self_learning_service.py b/src/psl/services/self_learning_service.py index 2523a06c20a62334c6b8d3d24492340df06de453..9c6b9bd54eda5ddf03e9b79cc0b9f426533050ca 100644 --- a/src/psl/services/self_learning_service.py +++ b/src/psl/services/self_learning_service.py @@ -1,4 +1,5 @@ import logging +from psl.models.deployment import Deployment # noqa: E501 from psl.repository import deployments_repository @@ -8,7 +9,7 @@ def deployments_deployment_iddelete(deployment_id): # noqa: E501 return None, 204 -def deployments_post(body): # noqa: E501 - logging.info("start monitoring deployment: " + body) - deployments_repository.add(body, body) +def deployments_post(deployment): # noqa: E501 + logging.info("start monitoring deployment: " + deployment.deployment_id) + deployments_repository.add(deployment.deployment_id, deployment.deployment_id) return "do some magic!", 201 diff --git a/test_input_data/psl_data.csv b/test_input_data/psl_data.csv new file mode 100644 index 0000000000000000000000000000000000000000..b6a5411638e60f8340456dfb9b68492530c964b6 --- /dev/null +++ b/test_input_data/psl_data.csv @@ -0,0 +1,1729 @@ +_time;cpu_usage_idle;cpu_usage_system;cpu_usage_user;disk_free;disk_used_percent;mem_free;mem_used_percent +2022-03-03T11:20:00Z;86.04486018208894;3.2523556205060857;10.417961855340419;75957148951.27272;24.960946022060753;336815104;24.960946022060753 +2022-03-03T11:30:00Z;86.09526403666631;3.1191360348688453;10.510266681942825;75951704790.70967;24.966324378989572;334690171.9;24.966324378989572 +2022-03-03T11:40:00Z;85.99982845396688;3.0631379847982383;10.673499975828122;75947976968.25807;24.97000714320635;329988263.9;24.97000714320635 +2022-03-03T11:50:00Z;86.16887369498441;3.0379620836937757;10.527854384644451;75943798817.57378;24.974134792533054;323303793.3;24.974134792533054 +2022-03-03T12:00:00Z;85.31288301725779;3.1739201788378013;11.229233815189524;75939861470.96774;24.978024548383267;322473521.5;24.978024548383267 +2022-03-03T12:10:00Z;85.78674696113919;3.1387317275508657;10.764522379870948;75936095529.29033;24.981744971078328;320252102.2;24.981744971078328 +2022-03-03T12:20:00Z;86.1362570791883;3.120741633442709;10.476172707810573;75932082109.93549;24.98570988018513;317773890.1;24.98570988018513 +2022-03-03T12:30:00Z;85.96898511749984;3.191863725677705;10.556136873253221;75927923678.96774;24.989818048147736;316032495.5;24.989818048147736 +2022-03-03T12:40:00Z;86.29352048955401;3.0497561243680837;10.395862728690094;75924282586.2295;24.993415130954226;314444749.6;24.993415130954226 +2022-03-03T12:50:00Z;86.37724107989649;3.028717472252225;10.324704906434501;75920145573.16129;24.997502139895705;312410904.8;24.997502139895705 +2022-03-03T13:00:00Z;86.01478802957443;3.1995644111379766;10.510593089565942;75916179654.19354;25.001420122753167;310672020.6;25.001420122753167 +2022-03-03T13:10:00Z;85.9173538590818;3.041493642259494;10.750473606889512;75911800303.48387;25.00574654019811;308266017;25.00574654019811 +2022-03-03T13:20:00Z;85.10222226576936;3.1825554166902474;11.389582433219262;75907141565.93549;25.0103489675297;305631033.8;25.0103489675297 +2022-03-03T13:30:00Z;85.33457137502126;3.087086587100853;11.312350977409835;75901838963.6129;25.015587477234217;302412984.7;25.015587477234217 +2022-03-03T13:40:00Z;86.0309117193063;3.0394194156871417;10.656192160701297;75897784420.72131;25.019593012817083;299550587.9;25.019593012817083 +2022-03-03T13:50:00Z;86.36787037200799;3.042271081991661;10.315461110596193;75893954626.06451;25.023376516699777;297927184.5;25.023376516699777 +2022-03-03T14:00:00Z;85.1113594324111;3.118465944029379;11.47458546021703;75890402535.2258;25.02688567337378;295158486.7;25.02688567337378 +2022-03-03T14:10:00Z;83.44411578809877;3.1970906054333965;13.055262633035916;75931228490.32259;24.986553182087516;293768555.4;24.986553182087516 +2022-03-03T14:20:00Z;86.13090081490286;3.1108425792726027;10.50002798606324;75928471684.12903;24.989276666731417;292007801.7;24.989276666731417 +2022-03-03T14:30:00Z;86.37660987634375;3.092765643663567;10.248060480967398;75924313205.5082;24.993384881771128;296340563.9;24.993384881771128 +2022-03-03T14:40:00Z;86.37338718436892;3.0401352678701143;10.31006038212067;75920797897.44263;24.996857700265814;294641664;24.996857700265814 +2022-03-03T14:50:00Z;86.24356020768799;3.0963618616645694;10.386758257651536;75916569765.16129;25.00103472706139;295648619.4;25.00103472706139 +2022-03-03T15:00:00Z;86.06150934290477;2.9772732796110577;10.698049462503677;75913000431.48387;25.0045609181597;310874838.7;25.0045609181597 +2022-03-03T15:10:00Z;86.2420724429166;3.039221001856729;10.470183798729838;75929370161.54839;24.988389049219442;336701638.2;24.988389049219442 +2022-03-03T15:20:00Z;86.23415312711404;3.064372969119142;10.411675637072499;75925445995.35484;24.992265783968996;334627146.3;24.992265783968996 +2022-03-03T15:30:00Z;86.22914671219804;2.9842580702946107;10.524695605092784;75921681894.81967;24.9959843877757;332056098.1;24.9959843877757 +2022-03-03T15:40:00Z;85.73460870455865;3.0616385869725877;10.92730021222423;75917288348.90323;25.00032482884979;330426830.5;25.00032482884979 +2022-03-03T15:50:00Z;85.13707734928778;3.1301192509007314;11.450186340439338;75913680896;25.003888678426378;329053877.7;25.003888678426378 +2022-03-03T16:00:00Z;83.74504149573657;3.4107282722879484;12.350924908839394;75566409265.54839;25.34696283250214;325207601.5;25.34696283250214 +2022-03-03T16:10:00Z;86.01199647418179;3.104409421815316;10.598418688830126;75545263929.80646;25.367852584316527;323778692.1;25.367852584316527 +2022-03-03T16:20:00Z;86.14813897937846;3.082230568940598;10.499245938879016;75541496072.25807;25.371574899725395;322227629.4;25.371574899725395 +2022-03-03T16:30:00Z;86.33882576072872;3.0138691103891087;10.377393505045475;75537301041.54839;25.375719225048407;320185707.4;25.375719225048407 +2022-03-03T16:40:00Z;83.45866021079779;3.719040326381003;12.251594531499308;75288889890.13333;25.621127827887282;318407475.2;25.621127827887282 +2022-03-03T16:50:00Z;85.6584758966946;3.1650709458955566;10.87797871532624;74272456972.59016;26.625275108525816;316227253.7;26.625275108525816 +2022-03-03T17:00:00Z;85.63137207404539;3.161156033430292;10.902485569634312;74268517078.70967;26.62916738086156;313254746.8;26.62916738086156 +2022-03-03T17:10:00Z;85.87911263833514;3.15986925854202;10.65820253687275;74282427689.29033;26.61542490799838;311433546.3;26.61542490799838 +2022-03-03T17:20:00Z;85.84815551252626;3.1119806570196724;10.76656302435204;74278430389.67741;26.619373892202763;309674975;26.619373892202763 +2022-03-03T17:30:00Z;85.70225183717706;3.108662602100188;10.92999296046678;74281033661.93549;26.61680208572781;307137767.2;26.61680208572781 +2022-03-03T17:40:00Z;86.15761176907031;3.0552305753867603;10.517141629853995;74324184617.96721;26.574172695820852;304596331.4;26.574172695820852 +2022-03-03T17:50:00Z;86.38875625072087;3.009455350653421;10.344968259906937;74320600823.74193;26.577713172682202;301412620.6;26.577713172682202 +2022-03-03T18:00:00Z;85.49162843968523;3.0634019405155613;11.103394118776013;74316393703.2258;26.58186944168203;299123414.7;26.58186944168203 +2022-03-03T18:10:00Z;86.19453344578959;2.9555883021115306;10.588119213115032;74312645665.03226;26.58557217729284;296747999;26.58557217729284 +2022-03-03T18:20:00Z;86.17964523332677;3.0449669413906535;10.492021707580594;74305362382.45161;26.592767426749294;296276892.9;26.592767426749294 +2022-03-03T18:30:00Z;86.11897243903888;3.0377263060975883;10.563614541959554;74296294366.96774;26.601725837020908;295740118.7;26.601725837020908 +2022-03-03T18:40:00Z;86.25477795390476;3.0081027307335066;10.46272656316346;74292396296.25807;26.605576791703005;295366920.3;26.605576791703005 +2022-03-03T18:50:00Z;86.20979352496327;2.9624771259311116;10.560172208984941;74288300168.53334;26.60962340948264;292800814.2;26.60962340948264 +2022-03-03T19:00:00Z;86.22423050548099;3.0555197039295083;10.474046348684391;74284594737.54839;26.613284052878694;289760156.9;26.613284052878694 +2022-03-03T19:10:00Z;86.5684635502061;3.0444816146549796;10.112762067148635;74302276442.83871;26.59581606657296;289544588.4;26.59581606657296 +2022-03-03T19:20:00Z;86.07598962305353;3.0396429048757354;10.592554039557047;74299439302.19354;26.598618914665003;287220703;26.598618914665003 +2022-03-03T19:30:00Z;86.17006287901779;3.0446782259706673;10.496514967823781;74292650314.32259;26.60532584395789;285841275.9;26.60532584395789 +2022-03-03T19:40:00Z;86.39659949612799;3.046126769229952;10.288655408864837;74289042200.7742;26.608890346194396;284027738.8;26.608890346194396 +2022-03-03T19:50:00Z;86.3480147251925;2.997519267060076;10.402235902928252;74284805875.40984;26.613075467043107;282372360.3;26.613075467043107 +2022-03-03T20:00:00Z;86.14219477674739;3.0581146019404644;10.542841281788359;74281068376.13115;26.616767791123046;279160932.7;26.616767791123046 +2022-03-03T20:10:00Z;85.34239271998418;3.049337423626569;11.332891024553524;74277024999.2258;26.620762295683075;278905492.6;26.620762295683075 +2022-03-03T20:20:00Z;86.1694652391634;3.132228824073518;10.422080625223801;74271408392.25807;26.62631101465482;277383960.8;26.62631101465482 +2022-03-03T20:30:00Z;86.33918577149436;3.0377826934734227;10.358265227382171;74260851877.16129;26.636739933026597;273667435.4;26.636739933026597 +2022-03-03T20:40:00Z;86.20827277398813;3.002207053457417;10.517160947440232;74256832313.80646;26.6407109118708;270025628.9;26.6407109118708 +2022-03-03T20:50:00Z;86.07458062247322;3.1391891096546694;10.489161833127305;74253067825.54839;26.644429898714;269109578.3;26.644429898714 +2022-03-03T21:00:00Z;86.17916555984074;3.0651739423004782;10.463950170600647;74265326575.21312;26.632319320703974;268697197.1;26.632319320703974 +2022-03-03T21:10:00Z;86.26584677958637;3.037805364160205;10.419412759315568;74300549053.93549;26.59752257650573;268463120.8;26.59752257650573 +2022-03-03T21:20:00Z;86.22603926561726;3.027837906739824;10.47241653545339;74296234842.83871;26.60178464168107;268820083.6;26.60178464168107 +2022-03-03T21:30:00Z;86.37628532517866;2.993001430575892;10.363701671296035;74290282165.67741;26.60766536876189;267756511;26.60766536876189 +2022-03-03T21:40:00Z;86.32178895411852;2.9842659852317515;10.433352303194983;74285881476.12903;26.612012867122736;267545831.2;26.612012867122736 +2022-03-03T21:50:00Z;86.17198977402649;3.049477439546646;10.506469802517193;74282230486.70967;26.615619726989063;268325392.5;26.615619726989063 +2022-03-03T22:00:00Z;86.38455616042651;2.976049646388229;10.351844508261125;74278108985.80646;26.61969141126128;265279025.5;26.61969141126128 +2022-03-03T22:10:00Z;86.44582133328107;2.9599163478198482;10.327329387684957;74274281198.93333;26.6234729316284;267224920.1;26.6234729316284 +2022-03-03T22:20:00Z;85.56163431894767;3.0582958214817553;11.080157822668463;74270332994.06451;26.627373414497455;266259290.8;26.627373414497455 +2022-03-03T22:30:00Z;86.20076503752453;3.017639108527722;10.530142656663156;74266366348.3871;26.63129211528085;277558106.8;26.63129211528085 +2022-03-03T22:40:00Z;86.23210552356643;3.002051243080894;10.48574868313866;74262548215.74193;26.63506409811079;309802809.8;26.63506409811079 +2022-03-03T22:50:00Z;86.14046557467516;3.023283438518013;10.568688424932065;74258409075.6129;26.639153208403272;308353552.5;26.639153208403272 +2022-03-03T23:00:00Z;86.32991074321919;3.0548417979099027;10.339039430306848;74254752008.25807;26.642766072740987;306425591.7;26.642766072740987 +2022-03-03T23:10:00Z;85.99758389107795;3.09072222608517;10.621441592242121;74280349035.35484;26.61747843721874;306163051.4;26.61747843721874 +2022-03-03T23:20:00Z;86.32269566368662;2.973553053024747;10.44896254750997;74270279176.39345;26.627426581673696;304524909.1;26.627426581673696 +2022-03-03T23:30:00Z;86.3375039289168;2.9738609152686117;10.421921533993254;74262612232.25807;26.635000855363064;301758464;26.635000855363064 +2022-03-03T23:40:00Z;86.42641847344893;3.0301578479462967;10.252311002160441;74258906343.2258;26.63866195126999;299918699.4;26.63866195126999 +2022-03-03T23:50:00Z;86.20210095224232;3.018180851574722;10.491425272394789;74254745467.87097;26.642772534074357;297535752.3;26.642772534074357 +2022-03-04T00:00:00Z;86.2062571501817;2.9627752488242263;10.514282563195914;74250965058.06451;26.646507250021983;296564537.8;26.646507250021983 +2022-03-04T00:10:00Z;86.38057804998928;2.936423491923178;10.389360875677253;74247309179.87097;26.650118939571822;295639898.8;26.650118939571822 +2022-03-04T00:20:00Z;86.6729934831482;2.9556464709060966;10.09308191358221;74243471863.60655;26.653909874148365;293507877.8;26.653909874148365 +2022-03-04T00:30:00Z;86.62202566506386;3.1994950288587836;9.910290486441534;74264263629.63934;26.6333694184418;291352643.1;26.6333694184418 +2022-03-04T00:40:00Z;86.1184070554887;3.0051770709175827;10.60260979375165;74291226227.6129;26.606732717714372;289228139.4;26.606732717714372 +2022-03-04T00:50:00Z;86.70693536616211;3.0998097731159544;9.904698237333864;74287552578.06451;26.610361963816466;286735723.4;26.610361963816466 +2022-03-04T01:00:00Z;86.87508722306072;3.0190810096195517;9.812717899312227;74283297230.45161;26.614565876991573;284341941.7;26.614565876991573 +2022-03-04T01:10:00Z;86.78448596950123;3.0815629988036837;9.85441606230656;74279308254.96774;26.61850663768076;281349203.9;26.61850663768076 +2022-03-04T01:20:00Z;86.8648037282151;2.9803150583023483;9.879433361882656;74274974290.58064;26.622788217388173;279641649.5;26.622788217388173 +2022-03-04T01:30:00Z;86.7806392990734;3.030195838035019;9.927480093180733;74268958317.11476;26.628731475710396;277775657.3;26.628731475710396 +2022-03-04T01:40:00Z;86.89421037431319;3.010125844926408;9.781190496269964;74264650851.09677;26.63298687733478;275557607.2;26.63298687733478 +2022-03-04T01:50:00Z;86.76963285480142;3.04223847600166;9.89743795539258;74260916620.3871;26.63667597235294;272568452.1;26.63667597235294 +2022-03-04T02:00:00Z;86.98101211183506;2.987067488949917;9.760432735627077;74256873670.19354;26.64067005535886;270614461.9;26.64067005535886 +2022-03-04T02:10:00Z;86.58898087692859;3.0242197097255525;10.076558549288174;74252963245.41936;26.64453321478174;269694136.7;26.64453321478174 +2022-03-04T02:20:00Z;86.50076271000675;3.0078868476719585;10.212546759585633;74249028508.90323;26.648420392090255;266784432.3;26.648420392090255 +2022-03-04T02:30:00Z;86.46896623023929;3.0405769783436707;10.189863476368087;74244896062.95082;26.652502889118715;266746252.4;26.652502889118715 +2022-03-04T02:40:00Z;85.79890193534251;3.1206837789252804;10.804061762365228;74241161017.80646;26.656192788727484;267019759.5;26.656192788727484 +2022-03-04T02:50:00Z;86.3048319674637;3.076152067877147;10.31883804288586;74236911682.06451;26.660390762697173;267720571.9;26.660390762697173 +2022-03-04T03:00:00Z;87.03743668685648;3.110081173001123;9.551811272728418;74233311694.45161;26.66394723721648;267727508.6;26.66394723721648 +2022-03-04T03:10:00Z;86.70397356527523;3.195009172411027;9.808956321707857;74251034029.41936;26.646439112324735;269533184;26.646439112324735 +2022-03-04T03:20:00Z;86.93706115620749;3.1572915360808347;9.595963960195528;74248201645.41936;26.64923726126525;269242905.2;26.64923726126525 +2022-03-04T03:30:00Z;87.07531590028344;3.051494735945547;9.597530145206981;74241491816.91803;26.655865987988744;268767826.6;26.655865987988744 +2022-03-04T03:40:00Z;87.15314201300883;3.037582438511749;9.523024446970265;74237671054.68852;26.659640568619213;268052215.7;26.659640568619213 +2022-03-04T03:50:00Z;87.22780479744179;2.9478136235938823;9.528559351524253;74233606936.7742;26.663655563491407;267228523.4;26.663655563491407 +2022-03-04T04:00:00Z;86.46863772827905;3.205824975283093;10.064328625907772;74262090124.3871;26.635516652509907;265621570.1;26.635516652509907 +2022-03-04T04:10:00Z;86.83224409218174;3.024020592917004;9.846355104590053;74281534497.03226;26.61630730423088;264113713.5;26.61630730423088 +2022-03-04T04:20:00Z;86.74078160461345;3.0106211121492574;9.977262306990252;74277502843.87097;26.620290226751894;264590369;26.620290226751894 +2022-03-04T04:30:00Z;86.56942045795589;3.0631542403357446;10.089828463318465;74273738818.06451;26.624008756733133;264100880.8;26.624008756733133 +2022-03-04T04:40:00Z;86.91766451197749;2.891052248564751;9.924582870391154;74269552162.13333;26.6281448085037;264025781.7;26.6281448085037 +2022-03-04T04:50:00Z;86.41991199842249;3.086105885444252;10.221887800499767;74265968177.54839;26.631685473423843;264573258.3;26.631685473423843 +2022-03-04T05:00:00Z;85.7563696182113;3.041738172492799;10.907583019919636;74261651720.25807;26.63594975764296;264523776;26.63594975764296 +2022-03-04T05:10:00Z;86.60081356430591;3.0461395233497766;10.072250479618225;74259037150.96774;26.63853272460281;265595012.1;26.63853272460281 +2022-03-04T05:20:00Z;86.47065932918355;3.0154562525074327;10.212975530056488;74254760464.51613;26.642757718693826;265273476.1;26.642757718693826 +2022-03-04T05:30:00Z;86.76467478671334;2.975243163820145;9.961720840471525;74243118575.48387;26.65425889207325;263948657.3;26.65425889207325 +2022-03-04T05:40:00Z;86.72546593006916;3.053819397695769;9.943535490562663;74236070614.70967;26.66122166406078;264966342.2;26.66122166406078 +2022-03-04T05:50:00Z;86.77584102416219;3.029281115461853;9.927442931384395;74232246070.55737;26.664999980901886;264064297.3;26.664999980901886 +2022-03-04T06:00:00Z;86.7320530710925;3.0659859991764478;9.905461574329241;74228279296;26.66891880900745;272113994.3;26.66891880900745 +2022-03-04T06:10:00Z;86.81436590111278;3.0328105222199513;9.865147232327292;74224236940.3871;26.672912304619427;306564393.3;26.672912304619427 +2022-03-04T06:20:00Z;86.65828241610677;3.131098733164508;9.922521860115978;74218538149.16129;26.678542214487123;303763654.2;26.678542214487123 +2022-03-04T06:30:00Z;86.80999860541542;3.089291980110709;9.825402015988734;74214363003.87097;26.682666894746077;302315217.8;26.682666894746077 +2022-03-04T06:40:00Z;86.68789747456727;3.0924014046522625;9.933300335878478;74210803117.41936;26.686183752807313;301666371.1;26.686183752807313 +2022-03-04T06:50:00Z;87.03457134520201;3.028074692946663;9.636058717871737;74206507746.62296;26.690427205405214;299009519.5;26.690427205405214 +2022-03-04T07:00:00Z;87.09279324972367;3.083068276627893;9.539921975397208;74202897894.81967;26.69399342488632;297162619.9;26.69399342488632 +2022-03-04T07:10:00Z;86.30010554854597;3.0946399110466127;10.316864422318481;74220785201.54839;26.67632232224926;294239463.2;26.67632232224926 +2022-03-04T07:20:00Z;86.90416061324996;3.1472346599798717;9.648944376503847;74216548616.25807;26.6805076998822;293289851.9;26.6805076998822 +2022-03-04T07:30:00Z;86.44876151505912;3.155674290632523;9.949513256314017;75761804981.67741;25.153928866745062;290589927.2;25.153928866745062 +2022-03-04T07:40:00Z;86.67270650228849;3.0645783637364787;9.969665690410578;76174215300.12903;24.74650335677494;289754867.4;24.74650335677494 +2022-03-04T07:50:00Z;86.74959692744856;3.1098147632320137;9.858358602227735;76170382369.03226;24.750289959187423;285740659.6;24.750289959187423 +2022-03-04T08:00:00Z;86.79116259877232;3.0138880940490878;9.91440104850812;76166283127.46666;24.754339653170884;282600811.4;24.754339653170884 +2022-03-04T08:10:00Z;86.7864180388041;3.13134276074858;9.797440887526635;76162606773.67741;24.75797157082765;281281436.9;24.75797157082765 +2022-03-04T08:20:00Z;86.69971398833712;3.1572123079024723;9.872200399865907;76158348585.29033;24.762178290440474;279627115.4;24.762178290440474 +2022-03-04T08:30:00Z;87.40022355782021;2.99267399781601;9.296284705030171;76154820872.25807;24.765663363962865;277639035.9;24.765663363962865 +2022-03-04T08:40:00Z;86.91576229978514;3.008481576722283;9.79887790633301;76150794173.93549;24.76964139153437;274248142.5;24.76964139153437 +2022-03-04T08:50:00Z;86.85148914308657;3.0154432806278866;9.8490608731244;76146601059.09677;24.773783824143564;273264102.8;24.773783824143564 +2022-03-04T09:00:00Z;86.79959881224966;3.057777512071218;9.855576541520486;76142941283.09677;24.77739936438702;271358612.6;24.77739936438702 +2022-03-04T09:10:00Z;86.62273090934751;3.02476423677534;10.072492879569483;76138213308.85246;24.78207019154975;269437654.7;24.78207019154975 +2022-03-04T09:20:00Z;86.40453707646068;3.049276095502585;10.284534829243222;76134706605.41936;24.785534509416266;266032821.7;24.785534509416266 +2022-03-04T09:30:00Z;87.12274937689305;3.0981992620585697;9.495672205023583;76127950649.80646;24.792208805712388;269777754.8;24.792208805712388 +2022-03-04T09:40:00Z;86.65794046163597;3.0004174487304613;10.051791556820492;76124284333.41936;24.7958308072892;272102697.3;24.7958308072892 +2022-03-04T09:50:00Z;86.7505087996756;2.9765765368679307;9.98794016100765;76120159132.90323;24.799906146457058;283669890.1;24.799906146457058 +2022-03-04T10:00:00Z;86.99396040120227;3.0358335318657477;9.6825881734525;76116285272.13115;24.80373318382736;285014874.8;24.80373318382736 +2022-03-04T10:10:00Z;86.74841080630412;3.084654255711262;9.903931076824797;76112344987.27869;24.80762584240939;282180508.9;24.80762584240939 +2022-03-04T10:20:00Z;86.76711586259131;3.095491368030733;9.854081659001512;76108529928.25807;24.81139478876574;279866401;24.81139478876574 +2022-03-04T10:30:00Z;86.50881847497949;3.0149940635157075;10.189037660018156;76104593540.12903;24.815283597724086;277334610.6;24.815283597724086 +2022-03-04T10:40:00Z;86.52989102494047;3.1098834372353825;10.082443740262274;76100353453.41936;24.81947243445469;277158945;24.81947243445469 +2022-03-04T10:50:00Z;86.77430389490651;3.1915002037532343;9.732394763365175;76096827193.80646;24.82295607212522;277643858.6;24.82295607212522 +2022-03-04T11:00:00Z;86.642424642388;3.132575112650716;9.922107315756145;76143114240;24.77722849801596;277683418.2;24.77722849801596 +2022-03-04T11:10:00Z;86.69030915525754;3.0188506538982365;9.995219105068772;76184885214.42622;24.735962409860242;278196818.6;24.735962409860242 +2022-03-04T11:20:00Z;86.82281914513753;3.08404332478752;9.806979719522223;76176760303.48387;24.743989114906274;276593036.4;24.743989114906274 +2022-03-04T11:30:00Z;86.30784753777638;2.97726054100049;10.455360547715399;76170525662.96774;24.750148397247465;279376070.2;24.750148397247465 +2022-03-04T11:40:00Z;86.82482103171114;3.0372097616331275;9.849773329261692;76166472142.45161;24.754152922812334;278478055.2;24.754152922812334 +2022-03-04T11:50:00Z;86.78076861997413;3.094766930505411;9.836918102044521;76162497833.29033;24.75807919445098;277630381.4;24.75807919445098 +2022-03-04T12:00:00Z;86.63045416806513;3.013167037667019;10.06807957925415;76158522797.41936;24.76200618401554;276459251.4;24.76200618401554 +2022-03-04T12:10:00Z;86.23489137102158;3.074154098788531;10.39609898660798;76154692442.83871;24.76579024105427;276799686.2;24.76579024105427 +2022-03-04T12:20:00Z;86.47360241530002;3.0359291980872576;10.183402822917012;76150677173.67741;24.769756977608914;276057649.5;24.769756977608914 +2022-03-04T12:30:00Z;86.43310178741976;3.0537450441396476;10.20643964388174;76146819138.06451;24.773568381098944;277546809.8;24.773568381098944 +2022-03-04T12:40:00Z;86.95300141678983;3.019722528597737;9.73844409053215;76142802019.09677;24.77753694510137;276684007.2;24.77753694510137 +2022-03-04T12:50:00Z;87.15232237469918;3.0931361316295876;9.481043270564447;76138782257.54839;24.781508119743556;276957448.3;24.781508119743556 +2022-03-04T13:00:00Z;87.11727940512887;3.0082118903649877;9.599175615863885;76135060798.95082;24.78518459702628;275229511.3;24.78518459702628 +2022-03-04T13:10:00Z;87.31160203395005;2.9850574007505335;9.417195771599438;76130624677.16129;24.789567099358354;277825099.5;24.789567099358354 +2022-03-04T13:20:00Z;86.22876736409987;3.033423812586363;10.435641066403123;76126507074.06451;24.79363493293696;276817061.2;24.79363493293696 +2022-03-04T13:30:00Z;87.20647009142793;3.031186437565606;9.492962631233354;76120250830.45161;24.799815557258043;282276698.8;24.799815557258043 +2022-03-04T13:40:00Z;87.00906312065722;3.0063839552906866;9.704841430688141;76116215543.74193;24.803802069408697;323569267.6;24.803802069408697 +2022-03-04T13:50:00Z;86.76922229791798;3.138815420291028;9.803264437798418;76112187986.58064;24.807780945438125;321161282.1;24.807780945438125 +2022-03-04T14:00:00Z;86.54662380767778;3.062322692349049;10.121120490699306;76108421384.25807;24.811502020793107;318995885.4;24.811502020793107 +2022-03-04T14:10:00Z;86.4982982294087;2.951788991920685;10.258978145177569;76104435947.01639;24.81543928600688;317644397.1;24.81543928600688 +2022-03-04T14:20:00Z;86.68126513519007;2.9878113339638057;10.045141863618053;76101231715.09677;24.818604788336735;314875904;24.818604788336735 +2022-03-04T14:30:00Z;86.61123125389504;3.0185772918955354;10.072103212784649;76152297075.6129;24.768156655447605;312931162.8;24.768156655447605 +2022-03-04T14:40:00Z;86.66755852004698;3.0569161700397323;9.968903156638575;76148260203.35484;24.77214473398212;310916657.5;24.77214473398212 +2022-03-04T14:50:00Z;86.75330016085466;3.0372090639789127;9.90060547968332;76144216790.70967;24.776139273849974;307809775.5;24.776139273849974 +2022-03-04T15:00:00Z;86.7078146709941;3.0845991116987506;9.903508109367202;76140528805.16129;24.779782682672668;306151556.1;24.779782682672668 +2022-03-04T15:10:00Z;86.70821131178432;2.973639417838653;10.034308932031015;76158406723.14754;24.762120855296242;303844583.2;24.762120855296242 +2022-03-04T15:20:00Z;86.78107533770732;3.0105240743204784;9.919601089064765;76155385083.80328;24.765105972049383;301628432.8;24.765105972049383 +2022-03-04T15:30:00Z;86.0112827062805;3.0421564774069974;10.637339228051909;76148956126.96774;24.771457222006294;298344514.1;24.771457222006294 +2022-03-04T15:40:00Z;86.60139426004622;3.053769855582516;10.074660871626909;76144745372.90323;24.775617080635772;296755926.7;24.775617080635772 +2022-03-04T15:50:00Z;86.66226284459225;3.0291410076507566;10.007934820746689;76141122130.58064;24.779196528784798;295589491.6;24.779196528784798 +2022-03-04T16:00:00Z;86.98939168100239;3.02319397123893;9.699041231668714;76136964822.70967;24.783303587225515;294531270.2;24.783303587225515 +2022-03-04T16:10:00Z;87.08647859954372;3.078327993172402;9.542405804390862;76133136648.25807;24.787085490486465;292132665.8;24.787085490486465 +2022-03-04T16:20:00Z;86.7059864774067;3.045066709673736;9.977253989875665;76129195998.42622;24.79097850963636;290311923.4;24.79097850963636 +2022-03-04T16:30:00Z;86.46465540995581;3.053453114425753;10.204175738698247;76125191597.41936;24.794934509400083;288019506.4;24.794934509400083 +2022-03-04T16:40:00Z;86.50637650162456;3.10820267556129;10.099679911885548;76121383836.90323;24.798696245469042;285554093.4;24.798696245469042 +2022-03-04T16:50:00Z;86.60021455802536;3.048347944136276;10.061532460523257;76117228709.16129;24.80280115013195;283541570.1;24.80280115013195 +2022-03-04T17:00:00Z;86.9059420734778;3.0052848114450956;9.810776903021909;76113587827.6129;24.80639802430126;280302559;24.80639802430126 +2022-03-04T17:10:00Z;86.97361376790508;3.145955260953574;9.585401053419911;76110133446.19354;24.809810652570835;278493448.3;24.809810652570835 +2022-03-04T17:20:00Z;86.92840160549842;3.09151746675168;9.698775878228775;76106697562.83871;24.813205006362214;276655797.7;24.813205006362214 +2022-03-04T17:30:00Z;87.27312053154967;2.9908369608447583;9.45721606538646;76099872290.13333;24.819947781914276;270524013.1;24.819947781914276 +2022-03-04T17:40:00Z;86.54778911475739;3.0632504283425335;10.106040739256448;76089651200;24.83004532960819;266641209.8;24.83004532960819 +2022-03-04T17:50:00Z;86.75288579951497;3.0672381984849313;9.871612002063346;76092545948.90323;24.827185569569785;266824340.6;24.827185569569785 +2022-03-04T18:00:00Z;87.18940539907884;3.1438191335374275;9.371798268593734;76135367052.3871;24.784882045278966;264665550.5;24.784882045278966 +2022-03-04T18:10:00Z;87.16084069866076;3.109468450865866;9.443070998916653;76131362155.35484;24.78883853507261;262681170.6;24.78883853507261 +2022-03-04T18:20:00Z;87.12640670377814;3.032895471453612;9.559879086411481;76127411299.09677;24.79274163728355;261696545;24.79274163728355 +2022-03-04T18:30:00Z;86.73411167899054;3.0567348600680835;9.928707116749147;76123570506.32259;24.796536006349267;263623647;24.796536006349267 +2022-03-04T18:40:00Z;86.91130724436995;2.9286539560234726;9.87916034638987;76119464976.78688;24.800591912300064;263403656.5;24.800591912300064 +2022-03-04T18:50:00Z;86.82972863126015;2.968465035295827;9.918845835817004;76115794382.45161;24.804218140117438;262343118.5;24.804218140117438 +2022-03-04T19:00:00Z;86.74165488995975;3.0538643720603638;9.931056141206827;76111543461.16129;24.80841768047097;261687229.9;24.80841768047097 +2022-03-04T19:10:00Z;86.70426506692725;3.038860442678118;9.970699316625451;76130114526.96774;24.79007108336038;261958358.7;24.79007108336038 +2022-03-04T19:20:00Z;86.74066739450795;3.014978450541377;9.986194913032021;76126537331.6129;24.79360504111193;263225079.7;24.79360504111193 +2022-03-04T19:30:00Z;86.54505261650829;3.085929954137272;10.084975088467129;76120484368.51613;24.799584841970912;264311444.6;24.799584841970912 +2022-03-04T19:40:00Z;86.46264703334695;3.0543452385906837;10.184332084422309;76116186632.39345;24.803830631305377;264649677.6;24.803830631305377 +2022-03-04T19:50:00Z;85.97786012916752;3.040581245561238;10.66858761257938;76107996655.48387;24.811921615865487;264769602.1;24.811921615865487 +2022-03-04T20:00:00Z;86.7397920786817;3.0555928680013036;9.917351405647677;76100026037.67741;24.819795892718616;263473019.9;24.819795892718616 +2022-03-04T20:10:00Z;86.52953119740596;3.1317527430658707;10.048718638241308;76096131468.3871;24.823643388303065;263956017.5;24.823643388303065 +2022-03-04T20:20:00Z;86.81941441858159;3.087450267591227;9.81232074220788;76092241589.67741;24.827486250001968;263375112.3;24.827486250001968 +2022-03-04T20:30:00Z;86.888435639587;2.935027271280792;9.87614439434981;76088202961.83606;24.831476062900016;263588698.8;24.831476062900016 +2022-03-04T20:40:00Z;86.95570384930029;3.013204821090777;9.75700848774588;76084438804.98361;24.835194722343296;264862468.2;24.835194722343296 +2022-03-04T20:50:00Z;86.94248275803612;3.003449021048088;9.78952413085002;76080237865.29033;24.839344885227966;264981655.1;24.839344885227966 +2022-03-04T21:00:00Z;86.86938756595667;3.0084368822016154;9.851250373301735;76076665426.58064;24.842874143827977;265754293.7;24.842874143827977 +2022-03-04T21:10:00Z;86.73038615337975;3.1078758178449033;9.88789259432314;76071935471.48387;24.84754692790057;307532370.6;24.84754692790057 +2022-03-04T21:20:00Z;86.41181649605063;3.160113443154931;10.151291990098914;76085419041.03226;24.834226334419565;305079329;24.834226334419565 +2022-03-04T21:30:00Z;86.6109834046621;3.075147206158984;10.01331916260034;76114421760;24.80557417166495;309991093.7;24.80557417166495 +2022-03-04T21:40:00Z;86.68796445836378;3.0922513191330023;9.916811813470753;76105131662.68852;24.81475197945845;308575450.2;24.81475197945845 +2022-03-04T21:50:00Z;86.80337814575974;3.0440428054444544;9.881625551044259;76101021696;24.818812268930163;306239620.1;24.818812268930163 +2022-03-04T22:00:00Z;86.30979736506102;3.053883998483449;10.372718034220629;76097161149.93549;24.82262615252794;301460843.4;24.82262615252794 +2022-03-04T22:10:00Z;86.84250014597822;3.0555111772902626;9.817961017416316;76093246893.41936;24.826493097378467;297982018.1;24.826493097378467 +2022-03-04T22:20:00Z;86.51732604244253;3.0189126900707506;10.163945720348469;76089211738.83871;24.830479478997137;299068911.5;24.830479478997137 +2022-03-04T22:30:00Z;86.56386895821935;3.0439590152924954;10.084576274742005;76085467003.87097;24.83417895130826;295930318.5;24.83417895130826 +2022-03-04T22:40:00Z;86.54463157987938;3.1918078969895207;9.96916589084647;76081254994.58064;24.838340049991615;292767677.9;24.838340049991615 +2022-03-04T22:50:00Z;86.7180358501985;3.01765472148344;9.985499273010262;76077699686.4;24.841852385119502;290788200.9;24.841852385119502 +2022-03-04T23:00:00Z;86.6373253365463;3.110579057336295;9.927783484543356;76073355990.70967;24.84614357850775;289968590.5;24.84614357850775 +2022-03-04T23:10:00Z;86.45785431120706;3.0540322913130864;10.2009870233564;76087165588.64516;24.83250089734868;288107817.3;24.83250089734868 +2022-03-04T23:20:00Z;86.88728868522492;2.9088715923499278;9.945876696657837;76078091032.7742;24.841465768953636;286719207.2;24.841465768953636 +2022-03-04T23:30:00Z;86.50955849343536;3.0581690175750884;10.140588461341697;76072395742.96774;24.847092219723677;283166323.6;24.847092219723677 +2022-03-04T23:40:00Z;86.72473044170424;3.0468581863119244;9.956882010532773;76068297761.03226;24.85114066930218;282070049;24.85114066930218 +2022-03-04T23:50:00Z;86.71723005775938;3.0690232125395176;9.938176097930382;76064447653.16129;24.854944240872992;280581417.3;24.854944240872992 +2022-03-05T00:00:00Z;86.72593578898987;3.040019971829609;9.938387641605292;76060499699.40984;24.858844475659943;278056422.8;24.858844475659943 +2022-03-05T00:10:00Z;85.97134573570034;3.0177935887889187;10.751724984604033;76056674832.51613;24.862623111341488;278312167.2;24.862623111341488 +2022-03-05T00:20:00Z;86.89349380526822;2.9699146836760324;9.861593914696893;76052944763.87097;24.866308094602054;279354004.6;24.866308094602054 +2022-03-05T00:30:00Z;86.87316221954593;3.0798703967431376;9.758923136305901;76048771930.83871;24.870430490551243;278628616.3;24.870430490551243 +2022-03-05T00:40:00Z;86.75317138259896;3.136811395631067;9.799877807970029;76045158862.45161;24.873999887737266;276328778.3;24.873999887737266 +2022-03-05T00:50:00Z;86.49405129801985;3.112451641854952;10.127355608290616;76065959737.80646;24.85345043281313;273001703.2;24.85345043281313 +2022-03-05T01:00:00Z;86.8320581291233;3.016512983516745;9.87694282627315;76093011241.29033;24.826725901177365;272722155;24.826725901177365 +2022-03-05T01:10:00Z;86.72251061587974;3.0488810635615;9.948813974754291;76088312149.33333;24.831368195153324;269263394.1;24.831368195153324 +2022-03-05T01:20:00Z;86.77884339835877;3.0682571363931213;9.88408013467673;76084712348.90323;24.834924484752328;266534449.5;24.834924484752328 +2022-03-05T01:30:00Z;86.74663166440023;3.0751666971997684;9.863332362137546;76078148971.35484;24.84140853067731;264489092.1;24.84140853067731 +2022-03-05T01:40:00Z;86.85712601130489;3.0739146012720946;9.803659056670273;76074239735.74193;24.845270515312322;262864631.7;24.845270515312322 +2022-03-05T01:50:00Z;86.91326561778385;3.1051670418978454;9.706761217854098;76070235367.2258;24.84922648297802;263671147.4;24.84922648297802 +2022-03-05T02:00:00Z;86.83728493265673;3.08436599463971;9.810102957459971;76066291910.19354;24.85312227539767;260900467.6;24.85312227539767 +2022-03-05T02:10:00Z;86.70421211669287;3.128951603446621;9.904396014443993;76061508574.96774;24.857847794393056;258661034.7;24.857847794393056 +2022-03-05T02:20:00Z;86.74348114776325;3.14960096988197;9.842044928441085;76049918657.04918;24.869297624834278;256353180.9;24.869297624834278 +2022-03-05T02:30:00Z;86.19047119430256;3.0735425760439283;10.439869818786027;76046281827.09677;24.872890496379288;255850429.9;24.872890496379288 +2022-03-05T02:40:00Z;86.96166522885237;2.9636047410701614;9.800442296655737;76042015644.90323;24.87710511317733;254416763.9;24.87710511317733 +2022-03-05T02:50:00Z;86.86255121666412;3.0654269954971434;9.791285780624754;76038477824;24.880600172396733;252586116.1;24.880600172396733 +2022-03-05T03:00:00Z;86.70600504456425;3.0662537796595175;9.918821744175448;76034155685.16129;24.884870069491274;248755563.4;24.884870069491274 +2022-03-05T03:10:00Z;86.59515700090603;3.028453708039256;10.02581204389715;76052616423.2258;24.866632466589884;247105604.3;24.866632466589884 +2022-03-05T03:20:00Z;86.8165219564152;3.042502800349269;9.866916920207068;76049139476.98361;24.870067386941017;245207172.1;24.870067386941017 +2022-03-05T03:30:00Z;86.73222179144734;3.052874765260744;9.923925312435218;76042929806.68852;24.87620200087653;244964451.1;24.87620200087653 +2022-03-05T03:40:00Z;86.88946585658032;3.0727480449133218;9.769352619904303;76038829485.41936;24.880252761513184;244967688.3;24.880252761513184 +2022-03-05T03:50:00Z;86.79724952737529;3.089051748697238;9.840427774523857;76034933462.70967;24.88410169294949;242360187.9;24.88410169294949 +2022-03-05T04:00:00Z;86.85189880163414;3.1026286554448035;9.76283533034159;76031045962.32259;24.887942205072626;240386444.4;24.887942205072626 +2022-03-05T04:10:00Z;86.80595096567271;3.044527504229282;9.856056883089542;76026996273.54839;24.89194294520988;238238026.3;24.89194294520988 +2022-03-05T04:20:00Z;86.8392336658582;3.042265123915129;9.849078149452104;76055561381.16129;24.863723104396406;236908006.8;24.863723104396406 +2022-03-05T04:30:00Z;86.85174262373526;2.9802162135542254;9.893131883782855;76074664540.32787;24.84485084534453;246442578.6;24.84485084534453 +2022-03-05T04:40:00Z;86.76246483640637;3.015155870049376;9.952301395429531;76071120565.67741;24.848351983930733;294615832.8;24.848351983930733 +2022-03-05T04:50:00Z;86.37604218244772;3.044150196563362;10.273039833306878;76066823333.16129;24.852597275745737;295102464;24.852597275745737 +2022-03-05T05:00:00Z;86.80980889608966;3.0586739293082585;9.836383638652084;76063262587.87097;24.8561149822649;292664287;24.8561149822649 +2022-03-05T05:10:00Z;86.78369150080047;3.087752673772038;9.821690383695264;76077183306.32259;24.84236252370471;291208423.2;24.84236252370471 +2022-03-05T05:20:00Z;86.53763448308261;3.0566579541420076;10.1141246299894;76074064136.25807;24.845443992323123;294139131.8;24.845443992323123 +2022-03-05T05:30:00Z;86.56748514402209;3.0408681059108575;10.115827012230433;76067571910.19354;24.851857746773085;295683303.2;24.851857746773085 +2022-03-05T05:40:00Z;86.6963334005126;3.015171615827007;10.02483720470454;76063567462.4;24.855813792757957;294423254.7;24.855813792757957 +2022-03-05T05:50:00Z;86.73132780181567;3.0675635971847344;9.92398808233335;76059708382.96774;24.859626227450693;293893285.2;24.859626227450693 +2022-03-05T06:00:00Z;86.94882019137314;3.006447351924431;9.785300873705928;76055655523.09677;24.863630100355632;292522084.7;24.863630100355632 +2022-03-05T06:10:00Z;86.53924219718498;3.1490016689349;10.016111906340862;76051918319.48387;24.8673221323435;290558414.5;24.8673221323435 +2022-03-05T06:20:00Z;86.62931681338205;3.1330108591442247;9.962644153559346;76047726195.6129;24.871463585962793;290115451.9;24.871463585962793 +2022-03-05T06:30:00Z;86.69146620395682;3.0899914880008383;9.949520396009392;76044120856.7742;24.875025347027577;289096538.8;24.875025347027577 +2022-03-05T06:40:00Z;86.5498672483048;2.993956015833792;10.173285071001454;76039804861.93549;24.879289174384734;285046255.5;24.879289174384734 +2022-03-05T06:50:00Z;86.70859419733185;2.973741696130453;10.045855983515002;76036253192.39345;24.882797914854294;284021206;24.882797914854294 +2022-03-05T07:00:00Z;85.95353200606459;3.1425986310004803;10.631486631880819;76032011825.54839;24.886988016247255;283055355.8;24.886988016247255 +2022-03-05T07:10:00Z;86.84029873568288;3.0405443904346625;9.829528601291772;76050466485.67741;24.868756417817263;281931908.1;24.868756417817263 +2022-03-05T07:20:00Z;86.67577800384835;3.0774952813482654;9.949020311804025;76047101027.09677;24.87208119805954;279594281.3;24.87208119805954 +2022-03-05T07:30:00Z;86.6550791487404;3.052888028241218;9.97748932526715;76040806862.45161;24.87829928506091;278592677.2;24.87829928506091 +2022-03-05T07:40:00Z;86.85387380214927;3.038262572779916;9.829213825652378;76034218380.3871;24.884808132063434;276528689.5;24.884808132063434 +2022-03-05T07:50:00Z;86.64643946374161;3.0781370414700384;10.006540644694129;76064504110.16394;24.854888466266825;274961969.5;24.854888466266825 +2022-03-05T08:00:00Z;86.6258351165169;3.068491654224262;10.027945278598663;76076200068.12903;24.84333387748638;270188879.7;24.84333387748638 +2022-03-05T08:10:00Z;86.63444803912579;3.050581630190458;10.06353407402679;76072065882.83871;24.847418092829347;266497585.5;24.847418092829347 +2022-03-05T08:20:00Z;86.44042062365165;2.997587642372198;10.270082853161473;76068450568.25807;24.850989709059153;264074008.8;24.850989709059153 +2022-03-05T08:30:00Z;86.4446760195348;3.078835152667079;10.19466260353789;76064114291.6129;24.85527357307633;262203061.7;24.85527357307633 +2022-03-05T08:40:00Z;86.73513748863247;3.0191311013537883;9.937463093106299;76060595034.83871;24.85875029255155;261823455;24.85875029255155 +2022-03-05T08:50:00Z;86.52344118721838;3.077021139203878;10.122211922661412;76056307645.93549;24.86298585973351;263448642.1;24.86298585973351 +2022-03-05T09:00:00Z;86.7240948074418;3.0366200381550468;9.96585318698506;76052648618.66667;24.866600660295706;263302969.8;24.866600660295706 +2022-03-05T09:10:00Z;85.94252456906499;3.099964131012582;10.66078178235268;76048100913.54839;24.871093397247492;264189314.1;24.871093397247492 +2022-03-05T09:20:00Z;86.37053329256528;3.071310297842545;10.273057987071162;76044276306.58064;24.874871776144808;262916162.1;24.874871776144808 +2022-03-05T09:30:00Z;86.61771540439842;2.987458175045624;10.082775895477061;76037845124.12903;24.881225224816735;262696035.1;24.881225224816735 +2022-03-05T09:40:00Z;86.65376469448252;3.032726224205845;10.03027330542733;76033809969.54839;24.885211606435412;264376716.4;24.885211606435412 +2022-03-05T09:50:00Z;86.6075075928006;3.0074411608108225;10.088442228586548;76029985098.32259;24.888990246396695;263710389.7;24.888990246396695 +2022-03-05T10:00:00Z;86.5199943114806;3.0670575531919124;10.116271785691795;76025887357.90164;24.893038457379852;263598080;24.893038457379852 +2022-03-05T10:10:00Z;86.5327269743238;3.038941168131839;10.147531684264553;76022205658.2295;24.896675656303756;263006711.6;24.896675656303756 +2022-03-05T10:20:00Z;86.47625992783848;3.175898855802075;10.07145248759849;76017938365.93549;24.900891369784475;262662804.6;24.900891369784475 +2022-03-05T10:30:00Z;86.31245901211769;3.266927150179408;10.138530227671582;76014458880;24.904328799131594;263913802.3;24.904328799131594 +2022-03-05T10:40:00Z;86.69589775531757;3.027691983650574;9.993247857498083;76010139846.19354;24.90859562872446;262859346.6;24.90859562872446 +2022-03-05T10:50:00Z;86.73461782317024;3.0727724967252295;9.906391393079453;76006510459.87097;24.912181146610884;260978820.1;24.912181146610884 +2022-03-05T11:00:00Z;86.7807600564964;3.063895187327469;9.863589465465555;76002331945.29033;24.916309155435517;261513216;24.916309155435517 +2022-03-05T11:10:00Z;86.5523733594766;3.0463928089857206;10.120375329644189;76021982795.54099;24.89689582524828;261668335.5;24.89689582524828 +2022-03-05T11:20:00Z;86.50259716112991;3.1025794827993547;10.12824652497409;76067212387.09677;24.852212924309857;263003287.1;24.852212924309857 +2022-03-05T11:30:00Z;86.14088781375267;3.0937351332417937;10.48542991610834;76068021479.2258;24.851413611687114;262488658.6;24.851413611687114 +2022-03-05T11:40:00Z;86.49239174644806;3.1473229660960733;10.0731556167121;76064094208;24.855293413938362;260684040.3;24.855293413938362 +2022-03-05T11:50:00Z;86.70950944516;2.9961905759131877;10.019156959109967;76060018159.48387;24.859320195207044;258562576.5;24.859320195207044 +2022-03-05T12:00:00Z;86.26928224342129;3.1376713804096594;10.299347143417359;76056327861.67741;24.862965888339506;255920788.6;24.862965888339506 +2022-03-05T12:10:00Z;86.70978979231454;3.0030563798895185;9.992672347417304;76051399316.64516;24.867834861988648;293719667.6;24.867834861988648 +2022-03-05T12:20:00Z;86.6944994586484;3.083217224417812;9.935891184809671;76033156300.8;24.885857374281787;297797598.4;24.885857374281787 +2022-03-05T12:30:00Z;86.57981632204749;3.093475910423843;10.025519219461954;76027452779.35484;24.891491957194603;295177635.7;24.891491957194603 +2022-03-05T12:40:00Z;86.75178850717533;3.0610996373330597;9.897977934891092;76023885031.2258;24.89501658190907;292833346.1;24.89501658190907 +2022-03-05T12:50:00Z;86.80272264000185;3.0355953715622195;9.891058621766554;76019647653.16129;24.899202742733937;291708531.6;24.899202742733937 +2022-03-05T13:00:00Z;86.57929288116489;3.02043247095791;10.137547786128946;76015936611.09677;24.902868929388358;289964824.8;24.902868929388358 +2022-03-05T13:10:00Z;86.41287590154434;2.9465167545554998;10.356770713289066;76011423876.12903;24.907327118874246;287923959.7;24.907327118874246 +2022-03-05T13:20:00Z;86.57383929802015;3.0419301606340636;10.076606392609873;76007504268.3871;24.911199350270245;286365828.1;24.911199350270245 +2022-03-05T13:30:00Z;86.5023337232912;3.047856807336825;10.167152862400625;76001097828.72131;24.917528355222707;285526989.6;24.917528355222707 +2022-03-05T13:40:00Z;85.59348459164582;3.096677102535941;11.023407620764754;75996991818.32259;24.921584736224347;284370415.5;24.921584736224347 +2022-03-05T13:50:00Z;86.45216255325742;3.1190672749304116;10.142991285099773;75993212994.06451;24.92531788578813;282997660.9;24.92531788578813 +2022-03-05T14:00:00Z;86.63025596009582;3.146541401811546;9.940365206601697;75988997813.67741;24.92948211723917;281772296.3;24.92948211723917 +2022-03-05T14:10:00Z;86.85914849102933;3.0797429434968286;9.793830897074765;75985421477.16129;24.9330152265328;278620556.4;24.9330152265328 +2022-03-05T14:20:00Z;86.75124133355538;3.068891485133923;9.899873569137293;75981085662.96774;24.937298633688012;277111114.3;24.937298633688012 +2022-03-05T14:30:00Z;86.57888761105784;3.1182893157611096;10.00465559044239;75977563499.35484;24.94077822486695;274443759.5;24.94077822486695 +2022-03-05T14:40:00Z;86.1952873081455;3.117994534820855;10.369091427368037;75973844727.74193;24.944452047642617;271939147.5;24.944452047642617 +2022-03-05T14:50:00Z;86.4101491116449;3.1781290460196048;10.117064691458738;76027271168;24.891671373410805;271357489.5;24.891671373410805 +2022-03-05T15:00:00Z;86.62387207690422;3.0930367671105192;9.976761891192666;76023160303.48387;24.895732549858067;270224483.1;24.895732549858067 +2022-03-05T15:10:00Z;86.77262469635224;3.0226114685324044;9.938653366278366;76041370326.70967;24.877742631402118;268309471;24.877742631402118 +2022-03-05T15:20:00Z;86.62530454275664;3.1252423484257545;9.962653127341891;76038172936.25807;24.88090137495686;266663341.4;24.88090137495686 +2022-03-05T15:30:00Z;86.78965227820966;3.0355384781692334;9.907754133973105;76031698679.74193;24.887297377056573;264981933.4;24.887297377056573 +2022-03-05T15:40:00Z;85.97874333825396;3.0615369474155636;10.66837752894242;76027842493.93549;24.89110695309878;264378133;24.89110695309878 +2022-03-05T15:50:00Z;86.81070445632207;3.1068386066289473;9.809739358399415;76023676795.87097;24.895222300320675;264111893;24.895222300320675 +2022-03-05T16:00:00Z;86.65008493931221;3.065752475862931;9.976619959134807;76020063661.41936;24.898791762772692;261452965.2;24.898791762772692 +2022-03-05T16:10:00Z;86.42619016793604;3.095448279308823;10.201889085299198;76015753876.64516;24.903049455126467;258702170.8;24.903049455126467 +2022-03-05T16:20:00Z;86.71508916231802;3.004367002390839;9.989397293062208;76012290316.59016;24.90647115108939;257549279;24.90647115108939 +2022-03-05T16:30:00Z;86.45153585254891;3.037099200465674;10.22300732015244;76007965410.62296;24.910743781866145;256155846.2;24.910743781866145 +2022-03-05T16:40:00Z;86.48524849722693;3.0500082615259116;10.17970476665123;76003510932.64516;24.91514441851502;254440547.1;24.91514441851502 +2022-03-05T16:50:00Z;86.4819633950347;3.100714749865822;10.141430471511468;75991773514.32259;24.926739966521104;251685770.5;24.926739966521104 +2022-03-05T17:00:00Z;86.53499805424322;3.1152568856211347;10.050121182174093;75987961657.80646;24.930505749081664;251970460.9;24.930505749081664 +2022-03-05T17:10:00Z;86.60990814162054;3.0703006906606882;10.021362707229732;75984871357.93549;24.9335586964609;251643507.6;24.9335586964609 +2022-03-05T17:20:00Z;86.30743180830706;3.126156602941227;10.22319317167317;75980935564.3871;24.937446918025305;252692281.8;24.937446918025305 +2022-03-05T17:30:00Z;86.55002661604752;3.126897757737554;10.049994852625735;75974697027.14754;24.943610049990184;252035600.5;24.943610049990184 +2022-03-05T17:40:00Z;86.41828591267995;3.0996974119003737;10.16540615111295;75970484290.06451;24.947771867669402;251946611.6;24.947771867669402 +2022-03-05T17:50:00Z;86.08636617580412;3.071841247912784;10.53710267915664;75966813150.96774;24.951398633663732;252360043.4;24.951398633663732 +2022-03-05T18:00:00Z;86.7617113621962;3.0481486935663558;9.888501038146687;75962517636.12903;24.955642228562905;250461388.8;24.955642228562905 +2022-03-05T18:10:00Z;86.54423211164841;3.26064336442973;9.893740912033074;75967964259.09677;24.95026143899251;251616751.5;24.95026143899251 +2022-03-05T18:20:00Z;86.90019255360986;3.1047101082464694;9.712151844086101;76010275740.90323;24.90846137657577;252085413.2;24.90846137657577 +2022-03-05T18:30:00Z;86.46123541338918;3.1227611553046066;10.13540519377846;76006499691.35484;24.91219178496783;251471211.4;24.91219178496783 +2022-03-05T18:40:00Z;86.7730654201448;3.0184651638293998;9.926450060317;76002477806.93333;24.91616505682394;251575989.7;24.91616505682394 +2022-03-05T18:50:00Z;86.66313194983046;3.0395194190349613;9.998797926021771;75998541361.54839;24.920053922346145;251733817.8;24.920053922346145 +2022-03-05T19:00:00Z;86.7469502884789;3.0538042695081784;9.912110521053476;75994661260.3871;24.923887124678014;251219027.9;24.923887124678014 +2022-03-05T19:10:00Z;86.28916944748785;3.013251703577327;10.408984243492766;76012629487.48387;24.906136079758365;251346205.4;24.906136079758365 +2022-03-05T19:20:00Z;86.61648909908263;3.004013603104463;10.102166652369426;76009647863.74193;24.909081664578256;251905387.4;24.909081664578256 +2022-03-05T19:30:00Z;86.57783291609856;3.0542846493061577;10.07884280781257;76003011484.90323;24.915637829426082;251019396.1;24.915637829426082 +2022-03-05T19:40:00Z;86.45332674388273;3.1162504634153527;10.108611346067365;75999343129.18033;24.919261845689228;284588494.5;24.919261845689228 +2022-03-05T19:50:00Z;85.97675402838703;3.143080403445569;10.586884620168382;75995018933.67741;24.92353377458906;290643373.4;24.92353377458906 +2022-03-05T20:00:00Z;86.57923629151693;3.097700634974043;10.033995800385064;75991429780.64516;24.927079545485427;287911407.5;24.927079545485427 +2022-03-05T20:10:00Z;86.86881034218219;3.10422901772363;9.715270266043792;75987160030.96774;24.931297686647124;286018845.4;24.931297686647124 +2022-03-05T20:20:00Z;86.84081740464434;3.1366190270243384;9.733903194952331;75983415362.06451;24.934997093692253;284345112.8;24.934997093692253 +2022-03-05T20:30:00Z;86.72327125762675;3.137080856743553;9.838536581123662;75979314076.90323;24.939048806570447;282608144.5;24.939048806570447 +2022-03-05T20:40:00Z;86.64059714748826;3.049621086506089;10.008102424942356;75975422354.88524;24.94289348929757;278385168.5;24.94289348929757 +2022-03-05T20:50:00Z;86.7498753756652;3.0768600070718612;9.879538414478098;75971436544;24.946831123638688;277495543.7;24.946831123638688 +2022-03-05T21:00:00Z;86.45651197375078;3.189420170862663;10.049917776722639;75967395311.48387;24.95082350972877;275574717.9;24.95082350972877 +2022-03-05T21:10:00Z;86.51461717206318;2.9563484357543044;10.240295222841667;75963142870.70967;24.955024551200147;274246404.2;24.955024551200147 +2022-03-05T21:20:00Z;86.55584102226814;3.0649533388679346;10.089190443327634;75955408631.74193;24.96266530632843;273354884.1;24.96266530632843 +2022-03-05T21:30:00Z;86.63578760811028;3.0521233070541416;10.024664311072955;75944451699.6129;24.97348980188698;270394929.5;24.97348980188698 +2022-03-05T21:40:00Z;86.46147624204501;3.1644046376346275;10.081058629814777;75957099024.51613;24.960995345352035;268489034.3;24.960995345352035 +2022-03-05T21:50:00Z;86.49350898292107;3.0594763140565333;10.16326583061164;75992188894.42622;24.92632960712177;266249513.3;24.92632960712177 +2022-03-05T22:00:00Z;86.49569580303582;3.1282754727234896;10.100192961923804;75987886542.45161;24.93057995651629;264404992;24.93057995651629 +2022-03-05T22:10:00Z;86.52266548634276;3.0265800953193054;10.161366128159136;75984221745.54839;24.934200456975258;261774369;24.934200456975258 +2022-03-05T22:20:00Z;86.21609251520312;3.1500970415804344;10.35711565291692;75980101103.48387;24.93827129278955;261505024;24.93827129278955 +2022-03-05T22:30:00Z;86.49027363335811;3.0738378862425244;10.169314382461007;75976272862.96774;24.942053261316506;260073538.1;24.942053261316506 +2022-03-05T22:40:00Z;86.48455965948072;3.069609975560845;10.153351798465472;75972302385.54839;24.945975747527516;253950810.8;24.945975747527516 +2022-03-05T22:50:00Z;86.7435256825627;2.9980832786551987;9.963609791023528;75968350107.27869;24.949880254562213;253058147.1;24.949880254562213 +2022-03-05T23:00:00Z;86.46492479540102;3.117165391746159;10.132274983692175;75964503865.80646;24.953680006467486;252528970.3;24.953680006467486 +2022-03-05T23:10:00Z;86.37119117593514;3.1483850930690434;10.163952484266012;76009598645.67741;24.909130287743423;253452618.3;24.909130287743423 +2022-03-05T23:20:00Z;86.70086279800114;3.143199517440225;9.818204138356034;76007580176.51613;24.911124359643676;253865257.3;24.911124359643676 +2022-03-05T23:30:00Z;87.1311448402347;3.1425467838577985;9.435437545487586;76000829043.6129;24.91779389152227;253186786.6;24.91779389152227 +2022-03-05T23:40:00Z;87.05778212840507;3.0949202453035562;9.533451091159987;75997242082.62296;24.92133749687158;252454317.4;24.92133749687158 +2022-03-05T23:50:00Z;86.4302184021682;3.152593215402521;10.139598801632431;75992931955.6129;24.9255955273246;252776580.1;24.9255955273246 +2022-03-06T00:00:00Z;86.95618693993397;3.165161162917604;9.607016197544336;75989331373.41936;24.929152589237855;252114415.5;24.929152589237855 +2022-03-06T00:10:00Z;87.07819373688581;3.124915357416947;9.505936535397085;75985346229.67741;24.933089564499415;252956672;24.933089564499415 +2022-03-06T00:20:00Z;87.22973396392518;3.0042815329698063;9.479026310597702;75981625476.12903;24.936765345254894;252290081;24.936765345254894 +2022-03-06T00:30:00Z;87.17582295690008;3.0792747459257304;9.44254345572853;75977607894.70967;24.940734366119298;249039955.9;24.940734366119298 +2022-03-06T00:40:00Z;87.0019684554672;3.144838269358565;9.565837841461338;75973677452.3871;24.944617301138234;246372484.1;24.944617301138234 +2022-03-06T00:50:00Z;86.95027172897456;3.176412269361941;9.564842993225643;75969830710.55737;24.948417547353177;244249236.6;24.948417547353177 +2022-03-06T01:00:00Z;87.04603899317677;3.0842487043932576;9.591696497420022;75965741056;24.952457770206703;242710990.5;24.952457770206703 +2022-03-06T01:10:00Z;86.89623608122935;3.099153485353498;9.710204610677604;75986689057.03226;24.931762967914988;241218064.5;24.931762967914988 +2022-03-06T01:20:00Z;86.98939833710325;3.1317567715688184;9.584746563628686;76012905042.58064;24.905863855299355;239314217.3;24.905863855299355 +2022-03-06T01:30:00Z;87.16264404771094;3.0832651982694603;9.441642502245728;76006896342.70967;24.91179992794268;238189468.9;24.91179992794268 +2022-03-06T01:40:00Z;87.03186830707739;3.0729953867755095;9.599273790756262;76002502788.12903;24.916140377576248;236669269.3;24.916140377576248 +2022-03-06T01:50:00Z;87.00297646451038;3.0637100209423926;9.63452108045281;75998956023.60655;24.91964427231326;235046251.4;24.91964427231326 +2022-03-06T02:00:00Z;86.7770770510005;3.0418379737430334;9.901223473112529;75994715433.29033;24.923833606563328;232849672.3;24.923833606563328 +2022-03-06T02:10:00Z;86.23847238745283;3.0585671065514988;10.416177516679095;75990976049.54839;24.927527792328977;231666588.9;24.927527792328977 +2022-03-06T02:20:00Z;86.76780895338709;3.094125425163288;9.858806475199788;75986902841.80646;24.93155176715992;230207421.9;24.93155176715992 +2022-03-06T02:30:00Z;86.67156598027545;3.1561614261300073;9.897274268765749;75983023995.87097;24.935383729437923;227798841.8;24.935383729437923 +2022-03-06T02:40:00Z;86.93901402265483;3.1034348672541574;9.678191760944905;75979127180.3871;24.939233444066154;225729569;24.939233444066154 +2022-03-06T02:50:00Z;86.98403508183975;3.055082356549613;9.702439268985271;75975087269.16129;24.943224524836342;221961299.9;24.943224524836342 +2022-03-06T03:00:00Z;86.93497758365294;3.0913803345093585;9.675256310063;75971338374.29507;24.946928106765203;220464425.3;24.946928106765203 +2022-03-06T03:10:00Z;87.1283014821771;3.0343417542790094;9.53083476341674;75989153924.12903;24.92932789369647;253311372.4;24.92932789369647 +2022-03-06T03:20:00Z;86.93496826418894;3.1406769144118565;9.647079858473726;75981307705.80646;24.937079274683768;265369864.3;24.937079274683768 +2022-03-06T03:30:00Z;87.22015253705678;2.9977553922416424;9.523422358594871;75971167265.03226;24.947097147828305;261979631.5;24.947097147828305 +2022-03-06T03:40:00Z;86.81968163932397;3.039897388686091;9.867321965390913;75967574478.45161;24.950646508354318;264726197.7;24.950646508354318 +2022-03-06T03:50:00Z;87.0565654746665;3.029048191669713;9.62339804620906;75963309617.54839;24.954859819832496;265310075.9;24.954859819832496 +2022-03-06T04:00:00Z;87.13481112716973;3.116786797800443;9.467658448237314;75959629924.72131;24.958495036168095;264966815.5;24.958495036168095 +2022-03-06T04:10:00Z;86.42840439711082;3.0429068798631755;10.254474753456279;75955542016;24.9625335342875;263442960.5;24.9625335342875 +2022-03-06T04:20:00Z;86.7762576729987;3.1679265400510044;9.76551907814689;75951687019.35484;24.966341935541823;262328914.6;24.966341935541823 +2022-03-06T04:30:00Z;87.002532264611;3.0359538867932923;9.700449221647549;75947751291.87097;24.970230091840257;260827400.3;24.970230091840257 +2022-03-06T04:40:00Z;86.61481388628117;3.191538646048683;9.918522975228177;75976841216;24.941491777974182;259173409;24.941491777974182 +2022-03-06T04:50:00Z;87.1275271326779;3.0239932582580473;9.581307540767325;75995425494.70967;24.92313212766489;250460226.1;24.92313212766489 +2022-03-06T05:00:00Z;87.04107339928369;3.00057018743617;9.667432326863963;75991298115.14754;24.927209619540598;245487582.4;24.927209619540598 +2022-03-06T05:10:00Z;87.07594257191208;3.2213054124094866;9.365726866692908;75988520557.11476;24.929953605196015;240762417.5;24.929953605196015 +2022-03-06T05:20:00Z;86.90396896300133;3.1339516262729967;9.650417993540001;75984250153.29033;24.934172392598047;242228521.3;24.934172392598047 +2022-03-06T05:30:00Z;87.10806889958111;3.049043225392072;9.565233424002104;75978347024.51613;24.940004170183705;237176435.6;24.940004170183705 +2022-03-06T05:40:00Z;87.09725570790184;3.1429347456655283;9.474281211728433;75973966088.25807;24.94433215401251;233951694.5;24.94433215401251 +2022-03-06T05:50:00Z;86.79749596505906;3.097996192084228;9.827515874588498;75970341656.7742;24.947912776949426;230963860.6;24.947912776949426 +2022-03-06T06:00:00Z;86.86776894023411;3.161171554974272;9.672934119980608;75966188444.90323;24.952015788898542;235917245.9;24.952015788898542 +2022-03-06T06:10:00Z;87.21736239718352;3.0411154822025632;9.470511754369788;75962433133.11476;24.955725710188222;234120328.5;24.955725710188222 +2022-03-06T06:20:00Z;86.88858612332551;3.065594890109778;9.776759048818645;75958405053.93549;24.959705101925994;222442198.7;24.959705101925994 +2022-03-06T06:30:00Z;86.73225847969633;3.1070971616504477;9.85464618412184;75954416474.83871;24.963645471019237;210143958.7;24.963645471019237 +2022-03-06T06:40:00Z;86.68371248167915;3.125272339026229;9.876766005181581;75950599927.74193;24.967415887465332;215021700.1;24.967415887465332 +2022-03-06T06:50:00Z;86.76025225724668;3.0527874006844704;9.813030560635966;75946437598.96774;24.971527906121537;215671246.5;24.971527906121537 +2022-03-06T07:00:00Z;86.84781262553588;3.0226577822682787;9.860569825708179;75942838404.12903;24.97508359744893;216745719.7;24.97508359744893 +2022-03-06T07:10:00Z;87.04976681698157;3.0173141153599574;9.647831359574019;75960544421.16129;24.95759159325758;215543279.5;24.95759159325758 +2022-03-06T07:20:00Z;87.23364751303092;3.033230793268567;9.450882176422121;75957808742.4;24.96029420583677;214190852.2;24.96029420583677 +2022-03-06T07:30:00Z;87.29273116677905;3.0483669028045592;9.371317090369976;75951044475.87097;24.96697671259489;211757980.9;24.96697671259489 +2022-03-06T07:40:00Z;87.21111768492449;3.095634114410143;9.398940752031098;75947304629.67741;24.970671355222482;207350156.4;24.970671355222482 +2022-03-06T07:50:00Z;86.84011292812185;3.0800269728793173;9.777005165747445;75943195416.7742;24.97473090001991;198859412.6;24.97473090001991 +2022-03-06T08:00:00Z;87.27987784097348;3.1252923335161804;9.32037958468154;75939371338.32259;24.978508756789246;226922892.4;24.978508756789246 +2022-03-06T08:10:00Z;86.86945208786499;3.251868049933493;9.59357532774883;75976637010.58064;24.941693515160182;228543058.6;24.941693515160182 +2022-03-06T08:20:00Z;87.21870046756383;3.0813296110283854;9.414312837694359;75986961110.70967;24.931494202553637;226000694.6;24.931494202553637 +2022-03-06T08:30:00Z;87.37979774262631;3.065698321347596;9.260217774017669;75983144859.27869;24.93526432690765;224893498.8;24.93526432690765 +2022-03-06T08:40:00Z;86.5202496675503;3.1052913970890335;10.07405768880446;75979001789.93549;24.93935731892186;225458836.6;24.93935731892186 +2022-03-06T08:50:00Z;87.24016542979813;3.1354721929859264;9.350086378448294;75975359124.64516;24.942955955272982;224526996.6;24.942955955272982 +2022-03-06T09:00:00Z;87.00418146092674;3.053621040468657;9.67013458259969;75971064931.09677;24.94719824485228;223145059.1;24.94719824485228 +2022-03-06T09:10:00Z;87.26697691762007;3.094413461740216;9.361364891545149;75967150938.83871;24.95106492863884;224573836.4;24.95106492863884 +2022-03-06T09:20:00Z;87.23923049815728;3.07086475762353;9.421278653827745;75962829130.32259;24.955334499403424;223672650.3;24.955334499403424 +2022-03-06T09:30:00Z;87.10562688947586;3.0396654364410063;9.57574763342924;75956807310.68852;24.961283533231096;222229640.5;24.961283533231096 +2022-03-06T09:40:00Z;87.09292292353744;3.1129163493428655;9.507298522159816;75952557878.55737;24.96548160242495;221553512.9;24.96548160242495 +2022-03-06T09:50:00Z;87.32654731751107;3.055420938811908;9.343749685198794;75948834155.35484;24.96916031694034;219423182.5;24.96916031694034 +2022-03-06T10:00:00Z;87.10192552574838;3.2303320698610567;9.391814454389172;75940345591.74193;24.977546279182707;216587363.1;24.977546279182707 +2022-03-06T10:10:00Z;87.21373983341846;3.091532005666507;9.416385740615373;75932497986.06451;24.985299030755883;213969556.6;24.985299030755883 +2022-03-06T10:20:00Z;87.09629792020677;3.13662397611556;9.491571024051709;75928635325.93549;24.989115002865454;211775025.5;24.989115002865454 +2022-03-06T10:30:00Z;87.19012697946548;3.0673738696402117;9.486754333068415;75924571565.41936;24.99312964465932;209025618.6;24.99312964465932 +2022-03-06T10:40:00Z;86.9260819130804;3.1078835648548155;9.705263051644735;75920863500.59016;24.996792890064306;235241270.6;24.996792890064306 +2022-03-06T10:50:00Z;87.16159221560348;3.098680793766304;9.468326716241664;75916591976.91803;25.001012783778414;251746634.3;25.001012783778414 +2022-03-06T11:00:00Z;86.11427728789106;3.1619877077336107;10.448263401919101;75913077000.25807;25.004485274873208;250127128.8;25.004485274873208 +2022-03-06T11:10:00Z;86.82446199681355;3.1298305419955814;9.770124504489122;75931713337.80646;24.986074194961006;249178884.2;24.986074194961006 +2022-03-06T11:20:00Z;86.77240415439171;3.1270913196927816;9.832767547691835;75929328805.16129;24.988429905731394;247702108.3;24.988429905731394 +2022-03-06T11:30:00Z;86.85643857575954;3.1786909103220924;9.686993069464176;75922624247.74193;24.995053425084553;245170836.6;24.995053425084553 +2022-03-06T11:40:00Z;87.0977626760898;3.0909578237686643;9.546239986186505;75966441934.45161;24.951765363281375;243725873.5;24.951765363281375 +2022-03-06T11:50:00Z;86.9311266148863;3.1168252467573816;9.659027232679218;75970463307.54099;24.94779259657691;244458793.3;24.94779259657691 +2022-03-06T12:00:00Z;86.94492506066535;3.0824391100235387;9.700165137979795;75966576243.6129;24.95163267751652;246839296;24.95163267751652 +2022-03-06T12:10:00Z;86.90805818273375;3.0840246251112524;9.725398028796146;75962718604.3871;24.955443689410586;245450884.1;24.955443689410586 +2022-03-06T12:20:00Z;86.65657915612422;3.077810531723839;9.996122250717082;75958602520.7742;24.959510021871342;245083421.4;24.959510021871342 +2022-03-06T12:30:00Z;86.895336303443;3.017900393924607;9.822411846163684;75954937723.87097;24.9631305223303;241558693.2;24.9631305223303 +2022-03-06T12:40:00Z;87.03877274423252;3.135636453388127;9.560484854181007;75950682310.19354;24.967334500771393;236985443.1;24.967334500771393 +2022-03-06T12:50:00Z;87.1598682917855;3.040878920185426;9.534089212163929;75947138543.48387;24.97083543393022;235551248.5;24.97083543393022 +2022-03-06T13:00:00Z;87.04523679624941;3.0358629735777267;9.654247059782865;75942808928.5246;24.975112716781386;233832315.9;24.975112716781386 +2022-03-06T13:10:00Z;86.58443942673188;3.0653676318223853;10.076273174620834;75938868917.67741;24.97900510467004;233702234.8;24.97900510467004 +2022-03-06T13:20:00Z;87.07891144697717;3.095632004334188;9.557401736825797;75931553461.67741;24.986232138665336;231286850.1;24.986232138665336 +2022-03-06T13:30:00Z;87.07779917719373;3.0758689787066;9.594675883980534;75920097280;24.99754984933698;230171832.7;24.99754984933698 +2022-03-06T13:40:00Z;86.89451216363331;3.0769213538021103;9.752659896717867;75915961046.70967;25.001636087925753;228968117.7;25.001636087925753 +2022-03-06T13:50:00Z;87.01852692562133;3.0701330621454055;9.637952519281827;75912065882.83871;25.005484170904143;228191793.5;25.005484170904143 +2022-03-06T14:00:00Z;86.89265446038915;3.075109354425754;9.765204994841026;75908202697.44263;25.009300661931867;226254914.1;25.009300661931867 +2022-03-06T14:10:00Z;87.08385692796438;3.084399858515035;9.559554173377368;75904098572.59016;25.013355180177843;225621289.3;25.013355180177843 +2022-03-06T14:20:00Z;87.0121694387828;3.0832272133537777;9.630487235942406;75900412828.90323;25.016996374236484;223714271;25.016996374236484 +2022-03-06T14:30:00Z;87.04737857401922;3.001079486217972;9.704120158951866;75896209143.74193;25.02114924940465;222287099.8;25.02114924940465 +2022-03-06T14:40:00Z;86.86610717568688;3.0518349742773294;9.810603162877806;75892653022.96774;25.024662387304257;221361317.2;25.024662387304257 +2022-03-06T14:50:00Z;86.8254134809278;3.0657317935967816;9.8415318611958;75886987858.58064;25.030259076781245;220220184.8;25.030259076781245 +2022-03-06T15:00:00Z;86.94835963964732;3.077213337137432;9.697465757621341;75868017498.83871;25.049000141556718;217678154.3;25.049000141556718 +2022-03-06T15:10:00Z;86.72797236194859;3.1401329665443116;9.848818784118516;75941273122.13333;24.976629959862308;215341386.3;24.976629959862308 +2022-03-06T15:20:00Z;86.7084331431429;3.064845674656457;9.965778602562432;75938356190.96774;24.979511634045814;212351438.5;24.979511634045814 +2022-03-06T15:30:00Z;86.90261145551038;3.0583390315855428;9.761990274328117;75931830139.87097;24.985958804684437;210480557.4;24.985958804684437 +2022-03-06T15:40:00Z;87.10966523419737;3.1116609719241106;9.505588571060805;75927890184.25807;24.989851138006447;210009104.8;24.989851138006447 +2022-03-06T15:50:00Z;86.78282174845984;3.186585397936308;9.720573418349435;75923945604.12903;24.99374803994801;207780038.2;24.99374803994801 +2022-03-06T16:00:00Z;86.98900664701434;3.0231110357264934;9.72094108799659;75919907344.51613;24.997737489068378;205725960.3;24.997737489068378 +2022-03-06T16:10:00Z;87.17126141138736;3.1276231322;9.424429516274534;75916156267.35484;25.00144322691487;202804124.9;25.00144322691487 +2022-03-06T16:20:00Z;87.07499105217661;3.1068324757560806;9.573302477535789;75911945635.67213;25.005602964641774;201064117.7;25.005602964641774 +2022-03-06T16:30:00Z;86.82212218423682;3.0855896946147805;9.797356602098121;75908381596.90323;25.00912392483119;199104049.5;25.00912392483119 +2022-03-06T16:40:00Z;86.83004419794665;3.053319495480556;9.832653341704708;75904083769.80646;25.01336980404013;198000707.1;25.01336980404013 +2022-03-06T16:50:00Z;87.18221900201455;3.0609413285040765;9.49721788247395;75900570921.29033;25.016840192713982;195976026.8;25.016840192713982 +2022-03-06T17:00:00Z;86.84850013017231;3.0871251259480856;9.779869977979027;75896300577.03226;25.021058921269624;194699792.5;25.021058921269624 +2022-03-06T17:10:00Z;86.52779737790134;3.2212739771299908;9.957975124717178;75912333444.12903;25.005219843630346;192477448.3;25.005219843630346 +2022-03-06T17:20:00Z;87.3155356985173;3.0215502964328684;9.388335182285621;75908903382.03279;25.008608446524775;190363449.8;25.008608446524775 +2022-03-06T17:30:00Z;87.18592049558193;3.1314806353994897;9.419237515160045;75902566267.87097;25.014868963911468;189060855.7;25.014868963911468 +2022-03-06T17:40:00Z;86.53608925284637;3.064360018094398;10.128492693094582;75898544194.06451;25.01884242286341;208786079.5;25.01884242286341 +2022-03-06T17:50:00Z;87.17682349121092;3.0309175648334166;9.54363744439411;75890085888;25.02719849328076;212916794.8;25.02719849328076 +2022-03-06T18:00:00Z;87.71637881814051;3.076237859217254;8.945326435960453;75882439448.7742;25.034752509903637;211316339.6;25.034752509903637 +2022-03-06T18:10:00Z;87.73449493461479;3.0139541597796753;8.997108990966522;75878321317.16129;25.03882086561019;234616237.4;25.03882086561019 +2022-03-06T18:20:00Z;87.80025599462274;3.009688017395506;8.92356296092957;75874756608;25.042342488088945;255463424;25.042342488088945 +2022-03-06T18:30:00Z;87.29465481930639;3.047059608592493;9.352652846336532;75876343002.2295;25.040775268625577;254770076.9;25.040775268625577 +2022-03-06T18:40:00Z;87.60855829202747;2.9754050556806826;9.153382159740094;75926222121.29033;24.991499039077024;253610776.8;24.991499039077024 +2022-03-06T18:50:00Z;87.54324896591156;3.1318382496115373;9.072032964807418;75921992869.16129;24.995677172184692;252074420.5;24.995677172184692 +2022-03-06T19:00:00Z;87.64384859701232;3.0932421991631314;8.998347725007132;75918371873.03226;24.999254401289942;249868023.7;24.999254401289942 +2022-03-06T19:10:00Z;87.40609960625144;3.0175536279261195;9.289324972982383;75936230829.41936;24.981611306323583;247877433.8;24.981611306323583 +2022-03-06T19:20:00Z;87.15613840849392;2.9769011973124773;9.60875411754443;75933199128.7742;24.98460636276657;246693755.9;24.98460636276657 +2022-03-06T19:30:00Z;87.4337028495817;3.0551335157252675;9.24624047816672;75926885805.41936;24.990843376906042;244644566.7;24.990843376906042 +2022-03-06T19:40:00Z;87.66318891862177;3.1170628651149124;8.972785221110481;75922904181.5082;24.994776874881083;242667652.1;24.994776874881083 +2022-03-06T19:50:00Z;86.60207792009639;3.129484676940518;10.013079389247375;75919184466.58064;24.998451629569548;242105562.2;24.998451629569548 +2022-03-06T20:00:00Z;87.34670443638132;3.019585772447481;9.393784771203837;75915116742.19354;25.00247018732304;241199070.4;25.00247018732304 +2022-03-06T20:10:00Z;87.00688518218242;3.0754106736091664;9.632492175923687;75911512460.3871;25.00603090413192;238864978.6;25.00603090413192 +2022-03-06T20:20:00Z;87.46087961609176;3.011572991082529;9.280571587115652;75907288559.48387;25.010203750694114;236858929.5;25.010203750694114 +2022-03-06T20:30:00Z;87.46371196710653;2.9685325861024157;9.284679003663118;75903829883.87097;25.013620621253267;236004649.3;25.013620621253267 +2022-03-06T20:40:00Z;87.48188775889511;2.9956000112514753;9.258042594738601;75899587735.08197;25.01781149513881;234994456.8;25.01781149513881 +2022-03-06T20:50:00Z;87.23472672835216;3.045895785534226;9.465523784891818;75895986612.45901;25.021369090949282;232514791.2;25.021369090949282 +2022-03-06T21:00:00Z;87.54261675065287;3.023050688019394;9.174851685391483;75891921292.3871;25.025385273448563;231769205.5;25.025385273448563 +2022-03-06T21:10:00Z;87.8037459812697;3.009727795940902;8.926030378616137;75887761738.32259;25.02949455093306;229358889.3;25.02949455093306 +2022-03-06T21:20:00Z;87.80811832919885;3.0383848098722797;8.88881906643878;75883791789.41936;25.033416515016135;227500098.1;25.033416515016135 +2022-03-06T21:30:00Z;87.79877594219452;3.028896644498322;8.914192945343096;75877455607.74193;25.039676111189365;227006464;25.039676111189365 +2022-03-06T21:40:00Z;87.7337529142495;2.950827341136902;9.070013597862792;75873596713.29033;25.04348836313731;224796936.3;25.04348836313731 +2022-03-06T21:50:00Z;87.69826881954448;3.028510579265477;9.016590551272898;75869540150.55737;25.047495894147698;222399587.1;25.047495894147698 +2022-03-06T22:00:00Z;87.69008844794566;3.0566258374563673;8.999323179140479;75866814464;25.05018863529886;218257936.5;25.05018863529886 +2022-03-06T22:10:00Z;87.4026920852698;3.039106336573424;9.291057181145577;75917117440;25.000493671975047;231712801.6;25.000493671975047 +2022-03-06T22:20:00Z;87.40007725178744;3.0903497880341884;9.212340995339149;75913670986.32259;25.003898468325392;236840167.2;25.003898468325392 +2022-03-06T22:30:00Z;87.88424186368383;3.054624889464871;8.797700864526789;75909415506.58064;25.008102512032483;235267105;25.008102512032483 +2022-03-06T22:40:00Z;87.68208995569094;3.06158187526291;9.0060905883396;75905852052.64516;25.011622894457368;234525134.5;25.011622894457368 +2022-03-06T22:50:00Z;87.8026571625497;3.0322721674492628;8.901408086316534;75901712119.74193;25.01571278794179;232033379.1;25.01571278794179 +2022-03-06T23:00:00Z;87.86316951281509;3.05057658556909;8.834974808963736;75898000568.65573;25.01937947746534;231103521;25.01937947746534 +2022-03-06T23:10:00Z;87.56806683386465;3.0732449361799983;9.033001287615772;75923222858.32259;24.99446204991719;229060138;24.99446204991719 +2022-03-06T23:20:00Z;87.82345266009196;3.0379513813638206;8.882983993541211;75920213949.93549;24.997434589592412;227324168.3;24.997434589592412 +2022-03-06T23:30:00Z;87.53812999257036;2.9886065710026735;9.18556817321441;75913952024.7742;25.003620826788925;226127475.6;25.003620826788925 +2022-03-06T23:40:00Z;87.49786627450082;3.023243910999273;9.221986095480155;75909840367.48387;25.007682786428106;224610766.5;25.007682786428106 +2022-03-06T23:50:00Z;87.60004060186158;3.0055477414237144;9.129567497120135;75906202657.03226;25.011276527829725;223578442.3;25.011276527829725 +2022-03-07T00:00:00Z;87.9012761213904;3.0026102772178858;8.847052207913947;75899301161.29033;25.01809460510958;222766971.9;25.01809460510958 +2022-03-07T00:10:00Z;87.89793273663705;3.007578085612051;8.836419599938246;75890169889.57378;25.027115507035024;221317252.1;25.027115507035024 +2022-03-07T00:20:00Z;87.3387422242276;3.052405570513487;9.348174532066295;75917658640.51613;24.99995901295607;219126733.6;24.99995901295607 +2022-03-07T00:30:00Z;87.830147400544;2.968524270534409;8.929440896144333;75914136080.51613;25.003438995730956;217632701.9;25.003438995730956 +2022-03-07T00:40:00Z;87.3634668494298;3.016333359230588;9.354091523110293;75909996940.3871;25.00752810602345;215530595.1;25.00752810602345 +2022-03-07T00:50:00Z;87.90260263642212;2.9843366564799005;8.8338508297608;75906274667.35484;25.011205387896773;214540023.7;25.011205387896773 +2022-03-07T01:00:00Z;87.89324616192263;2.962525115174141;8.860476548233349;75902308285.93549;25.01512382761619;212362537.3;25.01512382761619 +2022-03-07T01:10:00Z;87.9233628002311;2.9419241459248147;8.859516091675072;75898003993.18033;25.019376094333026;209603418.8;25.019376094333026 +2022-03-07T01:20:00Z;88.07600427028207;2.9940322529206487;8.663522992231519;75894153017.80646;25.023180522921212;208129712.3;25.023180522921212 +2022-03-07T01:30:00Z;88.10072643719437;3.009487270085523;8.614870512434175;75887696862.96774;25.02955864213871;206204928;25.02955864213871 +2022-03-07T01:40:00Z;88.1123733118434;2.926359645240232;8.718464300035143;75883980866.06451;25.03322972374265;226326594.1;25.03322972374265 +2022-03-07T01:50:00Z;87.83183257093964;3.0177964937342527;8.872189089938987;75879788610.06451;25.037371307893935;251082685.9;25.037371307893935 +2022-03-07T02:00:00Z;87.70293808741057;3.0703920338035253;8.964067582032976;75876308925.93549;25.04080893303903;250628029.9;25.04080893303903 +2022-03-07T02:10:00Z;87.9542575392255;3.023539250331862;8.741389758603807;75872049454.16394;25.04501692052403;248859548.9;25.04501692052403 +2022-03-07T02:20:00Z;87.86689143948068;2.981342647962892;8.874639982976802;75868513445.16129;25.0485101897433;246587193.8;25.0485101897433 +2022-03-07T02:30:00Z;87.73257452803377;3.0105386422980973;9.010602209630285;75864337639.2258;25.052635522662204;244498773.3;25.052635522662204 +2022-03-07T02:40:00Z;87.74605521563078;3.038731465483897;8.938824219872865;75860663064.7742;25.056265682488213;244053751.7;25.056265682488213 +2022-03-07T02:50:00Z;87.93208276253462;3.0352550978906985;8.744576894740938;75856647201.03226;25.060233006436768;242529313;25.060233006436768 +2022-03-07T03:00:00Z;87.9873296548905;3.101244068216285;8.639589633675504;75852821272.7742;25.064012690653946;241030903.7;25.064012690653946 +2022-03-07T03:10:00Z;87.86536198584882;3.0651151436608925;8.785224105527197;75870752834.06451;25.04629786836071;239744297.3;25.04629786836071 +2022-03-07T03:20:00Z;87.87140857325865;2.991382022500467;8.861240293376275;75867469857.57378;25.049541163475098;237601032.3;25.049541163475098 +2022-03-07T03:30:00Z;87.5938738353832;3.0344276855643817;9.093843884015394;75861388122.83871;25.055549388209236;235333799.9;25.055549388209236 +2022-03-07T03:40:00Z;88.00256349770957;3.0851309246036367;8.66693198918036;75907501485.41936;25.00999339839697;234152808.9;25.00999339839697 +2022-03-07T03:50:00Z;87.82886722516075;3.0065684053451673;8.880283926608271;75909365627.87097;25.008151787857603;232330405.2;25.008151787857603 +2022-03-07T04:00:00Z;87.96549702876874;3.0246753170303897;8.715669977600664;75905085572.12903;25.012380110514282;229820812.4;25.012380110514282 +2022-03-07T04:10:00Z;88.12714128452097;2.9689693683192107;8.625589064185158;75901636541.93549;25.01578745223837;228173031.2;25.01578745223837 +2022-03-07T04:20:00Z;88.05506886207911;2.981579549722548;8.687325341584964;75898114576.51613;25.019266847619328;225125012.6;25.019266847619328 +2022-03-07T04:30:00Z;88.10357316492284;3.018279781158236;8.584420572677422;75894487207.86885;25.02285037221812;224730673.5;25.02285037221812 +2022-03-07T04:40:00Z;87.21707336325083;3.063583479160509;9.442239365487898;75890445477.16129;25.02684325047799;223169217;25.02684325047799 +2022-03-07T04:50:00Z;87.70165166442352;3.0580879932870166;8.980918215656807;75886670088.25807;25.03057300621012;221297895.2;25.03057300621012 +2022-03-07T05:00:00Z;87.32666139297527;3.044453175976002;9.368607566637262;75882764354.06451;25.034431531747472;219494664.3;25.034431531747472 +2022-03-07T05:10:00Z;88.0379048514714;2.969045735739132;8.722574807212862;75879706624;25.03745230299191;218252783.5;25.03745230299191 +2022-03-07T05:20:00Z;87.96168580009378;3.0525801974942586;8.694865567178299;75875995714.06451;25.041118359114343;216732176.5;25.041118359114343 +2022-03-07T05:30:00Z;87.92869422542236;3.0247009279943855;8.773539229062019;75866072987.27869;25.05092114978212;217710459.9;25.05092114978212 +2022-03-07T05:40:00Z;87.98471198979684;3.0384548332636956;8.703117474044243;75857434690.06451;25.059455035793917;217882691.1;25.059455035793917 +2022-03-07T05:50:00Z;88.06743486371468;2.9856463757730474;8.675575750780656;75853162363.87097;25.063675722329354;216692207.5;25.063675722329354 +2022-03-07T06:00:00Z;87.96128594733685;3.0490725293660823;8.718409113195444;75849730246.19354;25.06706635595911;215776751.5;25.06706635595911 +2022-03-07T06:10:00Z;87.80844888132512;2.936330792998716;8.964294729144479;75845463006.96774;25.071282017013054;214512871.2;25.071282017013054 +2022-03-07T06:20:00Z;87.631331449898;2.9653533781555392;9.106384874231237;75841899883.35484;25.074802073107968;214872394.3;25.074802073107968 +2022-03-07T06:30:00Z;87.82398358912486;3.0107284191291734;8.884678000832109;75837781421.41936;25.07887075514449;213625955.1;25.07887075514449 +2022-03-07T06:40:00Z;87.35303941228774;3.0045008299983693;9.379826581812605;75834023341.41936;25.082583411186313;211992849.1;25.082583411186313 +2022-03-07T06:50:00Z;88.054384121137;3.0527922673480155;8.617458734545778;75830078827.35484;25.08648024786187;209949596.9;25.08648024786187 +2022-03-07T07:00:00Z;87.64746471555516;3.0699316475984597;8.98371630103651;75826159748.12903;25.090351957129904;207562289.5;25.090351957129904 +2022-03-07T07:10:00Z;87.18028061959252;3.0816941150289;9.443740110984416;75890006610.58064;25.027276812472994;206808031;25.027276812472994 +2022-03-07T07:20:00Z;87.7259839499752;3.032062531269092;8.951527632503565;75896536229.16129;25.0208261174707;207178454.7;25.0208261174707 +2022-03-07T07:30:00Z;87.96562048858243;3.0009236556322048;8.756423801734272;75890465405.90164;25.026823562616574;205086854.3;25.026823562616574 +2022-03-07T07:40:00Z;87.84491432754227;3.063034455273097;8.80342348764852;75886098167.74193;25.031138013916088;203479172.1;25.031138013916088 +2022-03-07T07:50:00Z;87.66669849925293;3.172735652881856;8.88237035513586;75882581751.74193;25.034611926953588;201597786.8;25.034611926953588 +2022-03-07T08:00:00Z;87.94748323266177;3.0640548583669567;8.679062472783967;75878271108.12903;25.03887046776526;201065637.2;25.03887046776526 +2022-03-07T08:10:00Z;87.9515986888372;3.031608951208815;8.736655385315567;75874691930.83871;25.042406383496612;201299968;25.042406383496612 +2022-03-07T08:20:00Z;87.72894917906586;3.177942108299969;8.81176587905279;75870499476.64516;25.04654816344588;209004913.3;25.04654816344588 +2022-03-07T08:30:00Z;87.75694985927616;3.044558360160077;8.925773843420764;75866508981.67741;25.050490425252928;206382839.7;25.050490425252928 +2022-03-07T08:40:00Z;87.61897913571487;2.980529944623486;9.132609611684408;75862898824.53334;25.05405694638417;204165120;25.05405694638417 +2022-03-07T08:50:00Z;86.96396244499888;3.0915783605282594;9.647302108319142;75858574897.54839;25.05832861001163;203030726.2;25.05832861001163 +2022-03-07T09:00:00Z;87.63750744311955;3.013799117930136;9.070802971830322;75855048968.25807;25.061811921352188;205103368.3;25.061811921352188 +2022-03-07T09:10:00Z;87.89778800885865;3.1007560315500986;8.713401992648992;75850324826.83871;25.066478962017367;221397322.3;25.066478962017367 +2022-03-07T09:20:00Z;87.8765547568617;3.033379823789265;8.822985676667725;75846636709.16129;25.070122501372037;248666310.2;25.070122501372037 +2022-03-07T09:30:00Z;87.94758222738704;3.007081039037414;8.75673447418285;75840082514.58064;25.07659747532392;247507581.9;25.07659747532392 +2022-03-07T09:40:00Z;87.89292718500447;3.0321550689509142;8.81300074609589;75836175678.95082;25.08045708898448;246549999.5;25.08045708898448 +2022-03-07T09:50:00Z;87.69099080868712;3.113549312656496;8.896864081922564;75832142999.08197;25.084441025803237;244760311.7;25.084441025803237 +2022-03-07T10:00:00Z;87.93145468947691;3.1339678929829593;8.663751756141659;75828201736.25807;25.088334650535952;243025589.7;25.088334650535952 +2022-03-07T10:10:00Z;87.53970656508955;3.134012967708826;9.003418412916623;75817129389.41936;25.09927316578521;241640745.3;25.09927316578521 +2022-03-07T10:20:00Z;86.79387865475061;3.1357257038757997;9.716524055928952;75812736231.2258;25.103613223822812;239918773.7;25.103613223822812 +2022-03-07T10:30:00Z;87.76362720564231;3.0542782985733994;8.882078392950616;75806974546.58064;25.10930526691633;239052363.5;25.10930526691633 +2022-03-07T10:40:00Z;87.76560088433797;3.1169030211038127;8.837908068351318;75857080716.3871;25.059804730987253;236034642.6;25.059804730987253 +2022-03-07T10:50:00Z;87.8327647110396;2.9884410121028364;8.899602946511985;75854726060.06557;25.06213092654947;235232355.1;25.06213092654947 +2022-03-07T11:00:00Z;87.90515979771837;3.0690303301481014;8.741179382662612;75850813968.51613;25.065995732601287;234448829.9;25.065995732601287 +2022-03-07T11:10:00Z;87.07227601941267;3.130195707445535;9.493687466898807;75880353065.29033;25.03681367524523;232305300.6;25.03681367524523 +2022-03-07T11:20:00Z;87.93989305813668;3.038238718003823;8.751302757088485;75878245541.16129;25.038895725704762;230730322.6;25.038895725704762 +2022-03-07T11:30:00Z;87.87548330692321;3.0525006009444295;8.79632255637498;75871498240;25.045561472155722;228190141.9;25.045561472155722 +2022-03-07T11:40:00Z;87.40235403633763;3.1263533281753326;9.184963236179337;75868968365.41936;25.048060768111867;226976836.3;25.048060768111867 +2022-03-07T11:50:00Z;87.11742153822284;3.2854230030414207;9.269154851799373;75863698332.90323;25.053267101681577;229086637.4;25.053267101681577 +2022-03-07T12:00:00Z;87.50380266738159;3.0313972204842963;9.159895614872909;75859836525.11476;25.057082231752833;250685968.5;25.057082231752833 +2022-03-07T12:10:00Z;87.49403503798654;3.0650995478091674;9.147517980266457;75855826085.16129;25.061044197470327;249726909.9;25.061044197470327 +2022-03-07T12:20:00Z;87.7606405506057;3.065897169389486;8.88775471643404;75851882562.06451;25.064940055155972;248592053.7;25.064940055155972 +2022-03-07T12:30:00Z;87.71521434930102;3.125183167561315;8.872630537194437;75847917369.80646;25.06885732008751;248088245.7;25.06885732008751 +2022-03-07T12:40:00Z;87.75293001865121;3.1134914833664804;8.859568230295618;75844459949.41936;25.07227295059279;245917998.2;25.07227295059279 +2022-03-07T12:50:00Z;87.66639156046509;3.027162448521382;9.029830736580893;75841053464.7742;25.075638261017048;243981060.2;25.075638261017048 +2022-03-07T13:00:00Z;87.70765637915017;3.071088424312845;8.93088697824281;75837244449.03226;25.079401237139887;244078658.1;25.079401237139887 +2022-03-07T13:10:00Z;87.32277528951595;3.084360354831244;9.299421023708787;75832695959.08197;25.08389474943741;243335101.9;25.08389474943741 +2022-03-07T13:20:00Z;87.73713589253529;3.074200677094038;8.88907462009265;75828774912;25.087768402776124;242451819.4;25.087768402776124 +2022-03-07T13:30:00Z;87.67994177906168;3.178039872666646;8.866090683691572;75822528908.3871;25.093938910868204;241123856.5;25.093938910868204 +2022-03-07T13:40:00Z;87.66764450049371;3.0157234752255637;9.043822127260839;75818355877.16129;25.09806150261536;238616047.5;25.09806150261536 +2022-03-07T13:50:00Z;87.41429185410773;3.016827742833531;9.295705860066578;75814433296.51613;25.101936670981072;238948217.7;25.101936670981072 +2022-03-07T14:00:00Z;87.47643471951146;2.974065190014335;9.227047598183319;75816941501.93549;25.099458782270794;237438183.2;25.099458782270794 +2022-03-07T14:10:00Z;87.89944214379875;3.0946544397571434;8.724656425328243;75862284724.45901;25.054663623823508;235000534.7;25.054663623823508 +2022-03-07T14:20:00Z;87.87571057844848;3.118255980964746;8.727339774003749;75858336074.32259;25.058564546578236;229284038.2;25.058564546578236 +2022-03-07T14:30:00Z;87.9529359337322;3.0834913693340944;8.679114699264298;75854601843.6129;25.06225364159639;228313814.7;25.06225364159639 +2022-03-07T14:40:00Z;88.16772259435443;2.9414682843239834;8.621654738820963;75850503729.54839;25.066302221706888;227144406.7;25.066302221706888 +2022-03-07T14:50:00Z;88.08708205140262;3.0036266853483644;8.624539393941042;75846618541.41936;25.07014044952026;227037910.7;25.07014044952026 +2022-03-07T15:00:00Z;87.81868750260278;3.0583203211069767;8.83648760361057;75842787129.80646;25.073925550814895;225360644.2;25.073925550814895 +2022-03-07T15:10:00Z;87.80378192819285;3.055026235069228;8.869246814369077;75860683121.31148;25.056245868374535;224002378.3;25.056245868374535 +2022-03-07T15:20:00Z;87.41730590109539;3.142810054677675;9.16201371188245;75857835107.09677;25.059059458607152;222395359;25.059059458607152 +2022-03-07T15:30:00Z;86.99229471622371;3.071055213914423;9.653122320225615;75851266906.83871;25.06554826894967;220486887.2;25.06554826894967 +2022-03-07T15:40:00Z;87.88866006052817;3.0266560608944326;8.804378307172477;75847251901.93549;25.069514744440305;218077976.8;25.069514744440305 +2022-03-07T15:50:00Z;87.79435042428494;3.1453344820401123;8.793514042844889;75843482392.7742;25.073238691499018;216196657.5;25.073238691499018 +2022-03-07T16:00:00Z;88.04935429996458;3.006587952265131;8.671200303826271;75839494276.12903;25.077178603730296;215452487.3;25.077178603730296 +2022-03-07T16:10:00Z;87.94671294963946;3.0726976942078092;8.701947029695962;75835403429.16129;25.081220004581525;213473380.7;25.081220004581525 +2022-03-07T16:20:00Z;87.6870321142969;3.0693675227531187;8.95713279670959;75831790250.66667;25.084789510544205;211782821.2;25.084789510544205 +2022-03-07T16:30:00Z;87.8130443279695;3.055271017720531;8.844518418979083;75827569895.2258;25.088958854498067;209453056;25.088958854498067 +2022-03-07T16:40:00Z;87.95473007577533;2.983072249406729;8.776042295194692;75823805539.09677;25.092677710809276;222307955.6;25.092677710809276 +2022-03-07T16:50:00Z;87.45228336714182;3.0487353080853876;9.227191964118884;75819870670.45161;25.096565018649777;255553073.5;25.096565018649777 +2022-03-07T17:00:00Z;87.7527718240657;3.0038352687602776;8.958936399838148;75815726773.67741;25.100658828093795;253958870.7;25.100658828093795 +2022-03-07T17:10:00Z;87.901628210851;3.088614931547823;8.720921613477989;75813032134.19354;25.1033208974378;252447760.8;25.1033208974378 +2022-03-07T17:20:00Z;87.86673878839196;3.044155738783692;8.798200898947997;75808892597.67741;25.107410399326255;250863280.3;25.107410399326255 +2022-03-07T17:30:00Z;87.9024889814449;3.075132583880521;8.75149846897401;75810629867.01639;25.105694128382684;249012025.8;25.105694128382684 +2022-03-07T17:40:00Z;87.42373846148345;2.995555179099766;9.282830248133434;75845955914.32259;25.07079506743534;247283117.4;25.07079506743534 +2022-03-07T17:50:00Z;87.72534699375223;3.161869427000571;8.854394858424643;75834062187.35484;25.082545034782115;245587968;25.082545034782115 +2022-03-07T18:00:00Z;87.80296299893065;3.1229681087289496;8.787891893447988;75829849583.48387;25.086706720859407;243768287;25.086706720859407 +2022-03-07T18:10:00Z;87.81863388814243;3.0460713501074155;8.85171586609498;75825682365.93549;25.09082356919914;241737001.3;25.09082356919914 +2022-03-07T18:20:00Z;87.46284600092007;3.1059343060981766;9.168826157317351;75821808606.96774;25.094650505995627;240468975.2;25.094650505995627 +2022-03-07T18:30:00Z;87.5463884289798;3.0390466103143052;9.146648094942586;75817941495.60655;25.098470875535263;242000202.3;25.098470875535263 +2022-03-07T18:40:00Z;87.69538445738023;3.0978500025796065;8.932583269347905;75813901038.93333;25.10246249516006;240741607.2;25.10246249516006 +2022-03-07T18:50:00Z;87.68670253478548;3.175368249978028;8.85940053220495;75810186933.67741;25.106131707981056;240526699.4;25.106131707981056 +2022-03-07T19:00:00Z;87.74249880746316;3.06667989017751;8.906049604349386;75805989392.51613;25.110278513411817;240209325.4;25.110278513411817 +2022-03-07T19:10:00Z;87.66762756953295;3.1318775967312193;8.908585417143255;75824015029.67741;25.092470752343797;240935176.3;25.092470752343797 +2022-03-07T19:20:00Z;87.82975399933972;3.158746117002529;8.735672930307404;75820823122.58064;25.095624078821086;240791684.1;25.095624078821086 +2022-03-07T19:30:00Z;87.77950186144339;3.063210440437689;8.877748064856238;75814816404.64516;25.1015581934846;239778429.9;25.1015581934846 +2022-03-07T19:40:00Z;87.80934617417846;3.0076453533407426;8.881717468388143;75810492348.85246;25.105829984362924;238713823;25.105829984362924 +2022-03-07T19:50:00Z;87.2554463989598;3.104922726769179;9.342846172084714;75806754089.29033;25.10952305953674;236447413.7;25.10952305953674 +2022-03-07T20:00:00Z;87.72778267037573;3.025499616807568;8.938527165508377;75802747276.3871;25.11348144204419;232926439.2;25.11348144204419 +2022-03-07T20:10:00Z;87.69227555377037;3.079384567936435;8.951774808572997;75798794107.87097;25.117386828564896;230181987.1;25.117386828564896 +2022-03-07T20:20:00Z;87.13464353769673;3.1025970592214844;9.474776815757604;75794947171.09677;25.121187267368015;229313899.4;25.121187267368015 +2022-03-07T20:30:00Z;87.91390468251358;2.934664529533348;8.87037299982821;75790854210.06451;25.125230756731032;229639621.2;25.125230756731032 +2022-03-07T20:40:00Z;87.74050260579487;3.105885413552506;8.861249772706257;75787176775.34427;25.12886374225358;227147049.3;25.12886374225358 +2022-03-07T20:50:00Z;88.02877460628174;2.9916336891901465;8.687300612883938;75782879467.01639;25.133109108963968;226275460.1;25.133109108963968 +2022-03-07T21:00:00Z;87.85666269379621;3.0613596357675603;8.789580789372721;75800948736;25.115258243451983;225934435.1;25.115258243451983 +2022-03-07T21:10:00Z;87.9137246061688;3.0313395931042977;8.77708439195821;75830337205.67741;25.08622499256118;223648717.6;25.08622499256118 +2022-03-07T21:20:00Z;87.91688251880224;3.071129969163848;8.743610948720372;75826750761.29033;25.089768087551803;222068141.4;25.089768087551803 +2022-03-07T21:30:00Z;87.83596653369558;3.1090234352846693;8.760064056988416;75819957743.48387;25.096478998070296;220232803.1;25.096478998070296 +2022-03-07T21:40:00Z;88.06021797197327;3.037278660119193;8.627517312584448;75816142451.6129;25.100248174462518;218046992.5;25.100248174462518 +2022-03-07T21:50:00Z;87.78458189503735;3.0388200839586155;8.907524731111499;75812103889.83606;25.10423792209456;215801459.6;25.10423792209456 +2022-03-07T22:00:00Z;87.60135860108491;3.049347877537451;9.056738367071734;75808201562.83871;25.108093081618545;214030071.7;25.108093081618545 +2022-03-07T22:10:00Z;87.43229180642587;3.102608860783772;9.206240475738586;75804310494.96774;25.111937118105335;212496585.4;25.111937118105335 +2022-03-07T22:20:00Z;87.94114197694135;3.0480575700533667;8.750468054060116;75800260674.06451;25.11593798877458;210532021.7;25.11593798877458 +2022-03-07T22:30:00Z;87.88031019485223;3.0324910195239454;8.810585414099629;75796530076.90323;25.119623494163086;208937356.4;25.119623494163086 +2022-03-07T22:40:00Z;87.98124208704238;3.0308848409566505;8.710679443450731;75792319653.16129;25.12378302646259;206732519.2;25.12378302646259 +2022-03-07T22:50:00Z;87.89973572775372;2.8902910252094394;8.93673529587993;75788760823.74193;25.12729884026794;207130690.1;25.12729884026794 +2022-03-07T23:00:00Z;87.9769046975052;3.0412622886117497;8.702177202061957;75784431582.42622;25.131575753991775;204899361;25.131575753991775 +2022-03-07T23:10:00Z;87.88529653369072;3.0433665816038293;8.74647175364029;75809967137.03226;25.106348847941522;202317691.9;25.106348847941522 +2022-03-07T23:20:00Z;87.45573292747038;3.0887184564073435;9.170178374434865;75806592627.6129;25.10968256962493;200745984;25.10968256962493 +2022-03-07T23:30:00Z;87.57897127927998;3.0248480962355133;9.098797284575245;75800444465.54839;25.11575641878058;199342278.2;25.11575641878058 +2022-03-07T23:40:00Z;87.92156233198449;3.055278563222251;8.748088783427088;75796283259.87097;25.119867327914907;196794434.1;25.119867327914907 +2022-03-07T23:50:00Z;87.78253821128737;3.0473277919222936;8.898353081473074;75792427470.45161;25.123676512361154;195266493.9;25.123676512361154 +2022-03-08T00:00:00Z;87.91359913861112;3.0647141122059853;8.734367505699115;75788505220.12903;25.127551354396896;193152363.4;25.127551354396896 +2022-03-08T00:10:00Z;88.04860555444132;3.0033412812833213;8.663594430387002;75784639538.36066;25.131370311623233;198774189.4;25.131370311623233 +2022-03-08T00:20:00Z;86.84665557392702;3.138979368154379;9.726991228702534;75780958406.19354;25.135006949901527;236962060.6;25.135006949901527 +2022-03-08T00:30:00Z;87.7874888903808;3.116344850961931;8.797819218087064;75806423040;25.10985010743031;237265164.6;25.10985010743031 +2022-03-08T00:40:00Z;88.00866480011402;3.0092975721406345;8.691922741729499;75828874801.54839;25.087669720593897;242219734.7;25.087669720593897 +2022-03-08T00:50:00Z;87.59773610291961;3.052455621277338;9.071801597881576;75824546584.7742;25.09194562215987;242717663;25.09194562215987 +2022-03-08T01:00:00Z;87.62107913423722;3.0326904649173256;9.08236761283617;75817417562.83871;25.098988475521434;240308224;25.098988475521434 +2022-03-08T01:10:00Z;87.86044684318826;3.0188844020033025;8.826441842315223;75807948800;25.10834278930978;236336227.1;25.10834278930978 +2022-03-08T01:20:00Z;87.87378451094104;3.0343943329132967;8.815540650569305;75804280237.41936;25.111967009930375;234219321.8;25.111967009930375 +2022-03-08T01:30:00Z;87.63397289486504;3.081822984551695;9.005594327075473;75797697370.83871;25.118470309323452;233530572.8;25.118470309323452 +2022-03-08T01:40:00Z;87.99445796356754;3.010421991096735;8.725405970037434;75793803858.58064;25.122316760652005;231360181.7;25.122316760652005 +2022-03-08T01:50:00Z;87.71539862776255;3.1674213780718548;8.715309259205355;75789833843.6129;25.126238790001064;230458136.8;25.126238790001064 +2022-03-08T02:00:00Z;87.8826990110845;3.136702716688631;8.705057552210203;75785869774.45161;25.130154945410702;229009738.3;25.130154945410702 +2022-03-08T02:10:00Z;87.99491087428379;3.04420542370312;8.67930388187116;75782059635.6129;25.13391903105542;227096113.5;25.13391903105542 +2022-03-08T02:20:00Z;87.92745581624776;3.012275441970928;8.77659411840266;75777903684.26666;25.13802474936773;225088677.2;25.13802474936773 +2022-03-08T02:30:00Z;87.4316833445512;3.0080664521055067;9.279046008063196;75774275980.3871;25.14160860514686;224394999.7;25.14160860514686 +2022-03-08T02:40:00Z;86.61562251781423;3.1116049895671254;9.985425843984602;75769989450.32259;25.14584332387091;223970018.6;25.14584332387091 +2022-03-08T02:50:00Z;87.73179525925363;3.0834012518671448;8.894175949419038;75766498072.7742;25.149292501096852;222227555.1;25.149292501096852 +2022-03-08T03:00:00Z;87.56776727094703;3.0814568809099487;9.093064933424186;75762205530.83871;25.15353315902631;221217626.8;25.15353315902631 +2022-03-08T03:10:00Z;87.66562450931563;3.048521237707641;9.012903917242527;75780692166.19354;25.135269971855443;219741811.6;25.135269971855443 +2022-03-08T03:20:00Z;87.76639836353566;3.021522524092597;8.92427965594756;75777250167.46666;25.138670367102296;218702022.2;25.138670367102296 +2022-03-08T03:30:00Z;87.7272049567671;3.0469200615381866;8.939452896930254;75770976784.51613;25.14486792359763;216951708.9;25.14486792359763 +2022-03-08T03:40:00Z;87.78777742654043;3.0421073391376505;8.880168925108817;75766890826.32259;25.14890449476533;215627473.8;25.14890449476533 +2022-03-08T03:50:00Z;87.93018484212288;3.030011790293996;8.761035354624486;75762954306.06451;25.15279343425568;213416200.3;25.15279343425568 +2022-03-08T04:00:00Z;87.82152282226727;3.0669187077488504;8.833541570758726;75798561957.16129;25.117616173266157;211372098.1;25.117616173266157 +2022-03-08T04:10:00Z;88.00948765812747;3.0357909101005536;8.68679221538912;75813250675.6129;25.103104997531208;209212052.6;25.103104997531208 +2022-03-08T04:20:00Z;87.92102560689287;3.04140619693978;8.74408165257033;75809546768.51613;25.10676413545834;208753631;25.10676413545834 +2022-03-08T04:30:00Z;87.69081330222498;3.0612251992394612;8.956073140861049;75805261689.70493;25.110997420470394;208110360.8;25.110997420470394 +2022-03-08T04:40:00Z;86.47089899166984;3.0869933152289626;10.177809011379887;75801776722.58064;25.1144402647551;205758397.9;25.1144402647551 +2022-03-08T04:50:00Z;87.83871773390743;3.0923578593785894;8.796844591751436;75797465418.32259;25.11869945822673;204373546;25.11869945822673 +2022-03-08T05:00:00Z;87.86766123522621;3.0488493164060007;8.81977381934913;75793896547.09677;25.12222519246309;202877126.2;25.12222519246309 +2022-03-08T05:10:00Z;87.56952536365719;3.2101096755668173;8.896009600881468;75802919506.58064;25.113311293599065;205275730.6;25.113311293599065 +2022-03-08T05:20:00Z;87.98525150623395;3.029613853201058;8.698562240335685;75797929455.48387;25.118241029888182;219324614.2;25.118241029888182 +2022-03-08T05:30:00Z;87.82707195268519;2.999842057705781;8.890029204653986;75791406063.21312;25.12468557383808;219223733.7;25.12468557383808 +2022-03-08T05:40:00Z;87.91078867824963;3.067532880799465;8.75291704381365;75787325037.11476;25.128717272524884;217006608.5;25.128717272524884 +2022-03-08T05:50:00Z;87.81989759722286;3.0798018032737433;8.82287752932108;75783459212.3871;25.132536370982535;215571875.7;25.132536370982535 +2022-03-08T06:00:00Z;87.67445178236366;3.083417552784582;8.957423574494474;75779404766.96774;25.136541810271314;213164164.1;25.136541810271314 +2022-03-08T06:10:00Z;87.84482778857155;3.155026972764319;8.728078723142474;75775696367.48387;25.140205386286006;210489740.4;25.140205386286006 +2022-03-08T06:20:00Z;87.95272333554826;2.9985999437722755;8.770292487567685;75771484730.7541;25.144366116911954;210957741.4;25.144366116911954 +2022-03-08T06:30:00Z;87.87897941241998;3.119233018109844;8.725356450259564;75767865881.18033;25.14794122540738;212404488.3;25.14794122540738 +2022-03-08T06:40:00Z;87.09194319096525;3.0593391234386806;9.546261490195448;75763560381.93549;25.152194684031052;211361329.5;25.152194684031052 +2022-03-08T06:50:00Z;87.7360106427839;3.096819488406678;8.888086939884738;75760027515.87097;25.15568484830092;210183597.4;25.15568484830092 +2022-03-08T07:00:00Z;87.53691222048869;3.0436884682375025;9.14248308236411;75755810144.5246;25.159851244229095;209696221.9;25.159851244229095 +2022-03-08T07:10:00Z;87.60919620202809;3.0887419072949394;9.026638034142186;75774114981.16129;25.14176765837309;207919368.3;25.14176765837309 +2022-03-08T07:20:00Z;87.8831490127238;3.1049065771215285;8.73325780043009;75770768086.70967;25.1450740988712;238694532.1;25.1450740988712 +2022-03-08T07:30:00Z;87.83213765319373;3.1357503155399757;8.750624767862634;75809295393.03226;25.107012472563714;243386500.1;25.107012472563714 +2022-03-08T07:40:00Z;87.86458461025019;3.0210016599920166;8.846523008212996;75816063043.14754;25.1003266231168;246407498.3;25.1003266231168 +2022-03-08T07:50:00Z;87.38066271857859;3.0245480194411165;9.330855686094043;75812102144;25.104239646828685;284595497.3;25.104239646828685 +2022-03-08T08:00:00Z;88.00855226124771;3.006385838867342;8.70025609777116;75808310833.54839;25.107985131665252;285981266.6;25.107985131665252 +2022-03-08T08:10:00Z;87.90308551693859;3.0247513233921106;8.788387352375965;75804159867.87097;25.11208592457059;287049493;25.11208592457059 +2022-03-08T08:20:00Z;87.86484130659802;3.06630732043133;8.800073343651604;75800552084.64516;25.115650100477133;285062177;25.115650100477133 +2022-03-08T08:30:00Z;87.63766982522687;3.1095425619827255;8.968389293945561;75796217195.35484;25.119932593908448;283174515.6;25.119932593908448 +2022-03-08T08:40:00Z;87.88268578246893;3.0284629836326653;8.827698646254296;75792726016;25.123381575336396;281435895.7;25.123381575336396 +2022-03-08T08:50:00Z;87.85332969593046;3.0959452413143067;8.792556890337892;75783826531.09677;25.132173492058534;280376287;25.132173492058534 +2022-03-08T09:00:00Z;87.90020790932395;3.0269876614931803;8.761297454570018;75776406296.7742;25.139504037919565;278355373.4;25.139504037919565 +2022-03-08T09:10:00Z;87.93303149936844;3.0555332562238284;8.73112277242209;75771847118.45161;25.1440081093989;276702056.9;25.1440081093989 +2022-03-08T09:20:00Z;87.94740272095069;3.074933918880612;8.680145817772049;75768038829.41936;25.147770367595808;274914601.3;25.147770367595808 +2022-03-08T09:30:00Z;87.90549209560432;3.1122855058264665;8.687435160567626;75761638300.90323;25.154093532846744;274053714.6;25.154093532846744 +2022-03-08T09:40:00Z;87.94947377200856;3.021017831234191;8.754097548901626;75757610281.29033;25.158072865738127;272353676.4;25.158072865738127 +2022-03-08T09:50:00Z;87.85547055837745;3.0416488371770067;8.814231571103642;75753784370.36066;25.161852532836342;270273833.3;25.161852532836342 +2022-03-08T10:00:00Z;87.20005858450493;3.0147568308792834;9.492410497845448;75749670119.2258;25.165917054968222;269415589.2;25.165917054968222 +2022-03-08T10:10:00Z;86.95679879139361;3.051577182884395;9.688850601424807;75745749124.12903;25.169790656950084;268685774.5;25.169790656950084 +2022-03-08T10:20:00Z;87.87997585945887;3.0546188011288016;8.79791869192898;75742084459.35484;25.173411026877055;267409844.5;25.173411026877055 +2022-03-08T10:30:00Z;87.57879837558428;3.034128221757937;9.09920899985817;75737998104.7742;25.1774479896407;265492347.9;25.1774479896407 +2022-03-08T10:40:00Z;87.30844679994226;3.0192748567527943;9.393939976678388;75733999153.54839;25.181398605494927;263343203.1;25.181398605494927 +2022-03-08T10:50:00Z;87.82947248589635;3.00209109110134;8.884319463356412;75730247277.11476;25.18510513295297;263653177.8;25.18510513295297 +2022-03-08T11:00:00Z;87.2602642924259;3.2021129170665694;9.270032622384873;75778208404.64516;25.137723712148116;264017259.4;25.137723712148116 +2022-03-08T11:10:00Z;87.18850132979374;3.096031971671311;9.422091431225104;75801386347.35484;25.11482592151086;264595059.6;25.11482592151086 +2022-03-08T11:20:00Z;87.04993806652234;3.169436641759004;9.48660531558379;75798300209.54839;25.117874757132505;263156652.1;25.117874757132505 +2022-03-08T11:30:00Z;86.80287999910182;3.1050049550659886;9.822873572025587;75791653392.51613;25.12444123400732;261400609.6;25.12444123400732 +2022-03-08T11:40:00Z;87.2403968503986;3.0221221272240864;9.440781563555905;75787887450.83871;25.12816165670237;257981340.9;25.12816165670237 +2022-03-08T11:50:00Z;87.10450426214818;3.091869590360851;9.532832316518785;75783900457.29033;25.132100459411756;257855554.1;25.132100459411756 +2022-03-08T12:00:00Z;87.4389562503615;3.018512624625694;9.292567782866714;75779790411.54099;25.13616082698867;254563691.4;25.13616082698867 +2022-03-08T12:10:00Z;86.80221502120749;3.030129766676929;9.892600907376558;75776190662.19354;25.139717066122433;252074380.4;25.139717066122433 +2022-03-08T12:20:00Z;87.53607351569998;3.0543480844198267;9.136560260289395;75772010562.06451;25.14384664133091;252775787.4;25.14384664133091 +2022-03-08T12:30:00Z;87.2171727036591;3.0959541152388814;9.407346321004384;75768204981.67741;25.147606223622084;251355606;25.147606223622084 +2022-03-08T12:40:00Z;87.50665572528513;3.029422248006091;9.169579707773854;75764283920.51613;25.15147989086993;250263353.8;25.15147989086993 +2022-03-08T12:50:00Z;87.41765064760669;3.0369658862883093;9.270745829073476;75760120534.70967;25.15559295378205;247862040.8;25.15559295378205 +2022-03-08T13:00:00Z;87.23711520671007;2.9858916591891362;9.485450175817244;75756571396.19672;25.159099193815095;246039651.1;25.159099193815095 +2022-03-08T13:10:00Z;87.42423397466153;3.0185515113013253;9.258192523009772;75746711719.86885;25.16883969611654;244339480.8;25.16883969611654 +2022-03-08T13:20:00Z;87.49462615803262;2.9734951248935966;9.256066558460923;75731301607.2258;25.18406354654266;242785907.6;25.18406354654266 +2022-03-08T13:30:00Z;87.48598488771259;2.9961173069151847;9.218456205163053;75724992908.3871;25.19029599206259;239566451.6;25.19029599206259 +2022-03-08T13:40:00Z;87.32990986726642;3.056148607950013;9.354114255680011;75720726395.87097;25.19451093519061;237225653.7;25.19451093519061 +2022-03-08T13:50:00Z;87.31404225355564;3.150719225483313;9.255618588202786;75717160497.54839;25.198033732457247;236425612.4;25.198033732457247 +2022-03-08T14:00:00Z;87.39161285035055;3.023282231678882;9.30106088248038;75713016732.90323;25.202127411369286;234742354.6;25.202127411369286 +2022-03-08T14:10:00Z;87.47905189806097;3.0054117620064296;9.226350595997944;75709194105.70493;25.20590383442664;232503296;25.20590383442664 +2022-03-08T14:20:00Z;87.27357349317316;3.0969504987465077;9.339563430567917;75709743037.93549;25.205361537146562;231535979.4;25.205361537146562 +2022-03-08T14:30:00Z;86.84142192760878;3.0929525212461217;9.756540981204923;75756920964.12903;25.158753851114586;228374964.5;25.158753851114586 +2022-03-08T14:40:00Z;87.50689731041707;3.0407505922968734;9.184719700256775;75753139959.74193;25.16248915445616;226743279.2;25.16248915445616 +2022-03-08T14:50:00Z;87.26135507468916;3.0511706870227036;9.397287833431234;75748969571.09677;25.16660913556359;225317722.8;25.16660913556359 +2022-03-08T15:00:00Z;87.31231434920359;3.1021317392257575;9.262553944913098;75745334503.2258;25.17020026632545;223593174.7;25.17020026632545 +2022-03-08T15:10:00Z;87.17584141506657;3.0339769269026418;9.401504029750116;75763340651.35484;25.152411758725524;222173184;25.152411758725524 +2022-03-08T15:20:00Z;87.34201509692954;3.005071310421792;9.375950634677778;75759994675.2;25.155717292026313;269931487;25.155717292026313 +2022-03-08T15:30:00Z;87.28805400787789;3.0904209077565308;9.321734748556286;75753896398.45161;25.16174185883026;267896039.2;25.16174185883026 +2022-03-08T15:40:00Z;87.16660486883438;3.1032696022138624;9.46269322626511;75749644618.32259;25.16594224764172;265698119.3;25.16594224764172 +2022-03-08T15:50:00Z;87.39992404232271;3.071255981482358;9.276508850030375;75745905168.51613;25.169636498673366;265106597.2;25.169636498673366 +2022-03-08T16:00:00Z;86.99892490250694;3.0628289990118582;9.633986121000357;75741855413.67741;25.173637304076603;265939472.5;25.173637304076603 +2022-03-08T16:10:00Z;87.11672123408587;3.06475453769409;9.549317292285618;75737967318.70967;25.177478403593703;264348837.2;25.177478403593703 +2022-03-08T16:20:00Z;87.12229201837071;3.030482457105096;9.556034725762958;75734078629.16129;25.181320090504713;263303366.2;25.181320090504713 +2022-03-08T16:30:00Z;86.91524972421078;3.0000433452815085;9.794510283027753;75721895130.2295;25.19335632733831;262327527.2;25.19335632733831 +2022-03-08T16:40:00Z;86.3655847571323;3.0343611370340553;10.318595452760086;75717914491.87097;25.197288851673125;261690665.3;25.197288851673125 +2022-03-08T16:50:00Z;86.64805083317411;3.1140401886362516;9.936630301175796;75713705653.67741;25.20144681758878;263812750.7;25.20144681758878 +2022-03-08T17:00:00Z;86.75425055384311;3.0469070699399796;9.914041942420054;75710129581.41936;25.20497966581843;263000922.8;25.20497966581843 +2022-03-08T17:10:00Z;86.85097249126385;3.0818400850565753;9.780864410777488;75706638666.32259;25.208428386182426;263294051.1;25.208428386182426 +2022-03-08T17:20:00Z;86.90811116398199;3.032603962236104;9.78158430489198;75703150063.48387;25.211874822236634;264287132.9;25.211874822236634 +2022-03-08T17:30:00Z;86.98659747487193;3.0829624662084263;9.653703334087849;75696409549.63934;25.218533863409228;266065391.5;25.218533863409228 +2022-03-08T17:40:00Z;86.80777323147497;3.0522671883075234;9.867110773369168;75692622294.03279;25.2222753424117;264499001.8;25.2222753424117 +2022-03-08T17:50:00Z;87.05125251748984;3.0694181441005495;9.578765613627375;75701093541.16129;25.21390648734917;261289785.8;25.21390648734917 +2022-03-08T18:00:00Z;86.96119935094703;3.059794333598247;9.677785255246;75740322849.03226;25.175151344594465;259025735.3;25.175151344594465 +2022-03-08T18:10:00Z;87.1946454580224;3.100511565357921;9.426421873774023;75736390094.45161;25.179036563923173;259324696.8;25.179036563923173 +2022-03-08T18:20:00Z;87.11255254795283;3.042603181003231;9.571954421143012;75732390746.83871;25.182987571373356;258552402.6;25.182987571373356 +2022-03-08T18:30:00Z;87.15763045290392;3.0936266239232753;9.486228903528486;75728618595.09677;25.186714129071802;257651480.8;25.186714129071802 +2022-03-08T18:40:00Z;87.18731651561167;3.013750549246883;9.530990590536375;75724484003.67213;25.190798745640148;254698595.1;25.190798745640148 +2022-03-08T18:50:00Z;86.97370900998484;2.997269580701906;9.745607987291526;75720847227.87097;25.194391563688438;253557991.2;25.194391563688438 +2022-03-08T19:00:00Z;86.80288705678264;3.0799372352866174;9.839511544258533;75716517359.48387;25.19866909690424;252972988.9;25.19866909690424 +2022-03-08T19:10:00Z;87.11615073424038;3.0718430200053697;9.452778481700488;75735086443.35484;25.18032445777346;250883105;25.18032445777346 +2022-03-08T19:20:00Z;87.22956017109064;3.0578613812598734;9.425067247922392;75731500659.6129;25.183866900104153;249315195.9;25.183866900104153 +2022-03-08T19:30:00Z;86.95922634303354;3.041817804186149;9.684620317143299;75725391343.48387;25.18990237285562;247815993.8;25.18990237285562 +2022-03-08T19:40:00Z;87.19544789875266;3.020480360303004;9.489579499239396;75721151653.16129;25.194090817990272;246282041.8;25.194090817990272 +2022-03-08T19:50:00Z;87.25799336834449;2.990470131936137;9.421724769297006;75717381529.6;25.197815372022703;244629041.5;25.197815372022703 +2022-03-08T20:00:00Z;87.37574310762959;3.009268665678092;9.31965875577866;75713381871.48387;25.201766686223063;242649946.8;25.201766686223063 +2022-03-08T20:10:00Z;87.2268701551965;3.0223255327758354;9.474519342375366;75709432072.25807;25.205668744178094;241933530.2;25.205668744178094 +2022-03-08T20:20:00Z;87.62511692614052;2.986012021759751;9.097173287058125;75705609315.09677;25.209445295627578;239942358.7;25.209445295627578 +2022-03-08T20:30:00Z;87.41609422779315;3.004494146993926;9.274827941578103;75701494552.7742;25.213510322768453;238932100.1;25.213510322768453 +2022-03-08T20:40:00Z;87.58248881751676;2.982950747660158;9.164542409811366;75697840326.19354;25.217120380668458;242717530.8;25.217120380668458 +2022-03-08T20:50:00Z;87.29485261290017;3.028463929318611;9.388467403041966;75693566480.51613;25.22134256832174;244301757.9;25.22134256832174 +2022-03-08T21:00:00Z;87.11488332277187;3.1599903224583126;9.418920047631733;75690057795.14754;25.224808844168066;243559589.2;25.224808844168066 +2022-03-08T21:10:00Z;86.57749969290808;2.9943024354189283;10.12820079494679;75685351424;25.229458329350905;241938633.4;25.229458329350905 +2022-03-08T21:20:00Z;87.43320297757126;3.0683885286860635;9.230451535241597;75702400363.35484;25.21261546073119;241595845.2;25.21261546073119 +2022-03-08T21:30:00Z;87.31412326399887;3.076120132879807;9.338453179946946;75730809162.32259;25.184550039258404;241043323.9;25.184550039258404 +2022-03-08T21:40:00Z;87.54700863481014;2.982036325466806;9.20163603217535;75726976033.03226;25.188336837468874;240572944.5;25.188336837468874 +2022-03-08T21:50:00Z;87.5111417838535;3.0466152380617295;9.171737311526265;75722962151.2258;25.192302203437638;239439673.8;25.192302203437638 +2022-03-08T22:00:00Z;87.38785293030688;3.0196615475179507;9.315109731172798;75718660230.29507;25.196552126998313;237133824;25.196552126998313 +2022-03-08T22:10:00Z;87.55572542939291;3.019620155599872;9.153813746813436;75706801317.16129;25.208267701306365;234968493.4;25.208267701306365 +2022-03-08T22:20:00Z;87.33788958210172;3.098663246146592;9.287160184683344;75702720247.74193;25.212299442790542;234396194.1;25.212299442790542 +2022-03-08T22:30:00Z;87.52195220098939;3.033206552863367;9.15847172909121;75699010659.09677;25.215964193593102;232556345.8;25.215964193593102 +2022-03-08T22:40:00Z;87.4567903600591;3.0040923132206485;9.260257325204716;75694778962.58064;25.22014474154253;228067856.5;25.22014474154253 +2022-03-08T22:50:00Z;87.37363289232177;3.013791970715274;9.327278723811506;75691237243.87097;25.223643651455546;271001533.9;25.223643651455546 +2022-03-08T23:00:00Z;87.43529984967623;3.0437566802525633;9.23855326024228;75686929903.48387;25.22789892896755;272863033.8;25.22789892896755 +2022-03-08T23:10:00Z;87.20600593068008;3.0352957232548046;9.45941327718296;75730931913.44263;25.18442877183263;271144629.7;25.18442877183263 +2022-03-08T23:20:00Z;87.04999978262087;3.085880130416016;9.590002559608516;75728172329.29033;25.187155000858073;271671956.6;25.187155000858073 +2022-03-08T23:30:00Z;87.27999632497382;2.9655686885134767;9.462388611442528;75722002365.93549;25.19325038779161;273109126.3;25.19325038779161 +2022-03-08T23:40:00Z;87.40419064463453;3.0974418437545252;9.205538210078487;75717853712.51613;25.197348896387158;271516374.7;25.197348896387158 +2022-03-08T23:50:00Z;87.20191909585539;3.106779143513968;9.412434738357987;75713985172.64516;25.201170677170158;270007329;25.201170677170158 +2022-03-09T00:00:00Z;87.17138572196396;3.071709301327425;9.474058946626238;75710079504.51613;25.205029137441525;267996919.7;25.205029137441525 +2022-03-09T00:10:00Z;87.07246099758369;2.9982098021030015;9.670061708816165;75706221468.90323;25.20884054093155;269668219.9;25.20884054093155 +2022-03-09T00:20:00Z;87.40296178862386;2.979414184869638;9.349843226381639;75702516954.2295;25.212500279091834;271145224.3;25.212500279091834 +2022-03-09T00:30:00Z;87.50930884476041;3.035737998893318;9.159730157630339;75698339443.6129;25.21662729608735;270473921;25.21662729608735 +2022-03-09T00:40:00Z;87.28735951488902;3.0460336044758125;9.39499350210841;75694740843.35484;25.22018240002079;269518055.2;25.22018240002079 +2022-03-09T00:50:00Z;87.33313063835385;3.051571546401437;9.348001228579372;75719174870.70967;25.196043707048588;267402471.2;25.196043707048588 +2022-03-09T01:00:00Z;87.75794652209699;3.0388755855128102;8.928490067518442;75742618458.83871;25.172883481851375;266348808.3;25.172883481851375 +2022-03-09T01:10:00Z;87.93022642799278;3.001000817364368;8.794372205465598;75737908719.48387;25.177536294529958;265543283.6;25.177536294529958 +2022-03-09T01:20:00Z;87.89447191214015;3.003831819576396;8.826367530171295;75734271764.98361;25.18112928911741;261596296.5;25.18112928911741 +2022-03-09T01:30:00Z;87.88816843988852;3.0135146721826964;8.819583686537396;75727679890.88524;25.187641487154234;258181648.5;25.187641487154234 +2022-03-09T01:40:00Z;87.16382923470799;3.0087915933520923;9.548655356223037;75723772762.83871;25.191501389697052;255724577;25.191501389697052 +2022-03-09T01:50:00Z;87.68115276915199;3.0203366877615996;9.01809083354675;75719795745.03226;25.195430337241422;256027482.8;25.195430337241422 +2022-03-09T02:00:00Z;87.72837335887081;3.000824514706991;9.009648768829065;75715815093.67741;25.199362874415428;253847023.5;25.199362874415428 +2022-03-09T02:10:00Z;87.56877749186069;3.0881127319608876;9.052480026296019;75712006342.19354;25.203125589474304;252843965.9;25.203125589474304 +2022-03-09T02:20:00Z;87.70594838796458;3.013656818266621;9.002437702464944;75707865550.45161;25.207216331416625;252484442.8;25.207216331416625 +2022-03-09T02:30:00Z;87.74855577221233;2.9902511695885026;8.97876127917293;75727987359.4754;25.187337734940613;250735834.2;25.187337734940613 +2022-03-09T02:40:00Z;87.41693914918845;3.0160132243202016;9.279392485929261;75722218915.67213;25.193036455494234;250032194.1;25.193036455494234 +2022-03-09T02:50:00Z;87.46235058339998;3.0414298715211876;9.225044846629626;75709251517.93549;25.20584711613841;249276151.7;25.20584711613841 +2022-03-09T03:00:00Z;87.71587452020196;2.989895963636499;8.998774494172913;75704937769.29033;25.210108724451786;248176640;25.210108724451786 +2022-03-09T03:10:00Z;87.55431246663198;3.105914022737821;9.05577630621014;75723035548.90323;25.192229692918826;246628814.5;25.192229692918826 +2022-03-09T03:20:00Z;87.5243750675171;3.0154423171674494;9.192640964882836;75719944786.58064;25.195283097160022;244670662.2;25.195283097160022 +2022-03-09T03:30:00Z;87.42536136707739;3.090335165176675;9.221647775739047;75713786054.19354;25.201367388874658;244291013.2;25.201367388874658 +2022-03-09T03:40:00Z;87.39962144947998;3.0538269805928255;9.256480517970344;75709651736.7742;25.20545173474962;244690481.5;25.20545173474962 +2022-03-09T03:50:00Z;87.48238216801256;3.09905305317892;9.151790419750217;75705700754.88524;25.209354961072933;246152026.8;25.209354961072933 +2022-03-09T04:00:00Z;86.53664951541316;3.1589990109667907;9.995762464297092;75701869865.29033;25.213139546659228;245319680;25.213139546659228 +2022-03-09T04:10:00Z;87.50996033728205;3.069634586331876;9.150746877185144;75697832464.51613;25.217128147321684;243686036.6;25.217128147321684 +2022-03-09T04:20:00Z;87.26837485984564;3.0976208924878144;9.340728081417936;75729147111.2258;25.186192001123576;242968972.4;25.186192001123576 +2022-03-09T04:30:00Z;87.31856509156877;3.0655630056843415;9.337572014387584;75745608869.16129;25.169929216654346;243156331.4;25.169929216654346 +2022-03-09T04:40:00Z;86.97462086774928;3.023720411349447;9.717596274035747;75742106062.45161;25.173389684897167;241477836.8;25.173389684897167 +2022-03-09T04:50:00Z;87.74440811132818;2.953301021188987;9.028256175360703;75737852810.4918;25.177591527749357;240580541.9;25.177591527749357 +2022-03-09T05:00:00Z;87.79012469161039;2.9513413150459944;8.980961107089986;75734351343.48387;25.181050672483444;238479360;25.181050672483444 +2022-03-09T05:10:00Z;87.00556117683949;3.022003895617307;9.688531687803254;75731076987.87097;25.184285450920644;237704159;25.184285450920644 +2022-03-09T05:20:00Z;87.282466347621;3.0736107582361707;9.376464100991283;75727446808.7742;25.187871751999;236037813.7;25.187871751999 +2022-03-09T05:30:00Z;87.80970689033049;3.077040102415919;8.851081721387722;75720957093.16129;25.194283026341207;233953610.3;25.194283026341207 +2022-03-09T05:40:00Z;88.00920651898632;2.9896179580613302;8.744181844234035;75716991306.32259;25.19820087866667;232058007.1;25.19820087866667 +2022-03-09T05:50:00Z;87.7585984768855;3.1566243005671732;8.807398299959063;75713085373.93549;25.20205960000201;230084809.4;25.20205960000201 +2022-03-09T06:00:00Z;87.74884463085338;3.088372077057159;8.872571271467649;75709018316.8;25.206077498568952;228776068.1;25.206077498568952 +2022-03-09T06:10:00Z;87.39692449165085;3.09262607784548;9.228474309551709;75705291875.09677;25.209758898726488;229196833;25.209758898726488 +2022-03-09T06:20:00Z;87.60447932146319;3.022258334706151;9.095006454530694;75701086009.80646;25.21391392767242;266376951.7;25.21391392767242 +2022-03-09T06:30:00Z;87.8171861042569;3.0278576457047466;8.889876588248498;75697525198.45161;25.21743169945758;272761096.3;25.21743169945758 +2022-03-09T06:40:00Z;87.91462375607465;3.0627733125314327;8.758589188204832;75693216074.32259;25.221688739151414;270663349.7;25.221688739151414 +2022-03-09T06:50:00Z;87.98969331667776;2.9570456580426923;8.759340251607762;75689617408;25.225243908350855;269247001.2;25.225243908350855 +2022-03-09T07:00:00Z;87.96171509021063;2.975384427315764;8.793971995857449;75685399837.37704;25.229410501146933;267068647.2;25.229410501146933 +2022-03-09T07:10:00Z;87.23068819957795;3.032739956889544;9.461567081664677;75703747947.35484;25.211284164995227;267279855.5;25.211284164995227 +2022-03-09T07:20:00Z;87.68678638668312;2.9916085940365185;9.026448357762968;75700451460.12903;25.214540807540267;271798404.1;25.214540807540267 +2022-03-09T07:30:00Z;87.33043121472285;2.9497113198786047;9.420582315924825;75694136286.96774;25.22077964912756;271395674.8;25.22077964912756 +2022-03-09T07:40:00Z;88.00104594289077;3.0720643616220578;8.66871697657441;75690191244.3871;25.224677007931064;270861411.1;25.224677007931064 +2022-03-09T07:50:00Z;87.82844039774442;3.015904071625095;8.877764550278508;75726211307.01639;25.18909232023218;270005875.6;25.18909232023218 +2022-03-09T08:00:00Z;87.92511819361646;3.094031978114585;8.701011320362232;75740608747.01639;25.174868902262705;268708963.1;25.174868902262705 +2022-03-09T08:10:00Z;87.07239546779967;3.1103218752175286;9.550523522243136;75731942234.83871;25.183430662203417;267540215.7;25.183430662203417 +2022-03-09T08:20:00Z;87.9770911298066;3.0760131256382333;8.676907678401605;75724467166.96774;25.190815378839083;263252826.8;25.190815378839083 +2022-03-09T08:30:00Z;87.92426011408571;3.0443983604292386;8.762937904221022;75720140205.41936;25.195090040351168;261150984.3;25.195090040351168 +2022-03-09T08:40:00Z;88.02052177070942;3.043646928596457;8.67654912595;75716571941.7705;25.198615174354373;259189978.2;25.198615174354373 +2022-03-09T08:50:00Z;88.00180061084673;3.044633745638943;8.682760846549478;75712336004.12903;25.202799912166594;260828311.1;25.202799912166594 +2022-03-09T09:00:00Z;87.93029336397076;3.1101831994126914;8.67903246870207;75708624433.54839;25.20646662094897;258529081.8;25.20646662094897 +2022-03-09T09:10:00Z;87.84681629204464;3.1400931637499867;8.726915384723316;75704040679.2258;25.210994971377904;254669328.5;25.210994971377904 +2022-03-09T09:20:00Z;87.93128345325097;3.0630986884714657;8.727760732286592;75700154434.06451;25.21483424344716;253415490.1;25.21483424344716 +2022-03-09T09:30:00Z;87.56260543195691;3.1365215828531947;8.966580693460452;75693707594.32259;25.221203160159565;251876781.4;25.221203160159565 +2022-03-09T09:40:00Z;87.87459669141124;3.0717837760112876;8.776059702146704;75689515377.31148;25.225344705793226;250998585.8;25.225344705793226 +2022-03-09T09:50:00Z;87.31535261549911;3.1667388291060043;9.21969358599158;75686004934.19354;25.228812718142937;254944843.5;25.228812718142937 +2022-03-09T10:00:00Z;87.30188003760958;3.06519883908877;9.338246858482963;75681697131.35484;25.2330684525169;250785792;25.2330684525169 +2022-03-09T10:10:00Z;87.56907665134622;3.0730883954383965;9.058712385633287;75678098465.03226;25.236623621716344;248191768.8;25.236623621716344 +2022-03-09T10:20:00Z;87.62936105039724;3.2185415397664787;8.852486715191578;75673913211.87097;25.240758287672303;246122363.9;25.240758287672303 +2022-03-09T10:30:00Z;87.74027828460869;3.155298407421276;8.776870481954065;75670148393.29033;25.244477600845467;244925605.2;25.244477600845467 +2022-03-09T10:40:00Z;87.86356551836015;3.0595546709226222;8.766328014611817;75666130641.83606;25.24844678968956;245111246.5;25.24844678968956 +2022-03-09T10:50:00Z;87.9556380087083;3.0319303478632227;8.732116507520619;75662202351.48387;25.252327598748984;243608675.1;25.252327598748984 +2022-03-09T11:00:00Z;87.98020831569893;2.980624560934419;8.754775045048405;75658342003.6129;25.256141286548797;242183251.9;25.256141286548797 +2022-03-09T11:10:00Z;87.93994554162609;3.044889333129906;8.706513481012914;75677577083.87097;25.23713870093726;239758699.4;25.23713870093726 +2022-03-09T11:20:00Z;87.5496829039883;3.0854214428888644;9.091965669958297;75721240774.19354;25.194002774165;238736747.4;25.194002774165 +2022-03-09T11:30:00Z;87.48314269911508;3.03748344137385;9.190406163513021;75723491988.64516;25.19177877016954;237298324.6;25.19177877016954 +2022-03-09T11:40:00Z;87.41503871164365;3.1129476731749213;9.189481589800057;75719878722.06451;25.195348363153553;236274324.6;25.195348363153553 +2022-03-09T11:50:00Z;87.58546007134858;2.9680136503703887;9.158284613261076;75715564407.46666;25.19961053057894;230460383;25.19961053057894 +2022-03-09T12:00:00Z;87.073520988917;3.066410173602347;9.588983583849435;75712002576.51613;25.20312930963592;225542815.5;25.20312930963592 +2022-03-09T12:10:00Z;87.33839449704128;2.9929122626366005;9.403625161756349;75707796182.70967;25.207284860709823;225069022.4;25.207284860709823 +2022-03-09T12:20:00Z;87.44912084306068;3.063656524242359;9.194613203738855;75704072786.58064;25.21096325210505;223290268.9;25.21096325210505 +2022-03-09T12:30:00Z;87.43793085792763;3.0570361537716457;9.232173963712864;75700016293.16129;25.21497071463962;221559907.1;25.21497071463962 +2022-03-09T12:40:00Z;87.20954277095562;3.0613992810755803;9.45007191354767;75696145639.2258;25.218794583934418;219989817.8;25.218794583934418 +2022-03-09T12:50:00Z;87.46029619631489;2.956379047871786;9.308119794737898;75692217412.26666;25.22267533036704;218121975.7;25.22267533036704 +2022-03-09T13:00:00Z;87.0274462883337;3.037785616406467;9.652946985056836;75688197747.6129;25.226646409285777;215873932.4;25.226646409285777 +2022-03-09T13:10:00Z;87.10249319716824;3.034665781799174;9.58304319393115;75684037070.45161;25.230756796292145;216145114.2;25.230756796292145 +2022-03-09T13:20:00Z;87.19618805327599;2.992452883955476;9.559839347161804;75679866880;25.2348765816016;214374796.4;25.2348765816016 +2022-03-09T13:30:00Z;87.26997660855646;3.0786412106959626;9.366027933355289;75673674718.96774;25.240993897908947;213218667.4;25.240993897908947 +2022-03-09T13:40:00Z;87.2976079726219;3.0614720466112955;9.348583821072607;75669665461.67741;25.244954695258155;210883947.4;25.244954695258155 +2022-03-09T13:50:00Z;87.6769969525503;2.9652616542421875;9.082653654174184;75665506105.80646;25.249063776944666;248219581.9;25.249063776944666 +2022-03-09T14:00:00Z;87.17172848756508;2.9118295724189216;9.631080770689247;75661953552.51613;25.25257339048062;261352613.2;25.25257339048062 +2022-03-09T14:10:00Z;87.40659409686613;3.055583142722806;9.250472068021951;75657762287.48387;25.256713995642006;260214381.1;25.256713995642006 +2022-03-09T14:20:00Z;87.2119811611995;3.107210369600539;9.376476204754121;75653901080.7742;25.26052853189971;259171295;25.26052853189971 +2022-03-09T14:30:00Z;87.31225525921913;3.1097479324718855;9.300711178010795;75649839104;25.26454141151176;255022839.7;25.26454141151176 +2022-03-09T14:40:00Z;87.52749711267056;3.0618834594686426;9.113039645029843;75646105137.54839;25.26823024546595;252296225;25.26823024546595 +2022-03-09T14:50:00Z;87.28707466899976;3.0743934061726663;9.352327830671655;75696827358.96774;25.218121104147208;251662996.6;25.218121104147208 +2022-03-09T15:00:00Z;87.31287242503016;3.0793614130975118;9.287690527680606;75693613257.44263;25.221296356788518;250281785.8;25.221296356788518 +2022-03-09T15:10:00Z;87.43223761330695;3.0732933675613356;9.205007696557614;75711892446.96774;25.203238108047127;247587146.3;25.203238108047127 +2022-03-09T15:20:00Z;87.39065062378965;3.010517927310344;9.324694520922;75708709392.51613;25.20638268888129;245402372.2;25.20638268888129 +2022-03-09T15:30:00Z;87.2715407807704;3.101320943600966;9.325717473528014;75695131747.09677;25.219796221137088;244632939.4;25.219796221137088 +2022-03-09T15:40:00Z;87.2621365217678;3.073555384150824;9.324914785185666;75689901419.35484;25.224963329844673;244119618.1;25.224963329844673 +2022-03-09T15:50:00Z;86.86342424736303;2.9975811545820483;9.833712434975793;75685985048.7742;25.22883236320698;242687339.4;25.22883236320698 +2022-03-09T16:00:00Z;86.8006613348808;2.9897151895735306;9.91830347501529;75681976790.03279;25.23279217407675;239719457;25.23279217407675 +2022-03-09T16:10:00Z;86.3583825399422;3.0446183932623874;10.301853642682872;75678128194.06451;25.23659425201925;238586450.6;25.23659425201925 +2022-03-09T16:20:00Z;87.18991671666849;3.100673636410337;9.42822014591645;75673980135.2258;25.240692173220868;235194938.8;25.240692173220868 +2022-03-09T16:30:00Z;87.35982944973918;2.9892648939488606;9.367659943287924;75670332052.64516;25.24429616138346;235182938.8;25.24429616138346 +2022-03-09T16:40:00Z;87.32882284711098;3.0615746160130093;9.320473520751376;75666238695.2258;25.248340042342438;233129521.5;25.248340042342438 +2022-03-09T16:50:00Z;87.36241941825222;3.0821587153225676;9.283265095712258;75662349146.83871;25.252182577711384;231654565.2;25.252182577711384 +2022-03-09T17:00:00Z;87.40084151242107;3.0004229529513577;9.341482505847189;75658466824.39345;25.25601797447854;230421140.6;25.25601797447854 +2022-03-09T17:10:00Z;87.270859214444;3.0421912422497432;9.323980634000753;75675370793.29033;25.239318324057116;229268513;25.239318324057116 +2022-03-09T17:20:00Z;87.1579132651675;3.0915135783846313;9.436913448098007;75672341008.51613;25.242311487786292;229048187.9;25.242311487786292 +2022-03-09T17:30:00Z;87.13605165202438;3.1250086722227803;9.457489488301986;75665613790.96774;25.24895739337521;226580312.1;25.24895739337521 +2022-03-09T17:40:00Z;87.31474490218368;2.981612122972129;9.41406719970335;75661969738.32259;25.2525574003122;225090328.8;25.2525574003122 +2022-03-09T17:50:00Z;87.49075574434623;3.0452676972009955;9.191084556586322;75657686049.03226;25.256789312598535;222702360.8;25.256789312598535 +2022-03-09T18:00:00Z;87.41179062177169;3.114201411804582;9.20119993759972;75654213830.19354;25.260219562686355;220755901.9;25.260219562686355 +2022-03-09T18:10:00Z;87.38317697154713;3.082953991191252;9.249357274925327;75654594761.44263;25.25984323575787;220077419.4;25.25984323575787 +2022-03-09T18:20:00Z;87.174033342401;3.09912507268848;9.457868652642194;75702119853.41936;25.21289258013971;219555972.1;25.21289258013971 +2022-03-09T18:30:00Z;87.01425270224297;3.0078729354763554;9.710281595097337;75698093419.35484;25.21687034664724;217775389.4;25.21687034664724 +2022-03-09T18:40:00Z;87.37604801488155;3.0089921542975335;9.338723179648028;75694289094.19354;25.22062868888453;216478300.3;25.22062868888453 +2022-03-09T18:50:00Z;87.17434025127179;3.069671488709901;9.476217322020652;75690416854.70967;25.22445412456317;215598179.1;25.22445412456317 +2022-03-09T19:00:00Z;87.41114241218386;3.0493729725568146;9.244133202099022;75686432900.12903;25.228389925036865;216193552.5;25.228389925036865 +2022-03-09T19:10:00Z;87.50060923540276;2.9381878698076873;9.278972380571497;75704826186.32259;25.210218958714865;218907086.5;25.210218958714865 +2022-03-09T19:20:00Z;87.41843524860882;2.996180891307173;9.307211614065181;75701409959.86885;25.21359389319834;216762368;25.21359389319834 +2022-03-09T19:30:00Z;87.38758166672874;2.9850120488202503;9.347968315484035;75695417872.51613;25.219513554119125;215211360.5;25.219513554119125 +2022-03-09T19:40:00Z;87.6204393950892;2.999321891324213;9.096843124514178;75691080340.64516;25.223798658190177;225743178.3;25.223798658190177 +2022-03-09T19:50:00Z;87.50506307416036;3.0838562694049507;9.139957007039005;75687651724.3871;25.22718583272228;237029640.3;25.22718583272228 +2022-03-09T20:00:00Z;87.41002480555082;3.0967992031908027;9.201941788863394;75683415139.09677;25.231371210355213;236249286.2;25.231371210355213 +2022-03-09T20:10:00Z;87.45018234673748;3.0324024374426664;9.23142082666553;75679816737.03226;25.234926118490677;234910158.5;25.234926118490677 +2022-03-09T20:20:00Z;87.54769250692569;2.9516232049205895;9.167004562661345;75675738442.32259;25.238955118803126;232745158.2;25.238955118803126 +2022-03-09T20:30:00Z;87.53020565790789;3.063633527717075;9.109102602019433;75671962674.36066;25.24268524901226;230062146.1;25.24268524901226 +2022-03-09T20:40:00Z;86.82717607564105;3.0831625393766258;9.808045283172879;75668065973.67741;25.246534850227462;228551092.5;25.246534850227462 +2022-03-09T20:50:00Z;87.28083969473714;3.1521103883524577;9.26559773840989;75664144119.74193;25.250409300667226;228235364.7;25.250409300667226 +2022-03-09T21:00:00Z;87.51647692214569;3.0263763043459275;9.170638650785117;75660385973.67741;25.254122021975046;228061778.6;25.254122021975046 +2022-03-09T21:10:00Z;87.36113989089381;3.027568703799458;9.327793583247868;75655851569.54839;25.258601618706816;226990011.7;25.258601618706816 +2022-03-09T21:20:00Z;87.60057195556159;2.9974552492658852;9.12805574376479;75652214321.54839;25.26219490324647;256819266.1;25.26219490324647 +2022-03-09T21:30:00Z;87.410234202558;2.960598276396905;9.313336793497209;75645522457.18033;25.26880588296939;277411707.9;25.26880588296939 +2022-03-09T21:40:00Z;86.82915623918329;2.9905275401482663;9.870840533755459;75641970083.67213;25.272315318896247;274253691.9;25.272315318896247 +2022-03-09T21:50:00Z;87.34752415734354;3.0450889849743734;9.313100422601021;75692498745.80646;25.22239739730914;271644804.1;25.22239739730914 +2022-03-09T22:00:00Z;87.42660193791707;3.14309867716023;9.161188214369089;75689831721.29033;25.225032185467853;271130359.7;25.225032185467853 +2022-03-09T22:10:00Z;87.62897319054967;2.955020080740557;9.136145629987668;75685723433.29033;25.229090816541362;269588744.3;25.229090816541362 +2022-03-09T22:20:00Z;87.46465930900487;2.9301917043651837;9.336875580647073;75676244135.86885;25.23845553758083;265801795.1;25.23845553758083 +2022-03-09T22:30:00Z;87.52074296024327;2.9850216565837533;9.235821990114902;75669680590.45161;25.24493974934564;264681670.2;25.24493974934564 +2022-03-09T22:40:00Z;86.9284323966249;3.094647169458487;9.692186619760085;75665752394.32259;25.248820465320787;263431795.6;25.248820465320787 +2022-03-09T22:50:00Z;87.17541831892231;2.96194483750725;9.5792629219908;75661999731.6129;25.252527769551147;269697816.8;25.252527769551147 +2022-03-09T23:00:00Z;87.4820718176801;2.9606580587268727;9.263634464158956;75657914500.12903;25.25656362279291;267836052.6;25.25656362279291 +2022-03-09T23:10:00Z;87.25955136069813;3.0793716271979705;9.363163124365858;75683769244.90323;25.231021384629912;266978799.5;25.231021384629912 +2022-03-09T23:20:00Z;87.59575884418476;2.9144986197638367;9.219238619766072;75680428233.44263;25.234322013244785;266389201.8;25.234322013244785 +2022-03-09T23:30:00Z;87.48927631138552;2.9965743293564753;9.235955811240792;75674498345.29033;25.240180226767624;264325846.7;25.240180226767624 +2022-03-09T23:40:00Z;87.4537071228326;2.9838129206940467;9.300756626963492;75670151828.64516;25.24447420701381;262185092.1;25.24447420701381 +2022-03-09T23:50:00Z;87.62502029309437;2.951905595751092;9.17207068434106;75666610043.87097;25.247973182192816;261728784.5;25.247973182192816 +2022-03-10T00:00:00Z;87.69415330337634;2.8883562114929693;9.14227045128524;75662481209.80646;25.252052110990316;269188063;25.252052110990316 +2022-03-10T00:10:00Z;87.49366106359672;3.022989290135198;9.194547558765048;75658992210.58064;25.255498938640496;269771412.6;25.255498938640496 +2022-03-10T00:20:00Z;87.50012429274595;2.9641232980995103;9.253516021807467;75655083107.09677;25.25936079274352;267701657.6;25.25936079274352 +2022-03-10T00:30:00Z;87.4930828069232;2.9271728191277773;9.31659322194825;75651223278.93333;25.263173967117506;267486439.2;25.263173967117506 +2022-03-10T00:40:00Z;86.92205223548834;3.0690537159083506;9.719489573903816;75647413016.7742;25.266938174592077;265395893.7;25.266938174592077 +2022-03-10T00:50:00Z;87.66130350579702;2.967571212699487;9.10517943189521;75643380967.2258;25.270921488709067;266738721;25.270921488709067 +2022-03-10T01:00:00Z;87.54338247595958;3.06480793900624;9.128804700584068;75639719671.74193;25.27453853007037;264251259.9;25.27453853007037 +2022-03-10T01:10:00Z;87.21537591969184;3.167179824905484;9.282618384442054;75635109821.93549;25.279092660566747;262623760.5;25.279092660566747 +2022-03-10T01:20:00Z;87.34913239939873;3.0761443260477592;9.28970196278235;75681061524.64516;25.233696376640633;260162725.2;25.233696376640633 +2022-03-10T01:30:00Z;87.50481647301834;2.995438075428287;9.203294764695798;75680600735.4754;25.234151596246136;259481868.6;25.234151596246136 +2022-03-10T01:40:00Z;87.23477965295884;2.991663107328718;9.504457238817174;75677017121.03226;25.237691895498397;259254668.4;25.237691895498397 +2022-03-10T01:50:00Z;86.97808923728593;3.010025147348098;9.750105336743927;75672834708.64516;25.241823755016636;257315542.7;25.241823755016636 +2022-03-10T02:00:00Z;87.5143414566292;3.033164053005481;9.162537156435816;75669162512.51613;25.245451565266883;256077031.2;25.245451565266883 +2022-03-10T02:10:00Z;87.42120564230163;3.001683506782856;9.3290174422026;75665141297.54839;25.24942417576093;253879725.4;25.24942417576093 +2022-03-10T02:20:00Z;87.36804937092019;3.0432156125139787;9.327439571955532;75661296276.64516;25.25322272185023;253574111;25.25322272185023 +2022-03-10T02:30:00Z;87.47384950138655;2.933710083790351;9.33096107963277;75657458738.36066;25.257013875763313;252242557.9;25.257013875763313 +2022-03-10T02:40:00Z;87.43329547693915;2.994667117858875;9.327962530466921;75653450454.70967;25.260973711241576;250473240.8;25.260973711241576 +2022-03-10T02:50:00Z;86.79383860586026;2.9826853265540696;9.95941070112086;75649738355.6129;25.264640942151896;221889238.7;25.264640942151896 +2022-03-10T03:00:00Z;87.46707281631751;2.9179808133657326;9.357458892705585;75645606746.83871;25.268722612121124;218201319.2;25.268722612121124 +2022-03-10T03:10:00Z;87.66963672174202;2.988352457875785;9.077334456817931;75663868498.58064;25.250681590392222;217934550.7;25.250681590392222 +2022-03-10T03:20:00Z;87.76505498131286;2.9718989332423686;8.972959361272865;75660180645.16129;25.254324868682936;218461349.2;25.254324868682936 +2022-03-10T03:30:00Z;87.78551457199421;2.98252420639992;8.978474861232668;75646035835.87097;25.268298709493163;218552386.1;25.268298709493163 +2022-03-10T03:40:00Z;87.8210798091502;3.013222554548238;8.904678065624438;75641726771.2;25.2725556904476;218101691.7;25.2725556904476 +2022-03-10T03:50:00Z;87.77203616568193;3.041641114576037;8.937327679425493;75638100562.58064;25.276138069039742;215798288.5;25.276138069039742 +2022-03-10T04:00:00Z;87.77244150818393;2.9544895223472305;9.031558199032181;75634031979.35484;25.280157475251155;215004919.7;25.280157475251155 +2022-03-10T04:10:00Z;88.0542756605485;2.9212111034214927;8.77476397677218;75630262404.12903;25.283881487575837;218582973.9;25.283881487575837 +2022-03-10T04:20:00Z;88.06586797813696;2.9979613168432886;8.685313172420951;75626343919.48387;25.28775260944994;221979416.8;25.28775260944994 +2022-03-10T04:30:00Z;88.11388525877454;2.965963569734193;8.666251513969947;75622396894.96774;25.291651926233243;220599857.5;25.291651926233243 +2022-03-10T04:40:00Z;87.98515864117581;2.947159295602644;8.783766469422842;75618648724.64516;25.295354792376045;219349784.8;25.295354792376045 +2022-03-10T04:50:00Z;87.7983243453358;3.092597218710142;8.841038150283286;75658459505.31148;25.256025205094662;221242687;25.256025205094662 +2022-03-10T05:00:00Z;86.8847902302245;3.0482657148625627;9.804471897932402;75666784652.3871;25.247800684171928;222272346.8;25.247800684171928 +2022-03-10T05:10:00Z;88.0053246170368;2.9823888237651035;8.752921312637122;75663442118.19354;25.25110281711446;224449436.9;25.25110281711446 +2022-03-10T05:20:00Z;87.56554983781479;3.013723379748331;9.15724187688671;75660054726.19354;25.25444926566659;224100352;25.25444926566659 +2022-03-10T05:30:00Z;87.8340608596284;3.053675499001703;8.854754801041352;75653376990.96774;25.261046287026375;222748539.9;25.261046287026375 +2022-03-10T05:40:00Z;87.75335358381045;3.0293119632251995;8.970980769399933;75649722301.93549;25.264656801788327;221494172.9;25.264656801788327 +2022-03-10T05:50:00Z;87.81357050928656;3.0191747242465516;8.921294808078796;75645637010.88524;25.268692713876487;217506396.3;25.268692713876487 +2022-03-10T06:00:00Z;87.12911631306794;3.0584798207352586;9.548319810614275;75641866636.3871;25.272417515812705;214215382.7;25.272417515812705 +2022-03-10T06:10:00Z;87.81916049979505;3.002480643307504;8.933066862046834;75637936854.70967;25.27629979817171;255653227.4;25.27629979817171 +2022-03-10T06:20:00Z;87.75368420897155;3.0100130843790645;8.98816993452021;75634031516.90323;25.280157932113095;259379794.6;25.280157932113095 +2022-03-10T06:30:00Z;87.73025338807238;3.0474726935404424;8.955233738917235;75630249653.67741;25.28389408391259;261426010.8;25.28389408391259 +2022-03-10T06:40:00Z;87.44134523479065;2.9514088706944563;9.365770110521874;75624289114.83871;25.28978257764663;261580800;25.28978257764663 +2022-03-10T06:50:00Z;87.81983830363653;2.9475291974578233;8.973706691435094;75614177544.25807;25.299771929551998;259229497.8;25.299771929551998 +2022-03-10T07:00:00Z;87.92581222372212;2.9637122826238094;8.818637579019988;75609986457.6;25.3039123584952;256861661.9;25.3039123584952 +2022-03-10T07:10:00Z;87.4163309221209;3.0064437384672646;9.322442130047131;75628284498.58064;25.285835486156067;254950234.8;25.285835486156067 +2022-03-10T07:20:00Z;87.85480027502231;3.0195402729422556;8.863470445127478;75624822982.19354;25.289255163152934;253639316.6;25.289255163152934 +2022-03-10T07:30:00Z;88.01194656285321;2.963649694277745;8.763346990658194;75618750992.51613;25.295253760618067;252585257.3;25.295253760618067 +2022-03-10T07:40:00Z;87.40938282120769;3.050432540039224;9.263218061514555;75614618128.51613;25.29933667064117;250530650.8;25.29933667064117 +2022-03-10T07:50:00Z;87.97849132224233;2.96611809356932;8.77701450706063;75610826223.48387;25.303082742871677;249608456.3;25.303082742871677 +2022-03-10T08:00:00Z;87.64545681831048;2.969637650730503;9.118929125109878;75606952200.25807;25.30690994073213;247072107.4;25.30690994073213 +2022-03-10T08:10:00Z;87.64887424062432;2.9985341697540924;9.101211387401367;75602976700.85246;25.31083738822859;246895062;25.31083738822859 +2022-03-10T08:20:00Z;87.21193468763205;3.0240079236322734;9.510877632025196;75637896357.16129;25.27633980622573;244793608.3;25.27633980622573 +2022-03-10T08:30:00Z;87.43029183089631;2.945969926690443;9.380269002965104;75650815603.6129;25.263576714861433;243724354.1;25.263576714861433 +2022-03-10T08:40:00Z;87.81877529862689;2.9926087418916194;8.93837802268249;75647247591.2258;25.267101600639872;242093089;25.267101600639872 +2022-03-10T08:50:00Z;87.8536143522746;3.074390085482705;8.812903469160208;75642986165.67741;25.27131151828639;239503426.1;25.27131151828639 +2022-03-10T09:00:00Z;88.01172579782967;3.046711865916522;8.682784619091445;75639519364.12903;25.27473641656274;238428622.5;25.27473641656274 +2022-03-10T09:10:00Z;87.92122871943583;2.976464810867665;8.847132821571462;75634858689.04918;25.279340758006832;236655532.1;25.279340758006832 +2022-03-10T09:20:00Z;87.21608982605837;3.0221777118449364;9.481023071133945;75631198340.12903;25.28295686424553;235041305.2;25.28295686424553 +2022-03-10T09:30:00Z;86.9400937546063;2.987223000543285;9.796423875699912;75624685105.54839;25.289391373281426;232939916.4;25.289391373281426 +2022-03-10T09:40:00Z;87.88887077105568;2.9664897356475124;8.882603263311678;75620824493.41936;25.293205322145205;230312266.3;25.293205322145205 +2022-03-10T09:50:00Z;88.02898816399583;3.000297276674096;8.72311768265815;75616910501.16129;25.29707200593175;227144472.8;25.29707200593175 +2022-03-10T10:00:00Z;87.88334258615916;2.9953299370718343;8.846209257417609;75612980785.54839;25.300954223024757;224162849;25.300954223024757 +2022-03-10T10:10:00Z;87.70816051389995;3.0081576357376547;9.03598706710959;75609243648;25.304646189746627;225461677.4;25.304646189746627 +2022-03-10T10:20:00Z;87.6893566673882;2.9464401755936533;9.118379493255123;75605175978.66667;25.308664693111783;225482114.1;25.308664693111783 +2022-03-10T10:30:00Z;87.57619534011307;3.0626547959155093;9.078541217538147;75601595811.67213;25.31220158658478;224744745.3;25.31220158658478 +2022-03-10T10:40:00Z;87.90987609666792;3.0706899748628524;8.676801837825478;75597365578.32259;25.316380689052938;223093132.4;25.316380689052938 +2022-03-10T10:50:00Z;87.96472730361442;3.018641687269843;8.764343017320405;75593896596.64516;25.31980774110708;221943279.5;25.31980774110708 +2022-03-10T11:00:00Z;88.02771686002426;3.0227377034194847;8.701012147776522;75589653074.58064;25.323999971669334;216431781.2;25.323999971669334 +2022-03-10T11:10:00Z;87.4894449219876;3.181382473406324;9.06138700149455;75628141072.51613;25.285977178628006;215145703.2;25.285977178628006 +2022-03-10T11:20:00Z;87.44197218975383;3.069121535069347;9.217760157353048;75626144668.90323;25.287949451686423;212840051.6;25.287949451686423 +2022-03-10T11:30:00Z;87.26687303197052;3.036481305753785;9.430739582376367;75614326519.74193;25.29962475473659;211483127.6;25.29962475473659 +2022-03-10T11:40:00Z;87.56614620166152;2.956230742811135;9.243151205034918;75599136173.41936;25.314631495160402;209629844.6;25.314631495160402 +2022-03-10T11:50:00Z;87.34353503119506;3.12296495118409;9.272062588530938;75628971767.74193;25.285156524025396;207177331.6;25.285156524025396 +2022-03-10T12:00:00Z;88.0335039625564;2.9735509220777643;8.762935606955121;75649520012.3871;25.2648566462605;205607770.8;25.2648566462605 +2022-03-10T12:10:00Z;87.7437723882495;3.031776548244384;8.95791917059054;75645482743.74193;25.268845116390963;203356490.3;25.268845116390963 +2022-03-10T12:20:00Z;87.65003734101937;2.974519595161408;9.098183785796158;75641842588.90323;25.272441272634342;203211478.7;25.272441272634342 +2022-03-10T12:30:00Z;87.65879266946347;2.973300038607966;9.116018102766096;75637616438.55737;25.27661634145012;208003336.3;25.27661634145012 +2022-03-10T12:40:00Z;87.67718835609881;3.0137860992690833;9.053445291347785;75634166750.96774;25.280024332624336;205898063.7;25.280024332624336 +2022-03-10T12:50:00Z;87.61943958777509;2.98818746257522;9.138032516251858;75629889866.32259;25.284249522513345;204174699.4;25.284249522513345 +2022-03-10T13:00:00Z;87.68371947103002;3.0016892899389966;9.075875090393616;75626365588.64516;25.287731202204064;223017554.6;25.287731202204064 +2022-03-10T13:10:00Z;87.21924110087046;2.961625838140368;9.531488124799276;75621798152.25807;25.292243431932597;237365314.1;25.292243431932597 +2022-03-10T13:20:00Z;87.79875214449577;2.909809168108372;9.024902365761323;75618111752.25807;25.295885274371436;235377564.9;25.295885274371436 +2022-03-10T13:30:00Z;87.86037325200189;2.9552024140292463;8.922334472256686;75611700442.2295;25.302219090818532;232262556.9;25.302219090818532 +2022-03-10T13:40:00Z;87.9549116382949;2.9728096400577457;8.79880017775205;75607748406.55737;25.30612335818795;268443715.1;25.30612335818795 +2022-03-10T13:50:00Z;86.95548982017557;3.069433553209999;9.715123669034787;75603925784.7742;25.309899775895634;274452017.5;25.309899775895634 +2022-03-10T14:00:00Z;87.80575181706072;2.9589219188606983;8.991081593506252;75599927956.64516;25.313849282227974;271969095.3;25.313849282227974 +2022-03-10T14:10:00Z;87.5454393267808;2.8579615667901503;9.268329254782607;75596243406.45161;25.317489297218998;270574978.1;25.317489297218998 +2022-03-10T14:20:00Z;87.42883664213795;3.0285739785880255;9.286763676425112;75592096140.3871;25.321586435228685;268718410.3;25.321586435228685 +2022-03-10T14:30:00Z;87.48180955779773;2.992500696502466;9.2755844134236;75588568889.80646;25.325071051889125;266795140.1;25.325071051889125 +2022-03-10T14:40:00Z;87.47040954291897;2.983901444701616;9.296308447024723;75584358333.93549;25.329230714720612;263670090.3;25.329230714720612 +2022-03-10T14:50:00Z;87.54525137583161;2.9501934799116163;9.222308337546767;75580806639.48387;25.332739479798654;262785816.8;25.332739479798654 +2022-03-10T15:00:00Z;87.49208324491218;2.984791600279773;9.275283693270774;75576630305.03226;25.336865334845502;260774086.2;25.336865334845502 +2022-03-10T15:10:00Z;87.12934012642374;3.0590658512115048;9.511631080156768;75587931367.2258;25.325700868726663;259091137;25.325700868726663 +2022-03-10T15:20:00Z;87.35601798864691;3.021982763454978;9.350275640268542;75609942148.12903;25.30395613239706;256724001;25.30395613239706 +2022-03-10T15:30:00Z;87.50836755513426;2.9798868752161574;9.275994009771841;75632420665.80646;25.28174931283328;255833583.5;25.28174931283328 +2022-03-10T15:40:00Z;87.60612678761088;2.9201207314210142;9.216601842128783;75628505860.19672;25.285616800140506;254427069.9;25.285616800140506 +2022-03-10T15:50:00Z;87.2569656514635;3.0463981444654076;9.441097488314698;75624500323.09677;25.289573922265323;252709062.2;25.289573922265323 +2022-03-10T16:00:00Z;87.01619448968887;2.9512631116457952;9.762345240583542;75620823370.32259;25.293206431667095;251937692.9;25.293206431667095 +2022-03-10T16:10:00Z;87.27786137732107;3.007011405186848;9.435837101356524;75616656417.03226;25.297323018942855;250628532.5;25.297323018942855 +2022-03-10T16:20:00Z;87.21755337569553;3.042213541768506;9.474775203700286;75613149316.12903;25.300787729475257;248822486.7;25.300787729475257 +2022-03-10T16:30:00Z;86.81793935270103;3.1099956688207775;9.81091481907582;75608857302.70967;25.30502786527677;247181245.9;25.30502786527677 +2022-03-10T16:40:00Z;86.84008809660205;2.96928182500446;9.932240533725473;75605353240.7742;25.308489573573475;244977796.1;25.308489573573475 +2022-03-10T16:50:00Z;86.92979834396755;3.0283267523235464;9.789089313952035;75601156505.6;25.312635582759132;242595906.1;25.312635582759132 +2022-03-10T17:00:00Z;86.87703799691792;2.945558395147734;9.92344071979579;75597505569.03226;25.316242390412654;240173056;25.316242390412654 +2022-03-10T17:10:00Z;87.04037133933012;2.956239107118537;9.743372206552854;75594374837.67741;25.31933528057992;238341813.7;25.31933528057992 +2022-03-10T17:20:00Z;87.02258304204902;3.08743731745652;9.606988434392683;75590568926.96774;25.32309518920106;236273731.1;25.32309518920106 +2022-03-10T17:30:00Z;87.26015368772791;2.996221978149526;9.48484280478493;75584333427.6129;25.329255320000172;234322448.5;25.329255320000172 +2022-03-10T17:40:00Z;87.301483825786;3.0825920056291403;9.326068150403044;75580271384.7742;25.33326826487821;232111203.1;25.33326826487821 +2022-03-10T17:50:00Z;87.46368491195116;2.9942000537691773;9.262932936497515;75576575075.09677;25.33691989721608;230232988.9;25.33691989721608 +2022-03-10T18:00:00Z;87.29899466162908;2.994114982628299;9.466609910048033;75572401135.21312;25.34104338663814;227957132.4;25.34104338663814 +2022-03-10T18:10:00Z;86.45770373332694;3.134145758731105;10.144022407008359;75568899369.29033;25.34450282667409;226173456.5;25.34450282667409 +2022-03-10T18:20:00Z;87.10931908405956;2.9981867075215565;9.602562182664238;75564512355.09677;25.3488368149743;225761313.6;25.3488368149743 +2022-03-10T18:30:00Z;87.33635326606023;3.0001062965592995;9.402846307687064;75560934102.70967;25.352371816981734;231379279.7;25.352371816981734 +2022-03-10T18:40:00Z;87.20499672277037;2.9177084804722635;9.60771749273211;75556556205.41936;25.356696798574834;230561990.2;25.356696798574834 +2022-03-10T18:50:00Z;86.92545391830744;3.0610261926422297;9.734528480762421;75572906151.86885;25.340544474124812;230055407.5;25.340544474124812 +2022-03-10T19:00:00Z;87.12130428976323;3.00053425890349;9.616415573486927;75603519588.72131;25.31030106225194;227225401.8;25.31030106225194 +2022-03-10T19:10:00Z;86.95409345745;3.061149750757566;9.71533048496385;75621183752.25807;25.292850405672397;226703161.8;25.292850405672397 +2022-03-10T19:20:00Z;86.72150938855711;3.010271014074953;9.999282121074105;75618308690.58064;25.295690716444735;225015940.1;25.295690716444735 +2022-03-10T19:30:00Z;86.93248013128417;2.999577267378668;9.817357147574764;75611618072.7742;25.30230046467325;223865268.5;25.30230046467325 +2022-03-10T19:40:00Z;86.7563895538797;3.0245347877392095;9.948824433262487;75608100731.87097;25.305775291434657;220813642.3;25.305775291434657 +2022-03-10T19:50:00Z;87.13464404205918;2.968396251830875;9.65005902322204;75603824111.48387;25.31000022025968;220944450.1;25.31000022025968 +2022-03-10T20:00:00Z;86.96985601143766;2.9885294865633667;9.781067176203583;75600291000.65573;25.313490626334715;219932407.7;25.313490626334715 +2022-03-10T20:10:00Z;86.70612220383076;2.9277781193654313;10.083393021821927;75596150519.74193;25.317581061205896;217329201.5;25.317581061205896 +2022-03-10T20:20:00Z;86.98646093121391;3.018022271058837;9.73247692202203;75592430691.09677;25.321255928237466;215583248.5;25.321255928237466 +2022-03-10T20:30:00Z;86.86951646871529;3.000565903141106;9.865058453507842;75588442045.93549;25.325196362596692;211954258.6;25.325196362596692 +2022-03-10T20:40:00Z;87.11607041458164;3.041958501491934;9.567158763103226;75584190397.93549;25.329396620876167;204020282.8;25.329396620876167 +2022-03-10T20:50:00Z;87.2198569994312;2.9962494885097817;9.521852960187077;75580383628.3871;25.333157377955214;202828502.7;25.333157377955214 +2022-03-10T21:00:00Z;87.01761271716279;3.036275032469184;9.671588688826883;75576286571.35484;25.337204913809817;202021326.5;25.337204913809817 +2022-03-10T21:10:00Z;87.10823271970607;2.966799067313864;9.66935616276092;75572290543.21312;25.34115264191132;234530221.4;25.34115264191132 +2022-03-10T21:20:00Z;86.92923492353482;3.0108721388222257;9.797361073251594;75568032999.2258;25.34535872491322;245303956.6;25.34535872491322 +2022-03-10T21:30:00Z;86.92646173466193;2.97814890247958;9.825024281252672;75556379218.58064;25.356871646171495;243931532.4;25.356871646171495 +2022-03-10T21:40:00Z;87.18348245573522;2.985326861609318;9.563021733785318;75549470059.35484;25.36369729430661;241184969.4;25.36369729430661 +2022-03-10T21:50:00Z;87.17878090171979;3.0034173184598556;9.53985598927125;75545896893.93549;25.367227270832547;238859891.6;25.367227270832547 +2022-03-10T22:00:00Z;87.1503941730815;3.0132775145546984;9.54775303194748;75541815428.12903;25.371259403912685;236445497.8;25.371259403912685 +2022-03-10T22:10:00Z;87.13590558912047;2.962218128693773;9.623017192059397;75538067388.85246;25.37496214059342;234490120.3;25.37496214059342 +2022-03-10T22:20:00Z;86.89230240142908;3.1124709922589187;9.733346570914144;75550547296.5246;25.362633077715483;231277006.5;25.362633077715483 +2022-03-10T22:30:00Z;86.2509119327352;2.9623541169558054;10.50961267751489;75585917522.58064;25.32769037200736;230044903.2;25.32769037200736 +2022-03-10T22:40:00Z;87.53455745871753;2.9094624506657136;9.295958038148205;75582139821.41936;25.33142241204926;227972723.6;25.33142241204926 +2022-03-10T22:50:00Z;87.25066653003688;3.0255280408716527;9.486302941934504;75578072757.67741;25.335440317142805;225470805.3;25.335440317142805 +2022-03-10T23:00:00Z;87.02266556787914;2.970599931957852;9.760568467414204;75574453413.16129;25.339015914598214;224252168.3;25.339015914598214 +2022-03-10T23:10:00Z;87.01064104259864;3.003786237558298;9.68506050019031;75599248879.48387;25.314520151375433;228567832.8;25.314520151375433 +2022-03-10T23:20:00Z;86.91999725513284;2.938783214560225;9.869821677862681;75596671681.04918;25.317066199181628;227091621.2;25.317066199181628 +2022-03-10T23:30:00Z;86.98291799212197;2.95864303337419;9.787013868795045;75589967475.6129;25.32368937080615;227327471.5;25.32368937080615 +2022-03-10T23:40:00Z;87.25713660256892;2.984584957125917;9.496268087009321;75586315164.90323;25.327297535992315;227199636.6;25.327297535992315 +2022-03-10T23:50:00Z;87.10862323424186;3.032071365620867;9.603021280480627;75582197693.93549;25.331365239038938;225719196.9;25.331365239038938 +2022-03-11T00:00:00Z;87.15821910006754;3.0383941967077828;9.5436720766655;75578463397.16129;25.33505439932308;221951765;25.33505439932308 +2022-03-11T00:10:00Z;87.10781799119557;2.954289563068938;9.66334409676374;75574725665.03226;25.3387469534389;219464274.6;25.3387469534389 +2022-03-11T00:20:00Z;87.27429968367736;3.0533284061729242;9.387328416321717;75570884475.87097;25.342541714100577;216346029.4;25.342541714100577 +2022-03-11T00:30:00Z;87.2998526260981;3.0221438700991627;9.41509138235533;75567090301.90164;25.346290027843484;214470656;25.346290027843484 +2022-03-11T00:40:00Z;86.99256350993967;3.1035536484554838;9.65815892117226;75563054377.29033;25.350277170185457;210951993.8;25.350277170185457 +2022-03-11T00:50:00Z;87.59037672724293;3.089298482804983;9.069676695141432;75559395394.06451;25.35389192723699;217477318.2;25.35389192723699 +2022-03-11T01:00:00Z;87.25740787753101;2.967584986986501;9.507757982618958;75555209744.51613;25.358026984788932;251149328.8;25.358026984788932 +2022-03-11T01:10:00Z;87.93785127513809;2.951107796663727;8.824099542987298;75551296412.90323;25.361893015915534;249807178.3;25.361893015915534 +2022-03-11T01:20:00Z;87.6958361014141;3.0646795052942575;8.960792028844361;75547015630.45161;25.366122056498153;247633589.7;25.366122056498153 +2022-03-11T01:30:00Z;87.60731467140403;2.9857055725932846;9.146940891660817;75541088826.7541;25.371977222848063;246052731.9;25.371977222848063 +2022-03-11T01:40:00Z;87.52305377052802;3.066413102233851;9.141906704749264;75536815335.2258;25.37619906063283;244245999.5;25.37619906063283 +2022-03-11T01:50:00Z;87.23463731663988;3.100598558804478;9.396198898706691;75543962194.58064;25.369138585453005;242615527.2;25.369138585453005 +2022-03-11T02:00:00Z;87.49708750963534;3.1087557042944183;9.125340820537824;75584962890.32259;25.328633465613834;240072968.3;25.328633465613834 +2022-03-11T02:10:00Z;87.78611883717689;3.0491840179898535;8.869300515675574;75581108752.51613;25.332441018410254;238084027.7;25.332441018410254 +2022-03-11T02:20:00Z;87.65801811052548;3.032654416937814;9.012984543693719;75577256200.25807;25.33624700482282;235788155.9;25.33624700482282 +2022-03-11T02:30:00Z;87.42737543623328;3.061250360892489;9.226295714600196;75573251633.54839;25.34020316828649;232942096.5;25.34020316828649 +2022-03-11T02:40:00Z;87.24666639012834;2.95348262201048;9.536753523005098;75569569187.67213;25.343841104395118;230659963.9;25.343841104395118 +2022-03-11T02:50:00Z;86.32448731021837;3.067464034106567;10.325884949164923;75565415589.16129;25.34794449831079;229260122.8;25.34794449831079 +2022-03-11T03:00:00Z;86.61157633231761;2.9635822543529153;10.170593639228596;75561905713.54839;25.35141195001493;227143151.5;25.35141195001493 +2022-03-11T03:10:00Z;87.0770393229085;2.9938217471648745;9.655863599199996;75579447824.51613;25.334081870753533;224811668.6;25.334081870753533 +2022-03-11T03:20:00Z;87.02400638977419;3.077537152956874;9.61107461833065;75572231795.6129;25.34121067942858;223459361.6;25.34121067942858 +2022-03-11T03:30:00Z;87.14826854106039;3.0919105426526743;9.476246586105347;75561673893.16129;25.351640968386217;221421369.8;25.351640968386217 +2022-03-11T03:40:00Z;86.98920191320255;3.0783464773142337;9.651403508663368;75557956310.70967;25.355313616374;220123069.9;25.355313616374 +2022-03-11T03:50:00Z;87.12408331712413;3.0150361027063926;9.597422514209121;75553890371.14754;25.359330410875728;217487492.1;25.359330410875728 +2022-03-11T04:00:00Z;87.08572569470387;3.0644592054144475;9.547055518999084;75550109762.06451;25.36306532369127;215476488.3;25.36306532369127 +2022-03-11T04:10:00Z;87.1757012321955;3.0090280492738892;9.532640994432914;75546229793.03226;25.366898395491155;214327031.7;25.366898395491155 +2022-03-11T04:20:00Z;87.0750035979112;2.9927028407725964;9.666426365799941;75542262486.70967;25.37081774893448;212627254.6;25.37081774893448 +2022-03-11T04:30:00Z;86.65120711258609;3.069338685175054;10.018986585164358;75538526538.32259;25.374508540868458;209659573.7;25.374508540868458 +2022-03-11T04:40:00Z;86.94870768907869;3.099681675041093;9.65971413345325;75534414154.32259;25.378571218433585;240529143.7;25.378571218433585 +2022-03-11T04:50:00Z;87.14113961111528;3.0059738629399586;9.573634562888591;75530869441.04918;25.382073086714996;256514774.7;25.382073086714996 +2022-03-11T05:00:00Z;87.20019441446337;2.974304628896461;9.535155220950733;75526581130.4918;25.386309564411064;254941844.6;25.386309564411064 +2022-03-11T05:10:00Z;86.16660919428064;3.014636129491112;10.487017527935537;75547636967.2258;25.365508229829015;253135112.3;25.365508229829015 +2022-03-11T05:20:00Z;87.08072725556615;3.052235667218001;9.607280563673447;75549596176.51613;25.363572701524962;250976784.5;25.363572701524962 +2022-03-11T05:30:00Z;87.1417941298065;3.0203716185267124;9.566338240482127;75594030377.29033;25.31967557747019;249428923.7;25.31967557747019 +2022-03-11T05:40:00Z;87.16224083511024;3.0921224934551645;9.497161284932242;75589858403.09677;25.32379712496145;246544978.6;25.32379712496145 +2022-03-11T05:50:00Z;87.15603858389066;3.037578718570136;9.565917850972578;75586111950.45161;25.32749829418842;244159719.2;25.32749829418842 +2022-03-11T06:00:00Z;87.08077189796359;2.9937442707366193;9.652560456640193;75582197625.70493;25.331365306444795;241731187.6;25.331365306444795 +2022-03-11T06:10:00Z;87.07499101096793;3.011181842519501;9.642066310314839;75578277755.87097;25.3352377967649;244636506.8;25.3352377967649 +2022-03-11T06:20:00Z;87.29081609614366;3.02647348720364;9.405805173942694;75574469136.51613;25.339000381291772;243870356.6;25.339000381291772 +2022-03-11T06:30:00Z;86.4930381795378;3.0556337999970173;10.174488413745118;75570347635.6129;25.343072065563977;242160757.5;25.343072065563977 +2022-03-11T06:40:00Z;87.19854482432302;3.0423034265456943;9.50159797593579;75566684093.93549;25.346691325969072;240197698.1;25.346691325969072 +2022-03-11T06:50:00Z;87.21966224178797;3.085846584073337;9.41075956043751;75562401990.19354;25.350921671871546;238160598.7;25.350921671871546 +2022-03-11T07:00:00Z;87.19632936638901;3.027327335354976;9.493690164467056;75558897531.87097;25.354383771764216;236401366.7;25.354383771764216 +2022-03-11T07:10:00Z;87.01094516890554;3.0098324056797874;9.698683130833432;75575036676.19672;25.33843970147012;234802209;25.33843970147012 +2022-03-11T07:20:00Z;86.4586385356263;3.0487497066440556;10.222737932363541;75570939441.54839;25.34248741279395;233508005.2;25.34248741279395 +2022-03-11T07:30:00Z;86.9006285840205;3.0961466772870834;9.73337434961752;75566793298.58064;25.346583441281762;230728552.9;25.346583441281762 +2022-03-11T07:40:00Z;87.00629149144784;3.0758959270543236;9.630692090198114;75562970277.16129;25.350360253795216;237988170.3;25.350360253795216 +2022-03-11T07:50:00Z;87.29453379316008;2.987926876045488;9.447462585941132;75559023649.03226;25.354259178982566;244578304;25.354259178982566 +2022-03-11T08:00:00Z;87.09319607330734;3.0848027638529487;9.528614382156677;75555026613.67741;25.358207902122977;242035325.9;25.358207902122977 +2022-03-11T08:10:00Z;87.15295471580397;3.0490427544025414;9.52594897954893;75551238672.51613;25.361950058393877;239872436.5;25.361950058393877 +2022-03-11T08:20:00Z;87.28597577780856;3.0441869238730637;9.3945331558866;75547070531.14754;25.366067819387585;236237989.2;25.366067819387585 +2022-03-11T08:30:00Z;86.95717325852642;3.039031493061466;9.739510741975016;75543439624.25807;25.36965483946179;239286800.5;25.36965483946179 +2022-03-11T08:40:00Z;87.3184318169992;3.0592899792695745;9.32810881029335;75539263421.93549;25.373780563976666;272193007.5;25.373780563976666 +2022-03-11T08:50:00Z;84.64369764593717;3.266364607247728;11.70452715984775;75470355885.41936;25.441855214269776;270252692.6;25.441855214269776 +2022-03-11T09:00:00Z;86.93268709191872;3.1482908836300814;9.667229716775742;75401917142.70967;25.50946673707283;267119516.9;25.50946673707283 +2022-03-11T09:10:00Z;87.10469417735563;3.019525119529226;9.612849531109527;75394695300.12903;25.516601289155318;266577819.3;25.516601289155318 +2022-03-11T09:20:00Z;86.93859026881759;3.078815301599058;9.723763758167447;75390361326.93333;25.520882877564848;264132938.3;25.520882877564848 +2022-03-11T09:30:00Z;86.53918661940376;3.093909403634959;10.09418991183249;75384182321.54839;25.526987197237357;262045828.1;25.526987197237357 +2022-03-11T09:40:00Z;86.7715667913041;3.0298099743017195;9.918439206536831;75380198895.48387;25.5309224755831;1302400231;25.5309224755831 +2022-03-11T09:50:00Z;87.07141416947013;3.0342638271455185;9.634892882373444;75376234297.80646;25.534839153120682;2766395987;25.534839153120682 +2022-03-11T10:00:00Z;87.06159361575887;3.0730987089084767;9.582810329133842;75372393703.2258;25.538633326388428;2443462590;25.538633326388428 +2022-03-11T10:10:00Z;87.1360057496349;2.9493155377916698;9.657954807330084;75368288123.87097;25.5426892815562;2258381278;25.5426892815562 +2022-03-11T10:20:00Z;86.77596430479618;3.0601278992161958;9.893749397009428;75364609123.09677;25.546323814203763;1686919498;25.546323814203763 +2022-03-11T10:30:00Z;86.71844732328644;3.0682415658477082;9.933114142003872;75360336174.16394;25.550545115951444;2217907960;25.550545115951444 +2022-03-11T10:40:00Z;87.36577351208552;2.8901770412475454;9.46360557668547;75356817077.67741;25.554021677076385;2164488830;25.554021677076385 +2022-03-11T10:50:00Z;86.66337949266945;3.0492272509051563;9.979517049966216;75352483311.48387;25.5583030609858;2155603109;25.5583030609858 +2022-03-11T11:00:00Z;86.94250723511263;3.113983790063754;9.692546313814463;75348902350.45161;25.561840738898972;3110200287;25.561840738898972 +2022-03-11T11:10:00Z;86.82877068809708;3.0762149147263056;9.824594694493182;75367846020.12903;25.54312604158489;3173183554;25.54312604158489 +2022-03-11T11:20:00Z;87.21353703083727;3.075657873789423;9.428831282186737;75364873777.54839;25.546062358633694;3167987712;25.546062358633694 +2022-03-11T11:30:00Z;87.00088074593734;3.0855221378759197;9.611452510634575;75358401922.09836;25.552455988689022;3154777121;25.552455988689022 +2022-03-11T11:40:00Z;86.97523560530954;3.0631471515940483;9.688926864191846;75354396870.19354;25.556412631483276;3130144306;25.556412631483276 +2022-03-11T11:50:00Z;86.81453423123784;3.095340728395059;9.803553315956346;75350519543.74193;25.560243092643415;3127608183;25.560243092643415 +2022-03-11T12:00:00Z;86.78553640101008;3.05843084628171;9.850541065551326;75346433981.93549;25.564279272215146;3122898217;25.564279272215146 +2022-03-11T12:10:00Z;86.8414853704786;3.066861751991692;9.82012374264825;75342706621.93549;25.56796157956997;3132035468;25.56796157956997 +2022-03-11T12:20:00Z;86.70001161751803;3.126300911047808;9.89138604667733;75356713094.29507;25.554124403610324;3145784617;25.554124403610324 +2022-03-11T12:30:00Z;86.91122441984791;3.0870527886832266;9.742955066168017;75390403432.91803;25.520841280515683;3141558470;25.520841280515683 +2022-03-11T12:40:00Z;87.08633354749432;3.044225097297618;9.585684534279974;75386093700.12903;25.52509892151261;3138790301;25.52509892151261 +2022-03-11T12:50:00Z;87.07249488017877;3.076988121080237;9.572910813096323;75382545176.7742;25.52860455382297;3135233982;25.52860455382297 +2022-03-11T13:00:00Z;87.0776620287924;3.0975199601492687;9.542753210108184;75378291877.16129;25.532806443752264;3130812315;25.532806443752264 +2022-03-11T13:10:00Z;86.91643306599994;2.992567719479463;9.785782197794015;75374150028.3871;25.536898229950488;3124148753;25.536898229950488 +2022-03-11T13:20:00Z;86.75753485125583;3.0354700876125924;9.93611818388973;75370047884.3871;25.540950791286605;3122494431;25.540950791286605 +2022-03-11T13:30:00Z;87.27430634500621;3.002323756438825;9.441854217293118;75363748500.64516;25.547174034301456;3119981667;25.547174034301456 +2022-03-11T13:40:00Z;87.30070169131854;2.998713780573411;9.4254324389027;75359742546.58064;25.55113156835099;3117500218;25.55113156835099 +2022-03-11T13:50:00Z;87.07409226565227;3.133961364252776;9.500898667205252;75355718358.70967;25.555107115814735;3108496417;25.555107115814735 +2022-03-11T14:00:00Z;86.62043811797534;3.028963299050952;10.068083586826996;75351946867.6129;25.55883302085324;3064351116;25.55883302085324 +2022-03-11T14:10:00Z;86.96103742665534;3.108020967070202;9.646281679893821;75347822625.57378;25.56290741312923;3063284835;25.56290741312923 +2022-03-11T14:20:00Z;87.68674713566212;3.0064298465386305;9.032220827194752;75344167046.29507;25.566518807377186;3061960175;25.566518807377186 +2022-03-11T14:30:00Z;87.3238021411431;3.1586300780424845;9.21715741684003;75339884411.87097;25.570749677547493;3062924453;25.570749677547493 +2022-03-11T14:40:00Z;87.20096486276171;3.079317164919296;9.458966131792476;75336387352.7742;25.574204467648876;3060849895;25.574204467648876 +2022-03-11T14:50:00Z;87.43407616281766;3.049111985675641;9.262659765165084;75332113441.03226;25.578426720568157;3058557457;25.578426720568157 +2022-03-11T15:00:00Z;86.90344776452834;3.0717252008450613;9.750417595637021;75328437413.16129;25.582058316246023;3055662198;25.582058316246023 +2022-03-11T15:10:00Z;86.86785013403544;3.053727098782965;9.796418151063797;75340901276.90323;25.56974510337511;3053007310;25.56974510337511 +2022-03-11T15:20:00Z;86.9950511671855;3.082632193444702;9.648066835331951;75335005047.46666;25.57557006501552;3050311812;25.57557006501552 +2022-03-11T15:30:00Z;86.49082344475111;3.1606273508274567;10.078061036943538;75328604226.06451;25.58189351961236;3044634558;25.58189351961236 +2022-03-11T15:40:00Z;86.80561530327431;3.01533280068717;9.906943303191541;75324536105.29033;25.585912468961816;3040992950;25.585912468961816 +2022-03-11T15:50:00Z;86.90986878873194;3.1202405252387404;9.686044534985225;75349284467.6129;25.56146324039241;3038276113;25.56146324039241 +2022-03-11T16:00:00Z;87.90826433968112;3.00873975582356;8.822970927710305;75375718730.32259;25.535348488934183;3035193410;25.535348488934183 +2022-03-11T16:10:00Z;87.57573726780862;3.1745024495154555;8.973579455248876;75372070779.87097;25.538952346564788;3032600781;25.538952346564788 +2022-03-11T16:20:00Z;87.83205442468709;3.00169544490649;8.874915452831273;75367785901.41936;25.543185433638993;3028859541;25.543185433638993 +2022-03-11T16:30:00Z;87.75808786324697;3.048906035871962;8.923940969794184;75364297610.4918;25.54663156155213;3027020238;25.54663156155213 +2022-03-11T16:40:00Z;87.6539988369934;3.0261589269764717;9.050913461693439;75359993393.54839;25.550883753373572;3024050374;25.550883753373572 +2022-03-11T16:50:00Z;87.33452599195695;3.063897863043277;9.321776687533488;75356383165.93549;25.55445034412186;3022521047;25.55445034412186 +2022-03-11T17:00:00Z;87.66212821461785;3.100758421333915;8.967295621942608;75352218128.51613;25.558565038683813;3021766127;25.558565038683813 +2022-03-11T17:10:00Z;87.62546932240369;3.0746698901963536;9.002972811394;75349308449.03226;25.561439548836756;3019696987;25.561439548836756 +2022-03-11T17:20:00Z;87.78494030162277;3.0327672715531198;8.93056288992499;75345345569.03226;25.565354529458514;3017671865;25.565354529458514 +2022-03-11T17:30:00Z;87.47539491964021;3.034214177313003;9.227090590576069;75339013808.2623;25.571609758159862;3016600675;25.571609758159862 +2022-03-11T17:40:00Z;87.44806475913306;3.1576990611295974;9.13271630930008;75335043270.19354;25.575532304287197;3014377010;25.575532304287197 +2022-03-11T17:50:00Z;86.77782720645244;3.181571825187893;9.769583612163746;75330962927.48387;25.579563327845445;3011900978;25.579563327845445 +2022-03-11T18:00:00Z;87.75415396038032;3.10894302435114;8.856782686890371;75327255783.2258;25.583225663806257;3009487310;25.583225663806257 +2022-03-11T18:10:00Z;87.54772678878439;3.1604434618786947;9.01592088797675;75323012591.48387;25.587417568038553;3007036449;25.587417568038553 +2022-03-11T18:20:00Z;87.73121477781872;3.1018675103056728;8.875004674586707;75319480386.06451;25.5909070796485;3004728840;25.5909070796485 +2022-03-11T18:30:00Z;87.42755877581322;3.1278540984163463;9.176440289022871;75315169610.32259;25.595165750992184;3000685618;25.595165750992184 +2022-03-11T18:40:00Z;87.80150425450356;2.9849245513021976;8.966928777036362;75311685222.4;25.598608023076007;2995451970;25.598608023076007 +2022-03-11T18:50:00Z;87.49452266988747;3.101019000244791;9.144878744856143;75307513150.95082;25.60272966664739;2991015011;25.60272966664739 +2022-03-11T19:00:00Z;87.06391138554682;3.1901062169379784;9.458751406103735;75303855401.29033;25.60634320504371;2984848219;25.60634320504371 +2022-03-11T19:10:00Z;87.41765491392746;3.1759099491340366;9.10827599072584;75321368906.32259;25.589041385957522;2981113988;25.589041385957522 +2022-03-11T19:20:00Z;87.7235115116279;3.108570249810585;8.873732591548606;75348221423.48387;25.562513435494267;2977981869;25.562513435494267 +2022-03-11T19:30:00Z;87.82566083799334;3.054930146454303;8.866849133017983;75367951242.4918;25.543022091046087;2971765844;25.543022091046087 +2022-03-11T19:40:00Z;87.67689486817011;3.103003089519159;8.955035950232396;75363814618.2295;25.547108715881144;2967156406;25.547108715881144 +2022-03-11T19:50:00Z;86.74989443255703;3.024126021968413;9.967152816372408;75360151485.93549;25.55072757185106;2967763340;25.55072757185106 +2022-03-11T20:00:00Z;87.72267041779904;3.0923511754848625;8.931515830519476;75356004418.06451;25.55482451406277;2991881381;25.55482451406277 +2022-03-11T20:10:00Z;87.81067568647573;3.088933390183755;8.8501787236484;75352473996.3871;25.55831226349088;2990335141;25.55831226349088 +2022-03-11T20:20:00Z;87.71900299206682;3.103161033309381;8.883697277573074;75348197838.45161;25.562536735453953;2988632593;25.562536735453953 +2022-03-11T20:30:00Z;87.67315153946623;3.0501266936352556;9.022093915759392;75344752573.93549;25.565940357016412;2986782984;25.565940357016412 +2022-03-11T20:40:00Z;87.31379268818092;2.9734024616011094;9.451903344303123;75340519323.27869;25.57012244032159;2978344691;25.57012244032159 +2022-03-11T20:50:00Z;87.26476059257142;3.0745661874007024;9.390442292878397;75336901400.7742;25.57369663295323;2978716969;25.57369663295323 +2022-03-11T21:00:00Z;87.28852956026729;3.041894945149362;9.409716823362748;75332837376;25.577711535811087;2979413487;25.577711535811087 +2022-03-11T21:10:00Z;87.11103611400907;3.064385489040942;9.545230292422579;75328615985.54839;25.581881902265522;2978291183;25.581881902265522 +2022-03-11T21:20:00Z;87.08095831240426;2.968870014701092;9.666367231489007;75324687723.35484;25.58576268350667;2975418897;25.58576268350667 +2022-03-11T21:30:00Z;86.99242665346418;3.023818227660267;9.726760778415285;75318277020.90323;25.592095899720604;2968970405;25.592095899720604 +2022-03-11T21:40:00Z;87.17436914807699;3.064136661341629;9.496797141954056;75314450564.12903;25.595876106065727;2964428162;25.595876106065727 +2022-03-11T21:50:00Z;86.95040252355913;3.020489331905822;9.74254795655281;75310327505.83606;25.599949328903506;2961909562;25.599949328903506 +2022-03-11T22:00:00Z;86.02621451139748;2.9773032496675;10.74634986713108;75306773603.09677;25.603460275577625;2959237781;25.603460275577625 +2022-03-11T22:10:00Z;86.68612532773237;3.017988817062923;10.029947290909528;75302519841.03226;25.60766262236887;2956421715;25.60766262236887 +2022-03-11T22:20:00Z;86.79969002231381;3.033505493191347;9.906695076002467;75298010409.29033;25.612117548555084;2955201767;25.612117548555084 +2022-03-11T22:30:00Z;86.93783949615984;3.0361008713827533;9.742254414192981;75286446542.45161;25.623541642796162;2953468631;25.623541642796162 +2022-03-11T22:40:00Z;87.29113133593412;3.069994226230863;9.352099527964176;75282880974.45161;25.627064113732857;2952037277;25.627064113732857 +2022-03-11T22:50:00Z;87.28250278631909;3.041926414023714;9.408353375825085;75302527647.4754;25.6076549102823;2950986433;25.6076549102823 +2022-03-11T23:00:00Z;87.4838192334397;2.9722172664178124;9.290682619077284;75330750530.06451;25.579773158014635;2948862745;25.579773158014635 +2022-03-11T23:10:00Z;87.1522463184429;2.9539464409068072;9.609220048970165;75376751054.45161;25.534328642519316;2943606784;25.534328642519316 +2022-03-11T23:20:00Z;87.19964391902452;2.9022460796088416;9.641312060082706;75374439787.35484;25.536611973302872;2937994339;25.536611973302872 +2022-03-11T23:30:00Z;86.6880149879559;2.924351951527238;10.093701374514806;75368215651.09677;25.542760878351103;2936089963;25.542760878351103 +2022-03-11T23:40:00Z;86.98405835115139;3.145449993454118;9.585737128292488;75364088072.25807;25.54683856709472;2933599265;25.54683856709472 +2022-03-11T23:50:00Z;87.19561637041507;3.0839023055838477;9.442980367891463;75360459280.51613;25.55042349758721;2931170052;25.55042349758721 +2022-03-12T00:00:00Z;87.11641344881627;3.040896823505646;9.554404053190519;75356220902.81967;25.554610645961446;2928296927;25.554610645961446 +2022-03-12T00:10:00Z;86.73993850186162;2.9445866786620787;10.027404878038338;75352970273.03226;25.5578219853475;2926246152;25.5578219853475 +2022-03-12T00:20:00Z;87.0424171814653;3.060411358928528;9.62339638658244;75348760774.19354;25.5619806039231;2923501172;25.5619806039231 +2022-03-12T00:30:00Z;86.99388230586847;3.129363088044342;9.621870061924696;75345226917.16129;25.56547174718289;2921883582;25.56547174718289 +2022-03-12T00:40:00Z;86.58110403562499;3.0169701250079313;10.129594655858636;75341066107.87097;25.569582264721248;2912471172;25.569582264721248 +2022-03-12T00:50:00Z;86.56588454659739;3.082333788698185;10.080740274890502;75337389749.67741;25.573214186729075;2909112824;25.573214186729075 +2022-03-12T01:00:00Z;86.91887650057551;3.0787316905769093;9.733297021292266;75333386911.4754;25.577168642577575;2906221667;25.577168642577575 +2022-03-12T01:10:00Z;87.27309950944091;3.049469790764545;9.408487185691817;75329082619.80328;25.581420908224477;2903674153;25.581420908224477 +2022-03-12T01:20:00Z;87.19506091514532;3.114725900800127;9.43403516217359;75325247223.74193;25.585209945807485;2904694454;25.585209945807485 +2022-03-12T01:30:00Z;87.28456642098885;3.0038457633604594;9.452966883954636;75318857067.35484;25.59152286429743;2902885409;25.59152286429743 +2022-03-12T01:40:00Z;87.13444888609204;3.1326494174882065;9.415945221003367;75314832813.41936;25.595498477027178;2902941762;25.595498477027178 +2022-03-12T01:50:00Z;87.20722531463403;3.084102978948575;9.429492283755417;75302562056.25807;25.607620917399004;2900547452;25.607620917399004 +2022-03-12T02:00:00Z;87.15825017257916;3.0641273640423923;9.49771028950048;75299042204.90323;25.61109822426817;2899607415;25.61109822426817 +2022-03-12T02:10:00Z;87.06485930834471;3.0631431162551914;9.599014670574608;75294782648.65573;25.615306295208043;2893909818;25.615306295208043 +2022-03-12T02:20:00Z;86.97952826648604;3.09334315124316;9.664688798948324;75310178370.06451;25.600096662069188;2890059181;25.600096662069188 +2022-03-12T02:30:00Z;87.02243772313176;3.0234945184680755;9.696214181857489;75342889224.25807;25.567781184363866;2888292682;25.567781184363866 +2022-03-12T02:40:00Z;87.67998974961185;3.117262903386206;8.942812459238105;75339283224.7742;25.571343598088582;2885652546;25.571343598088582 +2022-03-12T02:50:00Z;87.6262937560397;3.0961768391689852;9.02358064258106;75335294051.09677;25.575284554575763;2883812302;25.575284554575763 +2022-03-12T03:00:00Z;87.7633827939775;3.055026584886786;8.923236992310466;75331604281.80646;25.578929725580277;2881086893;25.578929725580277 +2022-03-12T03:10:00Z;87.53562787410114;3.09357018825429;9.102831253123458;75349436217.80646;25.561313324405273;2879225460;25.561313324405273 +2022-03-12T03:20:00Z;87.43363692275726;3.1319111677663107;9.159125764783012;75346198998.03279;25.564511415864587;2876478299;25.564511415864587 +2022-03-12T03:30:00Z;87.60802946533425;3.0686052861641993;9.05161844672573;75340006631.2258;25.57062893545946;2874454148;25.57062893545946 +2022-03-12T03:40:00Z;87.33934332168266;3.1524988750514558;9.232636838944915;75335830362.83871;25.574754725240304;2920048708;25.574754725240304 +2022-03-12T03:50:00Z;87.34963407566606;3.093844476729342;9.2891879966507;75332225882.83871;25.578315637847183;2919329858;25.578315637847183 +2022-03-12T04:00:00Z;86.91417056260262;3.1067524393373582;9.685321945743365;75327969147.87097;25.582520921608143;2917695818;25.582520921608143 +2022-03-12T04:10:00Z;87.32310129868716;3.0731710787412316;9.334574936912896;75324516748.3871;25.58593159189792;2915816283;25.58593159189792 +2022-03-12T04:20:00Z;87.45264306638113;3.1363509160213967;9.143329687857419;75320327721.96721;25.59006998550505;2914476771;25.59006998550505 +2022-03-12T04:30:00Z;87.66188739029954;3.0671333717587546;9.027444342337406;75316607412.45901;25.59374532758746;2912577206;25.59374532758746 +2022-03-12T04:40:00Z;86.8510917186914;3.112414210085052;9.767772619656096;75312622426.83871;25.597682146638626;2910854838;25.597682146638626 +2022-03-12T04:50:00Z;87.52375931851356;3.075190908172028;9.132866122691713;75308785531.87097;25.601472665010725;2908656673;25.601472665010725 +2022-03-12T05:00:00Z;87.37959515210208;3.0883316355380894;9.265531197395196;75304931460.12903;25.605280152541134;2907516598;25.605280152541134 +2022-03-12T05:10:00Z;87.46989796240942;3.139724415814003;9.127674107777057;75301851136;25.608323244755358;2905269567;25.608323244755358 +2022-03-12T05:20:00Z;87.68003833519874;3.0997668170222785;8.938207098261778;75298168832;25.611961040702607;2900260600;25.611961040702607 +2022-03-12T05:30:00Z;87.57703445796467;3.055543042329489;9.073072967851855;75291646254.16394;25.618404780061883;2898187693;25.618404780061883 +2022-03-12T05:40:00Z;87.38702959974404;3.157464563856933;9.161662873000761;75288018415.48387;25.621988769012173;2895958809;25.621988769012173 +2022-03-12T05:50:00Z;87.01820576444709;3.158895913095547;9.550564936823509;75298113403.87097;25.612015798871173;2894023449;25.612015798871173 +2022-03-12T06:00:00Z;87.5160249766516;3.1236263479603315;9.074890488494068;75335919880.25807;25.57466628981908;2891884280;25.57466628981908 +2022-03-12T06:10:00Z;87.76174534318939;3.0122837238590785;8.94426824039749;75331708795.87097;25.578826474778523;2879378333;25.578826474778523 +2022-03-12T06:20:00Z;87.8917578435941;3.0229682842621175;8.790074436953581;75328075974.19354;25.582415386496606;2874583745;25.582415386496606 +2022-03-12T06:30:00Z;87.66709915927866;3.0398148674987815;9.022197167004448;75324010958.45161;25.586431268344363;2873306938;25.586431268344363 +2022-03-12T06:40:00Z;87.35010847685851;3.0607090577364526;9.323327554098075;75320188860.85246;25.590207168203836;2871233305;25.590207168203836 +2022-03-12T06:50:00Z;87.05837276096257;3.079382507022902;9.585616207445174;75316330892.3871;25.594018505357944;2869589487;25.594018505357944 +2022-03-12T07:00:00Z;87.56562593198856;3.103788148507601;9.05783837676163;75312378648.7742;25.59792297815474;2866903586;25.59792297815474 +2022-03-12T07:10:00Z;87.63623268366227;3.080424531427476;9.004520938138354;75330450002.58064;25.5800700530192;2866221122;25.5800700530192 +2022-03-12T07:20:00Z;87.57586275707325;3.084036322112377;9.067209449999426;75327056334.45161;25.583422701840714;2864121724;25.583422701840714 +2022-03-12T07:30:00Z;87.29878580628004;3.1349848676250076;9.295138877228448;75321113236.64516;25.589293965352468;2862836703;25.589293965352468 +2022-03-12T07:40:00Z;87.60971949239375;3.0808743235102694;9.025507116941256;75315419841.04918;25.59491854480737;2861048865;25.59491854480737 +2022-03-12T07:50:00Z;87.61097522738355;3.098205689605488;9.026638623551444;75304934685.37704;25.605276966276737;2858767459;25.605276966276737 +2022-03-12T08:00:00Z;87.50457849060882;3.1143146480318507;9.100026602806954;75300709078.70967;25.60945149798547;2857888718;25.60945149798547 +2022-03-12T08:10:00Z;87.25044356471939;3.1456813571069353;9.338404865695926;75297106316.3871;25.613010713676513;2855929327;25.613010713676513 +2022-03-12T08:20:00Z;87.28545147393388;3.054266865826807;9.391945183571298;75293024520.25807;25.61704317308661;2853912378;25.61704317308661 +2022-03-12T08:30:00Z;87.65163848056235;3.113162294389682;8.968551224851641;75289247942.19354;25.620774103606628;2852061382;25.620774103606628 +2022-03-12T08:40:00Z;87.68168877457732;3.1180527963492857;8.903479296178752;75285291470.45161;25.62468275342701;2852225883;25.62468275342701 +2022-03-12T08:50:00Z;87.30374376348644;3.09048342846823;9.317593137530222;75281396786.36066;25.628530362424502;2851378738;25.628530362424502 +2022-03-12T09:00:00Z;87.48417668865747;3.0937180273497678;9.137643623782932;75277611536.51613;25.632269859908615;2849936703;25.632269859908615 +2022-03-12T09:10:00Z;86.82797810450491;3.0501241993950767;9.84890516220289;75273101113.80646;25.636725765084723;2847409185;25.636725765084723 +2022-03-12T09:20:00Z;87.49905342840398;3.1688166526496295;8.977481119843048;75278481209.80646;25.631410698369805;2846932530;25.631410698369805 +2022-03-12T09:30:00Z;87.83526460549614;3.0492964786157413;8.847926135465933;75318675257.80646;25.591702476311625;2845285145;25.591702476311625 +2022-03-12T09:40:00Z;87.36520560870571;3.019600814214809;9.305154471240805;75315147478.70967;25.59518761510001;2843279096;25.59518761510001 +2022-03-12T09:50:00Z;87.6003014755362;3.085973639239426;9.052142059566384;75310888101.16129;25.599395509500713;2841349748;25.599395509500713 +2022-03-12T10:00:00Z;87.32058137406962;3.0675148636493774;9.345023762461649;75307333632;25.602907015750475;2840244090;25.602907015750475 +2022-03-12T10:10:00Z;87.1054860625815;3.0653864235479396;9.552524448574088;75303205326.45161;25.606985422420035;2838705119;25.606985422420035 +2022-03-12T10:20:00Z;86.91972150063707;3.0900696275839294;9.7191971791052;75299505118.96774;25.610640905451525;2836911335;25.610640905451525 +2022-03-12T10:30:00Z;86.9174670465095;3.132504515878995;9.681072513198137;75295526978.06451;25.614570962517785;2835120921;25.614570962517785 +2022-03-12T10:40:00Z;87.24538484039543;3.0050517822387524;9.479079285940161;75291648462.45161;25.618402598465806;2831966549;25.618402598465806 +2022-03-12T10:50:00Z;87.13977226724421;3.12347965990606;9.442949617703796;75287843957.5082;25.6221611183122;2830866498;25.6221611183122 +2022-03-12T11:00:00Z;86.66204922885073;3.0971243727880577;9.982854282771005;75283789229.41936;25.626166836853834;2828376791;25.626166836853834 +2022-03-12T11:10:00Z;86.99961757683565;3.070591473473194;9.64027058987943;75303220190.96774;25.60697073757149;2826615379;25.60697073757149 +2022-03-12T11:20:00Z;87.09488796742212;3.130587202678532;9.496500715551022;75299756890.83871;25.610392176750185;2814182829;25.610392176750185 +2022-03-12T11:30:00Z;87.07894449349253;3.0474688460386155;9.593655906834908;75293870608.51613;25.616207311507516;2810243997;25.616207311507516 +2022-03-12T11:40:00Z;86.9872003194566;3.0727873998773285;9.672688190828387;75289531094.70967;25.62049437355837;2807920376;25.62049437355837 +2022-03-12T11:50:00Z;87.07464746551103;2.994030617501501;9.63706888927001;75285983232;25.623999353208777;2807724737;25.623999353208777 +2022-03-12T12:00:00Z;86.82914711547704;3.0474767558442464;9.841514549824309;75281835595.54099;25.628096857136008;2806132141;25.628096857136008 +2022-03-12T12:10:00Z;86.81872788401246;3.078220295568983;9.842259846666627;75270293834.32259;25.639499112947693;2803987225;25.639499112947693 +2022-03-12T12:20:00Z;86.95583646308796;3.1045353076294755;9.648081959467;75257396851.6129;25.65224020967217;2801776838;25.65224020967217 +2022-03-12T12:30:00Z;87.13765015680626;3.0556956512749114;9.527139043410857;75253519525.16129;25.656070670832307;2800465458;25.656070670832307 +2022-03-12T12:40:00Z;87.15669744124122;3.022151580485222;9.54107409265449;75249712425.29033;25.65983175424132;2798307697;25.65983175424132 +2022-03-12T12:50:00Z;86.9421841877871;3.1266210186983843;9.652723112137538;75249269396.64516;25.66026942799394;2796937084;25.66026942799394 +2022-03-12T13:00:00Z;87.14228083469592;2.979652238464116;9.600934766728928;75297813420.06557;25.612312156768702;2795736758;25.612312156768702 +2022-03-12T13:10:00Z;87.152303753515;3.026595887392073;9.540872403603307;75293145457.31148;25.61692369780082;2794038371;25.61692369780082 +2022-03-12T13:20:00Z;86.1759747099347;3.115583801249144;10.431278351187068;75289662166.70967;25.620364885827208;2792763656;25.620364885827208 +2022-03-12T13:30:00Z;87.10242135472362;3.0097081533377037;9.620136829066107;75282965537.03226;25.62698057326114;2790620722;25.62698057326114 +2022-03-12T13:40:00Z;86.8790214768668;3.144509488813222;9.608576901988643;75279364228.12903;25.630538353100317;2789447151;25.630538353100317 +2022-03-12T13:50:00Z;87.09808420444178;3.0451031461345814;9.573628780294912;75275205995.35484;25.634646325264942;2787994775;25.634646325264942 +2022-03-12T14:00:00Z;87.13525362078019;3.0913958365346446;9.518561877936277;75271534261.67741;25.63827367865321;2785709419;25.63827367865321 +2022-03-12T14:10:00Z;87.20344434237964;3.0155612571063592;9.522352371523581;75267534914.06451;25.6422246861034;2782497429;25.6422246861034 +2022-03-12T14:20:00Z;87.04708813037084;3.115620457746933;9.565855183106901;75263691544.7742;25.64602160054287;2780016508;25.64602160054287 +2022-03-12T14:30:00Z;87.13711938983404;3.064070971218693;9.518796176939297;75259836283.87097;25.64983026286117;2779033666;25.64983026286117 +2022-03-12T14:40:00Z;86.92816480330698;3.0267322877036724;9.767154168383318;75255856755.6129;25.65376169051329;2777243516;25.65376169051329 +2022-03-12T14:50:00Z;87.07054279795821;3.074684796685937;9.575842640915011;75252163947.35484;25.657409863753518;2775181547;25.657409863753518 +2022-03-12T15:00:00Z;86.64308247430203;3.0205992676846987;10.076743841186454;75248008819.6129;25.661514768416424;2773149730;25.661514768416424 +2022-03-12T15:10:00Z;87.22475383500267;3.0518099449486336;9.445128390528877;75266292967.2258;25.643451621515712;2772421203;25.643451621515712 +2022-03-12T15:20:00Z;87.10805066369652;3.1110760879006043;9.505123085937482;75262769482.32259;25.646932518014527;2770853492;25.646932518014527 +2022-03-12T15:30:00Z;86.90412946204957;3.097367406993304;9.741445958982023;75256905595.87097;25.652725527600044;2762606130;25.652725527600044 +2022-03-12T15:40:00Z;87.13124971179825;3.1462056760099566;9.42873099575215;75252616357.16129;25.65696292222984;2760870813;25.65696292222984 +2022-03-12T15:50:00Z;87.17474060323883;3.081733213521032;9.476391668529935;75240900708.72131;25.668536963486144;2760131881;25.668536963486144 +2022-03-12T16:00:00Z;87.21244791544648;3.010667216856501;9.48679625690147;75236548272.2623;25.67283679199331;2758413940;25.67283679199331 +2022-03-12T16:10:00Z;87.48063845139505;3.102961838698393;9.176519019980521;75232765489.54839;25.676573852167046;2757357370;25.676573852167046 +2022-03-12T16:20:00Z;87.39038629320892;3.0408592172631113;9.30925183832907;75228882944;25.680409469340667;2755601970;25.680409469340667 +2022-03-12T16:30:00Z;86.95741380431902;3.0889173838038;9.691636777304714;75278892131.09677;25.63100474389007;2754141217;25.63100474389007 +2022-03-12T16:40:00Z;87.36146325080011;3.054113362964681;9.322569139876826;75276969389.41936;25.6329042453657;2752997171;25.6329042453657 +2022-03-12T16:50:00Z;87.65025659730637;3.0631604703644117;9.04099332062311;75272855948.3871;25.6369679671867;2750462150;25.6369679671867 +2022-03-12T17:00:00Z;87.53661415050546;3.0659643837105732;9.133834275444379;75269300019.2;25.64048091581492;2749276490;25.64048091581492 +2022-03-12T17:10:00Z;87.22021465195999;3.1121705642004436;9.397633936559764;75287753496.7742;25.622250485646212;2747280549;25.622250485646212 +2022-03-12T17:20:00Z;86.83934091179054;3.0922555342609956;9.784253133187104;75285068899.09677;25.62490263455921;2745436622;25.62490263455921 +2022-03-12T17:30:00Z;87.64711402447219;3.1324062639696733;8.951791283636274;75278429150.96774;25.631462127972704;2743681222;25.631462127972704 +2022-03-12T17:40:00Z;87.50988168218424;3.1647428084111207;9.061350668049409;75274749687.74193;25.635097117482236;2741904703;25.635097117482236 +2022-03-12T17:50:00Z;87.6632740335847;3.0809438061327854;8.997085613884114;75270640673.03226;25.639156466481676;2740462844;25.639156466481676 +2022-03-12T18:00:00Z;87.51198583107646;3.033493625178616;9.195733282309426;75266893295.48387;25.642858549432535;2739052478;25.642858549432535 +2022-03-12T18:10:00Z;87.4531802332805;3.00061285547452;9.283224050165382;75262961294.68852;25.646743024086955;2737267481;25.646743024086955 +2022-03-12T18:20:00Z;87.6278182477826;3.123587485247571;8.97672976330113;75259047803.87097;25.65060921249392;2735135182;25.65060921249392 +2022-03-12T18:30:00Z;87.82501436888467;2.971909328717833;8.958784804650302;75255276643.09677;25.654334791202455;2732166507;25.654334791202455 +2022-03-12T18:40:00Z;87.64113412384437;3.1106554451733417;9.001887854337633;75251211429.16129;25.65835086884818;2730426897;25.65835086884818 +2022-03-12T18:50:00Z;87.26811722719532;3.0988707280072876;9.375318146584844;75247618048;25.661900816768142;2729364295;25.661900816768142 +2022-03-12T19:00:00Z;87.66217383071638;3.0849400496990036;8.99485606506587;75243379282.58064;25.66608834817887;2755410581;25.66608834817887 +2022-03-12T19:10:00Z;87.29609509446915;3.0032558855573668;9.431845953748585;75261674066.58064;25.648014693453216;2771932061;25.648014693453216 +2022-03-12T19:20:00Z;87.5388200216773;3.0855582161316137;9.115476567851388;75258114450.88524;25.651531284030874;2770938913;25.651531284030874 +2022-03-12T19:30:00Z;86.8174817191166;3.0192849789073692;9.911289449077266;75252135011.09677;25.657438450258663;2769785361;25.657438450258663 +2022-03-12T19:40:00Z;87.388405555231;2.9928585564755177;9.34151423416599;75247922275.09677;25.66160026686795;2768412936;25.66160026686795 +2022-03-12T19:50:00Z;87.54570423302886;3.082831288373328;9.127778407575017;75244215262.96774;25.665262472296778;2766786090;25.665262472296778 +2022-03-12T20:00:00Z;87.4430673987019;3.197357874744148;9.082376192724825;75291045095.2258;25.618998672784706;2765376017;25.618998672784706 +2022-03-12T20:10:00Z;87.77922098977622;3.024131308669515;8.94819167778706;75294695424;25.61539246557832;2763605289;25.61539246557832 +2022-03-12T20:20:00Z;87.72843294810694;2.976671231949119;9.034819406894709;75290916091.80328;25.619126116941295;2761824124;25.619126116941295 +2022-03-12T20:30:00Z;87.42129559834672;3.051585903824308;9.268756212759385;75286864268.3871;25.6231289659191;2759358398;25.6231289659191 +2022-03-12T20:40:00Z;87.88604297189536;2.9878471657345123;8.862863372004785;75283218762.32259;25.626730408707946;2759706162;25.626730408707946 +2022-03-12T20:50:00Z;87.66560250948095;3.0740494893788126;8.984710246710378;75279025317.16129;25.63087316764711;2759133083;25.63087316764711 +2022-03-12T21:00:00Z;87.7680869054673;3.0271033804198155;8.943290947089336;75275534996.64516;25.634321300617174;2761004888;25.634321300617174 +2022-03-12T21:10:00Z;87.62893524840464;3.1094957217154207;9.010283094823432;75270838404.12903;25.638961125363046;2758818387;25.638961125363046 +2022-03-12T21:20:00Z;87.41357376476083;2.9356784602431656;9.21801062277303;75267289682.58064;25.64246695347137;2755645572;25.64246695347137 +2022-03-12T21:30:00Z;87.68815697928186;3.0450204722155636;9.009727839925999;75260721698.13333;25.648955550611642;2753300348;25.648955550611642 +2022-03-12T21:40:00Z;87.21262119323252;3.0157546152305628;9.486711075807959;75256952039.2258;25.652679645606593;2751395774;25.652679645606593 +2022-03-12T21:50:00Z;87.18324512946208;3.084010842975639;9.460286590056587;75252936902.19354;25.656646251629233;2749047775;25.656646251629233 +2022-03-12T22:00:00Z;87.75959426770103;3.0565772269507625;8.937077264170195;75249104763.87097;25.660432070849804;2749562343;25.660432070849804 +2022-03-12T22:10:00Z;87.11511697071765;3.0688883787315278;9.554043407455104;75242292455.2258;25.667162039038395;2748455751;25.667162039038395 +2022-03-12T22:20:00Z;87.62931452810147;3.037178049694749;9.062519194146988;75232872844.3871;25.67646779492755;2747281606;25.67646779492755 +2022-03-12T22:30:00Z;87.38358752799441;3.041252738669858;9.309827169376236;75229197543.2258;25.68009867267948;2746246309;25.68009867267948 +2022-03-12T22:40:00Z;87.67957785057537;3.016886828877901;9.027224304378182;75225039046.19354;25.684206905908077;2744285713;25.684206905908077 +2022-03-12T22:50:00Z;87.7333890647082;3.0528378495669437;8.951356856938345;75221517741.41936;25.687685648629095;2742490145;25.687685648629095 +2022-03-12T23:00:00Z;87.79032003345324;3.054731820307718;8.900795813600798;75217264640;25.69188734276042;2740431839;25.69188734276042 +2022-03-12T23:10:00Z;87.59270656532911;3.1116374076079576;9.008296704626241;75261341629.93549;25.648343111932636;2739053954;25.648343111932636 +2022-03-12T23:20:00Z;87.49373152067575;3.03654693363349;9.213396023365998;75258300614.19354;25.651347370880718;2737983356;25.651347370880718 +2022-03-12T23:30:00Z;87.54097325796867;3.0904438733276836;9.108820754182638;75295208229.7705;25.614885858097338;2736498490;25.614885858097338 +2022-03-12T23:40:00Z;87.2256368270081;3.078837757745418;9.402152517878402;75303891934.96774;25.606307112949306;2734304553;25.606307112949306 +2022-03-12T23:50:00Z;87.7363537322303;3.084798303323683;8.901221126809462;75300092696.7742;25.61006042970509;2733078132;25.61006042970509 +2022-03-13T00:00:00Z;87.43714355540995;3.16197833719251;9.141749693350821;75296221184;25.613885147457797;2730662152;25.613885147457797 +2022-03-13T00:10:00Z;87.38825923448161;3.021195057788649;9.332549383363546;75292444077.41936;25.617616600105748;2728699442;25.617616600105748 +2022-03-13T00:20:00Z;87.6546464464204;3.007782645627453;9.074691156400862;75288791964.90323;25.62122456949395;2726445593;25.62122456949395 +2022-03-13T00:30:00Z;87.43803352864843;3.0691318104199006;9.241502106857634;75284700445.37704;25.625266634774384;2725630018;25.625266634774384 +2022-03-13T00:40:00Z;87.7930632143186;2.975765469742511;8.978737446251783;75281116243.93443;25.628807513931047;2724012494;25.628807513931047 +2022-03-13T00:50:00Z;87.7135981315384;3.0567528533932395;8.929464019782584;75276842281.29033;25.633029817137245;2721737299;25.633029817137245 +2022-03-13T01:00:00Z;87.31217090988828;3.0268956421842734;9.389515233135379;75273406860.3871;25.636423714066677;2720127505;25.636423714066677 +2022-03-13T01:10:00Z;87.50557865625841;3.0311934507138467;9.179524765422602;75268750633.29033;25.64102366129051;2717958210;25.64102366129051 +2022-03-13T01:20:00Z;87.19968173821218;3.188118847034886;9.324025478207798;75265111931.87097;25.644618381682015;2717042789;25.644618381682015 +2022-03-13T01:30:00Z;87.68881995137137;3.0912572618732685;8.958429294359624;75258637741.41936;25.65101431851575;2714549149;25.65101431851575 +2022-03-13T01:40:00Z;87.6353007479422;2.9827621449117165;9.119889634897543;75254839396.72131;25.65476675257572;2713543251;25.65476675257572 +2022-03-13T01:50:00Z;87.19399343930868;3.0242550482814665;9.496065709947853;75250883947.35484;25.658674392378096;2711503971;25.658674392378096 +2022-03-13T02:00:00Z;87.032234494102;3.122290100458032;9.588436754620263;75246964868.12903;25.66254610164616;2709904681;25.66254610164616 +2022-03-13T02:10:00Z;87.81841213136407;2.975616580167402;8.917884376148105;75243195425.03226;25.666269983438855;2708767975;25.666269983438855 +2022-03-13T02:20:00Z;87.72679845981219;3.0132321812057663;8.995656434776857;75239099292.90323;25.670316605569568;2706773487;25.670316605569568 +2022-03-13T02:30:00Z;87.24939629407626;3.0540063135820046;9.439253510534533;75235495077.16129;25.67387725711246;2704649031;25.67387725711246 +2022-03-13T02:40:00Z;87.57991466014634;3.063124946603219;9.101847972118112;75231248317.93549;25.678072685708408;2720067122;25.678072685708408 +2022-03-13T02:50:00Z;87.50701514598867;3.0534747824380997;9.177728143048284;75227833685.33333;25.6814460456052;2748396775;25.6814460456052 +2022-03-13T03:00:00Z;87.52882442232095;3.153708956555;9.043881405944283;75261099159.08197;25.64858265203803;2746452232;25.64858265203803 +2022-03-13T03:10:00Z;87.62561264968483;3.056926744505737;9.039901805450622;75297293939.6129;25.612825358254888;2744765143;25.612825358254888 +2022-03-13T03:20:00Z;87.63944812866178;2.9762011370111217;9.116017635809085;75294230924.3871;25.615851350778808;2743359884;25.615851350778808 +2022-03-13T03:30:00Z;87.22747111788935;3.033202085923612;9.476290034307576;75288193486.45161;25.621815814129324;2742817641;25.621815814129324 +2022-03-13T03:40:00Z;87.72006195592533;3.004312209723831;9.010157281110416;75284071258.83871;25.62588821632746;2743036810;25.62588821632746 +2022-03-13T03:50:00Z;87.70691690090007;3.0855202771516868;8.949785910597015;75272364098.06451;25.63745387250852;2741745202;25.63745387250852 +2022-03-13T04:00:00Z;87.52433504512967;3.012912041228237;9.208682314754189;75267990645.5082;25.641774463091156;2741209352;25.641774463091156 +2022-03-13T04:10:00Z;87.1544678397548;3.0862855911696414;9.470054093475229;75263979850.32259;25.645736779747107;2740456217;25.645736779747107 +2022-03-13T04:20:00Z;86.82203454368975;2.980224577850441;9.930508124970922;75260291996.90323;25.64938005803781;2740043512;25.64938005803781 +2022-03-13T04:30:00Z;87.2038451571254;3.0300574462712695;9.498340375806638;75256114539.35484;25.653507022606536;2737959785;25.653507022606536 +2022-03-13T04:40:00Z;87.14985663028627;3.080738545790395;9.516538804713118;75252585108.64516;25.656993793044762;2735977373;25.656993793044762 +2022-03-13T04:50:00Z;87.29752694520346;3.029682049162179;9.416229357980097;75248329364.64516;25.661198097815834;2733384803;25.661198097815834 +2022-03-13T05:00:00Z;87.23984913159627;2.968143926204937;9.527979668648449;75244840827.87097;25.664644468604056;2732761220;25.664644468604056 +2022-03-13T05:10:00Z;86.92901072018846;3.087281522872619;9.675610323411206;75241415193.18033;25.66802869760697;2730980268;25.66802869760697 +2022-03-13T05:20:00Z;87.38700596538861;2.9599932695352695;9.400426804399427;75237823587.09677;25.67157689190457;2728542409;25.67157689190457 +2022-03-13T05:30:00Z;87.28104120081399;2.994759137321932;9.470474191338068;75231305595.87097;25.678016100092012;2726648204;25.678016100092012 +2022-03-13T05:40:00Z;87.11570172348978;2.9748199574993777;9.650723051613758;75227403429.16129;25.68187110126572;2724194106;25.68187110126572 +2022-03-13T05:50:00Z;86.9706627528472;3.089134684979002;9.683750971135199;75223529538.06451;25.68569816859419;2723578120;25.68569816859419 +2022-03-13T06:00:00Z;86.72718368535193;2.982450736662248;10.041991636271613;75219555757.41936;25.68962391810488;2721952273;25.68962391810488 +2022-03-13T06:10:00Z;86.82278064053644;3.008379779553955;9.895410739493808;75215829965.63934;25.69330467619481;2713598791;25.69330467619481 +2022-03-13T06:20:00Z;86.83904614078214;3.0870971720510516;9.814543828203739;75211648419.67213;25.697435679765597;2699551975;25.697435679765597 +2022-03-13T06:30:00Z;86.07067959595157;3.1700633346520646;10.492043355927725;75239669297.54839;25.669753490577403;2697808863;25.669753490577403 +2022-03-13T06:40:00Z;87.18252053037627;3.033654068962092;9.540329646345022;75259694509.41936;25.649970323683274;2696618050;25.649970323683274 +2022-03-13T06:50:00Z;87.08186210524751;3.14323077739302;9.526913039815987;75256160916.64516;25.653461205879093;2694468245;25.653461205879093 +2022-03-13T07:00:00Z;87.25410893857904;3.0594205594481667;9.423555047407739;75252004797.93549;25.657567089531902;2692452088;25.657567089531902 +2022-03-13T07:10:00Z;87.20907799390005;3.0310776497963166;9.490134521934685;75270175909.16129;25.639615612746145;2691108454;25.639615612746145 +2022-03-13T07:20:00Z;87.09909122441667;2.97442711311246;9.654585312970362;75266902183.86885;25.64284976848157;2689962975;25.64284976848157 +2022-03-13T07:30:00Z;87.35377357232315;2.992349070818375;9.4070499148709;75260681645.41936;25.64899511920798;2688576017;25.64899511920798 +2022-03-13T07:40:00Z;87.20606282815965;3.0791295478168355;9.439401265262145;75256765208.7742;25.652864217836296;2686356381;25.652864217836296 +2022-03-13T07:50:00Z;87.09394855175127;3.052661500592576;9.567327483270406;75252754498.06451;25.656826451037364;2684474797;25.656826451037364 +2022-03-13T08:00:00Z;87.06726465044808;3.0409489355153174;9.63537241509417;75249081839.48387;25.660454718149552;2683414066;25.660454718149552 +2022-03-13T08:10:00Z;87.16294278436435;3.1092245689938003;9.474893164064618;75244924861.93549;25.66456145026029;2681434381;25.66456145026029 +2022-03-13T08:20:00Z;87.18619440868054;3.0648979761249215;9.46276846411338;75241400650.32259;25.668043064685026;2680049530;25.668043064685026 +2022-03-13T08:30:00Z;87.14274712795051;3.0220653676644025;9.593960756560461;75237104162.13333;25.672287621169833;2677443419;25.672287621169833 +2022-03-13T08:40:00Z;86.71837660268746;3.1008969912272275;9.910607115788354;75233610652.90323;25.675738904311842;2675593943;25.675738904311842 +2022-03-13T08:50:00Z;86.1537052097157;3.0443867200895345;10.49366915148485;75229422162.58064;25.67987676830149;2673560213;25.67987676830149 +2022-03-13T09:00:00Z;86.58309084581052;3.0920786785702075;10.071591959565545;75225777713.54839;25.68347716683445;2671656762;25.68347716683445 +2022-03-13T09:10:00Z;87.21321018883249;3.0548380316680466;9.472554978194639;75221327541.67741;25.687873549424463;2669762890;25.687873549424463 +2022-03-13T09:20:00Z;87.25576825033946;3.0591040498180653;9.431809205582226;75217504586.32259;25.69165029667193;2667327622;25.69165029667193 +2022-03-13T09:30:00Z;87.12958079662998;3.081057762810666;9.547228811847308;75210829757.93549;25.698244446327998;2665880213;25.698244446327998 +2022-03-13T09:40:00Z;87.15550241619123;2.9960758006284913;9.563295542578535;75198781070.68852;25.710147500947222;2660895116;25.710147500947222 +2022-03-13T09:50:00Z;86.94902827130743;3.0866603648955317;9.69592211798444;75195101778.58064;25.71378232140712;2659602432;25.71378232140712 +2022-03-13T10:00:00Z;86.90582817695591;3.0861563758293156;9.746313671240566;75217074836.64516;25.69207485195982;2657354124;25.69207485195982 +2022-03-13T10:10:00Z;87.12909966999104;2.999693618213508;9.580342670052513;75243220727.74193;25.666244986563342;2658108515;25.666244986563342 +2022-03-13T10:20:00Z;87.09329436004322;3.0570590340193076;9.569564836682398;75238949524.64516;25.67046456357689;2666284082;25.67046456357689 +2022-03-13T10:30:00Z;87.13850545887951;3.032639391230997;9.55204491823042;75235526958.16394;25.673845761455873;2703423752;25.673845761455873 +2022-03-13T10:40:00Z;87.19282611732747;3.0226378828686964;9.516120284487405;75231249458.36066;25.67807155906756;2702149434;25.67807155906756 +2022-03-13T10:50:00Z;86.1775143849068;3.1923122411931875;10.363408671878952;75227673236.64516;25.681604554948148;2700596125;25.681604554948148 +2022-03-13T11:00:00Z;87.15558434256913;3.051893066393233;9.539092404343153;75223598113.03226;25.685630422492913;2699344533;25.685630422492913 +2022-03-13T11:10:00Z;86.97434716574843;3.1135862105232586;9.63034202326719;75264864123.87097;25.64486319442374;2697918266;25.64486319442374 +2022-03-13T11:20:00Z;87.18770762546788;3.111260801586817;9.42759888204247;75262425682.58064;25.647272162244843;2695639846;25.647272162244843 +2022-03-13T11:30:00Z;87.10368110428095;3.0333355922016287;9.589241006872827;75256123920.51613;25.65349775483546;2692993156;25.65349775483546 +2022-03-13T11:40:00Z;87.327548183744;2.880100612113902;9.53587976746094;75252284825.6;25.657290446565153;2692825022;25.657290446565153 +2022-03-13T11:50:00Z;87.15669707977064;2.9170395515198417;9.665271125640341;75248220027.87097;25.66130611303512;2691291202;25.66130611303512 +2022-03-13T12:00:00Z;87.09784058898563;3.0868596079094703;9.527521960442916;75244600551.2258;25.664881841022517;2688935407;25.664881841022517 +2022-03-13T12:10:00Z;87.24723111471982;2.9999068028118487;9.483127083022177;75240354188.3871;25.6690768780225;2687386987;25.6690768780225 +2022-03-13T12:20:00Z;87.58976664389925;3.078668890996414;9.063910902150655;75236914935.74193;25.67247456037956;2685413947;25.67247456037956 +2022-03-13T12:30:00Z;87.4047271376924;3.1525382266905275;9.179479069581465;75232664014.45161;25.6766741007331;2684445993;25.6766741007331 +2022-03-13T12:40:00Z;87.74000214139987;2.986586838142722;9.026107044941034;75229088470.70967;25.680206426834797;2682871147;25.680206426834797 +2022-03-13T12:50:00Z;87.86388924340233;3.0230369894720712;8.85757642174358;75224953302.03279;25.684291613678134;2680955012;25.684291613678134 +2022-03-13T13:00:00Z;87.13937340177237;3.0959273992295078;9.491899769661803;75221224679.2258;25.687975168576383;2678423222;25.687975168576383 +2022-03-13T13:10:00Z;87.6770962808917;3.1016899147955628;8.90847112689032;75216855040;25.692291991920293;2677292792;25.692291991920293 +2022-03-13T13:20:00Z;87.44837260474253;3.01052666465521;9.277223447040292;75212925522.58064;25.696174013215316;2675151971;25.696174013215316 +2022-03-13T13:30:00Z;87.4782970874182;3.1920354570999994;9.065994130243087;75227457073.54839;25.68181810527897;2673429924;25.68181810527897 +2022-03-13T13:40:00Z;87.74215120482523;3.0406151462113526;8.96171651173849;75258419266.06451;25.651230153156344;2671408095;25.651230153156344 +2022-03-13T13:50:00Z;87.85240177810725;3.0174619055363525;8.854904041481676;75254789774.68852;25.6548157748264;2669895284;25.6548157748264 +2022-03-13T14:00:00Z;87.90839531306304;3.058575452789513;8.750276391107844;75250550280.39345;25.659004026302917;2668641445;25.659004026302917 +2022-03-13T14:10:00Z;87.63541385127712;3.1323760640810208;8.954949510928214;75247099309.41936;25.662413285349324;2666761447;25.662413285349324 +2022-03-13T14:20:00Z;87.78476912570957;3.117286586787805;8.80116562564521;75242842904.7742;25.666618242780327;2665240444;25.666618242780327 +2022-03-13T14:30:00Z;87.5455275326634;3.046511575263606;9.146217960683883;75239318957.41936;25.670099596141085;2662637501;25.670099596141085 +2022-03-13T14:40:00Z;87.50118285817668;3.066502963832057;9.15973014282916;75235184375.74193;25.674184203080014;2662570353;25.674184203080014 +2022-03-13T14:50:00Z;87.86500201803541;2.994890928274248;8.887848755197936;75231471946.32259;25.67785176032031;2660838367;25.67785176032031 +2022-03-13T15:00:00Z;87.84548299224669;3.0268831082184975;8.864749551213615;75227486845.90164;25.681788692784515;2659440310;25.681788692784515 +2022-03-13T15:10:00Z;87.73687948527825;3.0234549789410545;8.967414195245961;75245369410.06451;25.664122275389847;2657065819;25.664122275389847 +2022-03-13T15:20:00Z;87.27621632656961;3.0281851155987884;9.429511226276892;75242316766.96774;25.667138021152777;2655993988;25.667138021152777 +2022-03-13T15:30:00Z;87.87179601764062;3.0329723738508103;8.811093097946348;75235852684.3871;25.67352397228949;2654783092;25.67352397228949 +2022-03-13T15:40:00Z;87.79994260627169;3.086983649461134;8.831609789861435;75232145077.67741;25.67718676511225;2653230148;25.67718676511225 +2022-03-13T15:50:00Z;87.74205737361557;3.0164995090948694;8.965597675646203;75227929566.96774;25.681351322893256;2650383327;25.681351322893256 +2022-03-13T16:00:00Z;87.19637039933338;3.0688688928455377;9.448758356063058;75224458999.74193;25.684779941331254;2644896867;25.684779941331254 +2022-03-13T16:10:00Z;87.89041978946878;3.0288301015909407;8.805067166117873;75220200448;25.688987019907035;2644241375;25.688987019907035 +2022-03-13T16:20:00Z;87.86000790309768;3.0292376771204705;8.816380943684656;75214638905.80646;25.694481339673175;2641846536;25.694481339673175 +2022-03-13T16:30:00Z;87.64724461552223;3.101665920645541;8.927319071273613;75204135969.03226;25.704857327324202;2642255674;25.704857327324202 +2022-03-13T16:40:00Z;87.88325344445406;3.048522906217932;8.783023238811191;75200440980.64516;25.7085076543422;2640811327;25.7085076543422 +2022-03-13T16:50:00Z;87.90101147654897;3.0688224352290563;8.768004533680072;75196443350.70967;25.712456964876555;2639620600;25.712456964876555 +2022-03-13T17:00:00Z;87.79341394346837;3.1197845327862903;8.776001367079127;75207871256.7742;25.701167188050146;2636518962;25.701167188050146 +2022-03-13T17:10:00Z;87.72894170357756;3.0140429446105887;8.982412915366767;75245422491.27869;25.664069835768938;2635314605;25.664069835768938 +2022-03-13T17:20:00Z;87.36416308777834;3.144028293564626;9.211722525668282;75241405859.67213;25.66803791830095;2633727405;25.66803791830095 +2022-03-13T17:30:00Z;87.25440013069722;3.089880603481218;9.381716246455019;75235349801.29033;25.674020777032215;2631899665;25.674020777032215 +2022-03-13T17:40:00Z;87.77727702737654;3.07742850510735;8.87990170517266;75231083883.35484;25.6782351327663;2631053312;25.6782351327663 +2022-03-13T17:50:00Z;87.82761607420308;3.09547871789831;8.788542068638549;75227579160.7742;25.68169749372293;2629483619;25.68169749372293 +2022-03-13T18:00:00Z;87.78195144769863;3.0953067565542223;8.837256684887356;75223324672;25.68590055844012;2627515623;25.68590055844012 +2022-03-13T18:10:00Z;87.6838900932025;3.0440884396865795;8.985260203850416;75219839345.31148;25.68934375794303;2672945152;25.68934375794303 +2022-03-13T18:20:00Z;87.79574720725697;3.06267628488695;8.852688769760412;75215607908.72131;25.69352404910821;2670659848;25.69352404910821 +2022-03-13T18:30:00Z;87.64890343392914;3.1585700123228557;8.912278999723126;75211978223.48387;25.697109862296507;2669079123;25.697109862296507 +2022-03-13T18:40:00Z;87.7740766534598;3.0711548261934603;8.870845923052698;75207940888.7742;25.701098397692963;2667416873;25.701098397692963 +2022-03-13T18:50:00Z;87.26868504322162;3.0477480355722997;9.392735743348434;75204140659.6129;25.70485269343866;2665083216;25.70485269343866 +2022-03-13T19:00:00Z;87.94902611793025;2.986509925919449;8.767477209013823;75200263267.09677;25.708683219864795;2664363173;25.708683219864795 +2022-03-13T19:10:00Z;87.6997174909906;3.1191067438032825;8.87841098691511;75218021276.90323;25.691139851336544;2662569125;25.691139851336544 +2022-03-13T19:20:00Z;87.8885776723753;3.049119707975931;8.792659402259945;75215046689.57378;25.694078484793152;2660569550;25.694078484793152 +2022-03-13T19:30:00Z;88.02616287835947;3.0018717259873187;8.71400982432897;75208486185.29033;25.700559692182388;2658425493;25.700559692182388 +2022-03-13T19:40:00Z;87.35888166850333;3.0505062279651445;9.27475375065943;75204850060.3871;25.70415186720016;2656826137;25.70415186720016 +2022-03-13T19:50:00Z;87.75320029067355;3.1218430673486908;8.847499616024216;75200590154.32259;25.708360283728815;2655718484;25.708360283728815 +2022-03-13T20:00:00Z;87.6174429408246;3.0350899880767934;9.066093174310188;75197137292.3871;25.711771410880548;2654283247;25.711771410880548 +2022-03-13T20:10:00Z;87.15258236405407;3.101626820523557;9.422741456476173;75192893968.51613;25.715963445644835;2651975019;25.715963445644835 +2022-03-13T20:20:00Z;88.06698590746416;2.9556355114505495;8.695741100436084;75189299992.7742;25.719513980958713;2650350295;25.719513980958713 +2022-03-13T20:30:00Z;87.63616191335406;3.0927716856197365;9.008170857916511;75195446476.8;25.713441789559287;2648544289;25.713441789559287 +2022-03-13T20:40:00Z;87.97095413222007;3.048805782163553;8.709480341134803;75237294542.45161;25.67209954198075;2650866589;25.67209954198075 +2022-03-13T20:50:00Z;88.0052835921444;3.0281165181139147;8.667701238784957;75233373679.48387;25.675973013430625;2650272074;25.675973013430625 +2022-03-13T21:00:00Z;87.91999393828004;3.0252122613656223;8.777327496819527;75229459621.16129;25.67983976248317;2648780934;25.67983976248317 +2022-03-13T21:10:00Z;87.71216858273314;2.98549872993502;9.020064601016907;75225285136.51613;25.68396379008219;2647385187;25.68396379008219 +2022-03-13T21:20:00Z;87.04786420196838;3.033013078210038;9.624371848090608;75221173743.48387;25.688025488657384;2645156567;25.688025488657384 +2022-03-13T21:30:00Z;87.84564615211465;3.038801514679288;8.828833163858901;75215164382.96774;25.693962213960656;2642645521;25.693962213960656 +2022-03-13T21:40:00Z;87.96767726251505;3.0226361369049872;8.726990964445564;75210819953.31148;25.698254132443395;2640166582;25.698254132443395 +2022-03-13T21:50:00Z;87.51698670676649;2.9391682796080305;9.281777276510505;75207395922.58064;25.701636776873574;2638962754;25.701636776873574 +2022-03-13T22:00:00Z;87.86343034319671;3.05666218727722;8.801687103747243;75203125446.19354;25.705855635961207;2636587679;25.705855635961207 +2022-03-13T22:10:00Z;87.97960676872376;3.0312309561535127;8.718478401303155;75199579961.80646;25.709358266035853;2635402928;25.709358266035853 +2022-03-13T22:20:00Z;87.7864527046535;3.0527063038239866;8.892093981046807;75195448286.96774;25.71344000127106;2633579619;25.71344000127106 +2022-03-13T22:30:00Z;87.85668779406758;3.0741106982742354;8.798997989557721;75191740878.45161;25.717102598295856;2631033691;25.717102598295856 +2022-03-13T22:40:00Z;87.81657176753222;3.004458010679316;8.88882984722075;75187773775.7377;25.721021750591518;2629897844;25.721021750591518 +2022-03-13T22:50:00Z;87.52632106414345;3.034015783939321;9.124400573597514;75183891753.29033;25.724856850986882;2628481817;25.724856850986882 +2022-03-13T23:00:00Z;87.89269213438224;3.0553136706161528;8.789508720428513;75180085842.58064;25.72861675960802;2626358107;25.72861675960802 +2022-03-13T23:10:00Z;87.88492933096428;3.099583975322688;8.725492897879239;75204015467.35484;25.704976372496397;2624228011;25.704976372496397 +2022-03-13T23:20:00Z;87.97614737633062;3.062492876360415;8.692773056207516;75201284029.93549;25.707674794998795;2622487915;25.707674794998795 +2022-03-13T23:30:00Z;87.86823183476157;3.0616966103552463;8.794689118744976;75194646329.80646;25.714232265166505;2620289817;25.714232265166505 +2022-03-13T23:40:00Z;87.76207885609459;3.0333063146557255;8.925568801095201;75191151968.5246;25.717684390061503;2618946659;25.717684390061503 +2022-03-13T23:50:00Z;87.94487820134235;2.999756572873783;8.77790986543926;75186875425.03226;25.721909242921182;2617258248;25.721909242921182 +2022-03-14T00:00:00Z;87.27008001601989;3.0501525043370052;9.361662844840806;75185828500.64516;25.722943513120622;2615873536;25.722943513120622 +2022-03-14T00:10:00Z;87.93762032497327;3.1363530029661395;8.65150397116675;75229095737.80646;25.68019924757551;2613744153;25.68019924757551 +2022-03-14T00:20:00Z;87.59254511586234;3.0001254513424542;9.110461458556504;75225257257.29033;25.683991332331452;2613197102;25.683991332331452 +2022-03-14T00:30:00Z;87.92239831967954;3.080014742522721;8.71652957052786;75221320472.7742;25.687880532885767;2610339311;25.687880532885767 +2022-03-14T00:40:00Z;87.8240349646828;3.026586408089198;8.84931846033539;75217416588.3871;25.69173723097531;2608855040;25.69173723097531 +2022-03-14T00:50:00Z;87.90400712448766;3.0454153386711376;8.77799076270259;75213656678.4;25.69545169488515;2608716899;25.69545169488515 +2022-03-14T01:00:00Z;87.85959029992182;3.112169955721821;8.77435572249757;75209574862.45161;25.699484173875057;2607116817;25.699484173875057 +2022-03-14T01:10:00Z;87.78710454907578;3.0508357470748018;8.891607083004775;75205521738.32259;25.70348830784397;2606627807;25.70348830784397 +2022-03-14T01:20:00Z;87.93935075752488;3.0982537764565463;8.704343543810804;75201276102.19354;25.707682626918032;2604258623;25.707682626918032 +2022-03-14T01:30:00Z;87.56608931127734;3.163652957683612;8.989013128851816;75195407723.35484;25.713480074591097;2603459881;25.713480074591097 +2022-03-14T01:40:00Z;87.86786545937937;3.0571028617077505;8.808842554056643;75191048324.12903;25.717786781706007;2600720846;25.717786781706007 +2022-03-14T01:50:00Z;87.79093131090805;3.0002128471750336;8.926743599538764;75187535401.96721;25.721257243135387;2637465468;25.721257243135387 +2022-03-14T02:00:00Z;87.59327423746447;3.018966293318569;9.11059912248432;75183350565.7705;25.725391497166637;2644551085;25.725391497166637 +2022-03-14T02:10:00Z;87.16749649686639;3.0880734755275836;9.454512575847568;75179653053.93549;25.729044317131603;2642589167;25.729044317131603 +2022-03-14T02:20:00Z;87.6348059109975;3.1059302897708547;8.96550559270635;75174294230.70967;25.734338368196603;2641381112;25.734338368196603 +2022-03-14T02:30:00Z;87.90710936965658;3.0440997944012986;8.754846764196639;75163410894.45161;25.745090157438366;2639515312;25.745090157438366 +2022-03-14T02:40:00Z;87.98811302968348;3.0265693251209207;8.70071414777459;75159582191.48387;25.748872582827264;2637807352;25.748872582827264 +2022-03-14T02:50:00Z;87.68167011081778;3.148044187487331;8.90478373289799;75155561174.70967;25.752844997523326;2637020523;25.752844997523326 +2022-03-14T03:00:00Z;87.80300440594847;3.018679566369084;8.884974064637506;75151929142.55737;25.756433129259296;2636113524;25.756433129259296 +2022-03-14T03:10:00Z;87.60052606042062;3.129202268704257;8.991694066779216;75169468878.45161;25.73910539636386;2634341805;25.73910539636386 +2022-03-14T03:20:00Z;87.16114834259572;3.1193895368344475;9.422480295242472;75166679700.64516;25.741860861344612;2632891161;25.741860861344612 +2022-03-14T03:30:00Z;87.82151989240575;3.063273781249937;8.832648433947497;75160013328.51613;25.748446656953504;2630969310;25.748446656953504 +2022-03-14T03:40:00Z;87.87654051414307;3.123149468566248;8.717126563749668;75206782909.93549;25.70224238002752;2630043780;25.70224238002752 +2022-03-14T03:50:00Z;87.81440115905119;3.123679499632366;8.790340998626094;75208005896.25807;25.701034175955346;2627989306;25.701034175955346 +2022-03-14T04:00:00Z;87.9052196518172;3.0393496718918516;8.768464380160058;75204343741.93549;25.704652065774553;2625701822;25.704652065774553 +2022-03-14T04:10:00Z;87.74973938515602;3.1163907864303346;8.870133529425456;75200359628.8;25.70858802288664;2624037525;25.70858802288664 +2022-03-14T04:20:00Z;87.0493255759461;3.1608480040857763;9.491020029913003;75197498929.54839;25.71141414483197;2622048454;25.71141414483197 +2022-03-14T04:30:00Z;87.73253069215417;3.022896902202406;8.985282776214245;75193645782.70967;25.71522071863847;2620898998;25.71522071863847 +2022-03-14T04:40:00Z;87.6925910931215;3.008128088951394;9.016850075166488;75189664404.64516;25.719153973738425;2619529250;25.719153973738425 +2022-03-14T04:50:00Z;87.88503888832814;3.0160668337676393;8.835491108683991;75185988442.83871;25.722785504150284;2617265383;25.722785504150284 +2022-03-14T05:00:00Z;87.93773022236623;2.9753399502409144;8.821049372756498;75181817050.2295;25.726906477086832;2614997256;25.726906477086832 +2022-03-14T05:10:00Z;87.80878575549008;3.078390006265403;8.819493109380304;75201016732.90323;25.7079388612086;2614390454;25.7079388612086 +2022-03-14T05:20:00Z;87.70962916585982;3.0545493500840624;8.933565542116861;75197511944.25807;25.71140128743125;2612422326;25.71140128743125 +2022-03-14T05:30:00Z;87.45208909327177;3.0692679150254585;9.193855465022596;75191603398.19354;25.71723841682839;2610231560;25.71723841682839 +2022-03-14T05:40:00Z;87.62101996709508;3.070825035683759;9.034325280278308;75187333053.93549;25.72145714538402;2609511642;25.72145714538402 +2022-03-14T05:50:00Z;87.79914026043608;3.097761717495469;8.831216731620994;75183680809.29033;25.725065245304208;2607961944;25.725065245304208 +2022-03-14T06:00:00Z;87.77153004794897;3.0858530946192704;8.851260545658194;75179660808.39345;25.729036656401878;2606211270;25.729036656401878 +2022-03-14T06:10:00Z;87.71345693777688;3.0412818038802403;8.965993940192329;75175824669.37704;25.732826427959825;2605009689;25.732826427959825 +2022-03-14T06:20:00Z;86.97659219137834;3.039251999494479;9.708985101393202;75171945571.09677;25.73665863953251;2603115025;25.73665863953251 +2022-03-14T06:30:00Z;87.79364146152724;3.124759504039522;8.795511495935676;75167971988.64516;25.74058419324521;2601663983;25.74058419324521 +2022-03-14T06:40:00Z;87.73126195458656;3.0526486242713884;8.94121684633913;75164234190.45161;25.74427681262702;2600621039;25.74427681262702 +2022-03-14T06:50:00Z;87.16363076903612;3.0093672100178916;9.555519599551271;75160123458.06451;25.748337858542296;2598954169;25.748337858542296 +2022-03-14T07:00:00Z;87.77277636662977;3.0360522097378175;8.897676567973704;75156580587.01639;25.751837906865422;2597138366;25.751837906865422 +2022-03-14T07:10:00Z;87.22647335569097;3.117843085875157;9.38461788191397;75218918752.5246;25.690253223513828;2595331171;25.690253223513828 +2022-03-14T07:20:00Z;87.65780312203397;3.112606162393353;8.946762157493337;75227201469.93549;25.68207061940793;2594965042;25.68207061940793 +2022-03-14T07:30:00Z;87.43046343306071;3.1003293676764105;9.170859471612246;75220550028.3871;25.688641664902285;2593644544;25.688641664902285 +2022-03-14T07:40:00Z;87.83600316020525;3.0893152538907076;8.795871253792095;75216877237.67741;25.692270062546456;2592538690;25.692270062546456 +2022-03-14T07:50:00Z;87.78504940770985;3.1001024457420474;8.859020550276165;75212789363.6129;25.69630852642797;2591235959;25.69630852642797 +2022-03-14T08:00:00Z;87.80691030561137;3.0566383659165433;8.849433060419969;75209060754.88524;25.69999206741707;2589709279;25.69999206741707 +2022-03-14T08:10:00Z;87.93967031680103;3.001242502347108;8.739485238575346;75205121141.5082;25.70388406263983;2588756100;25.70388406263983 +2022-03-14T08:20:00Z;86.88412533806601;3.0570682175129607;9.756989622416905;75201196032;25.70776172930217;2586873526;25.70776172930217 +2022-03-14T08:30:00Z;87.34499337000477;3.004396713404705;9.305193817194004;75197419718.19354;25.711492398758207;2583930285;25.711492398758207 +2022-03-14T08:40:00Z;87.79945822911338;3.1377449883079063;8.783830898677788;75193305088;25.715557295367102;2582987479;25.715557295367102 +2022-03-14T08:50:00Z;87.76310319605577;3.0820139634520958;8.856617712228648;75189701202.58064;25.719117620580025;2581389983;25.719117620580025 +2022-03-14T09:00:00Z;87.87420779465371;3.053021430471204;8.788034597746602;75185447176.25807;25.723320228435245;2579455802;25.723320228435245 +2022-03-14T09:10:00Z;87.79745800915295;2.990872765932045;8.928235298019905;75181609430.03279;25.727111587775738;2577535174;25.727111587775738 +2022-03-14T09:20:00Z;87.72787704948853;3.0511887580904973;8.935734089772776;75177305715.6129;25.731363283147633;2575011510;25.731363283147633 +2022-03-14T09:30:00Z;87.82948782912734;3.0535758746975517;8.819292712651468;75171333285.16129;25.737263524760515;2602745195;25.737263524760515 +2022-03-14T09:40:00Z;87.76091063125436;2.984208593693108;8.993620715006942;75159187389.93549;25.749262612404575;2619081431;25.749262612404575 +2022-03-14T09:50:00Z;87.7303017933936;3.113223470305334;8.768796578129315;75154971020.3871;25.753428018643508;2617370690;25.753428018643508 +2022-03-14T10:00:00Z;87.70835213820229;3.0602230925627723;8.915622914775035;75151113367.08197;25.75723904444672;2616139373;25.75723904444672 +2022-03-14T10:10:00Z;87.69922818707923;3.1080647343956906;8.923308492449515;75147142309.16129;25.761162104142535;2614388141;25.761162104142535 +2022-03-14T10:20:00Z;86.79799325337153;3.0222506603978925;9.884941334244093;75143411778.06451;25.764847544265045;2612865817;25.764847544265045 +2022-03-14T10:30:00Z;87.6169134885343;3.0767846203132385;9.00249535724624;75139298931.6129;25.76891067869211;2611147214;25.76891067869211 +2022-03-14T10:40:00Z;87.8497346125238;3.0534012734765805;8.803130081761763;75175293654.70967;25.733351024246524;2609656733;25.733351024246524 +2022-03-14T10:50:00Z;87.86090466108557;3.023564284505567;8.848954166546237;75187199537.54839;25.721589047956943;2607673014;25.721589047956943 +2022-03-14T11:00:00Z;87.7959647727563;3.0560725888418876;8.856067025908695;75183770260.64516;25.72497687514897;2606234842;25.72497687514897 +2022-03-14T11:10:00Z;87.71588488354384;3.0295115608577072;8.959164445896583;75202624528.78688;25.706350498773137;2604912310;25.706350498773137 +2022-03-14T11:20:00Z;87.76724494991268;3.0830000355335057;8.8582010292499;75199821790.42622;25.709119360401516;2603135042;25.709119360401516 +2022-03-14T11:30:00Z;87.77157989572484;3.112942755711284;8.80449849133567;75193375710.96774;25.715487526020016;2601607564;25.715487526020016 +2022-03-14T11:40:00Z;87.38496452899905;3.0139740995149205;9.333705952992442;75189513249.03226;25.719303302331614;2599771086;25.719303302331614 +2022-03-14T11:50:00Z;87.36811543722676;3.1090340034778627;9.219534007372305;75185571179.35484;25.72319772416542;2598944570;25.72319772416542 +2022-03-14T12:00:00Z;87.78233391468252;3.150905255550521;8.799814601471702;75181668153.80646;25.727053573797022;2597751379;25.727053573797022 +2022-03-14T12:10:00Z;87.85095106586921;3.0692380971629105;8.784862021210127;75177868981.67741;25.730806825286823;2596313815;25.730806825286823 +2022-03-14T12:20:00Z;87.82359982854678;2.994827739294982;8.905251703203824;75173763709.90164;25.734862476593253;2593997196;25.734862476593253 +2022-03-14T12:30:00Z;87.64405511180063;3.0913690774166196;8.98501655803975;75170200525.63934;25.73838259260449;2592961965;25.73838259260449 +2022-03-14T12:40:00Z;87.05884292650836;3.0984442138926482;9.567926940426592;75166130902.70967;25.74240302595284;2591156819;25.74240302595284 +2022-03-14T12:50:00Z;87.81692786458643;2.994718258614688;8.882180703799945;75162336619.35484;25.74615144775911;2589606229;25.74615144775911 +2022-03-14T13:00:00Z;87.2641650927415;3.0655184367429023;9.401401152944345;75158444032;25.749996985363758;2587434612;25.749996985363758 +2022-03-14T13:10:00Z;87.88151124985212;3.011836992827333;8.837585111942024;75154086152.25807;25.75430219136082;2584734158;25.75430219136082 +2022-03-14T13:20:00Z;87.80261653750863;3.0590721606425015;8.866953135861193;75150344258.06451;25.757998857234227;2583967149;25.757998857234227 +2022-03-14T13:30:00Z;87.78867477499959;3.0349100748357065;8.885057036138635;75143795480.7742;25.764468479374642;2582738812;25.764468479374642 +2022-03-14T13:40:00Z;87.79351601672498;3.0772715356479634;8.838613771844825;75140139734.70967;25.768080038392487;2581449431;25.768080038392487 +2022-03-14T13:50:00Z;87.74588526504851;3.1404765614679375;8.846202018376413;75135945166.45161;25.77222390685354;2579419136;25.77222390685354 +2022-03-14T14:00:00Z;87.87919821866905;3.0833931740300473;8.772496645160334;75129551508.64516;25.778540284441156;2578094919;25.778540284441156 +2022-03-14T14:10:00Z;87.67547551520194;3.153040825074457;8.893398729912363;75153134823.2258;25.755242021667616;2576039606;25.755242021667616 +2022-03-14T14:20:00Z;87.75205716009529;3.0796548025269184;8.889628386785862;75171952375.74193;25.736651917135173;2573899247;25.736651917135173 +2022-03-14T14:30:00Z;87.43643631591537;3.0890121244235806;9.202763728031204;75167775948.8;25.74077786355441;2572065561;25.74077786355441 +2022-03-14T14:40:00Z;86.75936069551466;3.1014689243343683;9.870149840658788;75164013204.64516;25.744495127375373;2569226306;25.744495127375373 +2022-03-14T14:50:00Z;86.70111010502801;3.1111763180361978;9.92636440536352;75160283796.64516;25.748179457976004;2568862753;25.748179457976004 +2022-03-14T15:00:00Z;87.8327085269608;3.104584480540255;8.75830841604343;75156333601.03226;25.752081907526996;2567195598;25.752081907526996 +2022-03-14T15:10:00Z;87.92909488600462;3.0509930020008245;8.761640016921074;75174193944.7742;25.73443744197478;2565309077;25.73443744197478 +2022-03-14T15:20:00Z;87.8646144463883;3.06994509850217;8.790998309975956;75171273034.32259;25.737323047346614;2562635115;25.737323047346614 +2022-03-14T15:30:00Z;87.88862221040982;2.945368122888005;8.885474962300949;75164683537.06667;25.743832897269908;2561895523;25.743832897269908 +2022-03-14T15:40:00Z;87.13074928184308;3.1521586896226004;9.393318199039992;75160846798.45161;25.747623261179157;2560509291;25.747623261179157 +2022-03-14T15:50:00Z;87.69900016272689;3.066953054945986;8.936666621902248;75156789512.25807;25.75163150690567;2559285710;25.75163150690567 +2022-03-14T16:00:00Z;87.64232698973767;3.1353309832416;8.956486919832557;75153013793.03226;25.755361588967762;2557479110;25.755361588967762 +2022-03-14T16:10:00Z;87.6947438526293;3.1506911905819845;8.873186453734954;75148880070.19354;25.75944534744878;2556104435;25.75944534744878 +2022-03-14T16:20:00Z;87.74272524680508;3.012897860001824;8.975089743231127;75144985213.90164;25.763293126565816;2554765444;25.763293126565816 +2022-03-14T16:30:00Z;87.29159348781758;3.1487631442705752;9.246490036729352;75141182893.41936;25.76704948835468;2553352522;25.76704948835468 +2022-03-14T16:40:00Z;86.96479921759082;3.079425698278164;9.67456163263951;75137157186.06451;25.771026536936283;2550502235;25.771026536936283 +2022-03-14T16:50:00Z;87.14006727918313;3.1256475410395144;9.43721123692254;75133178252.3871;25.774957377194458;2549194157;25.774957377194458 +2022-03-14T17:00:00Z;87.65973611326712;3.1725540024316596;8.896908424636583;75129322330.83871;25.77876669217271;2547505945;25.77876669217271 +2022-03-14T17:10:00Z;87.77757076896205;3.0700059150947627;8.88088556241971;75126267111.2258;25.781784983309382;2564555281;25.781784983309382 +2022-03-14T17:20:00Z;87.61636502185246;3.201709990422818;8.911127101608875;75117272361.29033;25.790671013594174;2590704355;25.790671013594174 +2022-03-14T17:30:00Z;87.73461827640756;3.119833192416685;8.873021234458516;75107715891.2;25.800111974515513;2589760611;25.800111974515513 +2022-03-14T17:40:00Z;87.5409433784461;3.0856636964565864;9.106511979334003;75137656501.67741;25.770533256557208;2589826015;25.770533256557208 +2022-03-14T17:50:00Z;87.74367963971055;3.112112691005962;8.86618601124104;75155673484.3871;25.75273404533434;2589166097;25.75273404533434 +2022-03-14T18:00:00Z;87.45314255056162;3.054029279922038;9.193092243410254;75151412719.48387;25.756943310320903;2587275132;25.756943310320903 +2022-03-14T18:10:00Z;87.9169314935953;3.036905879124698;8.77508976697945;75147947965.93549;25.760366185351455;2584509935;25.760366185351455 +2022-03-14T18:20:00Z;87.71695827622382;3.1005631126802595;8.898749652108927;75143718845.93549;25.764544187927125;2583300532;25.764544187927125 +2022-03-14T18:30:00Z;87.81981076585795;3.068252788966227;8.8406631505313;75140110930.58064;25.76810849436566;2581148177;25.76810849436566 +2022-03-14T18:40:00Z;87.9088489121504;3.0304899903685856;8.782631880620487;75136015645.37704;25.772154279807737;2579914422;25.772154279807737 +2022-03-14T18:50:00Z;87.21540500857641;3.022784681501042;9.487524946137336;75132275612.90323;25.77584910646404;2578402073;25.77584910646404 +2022-03-14T19:00:00Z;87.65862225911157;3.1048135887839083;8.975437101819299;75128349795.09677;25.779727472863435;2576240904;25.779727472863435 +2022-03-14T19:10:00Z;87.5313347444192;3.1467596985909747;9.028303863860529;75146134230.70967;25.762157997937763;2575705319;25.762157997937763 +2022-03-14T19:20:00Z;87.87238900833681;3.0470946869117017;8.80696600707345;75143117790.96774;25.76513797793625;2573935666;25.76513797793625 +2022-03-14T19:30:00Z;87.79004525552806;3.0351619668255854;8.869784714569098;75136582236.32787;25.771594537248557;2572774962;25.771594537248557 +2022-03-14T19:40:00Z;87.57272781735695;3.0675433375247474;9.083362764955236;75132907189.67741;25.775225163565914;2570499766;25.775225163565914 +2022-03-14T19:50:00Z;87.6454691525981;3.1153422410210303;8.954731295404555;75128649728;25.779431165252813;2569656056;25.779431165252813 +2022-03-14T20:00:00Z;87.89072465436175;3.0606938078039665;8.750987887629545;75125233003.35484;25.782806591906077;2567488413;25.782806591906077 +2022-03-14T20:10:00Z;87.74179018178204;3.054647915449539;8.893046207195544;75120960941.41936;25.787027017377543;2565424161;25.787027017377543 +2022-03-14T20:20:00Z;87.9711940260046;3.0386734548863155;8.733125456801723;75117369674.32259;25.790574876785705;2563966315;25.790574876785705 +2022-03-14T20:30:00Z;87.83310171069;3.037413631941425;8.862190163467996;75113271560.25807;25.794623456896208;2563368591;25.794623456896208 +2022-03-14T20:40:00Z;87.7194574946379;3.029386269851169;8.965226655662029;75109538295.60655;25.798311597532955;2564568626;25.798311597532955 +2022-03-14T20:50:00Z;87.36338059837085;3.1042635528617257;9.242807180893946;75105589710.45161;25.802212456091617;2564086487;25.802212456091617 +2022-03-14T21:00:00Z;87.07410685464433;3.0466035971211753;9.591018204933993;75101680474.83871;25.806074440726633;2561795898;25.806074440726633 +2022-03-14T21:10:00Z;87.62646885884254;3.1843879770660903;8.903919883425493;75126299813.16129;25.781752676642583;2561364430;25.781752676642583 +2022-03-14T21:20:00Z;87.59247350135166;3.0865553132763006;9.040296407329322;75149196717.41936;25.759132527541798;2559156488;25.759132527541798 +2022-03-14T21:30:00Z;87.67280852835889;3.033776493236153;9.023446762354673;75143182336;25.765074213060576;2557451952;25.765074213060576 +2022-03-14T21:40:00Z;87.95163581022152;3.020036441137144;8.769184643402962;75138877373.93549;25.76932714099681;2555674756;25.76932714099681 +2022-03-14T21:50:00Z;87.72436722052834;3.0778048141865444;8.912014233649895;75135371767.60655;25.77279037501986;2553329135;25.77279037501986 +2022-03-14T22:00:00Z;87.83337030067354;3.1246158147757224;8.74547103721875;75131175440.51613;25.776935981054255;2552032685;25.776935981054255 +2022-03-14T22:10:00Z;87.65035173950294;3.086343430265402;8.94446002300476;75127530859.35484;25.780536510119198;2550477725;25.780536510119198 +2022-03-14T22:20:00Z;87.15823997598902;3.037026061714708;9.514556389961385;75123482425.80646;25.78453601020257;2548909551;25.78453601020257 +2022-03-14T22:30:00Z;87.59739586946655;3.117747180028181;8.983989388632175;75119684442.83871;25.788288086904483;2546775668;25.788288086904483 +2022-03-14T22:40:00Z;87.90530314016279;3.039997995359833;8.745527996278609;75115807578.83871;25.79211809120266;2545079884;25.79211809120266 +2022-03-14T22:50:00Z;87.91138052565063;3.005129400912146;8.81113311221502;75111861936.2623;25.79601604274978;2543112588;25.79601604274978 +2022-03-14T23:00:00Z;87.82667632787096;3.0510387342660565;8.87298143004308;75108107180.06557;25.799725415163177;2541714399;25.799725415163177 +2022-03-14T23:10:00Z;86.91153673920402;3.167207792941085;9.619393166457932;75153974305.03226;25.75441268668786;2539814714;25.75441268668786 +2022-03-14T23:20:00Z;87.86398483858049;3.0871155356931865;8.769316772532497;75151970171.87097;25.75639259586752;2537902344;25.75639259586752 +2022-03-14T23:30:00Z;87.8308271486757;3.0764964385928475;8.84168775403419;75137588785.54839;25.770600154200565;2536168481;25.770600154200565 +2022-03-14T23:40:00Z;87.27591004648903;3.0720244123849443;9.381475543835576;75133413243.87097;25.774725226055498;2534381534;25.774725226055498 +2022-03-14T23:50:00Z;87.40466181169515;3.1048084817686266;9.189275727323855;75129152941.41936;25.778934034180104;2533162337;25.778934034180104 +2022-03-15T00:00:00Z;87.80678179741213;3.013982487253059;8.896916421928806;75125584274.88524;25.782459566198877;2531332757;25.782459566198877 +2022-03-15T00:10:00Z;87.90246738815172;3.0364847197502782;8.78341031301032;75121681573.16129;25.78631509592014;2530117698;25.78631509592014 +2022-03-15T00:20:00Z;87.95698131407309;2.9992486267053247;8.754737100091681;75117973305.80646;25.789978541402846;2528683107;25.789978541402846 +2022-03-15T00:30:00Z;87.91066551299826;3.152538580214356;8.688204789837608;75114053169.54839;25.793851294926792;2526523656;25.793851294926792 +2022-03-15T00:40:00Z;87.86499757360004;3.0718945529487534;8.792548740478836;75133491332.12903;25.774648081651137;2524401862;25.774648081651137 +2022-03-15T00:50:00Z;87.5428503098968;3.1338834859234175;9.026175054879657;75162048512;25.746436072756897;2535028300;25.746436072756897 +2022-03-15T01:00:00Z;87.87688238781735;3.0704132964711186;8.780849112509024;75157972199.2258;25.750463115089527;2569868982;25.750463115089527 +2022-03-15T01:10:00Z;87.57787431881806;3.0024230874253606;9.145052243573529;75153908599.46666;25.75447759806948;2568664890;25.75447759806948 +2022-03-15T01:20:00Z;84.49731991424474;3.2471401324441405;11.871652258986312;75153088379.87097;25.75528790366106;2566853335;25.75528790366106 +2022-03-15T01:30:00Z;87.15555018318908;3.110719356311301;9.4505132476786;75150185372.90323;25.758155821948655;2566234641;25.758155821948655 +2022-03-15T01:40:00Z;87.64226638977962;3.0489484803159637;9.034459812635356;75145864753.54839;25.762424217925368;2564912359;25.762424217925368 +2022-03-15T01:50:00Z;87.58913353783626;3.1045557504026564;9.045947052985273;75142113742.45161;25.766129890505873;2563424785;25.766129890505873 +2022-03-15T02:00:00Z;87.52783829661908;3.1239663146536674;9.043130080390766;75138102503.2258;25.770092645834897;2561345435;25.770092645834897 +2022-03-15T02:10:00Z;87.36572576753477;3.072534143262756;9.273793102957985;75134008419.09677;25.774137244719793;2559952830;25.774137244719793 +2022-03-15T02:20:00Z;87.36285776484888;3.119238142697621;9.233609827450909;75130347788.59016;25.77775362914143;2558648584;25.77775362914143 +2022-03-15T02:30:00Z;87.7728839986535;3.0423801761412594;8.877892241680406;75126162531.09677;25.781888299377133;2557436102;25.781888299377133 +2022-03-15T02:40:00Z;87.6977121291612;3.1373330494607514;8.878002131901209;75122386745.80646;25.78561844670523;2555242694;25.78561844670523 +2022-03-15T02:50:00Z;87.52314259570093;3.208346033319437;8.98721790404352;75118446856.25807;25.789510714761242;2553040301;25.789510714761242 +2022-03-15T03:00:00Z;87.66154359149591;3.083649467576334;8.984178999844586;75114282413.41936;25.793624821929242;2552061616;25.793624821929242 +2022-03-15T03:10:00Z;87.50092848028942;3.081225496052936;9.144416691192891;75132495475.6129;25.77563190123758;2550246350;25.77563190123758 +2022-03-15T03:20:00Z;87.70608537905368;3.033556919498062;8.985192635524529;75128915464.39345;25.77916864081835;2548756414;25.77916864081835 +2022-03-15T03:30:00Z;87.33456793760351;3.183763802575478;9.205157925723821;75122932901.16129;25.785078892736735;2545687453;25.785078892736735 +2022-03-15T03:40:00Z;87.18628754354357;3.073665747518722;9.440773949238874;75118635536.51613;25.789324315083714;2545076885;25.789324315083714 +2022-03-15T03:50:00Z;87.69082301469014;3.072878717193037;8.962744692785234;75114967700.64516;25.79294781777839;2543529654;25.79294781777839 +2022-03-15T04:00:00Z;87.73554716311;3.026107665793405;8.95867018387689;75110920390.19354;25.79694620833986;2541750404;25.79694620833986 +2022-03-15T04:10:00Z;87.0050000394743;3.1075491962808526;9.59649184139059;75135222618.83871;25.772937721024753;2540445562;25.772937721024753 +2022-03-15T04:20:00Z;87.66342050490283;3.092450955670107;8.963385029221755;75161356221.93549;25.74711999510307;2537700121;25.74711999510307 +2022-03-15T04:30:00Z;87.58955356739028;3.0560248698676635;9.059501765089292;75157354260.98361;25.751073584304766;2536365948;25.751073584304766 +2022-03-15T04:40:00Z;87.76178440641634;3.0699441128505547;8.897240068637645;75153630241.03226;25.75475259198215;2534815149;25.75475259198215 +2022-03-15T04:50:00Z;87.79044310940645;3.0745377934708955;8.87125419672842;75149493809.54839;25.758839026368896;2533346601;25.758839026368896 +2022-03-15T05:00:00Z;87.69907158032143;3.145909791318542;8.863312726564391;75138751058.58064;25.76945192957644;2531602894;25.76945192957644 +2022-03-15T05:10:00Z;87.19461975222282;3.0671868558269266;9.438294295997997;75134083798.70967;25.77406277622119;2531048217;25.77406277622119 +2022-03-15T05:20:00Z;87.90286455187912;3.039997206029209;8.78506650349279;75130618648.7742;25.777486042847706;2529928041;25.777486042847706 +2022-03-15T05:30:00Z;87.7291629471114;3.078882942759133;8.91975115163191;75123940583.2258;25.784083390537464;2529124154;25.784083390537464 +2022-03-15T05:40:00Z;87.89280066316886;3.03409629524877;8.802898800844881;75120198504.91803;25.787780238299693;2528143030;25.787780238299693 +2022-03-15T05:50:00Z;87.03128989812812;3.0892359097282145;9.605094154824549;75116164789.67741;25.791765197975657;2526305908;25.791765197975657 +2022-03-15T06:00:00Z;87.53804713710032;3.030695653094052;9.14318435796781;75112347185.54839;25.795536658677644;2524485500;25.795536658677644 +2022-03-15T06:10:00Z;87.4609719918427;3.0518036838150464;9.200236657131843;75108432730.83871;25.799403799326157;2522805347;25.799403799326157 +2022-03-15T06:20:00Z;87.82553689430381;3.056887634115634;8.83828332778473;75104472559.48387;25.80331610404217;2521699244;25.80331610404217 +2022-03-15T06:30:00Z;87.7184453517978;3.119368425958046;8.883974938277358;75100714875.87097;25.80702836848803;2519335573;25.80702836848803 +2022-03-15T06:40:00Z;87.6688022687559;3.0636001344611086;8.987028987445077;75096629919.4754;25.81106394996649;2518642027;25.81106394996649 +2022-03-15T06:50:00Z;87.75889071109071;3.0902505354536993;8.851400132586855;75093006534.19354;25.81464353934685;2517770967;25.81464353934685 +2022-03-15T07:00:00Z;87.77103437057814;3.018095215642878;8.930706733298269;75088746429.93549;25.818852151673482;2515904644;25.818852151673482 +2022-03-15T07:10:00Z;87.23010363420101;3.070673499932841;9.406612258284495;75107290078.96774;25.8005326399502;2513786219;25.8005326399502 +2022-03-15T07:20:00Z;87.65530603044218;3.127419519321831;8.929818254259475;75103736997.16129;25.80404277561411;2512495121;25.80404277561411 +2022-03-15T07:30:00Z;87.69481920352345;3.0000823492368403;9.043854238513585;75097719312.51613;25.80998772443256;2510841378;25.80998772443256 +2022-03-15T07:40:00Z;87.60787697099407;3.1341148313369893;8.973348513625883;75115103397.16129;25.79281376142767;2508344419;25.79281376142767 +2022-03-15T07:50:00Z;87.66319524045508;3.0707823587417624;8.98343089147733;75145568994.62296;25.762716402009115;2506211989;25.762716402009115 +2022-03-15T08:00:00Z;87.35016582934949;3.1290192483658585;9.255599958117225;75141410617.80646;25.76682451647499;2503656019;25.76682451647499 +2022-03-15T08:10:00Z;86.7370125713568;3.062044703573163;9.923871408645269;75137793453.41936;25.77039796015262;2503089515;25.77039796015262 +2022-03-15T08:20:00Z;87.68512599515593;3.0860358826664327;8.943209691680067;75133797276.90323;25.77434583483512;2501241294;25.77434583483512 +2022-03-15T08:30:00Z;87.57353076114937;3.1745315409645225;8.967989864295339;75129831357.93549;25.77826381769257;2502231426;25.77826381769257 +2022-03-15T08:40:00Z;87.86972958487418;3.01894068329679;8.828630629834844;75125868279.74193;25.78217899411232;2545188058;25.78217899411232 +2022-03-15T08:50:00Z;87.5416662224899;3.118668602154672;9.067812285401882;75122189741.41936;25.785813069897927;2542616312;25.785813069897927 +2022-03-15T09:00:00Z;87.67177763789846;3.0451154737317427;8.984679637208856;75118100882.88524;25.78985250634973;2541758068;25.78985250634973 +2022-03-15T09:10:00Z;87.31296115034144;3.06927988042266;9.337180221322138;75113810118.19354;25.794091408516987;2540330149;25.794091408516987 +2022-03-15T09:20:00Z;87.63746633296266;3.0408890836387394;9.050369488426401;75110041864.25807;25.797814115521803;2538676224;25.797814115521803 +2022-03-15T09:30:00Z;87.28498780646251;3.0876176687063404;9.303920108943064;75103661551.48387;25.804117309378714;2536571937;25.804117309378714 +2022-03-15T09:40:00Z;87.80600493823432;3.0364335028121783;8.887595500340177;75099720869.16129;25.808010360626653;2536404378;25.808010360626653 +2022-03-15T09:50:00Z;87.684766742093;3.0670933637939153;8.97190891264302;75095796819.93443;25.811886979823296;2534782910;25.811886979823296 +2022-03-15T10:00:00Z;87.80432803965883;3.0176203067268554;8.882267286809135;75091800399.7377;25.815835095241003;2533919381;25.815835095241003 +2022-03-15T10:10:00Z;86.77515401565314;3.056472795717131;9.8503177197876;75088042446.45161;25.819547626100512;2531771954;25.819547626100512 +2022-03-15T10:20:00Z;87.68270478475662;3.050361566661972;8.994017793046632;75084185269.67741;25.823358181132622;2530906574;25.823358181132622 +2022-03-15T10:30:00Z;87.2679755025459;3.044718335302369;9.417102822181421;75080236395.35484;25.827259325363755;2529321422;25.827259325363755 +2022-03-15T10:40:00Z;87.71807177346045;3.0482426365104;8.93941615381553;75076302848;25.83114532788438;2527349000;25.83114532788438 +2022-03-15T10:50:00Z;87.86046468041495;3.019277535675456;8.820375021183548;75072332965.16129;25.83506722670145;2525569225;25.83506722670145 +2022-03-15T11:00:00Z;87.77609099766798;3.004242017626859;8.94443690706336;75066770885.2459;25.84056207768998;2522786981;25.84056207768998 +2022-03-15T11:10:00Z;87.70834514071545;3.0945516432548805;8.929829751345423;75094995145.44263;25.81267896446586;2522404137;25.81267896446586 \ No newline at end of file diff --git a/test_input_data/usage_idle_data.csv b/test_input_data/usage_idle_data.csv index 184ee4ff47edd910d3cb32046b420c8efb9b53a3..4426352746d249fa847248f2b6c5e2ebd39d68c1 100644 --- a/test_input_data/usage_idle_data.csv +++ b/test_input_data/usage_idle_data.csv @@ -1392,4 +1392,4 @@ _time;_value 2021-11-17T11:00:00Z;96.22618296114042 2021-11-17T12:00:00Z;96.18600928188728 2021-11-17T13:00:00Z;96.11710448444755 -2021-11-17T14:00:00Z;95.86516970627649 +2021-11-17T14:00:00Z;95.86516970627649 \ No newline at end of file diff --git a/tox.ini b/tox.ini index 25803828d395bf729f1bb9b65d26886d6b40b5ca..c0bbff1908affc39a3edaf77f1e048b51de119bf 100644 --- a/tox.ini +++ b/tox.ini @@ -8,4 +8,4 @@ deps=-r{toxinidir}/requirements.txt {toxinidir} commands= - pytest --cov=src\psl + pytest --cov=src\psl \ No newline at end of file