mavrikkk / ha_kettler

allows you to connect Redmond SkyKettle, SkyCooker and SkyHeat to your Home Assistant. see README to know further
131 stars 50 forks source link

Адаптируйте пожалуйста под чайники Redmond Skykettel M***S #3

Closed 3AXAPOB closed 4 years ago

3AXAPOB commented 4 years ago

Адаптируйте пожалуйста под чайники Redmond Skykettel M***S, например Skykettle RK-M171S-E, SkyKettle M216S. Готов поддержать донатом.

Или подскажите где на что поменять.

mavrikkk commented 4 years ago

Чтобы им заняться - нужен этот чайник )) иначе мне команды не перехватить и ничего не отладить. Поэтому сам заниматься не буду. Подсказать могу. Про этот чайник есть статья с расписанными командами: https://habr.com/en/post/371965/ . Там чайник RK-M171S.

Подсказываю: Все правки нужны в файле init.py Непосредственно команды, отсылаемые чайнику:

  1. Соединение: функция connect. Останется той же.

  2. Запрос на получение уведомлений; функция sendResponse. Остается той же.

  3. Авторизация: функция sendAuth. остается той же.

  4. Использовать или нет подсветку текущей температуры: функция sendUseBackLight. В принципе не обязательна и как она реализована у вас (и есть ли вообще) понятия не имею. Можете просто удалить все строки с ее вызовом, как и ее саму.

  5. Установка цветов подсветки: sendSetLights. Аналогично с предыдущим пунктом - все удалить.

  6. Синхронизация времени: функция sendSync. При отключенной подсветке в ней в любом случае смысла нет. Удаляете.

  7. Получение статистики работы: функция sendStat. Автор не упоминал о ней. Так что удаляем. Она нужна для получения значений: затраченной энергии, количестве включений и общем времени работы.

  8. Получение текущего статуса чайника: функция sendStatus. Она по любому нужна. Чтобы узнать текущее состояние чайника: включен, выключен, режим работы, температура. У автора раздел называется "Запросить состояние". Вроде бы и запрос и ответ сходятся. Попробуйте оставить как есть.

  9. Функции startNightColor, stopNightColor, sendSetLights, sendGetLights, sendUseBackLight, sendStat, sendSync, sendOn и ВСЕ ИХ ВЫЗОВЫ в других функциях удаляем. Также удаляем файл light.py. В массиве SUPPORTED_DOMAINS удаляем элемент light.

  10. Выключение чайника. Функция sendOff. Остается как есть.

  11. Включение чайника. Функция sendMode. Ее нужно править. Найдите в этой функции текст "00000000000000000000800000aa" и замените на "00aa"

По идее должно заработать. В любом случае, без чайника я вам больше ничем не помогу.

3AXAPOB commented 4 years ago

Не получилось (

Ошибки: Уровень: ERROR Sun Feb 09 2020 14:21:26 GMT+0300 (MSK) error first connect

Уровень: ERROR Sun Feb 09 2020 14:22:28 GMT+0300 (MSK) error connect

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

https://github.com/Andrey-m/homebridge-redmond-sh

mavrikkk commented 4 years ago

эти скрипты от автора той статьи.

раз не проходит коннект - то ваша система не дает блютусу коннектиться к неизвестным устройствам. Я писал об этом в статье и здесь уже объяснял:

Если gatttool не желает подключаться к чайнику (такое возможно при первом подключении к неизвестным устройствам), то попробуйте выполнить поиск чайника средствами os до подключения модуля:

sudo hciconfig device reset sudo timeout 1 hcitool lescan

device — id вашего блютус устройства (например, hci0). Убедитесь, что мак адрес вашего чайника есть в списке найденных устройств. После этого:

sudo hcitool lewladd mac sudo hcitool lerladd mac

mac — мак адрес вашего чайника

3AXAPOB commented 4 years ago

эти скрипты от автора той статьи

Они сделаны на ее основе. Но скрипт автора первой статьи на хабре у меня не заработал. А эти работают. Запускал их с сервера где установлен hass, они отрабатывают.

sudo hcitool lerladd макчайника

Выдал ошибку Cant add to resolving list: IO error (5)

Сейчас висит 10 таких ошибок: Уровень: ERROR Sun Feb 09 2020 15:37:56 GMT+0300 (MSK) error connect

Ошибок с авторизацией нет. Возможно чайник уже авторизован?

mavrikkk commented 4 years ago

Ошибку Cant add to resolving list: IO error (5) выдать и должен был. После выполнения команд пробовали подключить чайник? Перевести его в режим сопряжения и перезагрузить HA? Обязательно попробуйте, само по себе не заработает

Если скрипты отличаются от автора той статьи, та найдите разницу и замените команды

3AXAPOB commented 4 years ago

не помогло. у меня hassio в докере может он вообще не отрабатывает gatttool?

mavrikkk commented 4 years ago

разница в скриптах первого автора и присланного вами только в команде ВКЛЮЧИТЬ...так что как минимум подключиться он должен, что в полностью моей версии, что в модифицированной моей версии, что в его версии

mavrikkk commented 4 years ago

у меня тоже hassio. все работает

mavrikkk commented 4 years ago

где лог? экстрасенс в отпуске. модифицируйте функции connect sendResponce, sendAuth sendStatus, убрав из нее строки try и except. тогда он будет крашиться и выдавать информативную ошибку, а не заглушку

mavrikkk commented 4 years ago

на примере connect

def connect(self):
    answ = False
    self._is_busy = True
    self.child = pexpect.spawn("gatttool --adapter=" + self._device + " -I -t random -b " + self._mac, ignore_sighup=False)
    self.child.expect(r'\[LE\]>', timeout=1)
    self.child.sendline("connect")
    self.child.expect(r'Connection successful.*\[LE\]>', timeout=1)
    self._is_busy = False
    answ = True
    return answ
3AXAPOB commented 4 years ago

Вот такие ошибки появились

Connect to Kettler E0:C2:75:EE:3F:2C through device hci0 failed

и варнинг

Update failed

3AXAPOB commented 4 years ago

Ошибка при попытке авторизоваться

Sun Feb 09 2020 17:43:15 GMT+0300 (MSK) Timeout exceeded. <pexpect.pty_spawn.spawn object at 0xac273df0> command: /usr/bin/gatttool args: ['/usr/bin/gatttool', '--adapter=hci0', '-I', '-t', 'random', '-b', 'E0:C2:75:EE:3F:2C'] buffer (last 100 chars): b' connect\r\nAttempting to connect to E0:C2:75:EE:3F:2C\r\n[E0:C2:75:EE:3F:2C][LE]> ' before (last 100 chars): b' connect\r\nAttempting to connect to E0:C2:75:EE:3F:2C\r\n[E0:C2:75:EE:3F:2C][LE]> ' after: <class 'pexpect.exceptions.TIMEOUT'> match: None match_index: None exitstatus: None flag_eof: False pid: 89 child_fd: 36 closed: False timeout: 30 delimiter: <class 'pexpect.exceptions.EOF'> logfile: None logfile_read: None logfile_send: None maxread: 2000 ignorecase: False searchwindowsize: None delaybeforesend: 0.05 delayafterclose: 0.1 delayafterterminate: 0.1 searcher: searcher_re: 0: re.compile(b'Connection successful.*\[LE\]>') Traceback (most recent call last): File "/usr/local/lib/python3.7/site-packages/pexpect/expect.py", line 111, in expect_loop incoming = spawn.read_nonblocking(spawn.maxread, timeout) File "/usr/local/lib/python3.7/site-packages/pexpect/pty_spawn.py", line 482, in read_nonblocking raise TIMEOUT('Timeout exceeded.') pexpect.exceptions.TIMEOUT: Timeout exceeded.

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/components/websocket_api/commands.py", line 134, in handle_call_service connection.context(msg), File "/usr/src/homeassistant/homeassistant/core.py", line 1226, in async_call await asyncio.shield(self._execute_service(handler, service_call)) File "/usr/src/homeassistant/homeassistant/core.py", line 1251, in _execute_service await handler.func(service_call) File "/usr/src/homeassistant/homeassistant/helpers/entity_component.py", line 198, in handle_service self._platforms.values(), func, call, required_features File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 356, in entity_service_call future.result() # pop exception if have File "/usr/src/homeassistant/homeassistant/helpers/service.py", line 384, in _handle_service_platform_call result = await result File "/config/custom_components/r4s_kettler/switch.py", line 118, in async_turn_on await self._kettler.firstConnect() File "/config/custom_components/r4s_kettler/init.py", line 466, in firstConnect if self.connect(): File "/config/custom_components/r4skettler/init.py", line 358, in connect self.child.expect(r'Connection successful.*[LE]>', timeout=1) File "/usr/local/lib/python3.7/site-packages/pexpect/spawnbase.py", line 341, in expect timeout, searchwindowsize, async) File "/usr/local/lib/python3.7/site-packages/pexpect/spawnbase.py", line 369, in expect_list return exp.expect_loop(timeout) File "/usr/local/lib/python3.7/site-packages/pexpect/expect.py", line 119, in expect_loop return self.timeout(e) File "/usr/local/lib/python3.7/site-packages/pexpect/expect.py", line 82, in timeout raise TIMEOUT(msg) pexpect.exceptions.TIMEOUT: Timeout exceeded. <pexpect.pty_spawn.spawn object at 0xac273df0> command: /usr/bin/gatttool args: ['/usr/bin/gatttool', '--adapter=hci0', '-I', '-t', 'random', '-b', 'E0:C2:75:EE:3F:2C'] buffer (last 100 chars): b' connect\r\nAttempting to connect to E0:C2:75:EE:3F:2C\r\n[E0:C2:75:EE:3F:2C][LE]> ' before (last 100 chars): b' connect\r\nAttempting to connect to E0:C2:75:EE:3F:2C\r\n[E0:C2:75:EE:3F:2C][LE]> ' after: <class 'pexpect.exceptions.TIMEOUT'> match: None match_index: None exitstatus: None flag_eof: False pid: 89 child_fd: 36 closed: False timeout: 30 delimiter: <class 'pexpect.exceptions.EOF'> logfile: None logfile_read: None logfile_send: None maxread: 2000 ignorecase: False searchwindowsize: None delaybeforesend: 0.05 delayafterclose: 0.1 delayafterterminate: 0.1 searcher: searcher_re: 0: re.compile(b'Connection successful.*\[LE\]>')

mavrikkk commented 4 years ago

у вас вылет по таймауту. то есть за выделенное мной время (1 сек) ваш блютус не может подключиться к чайнику. У меня в коде 2 раза встречается "timeout=1" исправьте на 2 Больше я никогда не ставил.

Если не поможет, то через консоль проверьте:

gatttool --adapter=hci0 -I -t random -b E0:C2:75:EE:3F:2C если все пройдет нормально (а судя по логу этот этап проходит), то следом забейте: connect и ловите лог...

3AXAPOB commented 4 years ago

Ошибка авторизации исчезла.

gatttool --adapter=hci0 -I -t random -b E0:C2:75:EE:3F:2C если все пройдет нормально (а судя по логу этот этап проходит), то следом забейте: connect

[ E0:C2:75:EE:3F:2C][LE]> connect Attemping to connect to E0:C2:75:EE:3F:2C Connection succesful [ E0:C2:75:EE:3F:2C][LE]> (gatttool:2814): GLib-WARNING **:19:00:21.710: Invalid file descriptor.

в логе HASS

Уровень: WARNING Sun Feb 09 2020 19:05:29 GMT+0300 (MSK) Update failed

mavrikkk commented 4 years ago

ну, теперь попробуйте заново авторизоваться с перезагрузкой HA. если также все останется, то дальнейший шаг стандартный: убираем try except из модуля update и всех модулей, которые он вызывает и смотрим ошибки

3AXAPOB commented 4 years ago

pexpect.exceptions.TIMEOUT: Timeout exceeded. <pexpect.pty_spawn.spawn object at 0xaf7f0450> command: /usr/bin/gatttool args: ['/usr/bin/gatttool', '--adapter=hci0', '-I', '-t', 'random', '-b', 'E0:C2:75:EE:3F:2C'] buffer (last 100 chars): b' 0x000e 550affb54c75b1b40c88efaa\r\n\x1b[0;91mCommand Failed: \x1b[0mDisconnected\r\n[E0:C2:75:EE:3F:2C][LE]> ' before (last 100 chars): b' 0x000e 550affb54c75b1b40c88efaa\r\n\x1b[0;91mCommand Failed: \x1b[0mDisconnected\r\n[E0:C2:75:EE:3F:2C][LE]> ' after: <class 'pexpect.exceptions.TIMEOUT'>

верхняя ошибка исчезла. Появилась вот такая еще ошибка

File "/config/custom_components/r4s_kettler/switch.py", line 118, in async_turn_on await self._kettler.firstConnect() File "/config/custom_components/r4s_kettler/init.py", line 470, in firstConnect if self.sendAuth(): File "/config/custom_components/r4skettler/init.py", line 174, in sendAuth self.child.expect("value: ") # wait for response File "/usr/local/lib/python3.7/site-packages/pexpect/spawnbase.py", line 341, in expect timeout, searchwindowsize, async) File "/usr/local/lib/python3.7/site-packages/pexpect/spawnbase.py", line 369, in expect_list return exp.expect_loop(timeout) File "/usr/local/lib/python3.7/site-packages/pexpect/expect.py", line 119, in expect_loop return self.timeout(e) File "/usr/local/lib/python3.7/site-packages/pexpect/expect.py", line 82, in timeout raise TIMEOUT(msg) pexpect.exceptions.TIMEOUT: Timeout exceeded. <pexpect.pty_spawn.spawn object at 0xb10c9e90> <pexpect.pty_spawn.spawn object at 0xac134dd0> command: /usr/bin/gatttool args: ['/usr/bin/gatttool', '--adapter=hci0', '-I', '-t', 'random', '-b', 'E0:C2:75:EE:3F:2C'] buffer (last 100 chars): b'[LE]> \r\n(gatttool:99): GLib-\x1b[1;33mWARNING\x1b[0m : \x1b[34m19:51:57.889\x1b[0m: Invalid file descriptor.\r\n' before (last 100 chars): b'[LE]> \r\n(gatttool:99): GLib-\x1b[1;33mWARNING\x1b[0m : \x1b[34m19:51:57.889\x1b[0m: Invalid file descriptor.\r\n' after: <class 'pexpect.exceptions.TIMEOUT'> match: None

3AXAPOB commented 4 years ago

Поменял ключ на ffffffffffffffffff

result = await result File "/config/custom_components/r4s_kettler/switch.py", line 118, in async_turn_on await self._kettler.firstConnect() File "/config/custom_components/r4s_kettler/init.py", line 470, in firstConnect if self.sendAuth(): File "/config/custom_components/r4skettler/init.py", line 174, in sendAuth self.child.expect("value: ") # wait for response File "/usr/local/lib/python3.7/site-packages/pexpect/spawnbase.py", line 341, in expect timeout, searchwindowsize, async) File "/usr/local/lib/python3.7/site-packages/pexpect/spawnbase.py", line 369, in expect_list return exp.expect_loop(timeout) File "/usr/local/lib/python3.7/site-packages/pexpect/expect.py", line 119, in expect_loop return self.timeout(e) File "/usr/local/lib/python3.7/site-packages/pexpect/expect.py", line 82, in timeout raise TIMEOUT(msg) pexpect.exceptions.TIMEOUT: Timeout exceeded. <pexpect.pty_spawn.spawn object at 0xb09a07f0> command: /usr/bin/gatttool args: ['/usr/bin/gatttool', '--adapter=hci0', '-I', '-t', 'random', '-b', 'E0:C2:75:EE:3F:2C'] buffer (last 100 chars): b' 0x000e 5501ffffffffffffffffffaa\r\n\x1b[0;91mCommand Failed: \x1b[0mDisconnected\r\n[E0:C2:75:EE:3F:2C][LE]> ' before (last 100 chars): b' 0x000e 5501ffffffffffffffffffaa\r\n\x1b[0;91mCommand Failed: \x1b[0mDisconnected\r\n[E0:C2:75:EE:3F:2C][LE]> ' after: <class 'pexpect.exceptions.TIMEOUT'>

mavrikkk commented 4 years ago

первое сообщение: верхняя ошибка исчезла. Появилась вот такая еще ошибка Invalid file descriptor - это при попытке авторизоваться Вот что означает эта ошибка: When the bluetooth device disconnects (due to range, signal strength etc) the underlying cleanup process doesn't get invoked properly - hence the invalid descriptor. See this article for more info: http://www.spinics.net/lists/linux-bluetooth/msg63249.html Simply put the tool doesn't handle unsolicited/unexpected disconnections very well. Try moving your PI and device close to each other, connect with gatttool and then moving further apart - you'll see what I mean.

второе сообщение: опять таймаут при той же авторизации. Все, что написано выше, применимо и тут.

Краткие выводы: что то с сигналом блютус и/или большое расстояние между вашим блютус и чайником. Попробуйте законнектить ближе. Кстати, что за блютус у вас? Если встроенный в малинку, то забудьте про него...на него жалуются все и везде. В офф ветке малинки целая ветка есть. Купите, как я, свисток на али за 100 руб и не мучайтесь (убедитесь, то он поддерживает BLE).

3AXAPOB commented 4 years ago

Попробую поближе поднести. Но ведь баш скрипты работают на этом расстоянии : /

У меня orange pi pc c блютус свистком на чипе Qualcomm CSR8510.

mavrikkk commented 4 years ago

Баш скрипты примитивны донельзя ) они не используют нотификации вообще, теоретически и без авторизации можно. Если не авторизоваться на чайнике, то примерно через 1-2 сек он сбрасывает подключение. Без нотификаций ты никогда не узнаешь, сработала ли команда и не получишь правильно ответ. Скрипты просто пытаются протолкнуть команды как можно быстрее, но с задержкой небольшой (ибо команду чайник должен получить, распарсить и ответить, даже если отвечать некуда). И вот этот баланс скорости и задержек нужно точно подобрать, исходя из железа, расстояния. В модуле же идет аля эмуляция мобильного приложения: то есть я подключаюсь, авторизовываюсь, подписываюсь на уведомления и получаю их впоследствии. Из за того, что работает это через посредника в лице gatttool, да еще и с обратной связью, даже 1 команда превращается в череду событий. И естественно тут уже важны и качество связи и все остальное. Ранее я тоже использовал апельсинку - проблем с ней не замечено. Блютус у меня на каком то CSR чипе, точно не помню. с али за 100 р брал. Кто то недавно отписывался, что взял какой то baseus - отлично работает. У меня расстояние между чайником и малинкой - примерно 4-5 метров по прямой, но разделены стеной (находятся в разных комнатах). Проводил эксперимент: Если человек подходит к чайнику и закрывает его своим телом, то сигнал теряется )) Так что периодически, когда момент синхронизации совпадает с проходом человека мимо чайника, то синхронизация крашится и вылазит в логе ошибка "error update". Не чаще пары раз в день случается. Думаю в чайнике установлен ооооочень слабый блютус. Так что учтите

mavrikkk commented 4 years ago

То есть самая главная проблема - это ответ! Туда на дурака заслать можно что угодно (привет, баш скрипты). Тут играет роль мощность передающего устройства, то есть вашего свистка. И с ней, думаю, все в порядке, как и почти на любом свистке. А вот получить оттуда ответ - задача сложнее, передает уже чайник. У вас все ошибки именно на этом этапе, когда нужно дождаться ответа.

3AXAPOB commented 4 years ago

Перенёс поставил одноплатник с блютусом в 20 сантиметрах от чайника:

File "/config/custom_components/r4s_kettler/switch.py", line 118, in async_turn_on await self._kettler.firstConnect() File "/config/custom_components/r4s_kettler/init.py", line 470, in firstConnect if self.sendAuth(): File "/config/custom_components/r4skettler/init.py", line 174, in sendAuth self.child.expect("value: ") # wait for response File "/usr/local/lib/python3.7/site-packages/pexpect/spawnbase.py", line 341, in expect timeout, searchwindowsize, async) File "/usr/local/lib/python3.7/site-packages/pexpect/spawnbase.py", line 369, in expect_list return exp.expect_loop(timeout) File "/usr/local/lib/python3.7/site-packages/pexpect/expect.py", line 119, in expect_loop return self.timeout(e) File "/usr/local/lib/python3.7/site-packages/pexpect/expect.py", line 82, in timeout raise TIMEOUT(msg) pexpect.exceptions.TIMEOUT: Timeout exceeded. <pexpect.pty_spawn.spawn object at 0xac4ff090> command: /usr/bin/gatttool args: ['/usr/bin/gatttool', '--adapter=hci0', '-I', '-t', 'random', '-b', 'E0:C2:75:EE:3F:2C'] buffer (last 100 chars): b' 0x000e 5512ffffffffffffffffffaa\r\n\x1b[0;91mCommand Failed: \x1b[0mDisconnected\r\n[E0:C2:75:EE:3F:2C][LE]> ' before (last 100 chars): b' 0x000e 5512ffffffffffffffffffaa\r\n\x1b[0;91mCommand Failed: \x1b[0mDisconnected\r\n[E0:C2:75:EE:3F:2C][LE]> ' after: <class 'pexpect.exceptions.TIMEOUT'>

Может я что-то напутал когда код редактировал?

Посмотрите пожалуйста https://pastebin.com/4ZSaAje7

mavrikkk commented 4 years ago

код плюс минус похож на правду. есть по мелочи косяки, но они не критичны. подключайся к консоли апельсинки и вперед:

вводим gatttool --adapter=hci0 -I -t random -b E0:C2:75:EE:3F:2C ждем выполнения...вводим connect должен законнектиться (правда ненадолго) после коннекта вводим: char-write-cmd 0x000c 0100 ждем ответа (скорее всего ничего не будет) вводим: char-write-req 0x000e 5501ffffffffffffffffffaa ждем ответа. возможны ошибки, хрень, так как чайник давно отвалился, пофик главное ввести. дальше вводим: char-write-req 0x000e 550206aa ждем ответа. дальше делаем хитро...все, что ты вводил до этого, сохранилось в быстром вызове и доступно для быстрого ввода по нажатию клавиши "стрелка вверх". листая стрелкой вверх команды вводим все тоже самое заново в той же последовательности, только теперь практически не тратя время ) то есть выбираем последовательно: connect char-write-cmd 0x000c 0100 char-write-req 0x000e 5501ffffffffffffffffffaa char-write-req 0x000e 550206aa после каждой команды ждем ответа и тут же вбиваем следующую. По идее после правильной авторизации он не должен сбрасывать коннект и можно уже не торопиться с командами.

Результаты всей этой порнографии - сюда, будем смотреть

3AXAPOB commented 4 years ago

Свисток с апельсином в 20 см от чайника.

[E0:C2:75:EE:3F:2C][LE]> connect Attempting to connect to E0:C2:75:EE:3F:2C Connection successful [E0:C2:75:EE:3F:2C][LE]> char-write-cmd 0x000c 0100 [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 5501ffffffffffffffffffaa Characteristic value was written successfully Notification handle = 0x000b value: 55 01 ff 00 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 550206aa (gatttool:2196): GLib-WARNING **: 10:46:03.561: Invalid file descriptor.

Command Failed: Disconnected [E0:C2:75:EE:3F:2C][LE]> connect Attempting to connect to E0:C2:75:EE:3F:2C [E0:C2:75:EE:3F:2C][LE]> connect Connection successful [E0:C2:75:EE:3F:2C][LE]> char-write-cmd 0x000c 0100 [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 5501ffffffffffffffffffaa Characteristic value was written successfully Notification handle = 0x000b value: 55 01 ff 00 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 550206aa Characteristic value was written successfully [E0:C2:75:EE:3F:2C][LE]> (gatttool:2196): GLib-WARNING **: 10:47:14.310: Invalid file descriptor.

Misko82 commented 4 years ago

Здраствуйте поддержу товарища ЗАХАРОВА, адаптируйте пожалуйста под чайник RK-M171S-E

mavrikkk commented 4 years ago

на запрос авторизации был ответ от чайника - пошел на фик, с новым годом

усложним задачу...все тоже самое...НО перед отправкой команды char-write-req 0x000e 5501ffffffffffffffffffaa нужно перевести чайник в режим сопряжения, чтоб он в себя мог код записать

так же все логи сюда

3AXAPOB commented 4 years ago

[E0:C2:75:EE:3F:2C][LE]> connect Attempting to connect to E0:C2:75:EE:3F:2C Connection successful [E0:C2:75:EE:3F:2C][LE]> char-write-cmd 0x000c 0100 [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 5501ffffffffffffffffffaa Characteristic value was written successfully Notification handle = 0x000b value: 55 01 ff 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 40 0f 00 00 00 00 00 00 80 00 00 aa

3AXAPOB commented 4 years ago

Получилось с другим ключом

[E0:C2:75:EE:3F:2C][LE]> connect Attempting to connect to E0:C2:75:EE:3F:2C Connection successful [E0:C2:75:EE:3F:2C][LE]> char-write-cmd 0x000c 0100 Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 3d 0f 00 00 00 00 00 00 80 00 00 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 5501ffb54c75b1b40c88efaa Characteristic value was written successfully Notification handle = 0x000b value: 55 01 ff 02 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 550206aa Characteristic value was written successfully Notification handle = 0x000b value: 55 02 06 00 00 00 00 01 3d 0f 00 00 00 00 00 00 80 00 00 aa [E0:C2:75:EE:3F:2C][LE]>

mavrikkk commented 4 years ago

судя по ответу, у тебя 00 - пошел на фиг, а 02 - все хорошо, а у меня 00 - пошел на фиг, а 01 - все хорошо. Нужно исправить в функции sendAuth. Исправляй и пробуй. Только не забудь отключиться от чайника (команда exit).Ключ вставляй с лога, который подошел, он уже записан в чайнике. Недавно кипятил? 61 градус вроде у тебя было на момент лога ))

mavrikkk commented 4 years ago

Единственное, мне нифика не понятны записи: Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 40 0f 00 00 00 00 00 00 80 00 00 aa из первого лога...откуда? кто запрашивал статус, что он тебе ответил? и во втором логе он тебе ответил: Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 3d 0f 00 00 00 00 00 00 80 00 00 aa раньше, чем ты спросил...какая то фигня полная. либо ты уже ранее подписался на него и exit не написал...перезагрузи полностью апельсинку на всякий

3AXAPOB commented 4 years ago

Ну что первый успех! 😅😅😅

https://imageup.ru/img112/3554294/a6fc937d-2777-4e3a-89ae-03118822c9a3.jpg.html

Пока что не получилось включить и в логе пишет update failed. Но уже огромный прогресс!

Убрал трай в async_update. Исчезли все ошибки. Просто ничего не происходит.

Актуальный код тут https://pastebin.com/ExvJZQxg

Похоже что обновление температуры происходит только после пререзагрузки холм асистанта. В другое время update состояния и включение чайника не происходит.

mavrikkk commented 4 years ago

в коде лишние переменные: self._Watts = 0 self._alltime = 0 self._times = 0 self._boiltime = '80' self._rgb1 = '0000ff' self._rgb2 = 'ff0000' self._rand = '5e' self._usebacklight = True self._hold = False

лишние функции: calcMidColor rgbhex_to_hs hs_to_rgbhex theLightIsOn sendOn sendSync sendStat sendUseBackLight sendGetLights sendSetLights readNightColor startNightColor stopNightColor хоть многие из них и закомменчены, но все же...удали, мешают восприятию

в функции async_update верни все взад! все трай

в функции sendAuth верни назад трай (не забывай про правило отсутпов! 4 пробела)

в функции connect верни назад трай. таймаут поставь по 1 сек...можешь максимум 2

функция modeOn неправильная! если комментишь строчку, то все остальные сдвинь влево на 4 пробела!!! то есть строчки if self.sendStatus(): и answ = True сдвинь на 4 пробела влево

функция firstConnect тоже неправильная. по той же причине. строчки if self.sendStatus(): и self._time_upd = time.strftime("%H:%M") и answ = True сдвинь на 4 пробела влево

в функции modeUpdate удали строчки if self._mode == '01' and self._status == '02' and self._temp >= self._tgtemp and self._hold == False: self.modeOff() этот костыль не нужен тебе

в файле switch.py удали класс RedmondSwitchBacklight и RedmondSwitchHold а также строчки async_add_entities([RedmondSwitchBacklight(kettler)]) async_add_entities([RedmondSwitchHold(kettler)])

после этого перезагрузи и попробуй...если не заработает, то дальше в консоли работать надо

3AXAPOB commented 4 years ago

Поправил как вы написали. Обновление статуса заработало на постоянной основе.

Система ругалась на отсутствие переменных которые были удалены в init.py. Почистил sensor.py он теперь почти пустой.

При попытке включить ругался water_heater.py на if lightIsOn: удалил.

Теперь при попытке включить ничего не происходит. В логе пусто.

UPD: Не пусто Уровень: ERROR Thu Feb 13 2020 14:34:57 GMT+0300 (Москва, стандартное время) error composite modeOn

Исправленные файлы init.py https://pastebin.com/u8YhVwTZ water_heater.py https://pastebin.com/DhueGDVa sensor.py https://pastebin.com/3KQxHx7M

mavrikkk commented 4 years ago

sensor не до конца почистил. water_heater закомменченые смело удаляй в init в функции reset остались левые переменные, в функцию modeUpdate верни try

включи чайник руками, подожди, пока статус синхронизируется и попробуй выключить через home assistant.выключение должно работать. с modeOn надо убрать try и смотреть лог

mavrikkk commented 4 years ago

в sensor удаляй

@property def device_state_attributes(self): attrs = {} return attrs

ATTR_WATTS = 'energy spent' ATTR_ALLTIME = 'time working' ATTR_TIMES = 'amount of starts' ATTR_WATTS_MEASURE = 'kW * h' ATTR_ALLTIME_MEASURE = 'h' ATTR_TIMES_MEASURE = 'times'

в init удаляй функцию theKettlerIsOn(self), тоже нигде не используется...

3AXAPOB commented 4 years ago

Ошибка при попытке включить чайник:

pexpect.exceptions.TIMEOUT: Timeout exceeded. <pexpect.pty_spawn.spawn object at 0xac7ca150> command: /usr/bin/gatttool args: ['/usr/bin/gatttool', '--adapter=hci0', '-I', '-t', 'random', '-b', 'E0:C2:75:EE:3F:2C'] buffer (last 100 chars): b' \rCharacteristic value was written successfully\r\n\x1b[0;94m[E0:C2:75:EE:3F:2C]\x1b[0m[LE]> ' before (last 100 chars): b' \rCharacteristic value was written successfully\r\n\x1b[0;94m[E0:C2:75:EE:3F:2C]\x1b[0m[LE]> ' after: <class 'pexpect.exceptions.TIMEOUT'>

init.py https://pastebin.com/7GMZu31W

mavrikkk commented 4 years ago

я думаю, ошибка в self.sendMode(mode, temp): ибо остальные функции одинаковы с update а update работает. возвращай try на место.

  1. Выключение чайника проверил? Работает?
  2. подключайся к консоли апельсинки и вперед:

gatttool --adapter=hci0 -I -t random -b E0:C2:75:EE:3F:2C

connect

char-write-cmd 0x000c 0100

char-write-req 0x000e 5501ffffffffffffffffffaa

char-write-req 0x000e 550206aa

char-write-req 0x000e 55030500000000aa

Правила ввода команд те же, что и раньше. Единственное, с выключенным HomeAssistant все делай, чтоб не двоились и не троились запросы и ответы

Чайник должен включиться... Если не включится, то добавь следом команду: char-write-req 0x000e 550403aa

Результаты всей этой порнографии - сюда, будем смотреть

mavrikkk commented 4 years ago

char-write-req 0x000e 5501ffffffffffffffffffaa ключ только на свой замени

3AXAPOB commented 4 years ago

Выключаться из хоум ассистанта не захотел.

Включился после команды char-write-req 0x000e 550403aa

[E0:C2:75:EE:3F:2C][LE]> connect Attempting to connect to E0:C2:75:EE:3F:2C Connection successful [E0:C2:75:EE:3F:2C][LE]> char-write-cmd 0x000c 0100 [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 5501ffb54c75b1b40c88efaa Characteristic value was written successfully Notification handle = 0x000b value: 55 01 ff 02 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 55030500000000aa Characteristic value was written successfully [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 550403aa Characteristic value was written successfully Notification handle = 0x000b value: 55 04 03 01 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 5f 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 60 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 61 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 62 0f 00 02 00 00 00 00 80 00 00 aa

3AXAPOB commented 4 years ago

Как мне добавить это char-write-req 0x000e 550403aa в код?

mavrikkk commented 4 years ago
  1. добавить в в ваш инит функцию def sendOn(self) из моего инит

  2. поправить вашу функцию async def modeOn, добавив строчку if self.sendOn(): между вашими строчками if self.sendMode(mode, temp): и if self.sendStatus(): с правильным отступом

mavrikkk commented 4 years ago

если все работать будет, то останется только выключение...хотя странно, что не работает...будем через консоль смотреть

3AXAPOB commented 4 years ago

Сделал

error composite modeOn 14:19 custom_components/r4s_kettler/init.py (ERROR)

Мой инит https://pastebin.com/x656abHF

УПД:

Заработало!!!! Оказывается в начале нужно было температуру выбрать а потом включить electric?

mavrikkk commented 4 years ago

нет.

выбор температуры автоматом включает чайник.. с учетом задержки на отправку команд и получение ответа

3AXAPOB commented 4 years ago

Итог такой: 1.Чайник включается 2.Чайник выключается 3.Чайник передаёт свою температуру 4.Чайник сообщает свой статус включено, выключено.

Проблема при возникновении ошибки: buffer (last 100 chars): b'LE]> \r\n(gatttool:168): GLib-\x1b[1;33mWARNING\x1b[0m **: \x1b[34m16:59:23.924\x1b[0m: Invalid file descriptor.\r\n' чайник не включится или не выключится по команде пользователя.

Можно что-то сделать чтобы обходить эту ошибку? Реконект какой-то делать при ее возникновении?

mavrikkk commented 4 years ago
  1. Конечно можно...нужно только самая малость - узнать причину возникновения.

  2. Реконнект предусмотрен - команда апдейт выполняется каждые 30 или 60 сек. По идее она должна установить все как есть. Для ручного управления есть кнопка authorize. Если у вас где то что то вылетает окончательно, значит у вас где то удален и не вернулся на место try except. Посмотрите и добавьте. Все, что должно случиться при отвале чайника - это ошибка в логе HA по типу error connect.

  3. Другое дело, что правильных причины отвала должно быть 2: чайник сняли с подставки или при передаче данных возникла помеха(например, человек телом загородил чайник). Если у вас отвалы частые - это в любом случае неправильно. Нужно точно узнать ПОЧЕМУ вываливается та ошибка: предпосылки, условия: когда, где, в каких ситуациях, чем эта ситуация отличается от той, в которой все работало и тд и тп. Ну и лог полный.

3AXAPOB commented 4 years ago
  1. Я не увидел взаимосвязи между расстоянием и возникновением ошибки Invalid file descriptor, что в 20 сантиметрах, что 4 метрах она все равно возникает.
  2. Реконнет есть, по графику видно что данные по температуре обновляются круглосуточно и ошибки в логе есть когда не получается.

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

  1. Как я уже написал, я не увидел взаимосвязи между расстоянием и обрывом связи. Разве что я не пробовал переставить свисток в другой порт апельсина.
mavrikkk commented 4 years ago

тогда только пытаться через консоль

  1. Обязательно выключаем homeassistant
  2. через консоль логинимся на чайнике:

gatttool --adapter=hci0 -I -t random -b E0:C2:75:EE:3F:2C connect char-write-cmd 0x000c 0100 char-write-req 0x000e 5501ffb54c75b1b40c88efaa

  1. дальше можно и даже нужно не торопиться...вводим различные команды и смотрим за реакцией чайника:

а. получаем данные char-write-req 0x000e 550206aa

б. передаем режим работы кипячение char-write-req 0x000e 55030500000000aa

в. включаем char-write-req 0x000e 550403aa

г. получаем данные char-write-req 0x000e 550506aa

д. выключаем char-write-req 0x000e 550604aa

е. получаем данные char-write-req 0x000e 550706aa

ж. передаем режим работы нагрев до 70 char-write-req 0x000e 55080501004600aa

з. включаем char-write-req 0x000e 550903aa

и. получаем данные char-write-req 0x000e 550a06aa

к. выключаем char-write-req 0x000e 550b04aa

смотрим лог

3AXAPOB commented 4 years ago

root@orangepipcplus:~# gatttool --adapter=hci0 -I -t random -b E0:C2:75:EE:3F:2C [E0:C2:75:EE:3F:2C][LE]> connect Attempting to connect to E0:C2:75:EE:3F:2C Connection successful [E0:C2:75:EE:3F:2C][LE]> char-write-cmd 0x000c 0100 [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 5501ffb54c75b1b40c88efaa Characteristic value was written successfully Notification handle = 0x000b value: 55 01 ff 02 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 550206aa Characteristic value was written successfully Notification handle = 0x000b value: 55 02 06 00 00 00 00 01 42 0f 00 00 00 00 00 00 80 00 00 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 55030500000000aa Characteristic value was written successfully [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 550403aa Characteristic value was written successfully Notification handle = 0x000b value: 55 04 03 01 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 42 0f 00 02 00 00 00 00 80 00 00 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 550506aa Characteristic value was written successfully Notification handle = 0x000b value: 55 05 06 00 00 00 00 01 42 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 43 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 44 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 45 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 46 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 47 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 48 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 49 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 4a 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 4b 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 4c 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 4d 0f 00 02 00 00 00 00 80 00 00 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 550604aa Characteristic value was written successfully Notification handle = 0x000b value: 55 06 04 01 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 4d 0f 00 00 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 4e 0f 00 00 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 4f 0f 00 00 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 50 0f 00 00 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 51 0f 00 00 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 52 0f 00 00 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 53 0f 00 00 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 54 0f 00 00 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 55 0f 00 00 00 00 00 00 80 00 00 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 550706aa Characteristic value was written successfully Notification handle = 0x000b value: 55 07 06 00 00 00 00 01 55 0f 00 00 00 00 00 00 80 00 00 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 55080501004600aa Characteristic value was written successfully Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 54 0f 00 00 00 00 00 00 80 00 00 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 550903aa Characteristic value was written successfully Notification handle = 0x000b value: 55 09 03 01 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 54 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 55 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 54 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 55 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 56 0f 00 02 00 00 00 00 80 00 00 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 550a06aa Characteristic value was written successfully Notification handle = 0x000b value: 55 0a 06 00 00 00 00 01 56 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 57 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 58 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 59 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 5a 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 5b 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 5c 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 5d 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 5e 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 5f 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 60 0f 00 02 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 61 0f 00 02 00 00 00 00 80 00 00 aa [E0:C2:75:EE:3F:2C][LE]> char-write-req 0x000e 550b04aa Characteristic value was written successfully Notification handle = 0x000b value: 55 0b 04 01 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 61 0f 00 00 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 62 0f 00 00 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 63 0f 00 00 00 00 00 00 80 00 00 aa Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 64 0f 00 00 00 00 00 00 80 00 00 aa [E0:C2:75:EE:3F:2C][LE]>

Что удивительно во время всех этих манипуляций ниодного варнинга не проскочило.

mavrikkk commented 4 years ago

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

Notification handle = 0x000b value: 55 00 06 00 00 00 00 01 64 0f 00 00 00 00 00 00 80 00 00 aa

мой чайник шлет такие пакеты ТОЛЬКО когда его об этом просят.

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