Skip to content

Commit 4fa186f

Browse files
authored
Merge pull request #15 from Angelius007/tolwi-main
Tolwi main
2 parents 36b28f0 + 0a2ecd7 commit 4fa186f

File tree

13 files changed

+301
-179
lines changed

13 files changed

+301
-179
lines changed

custom_components/ecoflow_cloud/__init__.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
163163
CONF_DEVICE_TYPE: deviceConf.device_type
164164
})
165165

166-
api_client.configure_device(deviceConf.sn, deviceConf.name, deviceConf.device_type)
167-
api_client.devices[sn].configure(int(entry.options[OPTS_REFRESH_PERIOD_SEC]), bool(entry.options[OPTS_DIAGNOSTIC_MODE]))
166+
device = api_client.configure_device(deviceConf.sn, deviceConf.name, deviceConf.device_type)
167+
device.configure(int(entry.options[OPTS_REFRESH_PERIOD_SEC]), bool(entry.options[OPTS_DIAGNOSTIC_MODE]))
168168

169+
api_client.start()
169170
hass.data[DOMAIN][entry.entry_id] = api_client
170171

171172
hass.config_entries.async_update_entry(entry, data=new_data, options=entry.options)

custom_components/ecoflow_cloud/api/__init__.py

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,10 @@ class EcoflowMqttInfo:
2323

2424
class EcoflowApiClient:
2525

26-
def __init__(self):
27-
self.mqtt_info: EcoflowMqttInfo | None = None
28-
self.devices: dict[str, Any] = {}
29-
self.mqtt_client = None
30-
self.installation_site = None
26+
mqtt_info: EcoflowMqttInfo
27+
devices: dict[str, Any] = {}
28+
mqtt_client = None
29+
installation_site: str
3130

3231
@abstractmethod
3332
async def login(self):
@@ -45,21 +44,11 @@ async def quota_all(self, device_sn: str):
4544
def configure_device(self, device_sn: str, device_name: str, device_type: str):
4645
pass
4746

48-
def addOrUpdateDevice(self, device ):
49-
trouve=False
50-
for (k, v) in self.devices.items():
51-
if k == device.device_info.sn:
52-
self.devices[k] = device
53-
trouve=True
54-
break
55-
if not trouve:
56-
self.devices[device.device_info.sn] = device
57-
58-
def removeDevice(self, device ):
59-
for (k, v) in self.devices.items():
60-
if k == device.device_info.sn:
61-
self.devices.pop(k)
62-
break
47+
def add_device(self, device):
48+
self.devices[device.device_info.sn] = device
49+
50+
def remove_device(self, device):
51+
self.devices.pop(device.device_info.sn, None)
6352

6453
def _accept_mqqt_certification(self, resp_json: dict):
6554
_LOGGER.info(f"Received MQTT credentials: {resp_json}")
@@ -91,5 +80,9 @@ async def _get_json_response(self, resp: ClientResponse):
9180

9281
return json_resp
9382

83+
def start(self):
84+
from custom_components.ecoflow_cloud.api.ecoflow_mqtt import EcoflowMQTTClient
85+
self.mqtt_client = EcoflowMQTTClient(self.mqtt_info, self.devices)
86+
9487
def stop(self):
9588
self.mqtt_client.stop()

custom_components/ecoflow_cloud/api/ecoflow_mqtt.py

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ class EcoflowMQTTClient:
1818
def __init__(self, mqtt_info: EcoflowMqttInfo, devices: dict[str, BaseDevice]):
1919

2020
from ..devices import BaseDevice
21-
# Status pour ne pas boucler
2221
self.__autorise = True
2322
self.__mqtt_info = mqtt_info
2423
self.__error_count = 0
@@ -30,7 +29,7 @@ def __init__(self, mqtt_info: EcoflowMqttInfo, devices: dict[str, BaseDevice]):
3029
self.__client.on_connect = self.on_connect
3130
self.__client.on_disconnect = self.on_disconnect
3231
self.__client.on_message = self.on_message
33-
self.__client.on_socket_close = self.on_socket_close
32+
# self.__client.on_socket_close = self.on_socket_close
3433

3534
_LOGGER.info(f"Connecting to MQTT Broker {self.__mqtt_info.url}:{self.__mqtt_info.port} with client id {self.__mqtt_info.client_id} and username {self.__mqtt_info.username}")
3635
self.__client.connect(self.__mqtt_info.url, self.__mqtt_info.port, 30)
@@ -65,15 +64,8 @@ def on_connect(self, client, userdata, flags, rc):
6564
topics = []
6665
for (sn, device) in self.__devices.items():
6766
_LOGGER.debug(f"Add Topics for {sn}")
68-
69-
if device.device_info.data_topic:
70-
topics.append((device.device_info.data_topic, 1))
71-
if device.device_info.set_topic:
72-
topics.append((device.device_info.set_topic, 1))
73-
if device.device_info.set_reply_topic:
74-
topics.append((device.device_info.set_reply_topic, 1))
75-
if device.device_info.status_topic:
76-
topics.append((device.device_info.status_topic, 1))
67+
for topic in device.device_info.topics():
68+
topics.append((topic, 1))
7769

7870
self.__client.subscribe(topics)
7971
_LOGGER.info(f"Subscribed to MQTT topics {topics}")
@@ -101,9 +93,9 @@ def on_connect(self, client, userdata, flags, rc):
10193
self.stop()
10294

10395
return client
104-
105-
def on_socket_close(self, client, userdata, socket):
106-
_LOGGER.error(f"Unexpected MQTT Socket disconnection : {str(socket)}")
96+
#
97+
# def on_socket_close(self, client, userdata, socket):
98+
# _LOGGER.error(f"Unexpected MQTT Socket disconnection : {str(socket)}")
10799

108100
def on_disconnect(self, client, userdata, rc):
109101
if rc != 0:
@@ -115,21 +107,9 @@ def on_disconnect(self, client, userdata, rc):
115107

116108
def on_message(self, client, userdata, message):
117109
try:
118-
message_sn = None
119110
for (sn, device) in self.__devices.items():
120-
TOPICS = [device.device_info.data_topic, device.device_info.set_topic, device.device_info.set_reply_topic,
121-
device.device_info.get_topic, device.device_info.get_reply_topic, device.device_info.status_topic]
122-
match message.topic:
123-
case item if item in TOPICS:
124-
message_sn=sn
125-
break
126-
case _:
127-
pass
128-
if message_sn:
129-
_LOGGER.debug(f"Message for {message_sn} and Topic {message.payload}")
130-
self.__devices[message_sn].update_data(message.payload, message.topic)
131-
else:
132-
_LOGGER.warn(f"No device for Topic {message.topic}")
111+
if device.update_data(message.payload, message.topic):
112+
_LOGGER.debug(f"Message for {sn} and Topic {message.topic}")
133113
except UnicodeDecodeError as error:
134114
_LOGGER.error(f"UnicodeDecodeError: {error}. Ignoring message and waiting for the next one.")
135115

custom_components/ecoflow_cloud/api/private_api.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import base64
22
import logging
3-
import uuid
43

54
import aiohttp
5+
from homeassistant.util import uuid
66

77
from . import EcoflowException, EcoflowApiClient
8-
from .ecoflow_mqtt import EcoflowMQTTClient
98
from ..devices import EcoflowDeviceInfo, DiagnosticDevice
109

1110
_LOGGER = logging.getLogger(__name__)
@@ -52,9 +51,11 @@ async def login(self):
5251
response = await self.__call_api("/iot-auth/app/certification")
5352
self._accept_mqqt_certification(response)
5453

55-
async def fetch_all_available_devices():
56-
result = list()
57-
return result
54+
# Should be ANDROID_..str.._user_id
55+
self.mqtt_info.client_id = f'ANDROID_-{str(uuid.random_uuid_hex()).upper()}_{self.user_id}'
56+
57+
async def fetch_all_available_devices(self):
58+
return []
5859

5960
async def quota_all(self, device_sn: str):
6061
self.mqtt_client.send_get_message(device_sn, {"version": "1.1", "moduleType": 0, "operateType": "latestQuotas", "params": {}})
@@ -64,16 +65,13 @@ def configure_device(self, device_sn: str, device_name: str, device_type: str):
6465

6566
from ..devices.registry import devices
6667
if device_type in devices:
67-
self.device = devices[device_type](info)
68-
else:
69-
self.device = DiagnosticDevice(info)
70-
self.addOrUpdateDevice(self.device)
71-
72-
if self.mqtt_client:
73-
self.mqtt_client.reconnect()
68+
device = devices[device_type](info)
7469
else:
75-
self.mqtt_info.client_id = f'HomeAssistant-{self.installation_site}'
76-
self.mqtt_client = EcoflowMQTTClient(self.mqtt_info, self.devices)
70+
device = DiagnosticDevice(info)
71+
72+
self.add_device(device)
73+
74+
return device
7775

7876
def __create_device_info(self, device_sn: str, device_name: str, device_type: str) -> EcoflowDeviceInfo:
7977
return EcoflowDeviceInfo(

custom_components/ecoflow_cloud/api/public_api.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ async def login(self):
3535
_LOGGER.info(f"Requesting IoT MQTT credentials")
3636
response = await self.call_api("/certification")
3737
self._accept_mqqt_certification(response)
38+
self.mqtt_info.client_id = f'HomeAssistant-{self.installation_site}'
3839

3940
async def fetch_all_available_devices(self) -> list[EcoflowDeviceInfo]:
4041
_LOGGER.info(f"Requesting all devices")
@@ -50,16 +51,12 @@ def configure_device(self, device_sn: str, device_name: str, device_type: str):
5051

5152
from custom_components.ecoflow_cloud.devices.registry import device_by_product
5253
if device_type in device_by_product:
53-
self.device = device_by_product[device_type](info)
54+
device = device_by_product[device_type](info)
5455
else:
55-
self.device = DiagnosticDevice(info)
56+
device = DiagnosticDevice(info)
5657

57-
self.addOrUpdateDevice(self.device)
58-
if self.mqtt_client:
59-
self.mqtt_client.reconnect()
60-
else:
61-
self.mqtt_info.client_id = f'HomeAssistant-{self.installation_site}'
62-
self.mqtt_client = EcoflowMQTTClient(self.mqtt_info, self.devices)
58+
self.add_device(device)
59+
return device
6360

6461
async def quota_all(self, device_sn: str):
6562
raw = await self.call_api("/device/quota/all", {"sn": device_sn})

custom_components/ecoflow_cloud/devices/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class EcoflowDeviceInfo:
2020
sn: str
2121
name: str
2222
device_type: str
23+
client_id: str
2324
data_topic: str
2425
set_topic: str
2526
set_reply_topic: str
@@ -28,6 +29,17 @@ class EcoflowDeviceInfo:
2829
status_topic: str | None = None
2930
client_id: str | None = None
3031

32+
def topics(self) -> list[str]:
33+
topics = [
34+
self.data_topic,
35+
self.get_topic,
36+
self.get_reply_topic,
37+
self.set_topic,
38+
self.set_reply_topic,
39+
self.status_topic
40+
]
41+
return list(filter(lambda v: v is not None, topics))
42+
3143

3244
class BaseDevice(ABC):
3345

custom_components/ecoflow_cloud/devices/internal/delta2.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ def numbers(self, client: EcoflowApiClient) -> list[BaseNumberEntity]:
106106
lambda value: {"moduleType": 2, "operateType": "dsgCfg",
107107
"params": {"minDsgSoc": int(value)}}),
108108

109-
BatteryBackupLevel(client, "pd.bpPowerSoc", const.BACKUP_RESERVE_LEVEL, 5, 100,
109+
BatteryBackupLevel(client, self, "pd.bpPowerSoc", const.BACKUP_RESERVE_LEVEL, 5, 100,
110110
"bms_emsStatus.minDsgSoc", "bms_emsStatus.maxChargeSoc",
111111
lambda value: {"moduleType": 1, "operateType": "watthConfig",
112112
"params": {"isConfig": 1, "bpPowerSoc": int(value), "minDsgSoc": 0,

0 commit comments

Comments
 (0)