Code Monkey home page Code Monkey logo

hcpy's Introduction

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. Unlike most IoT devices that have a reputation for very bad security, BSG seem to have done a decent job of designing their system, especially since they allow a no-cloud local control configuration. The protocols seem sound, use well tested cryptographic libraries (TLS PSK with modern ciphres) or well understood primitives (AES-CBC with HMAC), and should prevent most any random attacker on your network from being able to take over your appliances to mine cryptocurrency.

WARNING: This tool not ready for prime time and is still beta!

Setup

To avoid running into issues later with your default python installs, it's recommended to use a py virtual env for doing this. Go to your desired test directory, and:

python3 -m venv venv
source venv/bin/activate
git clone https://github.com/osresearch/hcpy
cd hcpy
pip3 install -r requirements.txt

Install the Python dependencies; the sslpsk one is a little weird and we might need to revisit it later.

For Mac Users

Installing sslpsk needs some extra steps:

  1. The openssl package installed via brew: brew install openssl, and
  2. Install saslpsk separately with flags: LDFLAGS="-L$(brew --prefix openssl)/lib" CFLAGS="-I$(brew --prefix openssl)/include" pip3 install sslpsk
  3. Rest of the requirements should be fine with pip3 install -r requirements.txt

Authenticate to the cloud servers

laptop in a clothes washer with a display DoorState:Closed

hc-login $USERNAME $PASSWORD > config.json

The hc-login script perfoms the OAuth process to login to your Home Connect account with your usename and password. It receives a bearer token that can then be used to retrieves a list of all the connected devices, their authentication and encryption keys, and XML files that describe all of the features and options.

This only needs to be done once or when you add new devices; the resulting configuration JSON file should be sufficient to connect to the devices on your local network, assuming that your mDNS or DNS server resolves the names correctly.

Home Connect to MQTT

hc2mqtt config.json

This tool will establish websockets to the local devices and transform their messages into MQTT JSON messages. The exact format is likely to change; it is currently a thin translation layer over the XML retrieved from cloud servers during the initial configuration.

Dishwasher

laptop in a dishwasher

The dishwasher has a local HTTPS port open, although 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 a special hacked version of sslpsk is used to establish the connection and then hand control to the Python websock-client library.

Example message published to homeconnect/dishwasher:

{
    "state": "Run",
    "door":  "Closed",
    "remaining": "2:49",
    "power": true,
    "lowwaterpressure": false,
    "aquastop": false,
    "error": false,
    "remainingseconds": 10140
}
Full state information
{
    'AllowBackendConnection': False,
    'BackendConnected': False,
    'RemoteControlLevel': 'ManualRemoteStart',
    'SoftwareUpdateAvailable': 'Off',
    'ConfirmPermanentRemoteStart': 'Off',
    'ActiveProgram': 0,
    'SelectedProgram': 8192,
    'RemoteControlStartAllowed': False,
    '520': '2022-02-21T16:48:54',
    'RemoteControlActive': True,
    'AquaStopOccured': 'Off',
    'DoorState': 'Open',
    'PowerState': 'Off',
    'ProgramFinished': 'Off',
    'ProgramProgress': 100,
    'LowWaterPressure': 'Off',
    'RemainingProgramTime': 0,
    'ProgramAborted': 'Off',
    '547': False,
    'RemainingProgramTimeIsEstimated': True,
    'OperationState': 'Inactive',
    'StartInRelative': 0,
    'EnergyForecast': 82,
    'WaterForecast': 70,
    'ConnectLocalWiFi': 'Off',
    'SoftwareUpdateTransactionID': 0,
    'SoftwareDownloadAvailable': 'Off',
    'SoftwareUpdateSuccessful': 'Off',
    'ProgramPhase': 'Drying',
    'SilenceOnDemandRemainingTime': 0,
    'EcoDryActive': False,
    'RinseAid': 'R04',
    'SensitivityTurbidity': 'Standard',
    'ExtraDry': False,
    'HotWater': 'ColdWater',
    'TimeLight': 'On',
    'EcoAsDefault': 'LastProgram',
    'SoundLevelSignal': 'Off',
    'SoundLevelKey': 'Medium',
    'WaterHardness': 'H04',
    'DryingAssistantAllPrograms': 'AllPrograms',
    'SilenceOnDemandDefaultTime': 1800,
    'SpeedOnDemand': False,
    'InternalError': 'Off',
    'CheckFilterSystem': 'Off',
    'DrainingNotPossible': 'Off',
    'DrainPumpBlocked': 'Off',
    'WaterheaterCalcified': 'Off',
    'LowVoltage': 'Off',
    'SaltLack': 'Off',
    'RinseAidLack': 'Off',
    'SaltNearlyEmpty': 'Off',
    'RinseAidNearlyEmpty': 'Off',
    'MachineCareReminder': 'Off',
    '5121': False,
    'HalfLoad': False,
    'IntensivZone': False,
    'VarioSpeedPlus': False,
    '5131': False,
    '5134': True,
    'SilenceOnDemand': False
}

Clothes washer

laptop in a clothes washer

The clothes washer has a local HTTP port that also responds to websocket traffic, although the contents of the frames are AES-CBC encrypted with a key derived from HMAC(PSK,"ENC") and authenticated with SHA256-HMAC using another key derived from HMAC(PSK,"MAC"). The encrypted messages are send as binary data over the websocket (type 0x82).

Example message published to homeconnect/washer:

{
    "state": "Ready",
    "door": "Closed",
    "remaining": "3:48",
    "power": true,
    "lowwaterpressure": false,
    "aquastop": false,
    "error": false,
    "remainingseconds": 13680
}
Full state information
{
    'BackendConnected': False,
    'CustomerEnergyManagerPaired': False,
    'CustomerServiceConnectionAllowed': False,
    'DoorState': 'Open',
    'FlexStart': 'Disabled',
    'LocalControlActive': False,
    'OperationState': 'Ready',
    'RemoteControlActive': True,
    'RemoteControlStartAllowed': False,
    'WiFiSignalStrength': -50,
    'LoadInformation': 0,
    'AquaStopOccured': 'Off',
    'CustomerServiceRequest': 'Off',
    'LowWaterPressure': 'Off',
    'ProgramFinished': 'Off',
    'SoftwareUpdateAvailable': 'Off',
    'WaterLevelTooHigh': 'Off',
    'DoorNotLockable': 'Off',
    'DoorNotUnlockable': 'Off',
    'DoorOpen': 'Off',
    'FatalErrorOccured': 'Off',
    'FoamDetection': 'Off',
    'DrumCleanReminder': 'Off',
    'PumpError': 'Off',
    'ReleaseRinseHoldPending': 'Off',
    'EnergyForecast': 20,
    'EstimatedTotalProgramTime': 13680,
    'FinishInRelative': 13680,
    'FlexFinishInRelative': 0,
    'ProgramProgress': 0,
    'RemainingProgramTime': 13680,
    'RemainingProgramTimeIsEstimated': True,
    'WaterForecast': 40,
    'LoadRecommendation': 10000,
    'ProcessPhase': 4,
    'ReferToProgram': 0,
    'LessIroning': False,
    'Prewash': False,
    'RinseHold': False,
    'RinsePlus': 0,
    'SilentWash': False,
    'Soak': False,
    'SpeedPerfect': False,
    'SpinSpeed': 160,
    'Stains': 0,
    'Temperature': 254,
    'WaterPlus': False,
    'AllowBackendConnection': False,
    'AllowEnergyManagement': False,
    'AllowFlexStart': False,
    'ChildLock': False,
    'Language': 'En',
    'PowerState': 'On',
    'EndSignalVolume': 'Medium',
    'KeySignalVolume': 'Loud',
    'EnableDrumCleanReminder': True,
    'ActiveProgram': 0,
    'SelectedProgram': 28718
}

Coffee Machine

Image of the coffee machine from the Siemens website

The coffee machine needs a better mapping to MQTT messages.

Full state information
{
    'LastSelectedBeverage': 8217,
    'LocalControlActive': False,
    'PowerSupplyError': 'Off',
    'DripTrayNotInserted': 'Off',
    'DripTrayFull': 'Off',
    'WaterFilterShouldBeChanged': 'Off',
    'WaterTankEmpty': 'Off',
    'WaterTankNearlyEmpty': 'Off',
    'BrewingUnitIsMissing': 'Off',
    'SelectedProgram': 0,
    'MacchiatoPause': '5Sec',
    'ActiveProgram': 0,
    'BeverageCountdownWaterfilter': 48,
    'BeverageCountdownCalcNClean': 153,
    'RemoteControlStartAllowed': True,
    'EmptyDripTray': 'Off',
    'BeverageCountdownDescaling': 153,
    'EmptyDripTrayRemoveContainer': 'Off',
    'BeverageCounterRistrettoEspresso': 177,
    'AllowBackendConnection': True,
    'BeverageCounterHotWater': 37351,
    'RemindForMilkAfter': 'Off',
    'BeverageCounterFrothyMilk': 22,
    'BeverageCounterCoffeeAndMilk': 1077,
    'CustomerServiceRequest': 'Off',
    '4645': 0,
    'CoffeeMilkOrder': 'FirstCoffee',
    'BackendConnected': True,
    'BeverageCounterCoffee': 21,
    'Enjoy': 'Off',
    'UserMode': 'Barista',
    'PlaceEmptyGlassUnderOutlet': 'Off',
    'WaterTankNotInserted': 'Off',
    'PlaylistRunning': False,
    'BeverageCounterPowderCoffee': 9,
    'DemoModeActive': False,
    'CleanBrewingUnit': 'Off',
    'WaterHardness': 'Medium',
    'CloseDoor': 'Off',
    'EmptyMilkTank': 'Off',
    'SpecialRinsing': 'Off',
    'AllowConsumerInsights': False,
    'SwitchOffAfter': '01Hours15Minutes',
    '4681': 0,
    'LastSelectedCoffeeWorldBeverage': 20514,
    'BrightnessDisplay': 7,
    'CleanMilkTank': 'Off',
    'NotEnoughWaterForThisKindOfBeverage': 'Off',
    'ChildLock': False,
    '4666': 0,
    'Language': 'De',
    'MilkContainerConnected': 'Off',
    'SoftwareUpdateAvailable': 'Off',
    'LeaveProfilesAutomatically': True,
    'RemoveWaterFilter': 'Off',
    'OperationState': 'Inactive',
    'BeverageCounterHotMilk': 9,
    '4362': 0,
    'MilkTubeRemoved': 'Off',
    'DeviceIsToCold4C': 'Off',
    'SystemHasRunDry': 'Off',
    'DeviceShouldBeDescaled': 'Off',
    'PowerState': 'Standby',
    'DeviceShouldBeCleaned': 'Off',
    'DeviceShouldBeCalcNCleaned': 'Off',
    'BeanContainerEmpty': 'Off',
    'MilkStillOK': 'Off',
    'CoffeeOutletMissing': 'Off',
    'MilkReminder': 'Off',
    'RefillEmptyWaterTank': 'Off',
    'RefillEmptyBeanContainer': 'Off',
    'UnderOverVoltage': 'Off',
    'NotEnoughPomaceCapacityForThisKindOfBeverage': 'Off',
    'AdjustGrindSetting': 'Off',
    'InsertWaterFilter': 'Off',
    'FillDescaler': 'Off',
    'CleanFillWaterTank': 'Off',
    'PlaceContainerUnderOutlet': 'Off',
    'SwitchOffPower30sekBackOn': 'Off',
    'ThrowCleaningDiscInTheDrawer': 'Off',
    'RemoveMilkContainer': 'Off',
    'RemoveContainerUnderOutlet': 'Off',
    'MilkContainerRemoved': 'Off',
    'ServiceProgramFinished': 'Off',
    'DeviceDescalingOverdue': 'Off',
    'DeviceDescalingBlockage': 'Off',
    'CustomerServiceConnectionAllowed': False,
    'BeverageCountdownCleaning': 38,
    'ProcessPhase': 'None'
}

FRIDA tools

Moved to README-frida.md

hcpy's People

Contributors

atkaper avatar ericblade avatar jawsper avatar meidlinga avatar osresearch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hcpy's Issues

ERROR SIEMENS-appliance [Errno -2] Name or service not known

After done a hc-login which was succesfull
(a bunch of new files in the hcpy folder)
When i start python hc2mqtt config.json //I edited the default values for correct mqtt server.
I get:
python hc2mqtt config.json
Hello config_file='config.json' mqtt_host='my default' mqtt_prefix='homeconnect/'
ERROR SIEMENS-Dishwasher-xxx6 [Errno -2] Name or service not known
ERROR SIEMENS-HB876G5B6-xxx7 [Errno -2] Name or service not known
ERROR SIEMENS-WM14T6H9NL-xxx3 [Errno -2] Name or service not known
ERROR SIEMENS-EX877LYV5E-xxx6 [Errno -2] Name or service not known
ERROR SIEMENS-KI86NHDF0-xxx6 [Errno -2] Name or service not known

I expected a problem in my VLAN routing, however after changing the profile to the same as my smartphone where I do have the direct connection triangle it is still not connecting. There is still a possibility that is the issue however I don't see which ports are used.

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

Continuation of the project

Hello,

first of all. @osresearch Thank you for your great work. You have laid a great basis for a project with a lot of potential!

As you can see, there are people who want to use your project and are even committed to the point of wanting to participate in it themselves. However, I've been following the project for a while and I think it's not progressing as quickly as others would like.
This is not a criticism! Just an assessment of the situation.

As I saw in other projects, a good way the let the community and the project grow is to create a github organisation, add some people as owners and move the project to this organisation. In this way you can give your project to the people and the responsibility lies with several people and not just you.

Are you interested to go this way?
I would be happy if you answered me.

I wish you a nice weekend!

Kind regards,

Patrick

hclogin failing with a 401 "The access token is malformed"

Hi there! Just trying to pick this up, and I'm not sure where to start. I've added some extra debugging to try to see what's going on, but whatever it is, I'm not seeing it. I receive what looks to be a valid token, it gets to the
"# now we can fetch the rest of the account info" section, gets to account/details .. and i get a 401 Unauthorized back, and the test of the response is JSON containing

{ error: { description: "The access token is malformed", key: "invalid_token" } }

This is with the most recent PR added that fixes some prior issues, I reverted that to see if that was at fault, and just got a "Missing Schema" on a "Invalid URL" message.

Any ideas?

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.

hc-login: KeyError: 'returnUrl'

Hello,
I have the following error when running hc-login:

next preauth_url='https://singlekey-id.com/auth/en-gb/login?ReturnUrl=%2Fauth%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3D11F75C04-21C2-4DA9-A623-228B54E9A256%26redirect_uri%3Dhttps%253A%252F%252Fapi.home-connect.com%252Fsecurity%252Foauth%252Fredirect_target%26response_type%3Dcode%26scope%3Dopenid%2520email%2520profile%2520offline_access%2520homeconnect.general%26prompt%3Dlogin%26style_id%3Dbsh_hc_01%26state%3D%257B%2522session_id%2522%253A%25224cf70097-4a00-43fc-8192-3d423766035b%2522%257D%26suppressed_prompt%3Dlogin&f=XPA0'

Traceback (most recent call last):

File "/home/domotic/hcpy/./hc-login", line 139, in <module>

return_url = query["returnUrl"][0]
~~~~~^^^^^^^^^^^^^
KeyError: 'returnUrl'

All the steps before ran whithout any error.
Any help would be more than welcome!!!

hc-login not following 307 redirects

It seems that the server sometimes presents redirects using status code 302, and sometimes using 307. The former is properly handled, the latter is not.

Tested on macOS 14.1.2 and Python 3.11, results in the following (shortened) debug output:

--------
return_url='https://singlekey-id.com/auth/connect/authorize/callback?client_id=[...]', <Response [302]> 
return_url='https://singlekey-id.com/auth/login?returnUrl=%2Fauth%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3D[...]', <Response [302]> 
return_url='https://singlekey-id.com/auth/en-gb/login?returnUrl=%2Fauth%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3D[...]', <Response [307]> 
return_url='https://singlekey-id.com/auth/en-gb/login?returnUrl=%2Fauth%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3D[...]'
--------
Traceback (most recent call last):
  File "/Users/jorrit/Documents/Projects/home_control_py/./hc-login", line 188, in <module>
    code = query.get("code")[0]
           ~~~~~~~~~~~~~~~~~^^^
TypeError: 'NoneType' object is not subscriptable

The 302 redirect is properly handled, but the loop is ended upon a 307. This means the remaining code runs on the wrong URL, and crashes.

Changing line 168 seems to resolve this:
if r.status_code != 302 and r_status_code != 307:

Fix changed variable name

Hello,

this fix: 03e1b34
changed lines 135 / 139

one time capitalized one time not.

On my side I need to capilalize line 139.

returnUrl --> ReturnUrl

grafik

Connection Refused

ConnectionRefusedError: [Errno 111] Connection refused

i changed the host in the config.json to MAC, IP none of them seems to Work

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.

No MQTT message sent on {'AlarmClockElapsed': 1} (oven)

Hello,
Everything is working fine. I sucessfully installed HCPY and connected my SIEMENS oven.
I can see on my terminal window all events sent from the oven including the most interesting for me: {'AlarmClockElapsed': 1}.
Indeed, it's usefull on an oven to be notified when the time is elapsed!!!
I can see that some MQTT messages are sent to my server and I can read it correctly on MQTT Explorer. Those message are displayed on hcpy terminal window:
publish homeconnect/oven {"state": "Inactive", "door": "Closed", "remaining": "0:00", "power": "Standby", "lowwaterpressure": null, "aquastop": null, "error": null, "remainingseconds": 0}

Unfortunately, there is no MQTT message sent when {'AlarmClockElapsed': 1} is received.
2024-02-08 11:05:42.525354 {'AlarmClockElapsed': 1}

In config.json I can see the following lines:
"6131": { "name": "Cooking.Oven.Event.Cavity.001.AlarmClockElapsed" },

Is something missing? should I manualy add something?
Any help will be more than welcome!!!!

MQTT with password

Hi!
Like the work that is done here; liking each attempt to move IOT control without internet dependencies.
My MQTT server needs a password. This seems already implemented in https://github.com/bruestel/hcpy (forked).
I'm new to github. Can I suggest the edits necessary to apply user/pwd to the mqtt server myself or is there a main driver for this project?
Thanks!

(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).

auth failed with <Response [400]>

Hello,

I'm trying to run the hc-login with the right username and password, but i'm getting an reponse 400 with an auth. failed error.
I'm sure that the user and password is ok, (double checkt it and can use the same user and password on this site https://singlekey-id.com/nl), but still getting this error.

Any idea how to fixed this?

`ProcessPhase` values are missing

In the config.json, I find the LaundryCare.Common.Option.ProcessPhase feature. It represents the current phase of the clothes washing process (e.g. washing, rinsing, spinning). However, there is no values object that maps the process numbers to actual texts (like on some other features):

            "27142": {
                "name": "LaundryCare.Common.Option.ProcessPhase"
            },

Is it a bug in hc-login, or is it not transmitted by the Home Connect API?

Is there a way to get this mapping somewhere else? I would like to show the current process phase on a display, but could only figure out a small list of processes so far.

MacOS install

Howdy,

Few things I've ran into on Mac (arm).
Added #24 in case you're happy with the proposal below:

For Mac, building sslpsk needs some extra steps

  1. The openssl package installed via brew: brew install openssl, and
  2. Build saslpsk separately with flags: LDFLAGS="-L$(brew --prefix openssl)/lib" CFLAGS="-I$(brew --prefix openssl)/include" pip3 install sslpsk
  3. You may also want to pip3 install requests
  4. Finally install the rest of the requirements with pip3 install -r requirements.txt

If all that goes to plan, we get info from hc-login as expected

Hope that helps a few folks,
mb

hc_login malformed URL

In some cases, redirects may lead to malformed (partial) URLs. This may create to a request without the domain name, which is not handled by the requests package.

The problem seems to be on line 170 when the server presents a redirect without the domain name. This is properly handled on line 163 where it prepends singlekey_host when necessary, but this step is not performed at line 170. When singlekey_host is also (conditionally) prepended after line 170, this crash is resolved for me.

Tested on macOS 14.1.2 using Python 3.11. A partial debug output is given below.

--------
return_url='https://singlekey-id.com/auth/connect/authorize/callback?client_id=[...]', <Response [302]> 
return_url='https://singlekey-id.com/auth/login?returnUrl=%2Fauth%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%[...]', <Response [302]> 
Traceback (most recent call last):
  File "/Users/jorrit/Documents/Projects/home_control_py/./hc-login", line 167, in <module>
    r = session.get(return_url, allow_redirects=False)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jorrit/Documents/Projects/home_control_py/venv/lib/python3.11/site-packages/requests/sessions.py", line 602, in get
    return self.request("GET", url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jorrit/Documents/Projects/home_control_py/venv/lib/python3.11/site-packages/requests/sessions.py", line 575, in request
    prep = self.prepare_request(req)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jorrit/Documents/Projects/home_control_py/venv/lib/python3.11/site-packages/requests/sessions.py", line 486, in prepare_request
    p.prepare(
  File "/Users/jorrit/Documents/Projects/home_control_py/venv/lib/python3.11/site-packages/requests/models.py", line 368, in prepare
    self.prepare_url(url, params)
  File "/Users/jorrit/Documents/Projects/home_control_py/venv/lib/python3.11/site-packages/requests/models.py", line 439, in prepare_url
    raise MissingSchema(
requests.exceptions.MissingSchema: Invalid URL '/auth/en-gb/login?returnUrl=%2Fauth%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%[...]': No scheme supplied. Perhaps you meant https:///auth/en-gb/login?returnUrl=%2Fauth%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%[...]?

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 :-)

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.

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.

hc-login doesn't work with accounts migrated to singlekey

After (accidentally?) migrating to SingleKey, hc-login no longer works.

Response:

        <div class="panel">
          <div class="panel-body">

            <div class="info_topic_hdr" lng-key="migration.success_hdr">Success!</div>

      <div class="info-txt">
        <span id="migrationFormInfo" lng-key="migration.msg.success">
        Your Home Connect account is connected to SingleKey ID.<br/>
        From now on, you will log in to Home Connect with your SingleKey ID.<br/>
        Enjoy!
        </span>

      </div>


          </div>

          <div class="button-line">

            <button class="submit-btn" type="submit" lng-key="migration.btn.ok">OK</button>

          </div>
        </div>
      </form>

libssl-dev missing on ubuntu

Hi,
Just tried to install and ran into problem "sslpsk/_sslpsk.c:19:10: fatal error: openssl/ssl.h: Datei oder Verzeichnis nicht gefunden"

Turns out i had to manually install it: sudo apt install libssl-dev

After that it works. Mabe a missing include?

System is Ubuntu 23.10 amd64

greetings

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.