From a7a27888caca4a4fc4d52a0fdda3c1dc617b1576 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 28 Mar 2024 21:36:11 +0100 Subject: [PATCH 1/9] added test for eltako14bus lib --- docs/service-send-message/eep-params.md | 9 +++--- tests/test_send_message_service.py | 41 +++++++++++++++++++++---- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/docs/service-send-message/eep-params.md b/docs/service-send-message/eep-params.md index 85babf46..29fa9546 100644 --- a/docs/service-send-message/eep-params.md +++ b/docs/service-send-message/eep-params.md @@ -1,9 +1,11 @@ -# Paramters for EEPs in Send Message Events +# Paramters for EEPs in Send Message Events +(This file was auto-generated by using [eltako14bus library](https://github.com/grimmpp/eltako14bus/blob/master/eltakobus/eep.py) in [version 0.0.49](https://pypi.org/project/eltako14bus/).) + ## Not Supported EEPs * A5-09-0C * A5-38-08 -## Parameters for events: +## Parameters for events * A5-04-01: humidity, learn_button, temp_availability, temperature * A5-04-02: humidity, learn_button, temperature * A5-04-03: humidity, learn_button, telegram_type, temperature @@ -23,6 +25,3 @@ * G5-3F-7F: direction, state, time * H5-3F-7F: command, learn_button, time * M5-38-08: state - -## References: -Implementation of EEPs can be found [eltako14bus library](https://github.com/grimmpp/eltako14bus/blob/master/eltakobus/eep.py). diff --git a/tests/test_send_message_service.py b/tests/test_send_message_service.py index 122b8916..a7745aa5 100644 --- a/tests/test_send_message_service.py +++ b/tests/test_send_message_service.py @@ -3,6 +3,9 @@ from unittest import mock from homeassistant.helpers import dispatcher import inspect +import sys +import os +import json dispatcher.dispatcher_send = mock.Mock(return_value=None) @@ -45,9 +48,38 @@ async def test_send_message(self): await g.async_service_send_message(event, True) + def get_version_of_installed_eltako14bus(self): + dirname = [f for f in os.listdir(os.path.join(sys.exec_prefix, 'Lib', 'site-packages')) if f.startswith('eltako14bus')][0] + metadata_file = os.path.join(sys.exec_prefix, 'Lib', 'site-packages', dirname, 'METADATA') + with open(metadata_file, 'r') as f: + for l in f.readlines(): + if l.startswith('Version: '): + return l.replace('Version: ', '').strip() + return None + + def get_version_of_required_eltako14bus(self): + manifest_filename = os.path.join(os.getcwd(), 'custom_components', 'eltako', 'manifest.json') + with open(manifest_filename, 'r') as f: + manifest = json.loads( f.read() ) + + for r in manifest['requirements']: + if r.startswith('eltako14bus'): + return r.split('==')[1].strip() + return None + + async def test_eltako14bus_required_and_installed_is_the_same(self): + installed = self.get_version_of_installed_eltako14bus() + required = self.get_version_of_required_eltako14bus() + + self.assertIsNotNone(installed) + self.assertIsNotNone(required) + self.assertEqual(installed, required) async def test_write_eep_params_to_docs_file(self): - text = '# Paramters for EEPs in Send Message Events' + text = '# Paramters for EEPs in Send Message Events \n' + + text += f'(This file was auto-generated by using [eltako14bus library](https://github.com/grimmpp/eltako14bus/blob/master/eltakobus/eep.py) ' + text += f'in [version {self.get_version_of_installed_eltako14bus()}](https://pypi.org/project/eltako14bus/).)\n' text += '\n' text += "## Not Supported EEPs \n" @@ -55,7 +87,7 @@ async def test_write_eep_params_to_docs_file(self): text += f"* {eep_name}\n" text += '\n' - text += '## Parameters for events: \n' + text += '## Parameters for events \n' for eep_name in self.get_all_eep_names(): @@ -66,12 +98,9 @@ async def test_write_eep_params_to_docs_file(self): eep_init_args = sorted([param.name for param in sig.parameters.values() if param.kind == param.POSITIONAL_OR_KEYWORD and param.name != 'self']) text += f"* {eep_name}: {', '.join(eep_init_args)}\n" - text += '\n' - text += '## References:\n' - text += 'Implementation of EEPs can be found [eltako14bus library](https://github.com/grimmpp/eltako14bus/blob/master/eltakobus/eep.py).\n' - file='./docs/service-send-message/eep-params.md' with open(file, 'w') as filetowrite: filetowrite.write(text) + From 516b3204d11ca675d4a2574dfb35d52800127b5c Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 28 Mar 2024 21:56:16 +0100 Subject: [PATCH 2/9] added test to check lib versions for development and testing --- tests/test_metadata.py | 56 ++++++++++++++++++++++++++++++ tests/test_send_message_service.py | 31 +++-------------- 2 files changed, 60 insertions(+), 27 deletions(-) create mode 100644 tests/test_metadata.py diff --git a/tests/test_metadata.py b/tests/test_metadata.py new file mode 100644 index 00000000..23896706 --- /dev/null +++ b/tests/test_metadata.py @@ -0,0 +1,56 @@ +import os +import sys +import unittest +import json + +class MetadataTest(unittest.TestCase): + + def get_installed_lib_version(self, lib_name:str): + dirs = [f for f in os.listdir(os.path.join(sys.exec_prefix, 'Lib', 'site-packages')) if f.startswith(lib_name.replace('-', '_')+'-')] + if len(dirs) == 1: + metadata_file = os.path.join(sys.exec_prefix, 'Lib', 'site-packages', dirs[0], 'METADATA') + with open(metadata_file, 'r') as f: + for l in f.readlines(): + if l.startswith('Version: '): + return l.replace('Version: ', '').strip() + return None + return None + + def get_version_of_installed_eltako14bus(self): + return self.get_installed_lib_version('eltako14bus') + + def get_manifest(self): + manifest_filename = os.path.join(os.getcwd(), 'custom_components', 'eltako', 'manifest.json') + with open(manifest_filename, 'r') as f: + return json.loads( f.read() ) + + def get_version_of_required_eltako14bus(self): + manifest = self.get_manifest() + + for r in manifest['requirements']: + if r.startswith('eltako14bus'): + return r.split('==')[1].strip() + return None + + def test_check_all_installed_dependencies(self): + manifest = self.get_manifest() + + for r in manifest['requirements']: + if '==' in r: + lib_name = r.split('==')[0].strip() + required_version = r.split('==')[1].strip() + installed_version = self.get_installed_lib_version(lib_name) + + # if this test fails install specified libraries in manifest.json + self.assertEqual(required_version, installed_version) + + + return None + + def test_eltako14bus_required_and_installed_is_the_same(self): + installed = self.get_version_of_installed_eltako14bus() + required = self.get_version_of_required_eltako14bus() + + self.assertIsNotNone(installed) + self.assertIsNotNone(required) + self.assertEqual(installed, required) \ No newline at end of file diff --git a/tests/test_send_message_service.py b/tests/test_send_message_service.py index a7745aa5..35d5f06c 100644 --- a/tests/test_send_message_service.py +++ b/tests/test_send_message_service.py @@ -7,6 +7,8 @@ import os import json +from tests.test_metadata import MetadataTest + dispatcher.dispatcher_send = mock.Mock(return_value=None) class TestSendMessageService(unittest.IsolatedAsyncioTestCase): @@ -48,38 +50,13 @@ async def test_send_message(self): await g.async_service_send_message(event, True) - def get_version_of_installed_eltako14bus(self): - dirname = [f for f in os.listdir(os.path.join(sys.exec_prefix, 'Lib', 'site-packages')) if f.startswith('eltako14bus')][0] - metadata_file = os.path.join(sys.exec_prefix, 'Lib', 'site-packages', dirname, 'METADATA') - with open(metadata_file, 'r') as f: - for l in f.readlines(): - if l.startswith('Version: '): - return l.replace('Version: ', '').strip() - return None - - def get_version_of_required_eltako14bus(self): - manifest_filename = os.path.join(os.getcwd(), 'custom_components', 'eltako', 'manifest.json') - with open(manifest_filename, 'r') as f: - manifest = json.loads( f.read() ) - - for r in manifest['requirements']: - if r.startswith('eltako14bus'): - return r.split('==')[1].strip() - return None - - async def test_eltako14bus_required_and_installed_is_the_same(self): - installed = self.get_version_of_installed_eltako14bus() - required = self.get_version_of_required_eltako14bus() - - self.assertIsNotNone(installed) - self.assertIsNotNone(required) - self.assertEqual(installed, required) async def test_write_eep_params_to_docs_file(self): text = '# Paramters for EEPs in Send Message Events \n' + eltakobus_version = MetadataTest().get_version_of_installed_eltako14bus() text += f'(This file was auto-generated by using [eltako14bus library](https://github.com/grimmpp/eltako14bus/blob/master/eltakobus/eep.py) ' - text += f'in [version {self.get_version_of_installed_eltako14bus()}](https://pypi.org/project/eltako14bus/).)\n' + text += f'in [version {eltakobus_version}](https://pypi.org/project/eltako14bus/).)\n' text += '\n' text += "## Not Supported EEPs \n" From 33cd9794ffbf9f94b206c7918f7b9689286e10b8 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 28 Mar 2024 22:06:44 +0100 Subject: [PATCH 3/9] test improved --- docs/service-send-message/eep-params.md | 44 ++++++++++++------------- tests/test_send_message_service.py | 8 +++-- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/docs/service-send-message/eep-params.md b/docs/service-send-message/eep-params.md index 29fa9546..7b747b11 100644 --- a/docs/service-send-message/eep-params.md +++ b/docs/service-send-message/eep-params.md @@ -1,27 +1,27 @@ # Paramters for EEPs in Send Message Events -(This file was auto-generated by using [eltako14bus library](https://github.com/grimmpp/eltako14bus/blob/master/eltakobus/eep.py) in [version 0.0.49](https://pypi.org/project/eltako14bus/).) +(This file was auto-generated by using [eltako14bus library](https://github.com/grimmpp/eltako14bus/blob/master/eltakobus/eep.py) in [version 0.0.49](https://pypi.org/project/eltako14bus/) from unit-test `TestSendMessageService` in file `./tests/test_send_message_service.py`). ## Not Supported EEPs -* A5-09-0C -* A5-38-08 +* `A5-09-0C` +* `A5-38-08` ## Parameters for events -* A5-04-01: humidity, learn_button, temp_availability, temperature -* A5-04-02: humidity, learn_button, temperature -* A5-04-03: humidity, learn_button, telegram_type, temperature -* A5-06-01: day_light, illumination, twilight -* A5-07-01: learn_button, pir_status, pir_status_on, support_volrage_availability, support_voltage -* A5-08-01: illumination, learn_button, occupancy_button, pir_status, supply_voltage, temperature -* A5-10-06: current_temp, mode, stand_by, target_temp -* A5-10-12: current_temperature, humidity, target_temperature -* A5-12-01: data_type, divisor, learn_button, measurement_channel, meter_reading -* A5-12-02: data_type, divisor, learn_button, measurement_channel, meter_reading -* A5-12-03: data_type, divisor, learn_button, measurement_channel, meter_reading -* A5-13-01: dawn_sensor, day_night, hemisphere, identifier, learn_button, rain_indication, sun_east, sun_south, sun_west, temperature, wind_speed -* D5-00-01: contact, learn_button -* F6-02-01: energy_bow, rocker_first_action, rocker_second_action, second_action -* F6-02-02: energy_bow, rocker_first_action, rocker_second_action, second_action -* F6-10-00: handle_position, movement -* G5-3F-7F: direction, state, time -* H5-3F-7F: command, learn_button, time -* M5-38-08: state +* `A5-04-01`: humidity, learn_button, temp_availability, temperature +* `A5-04-02`: humidity, learn_button, temperature +* `A5-04-03`: humidity, learn_button, telegram_type, temperature +* `A5-06-01`: day_light, illumination, twilight +* `A5-07-01`: learn_button, pir_status, pir_status_on, support_volrage_availability, support_voltage +* `A5-08-01`: illumination, learn_button, occupancy_button, pir_status, supply_voltage, temperature +* `A5-10-06`: current_temp, mode, stand_by, target_temp +* `A5-10-12`: current_temperature, humidity, target_temperature +* `A5-12-01`: data_type, divisor, learn_button, measurement_channel, meter_reading +* `A5-12-02`: data_type, divisor, learn_button, measurement_channel, meter_reading +* `A5-12-03`: data_type, divisor, learn_button, measurement_channel, meter_reading +* `A5-13-01`: dawn_sensor, day_night, hemisphere, identifier, learn_button, rain_indication, sun_east, sun_south, sun_west, temperature, wind_speed +* `D5-00-01`: contact, learn_button +* `F6-02-01`: energy_bow, rocker_first_action, rocker_second_action, second_action +* `F6-02-02`: energy_bow, rocker_first_action, rocker_second_action, second_action +* `F6-10-00`: handle_position, movement +* `G5-3F-7F`: direction, state, time +* `H5-3F-7F`: command, learn_button, time +* `M5-38-08`: state diff --git a/tests/test_send_message_service.py b/tests/test_send_message_service.py index 35d5f06c..70d35d58 100644 --- a/tests/test_send_message_service.py +++ b/tests/test_send_message_service.py @@ -56,12 +56,14 @@ async def test_write_eep_params_to_docs_file(self): eltakobus_version = MetadataTest().get_version_of_installed_eltako14bus() text += f'(This file was auto-generated by using [eltako14bus library](https://github.com/grimmpp/eltako14bus/blob/master/eltakobus/eep.py) ' - text += f'in [version {eltakobus_version}](https://pypi.org/project/eltako14bus/).)\n' + text += f'in [version {eltakobus_version}](https://pypi.org/project/eltako14bus/) ' + rel_filename = '.'+__file__.replace(os.getcwd(), "").replace("\\", "/") + text += f'from unit-test `{type(self).__name__}` in file `{rel_filename}`). \n' text += '\n' text += "## Not Supported EEPs \n" for eep_name in self.NOT_SUPPORTED_EEPS: - text += f"* {eep_name}\n" + text += f"* `{eep_name}`\n" text += '\n' text += '## Parameters for events \n' @@ -73,7 +75,7 @@ async def test_write_eep_params_to_docs_file(self): sig = inspect.signature(EEP.find(eep_name).__init__) eep_init_args = sorted([param.name for param in sig.parameters.values() if param.kind == param.POSITIONAL_OR_KEYWORD and param.name != 'self']) - text += f"* {eep_name}: {', '.join(eep_init_args)}\n" + text += f"* `{eep_name}`: {', '.join(eep_init_args)}\n" file='./docs/service-send-message/eep-params.md' with open(file, 'w') as filetowrite: From c41bb4e32c51e1eaf1deb06f602aceeb6f783734 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 28 Mar 2024 22:19:28 +0100 Subject: [PATCH 4/9] tests improved --- tests/test_metadata.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 23896706..16dcb15e 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -32,6 +32,9 @@ def get_version_of_required_eltako14bus(self): return r.split('==')[1].strip() return None + def get_version_of_eltako_integration(self): + return self.get_manifest()['version'] + def test_check_all_installed_dependencies(self): manifest = self.get_manifest() @@ -53,4 +56,11 @@ def test_eltako14bus_required_and_installed_is_the_same(self): self.assertIsNotNone(installed) self.assertIsNotNone(required) - self.assertEqual(installed, required) \ No newline at end of file + self.assertEqual(installed, required) + + def test_if_changes_are_documented(self): + changes_filename = os.path.join(os.getcwd(), 'changes.md') + with open(changes_filename, 'r', encoding="utf-8") as f: + changes_text = f.read() + + self.assertTrue( f'## Version {self.get_version_of_eltako_integration()}' in changes_text ) \ No newline at end of file From 0d78d47f7986d9e23a44cd490432b195d517e414 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 28 Mar 2024 22:26:42 +0100 Subject: [PATCH 5/9] try to fix get site-paclages folder for ubutnu --- tests/test_metadata.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 16dcb15e..515350c0 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -2,11 +2,17 @@ import sys import unittest import json +import site class MetadataTest(unittest.TestCase): + def get_site_package_folder(self): + for f in site.getsitepackages(): + if 'site-packages' in f: + return f + def get_installed_lib_version(self, lib_name:str): - dirs = [f for f in os.listdir(os.path.join(sys.exec_prefix, 'Lib', 'site-packages')) if f.startswith(lib_name.replace('-', '_')+'-')] + dirs = [f for f in os.listdir(self.get_site_package_folder()) if f.startswith(lib_name.replace('-', '_')+'-')] if len(dirs) == 1: metadata_file = os.path.join(sys.exec_prefix, 'Lib', 'site-packages', dirs[0], 'METADATA') with open(metadata_file, 'r') as f: From 8b749c35969e840e7b7cbd14918daa6867650cf7 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 28 Mar 2024 22:37:16 +0100 Subject: [PATCH 6/9] try to fix get site-paclages folder for ubutnu --- tests/test_metadata.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 515350c0..1e97c864 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -10,11 +10,20 @@ def get_site_package_folder(self): for f in site.getsitepackages(): if 'site-packages' in f: return f - - def get_installed_lib_version(self, lib_name:str): + + def find_lib_folder(self, lib_name:str): dirs = [f for f in os.listdir(self.get_site_package_folder()) if f.startswith(lib_name.replace('-', '_')+'-')] if len(dirs) == 1: - metadata_file = os.path.join(sys.exec_prefix, 'Lib', 'site-packages', dirs[0], 'METADATA') + for f in os.listdir(self.get_site_package_folder()): + print(f"file in dir: {f}") + return dirs[0] + return None + + def get_installed_lib_version(self, lib_name:str): + + dir_name = self.find_lib_folder(lib_name) + if dir_name: + metadata_file = os.path.join(sys.exec_prefix, 'Lib', 'site-packages', dir_name, 'METADATA') with open(metadata_file, 'r') as f: for l in f.readlines(): if l.startswith('Version: '): From 5c3057490962bed950599a3752201b7265e85a44 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 28 Mar 2024 22:39:35 +0100 Subject: [PATCH 7/9] try to fix get site-paclages folder for ubutnu --- tests/test_metadata.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 1e97c864..5ed3e5f6 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -14,7 +14,7 @@ def get_site_package_folder(self): def find_lib_folder(self, lib_name:str): dirs = [f for f in os.listdir(self.get_site_package_folder()) if f.startswith(lib_name.replace('-', '_')+'-')] if len(dirs) == 1: - for f in os.listdir(self.get_site_package_folder()): + for f in os.listdir(os.join(self.get_site_package_folder(),dirs[0])): print(f"file in dir: {f}") return dirs[0] return None From 2ed9b9de582843ce3681d17ae23b939d169d9892 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 28 Mar 2024 22:42:39 +0100 Subject: [PATCH 8/9] try to fix get site-paclages folder for ubutnu --- tests/test_metadata.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 5ed3e5f6..5ffa73ec 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -14,16 +14,16 @@ def get_site_package_folder(self): def find_lib_folder(self, lib_name:str): dirs = [f for f in os.listdir(self.get_site_package_folder()) if f.startswith(lib_name.replace('-', '_')+'-')] if len(dirs) == 1: - for f in os.listdir(os.join(self.get_site_package_folder(),dirs[0])): + for f in os.listdir(os.path.join(self.get_site_package_folder(),dirs[0])): print(f"file in dir: {f}") - return dirs[0] + return os.path.join(self.get_site_package_folder(), dirs[0]) return None def get_installed_lib_version(self, lib_name:str): dir_name = self.find_lib_folder(lib_name) if dir_name: - metadata_file = os.path.join(sys.exec_prefix, 'Lib', 'site-packages', dir_name, 'METADATA') + metadata_file = os.path.join(dir_name, 'METADATA') with open(metadata_file, 'r') as f: for l in f.readlines(): if l.startswith('Version: '): From 2829d4ba98c7be3a327139d9ea7edc6699442111 Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Thu, 28 Mar 2024 22:44:03 +0100 Subject: [PATCH 9/9] try to fix get site-packages folder for ubutnu --- tests/test_metadata.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_metadata.py b/tests/test_metadata.py index 5ffa73ec..c05d959c 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -14,8 +14,6 @@ def get_site_package_folder(self): def find_lib_folder(self, lib_name:str): dirs = [f for f in os.listdir(self.get_site_package_folder()) if f.startswith(lib_name.replace('-', '_')+'-')] if len(dirs) == 1: - for f in os.listdir(os.path.join(self.get_site_package_folder(),dirs[0])): - print(f"file in dir: {f}") return os.path.join(self.get_site_package_folder(), dirs[0]) return None