diff --git a/bindings/python/native/MANIFEST.in b/bindings/python/native/MANIFEST.in index de92c867..9a264a7a 100644 --- a/bindings/python/native/MANIFEST.in +++ b/bindings/python/native/MANIFEST.in @@ -1,3 +1,3 @@ -include telldus.c -include telldus-core.h -recursive-include example/* +include telldus.c +include telldus-core.h +recursive-include example/* diff --git a/bindings/python/native/example/basic.py b/bindings/python/native/example/basic.py index ad5e37a0..f8fef675 100644 --- a/bindings/python/native/example/basic.py +++ b/bindings/python/native/example/basic.py @@ -1,47 +1,47 @@ - -import telldus -import time - -telldus.tdInit() -devices = telldus.tdGetNumberOfDevices() -print "Devices: %d\n" % devices - -allMethods = telldus.TELLSTICK_TURNON | telldus.TELLSTICK_TURNOFF | telldus.TELLSTICK_BELL | telldus.TELLSTICK_DIM - -for i in xrange(devices): - deviceid = telldus.tdGetDeviceId(i) - - if deviceid: - name = telldus.tdGetName(deviceid) - - print "%s - %s\n" % (deviceid, name) - - methods = telldus.tdMethods(deviceid, allMethods) - - if methods & telldus.TELLSTICK_TURNON: - print " * TurnOn\n" - telldus.tdTurnOn(deviceid) - time.sleep(1) - - if methods & telldus.TELLSTICK_TURNOFF: - print " * TurnOff\n" - telldus.tdTurnOff(deviceid) - time.sleep(1) - - if methods & telldus.TELLSTICK_BELL: - print " * Bell\n" - telldus.tdBell(deviceid) - time.sleep(1) - - if methods & telldus.TELLSTICK_TOGGLE: - print " * Toggle\n" - - if methods & telldus.TELLSTICK_DIM: - print " * Dim\n" - telldus.tdDim(deviceid, 128) - time.sleep(1) - -telldus.tdClose() - - - + +import telldus +import time + +telldus.tdInit() +devices = telldus.tdGetNumberOfDevices() +print "Devices: %d\n" % devices + +allMethods = telldus.TELLSTICK_TURNON | telldus.TELLSTICK_TURNOFF | telldus.TELLSTICK_BELL | telldus.TELLSTICK_DIM + +for i in xrange(devices): + deviceid = telldus.tdGetDeviceId(i) + + if deviceid: + name = telldus.tdGetName(deviceid) + + print "%s - %s\n" % (deviceid, name) + + methods = telldus.tdMethods(deviceid, allMethods) + + if methods & telldus.TELLSTICK_TURNON: + print " * TurnOn\n" + telldus.tdTurnOn(deviceid) + time.sleep(1) + + if methods & telldus.TELLSTICK_TURNOFF: + print " * TurnOff\n" + telldus.tdTurnOff(deviceid) + time.sleep(1) + + if methods & telldus.TELLSTICK_BELL: + print " * Bell\n" + telldus.tdBell(deviceid) + time.sleep(1) + + if methods & telldus.TELLSTICK_TOGGLE: + print " * Toggle\n" + + if methods & telldus.TELLSTICK_DIM: + print " * Dim\n" + telldus.tdDim(deviceid, 128) + time.sleep(1) + +telldus.tdClose() + + + diff --git a/bindings/python/native/example/callback.py b/bindings/python/native/example/callback.py index a6242a6f..ca5f6b8d 100644 --- a/bindings/python/native/example/callback.py +++ b/bindings/python/native/example/callback.py @@ -1,38 +1,38 @@ -import threading -import telldus -import time - -telldus.tdInit() - -def turnOn(): - print "turning on" - telldus.tdTurnOn(1) - -def turnOff(): - print "turning off" - telldus.tdTurnOff(1) - -def callback(deviceId, method, value, callbackId): - print "callback" - print "DeviceId: %i Method: %i Value: %s" % (deviceId, method, value) - return True - -#function to be called when device event occurs, even for unregistered devices -def rawcallback(data, controllerId, callbackId): - print "raw callback" - print "Data: %s ControllerId: %i" % (data, controllerId) - return True - -callbackid = telldus.tdRegisterDeviceEvent(callback) -rawcallbackid = telldus.tdRegisterRawDeviceEvent(rawcallback) - -print callbackid, rawcallbackid - -try: - while(1): - time.sleep(0.5) #don't exit -except KeyboardInterrupt: - print "Exiting" - telldus.tdUnregisterCallback(callbackid) - telldus.tdUnregisterCallback(rawcallbackid) - telldus.tdClose() +import threading +import telldus +import time + +telldus.tdInit() + +def turnOn(): + print "turning on" + telldus.tdTurnOn(1) + +def turnOff(): + print "turning off" + telldus.tdTurnOff(1) + +def callback(deviceId, method, value, callbackId): + print "callback" + print "DeviceId: %i Method: %i Value: %s" % (deviceId, method, value) + return True + +#function to be called when device event occurs, even for unregistered devices +def rawcallback(data, controllerId, callbackId): + print "raw callback" + print "Data: %s ControllerId: %i" % (data, controllerId) + return True + +callbackid = telldus.tdRegisterDeviceEvent(callback) +rawcallbackid = telldus.tdRegisterRawDeviceEvent(rawcallback) + +print callbackid, rawcallbackid + +try: + while(1): + time.sleep(0.5) #don't exit +except KeyboardInterrupt: + print "Exiting" + telldus.tdUnregisterCallback(callbackid) + telldus.tdUnregisterCallback(rawcallbackid) + telldus.tdClose() diff --git a/bindings/python/native/setup.py b/bindings/python/native/setup.py index e0413c13..19e0c7fa 100644 --- a/bindings/python/native/setup.py +++ b/bindings/python/native/setup.py @@ -1,345 +1,345 @@ -import sys -from distutils.core import setup, Extension - -DEBUG = True - -PLATFORM_IS_WINDOWS = sys.platform.lower().startswith('win') - -if PLATFORM_IS_WINDOWS: - - __doc__="""This is a distutils setup-script for the telldus extension - - To build the telldus extensions, simply execute: - python setup.py -q build - or - python setup.py -q install - to build and install into your current Python installation. - - These extensions require a number of libraries to build, some of which may - require you to install special SDKs or toolkits. This script will attempt - to build as many as it can, and at the end of the build will report any - extension modules that could not be built and why. - - This has got complicated due to the various different versions of - Visual Studio used - some VS versions are not compatible with some SDK - versions. Below are the Windows SDK versions required (and the URL - although - these are subject to being changed by MS at any time:) - - Python 2.6+: - - Build using Microsoft Visual Studio 2008 Express Edition: - http://www.microsoft.com/en-us/download/details.aspx?id=6506 - http://jenshuebel.wordpress.com/2009/02/12/visual-c-2008-express-edition-and-64-bit-targets/ - http://www.cppblog.com/Files/xcpp/VCE64BIT_WIN7SDK.zip - - For 32bit build: - Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 - http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b - Copy C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvars32.bat to - C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat - - For 64bit build: - Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1 (ISO) GRMSDKX_EN_DVD.iso - http://www.microsoft.com/en-us/download/details.aspx?id=18950 - Copy C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvars64.bat to - C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat - - Python 2.3->2.5: - - Microsoft Windows Software Development Kit Update for Windows Vista (version 6.0) - http://www.microsoft.com/downloads/en/details.aspx?FamilyID=4377f86d-c913-4b5c-b87e-ef72e5b4e065 - ** If you want to build Python 2.3, be sure to install the SDK compilers - too - although we don't use them, this setup option installs some .lib - files we do need. - ** - - If you multiple SDK versions on a single machine, set the MSSDK environment - variable to point at the one you want to use. Note that using the SDK for - a particular platform (eg, Windows 7) doesn't force you to use that OS as your - build environment. If the links above don't work, use google to find them. - - Building: - --------- - - To install the telldus extension, execute: - python setup.py -q install - - This will install the built extensions into your site-packages directory, - create an appropriate .pth file, and should leave everything ready to use. - There is no need to modify the registry. - - To build or install debug (_d) versions of these extensions, ensure you have - built or installed a debug version of Python itself, then pass the "--debug" - flag to the build command - eg: - python setup.py -q build --debug - or to build and install a debug version: - python setup.py -q build --debug install - - To build 64bit versions of this: - - * py2.5 and earlier - sorry, I've given up in disgust. Using VS2003 with - the Vista SDK is just too painful to make work, and VS2005 is not used for - any released versions of Python. See revision 1.69 of this file for the - last version that attempted to support and document this process. - - * 2.6 and later: On a 64bit OS, just build as you would on a 32bit platform. - On a 32bit platform (ie, to cross-compile), you must use VS2008 to - cross-compile Python itself. Note that by default, the 64bit tools are not - installed with VS2008, so you may need to adjust your VS2008 setup (see "For 64bit build"). Then - use: - vcs - setup.py build --plat-name=win-amd64 - - see the distutils cross-compilation documentation for more details. - """ - # Originally by Thomas Heller, started in 2000 or so. - import os - import shutil - - is_py3k = sys.version_info > (3,) # get this out of the way early on... - # We have special handling for _winreg so our setup3.py script can avoid - # using the 'imports' fixer and therefore start much faster... - if is_py3k: - import winreg as _winreg - else: - import _winreg - - try: - from distutils import log - except ImportError: - class Log: - def debug(self, msg, *args): - print msg % args - def info(self, msg, *args): - print msg % args - log = Log() - - try: - this_file = __file__ - except NameError: - this_file = sys.argv[0] - - this_file = os.path.abspath(this_file) - # We get upset if the cwd is not our source dir, but it is a PITA to - # insist people manually CD there first! - if os.path.dirname(this_file): - os.chdir(os.path.dirname(this_file)) - - - # We need to know the platform SDK dir before we can list the extensions. - def find_platform_sdk_dir(): - # Finding the Platform SDK install dir is a treat. There can be some - # dead ends so we only consider the job done if we find the "windows.h" - # landmark. - landmark = "include\\windows.h" - # 1. The use might have their current environment setup for the - # SDK, in which case the "MSSdk" env var is set. - sdkdir = os.environ.get("MSSdk") - if sdkdir: - if DEBUG: - print "PSDK: try %%MSSdk%%: '%s'" % sdkdir - if os.path.isfile(os.path.join(sdkdir, landmark)): - return sdkdir - # 2. The "Install Dir" value in the - # HKLM\Software\Microsoft\MicrosoftSDK\Directories registry key - # sometimes points to the right thing. However, after upgrading to - # the "Platform SDK for Windows Server 2003 SP1" this is dead end. - try: - key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, - r"Software\Microsoft\MicrosoftSDK\Directories") - sdkdir, ignore = _winreg.QueryValueEx(key, "Install Dir") - except EnvironmentError: - pass - else: - if DEBUG: - print r"PSDK: try 'HKLM\Software\Microsoft\MicrosoftSDK"\ - "\Directories\Install Dir': '%s'" % sdkdir - if os.path.isfile(os.path.join(sdkdir, landmark)): - return sdkdir - # 3. Each installed SDK (not just the platform SDK) seems to have GUID - # subkey of HKLM\Software\Microsoft\MicrosoftSDK\InstalledSDKs and - # it *looks* like the latest installed Platform SDK will be the - # only one with an "Install Dir" sub-value. - try: - key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, - r"Software\Microsoft\MicrosoftSDK\InstalledSDKs") - i = 0 - while True: - guid = _winreg.EnumKey(key, i) - guidkey = _winreg.OpenKey(key, guid) - try: - sdkdir, ignore = _winreg.QueryValueEx(guidkey, "Install Dir") - except EnvironmentError: - pass - else: - if DEBUG: - print r"PSDK: try 'HKLM\Software\Microsoft\MicrosoftSDK"\ - "\InstallSDKs\%s\Install Dir': '%s'"\ - % (guid, sdkdir) - if os.path.isfile(os.path.join(sdkdir, landmark)): - return sdkdir - i += 1 - except EnvironmentError: - pass - # 4. Vista's SDK - try: - key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, - r"Software\Microsoft\Microsoft SDKs\Windows") - sdkdir, ignore = _winreg.QueryValueEx(key, "CurrentInstallFolder") - except EnvironmentError: - pass - else: - if DEBUG: - print r"PSDK: try 'HKLM\Software\Microsoft\MicrosoftSDKs"\ - "\Windows\CurrentInstallFolder': '%s'" % sdkdir - if os.path.isfile(os.path.join(sdkdir, landmark)): - return sdkdir - - # 5. Failing this just try a few well-known default install locations. - progfiles = os.environ.get("ProgramFiles", r"C:\Program Files") - defaultlocs = [ - os.path.join(progfiles, "Microsoft Platform SDK"), - os.path.join(progfiles, "Microsoft SDK"), - ] - for sdkdir in defaultlocs: - if DEBUG: - print "PSDK: try default location: '%s'" % sdkdir - if os.path.isfile(os.path.join(sdkdir, landmark)): - return sdkdir - - - # Some nasty hacks to prevent most of our extensions using a manifest, as - # the manifest - even without a reference to the CRT assembly - is enough - # to prevent the extension from loading. For more details, see - # http://bugs.python.org/issue7833 - that issue has a patch, but it is - # languishing and will probably never be fixed for Python 2.6... - if sys.version_info > (2,6): - from distutils.spawn import spawn - from distutils.msvc9compiler import MSVCCompiler - MSVCCompiler._orig_spawn = MSVCCompiler.spawn - MSVCCompiler._orig_link = MSVCCompiler.link - - # We need to override this method for versions where issue7833 *has* landed - # (ie, 2.7 and 3.2+) - def manifest_get_embed_info(self, target_desc, ld_args): - _want_assembly_kept = getattr(self, '_want_assembly_kept', False) - if not _want_assembly_kept: - return None - for arg in ld_args: - if arg.startswith("/MANIFESTFILE:"): - orig_manifest = arg.split(":", 1)[1] - if target_desc==self.EXECUTABLE: - rid = 1 - else: - rid = 2 - return orig_manifest, rid - return None - # always monkeypatch it in even though it will only be called in 2.7 - # and 3.2+. - MSVCCompiler.manifest_get_embed_info = manifest_get_embed_info - - def monkeypatched_spawn(self, cmd): - is_link = cmd[0].endswith("link.exe") or cmd[0].endswith('"link.exe"') - is_mt = cmd[0].endswith("mt.exe") or cmd[0].endswith('"mt.exe"') - _want_assembly_kept = getattr(self, '_want_assembly_kept', False) - if not _want_assembly_kept and is_mt: - # We don't want mt.exe run... - return - if not _want_assembly_kept and is_link: - # remove /MANIFESTFILE:... and add MANIFEST:NO - # (but note that for winxpgui, which specifies a manifest via a - # .rc file, this is ignored by the linker - the manifest specified - # in the .rc file is still added) - for i in range(len(cmd)): - if cmd[i].startswith("/MANIFESTFILE:"): - cmd[i] = "/MANIFEST:NO" - break - if _want_assembly_kept and is_mt: - # We want mt.exe run with the original manifest - for i in range(len(cmd)): - if cmd[i] == "-manifest": - cmd[i+1] = cmd[i+1] + ".orig" - break - self._orig_spawn(cmd) - if _want_assembly_kept and is_link: - # We want a copy of the original manifest so we can use it later. - for i in range(len(cmd)): - if cmd[i].startswith("/MANIFESTFILE:"): - mfname = cmd[i][14:] - shutil.copyfile(mfname, mfname + ".orig") - break - - def monkeypatched_link(self, target_desc, objects, output_filename, *args, **kw): - # no manifests for 3.3+ - self._want_assembly_kept = sys.version_info < (3,3) and \ - (os.path.basename(output_filename).startswith("PyISAPI_loader.dll") or \ - os.path.basename(output_filename).startswith("perfmondata.dll") or \ - os.path.basename(output_filename).startswith("win32ui.pyd") or \ - target_desc==self.EXECUTABLE) - try: - return self._orig_link(target_desc, objects, output_filename, *args, **kw) - finally: - delattr(self, '_want_assembly_kept') - MSVCCompiler.spawn = monkeypatched_spawn - MSVCCompiler.link = monkeypatched_link - - def find_telldus_dev_dir(): - landmark = "telldus-core.h" - dev_dir = os.environ.get("TELLDUS_DEVDIR") - if dev_dir: - if DEBUG: - print "Telldus dev dir:" % dev_dir - if os.path.isfile(os.path.join(dev_dir, landmark)): - return dev_dir - - progfiles = os.environ.get("ProgramFiles", r"C:\Program Files") - defaultlocs = [ - os.path.join(progfiles + ' (x86)', "Telldus", "Development"), - os.path.join(progfiles, "Telldus", "Development"), - ] - for dev_dir in defaultlocs: - if DEBUG: - print "Telldus dev dir: '%s'" % dev_dir - if os.path.isfile(os.path.join(dev_dir, landmark)): - return dev_dir - if DEBUG: - print "Telldus dev dir not found, make sure dev code is installed. Or set TELLDUS_DEVDIR." - - sdk_dir = find_platform_sdk_dir() - sdk_include_dir = os.path.join(sdk_dir, 'Include') - - telldus_dev_dir = find_telldus_dev_dir() - telldus_platform = os.environ.get("TELLDUS_PLATFORM", 'x86_64') - telldus_library_dir = os.path.join(telldus_dev_dir, telldus_platform) - - include_dirs = [sdk_include_dir, telldus_dev_dir] - library_dirs = [telldus_library_dir] - libraries = ['python%i%i' % (sys.version_info[0], sys.version_info[1]) , 'TelldusCore'] - define_macros = [('_WINDOWS', 1)] - -else: - include_dirs = ['/usr/include', '/usr/local/include'] - library_dirs = ['/usr/lib', '/usr/local/lib'] - libraries = ['telldus-core'] - define_macros = [] - -define_macros.extend([('DATA_LENGTH', 20), ('CALLBACK_LENGTH', 20)]) - -telldus = Extension( - 'telldus', - include_dirs = include_dirs, - libraries = libraries, - library_dirs = library_dirs, - define_macros = define_macros, - sources = ['telldus.c'] -) - -setup( - name = 'telldus', - version = '1.0', - description = 'Python bindings for telldus', - author='Oyvind Saltvik', - author_email='oyvind.saltvik@gmail.com', - url='http://github.com/fivethreeo/telldus/', - ext_modules = [telldus] -) +import sys +from distutils.core import setup, Extension + +DEBUG = True + +PLATFORM_IS_WINDOWS = sys.platform.lower().startswith('win') + +if PLATFORM_IS_WINDOWS: + + __doc__="""This is a distutils setup-script for the telldus extension + + To build the telldus extensions, simply execute: + python setup.py -q build + or + python setup.py -q install + to build and install into your current Python installation. + + These extensions require a number of libraries to build, some of which may + require you to install special SDKs or toolkits. This script will attempt + to build as many as it can, and at the end of the build will report any + extension modules that could not be built and why. + + This has got complicated due to the various different versions of + Visual Studio used - some VS versions are not compatible with some SDK + versions. Below are the Windows SDK versions required (and the URL - although + these are subject to being changed by MS at any time:) + + Python 2.6+: + + Build using Microsoft Visual Studio 2008 Express Edition: + http://www.microsoft.com/en-us/download/details.aspx?id=6506 + http://jenshuebel.wordpress.com/2009/02/12/visual-c-2008-express-edition-and-64-bit-targets/ + http://www.cppblog.com/Files/xcpp/VCE64BIT_WIN7SDK.zip + + For 32bit build: + Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 + http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6b6c21d2-2006-4afa-9702-529fa782d63b + Copy C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvars32.bat to + C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat + + For 64bit build: + Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1 (ISO) GRMSDKX_EN_DVD.iso + http://www.microsoft.com/en-us/download/details.aspx?id=18950 + Copy C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvars64.bat to + C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat + + Python 2.3->2.5: + + Microsoft Windows Software Development Kit Update for Windows Vista (version 6.0) + http://www.microsoft.com/downloads/en/details.aspx?FamilyID=4377f86d-c913-4b5c-b87e-ef72e5b4e065 + ** If you want to build Python 2.3, be sure to install the SDK compilers + too - although we don't use them, this setup option installs some .lib + files we do need. + ** + + If you multiple SDK versions on a single machine, set the MSSDK environment + variable to point at the one you want to use. Note that using the SDK for + a particular platform (eg, Windows 7) doesn't force you to use that OS as your + build environment. If the links above don't work, use google to find them. + + Building: + --------- + + To install the telldus extension, execute: + python setup.py -q install + + This will install the built extensions into your site-packages directory, + create an appropriate .pth file, and should leave everything ready to use. + There is no need to modify the registry. + + To build or install debug (_d) versions of these extensions, ensure you have + built or installed a debug version of Python itself, then pass the "--debug" + flag to the build command - eg: + python setup.py -q build --debug + or to build and install a debug version: + python setup.py -q build --debug install + + To build 64bit versions of this: + + * py2.5 and earlier - sorry, I've given up in disgust. Using VS2003 with + the Vista SDK is just too painful to make work, and VS2005 is not used for + any released versions of Python. See revision 1.69 of this file for the + last version that attempted to support and document this process. + + * 2.6 and later: On a 64bit OS, just build as you would on a 32bit platform. + On a 32bit platform (ie, to cross-compile), you must use VS2008 to + cross-compile Python itself. Note that by default, the 64bit tools are not + installed with VS2008, so you may need to adjust your VS2008 setup (see "For 64bit build"). Then + use: + vcs + setup.py build --plat-name=win-amd64 + + see the distutils cross-compilation documentation for more details. + """ + # Originally by Thomas Heller, started in 2000 or so. + import os + import shutil + + is_py3k = sys.version_info > (3,) # get this out of the way early on... + # We have special handling for _winreg so our setup3.py script can avoid + # using the 'imports' fixer and therefore start much faster... + if is_py3k: + import winreg as _winreg + else: + import _winreg + + try: + from distutils import log + except ImportError: + class Log: + def debug(self, msg, *args): + print msg % args + def info(self, msg, *args): + print msg % args + log = Log() + + try: + this_file = __file__ + except NameError: + this_file = sys.argv[0] + + this_file = os.path.abspath(this_file) + # We get upset if the cwd is not our source dir, but it is a PITA to + # insist people manually CD there first! + if os.path.dirname(this_file): + os.chdir(os.path.dirname(this_file)) + + + # We need to know the platform SDK dir before we can list the extensions. + def find_platform_sdk_dir(): + # Finding the Platform SDK install dir is a treat. There can be some + # dead ends so we only consider the job done if we find the "windows.h" + # landmark. + landmark = "include\\windows.h" + # 1. The use might have their current environment setup for the + # SDK, in which case the "MSSdk" env var is set. + sdkdir = os.environ.get("MSSdk") + if sdkdir: + if DEBUG: + print "PSDK: try %%MSSdk%%: '%s'" % sdkdir + if os.path.isfile(os.path.join(sdkdir, landmark)): + return sdkdir + # 2. The "Install Dir" value in the + # HKLM\Software\Microsoft\MicrosoftSDK\Directories registry key + # sometimes points to the right thing. However, after upgrading to + # the "Platform SDK for Windows Server 2003 SP1" this is dead end. + try: + key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, + r"Software\Microsoft\MicrosoftSDK\Directories") + sdkdir, ignore = _winreg.QueryValueEx(key, "Install Dir") + except EnvironmentError: + pass + else: + if DEBUG: + print r"PSDK: try 'HKLM\Software\Microsoft\MicrosoftSDK"\ + "\Directories\Install Dir': '%s'" % sdkdir + if os.path.isfile(os.path.join(sdkdir, landmark)): + return sdkdir + # 3. Each installed SDK (not just the platform SDK) seems to have GUID + # subkey of HKLM\Software\Microsoft\MicrosoftSDK\InstalledSDKs and + # it *looks* like the latest installed Platform SDK will be the + # only one with an "Install Dir" sub-value. + try: + key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, + r"Software\Microsoft\MicrosoftSDK\InstalledSDKs") + i = 0 + while True: + guid = _winreg.EnumKey(key, i) + guidkey = _winreg.OpenKey(key, guid) + try: + sdkdir, ignore = _winreg.QueryValueEx(guidkey, "Install Dir") + except EnvironmentError: + pass + else: + if DEBUG: + print r"PSDK: try 'HKLM\Software\Microsoft\MicrosoftSDK"\ + "\InstallSDKs\%s\Install Dir': '%s'"\ + % (guid, sdkdir) + if os.path.isfile(os.path.join(sdkdir, landmark)): + return sdkdir + i += 1 + except EnvironmentError: + pass + # 4. Vista's SDK + try: + key = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, + r"Software\Microsoft\Microsoft SDKs\Windows") + sdkdir, ignore = _winreg.QueryValueEx(key, "CurrentInstallFolder") + except EnvironmentError: + pass + else: + if DEBUG: + print r"PSDK: try 'HKLM\Software\Microsoft\MicrosoftSDKs"\ + "\Windows\CurrentInstallFolder': '%s'" % sdkdir + if os.path.isfile(os.path.join(sdkdir, landmark)): + return sdkdir + + # 5. Failing this just try a few well-known default install locations. + progfiles = os.environ.get("ProgramFiles", r"C:\Program Files") + defaultlocs = [ + os.path.join(progfiles, "Microsoft Platform SDK"), + os.path.join(progfiles, "Microsoft SDK"), + ] + for sdkdir in defaultlocs: + if DEBUG: + print "PSDK: try default location: '%s'" % sdkdir + if os.path.isfile(os.path.join(sdkdir, landmark)): + return sdkdir + + + # Some nasty hacks to prevent most of our extensions using a manifest, as + # the manifest - even without a reference to the CRT assembly - is enough + # to prevent the extension from loading. For more details, see + # http://bugs.python.org/issue7833 - that issue has a patch, but it is + # languishing and will probably never be fixed for Python 2.6... + if sys.version_info > (2,6): + from distutils.spawn import spawn + from distutils.msvc9compiler import MSVCCompiler + MSVCCompiler._orig_spawn = MSVCCompiler.spawn + MSVCCompiler._orig_link = MSVCCompiler.link + + # We need to override this method for versions where issue7833 *has* landed + # (ie, 2.7 and 3.2+) + def manifest_get_embed_info(self, target_desc, ld_args): + _want_assembly_kept = getattr(self, '_want_assembly_kept', False) + if not _want_assembly_kept: + return None + for arg in ld_args: + if arg.startswith("/MANIFESTFILE:"): + orig_manifest = arg.split(":", 1)[1] + if target_desc==self.EXECUTABLE: + rid = 1 + else: + rid = 2 + return orig_manifest, rid + return None + # always monkeypatch it in even though it will only be called in 2.7 + # and 3.2+. + MSVCCompiler.manifest_get_embed_info = manifest_get_embed_info + + def monkeypatched_spawn(self, cmd): + is_link = cmd[0].endswith("link.exe") or cmd[0].endswith('"link.exe"') + is_mt = cmd[0].endswith("mt.exe") or cmd[0].endswith('"mt.exe"') + _want_assembly_kept = getattr(self, '_want_assembly_kept', False) + if not _want_assembly_kept and is_mt: + # We don't want mt.exe run... + return + if not _want_assembly_kept and is_link: + # remove /MANIFESTFILE:... and add MANIFEST:NO + # (but note that for winxpgui, which specifies a manifest via a + # .rc file, this is ignored by the linker - the manifest specified + # in the .rc file is still added) + for i in range(len(cmd)): + if cmd[i].startswith("/MANIFESTFILE:"): + cmd[i] = "/MANIFEST:NO" + break + if _want_assembly_kept and is_mt: + # We want mt.exe run with the original manifest + for i in range(len(cmd)): + if cmd[i] == "-manifest": + cmd[i+1] = cmd[i+1] + ".orig" + break + self._orig_spawn(cmd) + if _want_assembly_kept and is_link: + # We want a copy of the original manifest so we can use it later. + for i in range(len(cmd)): + if cmd[i].startswith("/MANIFESTFILE:"): + mfname = cmd[i][14:] + shutil.copyfile(mfname, mfname + ".orig") + break + + def monkeypatched_link(self, target_desc, objects, output_filename, *args, **kw): + # no manifests for 3.3+ + self._want_assembly_kept = sys.version_info < (3,3) and \ + (os.path.basename(output_filename).startswith("PyISAPI_loader.dll") or \ + os.path.basename(output_filename).startswith("perfmondata.dll") or \ + os.path.basename(output_filename).startswith("win32ui.pyd") or \ + target_desc==self.EXECUTABLE) + try: + return self._orig_link(target_desc, objects, output_filename, *args, **kw) + finally: + delattr(self, '_want_assembly_kept') + MSVCCompiler.spawn = monkeypatched_spawn + MSVCCompiler.link = monkeypatched_link + + def find_telldus_dev_dir(): + landmark = "telldus-core.h" + dev_dir = os.environ.get("TELLDUS_DEVDIR") + if dev_dir: + if DEBUG: + print "Telldus dev dir:" % dev_dir + if os.path.isfile(os.path.join(dev_dir, landmark)): + return dev_dir + + progfiles = os.environ.get("ProgramFiles", r"C:\Program Files") + defaultlocs = [ + os.path.join(progfiles + ' (x86)', "Telldus", "Development"), + os.path.join(progfiles, "Telldus", "Development"), + ] + for dev_dir in defaultlocs: + if DEBUG: + print "Telldus dev dir: '%s'" % dev_dir + if os.path.isfile(os.path.join(dev_dir, landmark)): + return dev_dir + if DEBUG: + print "Telldus dev dir not found, make sure dev code is installed. Or set TELLDUS_DEVDIR." + + sdk_dir = find_platform_sdk_dir() + sdk_include_dir = os.path.join(sdk_dir, 'Include') + + telldus_dev_dir = find_telldus_dev_dir() + telldus_platform = os.environ.get("TELLDUS_PLATFORM", 'x86_64') + telldus_library_dir = os.path.join(telldus_dev_dir, telldus_platform) + + include_dirs = [sdk_include_dir, telldus_dev_dir] + library_dirs = [telldus_library_dir] + libraries = ['python%i%i' % (sys.version_info[0], sys.version_info[1]) , 'TelldusCore'] + define_macros = [('_WINDOWS', 1)] + +else: + include_dirs = ['/usr/include', '/usr/local/include'] + library_dirs = ['/usr/lib', '/usr/local/lib'] + libraries = ['telldus-core'] + define_macros = [] + +define_macros.extend([('DATA_LENGTH', 20), ('CALLBACK_LENGTH', 20)]) + +telldus = Extension( + 'telldus', + include_dirs = include_dirs, + libraries = libraries, + library_dirs = library_dirs, + define_macros = define_macros, + sources = ['telldus.c'] +) + +setup( + name = 'telldus', + version = '1.0', + description = 'Python bindings for telldus', + author='Oyvind Saltvik', + author_email='oyvind.saltvik@gmail.com', + url='http://github.com/fivethreeo/telldus/', + ext_modules = [telldus] +) diff --git a/bindings/python/native/telldus.c b/bindings/python/native/telldus.c index 8459be3f..a96fe51d 100644 --- a/bindings/python/native/telldus.c +++ b/bindings/python/native/telldus.c @@ -1,843 +1,843 @@ -#include "Python.h" -#include "datetime.h" -#include -#include - -/* estrdup.c -- duplicate a string, die if error - * - * char *string; - * char *newstring; - * newstring = estrdup(string); - * - * estrdup returns a copy of its argument, located in memory - * allocated from the heap. If it is unable to allocate the - * necessary memory, estrdup executes PyErr_NoMemory(); - * (Generally, the routine error is not expected to return, - * but if it does, estrdup will return NULL.) -*/ - -int callbackLen = 0; - -typedef struct { - PyObject *func; - int callbackId; -} callbackInfo; - -static callbackInfo callbackList[CALLBACK_LENGTH]; - -void -addCallback(PyObject *func, int callbackId) -{ - if (callbackLen < CALLBACK_LENGTH) { - callbackList[callbackLen].func = func; - callbackList[callbackLen].callbackId = callbackId; - callbackLen++; - } -} - -void -removeCallback(int callbackId) -{ - int index = -1; - - int i; - int j; - - for (i = 0; i < callbackLen; i++) - { - if (callbackList[i].callbackId == callbackId) - { - index = i; - } - } - if (!(index == -1)) { - for (j = index; j < callbackLen - 1; j++) - { - callbackList[j] = callbackList[j+1]; - } - callbackLen--; - } -} - -int -hasCallback(int callbackId) -{ - int i; - - for (i = 0; i < callbackLen; i++) - { - if (callbackList[i].callbackId == callbackId) - { - return 1; - } - } - return 0; - -} - -PyObject * -getCallback(int callbackId) -{ - int i; - - for (i = 0; i < callbackLen; i++) - { - if (callbackList[i].callbackId == callbackId) - { - return callbackList[i].func; - } - } - return NULL; -} - -char * -estrdup(char *s) -{ - register char *t; - - if (NULL == (t = malloc(strlen(s)+1))) { - PyErr_NoMemory(); - return NULL; - } - strcpy(t, s); - return(t); -} - -static PyObject * -telldus_tdInit(PyObject *self) -{ - tdInit(); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -telldus_tdClose(PyObject *self) -{ - tdClose(); - Py_INCREF(Py_None); - return Py_None; -} - -static PyObject * -telldus_tdTurnOn(PyObject *self, PyObject *args) -{ - long id; - - if (!PyArg_ParseTuple(args, "l", &id)) - return NULL; - - return PyLong_FromLong((long) tdTurnOn(id)); -} - -static PyObject * -telldus_tdTurnOff(PyObject *self, PyObject *args) -{ - long id; - - if (!PyArg_ParseTuple(args, "l", &id)) - return NULL; - - return PyLong_FromLong((long) tdTurnOff(id)); -} - -static PyObject * -telldus_tdBell(PyObject *self, PyObject *args) -{ - long id; - - if (!PyArg_ParseTuple(args, "l", &id)) - return NULL; - - return PyLong_FromLong((long) tdBell(id)); -} - -static PyObject * -telldus_tdDim(PyObject *self, PyObject *args) -{ - long id; - unsigned char level; - - if (!PyArg_ParseTuple(args, "lb", &id, &level)) - return NULL; - - if (level < 0 || level > 255) - return NULL; - - return PyLong_FromLong((long) tdDim(id, level)); -} - -static PyObject * -telldus_tdLearn(PyObject *self, PyObject *args) -{ - long id; - - if (!PyArg_ParseTuple(args, "l", &id)) - return NULL; - - return PyLong_FromLong((long) tdLearn(id)); -} - -static PyObject * -telldus_tdMethods(PyObject *self, PyObject *args) -{ - long id; - long supportedmethods; - - if (!PyArg_ParseTuple(args, "ll", &id, &supportedmethods)) - return NULL; - - return PyLong_FromLong((long) tdMethods(id, supportedmethods)); -} - - -static PyObject * -telldus_tdLastSentCommand(PyObject *self, PyObject *args) -{ - long id; - long supportedmethods; - - if (!PyArg_ParseTuple(args, "ll", &id, &supportedmethods)) - return NULL; - - return PyLong_FromLong((long) tdLastSentCommand(id, supportedmethods)); -} - -static PyObject * -telldus_tdLastSentValue(PyObject *self, PyObject *args) -{ - long id; - char* value; - char* retval; - - if (!PyArg_ParseTuple(args, "l", &id)) - return NULL; - - value = tdLastSentValue(id); - retval = estrdup(value); - tdReleaseString(value); - return PyString_FromString(retval); -} - -static PyObject * -telldus_tdGetNumberOfDevices(PyObject *self) -{ - return PyLong_FromLong((long) tdGetNumberOfDevices()); -} - -static PyObject * -telldus_tdGetDeviceId(PyObject *self, PyObject *args) -{ - long index; - - if (!PyArg_ParseTuple(args, "l", &index)) - return NULL; - - return PyLong_FromLong((long) tdGetDeviceId(index)); -} - -static PyObject * -telldus_tdGetDeviceType(PyObject *self, PyObject *args) -{ - long id; - - if (!PyArg_ParseTuple(args, "l", &id)) - return NULL; - - return PyLong_FromLong((long) tdGetDeviceType(id)); -} - -static PyObject * -telldus_tdGetErrorString(PyObject *self, PyObject *args) -{ - long errorno; - char* errorString; - char* retval; - - if (!PyArg_ParseTuple(args, "l", &errorno)) - return NULL; - - errorString = tdGetErrorString(errorno); - retval = estrdup(errorString); - tdReleaseString(errorString); - return PyString_FromString(retval); -} - -static PyObject * -telldus_tdGetName(PyObject *self, PyObject *args) -{ - long id; - char* name; - char* retval; - - if (!PyArg_ParseTuple(args, "l", &id)) - return NULL; - - name = tdGetName(id); - retval = estrdup(name); - tdReleaseString(name); - return PyString_FromString(retval); -} - -static PyObject * -telldus_tdSetName(PyObject *self, PyObject *args) -{ - long id; - char* name; - - if (!PyArg_ParseTuple(args, "ls", &id, &name)) - return NULL; - - return PyLong_FromLong((long) tdSetName(id, name)); -} - -static PyObject * -telldus_tdGetProtocol(PyObject *self, PyObject *args) -{ - long id; - char* protocol; - char* retval; - - if (!PyArg_ParseTuple(args, "l", &id)) - return NULL; - - protocol = tdGetProtocol(id); - retval = estrdup(protocol); - tdReleaseString(protocol); - return PyString_FromString(retval); -} - -static PyObject * -telldus_tdSetProtocol(PyObject *self, PyObject *args) -{ - long id; - char* protocol; - - if (!PyArg_ParseTuple(args, "ls", &id, &protocol)) - return NULL; - - return PyLong_FromLong((long) tdSetProtocol(id, protocol)); - -} - -static PyObject * -telldus_tdGetModel(PyObject *self, PyObject *args) -{ - long id; - char* model; - char* retval; - - if (!PyArg_ParseTuple(args, "l", &id)) - return NULL; - - model = tdGetModel(id); - retval = estrdup(model); - tdReleaseString(model); - return PyString_FromString(retval); -} - -static PyObject * -telldus_tdSetModel(PyObject *self, PyObject *args) -{ - long id; - char* model; - - if (!PyArg_ParseTuple(args, "ls", &id, &model)) - return NULL; - - return PyLong_FromLong((long) tdSetProtocol(id, model)); - -} - -static PyObject * -telldus_tdGetDeviceParameter(PyObject *self, PyObject *args) -{ - long id; - char* name; - char* defaultValue; - char* param; - char* retval; - - if (!PyArg_ParseTuple(args, "lss", &id, &name, &defaultValue)) - return NULL; - - param = tdGetDeviceParameter(id, name, defaultValue); - retval = estrdup(param); - tdReleaseString(param); - return PyString_FromString(retval); -} - -static PyObject * -telldus_tdSetDeviceParameter(PyObject *self, PyObject *args) -{ - long id; - char* name; - char* value; - - if (!PyArg_ParseTuple(args, "lss", &id, &name, &value)) - return NULL; - - return PyLong_FromLong((long) tdSetDeviceParameter(id, name, value)); -} - -static PyObject * -telldus_tdAddDevice(PyObject *self) -{ - return PyLong_FromLong((long) tdAddDevice()); -} - -static PyObject * -telldus_tdRemoveDevice(PyObject *self, PyObject *args) -{ - long id; - - if (!PyArg_ParseTuple(args, "l", &id)) - return NULL; - - return PyLong_FromLong((long) tdRemoveDevice(id)); -} - -static PyObject * -telldus_tdSendRawCommand(PyObject *self, PyObject *args) -{ - char *command; - long reserved = 0; - - if (!PyArg_ParseTuple(args, "s|l", &command, &reserved)); - return NULL; - - return PyLong_FromLong((long) tdSendRawCommand(command, reserved)); -} - -static PyObject *DeviceEventCallback = NULL; - -void -telldus_deviceEventCallback(int deviceId, int method, const char *data, int callbackId, int context) -{ - - PyObject * result; - PyGILState_STATE gstate = PyGILState_Ensure(); - - // now call the Python callback function - result = PyObject_CallFunction(DeviceEventCallback, "llsl", deviceId, method, data, callbackId); - - if (result == NULL) { - // something went wrong so print to stderr - PyErr_Print(); - } - - // take care of reference handling - Py_XDECREF(result); - - PyGILState_Release(gstate); - - return; -} - -static PyObject * -telldus_tdRegisterDeviceEvent(PyObject *self, PyObject *args) -{ - - int result; - PyObject *func; - - if (!PyArg_ParseTuple(args, "O:tdRegisterDeviceEvent", &func)) { - PyErr_SetString(PyExc_StandardError, "Parse error!"); - return NULL; - } - - if (!PyCallable_Check(func)) { - // Error - PyErr_SetString(PyExc_StandardError, "The object should be callable!"); - return NULL; - } - - Py_XDECREF(DeviceEventCallback); - // stick around till we need you - Py_XINCREF(func); - - DeviceEventCallback = func; - - result = tdRegisterDeviceEvent((TDDeviceEvent) &telldus_deviceEventCallback, 0); - - addCallback(func, result); - - return PyLong_FromLong((long) result); -} - -static PyObject *DeviceChangeEventCallback = NULL; - -void -telldus_deviceChangeEventCallback(int deviceId, int changeEvent, int changeType, int callbackId, int context) -{ - PyObject * result; - PyGILState_STATE gstate = PyGILState_Ensure(); - - // now call the Python callback function - result = PyObject_CallFunction(DeviceChangeEventCallback, "llll", deviceId, changeEvent, changeType, callbackId); - - if (result == NULL) { - // something went wrong so print to stderr - PyErr_Print(); - } - - // take care of reference handling - Py_XDECREF(result); - - PyGILState_Release(gstate); - - return; -} - -static PyObject * -telldus_tdRegisterDeviceChangeEvent(PyObject *self, PyObject *args) -{ - int result; - PyObject *func; - - if (!PyArg_ParseTuple(args, "O", &func)) { - PyErr_SetString(PyExc_StandardError, "Parse error!"); - return NULL; - } - - if (!PyCallable_Check(func)) { - // Error - PyErr_SetString(PyExc_StandardError, "The object should be callable!"); - return NULL; - } - - Py_XDECREF(DeviceChangeEventCallback); - // stick around till we need you - Py_XINCREF(func); - - DeviceChangeEventCallback = func; - - result = tdRegisterDeviceChangeEvent((TDDeviceChangeEvent) &telldus_deviceChangeEventCallback, 0); - - addCallback(func, result); - - return PyLong_FromLong((long) result); -} - -static PyObject *RawDeviceEventCallback = NULL; - -void -telldus_rawDeviceEventCallback(const char *data, int controllerId, int callbackId, int context) -{ - PyObject * result; - PyGILState_STATE gstate = PyGILState_Ensure(); - - // now call the Python callback function - result = PyObject_CallFunction(RawDeviceEventCallback, "sll", data, controllerId, callbackId); - - if (result == NULL) { - // something went wrong so print to stderr - PyErr_Print(); - } - - // take care of reference handling - Py_XDECREF(result); - - PyGILState_Release(gstate); - - return; -} - -static PyObject * -telldus_tdRegisterRawDeviceEvent(PyObject *self, PyObject *args) -{ - int result; - PyObject *func; - - if (!PyArg_ParseTuple(args, "O", &func)) { - PyErr_SetString(PyExc_StandardError, "Parse error!"); - return NULL; - } - - if (!PyCallable_Check(func)) { - // Error - PyErr_SetString(PyExc_StandardError, "The object should be callable!"); - return NULL; - } - - Py_XDECREF(RawDeviceEventCallback); - // stick around till we need you - Py_XINCREF(func); - - RawDeviceEventCallback = func; - - result = tdRegisterRawDeviceEvent((TDRawDeviceEvent) &telldus_rawDeviceEventCallback, 0); - - addCallback(func, result); - - return PyLong_FromLong((long) result); -} - -static PyObject *SensorEventCallback = NULL; - -void -telldus_sensorEventCallback(const char *protocol, const char *model, int id, int dataType, const char *value, int timestamp, int callbackId, int context) -{ - PyObject * result; - PyGILState_STATE gstate = PyGILState_Ensure(); - - // now call the Python callback function - result = PyObject_CallFunction(SensorEventCallback, "ssllsll", protocol, model, id, dataType, value, timestamp, callbackId); - - if (result == NULL) { - // something went wrong so print to stderr - PyErr_Print(); - } - - // take care of reference handling - Py_XDECREF(result); - - PyGILState_Release(gstate); - - return; -} - -static PyObject * -telldus_tdRegisterSensorEvent(PyObject *self, PyObject *args) -{ - int result; - PyObject *func; - - if (!PyArg_ParseTuple(args, "O", &func)) { - PyErr_SetString(PyExc_StandardError, "Parse error!"); - return NULL; - } - - if (!PyCallable_Check(func)) { - // Error - PyErr_SetString(PyExc_StandardError, "The object should be callable!"); - return NULL; - } - - Py_XDECREF(SensorEventCallback); - // stick around till we need you - Py_XINCREF(func); - - SensorEventCallback = func; - - result = tdRegisterSensorEvent((TDSensorEvent) &telldus_sensorEventCallback, 0); - - addCallback(func, result); - - return PyLong_FromLong((long) result); -} - -static PyObject * -telldus_tdUnregisterCallback(PyObject *self, PyObject *args) -{ - long id; - PyObject *callback; - - if (!PyArg_ParseTuple(args, "l", &id)) - return NULL; - - if (hasCallback(id) == 1) { - callback = getCallback(id); - Py_DECREF(callback); - removeCallback(id); - } - - return PyLong_FromLong((long) tdUnregisterCallback(id)); -} - -static PyObject * -telldus_tdSensor(PyObject *self, PyObject *args) -{ - char protocol[DATA_LENGTH]; - char model[DATA_LENGTH]; - long sensorId = 0; - long dataTypes = 0; - - long result; - - result = tdSensor(protocol, DATA_LENGTH, model, DATA_LENGTH, &sensorId, &dataTypes); - - if (result == TELLSTICK_SUCCESS) - { - return Py_BuildValue("ssll", protocol, model, sensorId, dataTypes); - } - else - { - return PyLong_FromLong(result); - } - -} - -static PyObject * -telldus_tdSensorValue(PyObject *self, PyObject *args) -{ - char protocol[DATA_LENGTH]; - char model[DATA_LENGTH]; - long sensorId = 0; - long dataType = 0; - char value[DATA_LENGTH]; - long timestamp = 0; - long result; - - PyObject *floatObj = NULL; - PyObject *timeTuple = NULL; - PyObject *dateTime = NULL; - - - if (!PyArg_ParseTuple(args, "ssll", &protocol, &model, &sensorId, &dataType)) - return NULL; - - result = tdSensorValue(protocol, model, sensorId, dataType, value, DATA_LENGTH, ×tamp); - - if (result == TELLSTICK_SUCCESS) - { - - floatObj = PyFloat_FromDouble((double) timestamp); - timeTuple = Py_BuildValue("(O)", floatObj); - dateTime = PyDateTime_FromTimestamp(timeTuple); - - Py_DECREF(floatObj); - Py_DECREF(timeTuple); - - return Py_BuildValue("sO", value, dateTime); - } - else - { - return PyLong_FromLong(result); - } -} - -static PyMethodDef telldus_methods[] = { - {"tdInit", (PyCFunction) telldus_tdInit, METH_NOARGS, "Initiate telldus."}, - {"tdClose", (PyCFunction) telldus_tdClose, METH_NOARGS, "Close telldus."}, - {"tdTurnOn", (PyCFunction) telldus_tdTurnOn, METH_VARARGS, "Turn on device."}, - {"tdTurnOff", (PyCFunction) telldus_tdTurnOff, METH_VARARGS, "Turn off device."}, - {"tdBell", (PyCFunction) telldus_tdBell, METH_VARARGS, "Bell device."}, - {"tdDim", (PyCFunction) telldus_tdDim, METH_VARARGS, "Dim device."}, - {"tdLearn", (PyCFunction) telldus_tdLearn, METH_VARARGS, "Learn device."}, - {"tdMethods", (PyCFunction) telldus_tdMethods, METH_VARARGS, "Methods comment."}, - {"tdLastSentCommand", (PyCFunction) telldus_tdLastSentCommand, METH_VARARGS, "LastSentCommand comment."}, - {"tdLastSentValue", (PyCFunction) telldus_tdLastSentValue, METH_VARARGS, "LastSentValue comment."}, - {"tdGetNumberOfDevices", (PyCFunction) telldus_tdGetNumberOfDevices, METH_VARARGS, "GetNumberOfDevices comment."}, - {"tdGetDeviceId", (PyCFunction) telldus_tdGetDeviceId, METH_VARARGS, "GetDeviceId comment."}, - {"tdGetDeviceType", (PyCFunction) telldus_tdGetDeviceType, METH_VARARGS, "GetDeviceType comment."}, - {"tdGetErrorString", (PyCFunction) telldus_tdGetErrorString, METH_VARARGS, "GetErrorString comment."}, - {"tdGetName", (PyCFunction) telldus_tdGetName, METH_VARARGS, "GetName comment."}, - {"tdSetName", (PyCFunction) telldus_tdSetName, METH_VARARGS, "SetName comment."}, - {"tdGetProtocol", (PyCFunction) telldus_tdGetProtocol, METH_VARARGS, "GetProtocol comment."}, - {"tdSetProtocol", (PyCFunction) telldus_tdSetProtocol, METH_VARARGS, "SetProtocol comment."}, - {"tdGetModel", (PyCFunction) telldus_tdGetModel, METH_VARARGS, "GetModel comment."}, - {"tdSetModel", (PyCFunction) telldus_tdSetModel, METH_VARARGS, "SetModel comment."}, - {"tdGetDeviceParameter", (PyCFunction) telldus_tdGetDeviceParameter, METH_VARARGS, "GetDeviceParameter comment."}, - {"tdSetDeviceParameter", (PyCFunction) telldus_tdSetDeviceParameter, METH_VARARGS, "SetDeviceParameter comment."}, - {"tdAddDevice", (PyCFunction) telldus_tdAddDevice, METH_NOARGS, "AddDevice comment."}, - {"tdRemoveDevice", (PyCFunction) telldus_tdRemoveDevice, METH_VARARGS, "RemoveDevice comment."}, - {"tdSendRawCommand", (PyCFunction) telldus_tdSendRawCommand, METH_VARARGS, "SendRawCommand comment."}, - - {"tdRegisterDeviceEvent", (PyCFunction) telldus_tdRegisterDeviceEvent, METH_VARARGS, "RegisterDeviceEvent comment."}, - {"tdRegisterDeviceChangeEvent", (PyCFunction) telldus_tdRegisterDeviceChangeEvent, METH_VARARGS, "RegisterDeviceChangeEvent comment."}, - {"tdRegisterRawDeviceEvent", (PyCFunction) telldus_tdRegisterRawDeviceEvent, METH_VARARGS, "RegisterRawDeviceEvent comment."}, - {"tdRegisterSensorEvent", (PyCFunction) telldus_tdRegisterSensorEvent, METH_VARARGS, "RegisterSensorEvent comment."}, - {"tdUnregisterCallback", (PyCFunction) telldus_tdUnregisterCallback, METH_VARARGS, "UnregisterCallback comment."}, - {"tdSensor", (PyCFunction) telldus_tdSensor, METH_NOARGS, "Sensor comment."}, - {"tdSensorValue", (PyCFunction) telldus_tdSensorValue, METH_VARARGS, "SensorValue comment."}, - - {NULL, NULL, 0, NULL} /* sentinel */ -}; - -void -inittelldus(void) -{ - PyObject *module; - - PyObject *TELLSTICK_TURNON_GLUE; - PyObject *TELLSTICK_TURNOFF_GLUE; - PyObject *TELLSTICK_BELL_GLUE; - PyObject *TELLSTICK_TOGGLE_GLUE; - PyObject *TELLSTICK_DIM_GLUE; - PyObject *TELLSTICK_LEARN_GLUE; - PyObject *TELLSTICK_SUCCESS_GLUE; - PyObject *TELLSTICK_ERROR_NOT_FOUND_GLUE; - PyObject *TELLSTICK_ERROR_PERMISSION_DENIED_GLUE; - PyObject *TELLSTICK_ERROR_DEVICE_NOT_FOUND_GLUE; - PyObject *TELLSTICK_ERROR_METHOD_NOT_SUPPORTED_GLUE; - PyObject *TELLSTICK_ERROR_COMMUNICATION_GLUE; - PyObject *TELLSTICK_ERROR_UNKNOWN_GLUE; - PyObject *TELLSTICK_TYPE_DEVICE_GLUE; - PyObject *TELLSTICK_TYPE_GROUP_GLUE; - PyObject *TELLSTICK_TEMPERATURE_GLUE; - PyObject *TELLSTICK_HUMIDITY_GLUE; - - /* Create the module and add the functions */ - - module = Py_InitModule("telldus", telldus_methods); - - TELLSTICK_TURNON_GLUE = PyLong_FromLong((long) TELLSTICK_TURNON); - PyObject_SetAttrString(module, "TELLSTICK_TURNON", TELLSTICK_TURNON_GLUE); - Py_DECREF(TELLSTICK_TURNON_GLUE); - - TELLSTICK_TURNOFF_GLUE = PyLong_FromLong((long) TELLSTICK_TURNOFF); - PyObject_SetAttrString(module, "TELLSTICK_TURNOFF", TELLSTICK_TURNOFF_GLUE); - Py_DECREF(TELLSTICK_TURNOFF_GLUE); - - TELLSTICK_BELL_GLUE = PyLong_FromLong((long) TELLSTICK_BELL); - PyObject_SetAttrString(module, "TELLSTICK_BELL", TELLSTICK_BELL_GLUE); - Py_DECREF(TELLSTICK_BELL_GLUE); - - TELLSTICK_TOGGLE_GLUE = PyLong_FromLong((long) TELLSTICK_TOGGLE); - PyObject_SetAttrString(module, "TELLSTICK_TOGGLE", TELLSTICK_TOGGLE_GLUE); - Py_DECREF(TELLSTICK_TOGGLE_GLUE); - - TELLSTICK_DIM_GLUE = PyLong_FromLong((long) TELLSTICK_DIM); - PyObject_SetAttrString(module, "TELLSTICK_DIM", TELLSTICK_DIM_GLUE); - Py_DECREF(TELLSTICK_DIM_GLUE); - - TELLSTICK_LEARN_GLUE = PyLong_FromLong((long) TELLSTICK_LEARN); - PyObject_SetAttrString(module, "TELLSTICK_LEARN", TELLSTICK_LEARN_GLUE); - Py_DECREF(TELLSTICK_LEARN_GLUE); - - TELLSTICK_SUCCESS_GLUE = PyLong_FromLong((long) TELLSTICK_SUCCESS); - PyObject_SetAttrString(module, "TELLSTICK_SUCCESS", TELLSTICK_SUCCESS_GLUE); - Py_DECREF(TELLSTICK_SUCCESS_GLUE); - - TELLSTICK_ERROR_NOT_FOUND_GLUE = PyLong_FromLong((long) TELLSTICK_ERROR_NOT_FOUND); - PyObject_SetAttrString(module, "TELLSTICK_ERROR_NOT_FOUND", TELLSTICK_ERROR_NOT_FOUND_GLUE); - Py_DECREF(TELLSTICK_ERROR_NOT_FOUND_GLUE); - - TELLSTICK_ERROR_PERMISSION_DENIED_GLUE = PyLong_FromLong((long) TELLSTICK_ERROR_PERMISSION_DENIED); - PyObject_SetAttrString(module, "TELLSTICK_ERROR_PERMISSION_DENIED", TELLSTICK_ERROR_PERMISSION_DENIED_GLUE); - Py_DECREF(TELLSTICK_ERROR_PERMISSION_DENIED_GLUE); - - TELLSTICK_ERROR_DEVICE_NOT_FOUND_GLUE = PyLong_FromLong((long) TELLSTICK_ERROR_DEVICE_NOT_FOUND); - PyObject_SetAttrString(module, "TELLSTICK_ERROR_DEVICE_NOT_FOUND", TELLSTICK_ERROR_DEVICE_NOT_FOUND_GLUE); - Py_DECREF(TELLSTICK_ERROR_DEVICE_NOT_FOUND_GLUE); - - TELLSTICK_ERROR_METHOD_NOT_SUPPORTED_GLUE = PyLong_FromLong((long) TELLSTICK_ERROR_METHOD_NOT_SUPPORTED); - PyObject_SetAttrString(module, "TELLSTICK_ERROR_METHOD_NOT_SUPPORTED", TELLSTICK_ERROR_METHOD_NOT_SUPPORTED_GLUE); - Py_DECREF(TELLSTICK_ERROR_METHOD_NOT_SUPPORTED_GLUE); - - TELLSTICK_ERROR_COMMUNICATION_GLUE = PyLong_FromLong((long) TELLSTICK_ERROR_COMMUNICATION); - PyObject_SetAttrString(module, "TELLSTICK_ERROR_COMMUNICATION", TELLSTICK_ERROR_COMMUNICATION_GLUE); - Py_DECREF(TELLSTICK_ERROR_COMMUNICATION_GLUE); - - TELLSTICK_ERROR_UNKNOWN_GLUE = PyLong_FromLong((long) TELLSTICK_ERROR_UNKNOWN); - PyObject_SetAttrString(module, "TELLSTICK_ERROR_UNKNOWN", TELLSTICK_ERROR_UNKNOWN_GLUE); - Py_DECREF(TELLSTICK_ERROR_UNKNOWN_GLUE); - - TELLSTICK_TYPE_DEVICE_GLUE = PyLong_FromLong((long) TELLSTICK_TYPE_DEVICE); - PyObject_SetAttrString(module, "TELLSTICK_TYPE_DEVICE", TELLSTICK_TYPE_DEVICE_GLUE); - Py_DECREF(TELLSTICK_TYPE_DEVICE_GLUE); - - TELLSTICK_TYPE_GROUP_GLUE = PyLong_FromLong((long) TELLSTICK_TYPE_GROUP); - PyObject_SetAttrString(module, "TELLSTICK_TYPE_GROUP", TELLSTICK_TYPE_GROUP_GLUE); - Py_DECREF(TELLSTICK_TYPE_GROUP_GLUE); - - TELLSTICK_TEMPERATURE_GLUE = PyLong_FromLong((long) TELLSTICK_TEMPERATURE); - PyObject_SetAttrString(module, "TELLSTICK_TEMPERATURE", TELLSTICK_TEMPERATURE_GLUE); - Py_DECREF(TELLSTICK_TEMPERATURE_GLUE); - - TELLSTICK_HUMIDITY_GLUE = PyLong_FromLong((long) TELLSTICK_HUMIDITY); - PyObject_SetAttrString(module, "TELLSTICK_HUMIDITY", TELLSTICK_HUMIDITY_GLUE); - Py_DECREF(TELLSTICK_HUMIDITY_GLUE); - -} +#include "Python.h" +#include "datetime.h" +#include +#include + +/* estrdup.c -- duplicate a string, die if error + * + * char *string; + * char *newstring; + * newstring = estrdup(string); + * + * estrdup returns a copy of its argument, located in memory + * allocated from the heap. If it is unable to allocate the + * necessary memory, estrdup executes PyErr_NoMemory(); + * (Generally, the routine error is not expected to return, + * but if it does, estrdup will return NULL.) +*/ + +int callbackLen = 0; + +typedef struct { + PyObject *func; + int callbackId; +} callbackInfo; + +static callbackInfo callbackList[CALLBACK_LENGTH]; + +void +addCallback(PyObject *func, int callbackId) +{ + if (callbackLen < CALLBACK_LENGTH) { + callbackList[callbackLen].func = func; + callbackList[callbackLen].callbackId = callbackId; + callbackLen++; + } +} + +void +removeCallback(int callbackId) +{ + int index = -1; + + int i; + int j; + + for (i = 0; i < callbackLen; i++) + { + if (callbackList[i].callbackId == callbackId) + { + index = i; + } + } + if (!(index == -1)) { + for (j = index; j < callbackLen - 1; j++) + { + callbackList[j] = callbackList[j+1]; + } + callbackLen--; + } +} + +int +hasCallback(int callbackId) +{ + int i; + + for (i = 0; i < callbackLen; i++) + { + if (callbackList[i].callbackId == callbackId) + { + return 1; + } + } + return 0; + +} + +PyObject * +getCallback(int callbackId) +{ + int i; + + for (i = 0; i < callbackLen; i++) + { + if (callbackList[i].callbackId == callbackId) + { + return callbackList[i].func; + } + } + return NULL; +} + +char * +estrdup(char *s) +{ + register char *t; + + if (NULL == (t = malloc(strlen(s)+1))) { + PyErr_NoMemory(); + return NULL; + } + strcpy(t, s); + return(t); +} + +static PyObject * +telldus_tdInit(PyObject *self) +{ + tdInit(); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +telldus_tdClose(PyObject *self) +{ + tdClose(); + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject * +telldus_tdTurnOn(PyObject *self, PyObject *args) +{ + long id; + + if (!PyArg_ParseTuple(args, "l", &id)) + return NULL; + + return PyLong_FromLong((long) tdTurnOn(id)); +} + +static PyObject * +telldus_tdTurnOff(PyObject *self, PyObject *args) +{ + long id; + + if (!PyArg_ParseTuple(args, "l", &id)) + return NULL; + + return PyLong_FromLong((long) tdTurnOff(id)); +} + +static PyObject * +telldus_tdBell(PyObject *self, PyObject *args) +{ + long id; + + if (!PyArg_ParseTuple(args, "l", &id)) + return NULL; + + return PyLong_FromLong((long) tdBell(id)); +} + +static PyObject * +telldus_tdDim(PyObject *self, PyObject *args) +{ + long id; + unsigned char level; + + if (!PyArg_ParseTuple(args, "lb", &id, &level)) + return NULL; + + if (level < 0 || level > 255) + return NULL; + + return PyLong_FromLong((long) tdDim(id, level)); +} + +static PyObject * +telldus_tdLearn(PyObject *self, PyObject *args) +{ + long id; + + if (!PyArg_ParseTuple(args, "l", &id)) + return NULL; + + return PyLong_FromLong((long) tdLearn(id)); +} + +static PyObject * +telldus_tdMethods(PyObject *self, PyObject *args) +{ + long id; + long supportedmethods; + + if (!PyArg_ParseTuple(args, "ll", &id, &supportedmethods)) + return NULL; + + return PyLong_FromLong((long) tdMethods(id, supportedmethods)); +} + + +static PyObject * +telldus_tdLastSentCommand(PyObject *self, PyObject *args) +{ + long id; + long supportedmethods; + + if (!PyArg_ParseTuple(args, "ll", &id, &supportedmethods)) + return NULL; + + return PyLong_FromLong((long) tdLastSentCommand(id, supportedmethods)); +} + +static PyObject * +telldus_tdLastSentValue(PyObject *self, PyObject *args) +{ + long id; + char* value; + char* retval; + + if (!PyArg_ParseTuple(args, "l", &id)) + return NULL; + + value = tdLastSentValue(id); + retval = estrdup(value); + tdReleaseString(value); + return PyString_FromString(retval); +} + +static PyObject * +telldus_tdGetNumberOfDevices(PyObject *self) +{ + return PyLong_FromLong((long) tdGetNumberOfDevices()); +} + +static PyObject * +telldus_tdGetDeviceId(PyObject *self, PyObject *args) +{ + long index; + + if (!PyArg_ParseTuple(args, "l", &index)) + return NULL; + + return PyLong_FromLong((long) tdGetDeviceId(index)); +} + +static PyObject * +telldus_tdGetDeviceType(PyObject *self, PyObject *args) +{ + long id; + + if (!PyArg_ParseTuple(args, "l", &id)) + return NULL; + + return PyLong_FromLong((long) tdGetDeviceType(id)); +} + +static PyObject * +telldus_tdGetErrorString(PyObject *self, PyObject *args) +{ + long errorno; + char* errorString; + char* retval; + + if (!PyArg_ParseTuple(args, "l", &errorno)) + return NULL; + + errorString = tdGetErrorString(errorno); + retval = estrdup(errorString); + tdReleaseString(errorString); + return PyString_FromString(retval); +} + +static PyObject * +telldus_tdGetName(PyObject *self, PyObject *args) +{ + long id; + char* name; + char* retval; + + if (!PyArg_ParseTuple(args, "l", &id)) + return NULL; + + name = tdGetName(id); + retval = estrdup(name); + tdReleaseString(name); + return PyString_FromString(retval); +} + +static PyObject * +telldus_tdSetName(PyObject *self, PyObject *args) +{ + long id; + char* name; + + if (!PyArg_ParseTuple(args, "ls", &id, &name)) + return NULL; + + return PyLong_FromLong((long) tdSetName(id, name)); +} + +static PyObject * +telldus_tdGetProtocol(PyObject *self, PyObject *args) +{ + long id; + char* protocol; + char* retval; + + if (!PyArg_ParseTuple(args, "l", &id)) + return NULL; + + protocol = tdGetProtocol(id); + retval = estrdup(protocol); + tdReleaseString(protocol); + return PyString_FromString(retval); +} + +static PyObject * +telldus_tdSetProtocol(PyObject *self, PyObject *args) +{ + long id; + char* protocol; + + if (!PyArg_ParseTuple(args, "ls", &id, &protocol)) + return NULL; + + return PyLong_FromLong((long) tdSetProtocol(id, protocol)); + +} + +static PyObject * +telldus_tdGetModel(PyObject *self, PyObject *args) +{ + long id; + char* model; + char* retval; + + if (!PyArg_ParseTuple(args, "l", &id)) + return NULL; + + model = tdGetModel(id); + retval = estrdup(model); + tdReleaseString(model); + return PyString_FromString(retval); +} + +static PyObject * +telldus_tdSetModel(PyObject *self, PyObject *args) +{ + long id; + char* model; + + if (!PyArg_ParseTuple(args, "ls", &id, &model)) + return NULL; + + return PyLong_FromLong((long) tdSetProtocol(id, model)); + +} + +static PyObject * +telldus_tdGetDeviceParameter(PyObject *self, PyObject *args) +{ + long id; + char* name; + char* defaultValue; + char* param; + char* retval; + + if (!PyArg_ParseTuple(args, "lss", &id, &name, &defaultValue)) + return NULL; + + param = tdGetDeviceParameter(id, name, defaultValue); + retval = estrdup(param); + tdReleaseString(param); + return PyString_FromString(retval); +} + +static PyObject * +telldus_tdSetDeviceParameter(PyObject *self, PyObject *args) +{ + long id; + char* name; + char* value; + + if (!PyArg_ParseTuple(args, "lss", &id, &name, &value)) + return NULL; + + return PyLong_FromLong((long) tdSetDeviceParameter(id, name, value)); +} + +static PyObject * +telldus_tdAddDevice(PyObject *self) +{ + return PyLong_FromLong((long) tdAddDevice()); +} + +static PyObject * +telldus_tdRemoveDevice(PyObject *self, PyObject *args) +{ + long id; + + if (!PyArg_ParseTuple(args, "l", &id)) + return NULL; + + return PyLong_FromLong((long) tdRemoveDevice(id)); +} + +static PyObject * +telldus_tdSendRawCommand(PyObject *self, PyObject *args) +{ + char *command; + long reserved = 0; + + if (!PyArg_ParseTuple(args, "s|l", &command, &reserved)); + return NULL; + + return PyLong_FromLong((long) tdSendRawCommand(command, reserved)); +} + +static PyObject *DeviceEventCallback = NULL; + +void +telldus_deviceEventCallback(int deviceId, int method, const char *data, int callbackId, int context) +{ + + PyObject * result; + PyGILState_STATE gstate = PyGILState_Ensure(); + + // now call the Python callback function + result = PyObject_CallFunction(DeviceEventCallback, "llsl", deviceId, method, data, callbackId); + + if (result == NULL) { + // something went wrong so print to stderr + PyErr_Print(); + } + + // take care of reference handling + Py_XDECREF(result); + + PyGILState_Release(gstate); + + return; +} + +static PyObject * +telldus_tdRegisterDeviceEvent(PyObject *self, PyObject *args) +{ + + int result; + PyObject *func; + + if (!PyArg_ParseTuple(args, "O:tdRegisterDeviceEvent", &func)) { + PyErr_SetString(PyExc_StandardError, "Parse error!"); + return NULL; + } + + if (!PyCallable_Check(func)) { + // Error + PyErr_SetString(PyExc_StandardError, "The object should be callable!"); + return NULL; + } + + Py_XDECREF(DeviceEventCallback); + // stick around till we need you + Py_XINCREF(func); + + DeviceEventCallback = func; + + result = tdRegisterDeviceEvent((TDDeviceEvent) &telldus_deviceEventCallback, 0); + + addCallback(func, result); + + return PyLong_FromLong((long) result); +} + +static PyObject *DeviceChangeEventCallback = NULL; + +void +telldus_deviceChangeEventCallback(int deviceId, int changeEvent, int changeType, int callbackId, int context) +{ + PyObject * result; + PyGILState_STATE gstate = PyGILState_Ensure(); + + // now call the Python callback function + result = PyObject_CallFunction(DeviceChangeEventCallback, "llll", deviceId, changeEvent, changeType, callbackId); + + if (result == NULL) { + // something went wrong so print to stderr + PyErr_Print(); + } + + // take care of reference handling + Py_XDECREF(result); + + PyGILState_Release(gstate); + + return; +} + +static PyObject * +telldus_tdRegisterDeviceChangeEvent(PyObject *self, PyObject *args) +{ + int result; + PyObject *func; + + if (!PyArg_ParseTuple(args, "O", &func)) { + PyErr_SetString(PyExc_StandardError, "Parse error!"); + return NULL; + } + + if (!PyCallable_Check(func)) { + // Error + PyErr_SetString(PyExc_StandardError, "The object should be callable!"); + return NULL; + } + + Py_XDECREF(DeviceChangeEventCallback); + // stick around till we need you + Py_XINCREF(func); + + DeviceChangeEventCallback = func; + + result = tdRegisterDeviceChangeEvent((TDDeviceChangeEvent) &telldus_deviceChangeEventCallback, 0); + + addCallback(func, result); + + return PyLong_FromLong((long) result); +} + +static PyObject *RawDeviceEventCallback = NULL; + +void +telldus_rawDeviceEventCallback(const char *data, int controllerId, int callbackId, int context) +{ + PyObject * result; + PyGILState_STATE gstate = PyGILState_Ensure(); + + // now call the Python callback function + result = PyObject_CallFunction(RawDeviceEventCallback, "sll", data, controllerId, callbackId); + + if (result == NULL) { + // something went wrong so print to stderr + PyErr_Print(); + } + + // take care of reference handling + Py_XDECREF(result); + + PyGILState_Release(gstate); + + return; +} + +static PyObject * +telldus_tdRegisterRawDeviceEvent(PyObject *self, PyObject *args) +{ + int result; + PyObject *func; + + if (!PyArg_ParseTuple(args, "O", &func)) { + PyErr_SetString(PyExc_StandardError, "Parse error!"); + return NULL; + } + + if (!PyCallable_Check(func)) { + // Error + PyErr_SetString(PyExc_StandardError, "The object should be callable!"); + return NULL; + } + + Py_XDECREF(RawDeviceEventCallback); + // stick around till we need you + Py_XINCREF(func); + + RawDeviceEventCallback = func; + + result = tdRegisterRawDeviceEvent((TDRawDeviceEvent) &telldus_rawDeviceEventCallback, 0); + + addCallback(func, result); + + return PyLong_FromLong((long) result); +} + +static PyObject *SensorEventCallback = NULL; + +void +telldus_sensorEventCallback(const char *protocol, const char *model, int id, int dataType, const char *value, int timestamp, int callbackId, int context) +{ + PyObject * result; + PyGILState_STATE gstate = PyGILState_Ensure(); + + // now call the Python callback function + result = PyObject_CallFunction(SensorEventCallback, "ssllsll", protocol, model, id, dataType, value, timestamp, callbackId); + + if (result == NULL) { + // something went wrong so print to stderr + PyErr_Print(); + } + + // take care of reference handling + Py_XDECREF(result); + + PyGILState_Release(gstate); + + return; +} + +static PyObject * +telldus_tdRegisterSensorEvent(PyObject *self, PyObject *args) +{ + int result; + PyObject *func; + + if (!PyArg_ParseTuple(args, "O", &func)) { + PyErr_SetString(PyExc_StandardError, "Parse error!"); + return NULL; + } + + if (!PyCallable_Check(func)) { + // Error + PyErr_SetString(PyExc_StandardError, "The object should be callable!"); + return NULL; + } + + Py_XDECREF(SensorEventCallback); + // stick around till we need you + Py_XINCREF(func); + + SensorEventCallback = func; + + result = tdRegisterSensorEvent((TDSensorEvent) &telldus_sensorEventCallback, 0); + + addCallback(func, result); + + return PyLong_FromLong((long) result); +} + +static PyObject * +telldus_tdUnregisterCallback(PyObject *self, PyObject *args) +{ + long id; + PyObject *callback; + + if (!PyArg_ParseTuple(args, "l", &id)) + return NULL; + + if (hasCallback(id) == 1) { + callback = getCallback(id); + Py_DECREF(callback); + removeCallback(id); + } + + return PyLong_FromLong((long) tdUnregisterCallback(id)); +} + +static PyObject * +telldus_tdSensor(PyObject *self, PyObject *args) +{ + char protocol[DATA_LENGTH]; + char model[DATA_LENGTH]; + long sensorId = 0; + long dataTypes = 0; + + long result; + + result = tdSensor(protocol, DATA_LENGTH, model, DATA_LENGTH, &sensorId, &dataTypes); + + if (result == TELLSTICK_SUCCESS) + { + return Py_BuildValue("ssll", protocol, model, sensorId, dataTypes); + } + else + { + return PyLong_FromLong(result); + } + +} + +static PyObject * +telldus_tdSensorValue(PyObject *self, PyObject *args) +{ + char protocol[DATA_LENGTH]; + char model[DATA_LENGTH]; + long sensorId = 0; + long dataType = 0; + char value[DATA_LENGTH]; + long timestamp = 0; + long result; + + PyObject *floatObj = NULL; + PyObject *timeTuple = NULL; + PyObject *dateTime = NULL; + + + if (!PyArg_ParseTuple(args, "ssll", &protocol, &model, &sensorId, &dataType)) + return NULL; + + result = tdSensorValue(protocol, model, sensorId, dataType, value, DATA_LENGTH, ×tamp); + + if (result == TELLSTICK_SUCCESS) + { + + floatObj = PyFloat_FromDouble((double) timestamp); + timeTuple = Py_BuildValue("(O)", floatObj); + dateTime = PyDateTime_FromTimestamp(timeTuple); + + Py_DECREF(floatObj); + Py_DECREF(timeTuple); + + return Py_BuildValue("sO", value, dateTime); + } + else + { + return PyLong_FromLong(result); + } +} + +static PyMethodDef telldus_methods[] = { + {"tdInit", (PyCFunction) telldus_tdInit, METH_NOARGS, "Initiate telldus."}, + {"tdClose", (PyCFunction) telldus_tdClose, METH_NOARGS, "Close telldus."}, + {"tdTurnOn", (PyCFunction) telldus_tdTurnOn, METH_VARARGS, "Turn on device."}, + {"tdTurnOff", (PyCFunction) telldus_tdTurnOff, METH_VARARGS, "Turn off device."}, + {"tdBell", (PyCFunction) telldus_tdBell, METH_VARARGS, "Bell device."}, + {"tdDim", (PyCFunction) telldus_tdDim, METH_VARARGS, "Dim device."}, + {"tdLearn", (PyCFunction) telldus_tdLearn, METH_VARARGS, "Learn device."}, + {"tdMethods", (PyCFunction) telldus_tdMethods, METH_VARARGS, "Methods comment."}, + {"tdLastSentCommand", (PyCFunction) telldus_tdLastSentCommand, METH_VARARGS, "LastSentCommand comment."}, + {"tdLastSentValue", (PyCFunction) telldus_tdLastSentValue, METH_VARARGS, "LastSentValue comment."}, + {"tdGetNumberOfDevices", (PyCFunction) telldus_tdGetNumberOfDevices, METH_VARARGS, "GetNumberOfDevices comment."}, + {"tdGetDeviceId", (PyCFunction) telldus_tdGetDeviceId, METH_VARARGS, "GetDeviceId comment."}, + {"tdGetDeviceType", (PyCFunction) telldus_tdGetDeviceType, METH_VARARGS, "GetDeviceType comment."}, + {"tdGetErrorString", (PyCFunction) telldus_tdGetErrorString, METH_VARARGS, "GetErrorString comment."}, + {"tdGetName", (PyCFunction) telldus_tdGetName, METH_VARARGS, "GetName comment."}, + {"tdSetName", (PyCFunction) telldus_tdSetName, METH_VARARGS, "SetName comment."}, + {"tdGetProtocol", (PyCFunction) telldus_tdGetProtocol, METH_VARARGS, "GetProtocol comment."}, + {"tdSetProtocol", (PyCFunction) telldus_tdSetProtocol, METH_VARARGS, "SetProtocol comment."}, + {"tdGetModel", (PyCFunction) telldus_tdGetModel, METH_VARARGS, "GetModel comment."}, + {"tdSetModel", (PyCFunction) telldus_tdSetModel, METH_VARARGS, "SetModel comment."}, + {"tdGetDeviceParameter", (PyCFunction) telldus_tdGetDeviceParameter, METH_VARARGS, "GetDeviceParameter comment."}, + {"tdSetDeviceParameter", (PyCFunction) telldus_tdSetDeviceParameter, METH_VARARGS, "SetDeviceParameter comment."}, + {"tdAddDevice", (PyCFunction) telldus_tdAddDevice, METH_NOARGS, "AddDevice comment."}, + {"tdRemoveDevice", (PyCFunction) telldus_tdRemoveDevice, METH_VARARGS, "RemoveDevice comment."}, + {"tdSendRawCommand", (PyCFunction) telldus_tdSendRawCommand, METH_VARARGS, "SendRawCommand comment."}, + + {"tdRegisterDeviceEvent", (PyCFunction) telldus_tdRegisterDeviceEvent, METH_VARARGS, "RegisterDeviceEvent comment."}, + {"tdRegisterDeviceChangeEvent", (PyCFunction) telldus_tdRegisterDeviceChangeEvent, METH_VARARGS, "RegisterDeviceChangeEvent comment."}, + {"tdRegisterRawDeviceEvent", (PyCFunction) telldus_tdRegisterRawDeviceEvent, METH_VARARGS, "RegisterRawDeviceEvent comment."}, + {"tdRegisterSensorEvent", (PyCFunction) telldus_tdRegisterSensorEvent, METH_VARARGS, "RegisterSensorEvent comment."}, + {"tdUnregisterCallback", (PyCFunction) telldus_tdUnregisterCallback, METH_VARARGS, "UnregisterCallback comment."}, + {"tdSensor", (PyCFunction) telldus_tdSensor, METH_NOARGS, "Sensor comment."}, + {"tdSensorValue", (PyCFunction) telldus_tdSensorValue, METH_VARARGS, "SensorValue comment."}, + + {NULL, NULL, 0, NULL} /* sentinel */ +}; + +void +inittelldus(void) +{ + PyObject *module; + + PyObject *TELLSTICK_TURNON_GLUE; + PyObject *TELLSTICK_TURNOFF_GLUE; + PyObject *TELLSTICK_BELL_GLUE; + PyObject *TELLSTICK_TOGGLE_GLUE; + PyObject *TELLSTICK_DIM_GLUE; + PyObject *TELLSTICK_LEARN_GLUE; + PyObject *TELLSTICK_SUCCESS_GLUE; + PyObject *TELLSTICK_ERROR_NOT_FOUND_GLUE; + PyObject *TELLSTICK_ERROR_PERMISSION_DENIED_GLUE; + PyObject *TELLSTICK_ERROR_DEVICE_NOT_FOUND_GLUE; + PyObject *TELLSTICK_ERROR_METHOD_NOT_SUPPORTED_GLUE; + PyObject *TELLSTICK_ERROR_COMMUNICATION_GLUE; + PyObject *TELLSTICK_ERROR_UNKNOWN_GLUE; + PyObject *TELLSTICK_TYPE_DEVICE_GLUE; + PyObject *TELLSTICK_TYPE_GROUP_GLUE; + PyObject *TELLSTICK_TEMPERATURE_GLUE; + PyObject *TELLSTICK_HUMIDITY_GLUE; + + /* Create the module and add the functions */ + + module = Py_InitModule("telldus", telldus_methods); + + TELLSTICK_TURNON_GLUE = PyLong_FromLong((long) TELLSTICK_TURNON); + PyObject_SetAttrString(module, "TELLSTICK_TURNON", TELLSTICK_TURNON_GLUE); + Py_DECREF(TELLSTICK_TURNON_GLUE); + + TELLSTICK_TURNOFF_GLUE = PyLong_FromLong((long) TELLSTICK_TURNOFF); + PyObject_SetAttrString(module, "TELLSTICK_TURNOFF", TELLSTICK_TURNOFF_GLUE); + Py_DECREF(TELLSTICK_TURNOFF_GLUE); + + TELLSTICK_BELL_GLUE = PyLong_FromLong((long) TELLSTICK_BELL); + PyObject_SetAttrString(module, "TELLSTICK_BELL", TELLSTICK_BELL_GLUE); + Py_DECREF(TELLSTICK_BELL_GLUE); + + TELLSTICK_TOGGLE_GLUE = PyLong_FromLong((long) TELLSTICK_TOGGLE); + PyObject_SetAttrString(module, "TELLSTICK_TOGGLE", TELLSTICK_TOGGLE_GLUE); + Py_DECREF(TELLSTICK_TOGGLE_GLUE); + + TELLSTICK_DIM_GLUE = PyLong_FromLong((long) TELLSTICK_DIM); + PyObject_SetAttrString(module, "TELLSTICK_DIM", TELLSTICK_DIM_GLUE); + Py_DECREF(TELLSTICK_DIM_GLUE); + + TELLSTICK_LEARN_GLUE = PyLong_FromLong((long) TELLSTICK_LEARN); + PyObject_SetAttrString(module, "TELLSTICK_LEARN", TELLSTICK_LEARN_GLUE); + Py_DECREF(TELLSTICK_LEARN_GLUE); + + TELLSTICK_SUCCESS_GLUE = PyLong_FromLong((long) TELLSTICK_SUCCESS); + PyObject_SetAttrString(module, "TELLSTICK_SUCCESS", TELLSTICK_SUCCESS_GLUE); + Py_DECREF(TELLSTICK_SUCCESS_GLUE); + + TELLSTICK_ERROR_NOT_FOUND_GLUE = PyLong_FromLong((long) TELLSTICK_ERROR_NOT_FOUND); + PyObject_SetAttrString(module, "TELLSTICK_ERROR_NOT_FOUND", TELLSTICK_ERROR_NOT_FOUND_GLUE); + Py_DECREF(TELLSTICK_ERROR_NOT_FOUND_GLUE); + + TELLSTICK_ERROR_PERMISSION_DENIED_GLUE = PyLong_FromLong((long) TELLSTICK_ERROR_PERMISSION_DENIED); + PyObject_SetAttrString(module, "TELLSTICK_ERROR_PERMISSION_DENIED", TELLSTICK_ERROR_PERMISSION_DENIED_GLUE); + Py_DECREF(TELLSTICK_ERROR_PERMISSION_DENIED_GLUE); + + TELLSTICK_ERROR_DEVICE_NOT_FOUND_GLUE = PyLong_FromLong((long) TELLSTICK_ERROR_DEVICE_NOT_FOUND); + PyObject_SetAttrString(module, "TELLSTICK_ERROR_DEVICE_NOT_FOUND", TELLSTICK_ERROR_DEVICE_NOT_FOUND_GLUE); + Py_DECREF(TELLSTICK_ERROR_DEVICE_NOT_FOUND_GLUE); + + TELLSTICK_ERROR_METHOD_NOT_SUPPORTED_GLUE = PyLong_FromLong((long) TELLSTICK_ERROR_METHOD_NOT_SUPPORTED); + PyObject_SetAttrString(module, "TELLSTICK_ERROR_METHOD_NOT_SUPPORTED", TELLSTICK_ERROR_METHOD_NOT_SUPPORTED_GLUE); + Py_DECREF(TELLSTICK_ERROR_METHOD_NOT_SUPPORTED_GLUE); + + TELLSTICK_ERROR_COMMUNICATION_GLUE = PyLong_FromLong((long) TELLSTICK_ERROR_COMMUNICATION); + PyObject_SetAttrString(module, "TELLSTICK_ERROR_COMMUNICATION", TELLSTICK_ERROR_COMMUNICATION_GLUE); + Py_DECREF(TELLSTICK_ERROR_COMMUNICATION_GLUE); + + TELLSTICK_ERROR_UNKNOWN_GLUE = PyLong_FromLong((long) TELLSTICK_ERROR_UNKNOWN); + PyObject_SetAttrString(module, "TELLSTICK_ERROR_UNKNOWN", TELLSTICK_ERROR_UNKNOWN_GLUE); + Py_DECREF(TELLSTICK_ERROR_UNKNOWN_GLUE); + + TELLSTICK_TYPE_DEVICE_GLUE = PyLong_FromLong((long) TELLSTICK_TYPE_DEVICE); + PyObject_SetAttrString(module, "TELLSTICK_TYPE_DEVICE", TELLSTICK_TYPE_DEVICE_GLUE); + Py_DECREF(TELLSTICK_TYPE_DEVICE_GLUE); + + TELLSTICK_TYPE_GROUP_GLUE = PyLong_FromLong((long) TELLSTICK_TYPE_GROUP); + PyObject_SetAttrString(module, "TELLSTICK_TYPE_GROUP", TELLSTICK_TYPE_GROUP_GLUE); + Py_DECREF(TELLSTICK_TYPE_GROUP_GLUE); + + TELLSTICK_TEMPERATURE_GLUE = PyLong_FromLong((long) TELLSTICK_TEMPERATURE); + PyObject_SetAttrString(module, "TELLSTICK_TEMPERATURE", TELLSTICK_TEMPERATURE_GLUE); + Py_DECREF(TELLSTICK_TEMPERATURE_GLUE); + + TELLSTICK_HUMIDITY_GLUE = PyLong_FromLong((long) TELLSTICK_HUMIDITY); + PyObject_SetAttrString(module, "TELLSTICK_HUMIDITY", TELLSTICK_HUMIDITY_GLUE); + Py_DECREF(TELLSTICK_HUMIDITY_GLUE); + +}