# Piscada Cloud
Library for the Piscada Cloud including authentication and data access.
## Features
- Login to Piscada Cloud and retrieve credentials
- Persist credentialss locally
- Read historic values for multiple tags as a Pandas DataFrame
- Possible apply time-based linear interpolation to measurements
- Utils to add fractional representations of periods: day, week, year
## Install
Install from PyPI:
```shell
pip install piscada-cloud
```
or
```shell
poetry add piscada-cloud
```
Install from local source:
```shell
pip install --editable path/to/piscada_cloud
```
or
```shell
poetry add path/to/piscada_cloud
```
## Usage
### Authentication
To log-in interactively and persist the retrieved credentials on disk (under `$HOME/.piscada_credentials`) simply run:
```shell
python -m piscada_cloud.auth
```
or
```shell
poetry run python -m piscada_cloud.auth
```
Any future invocation, e.g. `credentials = piscada_cloud.auth.persisted_login()` will return the credentials on disk without user interaction.
`credentials = piscada_cloud.auth.login(username, password, host)` can be used to retrieve the credentials programmatically.
### Getting Data
The credentials retrieved through the login can be used to get the host and acccesss-token for the historical data API:
```python
from piscada_cloud import auth
credentials = auth.login_persisted()
host, token = auth.get_historian_credentials(credentials)
```
The host and token can be used to retrieve historic data as a Pandas DataFrame.
The `get_historic_values` method takes a row of parameters:
- `start`: Datetime object
- `end`: Datetime object
- `tags`: List of `Tag` objects
- `host` (optional): Endpoint to which we send the historian queries. e.g. `historian.piscada.online`.
- `token` (optional): Access token, associated with the endpoint, used for authentication.
The if the `host` or `token` arguments are not provided, the environment variables `HISTORIAN_HOST` and `HISTORIAN_TOKEN` are used in stead, respectively.
```python
from datetime import datetime, timedelta, timezone
from piscada_cloud.data import get_historic_values
from piscada_cloud.mappings import Tag
tags = [
Tag(controller_id="fe7bd2c3-6c20-44d4-aecc-df5822457400", name="ServerCpuUsage"),
Tag(controller_id="fe7bd2c3-6c20-44d4-aecc-df5822457400", name="ServerMemoryUsage"),
]
df = get_historic_values(
start=datetime.now(timezone.utc) - timedelta(days=30),
end=datetime.now(timezone.utc),
tags=tags
)
```
## Write Data
In this example the column `oCU135001RT90_MV` is selected and the average value is calculated using the method `.mean()`.
To write the result back to the Piscada Cloud, the `data` module offers the `write_value` function. It takes these arguments:
- `tag`: A `Tag` object
- `value`: The float, string, or dict value to write to the tag. Float and string will be sent as is, dict will be serialised as JSON string.
- `timestamp` (optional): The timestamp in milliseconds since epoch at which to write the value, by default `int(time.time() * 1000)`.
- `host`: Endpoint to send post request. Overrides the default, which is `os.environ['WRITEAPI_HOST']`.
- `token`: Access token accosiated with the host. Overrides the default, which is `os.environ['WRITEAPI_TOKEN']`.
The `Tag.name` must use the prefix `py_` as this is the only namespace allowed for writing data via the API.
```python
from piscada_cloud.data import write_value
from piscada_cloud.mappings import Tag
mean = df["oCU135001RT90_MV"].mean()
response = write_value(Tag(controller_id="0798ac4a-4d4f-4648-95f0-12676b3411d5", name="py_oCU135001RT90_MV_1h_mean"), value=mean)
if response.ok:
print("OK")
else:
print(response.text)
```
The `response` returned by the `write_value` method allows to check if the writing of data was successful `response.ok == True`.
### Manipulations
In order to support analysis in the context of periodic patters, the `manipulations` allow you to add fractional representations of day, week, and year as additional columns in the DataFrame:
- 00:00:00 -> 0.0 --- 23:59:59 -> 1.0
- Monday 00:00:00 -> 0.0 --- Sunday 23:59:59 -> 1.0
- 1st Jan. 00:00:00 -> 0.0 --- 31st Dec. 23:59:59 -> 1.0
```python
from piscada_cloud import manipulations
manipulations.add_weekdays(data)
manipulations.add_day_fraction(data)
manipulations.add_week_fraction(data)
manipulations.add_year_fraction(data)
```
## Development
### Run QA as a pre-commit hook
Enable the provided git pre commit hook: `ln -s ./qa.sh .git/hooks/pre-commit`
### Documentation
Build and run MkDocs documentation:
```bash
poetry run mkdocs build
poetry run mkdocs serve
```
Note: If you want to deploy a new version of your documentation, use below commands instead:
```bash
poetry run mike deploy [version]
poetry run mike serve
```
## Run documentation via docker image
```bash
docker pull piscada/piscada-cloud-documentation:tagname
docker run -p 8000:8000 piscada/piscada-cloud-documentation:tagname
```
## Requirements
The package will support the two latest version of Python.
## Authors
- Tim Jagenberg [tim.jagenberg@piscada.com](mailto:tim.jagenberg@piscada.com)
- Filip Henrik Larsen [filip.larsen@piscada.com](mailto:filip.larsen@piscada.com)
- Aleksandra Zajdel [aleksandra.zajdel@piscada.com](mailto:aleksandra.zajdel@piscada.com)
## License
© Piscada AS 2019
Raw data
{
"_id": null,
"home_page": "https://piscada.com/",
"name": "piscada_cloud",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.10",
"maintainer_email": null,
"keywords": "piscada, automation, building-automation, fish-farming, assisted-living",
"author": "Tim Jagenberg",
"author_email": "tim.jagenberg@piscada.com",
"download_url": "https://files.pythonhosted.org/packages/ff/4b/dfe2035c3f9dd6f1d4de0d43d25405b616e17c3560c651682615b8a95061/piscada_cloud-7.1.0.tar.gz",
"platform": null,
"description": "# Piscada Cloud\n\nLibrary for the Piscada Cloud including authentication and data access.\n\n## Features\n\n- Login to Piscada Cloud and retrieve credentials\n- Persist credentialss locally\n- Read historic values for multiple tags as a Pandas DataFrame\n- Possible apply time-based linear interpolation to measurements\n- Utils to add fractional representations of periods: day, week, year\n\n## Install\n\nInstall from PyPI:\n\n```shell\npip install piscada-cloud\n```\n\nor\n\n```shell\npoetry add piscada-cloud\n```\n\nInstall from local source:\n\n```shell\npip install --editable path/to/piscada_cloud\n```\n\nor\n\n```shell\npoetry add path/to/piscada_cloud\n```\n\n## Usage\n\n### Authentication\n\nTo log-in interactively and persist the retrieved credentials on disk (under `$HOME/.piscada_credentials`) simply run:\n\n```shell\npython -m piscada_cloud.auth\n```\n\nor\n\n```shell\npoetry run python -m piscada_cloud.auth\n```\n\nAny future invocation, e.g. `credentials = piscada_cloud.auth.persisted_login()` will return the credentials on disk without user interaction.\n\n`credentials = piscada_cloud.auth.login(username, password, host)` can be used to retrieve the credentials programmatically.\n\n### Getting Data\n\nThe credentials retrieved through the login can be used to get the host and acccesss-token for the historical data API:\n\n```python\nfrom piscada_cloud import auth\n\ncredentials = auth.login_persisted()\nhost, token = auth.get_historian_credentials(credentials)\n```\n\nThe host and token can be used to retrieve historic data as a Pandas DataFrame.\nThe `get_historic_values` method takes a row of parameters:\n\n- `start`: Datetime object\n- `end`: Datetime object\n- `tags`: List of `Tag` objects\n- `host` (optional): Endpoint to which we send the historian queries. e.g. `historian.piscada.online`.\n- `token` (optional): Access token, associated with the endpoint, used for authentication.\n\nThe if the `host` or `token` arguments are not provided, the environment variables `HISTORIAN_HOST` and `HISTORIAN_TOKEN` are used in stead, respectively.\n\n```python\nfrom datetime import datetime, timedelta, timezone\n\nfrom piscada_cloud.data import get_historic_values\nfrom piscada_cloud.mappings import Tag\n\n\ntags = [\n Tag(controller_id=\"fe7bd2c3-6c20-44d4-aecc-df5822457400\", name=\"ServerCpuUsage\"),\n Tag(controller_id=\"fe7bd2c3-6c20-44d4-aecc-df5822457400\", name=\"ServerMemoryUsage\"),\n]\n\ndf = get_historic_values(\n start=datetime.now(timezone.utc) - timedelta(days=30),\n end=datetime.now(timezone.utc),\n tags=tags\n)\n```\n\n## Write Data\n\nIn this example the column `oCU135001RT90_MV` is selected and the average value is calculated using the method `.mean()`.\n\nTo write the result back to the Piscada Cloud, the `data` module offers the `write_value` function. It takes these arguments:\n\n- `tag`: A `Tag` object\n- `value`: The float, string, or dict value to write to the tag. Float and string will be sent as is, dict will be serialised as JSON string.\n- `timestamp` (optional): The timestamp in milliseconds since epoch at which to write the value, by default `int(time.time() * 1000)`.\n- `host`: Endpoint to send post request. Overrides the default, which is `os.environ['WRITEAPI_HOST']`.\n- `token`: Access token accosiated with the host. Overrides the default, which is `os.environ['WRITEAPI_TOKEN']`.\n\nThe `Tag.name` must use the prefix `py_` as this is the only namespace allowed for writing data via the API.\n\n```python\nfrom piscada_cloud.data import write_value\nfrom piscada_cloud.mappings import Tag\n\n\nmean = df[\"oCU135001RT90_MV\"].mean()\nresponse = write_value(Tag(controller_id=\"0798ac4a-4d4f-4648-95f0-12676b3411d5\", name=\"py_oCU135001RT90_MV_1h_mean\"), value=mean)\nif response.ok:\n print(\"OK\")\nelse:\n print(response.text)\n```\n\nThe `response` returned by the `write_value` method allows to check if the writing of data was successful `response.ok == True`.\n\n### Manipulations\n\nIn order to support analysis in the context of periodic patters, the `manipulations` allow you to add fractional representations of day, week, and year as additional columns in the DataFrame:\n\n- 00:00:00 -> 0.0 --- 23:59:59 -> 1.0\n- Monday 00:00:00 -> 0.0 --- Sunday 23:59:59 -> 1.0\n- 1st Jan. 00:00:00 -> 0.0 --- 31st Dec. 23:59:59 -> 1.0\n\n```python\nfrom piscada_cloud import manipulations\n\nmanipulations.add_weekdays(data)\nmanipulations.add_day_fraction(data)\nmanipulations.add_week_fraction(data)\nmanipulations.add_year_fraction(data)\n```\n\n## Development\n\n### Run QA as a pre-commit hook\n\nEnable the provided git pre commit hook: `ln -s ./qa.sh .git/hooks/pre-commit`\n\n### Documentation\n\nBuild and run MkDocs documentation:\n\n```bash\npoetry run mkdocs build\npoetry run mkdocs serve\n```\n\nNote: If you want to deploy a new version of your documentation, use below commands instead:\n```bash\npoetry run mike deploy [version]\npoetry run mike serve\n```\n\n## Run documentation via docker image\n\n```bash\ndocker pull piscada/piscada-cloud-documentation:tagname\ndocker run -p 8000:8000 piscada/piscada-cloud-documentation:tagname\n```\n\n## Requirements\n\nThe package will support the two latest version of Python.\n\n## Authors\n\n- Tim Jagenberg [tim.jagenberg@piscada.com](mailto:tim.jagenberg@piscada.com)\n- Filip Henrik Larsen [filip.larsen@piscada.com](mailto:filip.larsen@piscada.com)\n- Aleksandra Zajdel [aleksandra.zajdel@piscada.com](mailto:aleksandra.zajdel@piscada.com)\n\n## License\n\n\u00a9 Piscada AS 2019\n",
"bugtrack_url": null,
"license": "Other/Proprietary License",
"summary": "Library for the Piscada Cloud including authentication and data access.",
"version": "7.1.0",
"project_urls": {
"Homepage": "https://piscada.com/"
},
"split_keywords": [
"piscada",
" automation",
" building-automation",
" fish-farming",
" assisted-living"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "a80e0e7f5103887656e148a1626216322d77cfa50ff78ee6b4ce1b82845262d6",
"md5": "32e694906f8fc3a8268aebdf1557a976",
"sha256": "77606f14d5cd509bf4583edceb3cc83cc18872a9b741cb8a14aefebb405a0be3"
},
"downloads": -1,
"filename": "piscada_cloud-7.1.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "32e694906f8fc3a8268aebdf1557a976",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.10",
"size": 24630,
"upload_time": "2024-09-05T06:51:19",
"upload_time_iso_8601": "2024-09-05T06:51:19.540964Z",
"url": "https://files.pythonhosted.org/packages/a8/0e/0e7f5103887656e148a1626216322d77cfa50ff78ee6b4ce1b82845262d6/piscada_cloud-7.1.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "ff4bdfe2035c3f9dd6f1d4de0d43d25405b616e17c3560c651682615b8a95061",
"md5": "65fe70c13f248ca4cfc15e70411340fb",
"sha256": "d4464ac273830ceda6a0facc81c566f6e3b75e2de19287763098ceea5098c5a0"
},
"downloads": -1,
"filename": "piscada_cloud-7.1.0.tar.gz",
"has_sig": false,
"md5_digest": "65fe70c13f248ca4cfc15e70411340fb",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.10",
"size": 22465,
"upload_time": "2024-09-05T06:51:20",
"upload_time_iso_8601": "2024-09-05T06:51:20.896937Z",
"url": "https://files.pythonhosted.org/packages/ff/4b/dfe2035c3f9dd6f1d4de0d43d25405b616e17c3560c651682615b8a95061/piscada_cloud-7.1.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-05 06:51:20",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "piscada_cloud"
}