From fb8978206c233bf8642d04daf02cab5212f886fc Mon Sep 17 00:00:00 2001 From: lunDreame <87955512+lunDreame@users.noreply.github.com> Date: Sun, 1 Sep 2024 13:40:29 +0900 Subject: [PATCH] fix elevator --- custom_components/bestin/center.py | 77 ++++++++++--------- custom_components/bestin/config_flow.py | 3 +- custom_components/bestin/controller.py | 25 +++--- custom_components/bestin/translations/en.json | 1 + custom_components/bestin/translations/ko.json | 1 + 5 files changed, 57 insertions(+), 50 deletions(-) diff --git a/custom_components/bestin/center.py b/custom_components/bestin/center.py index f15f742..5a29fb4 100644 --- a/custom_components/bestin/center.py +++ b/custom_components/bestin/center.py @@ -44,19 +44,13 @@ class CenterAPIv2: def __init__(self, hass, entry) -> None: """API initialization.""" self.elevator_arrived = False + self.elevator_number = entry.data.get("elevator_number", 1) self.features_list: list = [] self.elevator_data: dict = {} - async def process_elevator_request(self) -> None: - if not os.path.exists('data.json'): - await self.elevator_call_request() - else: - async with aiofiles.open('data.json', 'r') as file: - elevator_data = await file.read() - await self.handle_message_info(elevator_data, cache=True) - async def _v2_device_status(self, args=None): + """Updates the v2 device status asynchronously.""" if args is not None: LOGGER.debug(f"Task execution started with argument: {args}") self.last_update_time = args @@ -140,38 +134,34 @@ async def fetch_elevator_status(self) -> None: except Exception as ex: LOGGER.error(f"Fetch elevator status error occurred: {ex}") - async def handle_message_info(self, message, cache=False): + async def handle_message_info(self, message) -> None: """Handle message info for elevator status monitoring.""" data = json.loads(message) - - if not os.path.exists('data.json'): - async with aiofiles.open('data.json', 'w') as file: - await file.write(json.dumps(data["move_info"], indent=4)) - + if "move_info" in data: - self.elevator_data.update(data["move_info"]) - - serial = str(self.elevator_data["Serial"]) - floor = self.elevator_data.get("Floor", "대기") - move_dir = self.elevator_data.get("MoveDir", "대기") + serial = data["move_info"]["Serial"] + move_info = data["move_info"] - self.setup_device("elevator", 1, serial, False) - self.setup_device("elevator", 1, f"floor_{serial}", f"{floor} 층") - self.setup_device("elevator", 1, f"direction_{serial}", move_dir) - else: - if cache: - elevator_data = data.copy() - elevator_data.update({"Floor": "대기", "MoveDir": "대기"}) - self.elevator_data = elevator_data - - serial = str(self.elevator_data["Serial"]) - floor = self.elevator_data.get("Floor", "도착") + self.elevator_data = {serial: move_info} + self.elevator_data = dict(sorted(self.elevator_data.items())) + LOGGER.debug("Elevator data: %s", self.elevator_data) - self.setup_device("elevator", 1, f"floor_{serial}", f"{floor} 층") - self.setup_device("elevator", 1, f"direction_{serial}", "도착") + if len(self.elevator_data) >= 2: + for idx, (serial, info) in enumerate(self.elevator_data.items(), start=1): + floor = f"{info["move_info"]["Floor"]} 층" + move_dir = info["move_info"]["MoveDir"] + + self.setup_device("elevator", 1, f"floor_{str(idx)}", floor) + self.setup_device("elevator", 1, f"direction_{str(idx)}", move_dir) + else: + self.setup_device("elevator", 1, f"floor_1", move_info["Floor"]) + self.setup_device("elevator", 1, f"direction_1", move_info["MoveDir"]) + else: + for idx in range(1, self.elevator_number+1): + self.setup_device("elevator", 1, f"floor_{str(idx)}", "도착 층") + self.setup_device("elevator", 1, f"direction_{str(idx)}", "도착") - if not cache: - self.elevator_arrived = True + self.elevator_arrived = True async def request_feature_command(self, device_type: str, room_id: int, unit: str, value: str) -> None: """Request feature command.""" @@ -233,6 +223,10 @@ async def process_features(self, features: list) -> None: for feature in features: if feature["name"] in ["sensor", "mode"]: continue + if feature["name"] == "elevator": + for i in range(1, self.elevator_number+1): + self._elevator_registration(str(i)) + continue if feature["quantity"] == 0: LOGGER.debug(f"Skipping feature '{feature['name']}' with quantity 0") continue @@ -264,6 +258,11 @@ async def fetch_feature_list(self) -> None: if response.status == 200 and result_status == "ok": LOGGER.debug(f"Fetched feature list: {response_data}") + response_data["features"].append({ + "name": "elevator", + "quantity": self.elevator_number + }) + LOGGER.debug(f"Adding new feature 'elevator': {response_data}") self.features_list.extend(response_data["features"]) await self.process_features(response_data["features"]) else: @@ -321,10 +320,6 @@ async def start(self) -> None: self.stop_event.clear() self.tasks.append(asyncio.create_task(self.schedule_session_refresh())) await asyncio.sleep(1) - - if self.elevator_registration: - LOGGER.debug("Processing elevator request") - await self.process_elevator_request() v_key = getattr(self, f"_v{self.version[7:8]}_device_status") scan_interval = self.entry.options.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL) @@ -544,6 +539,12 @@ async def _v1_fetch_status( except Exception as ex: LOGGER.error(f"Error getting status for {device_type}: {ex}") + def _elevator_registration(self, id: str) -> None: + """Register an elevator with the given ID.""" + self.setup_device("elevator", 1, id, False) + self.setup_device("elevator", 1, f"floor_{id}", "대기 층") + self.setup_device("elevator", 1, f"direction_{id}", "대기") + def _parse_common_status( self, device_type: str, device_number: int, unit_num: str, unit_status: str ) -> None: diff --git a/custom_components/bestin/config_flow.py b/custom_components/bestin/config_flow.py index c9fd47b..d73f08a 100644 --- a/custom_components/bestin/config_flow.py +++ b/custom_components/bestin/config_flow.py @@ -189,7 +189,7 @@ async def async_step_center_v1( session = async_create_clientsession(self.hass) response, error_message = await self._v1_server_login(session) - + if error_message: errors["base"] = error_message[0] description_placeholders = {"err": error_message[1]} @@ -236,6 +236,7 @@ async def async_step_center_v2( return self.async_create_entry(title=user_input[self.config_identifier], data=self.data) data_schema = vol.Schema({ + vol.Required("elevator_number", default=1): ConfigFlow.int_between(1, 3), vol.Optional(CONF_IP_ADDRESS): cv.string, vol.Required(CONF_UUID): cv.string, }) diff --git a/custom_components/bestin/controller.py b/custom_components/bestin/controller.py index 35bcd8a..933c632 100644 --- a/custom_components/bestin/controller.py +++ b/custom_components/bestin/controller.py @@ -261,6 +261,8 @@ async def enqueue_command(self, device_id: str, value: Any, **kwargs: Optional[d room_id = int(parts[2]) pos_id = 0 sub_type = None + timestamp = self.timestamp1 if device_type in ["gas", "fan", "doorlock"] \ + else self.timestamp2 if kwargs: sub_type, value = next(iter(kwargs.items())) @@ -274,7 +276,7 @@ async def enqueue_command(self, device_id: str, value: Any, **kwargs: Optional[d queue_task = { "transmission": 1, - "timestamp": self.timestamp, + "timestamp": timestamp, "device_type": device_type, "room_id": room_id, "pos_id": pos_id, @@ -559,21 +561,20 @@ def handle_device_packet(self, packet: bytes) -> None: header = packet[1] packet_len = len(packet) room_id = device_state = device_id = None - self.timestamp = 0x00 - + if packet_len == 10: command = packet[2] - #self.timestamp = packet[3] + self.timestamp1 = packet[3] else: command = packet[3] - #self.timestamp = packet[4] - - if packet_len != 10 and command in [0x81, 0x82, 0x91, 0x92, 0xB2]: + self.timestamp2 = packet[4] + + if packet_len != 10 and command in [0x81, 0x82, 0x91, 0x92, 0xB2]: # response if header == 0x28: room_id, device_state = self.parse_thermostat(packet) device_id = f"thermostat_{room_id}" self.setup_device(device_id, device_state) - elif ((header == 0x31 and packet_len == 30) + elif ((self.gateway_type == "General" and packet_len == 30) or (self.gateway_type == "AIO" and packet_len in [20, 22]) or (self.gateway_type == "Gen2" and packet_len in [59, 72, 98]) ): @@ -586,8 +587,7 @@ def handle_device_packet(self, packet: bytes) -> None: for room_id, state in device_state.items(): device_id = f"energy_{room_id}" self.setup_device(device_id, state, is_sub=True) - - elif packet_len == 10 and command != 0x00: + elif packet_len == 10 and command != 0x00: # response parser_mapping = { 0x31: (self.parse_gas, "gas"), 0x41: (self.parse_doorlock, "doorlock"), @@ -598,7 +598,10 @@ def handle_device_packet(self, packet: bytes) -> None: room_id, device_state = parse_func(packet) device_id = f"{device_type}_{room_id}" self.setup_device(device_id, device_state) - + elif command not in [0x00, 0x11, 0x21, 0xA1]: # query + pass + #LOGGER.warning(f"Unknown device packet: {packet.hex()}") + async def handle_packet_queue(self, queue: dict) -> None: """Processes the queued command packet data.""" try: diff --git a/custom_components/bestin/translations/en.json b/custom_components/bestin/translations/en.json index c1961ed..76adb10 100644 --- a/custom_components/bestin/translations/en.json +++ b/custom_components/bestin/translations/en.json @@ -33,6 +33,7 @@ }, "center_v2": { "data": { + "elevator_number": "Elevator number", "ip_address": "IP address", "uuid": "UUID" }, diff --git a/custom_components/bestin/translations/ko.json b/custom_components/bestin/translations/ko.json index 343bf39..5820e7f 100644 --- a/custom_components/bestin/translations/ko.json +++ b/custom_components/bestin/translations/ko.json @@ -33,6 +33,7 @@ }, "center_v2": { "data": { + "elevator_number": "엘리베이터 수", "ip_address": "IP 주소", "uuid": "UUID" },