Giter VIP home page Giter VIP logo

mihai-dinculescu / tapo Goto Github PK

View Code? Open in Web Editor NEW
316.0 10.0 30.0 458 KB

Unofficial Tapo API Client. Works with TP-Link Tapo smart devices. Tested with light bulbs (L510, L520, L530, L610, L630), light strips (L900, L920, L930), plugs (P100, P105, P110, P115, P300), hubs (H100), switches (S200B) and sensors (KE100, T100, T110, T300, T310, T315).

License: MIT License

Rust 84.02% Python 15.98%
smart-home tapo l530 l510 p100 p110 iot

tapo's Introduction

Tapo

License Crates Documentation Crates.io PyPI Python PyPI
Unofficial Tapo API Client. Works with TP-Link Tapo smart devices. Tested with light bulbs (L510, L520, L530, L610, L630), light strips (L900, L920, L930), plugs (P100, P105, P110, P115, P300), hubs (H100), switches (S200B) and sensors (KE100, T100, T110, T300, T310, T315).

Device support

✓ - Rust only
✅ - Rust and Python

Feature


GenericDevice


L510
L520
L610
L530
L630

L900


L920
L930

P100
P105

P110
P115

P300


H100


device_reset
get_child_device_component_list_json
get_child_device_list
get_child_device_list_json
get_current_power
get_device_info
get_device_info_json
get_device_usage
get_energy_data
get_energy_usage
off
on
refresh_session
set_brightness
set_color
set_color_temperature
set_hue_saturation
set_lighting_effect
set() API *

* The set() API allows multiple properties to be set in a single request.

Hub (H100) Child Devices Support

Feature

KE100

S200B

T100

T110

T300

T310
T315
get_device_info *
get_device_info_json
get_temperature_humidity_records
get_trigger_logs
set_child_protection
set_frost_protection
set_max_control_temperature
set_min_control_temperature
set_target_temperature
set_temperature_offset

* Obtained by calling get_child_device_list on the hub device or get_device_info on a child device handler.

Rust

Usage

Cargo.toml

[dependencies]
tapo = "0.7"

main.rs

let device = ApiClient::new("<tapo-username>", "tapo-password")?
    .p110("<device ip address>")
    .await?;

device.on().await?;

Examples

export TAPO_USERNAME=
export TAPO_PASSWORD=
export IP_ADDRESS=

cargo run --example tapo_l530

See all examples in /tapo/examples.

Wrapper REST API

tapo-rest is a REST wrapper of this library that can be deployed as a service or serve as an advanced example.

Python

Usage

pip install tapo
client = ApiClient("<tapo-username>", "tapo-password")
device = await client.p110("<device ip address>")

await device.on()

Examples

cd tapo-py
poetry install
poetry shell

export TAPO_USERNAME=
export TAPO_PASSWORD=
export IP_ADDRESS=
python examples/tapo_p110.py

See all examples in /tapo-py/examples.

Contributing

Contributions are welcome and encouraged! See /CONTRIBUTING.md.

Troubleshooting

1. Installing openssl on Windows

With chocolatey

choco install openssl
[System.Environment]::SetEnvironmentVariable('OPENSSL_DIR', $Env:Programfiles + "\OpenSSL-Win64", "User")

or with vcpkg

git clone git@github.com:microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.bat
./vcpkg.exe install openssl-windows:x64-windows
./vcpkg.exe install openssl:x64-windows-static
./vcpkg.exe integrate install
[System.Environment]::SetEnvironmentVariable('OPENSSL_DIR', (Get-Location).Path + "\installed\x64-windows-static", "User")

Credits

Inspired by petretiandrea/plugp100.

tapo's People

Contributors

clementnerma avatar dependabot[bot] avatar felixhauptmann avatar michal-szczepaniak avatar mihai-dinculescu avatar pwoerndle avatar skoky 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

tapo's Issues

HELP request on code, not execution issue.

First, I do not use Rust (and do not plan on this). Therefore this question on my issues getting the CHILD DEVICES up and running using groovy on the Hubitat platform. I can control normal devices and get data (device info, child device list, child device components) successfully. Making the final step is not working.

Simple request: debug log data for when a child get_device_info and get_trigger_logs are implemented. This data should solve my format issues.

From a very old man, thanks in advance. Deve

How to actually use this?

I have no idea how to use this Python code and the README and examples don't make this clear. Import tapo, but import from what? I tried renaming tapo.pyi, but this just throws errors about the classes like PlugHandler being undefined. Could you explain how this Python code should actually be used? It would be nice to have a step-by-step in the README.

Copy/pasting the Python examples and running it doesn't work.

Docker image and rest api

Great repo!

It really would be helpful to have a Docker image and.a REST api for
easy usage from different environmenta as NodeRED or others.

Can we wait for such features in this repo or are there repos
out there for these features which could be mentioned in the README?

P300 support

Hi, I haven't seen on the list of supported devices any power bar and since i'm thinking of buying one from tapo so that i don't have to implement yet another api i was thinking if it would be possible to add support for it?

From my previous contribution, once i have the device i don't see any issue in adding missing features (i imagine it will need metod for turning each slot on/off and maybe getting statistics per slot other than that it will probably inherit much of plug stuff), but I was wondering if there's maybe something you know of that would prevent me from adding support for them?

If you see no obstacles feel free to respond and close the issue and I'll be back with PR!

H100 initialization attempt returns error

Just saw that H100 just got supported - exciting! But when I played with it (in python), I got the following
AttributeError: 'builtins.ApiClient' object has no attribute 'h100'. Did you mean: 'p100'?`

I'm not a developer so I'm not sure how to fix the issue.

S500D support

Thanks for building this and making it easy to use/install via pip!

I am able to turn my Tapo S500D smart dimmer switch on and off using the tapo library's generic device, but I'm unable to run this sample code, getting an error in the get_device_info() line.

client = ApiClient(USER,PW)
device = await client.generic_device(TAPO_IPADDR)
device_info = await device.get_device_info()
if device_info.device_on == True:
    print("Device is on. Turning it off...")
    await device.off()
elif device_info.device_on == False:
    print("Device is off. Turning it on...")
    await device.on()
else:
    print("This device does not support on/off functionality.")

The error is

File "/home/alarm_user/alarm2024/tapotest.py", line 14, in main
device_info = await device.get_device_info()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Exception: Serde(Error("missing field `overheated`", line: 1, column: 813))  

Python 3.11.2, tapo 0.3.0 installed via pip 24.0 on a raspberry pi running Raspbian GNU/Linux 12 (bookworm)

Support for KE100 (TRV) via H100

Hi everyone,
I recently got a kit with a H100 (https://www.tp-link.com/en/home-networking/smart-hub/tapo-h100/) Hub and a KE100 (https://www.tp-link.com/en/home-networking/smart-thermostat/ke100/) thermostat.

Following some of the examples for other child devices on the hub I was able to create the code read data from the KE100 attached to the hub. I'm struggling to get write operations going for the KE100 e.g. to set the target temperature.

Did you foresee write operations to child devices on the hub? Do you have any examples I could follow to maybe translate to operations on the KE100 TRV?

Python support/examples for L530 please

I've just joined the github community to congratulate mihai-dinculescu for the great tapo package. Unfortunately i don't know rast, but i am at home with python. Please add python support for lights, in particular the l530 light bulb. Thank you very very much. 8)

get_device_info broken for L900

Reproduction:

use tapo::ApiClient;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
  let tapo_username = env::var("TAPO_USERNAME")?;
  let tapo_password = env::var("TAPO_PASSWORD")?;
  let ip_address = env::var("IP_ADDRESS")?;

  let device = ApiClient::new(tapo_username, tapo_password)
    .l900(ip_address)
    .await?;
  let device_info = device.get_device_info().await?;

Result:
Error: Serde(Error("missing field `dynamic_light_effect_enable`", line: 1, column: 1052))

get_device_info_json is working correctly.

The issue seems to be that api_client.rs is implementing L900 support using a ColorLightHandler rather than a ColorLightStripHandler. The L900 model is in fact a light strip and doesn't seem to return the dynamic_light_effect_enable and dynamic_light_effect_id fields in the JSON, which Serde expects.

Changing this in the ApiClient::l900 function builds in Rust and fixes the issue, but breaks the Python build as tapo-py doesn't support light strips.

Panic in p110.get_device_info()

I'm using this tapo API to fetch the status of some P110 plugs with Python.
I got this rust panic while fetching the status:

Dec 02 05:56:09 raspberrypi python3[2031047]: thread 'tokio-runtime-worker' panicked at tapo/src/api/protocol/klap_cipher.rs:61:26:
Dec 02 05:56:09 raspberrypi python3[2031047]: range start index 32 out of range for slice of length 0
Dec 02 05:56:09 raspberrypi python3[2031047]: note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
Dec 02 05:56:09 raspberrypi python3[2031047]: Traceback (most recent call last):
...
Dec 02 05:56:09 raspberrypi python3[2031047]: File "/usr/local/bin/tapo-standby-killer.py", line 38, in readDeviceOn
Dec 02 05:56:09 raspberrypi python3[2031047]: device_info = await p110.get_device_info()
Dec 02 05:56:09 raspberrypi python3[2031047]: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Dec 02 05:56:09 raspberrypi python3[2031047]: pyo3_asyncio.RustPanic: rust future panicked

It's likely the device became unreachable after a successful connection with p110 = await client.p110(ip).
I was also wondering if, instead of just panicking, there is a better way to pass up an exception to the Python layer that it is easier to catch.

ImportError: cannot import name 'ApiClient' from partially initialized module 'tapo' (most likely due to a circular import)

Install pip module with pip install tapo

Get error when run python file python /home/admin/tapo.py
ImportError: cannot import name 'ApiClient' from partially initialized module 'tapo' (most likely due to a circular import) (/home/admin/tapo.py)

tapo.py

import asyncio
from tapo import ApiClient

async def main():
    client = ApiClient("[email protected]", "xxxx")
    device = await client.l530("192.168.x.xx")

    await device.off()
    
asyncio.run(main())

Can't compile `curl-sys v0.4.68+curl-8.4.0` on M1 Pro with Sonoma

Hello, I started a new project with tokio and this library as dependencies, but I'm getting a compilation error for curl-sys v0.4.68+curl-8.4.0 when I try to cargo run.

From what I can see from the dependency tree, curl-sys it's a dependency of isahc, and since this library needs gcc12, I (re)installed it by using brew install gcc@12.

Not sure if this a problem of the latest MacOS update (Sonoma), or if M1 Macs are even supported, can anyone help me debug this or should I open an issue upstream? 🙏

Stack trace
   Compiling curl-sys v0.4.68+curl-8.4.0
The following warnings were emitted during compilation:

warning: curl/lib/cf-socket.c: In function 'do_connect':
warning: curl/lib/cf-socket.c:1114:8: warning: implicit declaration of function '__builtin_available'; did you mean '__builtin_scalbl'? [-Wimplicit-function-declaration]
warning:  1114 |     if(__builtin_available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) {
warning:       |        ^~~~~~~~~~~~~~~~~~~
warning:       |        __builtin_scalbl
warning: curl/lib/cf-socket.c:1114:28: error: 'macOS' undeclared (first use in this function)
warning:  1114 |     if(__builtin_available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) {
warning:       |                            ^~~~~
warning: curl/lib/cf-socket.c:1114:28: note: each undeclared identifier is reported only once for each function it appears in
warning: curl/lib/cf-socket.c:1114:33: error: expected ')' before numeric constant
warning:  1114 |     if(__builtin_available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) {
warning:       |                           ~     ^~~~~~
warning:       |                                 )

error: failed to run custom build command for `curl-sys v0.4.68+curl-8.4.0`

Caused by:
  process didn't exit successfully: `/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-ac90b2d252e505dd/build-script-build` (exit status: 1)
  --- stdout
  cargo:rerun-if-changed=curl
  OPT_LEVEL = Some("0")
  TARGET = Some("aarch64-apple-darwin")
  HOST = Some("aarch64-apple-darwin")
  cargo:rerun-if-env-changed=CC_aarch64-apple-darwin
  CC_aarch64-apple-darwin = None
  cargo:rerun-if-env-changed=CC_aarch64_apple_darwin
  CC_aarch64_apple_darwin = None
  cargo:rerun-if-env-changed=HOST_CC
  HOST_CC = None
  cargo:rerun-if-env-changed=CC
  CC = Some("/opt/homebrew/bin/gcc-12")
  cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
  CRATE_CC_NO_DEFAULTS = None
  DEBUG = Some("true")
  CARGO_CFG_TARGET_FEATURE = Some("aes,crc,dit,dotprod,dpb,dpb2,fcma,fhm,flagm,fp16,frintts,jsconv,lor,lse,neon,paca,pacg,pan,pmuv3,ras,rcpc,rcpc2,rdm,sb,sha2,sha3,ssbs,vh")
  cargo:rerun-if-env-changed=CFLAGS_aarch64-apple-darwin
  CFLAGS_aarch64-apple-darwin = None
  cargo:rerun-if-env-changed=CFLAGS_aarch64_apple_darwin
  CFLAGS_aarch64_apple_darwin = None
  cargo:rerun-if-env-changed=HOST_CFLAGS
  HOST_CFLAGS = None
  cargo:rerun-if-env-changed=CFLAGS
  CFLAGS = None
  cargo:rustc-link-lib=clang_rt.osx
  cargo:rustc-link-search=/opt/homebrew/Cellar/gcc@12/12.3.0/bin/../lib/gcc/12/gcc/aarch64-apple-darwin23/12/:/opt/homebrew/Cellar/gcc@12/12.3.0/bin/../lib/gcc/12/gcc/:/opt/homebrew/Cellar/gcc@12/12.3.0/bin/../lib/gcc/12/gcc/aarch64-apple-darwin23/12/../../../../../../aarch64-apple-darwin23/lib/aarch64-apple-darwin23/12/:/opt/homebrew/Cellar/gcc@12/12.3.0/bin/../lib/gcc/12/gcc/aarch64-apple-darwin23/12/../../../../../../aarch64-apple-darwin23/lib/:/opt/homebrew/Cellar/gcc@12/12.3.0/bin/../lib/gcc/12/gcc/aarch64-apple-darwin23/12/../../../aarch64-apple-darwin23/12/:/opt/homebrew/Cellar/gcc@12/12.3.0/bin/../lib/gcc/12/gcc/aarch64-apple-darwin23/12/../../..//lib/darwin
  cargo:root=/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out
  cargo:include=/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out/include
  cargo:static=1
  cargo:rustc-cfg=libcurl_vendored
  cargo:rustc-cfg=link_libnghttp2
  cargo:rustc-cfg=link_libz
  /Library/Developer/CommandLineTools
  unable to determine Xcode version, assuming >= 9
  TARGET = Some("aarch64-apple-darwin")
  OPT_LEVEL = Some("0")
  HOST = Some("aarch64-apple-darwin")
  cargo:rerun-if-env-changed=CC_aarch64-apple-darwin
  CC_aarch64-apple-darwin = None
  cargo:rerun-if-env-changed=CC_aarch64_apple_darwin
  CC_aarch64_apple_darwin = None
  cargo:rerun-if-env-changed=HOST_CC
  HOST_CC = None
  cargo:rerun-if-env-changed=CC
  CC = Some("/opt/homebrew/bin/gcc-12")
  cargo:rerun-if-env-changed=CRATE_CC_NO_DEFAULTS
  CRATE_CC_NO_DEFAULTS = None
  DEBUG = Some("true")
  CARGO_CFG_TARGET_FEATURE = Some("aes,crc,dit,dotprod,dpb,dpb2,fcma,fhm,flagm,fp16,frintts,jsconv,lor,lse,neon,paca,pacg,pan,pmuv3,ras,rcpc,rcpc2,rdm,sb,sha2,sha3,ssbs,vh")
  cargo:rerun-if-env-changed=CFLAGS_aarch64-apple-darwin
  CFLAGS_aarch64-apple-darwin = None
  cargo:rerun-if-env-changed=CFLAGS_aarch64_apple_darwin
  CFLAGS_aarch64_apple_darwin = None
  cargo:rerun-if-env-changed=HOST_CFLAGS
  HOST_CFLAGS = None
  cargo:rerun-if-env-changed=CFLAGS
  CFLAGS = None
  running: "/opt/homebrew/bin/gcc-12" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-2" "-fno-omit-frame-pointer" "-arch" "arm64" "-I" "curl/lib" "-I" "curl/include" "-I" "/Users/mercxry/code/dirty-laundry/target/debug/build/libnghttp2-sys-c8a5d2cb9803c3bb/out/i/include" "-fvisibility=hidden" "-DBUILDING_LIBCURL" "-DCURL_DISABLE_DICT" "-DCURL_DISABLE_GOPHER" "-DCURL_DISABLE_IMAP" "-DCURL_DISABLE_LDAP" "-DCURL_DISABLE_LDAPS" "-DCURL_DISABLE_POP3" "-DCURL_DISABLE_RTSP" "-DCURL_DISABLE_SMB" "-DCURL_DISABLE_SMTP" "-DCURL_DISABLE_TELNET" "-DCURL_DISABLE_TFTP" "-DCURL_STATICLIB" "-DENABLE_IPV6" "-DHAVE_ASSERT_H" "-DOS=\"unknown\"" "-DHAVE_ZLIB_H" "-DHAVE_LONGLONG" "-DHAVE_LIBZ" "-DHAVE_BOOL_T" "-DHAVE_STDBOOL_H" "-DHAVE_GETADDRINFO" "-DHAVE_GETPEERNAME" "-DHAVE_GETSOCKNAME" "-DCURL_DISABLE_NTLM" "-DCURL_DISABLE_FTP" "-DUSE_NGHTTP2" "-DNGHTTP2_STATICLIB" "-DUSE_SECTRANSP" "-DHAVE_BUILTIN_AVAILABLE=1" "-DRECV_TYPE_ARG1=int" "-DHAVE_PTHREAD_H" "-DHAVE_ARPA_INET_H" "-DHAVE_ERRNO_H" "-DHAVE_FCNTL_H" "-DHAVE_NETDB_H" "-DHAVE_NETINET_IN_H" "-DHAVE_NETINET_TCP_H" "-DHAVE_POLL_H" "-DHAVE_FCNTL_O_NONBLOCK" "-DHAVE_SYS_SELECT_H" "-DHAVE_SYS_STAT_H" "-DHAVE_SYS_TIME_H" "-DHAVE_UNISTD_H" "-DHAVE_RECV" "-DHAVE_SELECT" "-DHAVE_SEND" "-DHAVE_SOCKET" "-DHAVE_STERRROR_R" "-DHAVE_SOCKETPAIR" "-DHAVE_STRUCT_TIMEVAL" "-DHAVE_SYS_UN_H" "-DUSE_THREADS_POSIX" "-DUSE_UNIX_SOCKETS" "-DRECV_TYPE_ARG2=void*" "-DRECV_TYPE_ARG3=size_t" "-DRECV_TYPE_ARG4=int" "-DRECV_TYPE_RETV=ssize_t" "-DSEND_QUAL_ARG2=const" "-DSEND_TYPE_ARG1=int" "-DSEND_TYPE_ARG2=void*" "-DSEND_TYPE_ARG3=size_t" "-DSEND_TYPE_ARG4=int" "-DSEND_TYPE_RETV=ssize_t" "-DSIZEOF_CURL_OFF_T=8" "-DSIZEOF_INT=4" "-DSIZEOF_SHORT=2" "-D__APPLE__" "-DHAVE_MACH_ABSOLUTE_TIME" "-DSIZEOF_SSIZE_T=8" "-DSIZEOF_SIZE_T=8" "-DSIZEOF_LONG=8" "-o" "/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out/build/curl/lib/asyn-thread.o" "-c" "curl/lib/asyn-thread.c"
  exit status: 0
  running: "/opt/homebrew/bin/gcc-12" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-2" "-fno-omit-frame-pointer" "-arch" "arm64" "-I" "curl/lib" "-I" "curl/include" "-I" "/Users/mercxry/code/dirty-laundry/target/debug/build/libnghttp2-sys-c8a5d2cb9803c3bb/out/i/include" "-fvisibility=hidden" "-DBUILDING_LIBCURL" "-DCURL_DISABLE_DICT" "-DCURL_DISABLE_GOPHER" "-DCURL_DISABLE_IMAP" "-DCURL_DISABLE_LDAP" "-DCURL_DISABLE_LDAPS" "-DCURL_DISABLE_POP3" "-DCURL_DISABLE_RTSP" "-DCURL_DISABLE_SMB" "-DCURL_DISABLE_SMTP" "-DCURL_DISABLE_TELNET" "-DCURL_DISABLE_TFTP" "-DCURL_STATICLIB" "-DENABLE_IPV6" "-DHAVE_ASSERT_H" "-DOS=\"unknown\"" "-DHAVE_ZLIB_H" "-DHAVE_LONGLONG" "-DHAVE_LIBZ" "-DHAVE_BOOL_T" "-DHAVE_STDBOOL_H" "-DHAVE_GETADDRINFO" "-DHAVE_GETPEERNAME" "-DHAVE_GETSOCKNAME" "-DCURL_DISABLE_NTLM" "-DCURL_DISABLE_FTP" "-DUSE_NGHTTP2" "-DNGHTTP2_STATICLIB" "-DUSE_SECTRANSP" "-DHAVE_BUILTIN_AVAILABLE=1" "-DRECV_TYPE_ARG1=int" "-DHAVE_PTHREAD_H" "-DHAVE_ARPA_INET_H" "-DHAVE_ERRNO_H" "-DHAVE_FCNTL_H" "-DHAVE_NETDB_H" "-DHAVE_NETINET_IN_H" "-DHAVE_NETINET_TCP_H" "-DHAVE_POLL_H" "-DHAVE_FCNTL_O_NONBLOCK" "-DHAVE_SYS_SELECT_H" "-DHAVE_SYS_STAT_H" "-DHAVE_SYS_TIME_H" "-DHAVE_UNISTD_H" "-DHAVE_RECV" "-DHAVE_SELECT" "-DHAVE_SEND" "-DHAVE_SOCKET" "-DHAVE_STERRROR_R" "-DHAVE_SOCKETPAIR" "-DHAVE_STRUCT_TIMEVAL" "-DHAVE_SYS_UN_H" "-DUSE_THREADS_POSIX" "-DUSE_UNIX_SOCKETS" "-DRECV_TYPE_ARG2=void*" "-DRECV_TYPE_ARG3=size_t" "-DRECV_TYPE_ARG4=int" "-DRECV_TYPE_RETV=ssize_t" "-DSEND_QUAL_ARG2=const" "-DSEND_TYPE_ARG1=int" "-DSEND_TYPE_ARG2=void*" "-DSEND_TYPE_ARG3=size_t" "-DSEND_TYPE_ARG4=int" "-DSEND_TYPE_RETV=ssize_t" "-DSIZEOF_CURL_OFF_T=8" "-DSIZEOF_INT=4" "-DSIZEOF_SHORT=2" "-D__APPLE__" "-DHAVE_MACH_ABSOLUTE_TIME" "-DSIZEOF_SSIZE_T=8" "-DSIZEOF_SIZE_T=8" "-DSIZEOF_LONG=8" "-o" "/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out/build/curl/lib/altsvc.o" "-c" "curl/lib/altsvc.c"
  exit status: 0
  running: "/opt/homebrew/bin/gcc-12" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-2" "-fno-omit-frame-pointer" "-arch" "arm64" "-I" "curl/lib" "-I" "curl/include" "-I" "/Users/mercxry/code/dirty-laundry/target/debug/build/libnghttp2-sys-c8a5d2cb9803c3bb/out/i/include" "-fvisibility=hidden" "-DBUILDING_LIBCURL" "-DCURL_DISABLE_DICT" "-DCURL_DISABLE_GOPHER" "-DCURL_DISABLE_IMAP" "-DCURL_DISABLE_LDAP" "-DCURL_DISABLE_LDAPS" "-DCURL_DISABLE_POP3" "-DCURL_DISABLE_RTSP" "-DCURL_DISABLE_SMB" "-DCURL_DISABLE_SMTP" "-DCURL_DISABLE_TELNET" "-DCURL_DISABLE_TFTP" "-DCURL_STATICLIB" "-DENABLE_IPV6" "-DHAVE_ASSERT_H" "-DOS=\"unknown\"" "-DHAVE_ZLIB_H" "-DHAVE_LONGLONG" "-DHAVE_LIBZ" "-DHAVE_BOOL_T" "-DHAVE_STDBOOL_H" "-DHAVE_GETADDRINFO" "-DHAVE_GETPEERNAME" "-DHAVE_GETSOCKNAME" "-DCURL_DISABLE_NTLM" "-DCURL_DISABLE_FTP" "-DUSE_NGHTTP2" "-DNGHTTP2_STATICLIB" "-DUSE_SECTRANSP" "-DHAVE_BUILTIN_AVAILABLE=1" "-DRECV_TYPE_ARG1=int" "-DHAVE_PTHREAD_H" "-DHAVE_ARPA_INET_H" "-DHAVE_ERRNO_H" "-DHAVE_FCNTL_H" "-DHAVE_NETDB_H" "-DHAVE_NETINET_IN_H" "-DHAVE_NETINET_TCP_H" "-DHAVE_POLL_H" "-DHAVE_FCNTL_O_NONBLOCK" "-DHAVE_SYS_SELECT_H" "-DHAVE_SYS_STAT_H" "-DHAVE_SYS_TIME_H" "-DHAVE_UNISTD_H" "-DHAVE_RECV" "-DHAVE_SELECT" "-DHAVE_SEND" "-DHAVE_SOCKET" "-DHAVE_STERRROR_R" "-DHAVE_SOCKETPAIR" "-DHAVE_STRUCT_TIMEVAL" "-DHAVE_SYS_UN_H" "-DUSE_THREADS_POSIX" "-DUSE_UNIX_SOCKETS" "-DRECV_TYPE_ARG2=void*" "-DRECV_TYPE_ARG3=size_t" "-DRECV_TYPE_ARG4=int" "-DRECV_TYPE_RETV=ssize_t" "-DSEND_QUAL_ARG2=const" "-DSEND_TYPE_ARG1=int" "-DSEND_TYPE_ARG2=void*" "-DSEND_TYPE_ARG3=size_t" "-DSEND_TYPE_ARG4=int" "-DSEND_TYPE_RETV=ssize_t" "-DSIZEOF_CURL_OFF_T=8" "-DSIZEOF_INT=4" "-DSIZEOF_SHORT=2" "-D__APPLE__" "-DHAVE_MACH_ABSOLUTE_TIME" "-DSIZEOF_SSIZE_T=8" "-DSIZEOF_SIZE_T=8" "-DSIZEOF_LONG=8" "-o" "/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out/build/curl/lib/base64.o" "-c" "curl/lib/base64.c"
  exit status: 0
  running: "/opt/homebrew/bin/gcc-12" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-2" "-fno-omit-frame-pointer" "-arch" "arm64" "-I" "curl/lib" "-I" "curl/include" "-I" "/Users/mercxry/code/dirty-laundry/target/debug/build/libnghttp2-sys-c8a5d2cb9803c3bb/out/i/include" "-fvisibility=hidden" "-DBUILDING_LIBCURL" "-DCURL_DISABLE_DICT" "-DCURL_DISABLE_GOPHER" "-DCURL_DISABLE_IMAP" "-DCURL_DISABLE_LDAP" "-DCURL_DISABLE_LDAPS" "-DCURL_DISABLE_POP3" "-DCURL_DISABLE_RTSP" "-DCURL_DISABLE_SMB" "-DCURL_DISABLE_SMTP" "-DCURL_DISABLE_TELNET" "-DCURL_DISABLE_TFTP" "-DCURL_STATICLIB" "-DENABLE_IPV6" "-DHAVE_ASSERT_H" "-DOS=\"unknown\"" "-DHAVE_ZLIB_H" "-DHAVE_LONGLONG" "-DHAVE_LIBZ" "-DHAVE_BOOL_T" "-DHAVE_STDBOOL_H" "-DHAVE_GETADDRINFO" "-DHAVE_GETPEERNAME" "-DHAVE_GETSOCKNAME" "-DCURL_DISABLE_NTLM" "-DCURL_DISABLE_FTP" "-DUSE_NGHTTP2" "-DNGHTTP2_STATICLIB" "-DUSE_SECTRANSP" "-DHAVE_BUILTIN_AVAILABLE=1" "-DRECV_TYPE_ARG1=int" "-DHAVE_PTHREAD_H" "-DHAVE_ARPA_INET_H" "-DHAVE_ERRNO_H" "-DHAVE_FCNTL_H" "-DHAVE_NETDB_H" "-DHAVE_NETINET_IN_H" "-DHAVE_NETINET_TCP_H" "-DHAVE_POLL_H" "-DHAVE_FCNTL_O_NONBLOCK" "-DHAVE_SYS_SELECT_H" "-DHAVE_SYS_STAT_H" "-DHAVE_SYS_TIME_H" "-DHAVE_UNISTD_H" "-DHAVE_RECV" "-DHAVE_SELECT" "-DHAVE_SEND" "-DHAVE_SOCKET" "-DHAVE_STERRROR_R" "-DHAVE_SOCKETPAIR" "-DHAVE_STRUCT_TIMEVAL" "-DHAVE_SYS_UN_H" "-DUSE_THREADS_POSIX" "-DUSE_UNIX_SOCKETS" "-DRECV_TYPE_ARG2=void*" "-DRECV_TYPE_ARG3=size_t" "-DRECV_TYPE_ARG4=int" "-DRECV_TYPE_RETV=ssize_t" "-DSEND_QUAL_ARG2=const" "-DSEND_TYPE_ARG1=int" "-DSEND_TYPE_ARG2=void*" "-DSEND_TYPE_ARG3=size_t" "-DSEND_TYPE_ARG4=int" "-DSEND_TYPE_RETV=ssize_t" "-DSIZEOF_CURL_OFF_T=8" "-DSIZEOF_INT=4" "-DSIZEOF_SHORT=2" "-D__APPLE__" "-DHAVE_MACH_ABSOLUTE_TIME" "-DSIZEOF_SSIZE_T=8" "-DSIZEOF_SIZE_T=8" "-DSIZEOF_LONG=8" "-o" "/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out/build/curl/lib/bufq.o" "-c" "curl/lib/bufq.c"
  exit status: 0
  running: "/opt/homebrew/bin/gcc-12" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-2" "-fno-omit-frame-pointer" "-arch" "arm64" "-I" "curl/lib" "-I" "curl/include" "-I" "/Users/mercxry/code/dirty-laundry/target/debug/build/libnghttp2-sys-c8a5d2cb9803c3bb/out/i/include" "-fvisibility=hidden" "-DBUILDING_LIBCURL" "-DCURL_DISABLE_DICT" "-DCURL_DISABLE_GOPHER" "-DCURL_DISABLE_IMAP" "-DCURL_DISABLE_LDAP" "-DCURL_DISABLE_LDAPS" "-DCURL_DISABLE_POP3" "-DCURL_DISABLE_RTSP" "-DCURL_DISABLE_SMB" "-DCURL_DISABLE_SMTP" "-DCURL_DISABLE_TELNET" "-DCURL_DISABLE_TFTP" "-DCURL_STATICLIB" "-DENABLE_IPV6" "-DHAVE_ASSERT_H" "-DOS=\"unknown\"" "-DHAVE_ZLIB_H" "-DHAVE_LONGLONG" "-DHAVE_LIBZ" "-DHAVE_BOOL_T" "-DHAVE_STDBOOL_H" "-DHAVE_GETADDRINFO" "-DHAVE_GETPEERNAME" "-DHAVE_GETSOCKNAME" "-DCURL_DISABLE_NTLM" "-DCURL_DISABLE_FTP" "-DUSE_NGHTTP2" "-DNGHTTP2_STATICLIB" "-DUSE_SECTRANSP" "-DHAVE_BUILTIN_AVAILABLE=1" "-DRECV_TYPE_ARG1=int" "-DHAVE_PTHREAD_H" "-DHAVE_ARPA_INET_H" "-DHAVE_ERRNO_H" "-DHAVE_FCNTL_H" "-DHAVE_NETDB_H" "-DHAVE_NETINET_IN_H" "-DHAVE_NETINET_TCP_H" "-DHAVE_POLL_H" "-DHAVE_FCNTL_O_NONBLOCK" "-DHAVE_SYS_SELECT_H" "-DHAVE_SYS_STAT_H" "-DHAVE_SYS_TIME_H" "-DHAVE_UNISTD_H" "-DHAVE_RECV" "-DHAVE_SELECT" "-DHAVE_SEND" "-DHAVE_SOCKET" "-DHAVE_STERRROR_R" "-DHAVE_SOCKETPAIR" "-DHAVE_STRUCT_TIMEVAL" "-DHAVE_SYS_UN_H" "-DUSE_THREADS_POSIX" "-DUSE_UNIX_SOCKETS" "-DRECV_TYPE_ARG2=void*" "-DRECV_TYPE_ARG3=size_t" "-DRECV_TYPE_ARG4=int" "-DRECV_TYPE_RETV=ssize_t" "-DSEND_QUAL_ARG2=const" "-DSEND_TYPE_ARG1=int" "-DSEND_TYPE_ARG2=void*" "-DSEND_TYPE_ARG3=size_t" "-DSEND_TYPE_ARG4=int" "-DSEND_TYPE_RETV=ssize_t" "-DSIZEOF_CURL_OFF_T=8" "-DSIZEOF_INT=4" "-DSIZEOF_SHORT=2" "-D__APPLE__" "-DHAVE_MACH_ABSOLUTE_TIME" "-DSIZEOF_SSIZE_T=8" "-DSIZEOF_SIZE_T=8" "-DSIZEOF_LONG=8" "-o" "/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out/build/curl/lib/bufref.o" "-c" "curl/lib/bufref.c"
  exit status: 0
  running: "/opt/homebrew/bin/gcc-12" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-2" "-fno-omit-frame-pointer" "-arch" "arm64" "-I" "curl/lib" "-I" "curl/include" "-I" "/Users/mercxry/code/dirty-laundry/target/debug/build/libnghttp2-sys-c8a5d2cb9803c3bb/out/i/include" "-fvisibility=hidden" "-DBUILDING_LIBCURL" "-DCURL_DISABLE_DICT" "-DCURL_DISABLE_GOPHER" "-DCURL_DISABLE_IMAP" "-DCURL_DISABLE_LDAP" "-DCURL_DISABLE_LDAPS" "-DCURL_DISABLE_POP3" "-DCURL_DISABLE_RTSP" "-DCURL_DISABLE_SMB" "-DCURL_DISABLE_SMTP" "-DCURL_DISABLE_TELNET" "-DCURL_DISABLE_TFTP" "-DCURL_STATICLIB" "-DENABLE_IPV6" "-DHAVE_ASSERT_H" "-DOS=\"unknown\"" "-DHAVE_ZLIB_H" "-DHAVE_LONGLONG" "-DHAVE_LIBZ" "-DHAVE_BOOL_T" "-DHAVE_STDBOOL_H" "-DHAVE_GETADDRINFO" "-DHAVE_GETPEERNAME" "-DHAVE_GETSOCKNAME" "-DCURL_DISABLE_NTLM" "-DCURL_DISABLE_FTP" "-DUSE_NGHTTP2" "-DNGHTTP2_STATICLIB" "-DUSE_SECTRANSP" "-DHAVE_BUILTIN_AVAILABLE=1" "-DRECV_TYPE_ARG1=int" "-DHAVE_PTHREAD_H" "-DHAVE_ARPA_INET_H" "-DHAVE_ERRNO_H" "-DHAVE_FCNTL_H" "-DHAVE_NETDB_H" "-DHAVE_NETINET_IN_H" "-DHAVE_NETINET_TCP_H" "-DHAVE_POLL_H" "-DHAVE_FCNTL_O_NONBLOCK" "-DHAVE_SYS_SELECT_H" "-DHAVE_SYS_STAT_H" "-DHAVE_SYS_TIME_H" "-DHAVE_UNISTD_H" "-DHAVE_RECV" "-DHAVE_SELECT" "-DHAVE_SEND" "-DHAVE_SOCKET" "-DHAVE_STERRROR_R" "-DHAVE_SOCKETPAIR" "-DHAVE_STRUCT_TIMEVAL" "-DHAVE_SYS_UN_H" "-DUSE_THREADS_POSIX" "-DUSE_UNIX_SOCKETS" "-DRECV_TYPE_ARG2=void*" "-DRECV_TYPE_ARG3=size_t" "-DRECV_TYPE_ARG4=int" "-DRECV_TYPE_RETV=ssize_t" "-DSEND_QUAL_ARG2=const" "-DSEND_TYPE_ARG1=int" "-DSEND_TYPE_ARG2=void*" "-DSEND_TYPE_ARG3=size_t" "-DSEND_TYPE_ARG4=int" "-DSEND_TYPE_RETV=ssize_t" "-DSIZEOF_CURL_OFF_T=8" "-DSIZEOF_INT=4" "-DSIZEOF_SHORT=2" "-D__APPLE__" "-DHAVE_MACH_ABSOLUTE_TIME" "-DSIZEOF_SSIZE_T=8" "-DSIZEOF_SIZE_T=8" "-DSIZEOF_LONG=8" "-o" "/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out/build/curl/lib/cfilters.o" "-c" "curl/lib/cfilters.c"
  exit status: 0
  running: "/opt/homebrew/bin/gcc-12" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-2" "-fno-omit-frame-pointer" "-arch" "arm64" "-I" "curl/lib" "-I" "curl/include" "-I" "/Users/mercxry/code/dirty-laundry/target/debug/build/libnghttp2-sys-c8a5d2cb9803c3bb/out/i/include" "-fvisibility=hidden" "-DBUILDING_LIBCURL" "-DCURL_DISABLE_DICT" "-DCURL_DISABLE_GOPHER" "-DCURL_DISABLE_IMAP" "-DCURL_DISABLE_LDAP" "-DCURL_DISABLE_LDAPS" "-DCURL_DISABLE_POP3" "-DCURL_DISABLE_RTSP" "-DCURL_DISABLE_SMB" "-DCURL_DISABLE_SMTP" "-DCURL_DISABLE_TELNET" "-DCURL_DISABLE_TFTP" "-DCURL_STATICLIB" "-DENABLE_IPV6" "-DHAVE_ASSERT_H" "-DOS=\"unknown\"" "-DHAVE_ZLIB_H" "-DHAVE_LONGLONG" "-DHAVE_LIBZ" "-DHAVE_BOOL_T" "-DHAVE_STDBOOL_H" "-DHAVE_GETADDRINFO" "-DHAVE_GETPEERNAME" "-DHAVE_GETSOCKNAME" "-DCURL_DISABLE_NTLM" "-DCURL_DISABLE_FTP" "-DUSE_NGHTTP2" "-DNGHTTP2_STATICLIB" "-DUSE_SECTRANSP" "-DHAVE_BUILTIN_AVAILABLE=1" "-DRECV_TYPE_ARG1=int" "-DHAVE_PTHREAD_H" "-DHAVE_ARPA_INET_H" "-DHAVE_ERRNO_H" "-DHAVE_FCNTL_H" "-DHAVE_NETDB_H" "-DHAVE_NETINET_IN_H" "-DHAVE_NETINET_TCP_H" "-DHAVE_POLL_H" "-DHAVE_FCNTL_O_NONBLOCK" "-DHAVE_SYS_SELECT_H" "-DHAVE_SYS_STAT_H" "-DHAVE_SYS_TIME_H" "-DHAVE_UNISTD_H" "-DHAVE_RECV" "-DHAVE_SELECT" "-DHAVE_SEND" "-DHAVE_SOCKET" "-DHAVE_STERRROR_R" "-DHAVE_SOCKETPAIR" "-DHAVE_STRUCT_TIMEVAL" "-DHAVE_SYS_UN_H" "-DUSE_THREADS_POSIX" "-DUSE_UNIX_SOCKETS" "-DRECV_TYPE_ARG2=void*" "-DRECV_TYPE_ARG3=size_t" "-DRECV_TYPE_ARG4=int" "-DRECV_TYPE_RETV=ssize_t" "-DSEND_QUAL_ARG2=const" "-DSEND_TYPE_ARG1=int" "-DSEND_TYPE_ARG2=void*" "-DSEND_TYPE_ARG3=size_t" "-DSEND_TYPE_ARG4=int" "-DSEND_TYPE_RETV=ssize_t" "-DSIZEOF_CURL_OFF_T=8" "-DSIZEOF_INT=4" "-DSIZEOF_SHORT=2" "-D__APPLE__" "-DHAVE_MACH_ABSOLUTE_TIME" "-DSIZEOF_SSIZE_T=8" "-DSIZEOF_SIZE_T=8" "-DSIZEOF_LONG=8" "-o" "/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out/build/curl/lib/cf-h1-proxy.o" "-c" "curl/lib/cf-h1-proxy.c"
  exit status: 0
  running: "/opt/homebrew/bin/gcc-12" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-2" "-fno-omit-frame-pointer" "-arch" "arm64" "-I" "curl/lib" "-I" "curl/include" "-I" "/Users/mercxry/code/dirty-laundry/target/debug/build/libnghttp2-sys-c8a5d2cb9803c3bb/out/i/include" "-fvisibility=hidden" "-DBUILDING_LIBCURL" "-DCURL_DISABLE_DICT" "-DCURL_DISABLE_GOPHER" "-DCURL_DISABLE_IMAP" "-DCURL_DISABLE_LDAP" "-DCURL_DISABLE_LDAPS" "-DCURL_DISABLE_POP3" "-DCURL_DISABLE_RTSP" "-DCURL_DISABLE_SMB" "-DCURL_DISABLE_SMTP" "-DCURL_DISABLE_TELNET" "-DCURL_DISABLE_TFTP" "-DCURL_STATICLIB" "-DENABLE_IPV6" "-DHAVE_ASSERT_H" "-DOS=\"unknown\"" "-DHAVE_ZLIB_H" "-DHAVE_LONGLONG" "-DHAVE_LIBZ" "-DHAVE_BOOL_T" "-DHAVE_STDBOOL_H" "-DHAVE_GETADDRINFO" "-DHAVE_GETPEERNAME" "-DHAVE_GETSOCKNAME" "-DCURL_DISABLE_NTLM" "-DCURL_DISABLE_FTP" "-DUSE_NGHTTP2" "-DNGHTTP2_STATICLIB" "-DUSE_SECTRANSP" "-DHAVE_BUILTIN_AVAILABLE=1" "-DRECV_TYPE_ARG1=int" "-DHAVE_PTHREAD_H" "-DHAVE_ARPA_INET_H" "-DHAVE_ERRNO_H" "-DHAVE_FCNTL_H" "-DHAVE_NETDB_H" "-DHAVE_NETINET_IN_H" "-DHAVE_NETINET_TCP_H" "-DHAVE_POLL_H" "-DHAVE_FCNTL_O_NONBLOCK" "-DHAVE_SYS_SELECT_H" "-DHAVE_SYS_STAT_H" "-DHAVE_SYS_TIME_H" "-DHAVE_UNISTD_H" "-DHAVE_RECV" "-DHAVE_SELECT" "-DHAVE_SEND" "-DHAVE_SOCKET" "-DHAVE_STERRROR_R" "-DHAVE_SOCKETPAIR" "-DHAVE_STRUCT_TIMEVAL" "-DHAVE_SYS_UN_H" "-DUSE_THREADS_POSIX" "-DUSE_UNIX_SOCKETS" "-DRECV_TYPE_ARG2=void*" "-DRECV_TYPE_ARG3=size_t" "-DRECV_TYPE_ARG4=int" "-DRECV_TYPE_RETV=ssize_t" "-DSEND_QUAL_ARG2=const" "-DSEND_TYPE_ARG1=int" "-DSEND_TYPE_ARG2=void*" "-DSEND_TYPE_ARG3=size_t" "-DSEND_TYPE_ARG4=int" "-DSEND_TYPE_RETV=ssize_t" "-DSIZEOF_CURL_OFF_T=8" "-DSIZEOF_INT=4" "-DSIZEOF_SHORT=2" "-D__APPLE__" "-DHAVE_MACH_ABSOLUTE_TIME" "-DSIZEOF_SSIZE_T=8" "-DSIZEOF_SIZE_T=8" "-DSIZEOF_LONG=8" "-o" "/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out/build/curl/lib/cf-haproxy.o" "-c" "curl/lib/cf-haproxy.c"
  exit status: 0
  running: "/opt/homebrew/bin/gcc-12" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-2" "-fno-omit-frame-pointer" "-arch" "arm64" "-I" "curl/lib" "-I" "curl/include" "-I" "/Users/mercxry/code/dirty-laundry/target/debug/build/libnghttp2-sys-c8a5d2cb9803c3bb/out/i/include" "-fvisibility=hidden" "-DBUILDING_LIBCURL" "-DCURL_DISABLE_DICT" "-DCURL_DISABLE_GOPHER" "-DCURL_DISABLE_IMAP" "-DCURL_DISABLE_LDAP" "-DCURL_DISABLE_LDAPS" "-DCURL_DISABLE_POP3" "-DCURL_DISABLE_RTSP" "-DCURL_DISABLE_SMB" "-DCURL_DISABLE_SMTP" "-DCURL_DISABLE_TELNET" "-DCURL_DISABLE_TFTP" "-DCURL_STATICLIB" "-DENABLE_IPV6" "-DHAVE_ASSERT_H" "-DOS=\"unknown\"" "-DHAVE_ZLIB_H" "-DHAVE_LONGLONG" "-DHAVE_LIBZ" "-DHAVE_BOOL_T" "-DHAVE_STDBOOL_H" "-DHAVE_GETADDRINFO" "-DHAVE_GETPEERNAME" "-DHAVE_GETSOCKNAME" "-DCURL_DISABLE_NTLM" "-DCURL_DISABLE_FTP" "-DUSE_NGHTTP2" "-DNGHTTP2_STATICLIB" "-DUSE_SECTRANSP" "-DHAVE_BUILTIN_AVAILABLE=1" "-DRECV_TYPE_ARG1=int" "-DHAVE_PTHREAD_H" "-DHAVE_ARPA_INET_H" "-DHAVE_ERRNO_H" "-DHAVE_FCNTL_H" "-DHAVE_NETDB_H" "-DHAVE_NETINET_IN_H" "-DHAVE_NETINET_TCP_H" "-DHAVE_POLL_H" "-DHAVE_FCNTL_O_NONBLOCK" "-DHAVE_SYS_SELECT_H" "-DHAVE_SYS_STAT_H" "-DHAVE_SYS_TIME_H" "-DHAVE_UNISTD_H" "-DHAVE_RECV" "-DHAVE_SELECT" "-DHAVE_SEND" "-DHAVE_SOCKET" "-DHAVE_STERRROR_R" "-DHAVE_SOCKETPAIR" "-DHAVE_STRUCT_TIMEVAL" "-DHAVE_SYS_UN_H" "-DUSE_THREADS_POSIX" "-DUSE_UNIX_SOCKETS" "-DRECV_TYPE_ARG2=void*" "-DRECV_TYPE_ARG3=size_t" "-DRECV_TYPE_ARG4=int" "-DRECV_TYPE_RETV=ssize_t" "-DSEND_QUAL_ARG2=const" "-DSEND_TYPE_ARG1=int" "-DSEND_TYPE_ARG2=void*" "-DSEND_TYPE_ARG3=size_t" "-DSEND_TYPE_ARG4=int" "-DSEND_TYPE_RETV=ssize_t" "-DSIZEOF_CURL_OFF_T=8" "-DSIZEOF_INT=4" "-DSIZEOF_SHORT=2" "-D__APPLE__" "-DHAVE_MACH_ABSOLUTE_TIME" "-DSIZEOF_SSIZE_T=8" "-DSIZEOF_SIZE_T=8" "-DSIZEOF_LONG=8" "-o" "/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out/build/curl/lib/cf-https-connect.o" "-c" "curl/lib/cf-https-connect.c"
  exit status: 0
  running: "/opt/homebrew/bin/gcc-12" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-2" "-fno-omit-frame-pointer" "-arch" "arm64" "-I" "curl/lib" "-I" "curl/include" "-I" "/Users/mercxry/code/dirty-laundry/target/debug/build/libnghttp2-sys-c8a5d2cb9803c3bb/out/i/include" "-fvisibility=hidden" "-DBUILDING_LIBCURL" "-DCURL_DISABLE_DICT" "-DCURL_DISABLE_GOPHER" "-DCURL_DISABLE_IMAP" "-DCURL_DISABLE_LDAP" "-DCURL_DISABLE_LDAPS" "-DCURL_DISABLE_POP3" "-DCURL_DISABLE_RTSP" "-DCURL_DISABLE_SMB" "-DCURL_DISABLE_SMTP" "-DCURL_DISABLE_TELNET" "-DCURL_DISABLE_TFTP" "-DCURL_STATICLIB" "-DENABLE_IPV6" "-DHAVE_ASSERT_H" "-DOS=\"unknown\"" "-DHAVE_ZLIB_H" "-DHAVE_LONGLONG" "-DHAVE_LIBZ" "-DHAVE_BOOL_T" "-DHAVE_STDBOOL_H" "-DHAVE_GETADDRINFO" "-DHAVE_GETPEERNAME" "-DHAVE_GETSOCKNAME" "-DCURL_DISABLE_NTLM" "-DCURL_DISABLE_FTP" "-DUSE_NGHTTP2" "-DNGHTTP2_STATICLIB" "-DUSE_SECTRANSP" "-DHAVE_BUILTIN_AVAILABLE=1" "-DRECV_TYPE_ARG1=int" "-DHAVE_PTHREAD_H" "-DHAVE_ARPA_INET_H" "-DHAVE_ERRNO_H" "-DHAVE_FCNTL_H" "-DHAVE_NETDB_H" "-DHAVE_NETINET_IN_H" "-DHAVE_NETINET_TCP_H" "-DHAVE_POLL_H" "-DHAVE_FCNTL_O_NONBLOCK" "-DHAVE_SYS_SELECT_H" "-DHAVE_SYS_STAT_H" "-DHAVE_SYS_TIME_H" "-DHAVE_UNISTD_H" "-DHAVE_RECV" "-DHAVE_SELECT" "-DHAVE_SEND" "-DHAVE_SOCKET" "-DHAVE_STERRROR_R" "-DHAVE_SOCKETPAIR" "-DHAVE_STRUCT_TIMEVAL" "-DHAVE_SYS_UN_H" "-DUSE_THREADS_POSIX" "-DUSE_UNIX_SOCKETS" "-DRECV_TYPE_ARG2=void*" "-DRECV_TYPE_ARG3=size_t" "-DRECV_TYPE_ARG4=int" "-DRECV_TYPE_RETV=ssize_t" "-DSEND_QUAL_ARG2=const" "-DSEND_TYPE_ARG1=int" "-DSEND_TYPE_ARG2=void*" "-DSEND_TYPE_ARG3=size_t" "-DSEND_TYPE_ARG4=int" "-DSEND_TYPE_RETV=ssize_t" "-DSIZEOF_CURL_OFF_T=8" "-DSIZEOF_INT=4" "-DSIZEOF_SHORT=2" "-D__APPLE__" "-DHAVE_MACH_ABSOLUTE_TIME" "-DSIZEOF_SSIZE_T=8" "-DSIZEOF_SIZE_T=8" "-DSIZEOF_LONG=8" "-o" "/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out/build/curl/lib/cf-socket.o" "-c" "curl/lib/cf-socket.c"
  cargo:warning=curl/lib/cf-socket.c: In function 'do_connect':

  cargo:warning=curl/lib/cf-socket.c:1114:8: warning: implicit declaration of function '__builtin_available'; did you mean '__builtin_scalbl'? [-Wimplicit-function-declaration]

  cargo:warning= 1114 |     if(__builtin_available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) {

  cargo:warning=      |        ^~~~~~~~~~~~~~~~~~~

  cargo:warning=      |        __builtin_scalbl

  cargo:warning=curl/lib/cf-socket.c:1114:28: error: 'macOS' undeclared (first use in this function)

  cargo:warning= 1114 |     if(__builtin_available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) {

  cargo:warning=      |                            ^~~~~

  cargo:warning=curl/lib/cf-socket.c:1114:28: note: each undeclared identifier is reported only once for each function it appears in

  cargo:warning=curl/lib/cf-socket.c:1114:33: error: expected ')' before numeric constant

  cargo:warning= 1114 |     if(__builtin_available(macOS 10.11, iOS 9.0, tvOS 9.0, watchOS 2.0, *)) {

  cargo:warning=      |                           ~     ^~~~~~

  cargo:warning=      |                                 )

  exit status: 1

  --- stderr
  fatal: not a git repository (or any of the parent directories): .git


  error occurred: Command "/opt/homebrew/bin/gcc-12" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-gdwarf-2" "-fno-omit-frame-pointer" "-arch" "arm64" "-I" "curl/lib" "-I" "curl/include" "-I" "/Users/mercxry/code/dirty-laundry/target/debug/build/libnghttp2-sys-c8a5d2cb9803c3bb/out/i/include" "-fvisibility=hidden" "-DBUILDING_LIBCURL" "-DCURL_DISABLE_DICT" "-DCURL_DISABLE_GOPHER" "-DCURL_DISABLE_IMAP" "-DCURL_DISABLE_LDAP" "-DCURL_DISABLE_LDAPS" "-DCURL_DISABLE_POP3" "-DCURL_DISABLE_RTSP" "-DCURL_DISABLE_SMB" "-DCURL_DISABLE_SMTP" "-DCURL_DISABLE_TELNET" "-DCURL_DISABLE_TFTP" "-DCURL_STATICLIB" "-DENABLE_IPV6" "-DHAVE_ASSERT_H" "-DOS=\"unknown\"" "-DHAVE_ZLIB_H" "-DHAVE_LONGLONG" "-DHAVE_LIBZ" "-DHAVE_BOOL_T" "-DHAVE_STDBOOL_H" "-DHAVE_GETADDRINFO" "-DHAVE_GETPEERNAME" "-DHAVE_GETSOCKNAME" "-DCURL_DISABLE_NTLM" "-DCURL_DISABLE_FTP" "-DUSE_NGHTTP2" "-DNGHTTP2_STATICLIB" "-DUSE_SECTRANSP" "-DHAVE_BUILTIN_AVAILABLE=1" "-DRECV_TYPE_ARG1=int" "-DHAVE_PTHREAD_H" "-DHAVE_ARPA_INET_H" "-DHAVE_ERRNO_H" "-DHAVE_FCNTL_H" "-DHAVE_NETDB_H" "-DHAVE_NETINET_IN_H" "-DHAVE_NETINET_TCP_H" "-DHAVE_POLL_H" "-DHAVE_FCNTL_O_NONBLOCK" "-DHAVE_SYS_SELECT_H" "-DHAVE_SYS_STAT_H" "-DHAVE_SYS_TIME_H" "-DHAVE_UNISTD_H" "-DHAVE_RECV" "-DHAVE_SELECT" "-DHAVE_SEND" "-DHAVE_SOCKET" "-DHAVE_STERRROR_R" "-DHAVE_SOCKETPAIR" "-DHAVE_STRUCT_TIMEVAL" "-DHAVE_SYS_UN_H" "-DUSE_THREADS_POSIX" "-DUSE_UNIX_SOCKETS" "-DRECV_TYPE_ARG2=void*" "-DRECV_TYPE_ARG3=size_t" "-DRECV_TYPE_ARG4=int" "-DRECV_TYPE_RETV=ssize_t" "-DSEND_QUAL_ARG2=const" "-DSEND_TYPE_ARG1=int" "-DSEND_TYPE_ARG2=void*" "-DSEND_TYPE_ARG3=size_t" "-DSEND_TYPE_ARG4=int" "-DSEND_TYPE_RETV=ssize_t" "-DSIZEOF_CURL_OFF_T=8" "-DSIZEOF_INT=4" "-DSIZEOF_SHORT=2" "-D__APPLE__" "-DHAVE_MACH_ABSOLUTE_TIME" "-DSIZEOF_SSIZE_T=8" "-DSIZEOF_SIZE_T=8" "-DSIZEOF_LONG=8" "-o" "/Users/mercxry/code/dirty-laundry/target/debug/build/curl-sys-6e53359a21003f41/out/build/curl/lib/cf-socket.o" "-c" "curl/lib/cf-socket.c" with args "gcc-12" did not execute successfully (status code exit status: 1)

Tapo: SessionTimeout

I have a P100 smart plug which is connected to the network and active. When I try to control it get the following error:

Tapo: SessionTimeout

What does it exactly mean and how could it be avoided?

Thank you.

missing field `re_power_type

Hi!

I recieved this error booth on rust and python examples on L510 bulbs.
Error: Serde(Error("missing field re_power_type", line: 1, column: 550))
I want to use the client to monitor the power usage of the bulbs.
What can I do to fix this issue?

Example for doing things with devices accessed throung the hub

It would be nice to have an example of how to access devices behind an h100 hub. In particular I am interested in how to get button events from an S200B and/or temperature/humidity history from a T310.

Comes to think of it, how do we respond in Python to events originating in the device - such as movements detected by the T100?

Great piece of work - many thanks!

[Feature Request] Please add audio reactive lighting control

Hey I tried a lot but I couldn't write a good working code which can control the lighting based on the music playing on my PC.
I tried Pyaudio with loopback but for some reason, the reactiveness was way too slow. Then I tried aubio in rust but that didn't work. Please can you help me achieve it?

Set brightness

builtins.PlugEnergyMonitoringHandler' object has no attribute 'set_brightness'

I am getting this error in here, what could be the reason?


import asyncio
import os

from tapo import ApiClient


async def main():
    client = ApiClient("xd", "xd")
    device = await client.p110("192.168.1.8")

    while True:
        user_input = input("Enter 'o' to turn the device on or 'c' to turn it off (or 'q' to quit): ")

        if user_input == 'o':
            await device.on()
            device_usage = await device.get_device_usage()
            print("Işık Açıldı, bilgiler:")
            print(f"Device usage: {device_usage.to_dict()}")
        elif user_input == 'c':
            await device.set_brightness('30')
            print("Işık kapatıldı.")

        elif user_input == 'q':
            break
        else:
            print("Invalid input. Please enter 'o' or 'c'.")

if __name__ == "__main__":
    asyncio.run(main())

Energy data interval

Is it possible to get the energy data in 5 minute intervals instead of hourly?

Local access to TAPO P110 for energy data

Is acquisition of energy data of the P110 still possible with local access?

I did that succesfully in NodeRed using the staus node of this flow. Lately I get invalid results. Could this be due to blocking of the functionality in recent firmware updates?

on_time characteristic causing error

Thanks for this project! For me, with recently bought L530 bulbs and updated firmware, getting info results in an error due to the lack of on_time

in src/responses/device_info_result/l530.rs
commenting out that line (28) allows the information to be printed.

Error: Tapo(InvalidCredentials)

Hey,

Been trying to figure out how best to get access to my P110s to pull energy stats.
Paraphrasing off the internet here - something changed in the TAPO firmware at some point in the past and now most API implementations no longer work.
Does your API client still work on the latest firmware? (v1.2.3)

The part I can't figure out is I've never once set credentials for the device itself, so I can only assume it's the same as my TAPO Account. But still InvalidCredential.

tia

P115 changing WI-FI

Hi

I would like to change the WI-FI for the outlet, without having to install the Tarot application,
using the example of the set_qs_info method from https://gitlab.com/0xSamy/TapoPlug-Rest-API/-/blob/master/tapo_plug/tapoPlugApi.py

That is, I reset the settings, connected to WI-FI "Tapo_Plug_XXXX", and sent a request to 192.168.0.1,
but if I do this, then in the "handshake1" method - server_hash will differ from local_hash and nothing will work

So is there a way to do this? Maybe when the settings are reset, a different connection method or a special username/password is used?

Thank you in advance

Feature request: toggle state

Would it be possible to create a toggle function by reading the json info and switching accordingly? Unfortunately I am not very familiar with Rust, and it would seem better to do this within rust rather than parsing json with some other language and setting a variable.

btw, I was able to build this with termux on Android and it is really great to be able to do things with tasker!

Support for security cameras

For personal uses, I'd love to have access to an API to control my surveillance devices (e.g. change the camera's angle, toggle it on/off, etc.)

Tapo cameras (C-series) support the ONVIF protocol which is a widespread standard for controlling IP cameras.

I'm not sure if adding RTSP streaming capabilities to this crate would be relevant, it may be more relevant to make another create for that.

I'm trying to search on how to connect to the cameras (which seems to be different than for smart plugs or bulbs as it uses separate credentials). It may represent a pretty big work so not sure if I can do this myself but I'll try to dig into this and see what I can find.

Meaning / correctness of timestamps of device.get_energy_data

I am currently testing the tapo module with my P110 smart plugs. I can get the data from the devices with all of your API calls in the TAPO_p110.py example, which is great !

I am now specifically looking into the device.get_energy_data calls for hourly, daily and monthly data and am trying to understand the various output parameters. The code delivers values for start_timestamp and end_timestamp. To understand their meaning I convert them to a Python datetime object and print them.

For the hourly data I get results that make sense, but for daily and monthly data the start and end values are equal. Is that something in the device output or in the post-treament in your module? I give example results below.

Energy data (hourly): {'data': [12, 12, 12, 12, 13, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12, 12, 12, 4, 0, 0, 0, 0, 0, 0], 'end_timestamp': 1716422399, 'interval': 60, 'local_time': '2024-05-22T17:20:07', 'start_timestamp': 1716336000}
start date_time: 2024-05-22 02:00:00 start_ts: 1716336000
  end date_time: 2024-05-23 01:59:59   end_ts: 1716422399

Energy data (daily): {'data': [8254, 10030, 6695, 4636, 3577, 1448, 499, 632, 2044, 3888, 3002, 1391, 725, 284, 5862, 8314, 9891, 5180, 9461, 7752, 3727, 6723, 5831, 4619, 8553, 4575, 4301, 3228, 3523, 962, 289, 289, 716, 3948, 2240, 1047, 905, 3385, 2470, 711, 290, 290, 293, 292, 289, 287, 288, 288, 286, 286, 291, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'end_timestamp': 1711929600, 'interval': 1440, 'local_time': '2024-05-22T17:20:07', 'start_timestamp': 1711929600}
start date_time: 2024-04-01 02:00:00 start_ts: 1711929600
  end date_time: 2024-04-01 02:00:00   end_ts: 1711929600

Energy data (monthly): {'data': [238328, 327085, 236519, 139607, 19388, 0, 0, 0, 0, 0, 0, 0], 'end_timestamp': 1704067200, 'interval': 43200, 'local_time': '2024-05-22T17:20:07', 'start_timestamp': 1704067200}
start date_time: 2024-01-01 01:00:00 start_ts: 1704067200
  end date_time: 2024-01-01 01:00:00   end_ts: 1704067200

P110 `get_energy_usage` errors on the latest firmware

Firmware: 1.1.6 Build 221114 Rel.203339

Error

Device inner response decrypted: {"result":{"today_runtime":896,"month_runtime":15603,"today_energy":6635,"month_energy":62939,"local_time":"2023-01-16 21:05:07","electricity_charge":[0,0,0],"current_power":0},"error_code":0}
Error: missing field `past24h` at line 1 column 176

The four arrays with detailed data, past24h, past7d, past30d and past1y are entirely gone in this new firmware version.

Current thinking: Make them optional and hope that they will be re-introduced at a later date.

p100 error: Local hash does not match server hash

I have this error when trying to use with p100

Traceback (most recent call last):
  File "/home/kn/dev/tapo/tapo_p100.py", line 33, in <module>
    asyncio.run(main())
  File "/home/kn/.pyenv/versions/3.10.4/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/home/kn/.pyenv/versions/3.10.4/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
    return future.result()
  File "/home/kn/dev/tapo/tapo_p100.py", line 15, in main
    device = await client.p100(ip_address)
Exception: Other(Local hash does not match server hash)

Support client.getDeviceList

Hi @mihai-dinculescu, first of all I want to show my gratitude to you for creating this package. I've been able to use it do some really cool stuff at home.

Request: I was thinking if there's a way to do client.getDeviceList() after initializing the ApiClient without having to supply the address of the different devices to e.g. client.p100("IP_ADDRESS_OF_DEVICE")? This will enable programmatically getting the address of connected devices without having to supply it manually

Why? I have a cron job that periodically checks if a particular device is turned off to do some stuff but the problem I noticed after letting the cron run for about 10hrs is the script had crashed and the reason is because the IP address of that device had changed!

Device IP Address changes whenever router is rebooted

[Improvement] Schedule

By using the official app, I have seen there is a scheduler to turn P100 off or on

It seems not to be a timer integrated in the app, as I tried to completely shut down my phone after setting the timer, the plug has switched on while the phone was powered off

If you need some tests to get the API used, I can try to help

Question: Tapo P115 Energy Data

Hello Guys,
my first question is .. is this possible to read with the python script the Energy data from the device?
When yes..
where i get the Username and Passwort... in the App i can not find them thanks

Sporadic segfaults in a python module when using ApiClient to query a Tapo P110

I get random segfaults executing a python module that uses ApiClient to query a P110 device. Unfortunately the Python stack frame is not available when the process receives the signal, but I could catch a core dump that I analyzed with gdb.
This is what it says

0 __pthread_kill_implementation (threadid=548354912640, signo=signo@entry=11, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44
1 0x0000007faeab0a64 in __pthread_kill_internal (signo=11, threadid=) at ./nptl/pthread_kill.c:78
2 0x0000007faea6a76c in __GI_raise (sig=11) at ../sysdeps/posix/raise.c:26
3
4 0x0000000000490d30 in ?? ()
5 0x0000007fad41f054 in pyo3::types::any::PyAny::call_method::hacc5388e8a698dd3 ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
6 0x0000007fad41cd00 in pyo3_asyncio::call_soon_threadsafe::h189597b182986bc9 ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
7 0x0000007fad41b164 in pyo3_asyncio::generic::set_result::h943446c3e13924f1 ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
8 0x0000007fad2d5e08 in <pyo3_asyncio::tokio::TokioRuntime as pyo3_asyncio::generic::Runtime>::spawn::{{closure}}::h4499f884fd2416d9 ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
9 0x0000007fad2c7184 in tokio::runtime::task::core::Core<T,S>::poll::h6f19112f45830e8f ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
10 0x0000007fad2827f8 in tokio::runtime::task::harness::Harness<T,S>::poll::h75be9602525f0e15 ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
11 0x0000007fad4314a8 in tokio::runtime::scheduler::multi_thread::worker::Context::run_task::h75332304a442adb5 ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
12 0x0000007fad4306f0 in tokio::runtime::scheduler::multi_thread::worker::Context::run::ha0d088c158a7571f ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
13 0x0000007fad42e714 in tokio::runtime::context::set_scheduler::hb924c7a4ab654997 ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
14 0x0000007fad429174 in tokio::runtime::context::runtime::enter_runtime::h2dc922c95f430ff4 ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
15 0x0000007fad430558 in tokio::runtime::scheduler::multi_thread::worker::run::hcd92fda4015a4913 ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
16 0x0000007fad424638 in <tokio::runtime::blocking::task::BlockingTask as core::future::future::Future>::poll::hf97cccf4b76a37d5 ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
17 0x0000007fad42b478 in tokio::runtime::task::core::Core<T,S>::poll::h66ccbdb9dab0dc88 ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
18 0x0000007fad42b9b8 in tokio::runtime::task::harness::Harness<T,S>::poll::hc66c5f1784947dac ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
19 0x0000007fad424884 in std::sys_common::backtrace::__rust_begin_short_backtrace::h51368bf6bad8d526 ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
20 0x0000007fad436388 in core::ops::function::FnOnce::call_once{{vtable.shim}}::h5d7b156d45e1195b ()
from /root/.venv/lib/python3.11/site-packages/tapo/tapo.cpython-311-aarch64-linux-gnu.so
21 0x0000007fad7b6d30 in alloc::boxed::{impl#47}::call_once<(), dyn core::ops::function::FnOnce<(), Output=()>, alloc::alloc::Global> ()
at library/alloc/src/boxed.rs:2020
22 alloc::boxed::{impl#47}::call_once<(), alloc::boxed::Box<dyn core::ops::function::FnOnce<(), Output=()>, alloc::alloc::Global>, alloc::alloc::Global> ()
at library/alloc/src/boxed.rs:2020
23 std::sys::pal::unix::thread::{impl#2}::new::thread_start () at library/std/src/sys/pal/unix/thread.rs:108
24 0x0000007faeaaee58 in start_thread (arg=0x7fe90c4f57) at ./nptl/pthread_create.c:442
25 0x0000007faeb17f9c in thread_start () at ../sysdeps/unix/sysv/linux/aarch64/clone.S:79

I can provide the dumped file if needed.
Seen on 0.2.1 and 0.3.0 versions

Build error

I get:
error: package time v0.3.19 cannot be built because it requires rustc 1.62.0 or newer, while the currently active rustc version is 1.61.0

Is it possible to depend on an earlier time package version ? Building on Ubuntu 22.04.2 LTS fails.

In-/decrease brightness by value

FOA big thx for this project! Never used rust, took me half a day to make an on-off button in homebridge to control my l930 lights :) gonna be ok from now on...

If am right there is no option to in-/decrease brightness by value, like by steps, by for example +/-5%

Any idead how to achieve this or could i request a feature like this?

cannot import 'LightHander' or 'ColorLightHandler' for typings

Hello,

First of all, thank @mihai-dinculescu for your work in this library.
So, while all we need is to import the ApiClient to use this library, I am trying to add Type support for intellisense in VSCode so I am importing:

from tapo import ApiClient, LightHandler, ColorLightHandler

and my editor now looks like this:
image

However, this happens when I run the code:
image

This is the list of all my imports, I hope this issue isn't related to shadowing or something.

import asyncio
import colorsys
import sys
import TouchPortalAPI as TP
import yaml
from functools import wraps
from typing import Awaitable, Dict, Optional, Tuple, TypeVar, Union
from argparse import ArgumentParser
from TouchPortalAPI.logger import Logger
from tapo import ApiClient, LightHandler, ColorLightHandler

So my questions is, were LightHandler and ColorLightHandler not intented to be imported like this? If so, how to import them?
Thank you kindly for your help pointing me into the right direction.

H100 Support in Python

Hi,

are there any plans to support the H100 hub in python? I can see the hub, but I'd like to get data from a temperature sensor thats connected to the hub.

Thanks

Failed to install and use API

Hi Mihai,

I tried to use the API but have two problems.

  1. Using Python 3.7 with spyder on my windows PC I received this error message:
Traceback (most recent call last):

  File "N:\10_Gemeinsam\Haus\Heizung\Vermessung\Datalogs\TPLink_P115_Auslesen_v2.py", line 32, in <module>
    asyncio.run(main())

  File "C:\ProgramData\Anaconda3\lib\asyncio\runners.py", line 34, in run
    "asyncio.run() cannot be called from a running event loop")

RuntimeError: asyncio.run() cannot be called from a running event loop
  1. Triying to install the API on my raspberry pi this error
pi@raspberrypi:~/Documents $ pip install tapo
Collecting tapo
  Downloading https://files.pythonhosted.org/packages/4a/20/914242caec6a15aae886f5eca36fce0d637b90dc2c2bd97bd5413c546b89/tapo-0.1.0.tar.gz (53kB)
    100% |████████████████████████████████| 61kB 1.4MB/s
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    IOError: [Errno 2] No such file or directory: '/tmp/pip-build-Bnabi8/tapo/setup.py'

Any hint for me?

ApiClient on AWS Lambda

I'm trying to run the tapo_p100.py example on an AWS Lambda (the local version works with my account and device) with the following code:

"""P100 & P105 Example"""

import asyncio

from tapo import ApiClient

async def test_device():
    tapo_username = "[email protected]"
    tapo_password = "mypassword"
    ip_address = "192.168.1.8"

    client = ApiClient(tapo_username, tapo_password)
    device = await client.p100(ip_address)

    print("Turning device on...")
    await device.on()

    print("Waiting 2 seconds...")
    await asyncio.sleep(2)

    print("Turning device off...")
    await device.off()

    device_info = await device.get_device_info()
    print(f"Device info: {device_info.to_dict()}")

    device_usage = await device.get_device_usage()
    print(f"Device usage: {device_usage.to_dict()}")


def lambda_handler(event, context):
    asyncio.run(test_device())

However it fails due to tiemout:


{
  "errorMessage": "Http(Error { kind: Timeout, context: None, source: Some(Error { description: \"Timeout was reached\", code: 28, extra: None }), source_type: Some(\"curl::error::Error\"), local_addr: None, remote_addr: None })",
  "errorType": "Exception",
  "requestId": "1a7c8ec3-f4a6-44b8-a1f7-3d34f5ac2963",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 37, in lambda_handler\n    asyncio.run(test_device())\n",
    "  File \"/var/lang/lib/python3.12/asyncio/runners.py\", line 194, in run\n    return runner.run(main)\n",
    "  File \"/var/lang/lib/python3.12/asyncio/runners.py\", line 118, in run\n    return self._loop.run_until_complete(task)\n",
    "  File \"/var/lang/lib/python3.12/asyncio/base_events.py\", line 687, in run_until_complete\n    return future.result()\n",
    "  File \"/var/task/lambda_function.py\", line 14, in test_device\n    device = await client.p100(ip_address)\n"
  ]
}

Again, this works correctly if ran (with a classic main) on my computer.

basic guide of usage under windows?

Assume most people have no idea how to set this up under say windows, a guide would be very handy

All we see is a mention of installing SSL under windows....and i can do that and have been doing that since the days of squid port (squidnt) for windows :) its everything else i have no clue about :)

edit:/update:

tried to get there on my own and as usual what looks simple given the README of a github repo, its anything and ive gone around in circles for the last 3 hours, and arrived right back where i started

what ive tried....

downloading:

rust-1.65.0-i686-pc-windows-gnu.msi (1st time rust user - cant say im a fan given the dependency hell under windows)
as advised by rust page:
msys2-x86_64-20221028.exe
ran msys2 setup (ive used msys2 before)
then ran pacman -S mingw-w64-ucrt-x86_64-gcc for build env

used set to set variables for IP,username.password

and then (as advised when trying to run) cargo run --example tapo_p110

i ran:

pacman -S openssl-devel pkg-config

which completed fine, but cargo still complained turning on backtracing showed it was complaining that openssl couldnt be found, but it was installed fine...

after an hour of getting nowhere i came across an alternate solution that involved installing the alternate msvc version of rust and 9.79Gb of Microsoft Visual Studio, at which point with my connection i tapped out and gave up.

there has to be a less torturous and data download hungry way to do this under windows, surely its just sending json payloads???

i really wish when people put up code they actually put a guide for people to actually use it - have a look at the instructions on my AutoBan PHP code for Unifi Gateways on my repo and the code commentary, thats documentation...

https://github.com/stylemessiah/Unifi-Auto-Ban

Bug in hue/saturation and color_temperature code

/// Sets the *hue* and *saturation*. ['ColorLightSetDeviceInfoParams::send'] must be called at the end to apply the changes.
/// The device will also be turned *on*, unless ['ColorLightSetDeviceInfoParams::off'] is called.
///
/// # Arguments
///
/// * 'hue' - between 1 and 360
/// * 'saturation' - between 1 and 100
pub fn hue_saturation(mut self, hue: u16, saturation: u8) -> Self {
    self.hue = Some(hue);
    self.saturation = Some(saturation);
    self.color_temperature = Some(0);

    self
}

/// Sets the *color temperature*. ['ColorLightSetDeviceInfoParams::send'] must be called at the end to apply the changes.
/// The device will also be turned *on*, unless ['ColorLightSetDeviceInfoParams::off'] is called.
///
/// # Arguments
///
/// * 'color_temperature' - between 2500 and 6500
pub fn color_temperature(mut self, value: u16) -> Self {
    self.hue = Some(0);
    self.saturation = Some(100);
    self.color_temperature = Some(value);

    self
}

Referring to the above code snippet in 'tapo/src/requests/set_device_info/color_light.rs' between line 65 to 92.

The code is wrong because hue must be 1 to 360, but in color_temperature and certain colors in COLOR_MAP, it is hard_coded to 0. Also, there are bulb color settings where the hue, saturation and color_temperature can co-exist such as color temperature is "3300", hue is "10", saturation is "19". Using the command:

await device.set().brightness(80).hue_saturation(10, 19).color_temperature(3300).send(device)

... will always trigger a Validation error.

await device.set_hue_saturation(hue, saturation)
Exception: Validation { field: "hue", message: "must be between 1 and 360" }

Please confirm if this is the case. Correct fix is that in 'fn hue_saturation', the line 'self.color_temperature' should be removed. In 'fn color_temperature', the lines 'self.hue' and 'self.saturation' should be removed.

Issue on Rust

Hello.
I try to run your Rust projects. But i have a problem about that. First, I go to ..\tapo-main\tapo-main\tapo folder for build 'Cargo.toml'.

image

Building succesfully happen. After the build, I run the 'cargo run" command and I get this error.

image

I installed the openssl by the way.

P110 getting current energy usage via different api method

I'm seeking help in adding support in p110 api to get current power draw, let me explain.

All my "smart" devices are on network without internet access for privacy and security concerns and i've noticed that if the device turns on and connects to that network or even looses connection and then reconnects, none of the get_device_usage,get_energy_usage,get_energy_usage work which in the tplink app i can see as no energy usage graphs whatsoever. To fix that you need to kickstart them with internet connection and then they work fine just fine. But while they are not working, i noticed in the app i could still see current power draw and fankly thats all i care about (on/off works fine), so i was hoping you could help me/we could work together on finding out that api method, but if you got P110/115 then you don't need my help :P

I'm happy to provide any information and help in any way i can to get it as it's stopping me from achieving perfection

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.