TionAPI / tion_python

Python module for Tion
GNU Lesser General Public License v3.0
64 stars 9 forks source link

Add S4 support #22

Closed andlommy closed 3 years ago

andlommy commented 3 years ago

Версия модуля: 1.20 Модель бризера: Tion S4 Версия прошивки (если известна): 02D0

Описание проблемы

Опишите возникшую проблему простыми словами When performing device.pair() (device in blue flashing mode), Authentication Failed response comes back from the breezer

Порядок действий, которые приводят к проявлению проблемы

from tion_btle import S3 as Breezer mac: str=str("XX:XX:XX:XX:XX:XX") device = Breezer(mac) device.pair()

Логи

buntu@ubuntu:/tmp$ sudo python3
Python 3.8.6 (default, Jan 27 2021, 15:42:20) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from tion_btle import S3 as Breezer
>>> mac: str=str("XX:XX:XX:XX:XX:XX")
>>> device=Breezer(mac)
>>> device.pair()
DEBUG:tion_btle.tion:Pairing
DEBUG:tion_btle.tion:Connecting
DEBUG:tion_btle.tion:Notifications was not requested
DEBUG:tion_btle.tion:Connected. BT pairing ...
DEBUG:tion_btle.tion:Got response while sending pair command: {'rsp': ['mgmt'], 'code': ['mgmterr'], 'estat': [5], 'emsg': ['Authentication Failed']}
CRITICAL:tion_btle.tion:Unexpected response: {'rsp': ['mgmt'], 'code': ['mgmterr'], 'estat': [5], 'emsg': ['Authentication Failed']}
CRITICAL:tion_btle.tion:Got exception while pair TionException: ('pair', {'rsp': ['mgmt'], 'code': ['mgmterr'], 'estat': [5], 'emsg': ['Authentication Failed']})
DEBUG:tion_btle.tion:disconnected
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/tion_btle/tion.py", line 518, in pair
    raise TionException('pair', rsp)
tion_btle.tion.TionException: ('pair', {'rsp': ['mgmt'], 'code': ['mgmterr'], 'estat': [5], 'emsg': ['Authentication Failed']})

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/dist-packages/tion_btle/tion.py", line 525, in pair
    raise TionException('pair', f"{type(e).__name__}: {str(e)}")
tion_btle.tion.TionException: ('pair', "TionException: ('pair', {'rsp': ['mgmt'], 'code': ['mgmterr'], 'estat': [5], 'emsg': ['Authentication Failed']})")
IATkachenko commented 3 years ago

S4 модулем не поддерживается: там может быть совершенно другой механизм сопряжения. Если у вас есть возможность -- соберите, пожалуйста, дамп общения телефона и бризера во время следующих действий:

  1. добавление бризера в приложение;
  2. получение информации от бризера (вместе с состоянием бризера)
  3. изменения скорости вентилятора
  4. изменения целевой температуры
  5. изменения режима работы нагревателя
  6. изменения режима заслонки (если есть)
andlommy commented 3 years ago

занимаюсь этим. пока не могу поднять hci_snoop на телефоне или планшете - не создается логфайл. Если есть идеи как его подшаманить - буду сильно признателен

IATkachenko commented 3 years ago

Все дампы что мне собирали делались на iPhone дебагом bluetooth стека.

andlommy commented 3 years ago

у меня 2 ведроида и в обоих дебаг блютус стека не делает нужные действия, но я поковыряюсь еще, уж больно хочется подружить свои бризеры с ХА

IATkachenko commented 3 years ago

Попробуйте через bluetoothctl сделать обычный pairing -- это может сработать, как в случае с Lite. Это самый простой вариант -- вдруг сработает. Если это получится -- будем думать как добыть пакаеты. Внешне бризеры очень похожи, но я не думаю что программный стек не поменялся (тем более если сработает сопряжение через bluetoothctl).

andlommy commented 3 years ago

Оно действительно похож на обычный Pairing, судя по расковыряным исходникам приложения, в 4с особой процедуры спаривания нет. Лог спаривания раздобыл snooplog.log

andlommy commented 3 years ago

В каждом из логов каждое действие делалось по 3 раза Logs.zip

Открытие проги и получение информации об устройстве Включение турбо режима и переключение на 4 скорость Включение прогрева (на 25 градусов, на 24 и на 20) Включение и выключение заслонки

IATkachenko commented 3 years ago

Спасибо. Может ближе к ночи будет что-нибудь что можно потестить.

IATkachenko commented 3 years ago

Быстро не получится -- по структуре пакетов он ближе к Lite, а не к S3, так что придется немного повозиться. Данные из дампов вытащил -- буду смотреть и разбираться.

andlommy commented 3 years ago

есть коды команд и примерная структура пакетов (из реверса apk приложения тиона) - если поможет, могу скинуть

IATkachenko commented 3 years ago

Я туда уже тоже заглянул. Да и из пакетов много чего понятно. Основная проблема в "аккуратно сделать": Lite-класс чуть сложнее и был не так хорошо написан как S3.

IATkachenko commented 3 years ago

@andlommy, попробуйте, пожалуйста, tests/s4.py из ветки s4-dev в двух вариантах:

  1. s4.py dummy
  2. s4.py MAC:вашего:Бризера

Первый -- просто для того чтобы убедиться что все работает. А результат второго будет интересно сравнить с действительностью.

Перед реальным запуском нужно будет сделать сопряжение устройств через bluetoothctl или примерно такой python скрипт

from tion_btle.s4 import S4
device = S4(MAC:вашего:Бризера)
device.pair()
andlommy commented 3 years ago

спасибо, завтра попробую. Спрашивал доки по протоколу у Тиона - не дали :(

IATkachenko commented 3 years ago

Они их обещают примерно с выпуска первого бризера :(

andlommy commented 3 years ago

Не заработало на бризере

root@ubuntu:/home/ubuntu/Documents/tion_python-s4-dev/tests# python3 ./s4.py XX:XX:XX:XX:XX:XX DEBUG:tion_btle.tion:Connecting WARNING:tion_btle.tion:Got BTLEDisconnectError:Failed to connect to peripheral XX:XX:XX:XX:XX:XX, addr type: random DEBUG:tion_btle.tion:Will try again. DEBUG:tion_btle.tion:Connecting WARNING:tion_btle.tion:Got BTLEDisconnectError:Failed to connect to peripheral XX:XX:XX:XX:XX:XX, addr type: random Traceback (most recent call last): File "/usr/local/lib/python3.8/dist-packages/tion_btle/tion.py", line 305, in _connect self._btle.connect(self.mac, btle.ADDR_TYPE_RANDOM) File "/usr/local/lib/python3.8/dist-packages/bluepy/btle.py", line 445, in connect self._connect(addr, addrType, iface) File "/usr/local/lib/python3.8/dist-packages/bluepy/btle.py", line 439, in _connect raise BTLEDisconnectError("Failed to connect to peripheral %s, addr type: %s" % (addr, addrType), rsp) bluepy.btle.BTLEDisconnectError: Failed to connect to peripheral XX:XX:XX:XX:XX:XX, addr type: random

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "./s4.py", line 18, in result = device.get() File "/usr/local/lib/python3.8/dist-packages/tion_btle/tion.py", line 218, in get self.connect() File "/usr/local/lib/python3.8/dist-packages/tion_btle/tion.py", line 538, in connect self._connect() File "/usr/local/lib/python3.8/dist-packages/tion_btle/tion.py", line 322, in _connect self._connect(need_notifications) File "/usr/local/lib/python3.8/dist-packages/tion_btle/tion.py", line 324, in _connect raise e File "/usr/local/lib/python3.8/dist-packages/tion_btle/tion.py", line 305, in _connect self._btle.connect(self.mac, btle.ADDR_TYPE_RANDOM) File "/usr/local/lib/python3.8/dist-packages/bluepy/btle.py", line 445, in connect self._connect(addr, addrType, iface) File "/usr/local/lib/python3.8/dist-packages/bluepy/btle.py", line 439, in _connect raise BTLEDisconnectError("Failed to connect to peripheral %s, addr type: %s" % (addr, addrType), rsp) bluepy.btle.BTLEDisconnectError: Failed to connect to peripheral XX:XX:XX:XX:XX:XX, addr type: random

в это же время bluetoothctl

[Breezer 4S]# connect XX:XX:XX:XX:XX:XX Attempting to connect to XX:XX:XX:XX:XX:XX Connection successful

IATkachenko commented 3 years ago

Спасибо. Небольшое уточнение: во время теста к бризеру не было подключено никаких устройств (телефон, magic Air или что-нибудь еще)?

andlommy commented 3 years ago

Отключил всех, попробовал еще раз, то же самое

IATkachenko commented 3 years ago

Интересно... До enable_notifications он не доходит... Добавлю побольше дебага вечером. Может станет понятнее что именно ему не удается. Пока варианта два:

  1. он подключается и не может получить список характеристик (меньшая из проблем)
  2. он не может даже подключиться.

Понять поможет примерно вот такая конструкция (если нигде не опечатался):

from bluepy import btle

mac = 'MAC:address:here'
device = btle.Peripheral(None)
print ('connecting')
device.connect(mac, btle.ADDR_TYPE_RANDOM)
print ('connected')
print(device.getCharacteristics())
device.disconnect()
print('disconnected')

Если это работает, а модуль нет -- буду думать в другую сторону.

IATkachenko commented 3 years ago

Да, бризер -- довольно капризная в плане BT штука: не любит частых подключений отключений и вообще активной работы с BT (по опыту Lite и S3). Еще если открыть bluetoothctl во втором окне, будет видно подключается ли хост к бризеру или нет.

andlommy commented 3 years ago

О. оно очухалось

root@ubuntu:/home/ubuntu/Documents/tion_python-s4-dev/tests# python3 ./s4.py XX:XX:XX:XX:XX:XX DEBUG:tion_btle.tion:Connecting DEBUG:tion_btle.tion:Enabling notification DEBUG:tion_btle.tion:Notify handler is 18 DEBUG:tion_btle.tion:Will write b'\x01\x00' to 19 handle DEBUG:tion_btle.tion:Result is {'rsp': ['wr']} DEBUG:tion_btle.tion:Delegation enabled DEBUG:tion_btle.tion:First read done. Data is c00000000000060054e2 DEBUG:tion_btle.tion:enable_notification is done Traceback (most recent call last): File "./s4.py", line 18, in result = device.get() File "/usr/local/lib/python3.8/dist-packages/tion_btle/tion.py", line 219, in get response = self._get_data_from_breezer() File "/usr/local/lib/python3.8/dist-packages/tion_btle/light_family.py", line 107, in _get_data_from_breezer self._do_action(self._try_write, request=self.create_request_params_command) File "/usr/local/lib/python3.8/dist-packages/tion_btle/s4.py", line 81, in create_request_params_command raise NotImplementedError() NotImplementedError root@ubuntu:/home/ubuntu/Documents/tion_python-s4-dev/tests#

IATkachenko commented 3 years ago

Привыкайте, так оно и работает :( Отлично, базовый функционал в порядке, можно двигаться дальше.

Я, конечно, забыл что команду для запроса данных нужно сделать, но там хоть из дампа можно взять, так что может даже сегодня сделаю :)

IATkachenko commented 3 years ago

Залил обновленную версию. Сейчас должно нормально отработать.

andlommy commented 3 years ago

Заработало

root@ubuntu:/home/ubuntu/Downloads/tion_python-s4-dev/tests# python3 ./s4.py XX:XX:XX:XX:XX:XX DEBUG:tion_btle.tion:Connecting DEBUG:tion_btle.tion:Enabling notification DEBUG:tion_btle.tion:Notify handler is 18 DEBUG:tion_btle.tion:Will write b'\x01\x00' to 19 handle DEBUG:tion_btle.tion:Result is {'rsp': ['wr']} DEBUG:tion_btle.tion:Delegation enabled DEBUG:tion_btle.tion:First read done. Data is c00000000000060054e2 DEBUG:tion_btle.tion:enable_notification is done DEBUG:tion_btle.tion:Doing _try_write. Attempt 1/3 DEBUG:tion_btle.tion:Writing 8010003aa132325ba5a7498e46d067bbaa to 98f00002-3788-83ea-453e-f52244709ddb DEBUG:tion_btle.light_family:Collecting data DEBUG:tion_btle.tion:Got data in 18 response 002f003a5831325ba5a749b8c8bc183f51001904 DEBUG:tion_btle.tion:Got data in 18 response 400d101d26df1d0a0005fa0900fb53e30054812f DEBUG:tion_btle.tion:Got data in 18 response c0000000000006002e3f DEBUG:tion_btle.light_family:Got 002f003a5831325ba5a749b8c8bc183f51001904 from tion DEBUG:tion_btle.light_family:Got 400d101d26df1d0a0005fa0900fb53e30054812f from tion DEBUG:tion_btle.light_family:Got c0000000000006002e3f from tion DEBUG:tion_btle.s4:Data is 3f510019040d101d26df1d0a0005fa0900fb53e30054812f00000000000600 DEBUG:main:Result is {'state': 'on', 'heater': 'off', 'heating': 'off', 'sound': 'on', 'mode': 'outside', 'out_temp': 16, 'in_temp': 13, 'heater_temp': 25, 'fan_speed': 4, 'filter_remain': 172.43253472222221, 'time': '17:32', 'request_error_code': 0, 'model': 'S4', 'light': 'on'} INFO:main:Initial state: device is on, light is on, sound is on, heater is off, fan_speed is 4, target_temp is 25

оно пока умеет только читать или писать тоже сможет?

IATkachenko commented 3 years ago

Пока только читать. Тион устроен так, что при команде set нужно передавать полное состояние бризера, а не только тот параметр, который хочется изменить. Поэтому сначала учимся читать, убеждаемся что читается все правильно, а потом начинаем учиться писать.

Эти результаты соответствуют действительности? Попробуйте некоторые параметры поменять (пультом или приложением) и убедиться что они корректно изменяются и в результатах теста. Сейчас очень важно убедиться что мы умеем получать правильные данные с бризера.

andlommy commented 3 years ago

Результаты считываются корректно

IATkachenko commented 3 years ago

Отлично. Тогда в ближайшее время займусь set-частью.

andlommy commented 3 years ago

премного благодарен. Умел бы писать на питоне, посодействовал бы

andlommy commented 3 years ago

Стесняюсь спросить - есть какой-нибудь прогресс? не терпиться протестировать :)

IATkachenko commented 3 years ago

Не стоит стесняться -- хороший вопрос!

Извините, пока со временем не особо :(

IATkachenko commented 3 years ago

@andlommy, попробуйте, пожалуйста, tests/s4.py из ветки s4-dev.

Оно должно:

  1. (это мы уже тестировали) сообщить текущее состояние бризера
  2. выключить/включить бризер (если включен, иначе просто включит и выключит в конце тестов)
  3. переключить туда-сюда нагреватель
  4. подвигать заслонку
  5. переключить вентилятор на 2 скорость, потом на 5, вернуть как было.

Дебага будет море, поэтому пришлите сюда только то, что пойдет не по плану, начиная с DEBUG:tion_btle.tion:Connecting и до ошибки или следующего теста.

Между действиями будет пауза в 10 секунд (настраивается параметром sleep_step, но меньше 5 секунд ставить не стоит), прервать можно практически в любой момент.

andlommy commented 3 years ago

Приветствую. Сори был в отъезде, на этой неделе попробую поиграться и сообщу

IATkachenko commented 3 years ago

@andlommy, никаких проблем. Все идет в удобном каждому ритме: дэдлайнов тут не бывает ;)

andlommy commented 3 years ago

Можно попросить добавить в тест, чтобы после установки режима он показывал состояние, а то непросто определить включился ли обогрев или нет :)

andlommy commented 3 years ago

INFO:main:Going to set mode to recirculation DEBUG:tion_btle.tion:Connecting DEBUG:tion_btle.tion:Enabling notification DEBUG:tion_btle.tion:Notify handler is 18 DEBUG:tion_btle.tion:Will write b'\x01\x00' to 19 handle DEBUG:tion_btle.tion:Result is {'rsp': ['wr']} DEBUG:tion_btle.tion:Delegation enabled DEBUG:tion_btle.tion:First read done. Data is c0010000000006009399 DEBUG:tion_btle.tion:enable_notification is done DEBUG:tion_btle.tion:Doing _try_write. Attempt 1/3 DEBUG:tion_btle.tion:Writing 8010003aa132327e85ee1ac563d7b6bbaa to 98f00002-3788-83ea-453e-f52244709ddb DEBUG:tion_btle.light_family:Collecting data DEBUG:tion_btle.tion:Got data in 18 response 002f003ac631327e85ee1a17e321d72551010002 DEBUG:tion_btle.tion:Got data in 18 response 400f11161f829d3b00ad3439005319b40031a103 DEBUG:tion_btle.tion:Got data in 18 response c001000000000600fc09 Traceback (most recent call last): File "s4.py", line 56, in device.set({test: state}) File "/usr/local/lib/python3.8/site-packages/tion_btle/tion.py", line 252, in set current_settings = self.get() File "/usr/local/lib/python3.8/site-packages/tion_btle/tion.py", line 219, in get response = self._get_data_from_breezer() File "/usr/local/lib/python3.8/site-packages/tion_btle/light_family.py", line 128, in _get_data_from_breezer self._btle.waitForNotifications(1.0) File "/usr/local/lib/python3.8/site-packages/bluepy/btle.py", line 560, in waitForNotifications resp = self._getResp(['ntfy','ind'], timeout) File "/usr/local/lib/python3.8/site-packages/bluepy/btle.py", line 416, in _getResp self.delegate.handleNotification(hnd, data) File "/usr/local/lib/python3.8/site-packages/tion_btle/tion.py", line 22, in handleNotification self.__topic.read() File "/usr/local/lib/python3.8/site-packages/bluepy/btle.py", line 197, in read return self.peripheral.readCharacteristic(self.valHandle) File "/usr/local/lib/python3.8/site-packages/bluepy/btle.py", line 530, in readCharacteristic resp = self._getResp('rd') File "/usr/local/lib/python3.8/site-packages/bluepy/btle.py", line 407, in _getResp resp = self._waitResp(wantType + ['ntfy', 'ind'], timeout) File "/usr/local/lib/python3.8/site-packages/bluepy/btle.py", line 362, in _waitResp raise BTLEDisconnectError("Device disconnected", resp) bluepy.btle.BTLEDisconnectError: Device disconnected

makp0 commented 3 years ago

народ, если вы мне скажете как мне это запустить, не имея компа с линухом 😅, я могу присоединиться к разработке.

Ravexkgd commented 3 years ago

Есть Тион 4S, debian и успешно подключаюсь через bluetoothctl Готов тоже помочь с дебагом и тестами.

IATkachenko commented 3 years ago

Ядро работает, похоже, нормально. Ошибка выше -- не специфичная для модели, скорее всего, плавающая и не критичная: модуль получил все необходимые данные и отвалился уже после этого.

@Zorgino, linux -- не обязательно. Для работы нужен python3.9 с установленным модулем bluepy. Это можно провернуть под Windows.

@Ravexkgd, спасибо. Я к выходным обновлю тестовый скрипт и чутка подкручу модуль чтобы при таких ошибках оно не крашилось.

makp0 commented 3 years ago

@IATkachenko, https://github.com/IanHarvey/bluepy/issues/410#issuecomment-638027571

IATkachenko commented 3 years ago

@Zorgino даже так... Тогда остается лазейка в виде того, что в Win-10 можно "Run Linux on windows" https://docs.microsoft.com/ru-ru/windows/wsl/install-win10

Плюс у меня есть дааавний проект по добавлению bleak в качестве BT интерфейса, но он не поддерживается HA и я не спешу (но абстракции для этого в модуле практически готовы: осталось добавить только уровень для разделения на bluepy и bleak).

makp0 commented 3 years ago

@IATkachenko, https://github.com/microsoft/WSL/issues/242#issuecomment-847887358 🙂

IATkachenko commented 3 years ago

@Zorgino, как все в виндах запущено...

Можно попросить добавить в тест, чтобы после установки режима он показывал состояние, а то непросто определить включился ли обогрев или нет :)

@andlommy, @Zorgino, обновил модуль и тестовый скрипт. Ошибки выше быть не должно, но могут проскакивать WARNING'и с ней связанные. Они не критичные и не должны мешать работе.

makp0 commented 3 years ago

to test tion s4. in Linux terminal:

  1. git clone https://github.com/TionAPI/tion_python.git
  2. cd tion_python
  3. git checkout s4-dev
  4. pip3 install -e ./
  5. python3 tests/s4.py "CF:7E:05:FC:**:**"
IATkachenko commented 3 years ago

Коллеги, у кого-нибудь получилось запустить тесты, после обновления от 4 июня?

makp0 commented 3 years ago

Коллеги, у кого-нибудь получилось запустить тесты, после обновления от 4 июня?

да, всё отлично, тесты бегают, ошибок нет. из сайдэффектов, по ощущениям, меньше сообщений об отвале "Got BTLEDisconnectError:Failed to connect to peripheral"

IATkachenko commented 3 years ago

Отлично! Тогда в ближайшие дни сделаю релиз модуля.