Garage door from Forcedoor

Nice and minimal :slight_smile:
Do you have my esphome fw on it and if so does it run well?

Has anyone had any success here?

I found out:

  • The iOS app talks to api.bit-door.com and doesn’t appear to be talking to Tuya directly. Creating an account here has no impact on Tuya either - you can’t re-use these credentials in the F-Linx app on Android
  • The Android app seems to be Tuya rebranded. It requires you to select a country (the iOS app does not) and the email for the 2FA code comes from a different email address (iOS: support@f-linx / Android: system[...].ismartlife[...] )
  • The QR code on the sticker can’t be scanned by either the Tuya or SmartLife app - only F-Linx it seems.

I sadly don’t have any android phone to get it into the Tuya ecosystem and the ‘manual’ doesn’t explain how to reset it, pressing the button several times or during 5-10 seconds doesn’t seem to reset it (the device remains on my wifi network).

Also tried to use an Android emulator but got stuck pretty quickly as it requires bluetooth/wifi which the emulator all mocks.

Getting an Android phone to get it linked to Tuya feels a bit excessive (if it even works), but if that’s what I have to do I’m sure I can find one I can use for a little while.

I tried some network sniffing and using tinytuya, but tinytuya doesn’t find it. The app communicates via bluetooth on iOS or via the bit-door API I assume when not in bluetooth range.

Also sniffed around an unencrypted iOS backup and found API tokens for the bit-door.com APIs but most give me an error 500 and a Java exception with a 'Please update your APP" error. The account endpoints seem to work. Found my ‘deviceId’ as well.

Tried decompiling the Android app but it doesn’t help me as the app is vastly different from the iOS app - as said, can’t even use the same account and ‘inviting’ an email address that exists in the Android app doesn’t work from the iOS app (“account doesn’t exist”).

I have two left hands when it comes to creating my own ESP-based things, so that’s not really an option.

I’m really out of ideas now.

I can’t update my message any longer, but I managed to get ahold of an actual Android phone.

So the F-linx 1.0.0 app is Tuya, but the newest Play Store version uses the bit-door.com APIs and is compatible with the current iOS version (accounts are on the bit-door backend for both operating systems).

I’m now trying with the ‘old’ app on an actual Android phone and will post my findings.

Edit:

  • The old app can’t find the USB dongle. I’ve now decompiled the new app to figure out how it talks to the dongle, it seems there’s some MQTT things going on with encrypted messages, and some API things. I’m not yet certain which is which in terms of encrypting/decrypting the MQTT messages and whether or not API calls are needed at all. However, I am certain this thing isn’t Tuya compatible. If it ever was, it was probably removed in a previous firmware update somewhere between 2021 and now.

Once again can’t seem to update my findings, guess I need to level up first.

Either way:
I didn’t have success in figuring out how the MQTT messages are encrypted/decrypted. However, I have had more luck with Bluetooth. Seems you can replay messages that you sniffed previously for light on/off, door up/down/stop.

So I bought an ESP32 and flashed the Bluetooth Proxy FW on it. Now trying to get Claude to write me a HACS plugin to expose a garage door and light entity that under the hood connects via Bluetooth to the dongle and sends the commands when necessary. Claude already got me a working proof-of-concept python script which I can run from my computer and it’s working flawlessly so far.

This also removes any cloud dependancy, which is also a win.

In doing so, I also figured out my car is broadcasting as iBeacon (which was my next step anyway, automating the garage upon approach by car) so will most likely use the built-in iBeacon. So double win.

I built mostly on your work. Works well, only issue is the c3 super mini has a weak radio. But I bought now one with external antenna and it is ok.

Hi,

I’m working on a similar project with the same motor and I’ve been following your findings.

I have successfully sniffed the Bluetooth traffic and isolated the specific Write Requests for the garage door (up/down) and the LED light. However, I’m currently stuck: when I try to replay these commands using nRF Connect while connected to the motor, nothing happens (even though I get a Write Response).

I noticed a specific 52-byte handshake/write occurring right after the connection. Since you mentioned your Python script is working “flawlessly,” I was wondering if you could share more details on how you handle the connection sequence? Do you need to send a specific authentication packet or maintain a session before the replay works?

Any help or snippets from your proof-of-concept would be greatly appreciated!

Hi, thanks for sharing this project, this is great job.

I noticed your setup uses 24V, while my garage opener board provides 5V. Could you share the exact model of your motor and your official dongle?

I’m using a ForceDoor opener (not 100% sure about the exact model yet). Do you think your UART approach would still work with a 5V version? I’m wondering if the control box keeps the same UART protocol regardless of voltage.

Thanks

I belive i have this motor unit WUXI FORCE TECHNOLOGY CO.,LTD.
it’s using this USB module you see in this video https://www.youtube.com/watch?v=ATSb90L6PMo
(it doesn’t seem to have a dedicated product page)

To clarify - this USB dongle has 24V on Vin,
and 5V on both TX and RX (from the dongle point of view).

In my setup on github i have chosen to do a step down from 5V on RX to 3.3V just to be on the safe side with the ESP32. My ESP has 3.3V on TX and thankfully it’s good enough for the motor unit.

noticed your setup uses 24V, while my garage opener board provides 5V.

where did you measure this? is this on the USB pins of the dongle, or some other breakout pins on the board?

As per my image here, the pins on the right are Vin (24V) and TX/RX (5V).
Those are the pins off the USB connector (hidden behind the soldere duponts).

But the pins on the bottom may have had 5V (the unmarked square one, i dont remember exactly)

Hi,

I have the exact same USB donglen my motor is an OpenIt 2 (and use f-linx app). On my motor’s female USB port (with the key unplugged), here is what I’m measuring: 5V on the VCC, 3.3V on the D- pin, and 2.28V on the D+ pin.

I tried adapting your code for a Wemos D1 mini. So far, only the door status feedback is working (I can see the values changing from 0% to 100% in real-time during opening/closing). However, the commands for Open, Close, Stop, and Light (ON/OFF) are not working at all.

I attempted to sniff the frames sent by the WiFi dongle by powering it with 5V. The phone app connects via Bluetooth and allows me to send the missing commands. Here is what I captured:

  • Light ON: 1A F0 F5
  • Light OFF: 1A F1 F4
  • Door Stop: 1A 01 E4
  • Close Door: 1A 02 E3
  • Open Door: 1A 00 E5

I’m currently stuck. I tried modifying your code to open the door using: - uartex.write: { id: bus_uartex, data: [0x1A, 0x00, 0xE5] } …but it still doesn’t work. Even worse, it seems to have messed up my motor’s limits—it now tries to keep opening even when it’s already fully open (the motor forces, then stops).

I’m quite new to reverse engineering and I’m not entirely sure if my capture procedure is 100% correct. What I can say for sure is that I consistently get these exact same frames every time I trigger an action.. Could you help me understand what might be going wrong? Also, could you explain the process you used to capture both incoming and outgoing frames?

Thanks a lot for your help!

Very interesting that you measure different voltages on the USB. certainly makes things easier for you :slight_smile:
Maybe i have a different motor unit, not sure, their product pages are a mess. This also look similar, i really dont know WUXI FORCE TECHNOLOGY CO.,LTD.

As to why it does not respect the commands - can you collect some dumps and post them?

If on Linux, something like
tio /dev/ttyUSB0 | tee some_log.bin
to view it cat some_log.bin | xxd

Because here you only have 3 bytes in the command. uartex.write: { id: bus_uartex, data: [0x1A, 0x00, 0xE5] . Dont know how the rest of your yaml looks like, but i think you need more bytes

Command protocol on my device:

  • header 0x23
  • length 0x07
  • whatever 0x41
  • command 0x02 for closing
  • whatever 0x0
  • then 1 byte CRC (check out tx_checksum in my yaml)
  • ends with 0x0d

It’s possible the unknown fields change the limits :person_shrugging:

Feel free to DM and we can chat on Discord if you need more help

I can do you one better.

Finally managed to get the cloud APIs to work, and the MQTT messages decoded.

So this should work for you as well, at least it does for me. It’s a little flakey, but so is the F-linx app, in a sense that it doesn’t always report the state of the garage door ‘in order’.

It could say ‘open: 4% 8% 16% 12% 24% 0% 50%’ for example, which is weird, but it’s the MQTT messages not being in order.

I’ll see if there’s anything I can do to improve - or if anyone wants to improve, feel free to reach out and we can work on it together.

I believe you can only be logged in to the app or HA, not both at the same time. Workaround is to ‘invite’ another account to your garage door and use that for HA.

You are a legend mate, ive just had a play around with it and works perfectly… will let you know if i have any bugs over the coming weeks

This is incredible! Thank you so so much for this

Hey,
Were you able to get this working at all? I am building a house that has a steel-line door which uses the same adapter and when I measure the voltage of the usb port it is also 5v.

It’s really confusing that the same module would exist for different voltages.

I measured 5V on my Steel-line adapter too, so that module likely runs on 5V internally. Different models just have different power input stages, but the logic stays the same.