Xively:如何使用python api激活设备?

Xively:如何使用python api激活设备?,python,cosm,xively,Python,Cosm,Xively,由于COSM已经成为Xively,一个很好的设备api已经被添加或一直存在——不确定。流程是 使用序列号创建产品批次 使用某些产品批次标识符激活设备 开始使用具有获得的提要/api密钥的设备 我不知道如何通过python API实现这一点-有任何指针吗?应该将其添加到库中,但现在您可以使用此代码实现设备激活。我已经使用环境变量来存储产品机密和设备序列号,但是对于适合您的用例的任何东西都要更改它。唯一棘手的是你需要打电话 您还需要注意将凭据存储到文件中,因为设备只能激活一次。如果您尝试一次又一次地

由于COSM已经成为Xively,一个很好的设备api已经被添加或一直存在——不确定。流程是

使用序列号创建产品批次 使用某些产品批次标识符激活设备 开始使用具有获得的提要/api密钥的设备
我不知道如何通过python API实现这一点-有任何指针吗?

应该将其添加到库中,但现在您可以使用此代码实现设备激活。我已经使用环境变量来存储产品机密和设备序列号,但是对于适合您的用例的任何东西都要更改它。唯一棘手的是你需要打电话

您还需要注意将凭据存储到文件中,因为设备只能激活一次。如果您尝试一次又一次地运行此代码,您将注意到403个错误,因此请使用Xively developer workbench来停用测试中的设备,您可能需要刷新页面

下面是一个使用配置文件或环境变量的完整工作示例:

#!/usr/bin/python

from os import environ 
from hashlib import sha1 
from binascii import a2b_hex 
import hmac
import sys, subprocess
import ConfigParser
import xively

CONFIG_FILE = 'xively.conf'

PROVISIONING = 'PROVISIONING'

PROVISIONING_PRODUCT_SECRET = 'PRODUCT_SECRET'
PROVISIONING_DEVICE_SERIAL = 'DEVICE_SERIAL'

PROVISIONING_FEED_ID = 'FEED_ID'
PROVISIONING_API_KEY = 'API_KEY'

def get_setting(config, section, key):
    try:
    value = config.get(section, key)
    except:
    print key + " not found in config file. Using environment variable " + key + " instead."

    try:
        value = environ[key]
    except:
        print key + " not found in environment."
        raise
    # value defined?
    if not value:
    raise
    return value

def xively_activate_product(secret, serial):
    activation = hmac.new(a2b_hex(secret), serial, sha1).hexdigest()
    creds = xively.Client(key=None).get('/v2/devices/'+activation+'/activate').json()
    return creds 

# main
config = ConfigParser.RawConfigParser()
config.read(CONFIG_FILE)

try:
    # see if we already have an api key and feed id
    feed_id = config.get(PROVISIONING, PROVISIONING_FEED_ID)
    api_key = config.get(PROVISIONING, PROVISIONING_API_KEY)

    print "Provisioned product details:"
    print "FEED_ID: " + str(feed_id)
    print "API_KEY: " + api_key

    # continue working with your activated product here

except:
    print "FEED_ID and API_KEY not found. Activating product now."

    # no error handling for secret- it _is_ needed
    try:
    secret = get_setting(config, PROVISIONING, PROVISIONING_PRODUCT_SECRET)
    except:        
    print "Finding " + PROVISIONING_PRODUCT_SECRET + " failed. Giving up."
    sys.exit(1)

    try:
    serial = get_setting(config, PROVISIONING, PROVISIONING_DEVICE_SERIAL)
    except:        
    serial = subprocess.check_output("hostname", shell=True)
    if not serial:
        print "Fallback to hostname for " + PROVISIONING_DEVICE_SERIAL + " failed. Giving up."
        sys.exit(1)

    try:    
    creds = xively_activate_product(secret, serial)

    # check if there were errors
    try:
        creds["errors"]
    except:
        pass
    else:
        print "Product activation failed (" + creds["title"] +": "+ creds["errors"] + ")."
        sys.exit(1)

    feed_id = creds['feed_id']
    api_key = creds['apikey']

    print "Product activation successful."
    print "FEED_ID: " + str(feed_id)
    print "API_KEY: " + api_key

    if not config.has_section(PROVISIONING):
        config.add_section(PROVISIONING)

    config.set(PROVISIONING, PROVISIONING_FEED_ID, feed_id)
    config.set(PROVISIONING, PROVISIONING_API_KEY, api_key)

    # Writing our configuration file to 'example.cfg'
    with open(CONFIG_FILE, 'wb') as configfile:
        config.write(configfile)

    except Exception as e:
    print "Product activation failed (" + str(e) +")."
    sys.exit(1)

这是我写的另一个有用的课程:

## Logging for debugging purposes
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


import os
from os import environ 
from hashlib import sha1 
from binascii import a2b_hex 
import hmac
import sys, subprocess
import ConfigParser
import xively


PROVISIONING = 'PROVISIONING'

PROVISIONING_PRODUCT_SECRET = 'PRODUCT_SECRET'

PROVISIONING_FEED_ID = 'FEED_ID'
PROVISIONING_API_KEY = 'API_KEY'


class XivelyManager:

    def __init__(self, settings="xively.conf"):
        # main
        self.settings=settings
        self.config = ConfigParser.RawConfigParser()
        self.config.read(settings)

        try:
            # see if we already have an api key and feed id

            self.api_key = self.get_setting(PROVISIONING, PROVISIONING_API_KEY)
            self.secret = self.get_setting(PROVISIONING, PROVISIONING_PRODUCT_SECRET)
            # continue working with your activated product here

        except:
            logger.exception( "API KEY and SECRET NOT FOUND" )

    def activate_sensor(self,serial):

            try:    
                creds = self.xively_activate_product(str(serial))

                # check if there were errors
                try:
                    creds["errors"]
                except:
                    pass
                else:
                    logger.exception("Product activation failed (" + creds["title"] +": "+ creds["errors"] + ").")
                    return False

                feed_id = creds['feed_id']
                api_key = creds['apikey']

                if not self.config.has_section(PROVISIONING):
                    self.config.add_section(PROVISIONING)

                if not self.config.has_section(str(serial)):
                    self.config.add_section(str(serial))

                self.config.set(PROVISIONING, PROVISIONING_API_KEY, api_key)
                self.config.set(str(serial), PROVISIONING_FEED_ID , feed_id)

                # Writing our configuration file to 'xively.cfg'
                with open(self.settings, 'wb') as configfile:
                    self.config.write(configfile)
                return True

            except Exception as e:
                logger.exception("Product activation failed (" + str(e) +").")
                return False

    def get_setting(self, section, key):
        try:

            value = self.config.get(section, key)
        except:
            logger.exception( key + " not found in config file. Using environment variable " + key + " instead.")
##            try:
##                value = environ[key]
##            except:
##                logger.exception( key + " not found in environment.")
##            finally:
##                pass
        finally:

            # value defined?
            if not value:
                raise
            return value

    def get_feed(self,serial):
        try:
            if self.config.has_section(str(serial)):
                feed_id = self.get_setting(str(serial), PROVISIONING_FEED_ID)
            else:
                feed_id=False
        except Exception, e:
            feed_id=False
        finally:
            return feed_id

    def xively_activate_product(self, serial):
        activation = hmac.new(a2b_hex(self.secret), serial, sha1).hexdigest()
        creds = xively.Client(key=None).get('/v2/devices/'+activation+'/activate').json()
        return creds 

if __name__ == "__main__":
    print "Testing Xively Manager "
    settings = os.path.join(os.path.dirname(sys.argv[0]), "config", "xively.conf")
    print settings

    testxive=XivelyManager(settings)
    #print testxive.activate_sensor(10)

    print testxive.get_feed(10)
当您的internet网关连接到多个其他设备时,这非常有用。 您的配置文件将更新如下内容:

[PROVISIONING]
product_secret = xxxxxxxxxxxxxxxxxxxxxxxxxxxx
api_key = xxxxxxxxxxxxxxxxxxxxxxxx

[productserial1]
feed_id = xxxxxxxx

[productserial2]
feed_id = xxxxxxxx

注意:显然pytonapi目前不支持设备激活。获取激活代码的文档似乎丢失了。我将看一看,并尝试为您提供一个工作示例。您想使用MAC地址作为设备的序列号吗?我想激活几个Raspberry PI,目前有4个,并考虑使用主机名。这允许我交换SD卡和更换无线适配器,同时维护用于临时/cpu速度/cpu负载的日志目标。@andig看起来人们拒绝这样的大编辑,所以我现在自己更新了它。。。谢谢你的剧本!我现在也把它变成了一个维基!
[PROVISIONING]
product_secret = xxxxxxxxxxxxxxxxxxxxxxxxxxxx
api_key = xxxxxxxxxxxxxxxxxxxxxxxx

[productserial1]
feed_id = xxxxxxxx

[productserial2]
feed_id = xxxxxxxx