diff --git a/README.md b/README.md index a3ae145..2312623 100644 --- a/README.md +++ b/README.md @@ -42,8 +42,25 @@ Provide the target IP using `-t` and a command to send using either `-c` or `-j` | reset | Reset the device to factory settings | | energy | Return realtime voltage/current/power| +When using commands from the `-c` list on power strips HS300 and HS303, you can use the `-o` flag to specify a specific outlet on the power strip using the child ID. +The child ID can be obtained by running the info command on the power strip at looking in the `"system"` > `"get_sysinfo"` > `"children"` sections. + More advanced commands such as creating or editing rules can be issued using the `-j` flag by providing the full JSON string for the command. Please consult [tplink-smarthome-commands.txt](tplink-smarthome-commands.txt) for a comprehensive list of commands. +#### Modifying Commands for HS300 and HS303 for the `-j` flag #### + +The same commands can be modified to control a single outlet by inserting `"context":{"child_ids":["CHILD_ID"]}, ` in front of `"system":`. If you dont specify a child outlet, the command will affect the entire power strip. + +For instance: +`{"system":{"set_led_off":{"off":0}}}` Will turn all outlets off + +`'{"context":{"child_ids":["8006...E101"]}, "system":{"set_led_off":{"off":0}}}'` Will turn just that one outlet on + +You can specify multiple child outlet IDs by adding them to the `child_ids` array in your command. + +Some commands are not outlet specific (ex. `info`) so the child ID(s) will be ignored by your power strip. + + ## Wireshark Dissector ## Wireshark dissector to decrypt TP-Link Smart Home Protocol packets (TCP port 9999). diff --git a/tplink_smartplug.py b/tplink_smartplug.py index 789cdcf..4cd3282 100755 --- a/tplink_smartplug.py +++ b/tplink_smartplug.py @@ -113,6 +113,7 @@ def decrypt(string): parser.add_argument("-p", "--port", metavar="", default=9999, required=False, help="Target port", type=validPort) parser.add_argument("-q", "--quiet", dest='quiet', action='store_true', help="Only show result") parser.add_argument("--timeout", default=10, required=False, help="Timeout to establish connection") +parser.add_argument("-o", "--outlet", metavar="", help="Child outlet ID. Typically around 42 characters. Will be ignored if manually specifying JSON. Use info command to get child IDs") group = parser.add_mutually_exclusive_group(required=True) group.add_argument("-c", "--command", metavar="", help="Preset command to send. Choices are: "+", ".join(commands), choices=commands) group.add_argument("-j", "--json", metavar="", help="Full JSON string of command to send") @@ -126,7 +127,8 @@ def decrypt(string): cmd = args.json else: cmd = commands[args.command] - + if args.outlet is not None: + cmd = '{"context":{"child_ids":["' + args.outlet + '"]}, ' + cmd[1:] # Send command and receive reply