-
Notifications
You must be signed in to change notification settings - Fork 180
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
MappedDevice Phase II #370
base: master
Are you sure you want to change the base?
Conversation
include_map = not bool( answer[0:1].lower() == 'n' ) | ||
if answer[0:1].lower() == 'a': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! Good addition.
tinytuya/wizard.py
Outdated
print(output) | ||
print( json.dumps(tuyadevices[:15], indent=4) ) | ||
if len(tuyadevices) > 15: | ||
print("%s(%d more devices hidden)" % (normal, (len(tuyadevices) - 15))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hum... interesting. I'm not sure we want to truncate the list. It may be better to make the JSON output optional (via command line?) and just notify the user that the device files is written.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure why we need to display all off them. A few are nice to verify the download worked, but with the addition of device mappings they're absolutely flooding the screen (I'm up to 130 devices and every time I ran the wizard it was dumping all 14,793 lines of devices.json to my screen). Perhaps add another prompt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a prompt. If you have <= 15 devices it asks:
3 devices downloaded, display? (Y/n):
and more than that gets:
130 devices downloaded, display? ([Y]es/[n]o/[s]ome):
As 15 was still flooding my screen, if you answer "s" it then displays just the first 10.
I love this! Going to play with it a bit more and drop any comments in-line... |
Got almost everything implemented. Json/array handling got a bit convoluted as things like bulb scene data are integers inside a dict inside a list inside another dict, but it seems to be functional. Still needs a lot more testing and cleanup. |
Scanner Run
❤️ I absolutely love seeing the translated (human readable) DPS keys. I do wonder if we should provide an option to show DPS index numbers instead, maybe In a scanner run... likely debug, but some lines like this show up:
And...
|
I can definitely add that, but I'm not really sure it's needed for the scanner. I'm probably going to put the raw values in a "dps_raw" key and modify the "changed" list to return the dps object instead of just the name, and people can then check snapshot.json after running the scanner if they really need the raw values. |
Sold! 😄 We can always add it later. Thanks LW! This is awesome. |
…" and "dps_objects" to responses
Done. I also pulled out a bunch of debugging print()s to help with the flood while scanning. |
or | ||
MappedDevice.dps.some_dp_name = new_value | ||
or | ||
MappedDevice.dps['some_dp_name'] = new_value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is brilliant. It elevates ease-of-use. I'm thinking how we best add this to README...
#!/usr/bin/env python
import tinytuya
device = tinytuya.MappedDevice(
dev_id="XXX", local_key="XXX", persist=True
)
device.set_version(3.3)
device["switch"] = True Results in:
I believe here it should be changed from this: def encode_value( self, new_value ):
return self.obj.encode_value( new_value, False ) to this: def encode_value( self, new_value , pack = False ):
return self.obj.encode_value( new_value, pack=pack ) |
Thank you for the bug report, @spinza ! Yes, that does look like a good way to fix it. |
I've written a Tuya MQTT device bridge using the MappedDevice class in this PR. It works on any device found in a local I am not sure if bitmaps are settable but that's the only function that won't work (if possible). I.e. you cannot set bitmap values from MQTT to Tuya but Tuya to MQTT flows work. This class was very useful to generalise this. My use case for this is OpenHAB. OpenHAB now automatically discovers Tuya devices as Things on the MQTT OpenHab integration. It also sets up appropriate channels with the right units etc. Some of the unit functionality won't work as well but I don't have enough devices (I only have two) to test units. |
Hmm, I wonder if it would be a good idea to expand bitmasks into an array of true/false values which you could set like |
That is essentially what I've done in the MQTT bridge. It takes the bitmap and publishes it as a series of boolean topics. With the bridge there is a risk of name collisions though. |
The code I mention is available here |
Can you make the above fix to your code, so if someone install it they can at least get my server working? |
@spinza Fixed. It's not functional yet, but I also started on expanding bitmaps. |
Cool. Is the default behaviour unchanged with regard to bitmaps? |
Kinda? I haven't finished implementing it yet so at the moment nothing has changed. When I'm done the "parent" DP bitmap will remain the same as it is now, but there will be additional pseudo-DPs added for each bit option. To shut that off (thereby keeping everything exactly the same as it is now) set |
Can a bitmap be settable? |
Assuming the device allows it, yes. Currently you can set it either with an int (i.e. |
Draft for now as there are still a few FIXME's and errant print()'s, but I wanted some feedback on the direction I was going.
The scanner has also been updated to use it. Instead of
you now get
As you can see, scaled ints are automatically turned into floats, enums are changed to their labels, and bitmasks are now lists of labels. When setting, everything is converted back as needed.
When updates are received either via a status() response or an async update, the dps dict keys are mapped to the DP names. If the received value is different than the last received value then the name is also added to a 'changed' list:
In addition to this, the last received value for any particular DP can be retrieved at any time:
The d.dps[...] object can also be used to get the int_min/int_max/enum_range/bitmask values for those data types as well as the DP ID and any name(s) associated with that DP, in addition to the last known (parsed) value and raw value.
Example d.dps[...] object for a bitmap:
Setting new values can be done in a similar dict-like manner; all of these are equivalent:
Since dict-like access cannot pass the
nowait
flag, there is now a device-level switch for it:Todo:
Implement the 'Json' data type, implementcleanup and documentation.d.set_multiple_values()
, implementd.set_timer()
, andCloses #185