From 124657029b58abbc74597661f123b0b67dbc8a4e Mon Sep 17 00:00:00 2001 From: Philipp Grimm Date: Sun, 18 Feb 2024 23:55:01 +0100 Subject: [PATCH] F2SR14 Support --- changes.md | 4 +++ eo_man/controller/app_bus.py | 1 + eo_man/data/app_info.py | 35 +++++++++++++++++- eo_man/data/data_helper.py | 1 + eo_man/data/device.py | 39 ++++++++++++--------- eo_man/data/ha_config_generator.py | 17 ++++----- eo_man/icons/Software-update-available.png | Bin 0 -> 4644 bytes eo_man/icons/image_gallary.py | 9 ++++- eo_man/view/menu_presenter.py | 21 +++++++++++ eo_man/view/tool_bar.py | 27 +++++++++++++- setup.py | 5 ++- 11 files changed, 128 insertions(+), 31 deletions(-) create mode 100644 eo_man/icons/Software-update-available.png diff --git a/changes.md b/changes.md index 8d8ee78..0b2d475 100644 --- a/changes.md +++ b/changes.md @@ -1,5 +1,9 @@ # Change Log +## v0.1.7 F2SR14 Support +* Support for F4SR14 added +* Update Button added + ## v0.1.6 Sensor Values are evaluated * Sensor values are displayed in command line * Sponsor button added diff --git a/eo_man/controller/app_bus.py b/eo_man/controller/app_bus.py index f2767ae..f2e51a1 100644 --- a/eo_man/controller/app_bus.py +++ b/eo_man/controller/app_bus.py @@ -17,6 +17,7 @@ class AppBusEventType(Enum): SET_DATA_TABLE_FILTER = 13 # applies data filter to data table ADDED_DATA_TABLE_FILTER = 14 # adds data filter to application data REMOVED_DATA_TABLE_FILTER = 15 # remove data filter from application data + RELOAD = 16 class AppBus(): diff --git a/eo_man/data/app_info.py b/eo_man/data/app_info.py index 21ff79f..2b145ab 100644 --- a/eo_man/data/app_info.py +++ b/eo_man/data/app_info.py @@ -1,8 +1,11 @@ import os +import requests class ApplicationInfo(): app_info:dict[str:str]=None + pypi_info_latest_versino:dict=None + pypi_info_current_version:dict=None @classmethod def get_app_info(cls, filename:str=None): @@ -39,9 +42,31 @@ def get_app_info(cls, filename:str=None): app_info['license'] = l.split(':',1)[1].strip() elif l.startswith('Requires-Python:'): app_info['requires-python'] = l.split(':',1)[1].strip() + + # get latest version + cls.pypi_info_latest_versino = cls._get_info_from_pypi() + app_info['lastest_available_version'] = cls.pypi_info_latest_versino.get('info', {}).get('version', None) + # get current/installed version + if app_info['version'] is not None and app_info['version'] != '': + cls.pypi_info_current_version = cls._get_info_from_pypi(app_info['version']) return app_info + @classmethod + def _get_info_from_pypi(cls, version:str=''): + if version is not None and version != '': + if not version.startswith('/') and not version.endswith('/'): + version = version + '/' + + url = f"https://pypi.org/pypi/eo-man/{version}json" + + response = requests.get(url) + if response.status_code == 200: + return response.json() + + return {} + + @classmethod def get_app_info_as_str(cls, separator:str='\n', prefix:str='') -> str: result = '' @@ -75,4 +100,12 @@ def get_license(cls) -> str: @classmethod def get_requires_python(cls) -> str: - return cls.get_app_info().get('requires-python', 'unknown') \ No newline at end of file + return cls.get_app_info().get('requires-python', 'unknown') + + @classmethod + def get_lastest_available_version(cls) -> str: + return cls.get_app_info().get('lastest_available_version', 'unknown') + + @classmethod + def is_version_up_to_date(cls) -> bool: + return cls.pypi_info_current_version['info']['version'] == cls.pypi_info_latest_versino['info']['version'] \ No newline at end of file diff --git a/eo_man/data/data_helper.py b/eo_man/data/data_helper.py index 3eef6d9..40c5018 100644 --- a/eo_man/data/data_helper.py +++ b/eo_man/data/data_helper.py @@ -34,6 +34,7 @@ {'hw-type': 'FSR14_1x', CONF_EEP: 'M5-38-08', 'sender_eep': 'A5-38-08', CONF_TYPE: Platform.LIGHT, 'PCT14-function-group': 2, 'PCT14-key-function': 51, 'description': 'Eltako relay', 'address_count': 1}, {'hw-type': 'FSR14_x2', CONF_EEP: 'M5-38-08', 'sender_eep': 'A5-38-08', CONF_TYPE: Platform.LIGHT, 'PCT14-function-group': 2, 'PCT14-key-function': 51, 'description': 'Eltako relay', 'address_count': 2}, {'hw-type': 'FSR14_4x', CONF_EEP: 'M5-38-08', 'sender_eep': 'A5-38-08', CONF_TYPE: Platform.LIGHT, 'PCT14-function-group': 2, 'PCT14-key-function': 51, 'description': 'Eltako relay', 'address_count': 4}, + {'hw-type': 'F4SR14_LED', CONF_EEP: 'M5-38-08', 'sender_eep': 'A5-38-08', CONF_TYPE: Platform.LIGHT, 'PCT14-function-group': 2, 'PCT14-key-function': 51, 'description': 'Eltako relay', 'address_count': 4}, {'hw-type': 'FSB14', CONF_EEP: 'G5-3F-7F', 'sender_eep': 'H5-3F-7F', CONF_TYPE: Platform.COVER, 'PCT14-function-group': 2, 'PCT14-key-function': 31, 'description': 'Eltako cover', 'address_count': 2}, diff --git a/eo_man/data/device.py b/eo_man/data/device.py index 53f6b97..ddc5de8 100644 --- a/eo_man/data/device.py +++ b/eo_man/data/device.py @@ -117,35 +117,40 @@ async def async_get_bus_device_by_natvice_bus_object(cls, device: BusObject, fam if bd.dev_size > 1: bd.name += f" ({bd.channel}/{bd.dev_size})" - info:dict = find_device_info_by_device_type(bd.device_type) + Device.set_suggest_ha_config(bd) + + return bd + + @classmethod + def set_suggest_ha_config(cls, device): + id = int.from_bytes( AddressExpression.parse(device.address)[0], 'big') + info:dict = find_device_info_by_device_type(device.device_type) if info is not None: - bd.use_in_ha = True - bd.ha_platform = info[CONF_TYPE] - bd.eep = info.get(CONF_EEP, None) + device.use_in_ha = True + device.ha_platform = info[CONF_TYPE] + device.eep = info.get(CONF_EEP, None) if info.get('sender_eep', None): - bd.additional_fields['sender'] = { + device.additional_fields['sender'] = { CONF_ID: a2s( SENDER_BASE_ID + id ), CONF_EEP: info.get('sender_eep') } if info[CONF_TYPE] == Platform.COVER: - bd.additional_fields[CONF_DEVICE_CLASS] = 'shutter' - bd.additional_fields[CONF_TIME_CLOSES] = 25 - bd.additional_fields[CONF_TIME_OPENS] = 25 + device.additional_fields[CONF_DEVICE_CLASS] = 'shutter' + device.additional_fields[CONF_TIME_CLOSES] = 25 + device.additional_fields[CONF_TIME_OPENS] = 25 if info[CONF_TYPE] == Platform.CLIMATE: - bd.additional_fields[CONF_TEMPERATURE_UNIT] = f"'{UnitOfTemperature.KELVIN}'" - bd.additional_fields[CONF_MIN_TARGET_TEMPERATURE] = 16 - bd.additional_fields[CONF_MAX_TARGET_TEMPERATURE] = 25 - thermostat = BusObjectHelper.find_sensor(bd.memory_entries, device.address, channel, in_func_group=1) + device.additional_fields[CONF_TEMPERATURE_UNIT] = f"'{UnitOfTemperature.KELVIN}'" + device.additional_fields[CONF_MIN_TARGET_TEMPERATURE] = 16 + device.additional_fields[CONF_MAX_TARGET_TEMPERATURE] = 25 + thermostat = BusObjectHelper.find_sensor(device.memory_entries, device.address, device.channel, in_func_group=1) if thermostat: - bd.additional_fields[CONF_ROOM_THERMOSTAT] = {} - bd.additional_fields[CONF_ROOM_THERMOSTAT][CONF_ID] = b2s(thermostat.sensor_id) - bd.additional_fields[CONF_ROOM_THERMOSTAT][CONF_EEP] = A5_10_06.eep_string #TODO: derive EEP from switch/sensor function + device.additional_fields[CONF_ROOM_THERMOSTAT] = {} + device.additional_fields[CONF_ROOM_THERMOSTAT][CONF_ID] = b2s(thermostat.sensor_id) + device.additional_fields[CONF_ROOM_THERMOSTAT][CONF_EEP] = A5_10_06.eep_string #TODO: derive EEP from switch/sensor function #TODO: cooling_mode - - return bd @classmethod def get_decentralized_device_by_telegram(cls, msg: RPSMessage): diff --git a/eo_man/data/ha_config_generator.py b/eo_man/data/ha_config_generator.py index 934f3a4..738777e 100644 --- a/eo_man/data/ha_config_generator.py +++ b/eo_man/data/ha_config_generator.py @@ -60,14 +60,15 @@ def generate_ha_config(self, device_list:list[Device]) -> str: out += f" {CONF_DEVICES}:\n" for platform in ha_platforms: - out += f" {platform}:\n" - for _d in [d for d in devices if d.ha_platform == platform]: - device:Device = _d - # devices - if device.base_id == fam14.external_id: - out += self.config_section_from_device_to_string(device, True, 0) + "\n\n" - elif 'sensor' in platform: - out += self.config_section_from_device_to_string(device, True, 0) + "\n\n" + if platform != '': + out += f" {platform}:\n" + for _d in [d for d in devices if d.ha_platform == platform]: + device:Device = _d + # devices + if device.base_id == fam14.external_id: + out += self.config_section_from_device_to_string(device, True, 0) + "\n\n" + elif 'sensor' in platform: + out += self.config_section_from_device_to_string(device, True, 0) + "\n\n" # logs out += "logger:\n" out += " default: info\n" diff --git a/eo_man/icons/Software-update-available.png b/eo_man/icons/Software-update-available.png new file mode 100644 index 0000000000000000000000000000000000000000..d9e147f8a028f31760bccf9828a5418bacccc501 GIT binary patch literal 4644 zcmV+<65H*GP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00006 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 aH!CnOIxsMHWrb+~0000 ImageTk.PhotoImage: @classmethod def get_github_icon(cls, size:tuple[int:int]=(32,32)) -> ImageTk.PhotoImage: - return ImageGallery.get_image("github_icon.png", size) \ No newline at end of file + return ImageGallery.get_image("github_icon.png", size) + + @classmethod + def get_software_update_available_icon(cls, size:tuple[int:int]=(32,32)) -> ImageTk.PhotoImage: + return ImageGallery.get_image("Software-update-available.png", size) \ No newline at end of file diff --git a/eo_man/view/menu_presenter.py b/eo_man/view/menu_presenter.py index a5c3895..b4774f4 100644 --- a/eo_man/view/menu_presenter.py +++ b/eo_man/view/menu_presenter.py @@ -3,10 +3,12 @@ from tkinter import * from tkinter import filedialog import logging +from tkinter import messagebox import webbrowser from ..controller.app_bus import AppBus, AppBusEventType +from ..data.device import Device from ..data.data_manager import DataManager from ..data.ha_config_generator import HomeAssistantConfigurationGenerator @@ -72,6 +74,12 @@ def __init__(self, main: Tk, app_bus: AppBus, data_manager: DataManager): accelerator="ALT+F") + ha_menu = Menu(menu_bar, tearoff=False) + menu_bar.add_cascade(label="Home Assistant", menu=ha_menu) + ha_menu.add_command(label="Reset to suggested HA properties.", + command=self.reset_to_suggested_ha_properties) + + help_menu = Menu(menu_bar, tearoff=False) menu_bar.add_cascade(label="Help", menu=help_menu) @@ -224,8 +232,21 @@ def export_ha_config(self, save_as:bool=False): self.app_bus.fire_event(AppBusEventType.LOG_MESSAGE, {'msg': msg, 'log-level': 'ERROR', 'color': 'red'}) logging.exception(msg, exc_info=True) + + def reset_to_suggested_ha_properties(self): + yes = messagebox.askyesno("Reset to suggested HA properties.", "Do you want to reset Home Assistant relevant properties of all devices to initial values?") + if yes: + for d in self.data_manager.devices.values(): + Device.set_suggest_ha_config(d) + if d.is_bus_device(): + self.app_bus.fire_event(AppBusEventType.UPDATE_DEVICE_REPRESENTATION, d) + else: + self.app_bus.fire_event(AppBusEventType.UPDATE_SENSOR_REPRESENTATION, d) + def open_eo_man_repo(self): webbrowser.open_new(r"https://github.com/grimmpp/enocean-device-manager") def open_eo_man_documentation(self): webbrowser.open_new(r"https://github.com/grimmpp/enocean-device-manager/tree/main/docs") + + \ No newline at end of file diff --git a/eo_man/view/tool_bar.py b/eo_man/view/tool_bar.py index d906209..555d5b3 100644 --- a/eo_man/view/tool_bar.py +++ b/eo_man/view/tool_bar.py @@ -1,13 +1,19 @@ +import threading import tkinter as tk import os from tkinter import * +from tkinter import messagebox from PIL import Image, ImageTk from idlelib.tooltip import Hovertip import webbrowser +import subprocess + +from eo_man import LOGGER from .donation_button import DonationButton from .menu_presenter import MenuPresenter from ..icons.image_gallary import ImageGallery +from ..data.app_info import ApplicationInfo as AppInfo class ToolBar(): @@ -32,10 +38,29 @@ def __init__(self, main: Tk, menu_presenter:MenuPresenter, row:int): b = self._create_img_button(f, "GitHub: EnOcean Device Manager Documentation", ImageGallery.get_help_icon(), menu_presenter.open_eo_man_documentation) b.pack(side=RIGHT, padx=(0,2), pady=2) + if not AppInfo.is_version_up_to_date(): + new_v = AppInfo.get_lastest_available_version() + b = self._create_img_button(f, f"New Software Version 'v{new_v}' is available.", ImageGallery.get_software_update_available_icon(), self.show_how_to_update) + b.pack(side=RIGHT, padx=(0,2), pady=2) + + def _create_img_button(self, f:Frame, tooltip:str, image:ImageTk.PhotoImage, command) -> Button: b = Button(f, image=image, relief=GROOVE, cursor="hand2", command=command) Hovertip(b,tooltip,300) b.image = image b.pack(side=LEFT, padx=(2,0), pady=2) return b - \ No newline at end of file + + def show_how_to_update(self): + base_path = os.environ.get('VIRTUAL_ENV', '') + if base_path != '': + base_path = os.path.join(base_path, 'Scripts') + + new_version = AppInfo.get_lastest_available_version() + + msg = f"A new version 'v{new_version}' of 'EnOcean Device Manager' is available. \n\n" + msg += f"You can update this application by entering \n" + msg += f"'{os.path.join(base_path, 'pip')}' install eo_man --upgrade'\n" + msg += f"into the command line." + + messagebox.showinfo("Update Available", msg) \ No newline at end of file diff --git a/setup.py b/setup.py index 4e32822..01b29a4 100644 --- a/setup.py +++ b/setup.py @@ -1,8 +1,7 @@ import os from setuptools import setup, find_packages from distutils.core import setup -import shutil -import re + base_dir = os.path.dirname(__file__) @@ -24,7 +23,7 @@ setup( name='eo_man', - version='0.1.6', + version='0.1.7', package_dir={'eo_man':"eo_man"}, # packages=find_packages("./eo-man"), #package_data={'': ['*.png']},