More BLE for the Somfy Sonesse2 Zigbee Motors

More BLE for the Somfy Sonesse2 Zigbee Motors
Actually my blinds this time.

I've had people reach out and ask if I knew anything about other commands for configuring the Sonesse2 motors without the offical app. So I've dug through the source I have here, and this is what I've found.

First of all, I'm pretty sure you need to perform an Authentication first in all cases.

⚠️
You try these at your own risk!

Setting up a blind

To set up a blind without access to the Tahoma Pro app, you need todo the following.

😮‍💨
Some BLE tools try to read immediately after writing a value, many endpoints on the blinds will error if you read, so don't get confused between an error from the write and an error from an implicit read.

On iOS I used "BT Inspector", needed the paid for version but worth it!
  • Authentication - Pin code to authenticate.
  • Identify - Just to be sure that you have correctly authenticated.
  • Configure Range - Just use "Start" unless you have range limits.
  • Set Direction - Set it to clockwise.
  • Move Up - See if your blind moves down.
  • Set Direction - If the blind moved down, set it to counter-clockwise.
  • Move Up - Keep repeating until you get to the upper point for your blind.
  • Set Limit - Set the upper limit.
  • Move Down - Keep repeating until you get to the lower point of your blind.
  • Set Limit - Set the lower limit.
  • Leave Network - The blind will now look for a zigbee network.

Commands

Authentication✅

Open access to the motors configuration system.

What Description
Endpoint 0000000b-cad9-46c6-a2ea-2ca16d57b4a5
Parameters Pin code for motor, as a 3 byte int, in little-endian.

Delivery Mode ✅

Switches the motor off, until the button is physically pressed on the tube.

What Description
Endpoint 0000000a-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x01

Leave Network ✅

Causes a factory default motor to leave its own Zigbee network and start polling to join another.

What Description
Endpoint 00020001-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x01

Identify✅

Cause the blind to dance to help identify which blind is being accessed.

What Description
Endpoint 00000001-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x01

Open⚠️

May be for venetian blinds, doesn't exist on roller - Open the blind.

What Description
Endpoint 0000000d-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x01

Close⚠️

May be for venetian blinds, doesn't exist on roller - Close the blind.

What Description
Endpoint 0000000e-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x01

Stop✅

Stop the blind.

What Description
Endpoint 00000006-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x01

Configure Range✅

Enable the blind to configure its range, this is needed before any Move command when the blind has yet to have limits defined. Start seemed to be enough for my blinds.

What Description
Endpoint 0001000B-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x0000 = "Start", 0x0002 = "Half", 0x0001 = "Full".

Move Up✅

Move the blind up manually.

What Description
Endpoint 00010009-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x????, 16 bit, 1-500, little endian, 1 small step, 500 larger.

Move Down✅

Move the blind down manually.

What Description
Endpoint 00010008-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x01 moves large amount, 0xf401 moves a small amount

Go To Position✅

Move the blind to a specific position, 0-32767 calibrated against limits set!

What Description
Endpoint 00000005-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x????, 16 bit, 0 (open) - 32767 (closed), little endian

Set Limit✅

Set's the limits of the blind.

What Description
Endpoint 00010007-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x00 to set upper limit, 0x01 to set lower limit

Set Direction✅

Set the direction of the blind.

What Description
Endpoint 00010005-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x00 - Counter Clockwise, 0x01 - Clockwise

Reset to factory defaults✅

Reset the blind to factory defaults.

What Description
Endpoint 00010001-cad9-46c6-a2ea-2ca16d57b4a5
Parameters 0x01

Write Data🚨

This section could be very dangerous, while the Tahoma app only seems to send CBOR pairs when it writes, it may be more complicated than that.

This is also the way the firmware is uploaded, I don't think that you can upload a corrupt firmware... but you might be able to.

YOU HAVE BEEN WARNED!

Read and write configuration data from the blind, this appears to be needed to configure the blind in some circumstances.

What Description
Endpoint 00040001-cad9-46c6-a2ea-2ca16d57b4a5
Parameters No simple parameter, it's a protocol.

It appears that WriteData allows interacting with multiple different "files" on the motor, not all files may be present on all Somfy devices.

   CONFIG_FILE_HMI("00C2"),
   CONFIG_FILE_MOTOR("00C4"),
   CONFIG_FILE_RADIO("00C3"),
   CONFIG_FILE_TYPE("00D2");

File types.

Different commands can be sent to open the files.

   CLOSE_FILE("04"),
   OPEN_FILE("00"),
   READ("03"),
   SIZE("01"),
   WRITE("02");

File operations.

These files can be opened in different modes.

   READ("00"),
   WRITE("01");

File open modes.

Configuration seems to be sent a Concise Binary Object Representation (CBOR), a binary format that was inspired by JSON.

A file open command, seemed to be something like:

00 - Open File
C4 00 - Motor config file
00 - Mode
Nothing - Additional content (maybe for write)

The write suceeds, an immediate read after errors.

Then read the file contents with:

03 - Read File
C4 00 - Motor config file
00 - Mode
Nothing - Additional content (maybe for write)

Which returns:

aa6b4170706c69636174696f6e8266526f6c6c6572a36177f5616966526f6c6c657261658466526f6c6c65726856656e657469616e655368656572655a65627261715265766572736564446972656374696f6e82f4a26177f56169f4694c69667452616e676582f6a56177f5616c1a0000027861681a0000f6e061756570756c73656169f66c4e6f6d696e616c5370656564821907d0a56177f5616c1903e86168190af0617568312f31303072706d61691907d06b5374617274557052616d70821903e8a56177f5616c1901f461681903e86175626d7361691903e86d5374617274446f776e52616d70821903e8a56177f5616c19

Motor Config

Motor file:

{"Application": ["Roller", {"w": true, "i": "Roller", "e": ["Roller", "Venetian", "Sheer", "Zebra"]}], "ReversedDirection": [false, {"w": true, "i": false}], "LiftRange": [null, {"w": true, "l": 632, "h": 63200, "u": "pulse", "i": null}], "NominalSpeed": [2000, {"w": true, "l": 1000, "h": 2800, "u": "1/100rpm", "i": 2000}], "StartUpRamp": [1000, {"w": true, "l": 500, "h": 1000, "u": "ms", "i": 1000}], "StartDownRamp": [1000, {"w": true, "l": 500, "h": 1000, "u": "ms", "i": 1000}], "StopUpRamp": [1000, {"w": true, "l": 500, "h": 1000, "u": "ms", "i": 1000}], "StopDownRamp": [1000, {"w": true, "l": 500, "h": 1000, "u": "ms", "i": 1000}], "DisabledSoftRamps": [false, {"w": true, "i": false}], "IntermediatePositionsLift": [[[null, {"w": true, "l": 0, "h": 51200, "u": "1/512%", "i": null}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}], [null, {"u": "1/512%"}]], {"w": true, "h": 16}]}

Motor Config Decoded

Type file:

{_ "MediaSoftRelease": ["5173576A005"], "MediaSoftBuild": [5], "MediaDataModelRevision": ["05"], "MediaDiagRevision": ["08"], "MediaDataRevision": ["00"], "ZigbeeStackRevision": ["7.2.0.0"], "ZigbeeDeviceType": ["SED"], "BLEStackRevision": ["5.0.0.108"], "BLEDeviceType": ["Peripheral"], "MediaBootloaderRelease": ["2.2.4101"], "SecureElementVersion": ["2.1.7"], "Motor": ["SONESSE28", null], "Type": ["WF 12V", null], "Detail": ["2Nm 20RPM", null], "MotorSoftRelease": ["5169743A06", null], "MotorSoftBuild": ["D455B1D7", null], "MotorBootloaderRelease": ["5163735A02", null], "MotorDataRevision": ["00", null], "MotorDiagRevision": ["08", null], "MotorDataModelRevision": ["05", null], "MotorPCBARelease": ["5166982A04", null], "MotorCustomization": ["Undefined", null], "MotorEMS": ["20240117AA", null], "MotorProduction": ["Undefined", null], "MotorSerialNumber": ["Undefined", null]}

Type config decoded

Radio file:

{"DeviceName": ["Sonesse2 28 WF Li-Ion", {"w": true, "h": 60, "u": "string", "i": "Sonesse2 28 WF Li-Ion"}], "EndProduct": ["1D Roller Shade", {"w": true, "e": ["1D Roller Shade", "1D Roman Shade", "1D Balloon Shade", "1D Woven Wood", "1D Projection Screen", "1D Pleated Shade", "1D Cellular Shade", "1D Layered Shade", "2D Sheer Shade", "2D Interior Blind"], "i": "1D Roller Shade"}], "ZigbeeTxPower": [[[12, {"w": true, "l": -10, "h": 19, "u": "dBm"}], [12], [12], [12], [12], [12], [12], [12], [12], [12], [12], [12], [12], [12], [12], [11]], {"w": false, "h": 16}], "BleTxPower": [9, {"w": true, "l": -10, "h": 19, "u": "dBm"}], "StepLiftConversion": [3, {"w": true, "l": 1, "h": 1000, "u": "1/10%", "i": 3}], "StepTiltConversion": [70, {"w": true, "l": 1, "h": 1000, "u": "1/10%", "i": 70}]}

Radio config decoded

HMI file appears to be empty.