Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complemented low control #84

Closed

Conversation

Anders-Holst
Copy link
Contributor

This pull request contains the changes to the low-level control interface, ControlInterface, suggested in the unwieldy pull request #80 .

(I really tried to make the commit messages more specific this time. But with so many changes, some are still kind of vague.)

/ Anders

@Anders-Holst
Copy link
Contributor Author

I noticed that you have an old branch with mqtt support added. Why did you not merge it? I noticed that your solution with the parameters were more flexible than mine, so I adjusted my version to look more like yours.
I also added the security.py fixes here - they belong here since they are needed for the low level 'set_network_mode_station'. I have not solved the 48 byte encryption issue though since it is not my field.

@scrool
Copy link
Owner

scrool commented Oct 26, 2021

I noticed that you have an old branch with mqtt support added. Why did you not merge it? I noticed that your solution with the parameters were more flexible than mine, so I adjusted my version to look more like yours.

I don't recall details but I think it was either that I haven't tested that enough or I wasn't sure about usefullness/user friendliness of CLI interface.

I also added the security.py fixes here - they belong here since they are needed for the low level 'set_network_mode_station'.

This part is the most tricky one. We have unit tests for this part of the code. I didn't know that this code is failing. Have you managed to get those failed?

I have not solved the 48 byte encryption issue though since it is not my field.

I'm not sure what you mean by "48 byte encryption issue". Has somebody reported issue that I haven't noticed?

Copy link
Owner

@scrool scrool left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I like these changes. I have commented inline for those parts that I would like to change or I wasn't sure about a reason for a change.

I would like you to leave out realtime UDP client from this pull request. I would like to see that in a separate PR, preferrably with some unit tests that cover all those versions.

xled/control.py Show resolved Hide resolved
xled/control.py Outdated
if password:
json_payload = {
"mode": 2,
"ap": {"password": password, "enc": 4}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this easier to read.

Since {"mode": 2} is always sent that could be a default. And only if a password is set we could add second dict entry - "ap".

xled/control.py Show resolved Hide resolved
xled/control.py Outdated
}
if ssid and password:
encpassword = xled.security.encrypt_wifi_password(password, self.hw_address)
json_payload = {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above - let's use default with single dict entry "mode": 1 and only if password and ssid are available add those.

xled/control.py Show resolved Hide resolved
xled/control.py Outdated

def get_led_effects(self):
"""
Get the number of effects and their unique_ids
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use "Gets" instead of "Get" similarly to other API docstrings.

xled/control.py Outdated

def get_led_effects_current(self):
"""
Get the current effect index
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use "Gets" instead of "Get" similarly to other API docstrings.

xled/control.py Outdated

def delete_playlist(self):
"""
Clear the playlist
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use "Clears" instead of "Clear" similarly to other API docstrings.

xled/control.py Outdated
@@ -74,6 +74,52 @@ def session(self):
assert self._session
return self._session

def check_status(self):
"""
Check that the device is online and responding
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use "Checks" instead of "Check" similarly to other API docstrings.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for all the doc-string oversights. Fixed.

xled/control.py Outdated
assert all(key in app_response.keys() for key in required_keys)
return app_response

def set_mqtt_config(self, br_host, br_port, client_id, user, interval):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be duplicated from earlier commit ee7114c .

@Anders-Holst
Copy link
Contributor Author

I also added the security.py fixes here - they belong here since they are needed for the low level 'set_network_mode_station'.

This part is the most tricky one. We have unit tests for this part of the code. I didn't know that this code is failing. Have you managed to get those failed?

If you refer to test_security.py, it appears to only test security.xor_strings, not security.encrypt_wifi_password which is the culprit. Yes I tested it and the old code works in python 2.7 but fails in python 3.6. The new code works in both.

I have not solved the 48 byte encryption issue though since it is not my field.

I'm not sure what you mean by "48 byte encryption issue". Has somebody reported issue that I haven't noticed?

I refer to issue #70 opened by someone called scrool on January 3... ;-)

I would like you to leave out realtime UDP client from this pull request. I would like to see that in a separate PR, preferrably with some unit tests that cover all those versions.

That will take some delicate operation again. I'll do it but not tonight. Meanwhile, have you checked out the file test_low_control.py checked into my (soon obsolete) pull request #80? It contains test for all low level interface calls (except firmware and change network mode) including all versions of the realtime calls. You can also run
python -m xled.test_colorsphere also from that pull request, to see the realtime interface in intense action. Otherwise, you can try this snippet as a visual unit test (assuming RGB led profile). Since Twinkly appears to be backward compatible, all protocol versions work on newer firmwares (and not family D), so then the colors should be in sequence: green, yellow, lime, and orange. On older firmware (family F) the last color will come out wrong (since its the wrong protocol). On family D, presumably the last two colors will come out wrong or not at all.

from xled.control import ControlInterface
from xled.discover import discover
import io
import struct
import time

dev = discover()
ctr = ControlInterface(dev.ip_address, dev.hw_address)
num_leds = ctr.get_device_info()['number_of_led']

def make_solid_movie(num, r, g, b):
    pat = [struct.pack(">BBB", r, g, b)] * num
    movie = io.BytesIO()
    movie.write(b''.join(pat))
    movie.seek(0)
    return movie

ctr.set_mode("rt")

print("Green")
ctr.set_rt_frame_rest(make_solid_movie(num_leds, 0, 255, 0))
time.sleep(5)

print("Warm yellow")
ctr.set_rt_frame_socket(make_solid_movie(num_leds, 230, 170, 0), 1, min(255, num_leds))
time.sleep(5)

print("Lime")
ctr.set_rt_frame_socket(make_solid_movie(num_leds, 100, 255, 0), 2)
time.sleep(5)

print("Orange")
ctr.set_rt_frame_socket(make_solid_movie(num_leds, 230, 85, 0), 3)
time.sleep(5)

@Anders-Holst
Copy link
Contributor Author

@scrool , I have now removed the realtime UDP protocols from this pull request, as you wished.

I am standing by to add it again, together with the new unit test, once you have merged this one.

And in line after that are all the other low-level unit tests.

@scrool
Copy link
Owner

scrool commented Nov 14, 2021

@Anders-Holst I have noticed that you haven't run black linter on your changes. Usually it would be run automatically with pre-commit hook - see https://github.com/scrool/xled/blob/develop/CONTRIBUTING.rst how to set it up:

$ pip install -r requirements_dev.txt
$ pre-commit install

To not miss this next time I have updated GitHub actions to run linters for pull requests but this doesn't run against this PR because it is based on develop branch before I added #88.

Please:

  1. rebase your changes against develop
  2. make sure you run black and commit all its changes.

@Anders-Holst
Copy link
Contributor Author

OK, you are right, I had missed black. Tried to rebase and apply black. I thought I had fixed it all now. (Obviously did a small mistake when committing, and git rebase seemed confused so I was not able to just "drop" my last commit.)
But when pushing I still get complaints from "lint". Why? I can not find any log saying what it complains on.
Getting very tired, need to sleep...

@scrool
Copy link
Owner

scrool commented Nov 14, 2021

From what I can tell, black passes now. 👍

There is one error caught by flake8 though - see https://github.com/scrool/xled/runs/4205988557?check_suite_focus=true#step:4:56

xled/control.py:33:1: F401 'xled.security.encrypt_wifi_password' imported but unused

that's because you import directly method encrypt_wifi_password but later you use xled.security.encrypt_wifi_password.

@Anders-Holst
Copy link
Contributor Author

New try. Fixed the problem, passes black and flake8 here. Hope it passes on your side too.
(I really tried to undo the two confused commits from last night, but the first seem to be "special" as it was the result of trying to solve conflicts appearing during rebase, so can't be easily removed. So I let it be, although the history looks ugly...)

Copy link
Contributor

@magicus magicus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From what I can tell, this looks like a very good change.

xled/control.py Show resolved Hide resolved
@scrool
Copy link
Owner

scrool commented Nov 15, 2021

I have skipped those commits which didn't provide any changes and merged the rest into develop.

Thanks again! 🥳

@scrool scrool closed this Nov 15, 2021
@Anders-Holst Anders-Holst deleted the complemented-low-control branch November 15, 2021 20:03
scrool added a commit that referenced this pull request Nov 27, 2021
Up until now see merged #84, #90, #91 for the contributions.
scrool added a commit that referenced this pull request Nov 27, 2021
Up until now see merged #84, #90, #91 for the contributions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants