tinytuya icon indicating copy to clipboard operation
tinytuya copied to clipboard

Package python-pip is obsolete on Debian

Open pascal-fb-martin opened this issue 3 years ago • 19 comments

Apparently Debian no longer has python-pip: it was renamed python3-pip. Same for python-crypto. (My guess is that Debian is trying to support both Python 2 and 3.)

For reason only known to God, installing these two packages fetches package javascript-common. Is Python now dependent on JavaScript? That would be funny. Will installing any Python package fetch every other scripting language packages in the near future? Tcl and R too? :-)

Sometime the quest to reuse goes way too far.

Otherwise, thanks you for tinytuya. I am trying to use Tuya devices without depending on the cloud.

pascal-fb-martin avatar Apr 17 '22 03:04 pascal-fb-martin

Hi @pascal-fb-martin ! Thanks for the feedback.

Yes, those setup instructions are a bit dated. You should not need python-crypto and many systems already have pip installed (or it will be handled by other package managers). I'll update the instructions:

  # Install TinyTuya
  python -m pip install tinytuya

It will fetch pycryptodome and requests which is generally all you will need to run tinytuya.

jasonacox avatar Apr 17 '22 04:04 jasonacox

Actually, I am using raspbian 11.2 (32 bit) on a Raspberry Pi 2 (a minimal install, not desktop GUI), and pip was not installed.

Considering that Python is pretty important in the Raspberry Pi ecosystem, this is kind of interesting..

I am not really a Python programmer myself (I have done some limited Python programming). I am actually trying to learn about the LAN protocol being used by Tuya devices. (The devices are dirt cheap Feit Electric smart bulbs from Costco--less that $8 for two bulbs, after store rebate.) At this point I am chocking on how to find the device key, since Feit does not use the Tuya app (they have their own) and no web access that I can find.

pascal-fb-martin avatar Apr 17 '22 04:04 pascal-fb-martin

Thanks @pascal-fb-martin - I left a link in the instructions on how to install pip if it isn't already there. Using the OS package manager is probably the best approached (e.g. the apt-get install python3-pip in your case).

I would be very interested to know if you can get those bulbs to work. The Tuya IoT portals expect you to use the "Smart Life" application to link the devices to your account. I'm not sure how another app would work. I would likely try the "Smart Life" app anyway just in case they are compatible. I know others have reported having some success with the Costco Feit devices (see this PR https://github.com/jasonacox/tinytuya/pull/54).

Good luck! Let us know how it goes.

jasonacox avatar Apr 17 '22 05:04 jasonacox

Tinytuya was able to detect the device:

$ python3 -m tinytuya scan

TinyTuya (Tuya device scanner) [1.4.0]

Scanning on UDP ports 6666 and 6667 for devices (15 retries)...

Unknown v3.3 Device   Product ID = key8u54q9dtru5jw  [Valid payload]:
    Address = 192.168.1.179,  Device ID = eb35df3d07961da723xaog, Local Key = ,  Version = 3.3, MAC = 
    No Stats for 192.168.1.179: DEVICE KEY required to poll for status
                    
Scan Complete!  Found 1 devices.

      Saving device snapshot data to snapshot.json

I will try the "Smart Life" app. Thanks for the tip.

Do you know of a description of the Tuya LAN protocol?

I have my own set of home automation software (no UI remotely as good as Home Assistant..): see my projects. I have support for TP-Link Kasa (pretty happy so far), Wiz Connected (devices are OK if the install succeeds--the Wiz app is a complete horror) and old Orvibo devices (the protocol was changed since then).

I would like to add support for Tuya. My main goal is to avoid Cloud dependencies. My home starts to look like a patchwork of cheap home automation devices..

pascal-fb-martin avatar Apr 17 '22 05:04 pascal-fb-martin

The Feit app is actually a rebranded Tuya Smart Life app: same exact UI. :-) However they do not seem to use the same cloud: I wa able to create an account with the same email address, different password.

Apart from a timeout at the end of the install, the device works fine with the Tuya app: I uninstalled the Feit app (no need for multiple copy of the same). Now I can look at following your instructions..

Thank you so much.

pascal-fb-martin avatar Apr 17 '22 05:04 pascal-fb-martin

That's great news! Thanks for the update.

As to your project and questions about Tuya LAN communcation: Tuya devices communicate via UDP (6666 and 6667) and TCP (6668). A graphical representation of the message passing is here. Starting with 3.3 devices (you have one), the payloads are encrypted (hence the need for the LocalKey). UDP broadcasts are emitted from the devices when not being controlled by the app and they all use the same UDP key (included in TinyTuya).

Take a look at the TinyTuya code and you will see the TuyaMessage format, how to pack/unpack them and the command structures. This was discovered by the community as Tuya doesn't release their protocol specifics for LAN, but some of it does mirror the their published cloud APIs.

The LocalKey for each device is created when you pair it with the Smart Life app (and it will reset it to a new one if you re-pair). Once you have the LocalKey you can stay on LAN for all communication which is the primary use case for TinyTuya. If you want to see the raw and decrypted payloads using TinyTuya, you can call the tinytuya.set_debug(True) function at the top of your code and it will output the handshakes and payloads.

I hope that helps. Have fun!

jasonacox avatar Apr 17 '22 06:04 jasonacox

Thank you so much! It really was all the help I that I could dream of!

I got the local key. I just hope that it does not expire after one year (like the IoT free developer account..).

Shameless plug:

Look at my set of applications. What makes it a bit complex is that this is a set of microservices (running on Raspberry Pi) that interact with each other: here the microservice model replaces the driver or plugin model. This is so much easier to maintain: these are separate applications built and installed independently. I can relocate each service to a different computer without any change to the configurations.

In the case of light control, you only need to look at houselights (mainly lights schedule) and housekasa (Kasa devices) or housewiz (Wize Connected devices).

The suite also include a (somewhat smart) sprinkler controller, with the sprinklers commanded on and off by houserelays, using the same API as housekaza or housewiz--this forced me to add a "gear" attribute as a filter so that the sprinklers do not show up in the houselight webUI (the scheduling in houselight is too primitive for sprinker control).

There is a dynamic discovery mechanism that goes through the houseportal microservice--which serves as a repository of active microservices.

Warning: this is C code. (I am showing my age.. :-)

pascal-fb-martin avatar Apr 17 '22 06:04 pascal-fb-martin

One more question: I see that there are two UDP ports and one TCP port. Do you know if all controls (on, off, color, dimmer) can be sent through UDP?

pascal-fb-martin avatar Apr 17 '22 06:04 pascal-fb-martin

Tuya devices only use UDP to announce themselves/discovery (6666 for 3.1 devices, and 6667 for 3.3 devices). All command/control action is via TCP on port 6668 which is the only port the Tuya SOC has open. Of course, they were designed to be "cloud first" so they phone home to Tuya Cloud as a default for state change and to watch for control, but you can mimic that on the LAN by keeping a persistent connection to port 6668 and send/watch for events asynchronously. Here is an example script that does that: async_send_receive.py.

Look at my set of applications

Awesome projects! I love that you even built your own http server (echttp)! You should post some UI screenshots for houseportal. I want to see it work.

There's nothing wrong with C. I still prize my K&R book and do quite a bit of C++ and Obj C programming these days, mostly Arduino libraries like TM1637TinyDisplay, OpenGL-LIDAR-Display and iOS projects like iCurlHTTP including cross-compiling openssl/libcurl to ARM (Build-OpenSSL-cURL).

I built TinyTuya in python to make it approachable to the masses and get good engagement from the Tuya user and maker community to help develop it. I'm happy with the community contributions and the extension of TinyTuya over the years. If you are open to a polyglot ecosystem, you could easily spin up a TinyTuya based microservice to your houseportal project! Let me know if you do an how it goes.

I just hope that it does not expire after one year (like the IoT free developer account..).

Unless you are a business, Tuya will not expire your account despite the warnings. They now give that disclaimer in their email updates. I have seen the IoT UI give me warnings or not have all the feature it did when I signed up, but the credentials for my account continue to work with the TinyTuya wizard for Cloud API calls (e.g. to fetch the keys for existing newly paired devices). Also, your keys should stay the same unless you re-pair with the Smart Life app.

Let us know how your Tuya adventure goes. 👍

jasonacox avatar Apr 17 '22 15:04 jasonacox

"If you are open to a polyglot ecosystem": that is one thing that I love with microservices. Because the API is HTTP and JSON, the programming language used for each microservice is irrelevant. I have a plan to switch to Rust at some point, but the language, and web libraries, keep changing so I will wait a bit.

I would be really happy if you do create a Tuya microservice. I have not really experimented with Python, beside some small work modifying Kodi plugins. The install of tinytuya was reasonably simple (apt even warned to use python3-pip instead..). Note that running the applications as services (deamons) is important to me. Southen California does have the occasional rolling blackout..

I wanted a "web console" for easy monitoring & administration. The idea of switching all the way to microservices came later, but having multiple applications on the same RPI was always the goal.

I started with Tcl (tclhttpd library), but maintaining and adding independent modules to a monolithic Tcl application is hell..

I tried JavaScript, forking a nascent sprinkler controller project. Javascript keeps changing, and Node.js installation is definitely not Debian-friendly. That one Node.js application quickly became a high maintenance diva. Still glad that I learned JavaScript, though.

I wanted something easy to maintain: language and API stability, low memory footprint and minimal dependencies. Go was a no-go :-), it is a memory hog. So I went back to C, but I found no decent web library. The Gnu libmicrohttpd is an API horror, a throwback from the 80's.. Since decoding a HTTP request is less than a 1000 lines of code, and that is all it offers, there was no point going with the aggravation.

Then I wanted a single access point (port) per machine, because managing port number assignments is a hassle: the portal concept came from there.

I will add some screen dumps. You are right: without these it is hard to visualize what the applications offer. Warning: I have a minimalistic and utilitarian view of UI. A colleague once joked that my GUIs are mostly text-based. :-)

Thanks.

pascal-fb-martin avatar Apr 17 '22 19:04 pascal-fb-martin

What a great story! I especially loved your decision tree to C. No doubt about it, it is as close to the metal as you can get, well practically anyway. A friend of mine is convinced that he can compiled to assembly by hand better than any CC. I told him, no thanks! :)

If you do decide to try on python (e.g. TinyTuya) for your next project, its not difficult to set it up as a service. I have several python services running and actually put the steps in one of my github projects called SentryPi. The service is stupid simple, but the steps to turn a python app into a service may be useful to you.

I hear you on the power outages! SoCal here too. When we added solar, I went with Tesla and the Powerwalls. I love the whole house backup and being completely off the grid, but better than that is the rich set of APIs I discovered. Check out my Powerwall-Dashboard and pyPowerwall projects sometime. I suppose there is a payback curve on solar, but after I found the APIs, I discovered it was worth it as a hobby/toy too. ;-)

jasonacox avatar Apr 17 '22 23:04 jasonacox

Actually, "close to the metal" was more of a downside.

Memory and string management in C is a chore, so I chose to waste memory and accept size limits rather than recreating a memory management runtime.

JavaScript's performances were fine and memory footprint was OK: a steady 32 MB to run a monolythic sprinkler controller (after optimizations). That was still within the range for runing multiple microservices on a 512 MB RPI Zero.. I target 10 microservices per machine.

I have seen reports that Rust is as fast as C, if not faster (less aliasing effects as C). The fixed cost of the Rust runtime is apparently much smaller than Node.js, way below Go or Java.

Overall Rust may be my prime choice when it stabilizes. I am not planning to abandon C (or echttp), just likely to use Rust for new applications that manipulate a lot of variable-length strings. That may become a trilingual environment (I do use JavaScript for web UI).

pascal-fb-martin avatar Apr 18 '22 17:04 pascal-fb-martin

I just added a (crude) gallery of screenshots (with explanations) to the houseportal project. The HousePortal is minimal, since the service does all its work in the background, automatically. Let me know If that answer your UI question.

Otherwise I misread your previous note. I do not know yet if I would write a Python service, but I will certainly start using your tinytuya API first, to get a sense of how it works. I do not dislike Python: I have found it reasonably easy to use. But I want to assess first how complex is the Tuya protocol (including encryption, but I do have some experience with openssl).

What control I need is minimal, i.e. turning lights on and off, no dimmer or color support, as my goal is to schedule light activity when we are not home. I might look at more sophisticated feature later (scenes, IFTTT-like logic between services, etc) but that is not my short term goal.

I am in the process of creating a better service management: centralized configuration management service--to avoid manual transfer of configuration when migrating a service--and centralized log storage service. If I want all my services to benefit from this environment, I may have to create a Python library for these support services. This would be a significant time investment. On the other side, this also opens the door to more people creating services. My immediate problem is that I cannot invest a lot of time to this in the short term: I do have a day job. :-)

pascal-fb-martin avatar Apr 19 '22 05:04 pascal-fb-martin

I also added galleries for the HouseKasa and HouseLights services. This way it shows a complete line of services involved with light automation. I will probably add some more in the coming days, since it is pretty easy.

BTW, my philosophy is in line with what someone was saying when complaining about TP-Link locking up their device in the UK: "home automation" is about making the home react autonomously, not just about adding buttons in a phone app. This guy was doing a lot more automation than scheduling lights..

pascal-fb-martin avatar Apr 21 '22 05:04 pascal-fb-martin

Looks great!

jasonacox avatar Apr 23 '22 04:04 jasonacox

Thank you for being kind.

The files examples/bulb-scene.py and examples/bulb.py contain an actual ID, IP address and local key set (as default, apparently). Is not that risky? Why not use devices.json?

Otherwise when I use async_send_receive.py, the bulb answers to the first status request, but remain silent after that. Any idea what I did wrong? (I replaced the placeholders with my actual IP, ID and key, obviously.) -- Hoops: I did not notice that the loop was sending heartbeats, not status requests. I do receive status changes after that..

pascal-fb-martin avatar Apr 23 '22 23:04 pascal-fb-martin

Hi @pascal-fb-martin,

Yes, these are bogus credentials in the examples. A person could abstract those by using an external file if desired. I think I have a snapshot example that does use snapshot.json to do that. However, I'm big on easy of use and approach with the intent that even a novice python learner can start controlling their Tuya ecosystem with little friction, hence the straightforward approach.

You are right on the async example. If you run it as-is, the loop will only show state changes coming from the device. This is how Tuya devices work, they only send updates when something changes unless you specifically ask for status. If you monitor a Tuya switch, you will see events come in if you manually toggle the switch, for example. The Hearbeat is important or the Tuya device will timeout the TCP connection.

The SOC Tuya software is fairly basic and non-robust. It is single threaded (usually only one TCP connection allowed at a time) and you will see that even with the hearbeat, a connection may eventually fail (likely an ESP reboot) so a more robust async loop would handle connection errors on the heartbeat and re-establish a persistent connection. There are more elegant ways to use python threading for async calls where you set up the connection and your functions wait for events, but that requires more sophisticated programming (localtuya does this for example for home assistant). My design principle for TinyTuya was to make it approachable for all levels of python developers, where they only need to sling 4 lines of python code to turn on a switch. :)

jasonacox avatar Apr 24 '22 15:04 jasonacox

I did not mean to criticize tinytuya. I sent my comment too early, I corrected it later. Sorry.

TCP: that also includes if there is a switch and the bulb is turned off. That is one reason why I like using UDP for this type of applications. If you don't get the answer, just repeat the request. Much simpler than managing a TCP context that you do not really need. (Even if you use TCP and the connection is lost, you need to repeat the request. That does not mean that I would always prefer UDP, but in the case when the data is small and fits in an Ethernet packet, and the protocol is question/response, then you don't really take advantage of the TCP benefits.)

pascal-fb-martin avatar Apr 24 '22 21:04 pascal-fb-martin

No worries! I didn't see it as criticism. Those are valid observations, some of which is just about the Tuya devices themselves. I agree on the UDP point. I wish they had a more robust API that included UDP status and control. But to be fair, at least they have a way to control them outside of the cloud.

jasonacox avatar Apr 24 '22 22:04 jasonacox