Hcpy - Interface with Home Connect appliances in Python

Related tags

Deep Learning hcpy
Overview

dishwasher installed in a kitchen

Interface with Home Connect appliances in Python

This is a very, very beta interface for Bosch-Siemens Home Connect devices through their local network connection. It has some tools to find the TLS PSK (Pre-shared Key) that is used to allow local access, and a Python script that can construct the proper Websocket interface to subscribe to events.

WARNING: This is not ready for prime time!

The dishwasher has a local HTTPS port open (and the dryer seems to have unencrypted HTTP). Attempting to connect to the HTTPS port with curl results in a cryptic protocol error due to the non-standard cipher selection, ECDHE-PSK-CHACHA20-POLY1305. PSK also requires that both sides agree on a symetric key, so it is necessary to figure out what that key is before any further progress can be made.

Finding the PSK

application setup screen

You will need to set the dishwasher to "Local network only" in the setup application so that your phone will connect directly to it, rather than going through the cloud services.

You'll also need a rooted Android phone running frida-server and the find-psk.frida script. This will hook the callback from the OpenSSL library hcp::client_psk_callback that is called when OpenSSL has made a connection and now needs to establish the PSK.

frida --no-pause -f com.bshg.homeconnect.android.release -U -l find-psk.frida

It should start the Home Connect application and eventually print a message like:

psk callback hint 'HCCOM_Local_App'
psk 32 0x6ee63fb2f0
           0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F  0123456789ABCDEF
00000000  0e c8 1f d8 c6 49 fa d8 bc e7 fd 34 33 54 13 d4  .....I.....43T..
00000010  73 f9 2e 01 fc d8 26 80 49 89 4c 19 d7 2e cd cb  s.....&.I.L.....

Which gives you the 32-byte PSK value to copy into the hcpy program.

SSL logging

The Frida script will also dump all of the SSL traffic so that you can see different endpoints and things. Not much is documented yet.

Note that the TX from the phone on the websocket is "masked" with an repeating 4-byte XOR that is sent in the first part of each messages. The script could be augmented to decode those as well. The replies from the device are not masked so they can be read in the clear.

hcpy

The hcpy tool can contact your device, and if the PSK is correct, it will register for notification of events.

RX: {'sID': 2354590730, 'msgID': 3734589701, 'resource': '/ei/initialValues', 'version': 2, 'action': 'POST', 'data': [{'edMsgID': 3182729968}]}
TX: {"sID":2354590730,"msgID":3734589701,"resource":"/ei/initialValues","version":2,"action":"RESPONSE","data":[{"deviceType":"Application","deviceName":"py-hca","deviceID":"1234"}]}
TX: {"sID":2354590730,"msgID":3182729968,"resource":"/ci/services","version":1,"action":"GET"}
TX: {"sID":2354590730,"msgID":3182729969,"resource":"/iz/info","version":1,"action":"GET"}
TX: {"sID":2354590730,"msgID":3182729970,"resource":"/ei/deviceReady","version":2,"action":"NOTIFY"}
RX: {'sID': 2354590730, 'msgID': 3182729968, 'resource': '/ci/services', 'version': 1, 'action': 'RESPONSE', 'data': [{'service': 'ci', 'version': 3}, {'service': 'ei', 'version': 2}, {'service': 'iz', 'version': 1}, {'service': 'ni', 'version': 1}, {'service': 'ro', 'version': 1}]}
RX: {'sID': 2354590730, 'msgID': 3182729969, 'resource': '/iz/info', 'version': 1, 'action': 'RESPONSE', 'data': [{'deviceID': '....', 'eNumber': 'SX65EX56CN/11', 'brand': 'SIEMENS', 'vib': 'SX65EX56CN', 'mac': '....', 'haVersion': '1.4', 'swVersion': '3.2.10.20200911163726', 'hwVersion': '2.0.0.2', 'deviceType': 'Dishwasher', 'deviceInfo': '', 'customerIndex': '11', 'serialNumber': '....', 'fdString': '0201', 'shipSki': '....'}]}

Feature UID mapping

There are other things that can be hooked in the application to get the mappings of the uid to actual menu settings and XML files of the configuration parameters.

In the xml/ directory are some of the device descriptions and feature maps that the app downloads from the Home Connect servers. Note that the XML has unadorned hex, while the websocket messages are in decimal.

For instance, when the dishwasher door is closed and then re-opened, it sends the messages for 'uid':512, which is 0x020F hex:

RX: {... 'data': [{'uid': 527, 'value': 1}]}
RX: {... 'data': [{'uid': 527, 'value': 0}]}

In the xml/dishwasher-description.xml there is a statusList that says uid 0x020f is a readonly value that uses enum 0x0201:

">
    
  

In the xml/dishwasher-featuremap.xml there is a mapping of feature reference UIDs to names:

BSH.Common.Status.DoorState">
    
   
    BSH.Common.Status.DoorState
   

as well as mappings of enum ids to enum names and values:

Open Closed ">
    
   
      
    
     Open
    
      
    
     Closed
    
    
   
Comments
  • (docs) Does the unencrypted port for the dryer require the PSK, too?

    (docs) Does the unencrypted port for the dryer require the PSK, too?

    Hi, thank you for your effort. Does the dryer require the PSK, too?

    I tried applying your code on an EQ.9 plus connect s500 coffee maker, and first scanned where to connect:

    $ sudo nmap -sS 192.168.XX.XX
    Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-01 09:43 CET
    Nmap scan report for 192.168.XX.XX
    Host is up (0.099s latency).
    Not shown: 999 closed tcp ports (reset)
    PORT   STATE SERVICE
    80/tcp open  http
    MAC Address: 68:A4:0E:XX:XX:XX (BSH Hausgerte GmbH)
    
    Nmap done: 1 IP address (1 host up) scanned in 40.94 seconds
    

    As you mentioned that the connection was unencrypted, I assumed that no PSK is needed, but dropping the SSL socket from your code yields the following result:

    --- request header ---
    GET /homeconnect HTTP/1.1
    Upgrade: websocket
    Host: 192.168.XX.XX
    Origin: 
    Sec-WebSocket-Key: qnpSjK5rTYFwtZSS8Y1eIg==
    Sec-WebSocket-Version: 13
    Connection: Upgrade
    
    
    -----------------------
    --- response header ---
    HTTP/1.1 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: lpgdCwDkx9WcT3UBrMEJmotBgHg=
    -----------------------
    ++Rcv raw: b'\x82~\x00\x90b\xc1B\xcfMe\xcf\xe6a\xfa\x19#\xff;\xb0\xc04\x9e\xd7\xeb&\xb3\xed\x91F\xb0\xf8\xc9G\x08\xd9\xc0\xfabj\x18l\xe8\x1fQ\x15\xf8 f\x16\xf5\xd3\xe3\x8dx\xe85A\xb1|2\x024\xfcS\x18>\xf1\xdb|U~\x92\x0e\xa2n\xc0\xcb\x05\xbc\x89\x92\x17`\xf6Z5\x03!\xcd\xe8"\'\xf1n"\xf4i,\x1d,\x80=\x1a\x94z-\xc0x\xa5\x01\x8c:\xec\x94\x94\x03r5\xa7\x94\x90=,N\xec\tqK\x1d=\xe2M\x9e$\xb5\x90O\xaa\xf3\xa5\x00T\xab\x04~\x88\x06\xdf'
    ++Rcv decoded: fin=1 opcode=2 data=b'b\xc1B\xcfMe\xcf\xe6a\xfa\x19#\xff;\xb0\xc04\x9e\xd7\xeb&\xb3\xed\x91F\xb0\xf8\xc9G\x08\xd9\xc0\xfabj\x18l\xe8\x1fQ\x15\xf8 f\x16\xf5\xd3\xe3\x8dx\xe85A\xb1|2\x024\xfcS\x18>\xf1\xdb|U~\x92\x0e\xa2n\xc0\xcb\x05\xbc\x89\x92\x17`\xf6Z5\x03!\xcd\xe8"\'\xf1n"\xf4i,\x1d,\x80=\x1a\x94z-\xc0x\xa5\x01\x8c:\xec\x94\x94\x03r5\xa7\x94\x90=,N\xec\tqK\x1d=\xe2M\x9e$\xb5\x90O\xaa\xf3\xa5\x00T\xab\x04~\x88\x06\xdf'
    error handling msg 'utf-8' codec can't decode byte 0xc1 in position 1: invalid start byte b'b\xc1B\xcfMe\xcf\xe6a\xfa\x19#\xff;\xb0\xc04\x9e\xd7\xeb&\xb3\xed\x91F\xb0\xf8\xc9G\x08\xd9\xc0\xfabj\x18l\xe8\x1fQ\x15\xf8 f\x16\xf5\xd3\xe3\x8dx\xe85A\xb1|2\x024\xfcS\x18>\xf1\xdb|U~\x92\x0e\xa2n\xc0\xcb\x05\xbc\x89\x92\x17`\xf6Z5\x03!\xcd\xe8"\'\xf1n"\xf4i,\x1d,\x80=\x1a\x94z-\xc0x\xa5\x01\x8c:\xec\x94\x94\x03r5\xa7\x94\x90=,N\xec\tqK\x1d=\xe2M\x9e$\xb5\x90O\xaa\xf3\xa5\x00T\xab\x04~\x88\x06\xdf'
    ++Rcv raw: b'\x88\t\x03\xeaTimeout'
    ++Rcv decoded: fin=1 opcode=8 data=b'\x03\xeaTimeout'
    ++Sent raw: b'\x88\x82jx\xd6mi\x90'
    ++Sent decoded: fin=1 opcode=8 data=b'\x03\xe8'
    Traceback (most recent call last):
      File "/home/richard/hcpy/hcpy", line 155, in <module>
        buf = ws.recv()
      File "/nix/store/k0qjfvyrw4h8v3g3lji039fq9mjffjq5-python3.9-websocket-client-1.2.1/lib/python3.9/site-packages/websocket/_core.py", line 354, in recv
        opcode, data = self.recv_data()
      File "/nix/store/k0qjfvyrw4h8v3g3lji039fq9mjffjq5-python3.9-websocket-client-1.2.1/lib/python3.9/site-packages/websocket/_core.py", line 377, in recv_data
        opcode, frame = self.recv_data_frame(control_frame)
      File "/nix/store/k0qjfvyrw4h8v3g3lji039fq9mjffjq5-python3.9-websocket-client-1.2.1/lib/python3.9/site-packages/websocket/_core.py", line 396, in recv_data_frame
        frame = self.recv_frame()
      File "/nix/store/k0qjfvyrw4h8v3g3lji039fq9mjffjq5-python3.9-websocket-client-1.2.1/lib/python3.9/site-packages/websocket/_core.py", line 435, in recv_frame
        return self.frame_buffer.recv_frame()
      File "/nix/store/k0qjfvyrw4h8v3g3lji039fq9mjffjq5-python3.9-websocket-client-1.2.1/lib/python3.9/site-packages/websocket/_abnf.py", line 337, in recv_frame
        self.recv_header()
      File "/nix/store/k0qjfvyrw4h8v3g3lji039fq9mjffjq5-python3.9-websocket-client-1.2.1/lib/python3.9/site-packages/websocket/_abnf.py", line 293, in recv_header
        header = self.recv_strict(2)
      File "/nix/store/k0qjfvyrw4h8v3g3lji039fq9mjffjq5-python3.9-websocket-client-1.2.1/lib/python3.9/site-packages/websocket/_abnf.py", line 372, in recv_strict
        bytes_ = self.recv(min(16384, shortage))
      File "/nix/store/k0qjfvyrw4h8v3g3lji039fq9mjffjq5-python3.9-websocket-client-1.2.1/lib/python3.9/site-packages/websocket/_core.py", line 519, in _recv
        return recv(self.sock, bufsize)
      File "/nix/store/k0qjfvyrw4h8v3g3lji039fq9mjffjq5-python3.9-websocket-client-1.2.1/lib/python3.9/site-packages/websocket/_socket.py", line 125, in recv
        raise WebSocketConnectionClosedException(
    websocket._exceptions.WebSocketConnectionClosedException: Connection to remote host was lost.
    

    It looks a lot like the PSK is needed. Would be great if you could clarify this :) I might also be able to help with support for the mentioned coffee maker, so feel free to ping me if you want (just didn't have time to get the PSK right now).

    opened by CRTified 13
  • hc-login fails with HTTP 403 even though credentials are correct

    hc-login fails with HTTP 403 even though credentials are correct

    I've added a print statement after the "Did not get a redirect" message to print both the status code as well as the response text and headers:

    {
      "error": "access_denied",
      "error_description": "login session expired"
    }
    {'Date': 'Sun, 06 Mar 2022 22:26:07 GMT', 'Content-Type': 'application/json', 'Content-Length': '78', 'Connection': 'keep-alive', 'access-control-allow-origin': '*', 'access-control-allow-methods': 'GET,POST,OPTIONS,PUT,DELETE', 'access-control-allow-credentials': 'true', 'access-control-allow-headers': 'Authorization,Content-Type,Accept,Cache-Control,Last-Event-ID,If-Modified-Since,X-Requested-With,X-Events-Facade,User-Agent', 'referrer-policy': 'origin', 'x-frame-options': 'sameorigin', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block', 'api-gateway-service': 'api-gateway', 'hc-env': 'EU-PRD', 'x-vcap-request-id': '1a9e8b59-a350-4e59-5ed9-5abbc74d3b98'}
    

    Do you have any idea on how to debug this/what I can check? Logging in with the same credentials on my phone works and the app is usable there.

    opened by trilader 8
  • Reading out encryption keys still working?

    Reading out encryption keys still working?

    Hi everybody,

    maybe just a short (or stupid) question: I tried to follow your approach to read out the encryption keys in order to establish a local websocket connection to my device (a clothes washer). However, the ReadAccount scope is making trouble, throwing an authorization exception "given scope doesn't match requested scope". Furthermore, i cannot find the ReadAccount scope in documentation, at least not on this page: https://api-docs.home-connect.com/authorization?#authorization-scopes

    I was also not able to find the https://prod.reu.rest.homeconnectegw.com/ endpoint in any documentation. Where do you guys found that information?

    If i leave the ReadAccount scope out, i get my bearer token and i am able to communicate with the home connect servers. Unfortunately, i was looking forward to the local communication and to skip the home connect servers.

    Am i missing something? Or have there been some changes in the API?

    Thanks for your effort and i am really looking forward to your replies.

    opened by Eroli 5
  • Login flow and device credentials

    Login flow and device credentials

    Since we don't want everyone to have to root their android phone to observe the PSK and IV for talking to their devices, we should track the login flow from the app and replicate it in a python tool.

    opened by osresearch 5
  • Encryption issue: Is the IV updated?

    Encryption issue: Is the IV updated?

    Hi everybody,

    i am currently working on a C# port of this nice project. I am working with a WAV28G40 washer from Bosch and i am facing a strange issue.

    • I can successfully connect to the washer and receive the welcome msg (resource: /ei/initialValues).

    • I can successfully respond to that message with the RESPONSE action. The washing machine should now answer with the registeredDevices

    • When i receive the next (2nd) message from the washer, the first 16 bytes are broken. The received message starts like this ?,?S???↕??→?7@?"msgID":216593xxx,"resource":"/ci/registeredDevices", ... Based on this error I assume this should be an issue with the IV, since the remaining message is decrypted successfully. However, i am not able to find any difference to the python script. Therefore, i have some open questions looking to your feedback:

    • Is the IV updated in any way or is the same one used for the whole communication?

    • If the IIV is updated, how does this take place?

    If you have any hints for me regarding this error, please let me know :-)

    opened by Eroli 3
  • authentication failed due to new authentication with SingleKey ID?

    authentication failed due to new authentication with SingleKey ID?

    Connecting to home connect fails, I think because a new authentication is used. The login page is at 'https://singlekey-id.com/auth/en-us/log-in/'

    When checking for the redirect page (HTTP 302) now HTTP 200 is returned)

    opened by Vic-s 7
  • Error  [SSL: NO_CIPHERS_AVAILABLE] no ciphers available (_ssl.c:1129)

    Error [SSL: NO_CIPHERS_AVAILABLE] no ciphers available (_ssl.c:1129)

    Hi there!

    A colleague is trying your library but gets the following error:

    ERROR BOSCH-Dishwasher-012030517384011330 [SSL: NO_CIPHERS_AVAILABLE] no ciphers available (_ssl.c:1129)

    Is this related to the thing you mention in the README? so a special hacked version of sslpsk is used to establish the connection

    Is there something we're doing wrong?

    Thanks for any suggestion!

    Setup: python 3.9.13 OpenSSL 3.0.4 macOS

    opened by themilkman 0
  • hc-login should save intermediate files

    hc-login should save intermediate files

    The hc-login should (or include in the config) information about the home connect account so that the XML can be reprocessed or manual experimentation with the REST endpoints.

    opened by osresearch 0
  • Coffee Machine (Siemens TI9558X1DE, EQ.9 plus connect s500) logs

    Coffee Machine (Siemens TI9558X1DE, EQ.9 plus connect s500) logs

    I did not want to spam #2 as it becomes off-topic. I've attached the (commented) log of hc2mqtt for:

    1. Turning the coffee machine on
    2. Making an Americano
    3. Refilling the water tank
    4. Making a Cappucchino
    5. Cleaning the Milk system
    6. Shutting down

    I hope this helps :)

    making-coffee.log

    opened by CRTified 1
Owner
Trammell Hudson
I like to take things apart.
Trammell Hudson
ROS-UGV-Control-Interface - Control interface which can be used in any UGV

ROS-UGV-Control-Interface Cam Closed: Cam Opened:

Ahmet Fatih Akcan 1 Nov 4, 2022
Aligning Latent and Image Spaces to Connect the Unconnectable

About This repo contains the official implementation of the Aligning Latent and Image Spaces to Connect the Unconnectable paper. It is a GAN model whi

Ivan Skorokhodov 203 Jan 3, 2023
This repo is the code release of EMNLP 2021 conference paper "Connect-the-Dots: Bridging Semantics between Words and Definitions via Aligning Word Sense Inventories".

Connect-the-Dots: Bridging Semantics between Words and Definitions via Aligning Word Sense Inventories This repo is the code release of EMNLP 2021 con

null 12 Nov 22, 2022
Home repository for the Regularized Greedy Forest (RGF) library. It includes original implementation from the paper and multithreaded one written in C++, along with various language-specific wrappers.

Regularized Greedy Forest Regularized Greedy Forest (RGF) is a tree ensemble machine learning method described in this paper. RGF can deliver better r

RGF-team 364 Dec 28, 2022
a spacial-temporal pattern detection system for home automation

Argos a spacial-temporal pattern detection system for home automation. Based on OpenCV and Tensorflow, can run on raspberry pi and notify HomeAssistan

Angad Singh 133 Jan 5, 2023
Irrigation controller for Home Assistant

Irrigation Unlimited This integration is for irrigation systems large and small. It can offer some complex arrangements without large and messy script

Robert Cook 176 Jan 2, 2023
My personal Home Assistant configuration.

About This is my personal Home Assistant configuration. My guiding princile is to have full local control of all my devices. I intend everything to ru

Chris Turra 13 Jun 7, 2022
This is the official code release for the paper Shape and Material Capture at Home

This is the official code release for the paper Shape and Material Capture at Home. The code enables you to reconstruct a 3D mesh and Cook-Torrance BRDF from one or more images captured with a flashlight or camera with flash.

null 89 Dec 10, 2022
A PyTorch implementation for Unsupervised Domain Adaptation by Backpropagation(DANN), support Office-31 and Office-Home dataset

DANN A PyTorch implementation for Unsupervised Domain Adaptation by Backpropagation Prerequisites Linux or OSX NVIDIA GPU + CUDA (may CuDNN) and corre

null 8 Apr 16, 2022
Dahua Camera and Doorbell Home Assistant Integration

Home Assistant Dahua Integration The Dahua Home Assistant integration allows you to integrate your Dahua cameras and doorbells in Home Assistant. It's

Ronnie 216 Dec 26, 2022
🗣️ Microsoft Edge TTS for Home Assistant, no need for app_key

Microsoft Edge TTS for Home Assistant This component is based on the TTS service of Microsoft Edge browser, no need to apply for app_key. Install Down

null 152 Dec 31, 2022
A Home Assistant custom component for Lobe. Lobe is an AI tool that can classify images.

Lobe This is a Home Assistant custom component for Lobe. Lobe is an AI tool that can classify images. This component lets you easily use an exported m

Kendell R 4 Feb 28, 2022
Analysing poker data from home games with friends

Poker Game Analysis Analysing poker data from home games with friends. Not a lot of data is collected, so this project is primarily focussed on descri

Stavros Karmaniolos 1 Oct 15, 2022
Price-Prediction-For-a-Dream-Home - A machine learning based linear regression trained model for house price prediction.

Price-Prediction-For-a-Dream-Home ROADMAP TO THIS LINEAR REGRESSION BASED HOUSE PRICE PREDICTION PREDICTION MODEL Import all the dependencies of the p

DIKSHA DESWAL 1 Dec 29, 2021
Public scripts, services, and configuration for running a smart home K3S network cluster

makerhouse_network Public scripts, services, and configuration for running MakerHouse's home network. This network supports: TODO features here For mo

Scott Martin 1 Jan 15, 2022
Speech Recognition is an important feature in several applications used such as home automation, artificial intelligence

Speech Recognition is an important feature in several applications used such as home automation, artificial intelligence, etc. This article aims to provide an introduction on how to make use of the SpeechRecognition and pyttsx3 library of Python.

RISHABH MISHRA 1 Feb 13, 2022
Nest Protect integration for Home Assistant. This will allow you to integrate your smoke, heat, co and occupancy status real-time in HA.

Nest Protect integration for Home Assistant Custom component for Home Assistant to interact with Nest Protect devices via an undocumented and unoffici

Mick Vleeshouwer 175 Dec 29, 2022
High performance, easy-to-use, and scalable machine learning (ML) package, including linear model (LR), factorization machines (FM), and field-aware factorization machines (FFM) for Python and CLI interface.

What is xLearn? xLearn is a high performance, easy-to-use, and scalable machine learning package that contains linear model (LR), factorization machin

Chao Ma 3k Jan 3, 2023
High performance, easy-to-use, and scalable machine learning (ML) package, including linear model (LR), factorization machines (FM), and field-aware factorization machines (FFM) for Python and CLI interface.

What is xLearn? xLearn is a high performance, easy-to-use, and scalable machine learning package that contains linear model (LR), factorization machin

Chao Ma 2.8k Feb 12, 2021