azerty9971 / xtend_tuya

eXtend Tuya's integration
GNU General Public License v3.0
34 stars 4 forks source link

More entities added for connected litterboxes #38

Closed d4nm0 closed 1 day ago

d4nm0 commented 2 weeks ago

Hello, thx for this integration. I have a litter box connected to tuya and I don't have many entities coming up via integration. Is it possible to upload more entities?

current entity: image

image of the tuya application : image

azerty9971 commented 2 weeks ago

Bonjour, est ce que vous pourriez m'envoyer les données de statistiques ? (le bouton "Télécharger le diagnostic de xtended tuya" sur votre premier screenshot)

Merci d'avance :) Azerty

d4nm0 commented 2 weeks ago

Re bonjour, je ne savais pas que vous étiez Français.

{ "home_assistant": { "installation_type": "Home Assistant OS", "version": "2024.7.0b10", "dev": false, "hassio": true, "virtualenv": false, "python_version": "3.12.4", "docker": true, "arch": "aarch64", "timezone": "Europe/Paris", "os_name": "Linux", "os_version": "6.6.31-haos-raspi", "supervisor": "2024.06.2", "host_os": "Home Assistant OS 12.4", "docker_version": "26.1.4", "chassis": "embedded", "run_as_root": true }, "custom_components": { "meross_lan": { "documentation": "https://github.com/krahabb/meross_lan", "version": "5.2.2", "requirements": [] }, "Water_meter_suez": { "documentation": "https://github.com/d4nm0/Water-Meter-Suez", "version": "3.0.0", "requirements": [] }, "smartlife": { "documentation": "https://www.home-assistant.io/integrations/smartlife", "version": "0.1.0", "requirements": [ "tuya-device-sharing-sdk==0.2.0" ] }, "xtend_tuya": { "documentation": "https://github.com/azerty9971/xtend_tuya", "version": "1.2.6", "requirements": [ "tuya-device-sharing-sdk==0.1.9" ] }, "hacs": { "documentation": "https://hacs.xyz/docs/configuration/start", "version": "1.34.0", "requirements": [ "aiogithubapi>=22.10.1" ] }, "eufy_security": { "documentation": "https://github.com/fuatakgun/eufy_security", "version": "8.0.2", "requirements": [ "websocket-client==1.4.2", "aiortsp==1.3.7" ] }, "proxmoxve": { "documentation": "https://github.com/dougiteixeira/proxmoxve", "version": "3.4.4", "requirements": [ "proxmoxer==2.0.1" ] }, "delete": { "documentation": "https://github.com/chomupashchuk/delete-file-home-assistant", "version": "1.9", "requirements": [] }, "meross_cloud": { "documentation": "https://www.home-assistant.io/components/meross_cloud", "version": "1.3.2", "requirements": [ "meross_iot==0.4.7.2b3" ] } }, "integration_manifest": { "domain": "xtend_tuya", "name": "Xtended Tuya", "codeowners": [ "azerty9971" ], "config_flow": true, "dependencies": [ "ffmpeg", "tuya" ], "dhcp": [ { "macaddress": "105A17*" }, { "macaddress": "10D561*" }, { "macaddress": "1869D8*" }, { "macaddress": "381F8D*" }, { "macaddress": "508A06*" }, { "macaddress": "68572D*" }, { "macaddress": "708976*" }, { "macaddress": "7CF666*" }, { "macaddress": "84E342*" }, { "macaddress": "D4A651*" }, { "macaddress": "D81F12*" } ], "documentation": "https://github.com/azerty9971/xtend_tuya", "integration_type": "hub", "iot_class": "cloud_push", "issue_tracker": "https://github.com/azerty9971/xtend_tuya/issues", "loggers": [ "tuya_iot" ], "requirements": [ "tuya-device-sharing-sdk==0.1.9" ], "version": "1.2.6", "is_built_in": false }, "setup_times": { "null": { "setup": 6.746297003701329e-05 }, "b9f8fabb6a0086e7a4022e1e4a04f23e": { "wait_import_platforms": -0.23152963299071416, "config_entry_setup": 1.1486447770148516 } }, "data": { "endpoint": "https://apigw.tuyaeu.com", "terminal_id": "1717016004490TPIQv9", "mqtt_connected": true, "disabled_by": null, "disabled_polling": false, "devices": [ { "id": "bf5145dffa9ee94391vcpi", "name": "Smart Plug", "category": "cz", "product_id": "uekfgut3btdby31l", "product_name": "Smart Plug", "online": true, "sub": false, "time_zone": "+02:00", "active_time": "2024-06-16T17:56:47+00:00", "create_time": "2024-06-16T17:56:47+00:00", "update_time": "2024-06-16T17:56:47+00:00", "function": { "switch_1": { "type": "Boolean", "value": {} }, "countdown_1": { "type": "Integer", "value": { "unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1 } }, "relay_status": { "type": "Enum", "value": { "range": [ "power_off", "power_on", "last" ] } } }, "status_range": { "switch_1": { "type": "Boolean", "value": {} }, "countdown_1": { "type": "Integer", "value": { "unit": "s", "min": 0, "max": 86400, "scale": 0, "step": 1 } }, "relay_status": { "type": "Enum", "value": { "range": [ "power_off", "power_on", "last" ] } } }, "status": { "switch_1": false, "countdown_1": 0, "relay_status": "last" }, "home_assistant": { "name": "Smart Plug", "name_by_user": "Prise Terrarium", "disabled": false, "disabled_by": null, "entities": [ { "disabled": false, "disabled_by": null, "entity_category": "config", "device_class": null, "original_device_class": null, "icon": null, "original_icon": null, "unit_of_measurement": null, "state": { "entity_id": "select.smart_plug_comportement_a_la_mise_sous_tension", "state": "last", "attributes": { "options": [ "power_off", "power_on", "last" ], "friendly_name": "Prise Terrarium Comportement \u00e0 la mise sous tension" }, "last_changed": "2024-07-03T11:49:59.858367+00:00", "last_reported": "2024-07-03T11:49:59.858367+00:00", "last_updated": "2024-07-03T11:49:59.858367+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": null, "device_class": null, "original_device_class": "outlet", "icon": null, "original_icon": null, "unit_of_measurement": null, "state": { "entity_id": "switch.smart_plug_prise_1", "state": "off", "attributes": { "device_class": "outlet", "friendly_name": "Prise Terrarium Prise 1" }, "last_changed": "2024-07-03T11:49:59.864096+00:00", "last_reported": "2024-07-03T11:49:59.864096+00:00", "last_updated": "2024-07-03T11:49:59.864096+00:00" } } ] }, "set_up": false, "support_local": true }, { "id": "bf80ca98b2da422bf4na8b", "name": "Smart Litter Box", "category": "msp", "product_id": "uzwdwonukfc4falp", "product_name": "Smart Litter Box", "online": true, "sub": false, "time_zone": "+02:00", "active_time": "2024-05-29T20:45:30+00:00", "create_time": "2024-05-29T20:45:30+00:00", "update_time": "2024-05-29T20:45:30+00:00", "function": { "delay_clean_time": { "type": "Integer", "value": { "unit": "\u5206\u949f", "min": 1, "max": 60, "scale": 0, "step": 1 } }, "factory_reset": { "type": "Boolean", "value": {} } }, "status_range": { "delay_clean_time": { "type": "Integer", "value": { "unit": "\u5206\u949f", "min": 1, "max": 60, "scale": 0, "step": 1 } }, "factory_reset": { "type": "Boolean", "value": {} } }, "status": { "delay_clean_time": 3, "factory_reset": false }, "home_assistant": { "name": "Smart Litter Box", "name_by_user": null, "disabled": false, "disabled_by": null, "entities": [ { "disabled": false, "disabled_by": null, "entity_category": "config", "device_class": null, "original_device_class": null, "icon": null, "original_icon": null, "unit_of_measurement": null, "state": { "entity_id": "number.smart_litter_box_delay_clean_time", "state": "3.0", "attributes": { "min": 1.0, "max": 60.0, "step": 1.0, "mode": "auto", "friendly_name": "Smart Litter Box Delay clean time" }, "last_changed": "2024-07-03T11:50:10.314552+00:00", "last_reported": "2024-07-03T11:50:10.314552+00:00", "last_updated": "2024-07-03T11:50:10.314552+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "config", "device_class": null, "original_device_class": null, "icon": null, "original_icon": null, "unit_of_measurement": null, "state": { "entity_id": "switch.smart_litter_box_factory_reset", "state": "off", "attributes": { "friendly_name": "Smart Litter Box Factory reset" }, "last_changed": "2024-07-03T11:50:10.318755+00:00", "last_reported": "2024-07-03T11:50:10.318755+00:00", "last_updated": "2024-07-03T11:50:10.318755+00:00" } } ] }, "set_up": true, "support_local": true } ] } }

Merci pour ton taff ;)

azerty9971 commented 2 weeks ago

Salut, Oui, enfin, presque, je suis Belge ;).

Je viens de regarder et en fait le soucis c'est que le cloud n'envoie pas plus d'infos :/.

Est ce que tu pourrais télécharger la dernière beta de XTended Tuya sur HACS, puis après avoir redémarré Home Assistant tu vas dans Paramètres -> Système -> Journaux et tu fais "Télécharger les journeaux complets". Ca me dira ce que le cloud Tuya envoie...

Un tout grand merci d'avance, Azerty

d4nm0 commented 2 weeks ago

Salut, Oui, enfin, presque, je suis Belge ;).

Je viens de regarder et en fait le soucis c'est que le cloud n'envoie pas plus d'infos :/.

Est ce que tu pourrais télécharger la dernière beta de XTended Tuya sur HACS, puis après avoir redémarré Home Assistant tu vas dans Paramètres -> Système -> Journaux et tu fais "Télécharger les journeaux complets". Ca me dira ce que le cloud Tuya envoie...

Un tout grand merci d'avance, Azerty

Je t'avoue que je ne sais pas comment faire. Ca ne fais pas longtemps que j'utilise HA. Mais si tu me guide un peu, je te le fais dans les minutes qui suivent :).

azerty9971 commented 2 weeks ago

En gros, tu vas dans HACS (dans le menu de gauche), puis a coté de Xtended Tuya, tu as les 3 points, tu clic dessus, puis tu fais "retélécharger": image

Tu devrais voir cet écran: image

Tu coches "Afficher les versions beta", ça va recharger pendant quelques secondes, puis tu prend la dernière version dispo (comme sur le screenshot) et tu fais "télécharger"

Ca va te demander après de redémarrer Home Assistant (en bas à gauche), tu valide et quand HA aura redémarré tu devrais voir les journaux système.

Si c'est pas clair n'hésite pas à me dire ;)

d4nm0 commented 2 weeks ago

D'accord, c'est très clair ! voila les journaux complets : home-assistant_2024-07-03T12-52-12.614Z.log

azerty9971 commented 2 weeks ago

Arf, en fait le cloud n'envoie pas non plus les infos manquantes: 2024-07-03 14:46:39.630 WARNING (SyncWorker_2) [custom_components.xtend_tuya] update_device_specification => {'t': 1720010799602, 'sign': '4f3dc0a2858d29968a91edd3a3c766c8', 'tid': '4ab25017393a11ef9097ba20a7751800', 'success': True, 'result': {'category': 'msp', 'functions': [{'code': 'delay_clean_time', 'type': 'Integer', 'values': '{"unit":"分钟","min":1,"max":60,"scale":0,"step":1}'}, {'code': 'factory_reset', 'type': 'Boolean', 'values': '{}'}], 'status': [{'code': 'delay_clean_time', 'type': 'Integer', 'values': '{"unit":"分钟","min":1,"max":60,"scale":0,"step":1}'}, {'code': 'factory_reset', 'type': 'Boolean', 'values': '{}'}]}} 2024-07-03 14:46:39.718 WARNING (SyncWorker_2) [custom_components.xtend_tuya] update_device_strategy_info => {'t': 1720010799708, 'sign': '51f91e520961d1fe60ff2bdf6abacfa9', 'tid': '4ac1a635393a11efa7caaa6c9a60812c', 'success': True, 'result': {'category': 'msp', 'dpStatusRelationDTOS': [{'dpCode': 'delay_clean_time', 'dpId': 5, 'enumMappingMap': {}, 'statusCode': 'delay_clean_time', 'statusFormat': '{"delay_clean_time":"$"}', 'supportLocal': True, 'valueConvert': 'default', 'valueDesc': '{"unit":"分钟","min":1,"max":60,"scale":0,"step":1}', 'valueType': 'Integer'}, {'dpCode': 'factory_reset', 'dpId': 23, 'enumMappingMap': {}, 'statusCode': 'factory_reset', 'statusFormat': '{"factory_reset":"$"}', 'supportLocal': True, 'valueConvert': 'default', 'valueDesc': '{}', 'valueType': 'Boolean'}], 'productKey': 'uzwdwonukfc4falp'}}

On voit qu'il envoie delay_clean_time et factory_reset mais pas plus :/

Je vais tenter de voir si à partir du cloud IOT j'arrive à avoir plus d'infos, est ce que tu saurais me dire la marque de la litière et le modèle stp ?

Merci d'avance ;)

d4nm0 commented 2 weeks ago

yes, je te donne carrément le lien de leur site. https://hholove.com/products/cat-litter-box marque : hholove

azerty9971 commented 2 weeks ago

Mince, il n'est pas disponible en Appareil virtuel sur le cloud, est ce que tu pourrais partager ton device avec moi ? Dans l'app Tuya/Smartlife, tu vas dans les paramètre de la litière (la roue crantée) puis "Appareil partagé" et si tu peux m'envoyer le lien sur devun999999@gmail.com .

Ca me permettra l'accès à la litière (promis, je vais pas foutre la merde) mais surtout ça me permettra de voir ce que le cloud répond quand jedemande les infos détaillées de l'appareil

d4nm0 commented 2 weeks ago

C'est envoyé ! Toute façons, tu peux juste faire tournée la merde de mon chat XD. y'a pas beaucoup plus d'accès.

azerty9971 commented 2 weeks ago

Ça m'a juste envoyé une demande pour télécharger smart life, tu dois d'abord ouvrir la page de la litière, puis le crayon en haut a droit, puis partager et faire copier ;)

d4nm0 commented 2 weeks ago

regarde tes mails

azerty9971 commented 2 weeks ago

Screenshot_20240703-151156_Smart Life.png

Ça ressemble à ça chez moi

d4nm0 commented 2 weeks ago

yes j'ai fais partage avec le compte la première fois. et la deuxième fois par mail je t'es envoyé le lien que j'ai copier.

d4nm0 commented 2 weeks ago

normalement c'est good la

azerty9971 commented 2 weeks ago

J'ai pas reçu, dans région, tu as mis Belgique quand tu as fait le partage ?

d4nm0 commented 2 weeks ago

yes, quand je ressaye a nouveau ca me dit qu'il a déjà été partager avec toi. Je t'ai renvoyé un mail. avec le lien direct.

azerty9971 commented 2 weeks ago

Je viens de le recevoir, je vais regarder ça ce soir ;)

d4nm0 commented 2 weeks ago

Super, Merci :)

svenadlung commented 2 weeks ago

Salut! Having the same issue. Happy you are working on a solution 🙌

azerty9971 commented 2 weeks ago

Let's switch to English since we have 2 persons with the issue :)

I've just posted a new beta version that allows to input your Tuya IOT Platform credentials (like the old version of the Tuya integration)

To use this new feature, go to the integration page then next to your username hit "configure": You'll be prompted with the exact same window as the previous Tuya integration. To retrieve the information, you have to follow this guide: 0- Before you start, in the IOT platform make sure that you selected the data center of your region on the top right (IMPORTANT) 1- Configure your Tuya IOT platform developer account: https://developer.tuya.com/en/docs/iot/Platform_Configuration_smarthome?id=Kamcgamwoevrx 2- Input the required credentials: https://developer.tuya.com/en/docs/iot/Home-assistant-tuya-intergration?id=Kb0eqjig0utdd

Once it's configured, I recommend to restart Home Assistant (in theory it's not needed but it's safer since this is an early beta). If possible then upload the full logs here so that I can see if everything worked as expected or not. And of course, check if you have new sensors available in your Cat Litter box in HA ;)

azerty9971 commented 2 weeks ago

Before posting the logs here please remove your Tuya username and password which should be present in the log :)

svenadlung commented 1 week ago

Let's switch to English since we have 2 persons with the issue :)

Thank you very much. I appreciate it very much.

A new switch entity to "empty" has appeared. Unfortunately, it triggers the following error for me:

Error when calling the service switch/turn_on. network error:(2008) command or value not support

That's what my HA logs show – that's what you asked for, isn't it?


Quelle: components/websocket_api/commands.py:241
Integration: Home Assistant WebSocket API (Dokumentation, Probleme)
Erstmals aufgetreten: 19:52:32 (2 Vorkommnisse)
Zuletzt protokolliert: 19:52:37

[139911849888352] Unexpected exception
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 241, in handle_call_service
    response = await hass.services.async_call(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2731, in async_call
    response_data = await coro
                    ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/core.py", line 2774, in _execute_service
    return await target(service_call)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 999, in entity_service_call
    single_response = await _handle_entity_call(
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 1071, in _handle_entity_call
    result = await task
             ^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 1689, in async_turn_off
    await self.hass.async_add_executor_job(ft.partial(self.turn_off, **kwargs))
  File "/usr/local/lib/python3.12/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/xtend_tuya/switch.py", line 258, in turn_off
    self._send_command([{"code": self.entity_description.key, "value": False}])
  File "/config/custom_components/xtend_tuya/base.py", line 275, in _send_command
    self.device_manager.send_commands(self.device.id, commands)
  File "/usr/local/lib/python3.12/site-packages/tuya_sharing/manager.py", line 93, in send_commands
    return self.device_repository.send_commands(device_id, commands)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/tuya_sharing/device.py", line 180, in send_commands
    self.api.post(f"/v1.1/m/thing/{device_id}/commands", None, {"commands": commands})
  File "/usr/local/lib/python3.12/site-packages/tuya_sharing/customerapi.py", line 192, in post
    return self.__request("POST", path, params, body)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/tuya_sharing/customerapi.py", line 121, in __request
    raise Exception(f"network error:({ret['code']}) {ret['msg']}")
Exception: network error:(2008) command or value not support
azerty9971 commented 1 week ago

Nice, at least it's moving forward:).

Could you export the diagnostic data from the cat litter box page (the export extended tuya diagnostic)?

Big thanks in advance!! Azerty

svenadlung commented 1 week ago

Does this help? home-assistant_xtend_tuya_2024-07-06T19-21-53.085Z.log

azerty9971 commented 1 week ago

Hello, Could you now retry with the latest beta?

If you haven't done so yet, you need to configure the Tuya IOT Cloud credentials in the eXtended Tuya configuration page: (the button named "Configurer" in the following screenshot): image

azerty9971 commented 1 week ago

And also, could you verify that the switches work as expected? (like the one to turn on/off the indicator light)

Thanks, Azerty

d4nm0 commented 1 week ago

Hello, so i created my cloud project on the tuya platform, i downloaded the latest beta. I entered the correct information given by the tuya cloud project. But when I configure the extension I get an error. I'll provide you with the logs. image home-assistant_xtend_tuya_2024-07-08T06-46-45.095Z.log

Thanks for your work : )

svenadlung commented 1 week ago

Same here. After updating to latest beta the entities are deactivated and the integration comes with an init error. I also did configure the cloud account before.

azerty9971 commented 1 week ago

Can you retry with the updated beta?

Have a nice day, Azerty

d4nm0 commented 1 week ago

Hello, The extension works. And it returns a lot of information. I don't know what it means yet. But it's there.

image0

image

azerty9971 commented 1 week ago

Yes, I've matched the text with their technical names but sometimes they are not really understandable.

If you want me to update the texts that's totally doable ;)

Can you test is the switches work ? Like the one to turn on/off the indicator light on the litter.

Thanks in advance, Azerty

svenadlung commented 1 week ago

Can confirm it seems to be connected and it lists a lot of entities 🙌

Screenshot 2024-07-08 at 14 43 52@2x

Triggering "Cleaning" on the device doesn't show up in interface though:

Screenshot 2024-07-08 at 14 43 45@2x

"Empty" command seems to be broken:

This entity is no longer provided by the xtend_tuya integration. If the entity is no longer used, delete it in the settings.

Screenshot 2024-07-08 at 14 44 12@2x

Triggering "Indicator light" switch results in an error:

Screenshot 2024-07-08 at 14 45 41@2x

azerty9971 commented 1 week ago

there is more work to be done on the actions then :)

I'll keep you posted for an updated beta when I've figured it out ;)

azerty9971 commented 1 week ago

Hello, Can you try the latest beta and let me know if everything is working better?

Have a nice day, Azerty

svenadlung commented 1 week ago

Seems like this one is crashing on init again. Logs attached. home-assistant_xtend_tuya_2024-07-08T20-19-27.503Z.log

azerty9971 commented 1 week ago

This is because I had left some of my debug infos, can you fetch the latest beta and retry? Sorry :'(

azerty9971 commented 1 week ago

OK, I've went through all the texts in Chinese that the API was returning and I think I figured out most of the sensors/functions available...

Could you please test and verify that my assumptions are correct? (that all sensors, actions, ect are doing what they are named to do?)

Specifically, the Child Lock function is named reboot, so it's either a reboot or a Child lock, could you please test and let me know?

beta 08 is posted and ready for your testing :)

Have fun, Azerty

azerty9971 commented 1 week ago

There is (again) a new beta release, some sensors were not showing up :)

Now I think the Litter box should be usable in HA :)

d4nm0 commented 1 week ago

Hi, there, Great, I've got lots of information. Now I have to figure out what they correspond to. I'd like to find the same interface as tuya but on Home Assistant. I need to find the entities that correspond to the number of times the litter is cleaned. The temperature I have is the most explicit XD. and then the other two buttons. The one to force cleaning and the one to empty the litter. PS: I suppose it was you who was playing with my litter box last night? Thank you for your reactivity! and your work

image hholove_litter

azerty9971 commented 1 week ago

Yes, that was me, sorry about that I hope the cat was not too bothered :'( I've done a lot of testing with the indicator light and have triggered a couple of cleaning (both by mistake and to test)

For the number of times the cat went to the toilet, the doc says it should be the number of times the entity "Number of cleaning" gets set to 1 each day.

I'll try to implement it using virtualstates keep you posted ;)

Did you check if the child lock is actually the child lock or the reboot function?

For the force cleaning, there is either the "One click cleanup" switch that does that or you can set the "Manual shoveling" to "Start manual shoveling"

Do you have a function to empty the litter from the app? What does it do?

I'm happy to see that I helped you ;)

Have a nice day, Azerty

d4nm0 commented 1 week ago

no problem, I was hearing beeps XD. To clean the litter box, the One click cleanup button doesn't work, you have to go through the selection entity and select manual startup. and the poop counter can be interesting, I'll make some stats XD. and for emptying the litter box, I haven't found the right entity yet. image

azerty9971 commented 1 week ago

How does the emptying of the litter box work? You push on a button and it opens the bin place ?

There was one entity that looked a duplicate of another one, that might be it ...

d4nm0 commented 1 week ago

To empty the litter completely, there's a button that turns the litter in the other direction.

azerty9971 commented 1 week ago

I've sent you a mail on your email address that ends with org ;)

d4nm0 commented 1 week ago

I lost access this week and I'm in discussion with my host to get it back. Can you go through another place? dan.monceau.lpcb@gmail.com