0

I was trying to execute the TPLINK smartplug python script: https://github.com/softScheck/tplink-smartplug/blob/master/tplink-smartplug.py

The main issue is related with the "sock_tcp.send(encrypt(cmd))". The variable cmd is a string that I pass as argument in the terminal (see example below). Executing this code with Python2 I got a successful response from the smartplug

bash:~/tplink-smartplug-master$ python tplink-smartplug.py -t 192.168.xx.xx -j '{"emeter":{"get_realtime":{}}}'

Output - print

Sent:     {"emeter":{"get_realtime":{}}} 

('Received: ', '{"emeter":{"get_realtime":{"current":0.039509,"voltage":236.064036,"power":4.880813,"total":0.004000,"err_code":0}}}')

If I execute the code with Python3 I got the error "TypeError: a bytes-like object is required, not 'str'". This is related with Python3 using unicode for strings while Python2 uses bytes.

However if I change the code to accommodate Python3 demands as such: "sock_tcp.send(encrypt(cmd).encode())" to force a conversion from Unicode to bytes. The response when executing the code is:

bash:~/tplink-smartplug-master$ python3 tplink-smartplug.py -t 192.168.xx.xx -j '{"emeter":{"get_realtime":{}}}' 

Output - print

Sent:     {"emeter":{"get_realtime":{}}} 

Received:

Any ideas what kind of conversation should I do to make it working in Python3 ?

The encrypt() functions only add a extra chart you can check it on the link above.

Thank you for the help! Jp

JPG
  • 1
  • I think it is better to start an issue on github. – tim Dec 10 '17 at 02:22
  • `bytes(string_to_convert, "utf-8")` – Jared Smith Dec 10 '17 at 02:24
  • Possible duplicate of [Best way to convert string to bytes in Python 3?](https://stackoverflow.com/questions/7585435/best-way-to-convert-string-to-bytes-in-python-3) – Jared Smith Dec 10 '17 at 02:24
  • @tim what could that *possibly* accomplish? – Jared Smith Dec 10 '17 at 02:25
  • @JaredSmith I tried as: `sock_tcp.send(bytes(encrypt(cmd), "utf-8"))` but getting the same empty result. It seems the conversion in Python3 "destroys" the message and the device does not recognise the command. – JPG Dec 10 '17 at 08:55
  • @JaredSmith I also tried with bitarray without success. When printing the data from the socket directly with Python2 I get bytes but with Python3 it returns empty. It seems that there is something on the conversion destroying the message :S – JPG Dec 10 '17 at 09:07
  • @user1529023 that function is using `xor` for encryption (which is a whole other conversation in itself, but out of scope here) so it should probably be `encrypt(bytes(cmd, "utf8"))`. – Jared Smith Dec 10 '17 at 18:58
  • @JaredSmith I tried that before. However the encrypt function needs the "cmd" string to add the encryption. Outputing as result a string. The output is what is sent via the socket and what should be converted as bytes. But somehow when we convert the final message to bytes in Python3 it is not recognised by the smartplug, while in Python2 is not a problem. `def encrypt(string): key = 171 result = "\0\0\0\0" for i in string: a = key ^ ord(i) key = a result += chr(a) return result` – JPG Dec 10 '17 at 21:38
  • @JaredSmith Found the Solution. It seems someone at raised an issue in GitHub for Python3 (sorry I missed when I searched on the first time). Basically they changed the encrypt and decrypt function and encode each char to 'latin1'. Check solution here: https://github.com/softScheck/tplink-smartplug/issues/20 – JPG Dec 10 '17 at 21:46

0 Answers0