Skip to content

Commit

Permalink
Remove pandas dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
masaccio committed Jun 8, 2023
1 parent 0fc1a84 commit 03ffb92
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 126 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,20 @@ async with AsyncSensorClient() as client:

## Tanks object

`history` returns a Pandas dataframe with all entries available from the web API, sorted by logging time. There should be one record per day. The dataframe has the following entries:
As of version 3.0, `history` no longer returns a Pandas dataframe to simplify packge dependencies. Instead, an list of dicts is returned, where each list element is a sample from the web API, sorted by logging time. There should be one record per day. Each dict has the following keys:

* `reading_date`: a datetime object indicating the time a measurement was made
* `level_percent`: integer percentage full
* `level_litres`: number of lites in the tank

You can construct a Pandas dataframe simply using:

``` python
tanks = await client.tanks
history = await tanks[0].history
df = pd.DataFrame(history)
```

## Scripts

Reporting on the current status of the tank using `kingspan-status`:
Expand All @@ -75,7 +83,7 @@ History:
02-Feb-2021 00:59 76 986
```

`kingspan-notifier` can be used to check the status of a tabk and report via email when the tank is likely to run out of oil.
`kingspan-notifier` can be used to check the status of a tabk and report via email when the tank is likely to run out of oil. As of version 3.0, [pandas](https://pypi.org/project/pandas/) is no longer installed as a dependency so you must `pip install pandas` manually to use `kingspan-notifier`.

``` bash
% kingspan-notifier --config kingspan.ini
Expand Down
241 changes: 144 additions & 97 deletions poetry.lock

Large diffs are not rendered by default.

6 changes: 2 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,13 @@ name = "kingspan-connect-sensor"
packages = [{include = "connectsensor", from = "src"}]
readme = "README.md"
repository = "https://github.com/masaccio/kingspan-connect-sensor"
version = "2.1.1"
version = "3.0.0"

[tool.poetry.dependencies]
async-property = "^0.2.1"
asyncio = "^3.4.3"
datetime = "^4.7"
# homeassistant has a constraint on httpx==0.24
httpx = "^0.24"
# homeassistant has a constraint on pandas==1.4.3
pandas = "^1.4.3"
python = "^3.9"
requests = "^2.28.1"
zeep = "^4.2.0"
Expand All @@ -33,6 +30,7 @@ zeep = "^4.2.0"
aiofiles = "^22.1.0"
black = {version = "^22.10.0", allow-prereleases = true}
openpyxl = "^3.0.10"
pandas = "^1.4.3"
pytest = "^7.1.0"
pytest-asyncio = "^0.20.2"
pytest-console-scripts = "^1.3.1"
Expand Down
4 changes: 2 additions & 2 deletions src/connectsensor/_kingspan_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ def cached_history(tank, cache_db, update):
if table_exists(cursor):
query = "SELECT * FROM history;"
old_history = pd.read_sql_query(query, db, parse_dates=["reading_date"])
new_history = tank.history
new_history = pd.DataFrame(tank.history)
history = pd.concat([old_history, new_history]).drop_duplicates()
else:
history = tank.history
history = pd.DataFrame(tank.history)

if update:
history.to_sql("history", db, if_exists="replace", index=False)
Expand Down
2 changes: 1 addition & 1 deletion src/connectsensor/_kingspan_notifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def read_tank_history(config):
sys.exit(1)

tanks = client.tanks
return tanks[0].history
return pd.DataFrame(tanks[0].history)


def update_tank_cache(config, history, update=False):
Expand Down
8 changes: 4 additions & 4 deletions src/connectsensor/_kingspan_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ def main():

print("\nHistory:")
print("\t{0:<22} {1:<6} {2:<5}".format("Reading date", "%Full", "Litres"))
for index, measurement in tank.history.iterrows():
for index, measurement in enumerate(tank.history):
print(
"\t{0:<22} {1:<6} {2:<5}".format(
measurement.reading_date.strftime("%d-%b-%Y %H:%M"),
measurement.level_percent,
measurement.level_litres,
measurement["reading_date"].strftime("%d-%b-%Y %H:%M"),
measurement["level_percent"],
measurement["level_litres"],
)
)

Expand Down
19 changes: 12 additions & 7 deletions src/connectsensor/tank.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def last_read(self) -> str:
@property
def history(self):
history_data = self._soap_client._get_history(self._signalman_no)
return history_to_df(history_data)
return transform_history_data(history_data)

def _cache_tank_data(self):
if self._level_data is None:
Expand Down Expand Up @@ -94,7 +94,7 @@ async def last_read(self) -> str:
@async_property
async def history(self):
history_data = await self._soap_client._get_history(self._signalman_no)
return history_to_df(history_data)
return transform_history_data(history_data)

async def _cache_tank_data(self):
if self._level_data is None:
Expand All @@ -108,8 +108,13 @@ def unpack_tank_data(cls, response):
cls._tank_info = {x["Name"]: x["Value"] for x in tank_info["APITankInfoItem"]}


def history_to_df(history_data):
df = pd.DataFrame(serialize_object(history_data))
df = df[["ReadingDate", "LevelPercentage", "LevelLitres"]]
df.columns = ["reading_date", "level_percent", "level_litres"]
return df
def transform_history_data(data):
data = [
{
"reading_date": x["ReadingDate"],
"level_percent": x["LevelPercentage"],
"level_litres": x["LevelLitres"],
}
for x in data
]
return data
14 changes: 8 additions & 6 deletions tests/test_async.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import pytest

from datetime import datetime
from unittest.mock import patch
from zeep.transports import AsyncTransport

from mock_data import VALID_STATUS, USERNAME, PASSWORD
from mock_requests import MockResponse, mock_load_remote_data, async_mock_post_xml
import pandas as pd
import pytest

from mock_data import PASSWORD, USERNAME, VALID_STATUS
from mock_requests import MockResponse, async_mock_post_xml, mock_load_remote_data
from zeep.transports import AsyncTransport

from connectsensor import __version__, AsyncSensorClient
from connectsensor import AsyncSensorClient, __version__


@pytest.mark.asyncio
Expand All @@ -32,6 +33,7 @@ async def test_status():
assert await tanks[0].capacity == 2000

tank_history = await tanks[0].history
tank_history = pd.DataFrame(tank_history)
assert tank_history.reading_date[0] == datetime(2021, 1, 25, 13, 59, 14)
assert tank_history.level_percent[1] == 95
assert tank_history.level_litres[2] == 1880
6 changes: 3 additions & 3 deletions tests/test_sync.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import pytest

from datetime import datetime
from unittest.mock import patch
from zeep.transports import Transport
Expand All @@ -9,6 +7,8 @@

from connectsensor import __version__, SensorClient

import pandas as pd


def test_status():
with patch.object(
Expand All @@ -29,7 +29,7 @@ def test_status():
assert tanks[0].model == "TestModel"
assert tanks[0].name == "TestTank"
assert tanks[0].capacity == 2000
tank_history = tanks[0].history
tank_history = pd.DataFrame(tanks[0].history)
assert tank_history.reading_date[0] == datetime(2021, 1, 25, 13, 59, 14)
assert tank_history.level_percent[1] == 95
assert tank_history.level_litres[2] == 1880

0 comments on commit 03ffb92

Please sign in to comment.