Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

hdhomerun.py - v3 - quintesse

By: a guest on Apr 3rd, 2011  |  syntax: Python  |  size: 25.54 KB  |  views: 165  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #
  2. # hdhomerun.py
  3. #
  4. # Copyright (c) 2011 Tako Schotanus <tako@codejive.org>.
  5. #
  6. # This library is free software; you can redistribute it and/or
  7. # modify it under the terms of the GNU Lesser General Public
  8. # License as published by the Free Software Foundation; either
  9. # version 3 of the License, or (at your option) any later version.
  10. #
  11. # This library is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14. # Lesser General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU Lesser General Public
  17. # License along with this library.  If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. # As a special exception to the GNU Lesser General Public License,
  20. # you may link, statically or dynamically, an application with a
  21. # publicly distributed version of the Library to produce an
  22. # executable file containing portions of the Library, and
  23. # distribute that executable file under terms of your choice,
  24. # without any of the additional requirements listed in clause 4 of
  25. # the GNU Lesser General Public License.
  26. #
  27. # By "a publicly distributed version of the Library", we mean
  28. # either the unmodified Library as distributed by Silicondust, or a
  29. # modified version of the Library that is distributed under the
  30. # conditions defined in the GNU Lesser General Public License.
  31. #
  32.  
  33. ###################################################################################
  34. # PS: Parts of the documentation in this file are copied from the C header files
  35. # Copyright (c) 2006-2007 Silicondust USA Inc. <www.silicondust.com>.
  36. # which are distributed under the LGPL as well, it's assumed the original copyright
  37. # holders are okay with this.
  38. ###################################################################################
  39.  
  40. from ctypes import *
  41. import sys
  42.  
  43. HDHOMERUN_DEVICE_TYPE_WILDCARD = 0xFFFFFFFF
  44. HDHOMERUN_DEVICE_TYPE_TUNER = 0x00000001
  45. HDHOMERUN_DEVICE_ID_WILDCARD = 0xFFFFFFFF
  46.  
  47. HDHOMERUN_STATUS_COLOR_NEUTRAL = 0xFFFFFFFF
  48. HDHOMERUN_STATUS_COLOR_RED = 0xFFFF0000
  49. HDHOMERUN_STATUS_COLOR_YELLOW = 0xFFFFFF00
  50. HDHOMERUN_STATUS_COLOR_GREEN = 0xFF00C000
  51.  
  52. HDHOMERUN_CHANNELSCAN_PROGRAM_NORMAL = 0
  53. HDHOMERUN_CHANNELSCAN_PROGRAM_NODATA = 1
  54. HDHOMERUN_CHANNELSCAN_PROGRAM_CONTROL = 2
  55. HDHOMERUN_CHANNELSCAN_PROGRAM_ENCRYPTED = 3
  56.  
  57. _c_bool = c_int32
  58.        
  59. class hdhomerun_discover_device_t(Structure):
  60.     _fields_ = [
  61.         ("ip_addr", c_uint32),
  62.         ("device_type", c_uint32),
  63.         ("device_id", c_uint32),
  64.         ("tuner_count", c_ubyte)
  65.     ]
  66.  
  67. class hdhomerun_tuner_status_t(Structure):
  68.     _fields_ = [
  69.         ("channel", c_char * 32),
  70.         ("lock_str", c_char * 32),
  71.         ("signal_present", _c_bool),
  72.         ("lock_supported", _c_bool),
  73.         ("lock_unsupported", _c_bool),
  74.         ("signal_strength", c_int32),
  75.         ("signal_to_noise_quality", c_int32),
  76.         ("symbol_error_quality", c_int32),
  77.         ("raw_bits_per_second", c_uint32),
  78.         ("packets_per_second", c_uint32)
  79.     ]
  80.    
  81. class hdhomerun_channelscan_program_t(Structure):
  82.     _fields_ = [
  83.         ("program_str", c_char * 64),
  84.         ("program_number", c_ushort),
  85.         ("virtual_major", c_ushort),
  86.         ("virtual_minor", c_ushort),
  87.         ("type", c_ushort),
  88.         ("name", c_char * 32)
  89.     ]
  90.  
  91. class hdhomerun_channelscan_result_t(Structure):
  92.     _fields_ = [
  93.         ("channel_str", c_char * 64),
  94.         ("channelmap", c_uint32),
  95.         ("frequency", c_uint32),
  96.         ("status", hdhomerun_tuner_status_t),
  97.         ("program_count", c_int32),
  98.         ("programs", hdhomerun_channelscan_program_t * 64),
  99.         ("transport_stream_id_detected", _c_bool),
  100.         ("transport_stream_id", c_ushort)
  101.     ]
  102.  
  103. class hdhomerun_plotsample_t(Structure):
  104.     _fields_ = [
  105.         ("real", c_ushort),
  106.         ("imag", c_ushort)
  107.     ]
  108.  
  109. #
  110. # Low-level interface to libhdhomerun
  111. #
  112. class LibHdhr:
  113.     def __init__(self):
  114.         lib = self._libhdhr = cdll.LoadLibrary("libhdhomerun.so.1")
  115.         # Discovery related functions
  116.         LibHdhr._libfunc(lib.hdhomerun_discover_find_devices_custom, [ c_uint32, c_uint32, c_uint32, POINTER(hdhomerun_discover_device_t), c_int32 ], c_int32)
  117.         LibHdhr._libfunc(lib.hdhomerun_discover_validate_device_id, [ c_uint32 ], _c_bool)
  118.         # Device related functions
  119.         LibHdhr._libfunc(lib.hdhomerun_device_create, [ c_uint32, c_uint32, c_uint32, c_void_p ], c_void_p)
  120.         LibHdhr._libfunc(lib.hdhomerun_device_create_from_str, [ c_char_p, c_void_p ], c_void_p)
  121.         LibHdhr._libfunc(lib.hdhomerun_device_destroy, [ c_void_p ])
  122.         LibHdhr._libfunc(lib.hdhomerun_device_get_name, [ c_void_p ], c_char_p)
  123.         LibHdhr._libfunc(lib.hdhomerun_device_get_device_id, [ c_void_p ], c_uint32)
  124.         LibHdhr._libfunc(lib.hdhomerun_device_get_device_ip, [ c_void_p ], c_uint32)
  125.         LibHdhr._libfunc(lib.hdhomerun_device_get_device_id_requested, [ c_void_p ], c_uint32)
  126.         LibHdhr._libfunc(lib.hdhomerun_device_get_device_ip_requested, [ c_void_p ], c_uint32)
  127.         LibHdhr._libfunc(lib.hdhomerun_device_get_tuner, [ c_void_p ], c_uint32)
  128.         LibHdhr._libfunc(lib.hdhomerun_device_set_device, [ c_void_p, c_uint32, c_uint32 ], c_int32)
  129.         LibHdhr._libfunc(lib.hdhomerun_device_set_tuner, [ c_void_p, c_uint32 ], c_int32)
  130.         LibHdhr._libfunc(lib.hdhomerun_device_set_tuner_from_str, [ c_void_p, c_char_p ],c_int32)
  131.         LibHdhr._libfunc(lib.hdhomerun_device_get_local_machine_addr, [ c_void_p ], c_uint32)
  132.         LibHdhr._libfunc(lib.hdhomerun_device_get_model_str, [ c_void_p ], c_char_p)
  133.         LibHdhr._libfunc(lib.hdhomerun_device_get_tuner_status, [ c_void_p, POINTER(c_char_p), POINTER(hdhomerun_tuner_status_t) ], c_int32)
  134.         LibHdhr._libfunc(lib.hdhomerun_device_get_tuner_streaminfo, [ c_void_p, POINTER(c_char_p) ], c_int32)
  135.         LibHdhr._libfunc(lib.hdhomerun_device_get_tuner_channel, [ c_void_p, POINTER(c_char_p) ], c_int32)
  136.         LibHdhr._libfunc(lib.hdhomerun_device_get_tuner_channelmap, [ c_void_p, POINTER(c_char_p) ], c_int32)
  137.         LibHdhr._libfunc(lib.hdhomerun_device_get_tuner_filter, [ c_void_p, POINTER(c_char_p) ], c_int32)
  138.         LibHdhr._libfunc(lib.hdhomerun_device_get_tuner_program, [ c_void_p, POINTER(c_char_p) ], c_int32)
  139.         LibHdhr._libfunc(lib.hdhomerun_device_get_tuner_target, [ c_void_p, POINTER(c_char_p) ], c_int32)
  140.         LibHdhr._libfunc(lib.hdhomerun_device_get_tuner_lockkey_owner, [ c_void_p, POINTER(c_char_p) ], c_int32)
  141.         LibHdhr._libfunc(lib.hdhomerun_device_get_ir_target, [ c_void_p, POINTER(c_char_p) ], c_int32)
  142.         LibHdhr._libfunc(lib.hdhomerun_device_get_lineup_location, [ c_void_p, POINTER(c_char_p) ], c_int32)
  143.         LibHdhr._libfunc(lib.hdhomerun_device_set_tuner_channel, [ c_void_p, c_char_p ], c_int32)
  144.         LibHdhr._libfunc(lib.hdhomerun_device_set_tuner_channelmap, [ c_void_p, c_char_p ], c_int32)
  145.         LibHdhr._libfunc(lib.hdhomerun_device_set_tuner_filter, [ c_void_p, c_char_p ], c_int32)
  146.         LibHdhr._libfunc(lib.hdhomerun_device_set_tuner_program, [ c_void_p, c_char_p ], c_int32)
  147.         LibHdhr._libfunc(lib.hdhomerun_device_set_tuner_target, [ c_void_p, c_char_p ], c_int32)
  148.         LibHdhr._libfunc(lib.hdhomerun_device_set_ir_target, [ c_void_p, c_char_p ], c_int32)
  149.         LibHdhr._libfunc(lib.hdhomerun_device_set_lineup_location, [ c_void_p, c_char_p ], c_int32)
  150.         LibHdhr._libfunc(lib.hdhomerun_device_get_version, [ c_void_p, POINTER(c_char_p), POINTER(c_uint32) ], c_int32)
  151.         LibHdhr._libfunc(lib.hdhomerun_device_get_supported, [ c_void_p, c_char_p, POINTER(c_char_p) ], c_int32)
  152.         LibHdhr._libfunc(lib.hdhomerun_device_tuner_lockkey_request, [ c_void_p, POINTER(c_char_p) ], c_int32)
  153.         LibHdhr._libfunc(lib.hdhomerun_device_tuner_lockkey_release, [ c_void_p ], c_int32)
  154.         LibHdhr._libfunc(lib.hdhomerun_device_tuner_lockkey_force, [ c_void_p ], c_int32)
  155.         LibHdhr._libfunc(lib.hdhomerun_device_tuner_lockkey_use_value, [ c_void_p, c_uint32 ], c_int32)
  156.         LibHdhr._libfunc(lib.hdhomerun_device_wait_for_lock, [ c_void_p, POINTER(hdhomerun_tuner_status_t) ], c_int32)
  157.         LibHdhr._libfunc(lib.hdhomerun_device_channelscan_init, [ c_void_p, c_char_p ], c_int32)
  158.         LibHdhr._libfunc(lib.hdhomerun_device_channelscan_advance, [ c_void_p, POINTER(hdhomerun_channelscan_result_t) ], c_int32)
  159.         LibHdhr._libfunc(lib.hdhomerun_device_channelscan_detect, [ c_void_p, POINTER(hdhomerun_channelscan_result_t) ], c_int32)
  160.         LibHdhr._libfunc(lib.hdhomerun_device_channelscan_get_progress, [ c_void_p ], c_ubyte)
  161.         # Channel related functions
  162.         LibHdhr._libfunc(lib.hdhomerun_channelmap_get_channelmap_scan_group, [ c_char_p ], c_char_p)
  163.        
  164.     @staticmethod
  165.     def _libfunc(func, argtypes, restype = None):
  166.         func.argtypes = argtypes
  167.         func.restype = restype
  168.        
  169.     @staticmethod
  170.     def _get_str_attr(func, device_p):
  171.         p = pointer(c_char_p())
  172.         res = func(device_p, p)
  173.         return (res, None) if (res != 1) else (res, p.contents.value)
  174.  
  175.     #
  176.     # Find devices.
  177.     #
  178.     # The device information is stored in caller-supplied array of hdhomerun_discover_device_t vars.
  179.     # Multiple attempts are made to find devices.
  180.     # Execution time is typically 400ms if max_count is not reached.
  181.     #
  182.     # Set target_ip to zero to auto-detect the IP address.
  183.     # Set device_type to HDHOMERUN_DEVICE_TYPE_TUNER to detect HDHomeRun tuner devices.
  184.     # Set device_id to HDHOMERUN_DEVICE_ID_WILDCARD to detect all device ids.
  185.     #
  186.     # Returns the number of devices found.
  187.     # Retruns -1 on error.
  188.     #
  189.     def discover_find_devices_custom(self, target_ip, device_type, device_id, result_list = None, max_count = 64):
  190.         result_list = result_list or (hdhomerun_discover_device_t * 64)()
  191.         res = self._libhdhr.hdhomerun_discover_find_devices_custom(target_ip, device_type, device_id, pointer(result_list[0]), max_count)
  192.         return (res, None) if (res < 0) else (res, result_list)
  193.        
  194.     #
  195.     # Verify that the device ID given is valid.
  196.     #
  197.     # The device ID contains a self-check sequence that detects common user input errors including
  198.     # single-digit errors and two digit transposition errors.
  199.     #
  200.     # Returns TRUE if valid.
  201.     # Returns FALSE if not valid.
  202.     #
  203.     def discover_validate_device_id(self, device_id):
  204.         return self._libhdhr.hdhomerun_discover_validate_device_id(device_id)
  205.  
  206.     #
  207.     # uint32_t device_id = 32-bit device id of device. Set to HDHOMERUN_DEVICE_ID_WILDCARD to match any device ID.
  208.     # uint32_t device_ip = IP address of device. Set to 0 to auto-detect.
  209.     # unsigned int tuner = tuner index (0 or 1). Can be changed later by calling device_set_tuner().
  210.     # struct hdhomerun_debug_t *dbg: Pointer to debug logging object. Optional.
  211.     #
  212.     # Returns a pointer to the newly created device object.
  213.     #
  214.     # When no longer needed, the socket should be destroyed by calling device_destroy().
  215.     #
  216.     def device_create(self, device_id, device_ip, tuner, debug_t = None):
  217.         return self._libhdhr.hdhomerun_device_create(device_id, device_ip, tuner, debug_t)
  218.  
  219.     #
  220.     # The device_create_from_str function creates a device object from the given device_str.
  221.     # The device_str parameter can be any of the following forms:
  222.     #     <device id>
  223.     #     <device id>-<tuner index>
  224.     #     <ip address>
  225.     # If the tuner index is not included in the device_str then it is set to zero. Use hdhomerun_device_set_tuner
  226.     # or hdhomerun_device_set_tuner_from_str to set the tuner.
  227.     #
  228.     def device_create_from_str(self, device_str, debug_t = None):
  229.         return self._libhdhr.hdhomerun_device_create_from_str(device_str, debug_t)
  230.  
  231.     #
  232.     # Call when socket no longer needed
  233.     #
  234.     def device_destroy(self, device_p):
  235.         self._libhdhr.hdhomerun_device_destroy(device_p)
  236.  
  237.     #
  238.     # Get the device id, ip, or tuner of the device instance.
  239.     #
  240.  
  241.     def device_get_name(self, device_p):
  242.         return self._libhdhr.hdhomerun_device_get_name(device_p)
  243.  
  244.     def device_get_device_id(self, device_p):
  245.         return self._libhdhr.hdhomerun_device_get_device_id(device_p)
  246.  
  247.     def device_get_device_ip(self, device_p):
  248.         return self._libhdhr.hdhomerun_device_get_device_ip(device_p)
  249.  
  250.     def device_get_device_id_requested(self, device_p):
  251.         return self._libhdhr.hdhomerun_device_get_device_id_requested(device_p)
  252.  
  253.     def device_get_device_ip_requested(self, device_p):
  254.         return self._libhdhr.hdhomerun_device_get_device_ip_requested(device_p)
  255.  
  256.     def device_get_tuner(self, device_p):
  257.         return self._libhdhr.hdhomerun_device_get_tuner(device_p)
  258.  
  259.     #
  260.     # Get the device id, ip, or tuner of the device instance.
  261.     #
  262.    
  263.     def device_set_device(self, device_p, device_id, device_ip):
  264.         return self._libhdhr.hdhomerun_device_set_device(device_p, device_id, device_ip)
  265.  
  266.     def device_set_tuner(self, device_p, tuner):
  267.         return self._libhdhr.hdhomerun_device_set_tuner(device_p, tuner)
  268.  
  269.     # The hdhomerun_device_set_tuner_from_str function sets the tuner from the given tuner_str.
  270.     # The tuner_str parameter can be any of the following forms:
  271.     #     <tuner index>
  272.     #     /tuner<tuner index>
  273.     def device_set_tuner_from_str(self, device_p, tuner_str):
  274.         return self._libhdhr.hdhomerun_device_set_tuner_from_str(device_p, tuner_str)
  275.  
  276.     #
  277.     # Get the local machine IP address used when communicating with the device.
  278.     #
  279.     # This function is useful for determining the IP address to use with set target commands.
  280.     #
  281.     # Returns 32-bit IP address with native endianness, or 0 on error.
  282.     #
  283.     def device_get_local_machine_addr(self, device_p):
  284.         return self._libhdhr.hdhomerun_device_get_local_machine_addr(device_p)
  285.  
  286.     def device_get_model_str(self, device_p):
  287.         return self._libhdhr.hdhomerun_device_get_model_str(device_p)
  288.  
  289.     #
  290.     # Get operations.
  291.     #
  292.     # Returns a string with the information if the operation was successful.
  293.     # Returns 0 if the operation was rejected.
  294.     # Returns -1 if a communication error occurred.
  295.     #
  296.  
  297.     def device_get_tuner_status(self, device_p, status = None):
  298.         p = pointer(c_char_p())
  299.         status = status or hdhomerun_tuner_status_t()
  300.         res = self._libhdhr.hdhomerun_device_get_tuner_status(device_p, p, status)
  301.         return (res, None, None) if (res != 1) else (res, p.contents.value, status)
  302.  
  303.     def device_get_tuner_streaminfo(self, device_p):
  304.         func = self._libhdhr.hdhomerun_device_get_tuner_streaminfo
  305.         return LibHdhr._get_str_attr(func, device_p)
  306.  
  307.     def device_get_tuner_channel(self, device_p):
  308.         func = self._libhdhr.hdhomerun_device_get_tuner_channel
  309.         return LibHdhr._get_str_attr(func, device_p)
  310.  
  311.     def device_get_tuner_channelmap(self, device_p):
  312.         func = self._libhdhr.hdhomerun_device_get_tuner_channelmap
  313.         return LibHdhr._get_str_attr(func, device_p)
  314.  
  315.     def device_get_tuner_filter(self, device_p):
  316.         func = self._libhdhr.hdhomerun_device_get_tuner_filter
  317.         return LibHdhr._get_str_attr(func, device_p)
  318.  
  319.     def device_get_tuner_program(self, device_p):
  320.         func = self._libhdhr.hdhomerun_device_get_tuner_program
  321.         return LibHdhr._get_str_attr(func, device_p)
  322.  
  323.     def device_get_tuner_target(self, device_p):
  324.         func = self._libhdhr.hdhomerun_device_get_tuner_target
  325.         return LibHdhr._get_str_attr(func, device_p)
  326.  
  327.     def device_get_tuner_lockkey_owner(self, device_p):
  328.         func = self._libhdhr.hdhomerun_device_get_tuner_lockkey_owner
  329.         return LibHdhr._get_str_attr(func, device_p)
  330.  
  331.     def device_get_ir_target(self, device_p):
  332.         func = self._libhdhr.hdhomerun_device_get_ir_target
  333.         return LibHdhr._get_str_attr(func, device_p)
  334.  
  335.     def device_get_lineup_location(self, device_p):
  336.         func = self._libhdhr.hdhomerun_device_get_lineup_location
  337.         return LibHdhr._get_str_attr(func, device_p)
  338.  
  339.     def device_get_version(self, device_p):
  340.         p = pointer(c_char_p())
  341.         n = pointer(c_uint(0))
  342.         res = self._libhdhr.hdhomerun_device_get_version(device_p, p, n)
  343.         return (res, p.contents.value, n.contents.value)
  344.  
  345.     def device_get_supported(self, device_p, prefix):
  346.         p = pointer(c_char_p())
  347.         res = self._libhdhr.hdhomerun_device_get_supported(device_p, prefix, p)
  348.         return (res, p.contents.value)
  349.  
  350.     #
  351.     # Set operations.
  352.     #
  353.     # const char *<name> = String to send to device.
  354.     #
  355.     # Returns 1 if the operation was successful.
  356.     # Returns 0 if the operation was rejected.
  357.     # Returns -1 if a communication error occurred.
  358.     #
  359.  
  360.     def device_set_tuner_channel(self, device_p, channel):
  361.         return self._libhdhr.hdhomerun_device_set_tuner_channel(device_p, channel)
  362.  
  363.     def device_set_tuner_channelmap(self, device_p, channelmap):
  364.         return self._libhdhr.hdhomerun_device_set_tuner_channelmap(device_p, channelmap)
  365.  
  366.     def device_set_tuner_filter(self, device_p, filter):
  367.         return self._libhdhr.hdhomerun_device_set_tuner_filter(device_p, filter)
  368.  
  369.     def device_set_tuner_program(self, device_p, program):
  370.         return self._libhdhr.hdhomerun_device_set_tuner_program(device_p, program)
  371.  
  372.     def device_set_tuner_target(self, device_p, target):
  373.         return self._libhdhr.hdhomerun_device_set_tuner_target(device_p, target)
  374.  
  375.     def device_set_ir_target(self, device_p, target):
  376.         return self._libhdhr.hdhomerun_device_set_ir_target(device_p, target)
  377.  
  378.     def device_set_lineup_location(self, device_p, location):
  379.         return self._libhdhr.hdhomerun_device_set_lineup_location(device_p, location)
  380.        
  381.        
  382.     #
  383.     # Tuner locking.
  384.     #
  385.     # The hdhomerun_device_tuner_lockkey_request function is used to obtain a lock
  386.     # or to verify that the hdhomerun_device object still holds the lock.
  387.     # Returns 1 if the lock request was successful and the lock was obtained.
  388.     # Returns 0 if the lock request was rejected.
  389.     # Returns -1 if a communication error occurs.
  390.     #
  391.     # The hdhomerun_device_tuner_lockkey_release function is used to release a
  392.     # previously held lock. If locking is used then this function must be called
  393.     # before destroying the hdhomerun_device object.
  394.     #
  395.  
  396.     def device_tuner_lockkey_request(self, device_p):
  397.         err = pointer(c_char_p())
  398.         res = self._libhdhr.hdhomerun_device_tuner_lockkey_request(device_p, err)
  399.         return (res, err.contents.value)
  400.  
  401.     def device_tuner_lockkey_release(self, device_p):
  402.         return self._libhdhr.hdhomerun_device_tuner_lockkey_release(device_p)
  403.  
  404.     def device_tuner_lockkey_force(self, device_p):
  405.         return self._libhdhr.hdhomerun_device_tuner_lockkey_force(device_p)
  406.  
  407.     #
  408.     # Intended only for non persistent connections; eg, hdhomerun_config.
  409.     #
  410.     def device_tuner_lockkey_use_value(self, device_p, lockkey):
  411.         return self._libhdhr.hdhomerun_device_tuner_lockkey_use_value(device_p, lockkey)
  412.  
  413.     #
  414.     # Wait for tuner lock after channel change.
  415.     #
  416.     # The hdhomerun_device_wait_for_lock function is used to detect/wait for a lock vs no lock indication
  417.     # after a channel change.
  418.     #
  419.     # It will return quickly if a lock is aquired.
  420.     # It will return quickly if there is no signal detected.
  421.     # Worst case it will time out after 1.5 seconds - the case where there is signal but no lock.
  422.     #
  423.     def device_wait_for_lock(self, device_p, status = None):
  424.         status = status or hdhomerun_tuner_status_t()
  425.         res = self._libhdhr.hdhomerun_device_wait_for_lock(device_p, status)
  426.         return (res, None) if (res != 1) else (res, status)
  427.    
  428.     #
  429.     # Channel scan API.
  430.     #
  431.    
  432.     def device_channelscan_init(self, device_p, channelmap):
  433.         return self._libhdhr.hdhomerun_device_channelscan_init(device_p, channelmap)
  434.    
  435.     def device_channelscan_advance(self, device_p, result = None):
  436.         result = result or hdhomerun_channelscan_result_t()
  437.         res = self._libhdhr.hdhomerun_device_channelscan_advance(device_p, result)
  438.         return (res, None) if (res != 1) else (res, result)
  439.    
  440.     def device_channelscan_detect(self, device_p, result = None):
  441.         result = result or hdhomerun_channelscan_result_t()
  442.         res = self._libhdhr.hdhomerun_device_channelscan_detect(device_p, result)
  443.         return (res, None) if (res != 1) else (res, result)
  444.    
  445.     def device_channelscan_get_progress(self, device_p):
  446.         return self._libhdhr.hdhomerun_device_channelscan_get_progress(device_p)
  447.    
  448.     def channelmap_get_channelmap_scan_group(self, channelmap):
  449.         return self._libhdhr.hdhomerun_channelmap_get_channelmap_scan_group(channelmap)
  450.        
  451.  
  452. def ip2str(ip):
  453.         return '%d.%d.%d.%d' % (ip >> 24, (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff)
  454.  
  455. def id2str(id):
  456.         return '%08X' % id
  457.  
  458. def show_device_info(lib, dev):
  459.     print "  Id:         ", id2str(lib.device_get_device_id(dev)), "(", id2str(lib.device_get_device_id_requested(dev)), ")"
  460.     print "  Address:    ", ip2str(lib.device_get_device_ip(dev)), "(", ip2str(lib.device_get_device_ip_requested(dev)), ")"
  461.     print "  Local IP:   ", ip2str(lib.device_get_local_machine_addr(dev))
  462.     print "  Model:      ", lib.device_get_model_str(dev)
  463.     print "  Version:    ", lib.device_get_version(dev)
  464.     print "  Festures:   ", lib.device_get_supported(dev, None)
  465.     print "  IR Target:  ", lib.device_get_ir_target(dev)
  466.     print "  Lineup Loc: ", lib.device_get_lineup_location(dev)
  467.     print ""
  468.  
  469. def show_tuner_info(lib, dev):
  470.     print "    Tuner:      ", lib.device_get_tuner(dev)
  471.     print "    Name:       ", lib.device_get_name(dev)
  472.     print "    StreamInfo: ", lib.device_get_tuner_streaminfo(dev)
  473.     print "    Channel:    ", lib.device_get_tuner_channel(dev)
  474.     print "    ChannelMap: ", lib.device_get_tuner_channelmap(dev)
  475.     print "    Filter:     ", lib.device_get_tuner_filter(dev)
  476.     print "    Program:    ", lib.device_get_tuner_program(dev)
  477.     print "    Target:     ", lib.device_get_tuner_target(dev)
  478.     print "    Lock Owner: ", lib.device_get_tuner_lockkey_owner(dev)
  479.     (res, s1, s2) = lib.device_get_tuner_status(dev)
  480.     print "    Status:     ", s1
  481.     print "      Channel:          ", s2.channel
  482.     print "      Lock Str:         ", s2.lock_str
  483.     print "      Signal Present:   ", s2.signal_present
  484.     print "      Lock Supported:   ", s2.lock_supported
  485.     print "      Lock Unsupported: ", s2.lock_unsupported
  486.     print "      Signal Strength:  ", s2.signal_strength
  487.     print "      Signal Quality:   ", s2.signal_to_noise_quality
  488.     print "      Symbol Quality:   ", s2.symbol_error_quality
  489.     print "      Bits / sec:       ", s2.raw_bits_per_second
  490.     print "      Packets / sec:    ", s2.packets_per_second
  491.     print ""
  492.  
  493. lib = LibHdhr()
  494.  
  495. if True:
  496.     (res, devs) = lib.discover_find_devices_custom(0, HDHOMERUN_DEVICE_TYPE_TUNER, HDHOMERUN_DEVICE_ID_WILDCARD)
  497.     if res > 0:
  498.         print "Devices found:"
  499.         for i in range(res):
  500.             dd = devs[i]
  501.             dev = lib.device_create(dd.device_id, dd.ip_addr, 0)
  502.             if not not dev:
  503.                 show_device_info(lib, dev)
  504.                 for j in range(dd.tuner_count):
  505.                     lib.device_set_tuner(dev, j)
  506.                     show_tuner_info(lib, dev)
  507.                 lib.device_destroy(dev)
  508.             else:
  509.                 print "Could not create device", dd.device_id
  510.         print ""
  511.     elif res == 0:
  512.         print "NO devices found!"
  513.     else:
  514.         print "Error trying to discover devices"
  515.    
  516.  
  517. if True:
  518.     dev = lib.device_create(HDHOMERUN_DEVICE_ID_WILDCARD, 0, 1)
  519.     #dev = lib.device_create_from_str("111035F2")
  520.     if not dev:
  521.         print "Could not create device!"
  522.         sys.exit()
  523.  
  524.     device_id_requested = lib.device_get_device_id_requested(dev)
  525.     if not lib.discover_validate_device_id(device_id_requested):
  526.         print "Invalid device Id:", hex(device_id_requested)
  527.         lib.device_destroy(dev)
  528.         sys.exit()
  529.    
  530.     #print lib.device_set_tuner_from_str(dev, "1")
  531.    
  532.     (res, err) = lib.device_tuner_lockkey_request(dev)
  533.     if res != 1:
  534.         print "Could not lock tuner: ", err
  535.         lib.device_destroy(dev)
  536.         sys.exit()
  537.    
  538.     print "Scanning..."
  539.     lib.device_set_tuner_target(dev, "none")
  540.     (res, chmap) = lib.device_get_tuner_channelmap(dev)
  541.     group = lib.channelmap_get_channelmap_scan_group(chmap)
  542.     if not not group:
  543.         if lib.device_channelscan_init(dev, group) == 1:
  544.             cont = True
  545.             while cont:
  546.                 (res, scan) = lib.device_channelscan_advance(dev)
  547.                 if res == 1:
  548.                     print scan.frequency, scan.channel_str, scan.status.signal_present,
  549.                     (res, detres) = lib.device_channelscan_detect(dev, scan)
  550.                     if res == 1:
  551.                         print lib.device_channelscan_get_progress(dev)
  552.                         for i in range(detres.program_count):
  553.                             p = detres.programs[i]
  554.                             print "   ", p.program_str, p.type
  555.                     elif res == 0:
  556.                         print "No signal"
  557.                     else:
  558.                         print "*** Communication error ***"
  559.                         cont = False
  560.                 else:
  561.                     cont = False
  562.         else:
  563.             print "Could not initialize channel scan"
  564.     else:
  565.         print "Unknown channel map ", chmap
  566.     lib.device_tuner_lockkey_release(dev)
  567.     lib.device_destroy(dev)