Skip to content

Commit

Permalink
23.11.0 (#427)
Browse files Browse the repository at this point in the history
- fix #425
- fix #424
  • Loading branch information
spacemanspiff2007 authored Nov 23, 2023
1 parent e4b8973 commit a91eb84
Show file tree
Hide file tree
Showing 58 changed files with 423 additions and 222 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/run-tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on: [push, pull_request]

jobs:
pre-commit:
name:
name: pre-commit
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand Down
7 changes: 0 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,6 @@ repos:
# - pep8-naming==0.13.3


- repo: https://github.com/asottile/pyupgrade
rev: v3.10.1
hooks:
- id: pyupgrade
args: ["--py38-plus"]


- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
Expand Down
69 changes: 69 additions & 0 deletions .ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@

line-length = 120
indent-width = 4

target-version = "py38"
src = ["src", "test"]

# https://docs.astral.sh/ruff/settings/#ignore-init-module-imports
ignore-init-module-imports = true

extend-exclude = ["__init__.py"]

select = [
"E", "W", # https://docs.astral.sh/ruff/rules/#pycodestyle-e-w
"I", # https://docs.astral.sh/ruff/rules/#isort-i
"UP", # https://docs.astral.sh/ruff/rules/#pyupgrade-up

"A", # https://docs.astral.sh/ruff/rules/#flake8-builtins-a
"ASYNC", # https://docs.astral.sh/ruff/rules/#flake8-async-async
"C4", # https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4
"EM", # https://docs.astral.sh/ruff/rules/#flake8-errmsg-em
"FIX", # https://docs.astral.sh/ruff/rules/#flake8-fixme-fix
"INP", # https://docs.astral.sh/ruff/rules/#flake8-no-pep420-inp
"ISC", # https://docs.astral.sh/ruff/rules/#flake8-implicit-str-concat-isc
"PIE", # https://docs.astral.sh/ruff/rules/#flake8-pie-pie
"PT", # https://docs.astral.sh/ruff/rules/#flake8-pytest-style-pt
"PTH", # https://docs.astral.sh/ruff/rules/#flake8-use-pathlib-pth
"RET", # https://docs.astral.sh/ruff/rules/#flake8-return-ret
"SIM", # https://docs.astral.sh/ruff/rules/#flake8-simplify-sim
"SLOT", # https://docs.astral.sh/ruff/rules/#flake8-slots-slot
"T10", # https://docs.astral.sh/ruff/rules/#flake8-debugger-t10
"TCH", # https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch
"TD", # https://docs.astral.sh/ruff/rules/#flake8-todos-td

"TRY", # https://docs.astral.sh/ruff/rules/#tryceratops-try
"FLY", # https://docs.astral.sh/ruff/rules/#flynt-fly
"PERF", # https://docs.astral.sh/ruff/rules/#perflint-perf
"RUF", # https://docs.astral.sh/ruff/rules/#ruff-specific-rules-ruf

# "PL", # https://docs.astral.sh/ruff/rules/#pylint-pl
# "FURB", # https://docs.astral.sh/ruff/rules/#refurb-furb
]

ignore = [
"RET501", # https://docs.astral.sh/ruff/rules/unnecessary-return-none/#unnecessary-return-none-ret501
"TRY400", # https://docs.astral.sh/ruff/rules/error-instead-of-exception/

"A003", # https://docs.astral.sh/ruff/rules/builtin-attribute-shadowing/
]


[format]
# Use single quotes for non-triple-quoted strings.
quote-style = "single"



[lint.flake8-builtins]
builtins-ignorelist = ["id", "input"]


[lint.per-file-ignores]
"docs/conf.py" = ["INP001", "A001"]
"setup.py" = ["PTH123"]


[lint.isort]
# https://docs.astral.sh/ruff/settings/#isort-lines-after-imports
lines-after-imports = 2
17 changes: 8 additions & 9 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
import os
import re
import sys
from pathlib import Path

import sphinx
from docutils.nodes import Text, Node
from docutils.nodes import Node, Text
from sphinx.addnodes import desc_signature

IS_RTD_BUILD = os.environ.get('READTHEDOCS', '-').lower() == 'true'
IS_CI = os.environ.get('CI', '-') == 'true'


# https://www.sphinx-doc.org/en/master/extdev/logging.html
sphinx_logger = sphinx.util.logging.getLogger('post')
logger_lvl = logging.DEBUG if IS_RTD_BUILD or IS_CI else logging.INFO # set level to DEBUG for CI
Expand All @@ -35,7 +35,11 @@ def log(msg: str):
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
sys.path.insert(0, os.path.join(os.path.abspath('..'), 'src'))
src_folder = Path(__file__).parent.with_name('src')
assert src_folder.is_dir()

# required for autodoc
sys.path.insert(0, str(src_folder))

# -- Project information -----------------------------------------------------

Expand All @@ -49,6 +53,7 @@ def log(msg: str):
release = 'beta'
try:
from HABApp import __version__

version = __version__
print(f'Building docs for {version}')
except Exception as e:
Expand Down Expand Up @@ -229,15 +234,13 @@ def log(msg: str):
(re.compile(r'py:class'), re.compile(r'(?:datetime|pendulum|aiohttp|pathlib)\..+'))
]


# -- Extension configuration -------------------------------------------------
exec_code_working_dir = '../src'
exec_code_source_folders = ['../src', '../tests']

autodoc_member_order = 'bysource'
autoclass_content = 'class'


# No config on member
autodoc_pydantic_model_show_config_member = False
autodoc_pydantic_model_show_config_summary = False
Expand All @@ -255,9 +258,6 @@ def log(msg: str):
autodoc_pydantic_field_list_validators = False
autodoc_pydantic_field_swap_name_and_alias = True




# ----------------------------------------------------------------------------------------------------------------------
# Post processing of default value

Expand Down Expand Up @@ -339,7 +339,6 @@ def setup(app):
'python': ('https://docs.python.org/3', None)
}


# Don't show warnings for missing python references since these are created via intersphinx during the RTD build
if not IS_RTD_BUILD:
nitpick_ignore_regex.append(
Expand Down
2 changes: 1 addition & 1 deletion docs/interface_habapp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ And since it is just like a normal item triggering on changes etc. is possible,
my_agg.aggregation_period(2 * 3600)

# Use max as an aggregation function
my_agg.aggregation_func = max
my_agg.aggregation_func(max)


The value of ``my_agg`` in the example will now always be the maximum of ``MyInputItem`` in the last two hours.
Expand Down
5 changes: 5 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ MyOpenhabRule()
```

# Changelog
#### 23.11.1 (2023-11-23)
- Fix for very small float values (#425)
- Fix for writing to persistence (#424)
- Updated dependencies

#### 23.09.2 (2023-09-24)
- Made channel type on a ``Thing`` optional (#416)
- Fixed an issue with mqtt publish and reconnect
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
# -----------------------------------------------------------------------------
# Packages for source formatting
# -----------------------------------------------------------------------------
pre-commit >= 3.3, < 3.4
pre-commit >= 3.5, < 3.6
ruff >= 0.1.6, < 0.2

# -----------------------------------------------------------------------------
# Packages for other developement tasks
Expand Down
16 changes: 8 additions & 8 deletions requirements_setup.txt
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
aiohttp == 3.8.5
pydantic == 2.3.0
msgspec == 0.18.2
aiohttp == 3.9.0
pydantic == 2.5.2
msgspec == 0.18.4
pendulum == 2.1.2
bidict == 0.22.1
watchdog == 3.0.0
ujson == 5.8.0
aiomqtt == 1.2.0
aiomqtt == 1.2.1

immutables == 0.20
eascheduler == 0.1.11
easyconfig == 0.3.0
stack_data == 0.6.2
easyconfig == 0.3.1
stack_data == 0.6.3
colorama == 0.4.6

voluptuous == 0.13.1
voluptuous == 0.14.1

typing-extensions == 4.7.1
typing-extensions == 4.8.0

aiohttp-sse-client == 0.2.1

Expand Down
4 changes: 2 additions & 2 deletions requirements_tests.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
# -----------------------------------------------------------------------------
# Packages to run source tests
# -----------------------------------------------------------------------------
packaging == 23.1
pytest == 7.4.2
packaging == 23.2
pytest == 7.4.3
pytest-asyncio == 0.21.1
15 changes: 14 additions & 1 deletion run/conf_testing/rules/openhab/test_items.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from HABApp.core.events import ValueUpdateEventFilter
from HABApp.core.types import HSB, RGB
from HABApp.openhab.interface_async import async_get_items
from HABApp.openhab.items import GroupItem, StringItem, ColorItem
from HABApp.openhab.items import GroupItem, StringItem, ColorItem, NumberItem
from HABAppTests import OpenhabTmpItem, TestBaseRule, ItemWaiter, EventWaiter


Expand All @@ -21,6 +21,7 @@ def __init__(self):
self.add_test('TestExisting', self.test_existing)
self.add_test('TestColor', self.test_color)
self.add_test('TestGroupFunction', self.test_group_func)
self.add_test('TestSmallValues', self.test_small_float_values)

self.item_number = OpenhabTmpItem('Number')
self.item_switch = OpenhabTmpItem('Switch')
Expand Down Expand Up @@ -66,6 +67,18 @@ def test_api(self):
self.openhab.get_item(self.item_group.name)
asyncio.run_coroutine_threadsafe(async_get_items(), loop).result()

@OpenhabTmpItem.create('Number', arg_name='tmp_item')
def test_small_float_values(self, tmp_item: OpenhabTmpItem):
# https://github.com/spacemanspiff2007/HABApp/issues/425
item = NumberItem.get_item(tmp_item.name)
assert item.value is None

for i in range(3, 16, 3):
with ItemWaiter(item) as waiter:
value = 1 / 10 ** i
item.oh_post_update(value)
waiter.wait_for_state(value)

@OpenhabTmpItem.use('String', arg_name='oh_item')
def test_tags(self, oh_item: OpenhabTmpItem):
oh_item.create_item(tags=['tag1', 'tag2'])
Expand Down
75 changes: 47 additions & 28 deletions run/conf_testing/rules/openhab/test_persistence.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,66 @@
from __future__ import annotations

from datetime import datetime, timedelta
from typing import Final, Any

from HABApp.openhab.definitions.helpers import OpenhabPersistenceData
from HABApp.openhab.items import NumberItem
from HABAppTests import TestBaseRule


class TestPersistence(TestBaseRule):

def __init__(self):
class TestPersistenceBase(TestBaseRule):
def __init__(self, service_name: str, item_name: str):
super().__init__()
self.item = 'RRD4J_Item'

self.add_test('RRD4J configured', self.test_configured)
self.add_test('RRD4J get', self.test_get)
self.config.skip_on_failure = True
self.item_name: Final = item_name
self.service_name: Final = service_name

self.add_test(f'Persistence {service_name} available', self.test_service_available)

def set_up(self):
i = NumberItem.get_item(self.item)
i.oh_post_update(i.value + 1 if i.value < 10 else 0)
i = NumberItem.get_item(self.item_name)
i.oh_post_update(int(i.value) + 1 if i.value < 10 else 0)

def test_configured(self):
def test_service_available(self):
for cfg in self.oh.get_persistence_services():
if cfg.id == 'rrd4j':
if cfg.id == self.service_name:
break
else:
raise ValueError('rrd4j not found!')
raise ValueError(f'Persistence service "{self.service_name}" not found!')

def set_persistence_data(self, time: datetime, state: Any):
return self.openhab.set_persistence_data(self.item_name, self.service_name, time, state)

def get_persistence_data(self, start_time: datetime | None, end_time: datetime | None) -> OpenhabPersistenceData:
return self.openhab.get_persistence_data(self.item_name, self.service_name, start_time, end_time)


class TestRRD4j(TestPersistenceBase):

def __init__(self):
super().__init__('rrd4j', 'RRD4J_Item')
self.add_test('RRD4J get', self.test_get)

def test_get(self):
now = datetime.now()
d = self.openhab.get_persistence_data(self.item, 'rrd4j', now - timedelta(seconds=60), now)
d = self.get_persistence_data(now - timedelta(seconds=60), now)
assert d.get_data()

# def test_set(self):
# now = datetime.now()
# d = self.openhab.get_persistence_data(self.item, 'mapdb', now - timedelta(seconds=5), now)
# was = d.get_data()
#
# assert list(was.values()) == [1]
#
# self.openhab.set_persistence_data(self.item, 'mapdb', now, 2)
#
# d = self.openhab.get_persistence_data(self.item, 'mapdb', now - timedelta(seconds=5),
# now + timedelta(seconds=5))
# ist = d.get_data()
# assert list(ist.values()) == [2], ist


TestPersistence()

TestRRD4j()


class TestMapDB(TestPersistenceBase):

def __init__(self):
super().__init__('mapdb', 'RRD4J_Item')
self.add_test('MapDB get', self.test_get)

def test_get(self):
now = datetime.now()
d = self.get_persistence_data(now - timedelta(seconds=60), now)
assert d.get_data()


TestMapDB()
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ def load_req() -> typing.List[str]:
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3 :: Only",
"Topic :: Home Automation"
],
Expand Down
Loading

0 comments on commit a91eb84

Please sign in to comment.