diff --git a/src/setup_tool.py b/src/setup_tool.py index 288e75d..3dd1bb3 100644 --- a/src/setup_tool.py +++ b/src/setup_tool.py @@ -1,77 +1,71 @@ # setup_tool.py 28/05/2016 D.J.Whale # # A simple menu-driven setup tool for the Energenie Python library. - +# # Just be a simple menu system. # This then means you don't have to have all this in the demo apps # and the demo apps can just refer to object variables names # from an assumed auto_create registry, that is built using this setup tool. -#TODO: Choose a better way to interrupt other than Ctrl-C -#It's very platform independent -#also, the foreground thread gets the KeyboardInterrupt, -#so as soon as threads are added, its a bad way to terminate user entry -#or processing. import time import energenie from energenie.lifecycle import * + +#===== GLOBALS ===== + +quit = False + + +#===== INPUT METHODS ========================================================== + try: readin = raw_input # Python 2 except NameError: readin = input # Python 3 -quit = False + +def get_house_code(): + """Get a house code or default to Energenie code""" + + while True: + try: + hc = readin("House code? (ENTER for default) ") + if hc == "": return None + + except KeyboardInterrupt: + return None # user abort + + try: + house_code = int(hc, 16) + return house_code + + except ValueError: + print("Must enter a number") -def do_legacy_learn(): - """Repeatedly broadcast a legacy switch message, so you can learn a socket to the pattern""" - # get house code, default to energenie code - hc = readin("House code? (ENTER for default) ") - if hc == "": - house_code = None - else: - house_code = int(hc, 16) - #TODO: error check +def get_device_index(): + """get switch index, default 1 (0,1,2,3,4)""" - # get switch index, default 1 (0,1,2,3,4) - si = readin("Switch index 1..4? (ENTER for all)") - if si == "": - switch_index = 0 #ALL - else: - switch_index = int(si) - #TODO: error check + while True: + try: + di = readin("Device index 1..4? (ENTER for all)") + except KeyboardInterrupt: + return None # user abort - device = energenie.Devices.ENER002((house_code, switch_index)) + if di == "": return 0 # ALL + try: + device_index = int(di) + return device_index - # in a loop until Ctrl-C - try: - while True: #TODO: detect Ctrl-C - print("ON") - device.turn_on() - time.sleep(0.5) - print("OFF") - device.turn_off() - time.sleep(0.5) - except KeyboardInterrupt: - pass # user exit - - -def do_mihome_discovery(): - """Discover any mihome device when it sends reports""" - print("Discovery mode, press Ctrl-C to stop") - energenie.Registry.discovery_ask(energenie.Registry.ask) - try: - while True: - energenie.loop() # Allow receive processing - time.sleep(0.25) # tick fast enough to get messages in quite quickly - except KeyboardInterrupt: - print("Discovery stopped") + except ValueError: + print("Must enter a number") def show_registry(): """Show the registry as a numbered list""" + names = energenie.registry.names() i=1 for name in names: @@ -80,40 +74,89 @@ return names -def do_list_registry(): - """List the entries in the registry""" - show_registry() +def get_device_name(): + """Give user a list of devices and choose one from the list""" - -def do_switch_device(): - global quit - """Turn the switch on a socket on and off, to test it""" - - #TODO DRY name = select_device() - # select the device from a menu of numbered devices names = show_registry() - # ask user for on/off/another/done - i = readin("Which device %s to %s" % (1,len(names))) - device_index = int(i) - #TODO: error check - #TODO: Ctrl-C check + try: + while True: + i = readin("Which device %s to %s" % (1,len(names))) + try: + device_index = int(i) + break # got it + except ValueError: + print("Must enter a number") + + except KeyboardInterrupt: + return None # nothing chosen, user aborted name = names[device_index-1] print("selected: %s" % name) - device = energenie.registry.get(name) - #TODO: DRY END + return name - #TODO could list all action methods by introspecting device class - # and build a device specific menu + +#===== ACTION ROUTINES ======================================================== + +def do_legacy_learn(): + """Repeatedly broadcast a legacy switch message, so you can learn a socket to the pattern""" + + # get device + house_code = get_house_code() + device_index = get_device_index() + device = energenie.Devices.ENER002((house_code, device_index)) + + # in a loop until Ctrl-C + try: + while True: + print("ON") + device.turn_on() + time.sleep(0.5) + + print("OFF") + device.turn_off() + time.sleep(0.5) + + except KeyboardInterrupt: + pass # user exit + + +def do_mihome_discovery(): + """Discover any mihome device when it sends reports""" + + print("Discovery mode, press Ctrl-C to stop") + energenie.Registry.discovery_ask(energenie.Registry.ask) + try: + while True: + energenie.loop() # Allow receive processing + time.sleep(0.25) # tick fast enough to get messages in quite quickly + + except KeyboardInterrupt: + print("Discovery stopped") + + +def do_list_registry(): + """List the entries in the registry""" + + show_registry() + + +def do_switch_device(): + """Turn the switch on a socket on and off, to test it""" + + global quit + + name = get_device_name() + device = energenie.registry.get(name) + def on(): print("Turning on") - device.turn_on + device.turn_on() def off(): print("Turning off") - device.turn_off + device.turn_off() MENU = [ ("on", on), @@ -126,6 +169,7 @@ choice = get_choice((1,len(MENU))) if choice != None: handle_choice(MENU, choice) + except KeyboardInterrupt: pass # user exit quit = False @@ -135,21 +179,8 @@ def do_show_device_status(): """Show the readings associated with a device""" - #TODO DRY name = select_device() - names = show_registry() - - energenie.loop() # allow receive processing #TODO: not long enough for >1 msg?? - - # ask user for on/off/another/done - i = readin("Which device %s to %s" % (1,len(names))) - device_index = int(i) - #TODO: error check - #TODO: Ctrl-C check - - name = names[device_index-1] - print("selected: %s" % name) + name = get_device_name() device = energenie.registry.get(name) - #TODO: DRY END readings = device.get_readings_summary() print(readings) @@ -158,6 +189,7 @@ @untested def do_watch_devices(): """Repeatedly show readings for all devices""" + try: while True: energenie.loop() # allow receive processing @@ -177,42 +209,20 @@ @untested def do_rename_device(): """Rename a device in the registry to a different name""" - #This is useful when turning auto discovered names into your own names - #TODO DRY name = select_device() - names = show_registry() + # This is useful when turning auto discovered names into your own names - # ask user for on/off/another/done - i = readin("Which device %s to %s" % (1,len(names))) - device_index = int(i) - #TODO: error check - #TODO: Ctrl-C check - - name = names[device_index-1] - print("selected: %s" % name) - #TODO: DRY END - + old_name = get_device_name() new_name = readin("New name?") - energenie.registry.rename(name, new_name) + energenie.registry.rename(old_name, new_name) @untested def do_delete_device(): """Delete a device from the registry so it is no longer recognised""" - #TODO DRY name = select_device() - names = show_registry() - - # ask user for on/off/another/done - i = readin("Which device %s to %s" % (1,len(names))) - device_index = int(i) - #TODO: error check - #TODO: Ctrl-C check - - name = names[device_index-1] - print("selected: %s" % name) - #TODO: DRY END + name = get_device_name() energenie.registry.delete(name) @@ -220,6 +230,7 @@ @untested def do_logging(): """Enter a mode where all communications are logged to screen and a file""" + import Logger # provide a default incoming message handler for all fsk messages @@ -242,12 +253,16 @@ def do_quit(): """Finished with the program, so exit""" + global quit quit = True +#===== MENU =================================================================== + def show_menu(menu): """Display a menu on the console""" + i = 1 for item in menu: print("%d. %s" % (i, item[0])) @@ -256,6 +271,7 @@ def get_choice(choices): """Get and validate a numberic choice from the tuple choices(first, last)""" + first = choices[0] last = choices[1] try: @@ -275,6 +291,7 @@ def handle_choice(menu, choice): """Route to the handler for the given menu choice""" + menu[choice-1][1]() @@ -292,7 +309,11 @@ ] +#===== MAIN PROGRAM =========================================================== + def setup_tool(): + """The main program loop""" + while not quit: print("MAIN MENU") show_menu(MAIN_MENU) @@ -301,15 +322,15 @@ handle_choice(MAIN_MENU, choice) -#----- MAIN ENTRY POINT ------------------------------------------------------- - if __name__ == "__main__": + energenie.init() try: setup_tool() finally: energenie.finished() + # END