{"id":17511729,"url":"https://github.com/claws/txpachube","last_synced_at":"2026-03-05T23:43:04.861Z","repository":{"id":2141172,"uuid":"3085293","full_name":"claws/txPachube","owner":"claws","description":"A Python wrapper for the Cosm/Pachube v2 API, using the twisted networking framework","archived":false,"fork":false,"pushed_at":"2014-01-02T00:30:12.000Z","size":215,"stargazers_count":12,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-03T16:38:04.668Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/claws.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"MIT-LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-01-02T02:47:13.000Z","updated_at":"2014-01-02T00:30:12.000Z","dependencies_parsed_at":"2022-07-18T08:30:45.265Z","dependency_job_id":null,"html_url":"https://github.com/claws/txPachube","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/claws/txPachube","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claws%2FtxPachube","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claws%2FtxPachube/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claws%2FtxPachube/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claws%2FtxPachube/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/claws","download_url":"https://codeload.github.com/claws/txPachube/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/claws%2FtxPachube/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30156180,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-05T22:39:40.138Z","status":"ssl_error","status_checked_at":"2026-03-05T22:39:24.771Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-20T05:09:43.451Z","updated_at":"2026-03-05T23:43:04.812Z","avatar_url":"https://github.com/claws.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"txpachube (is now `txcosm \u003chttps://github.com/claws/txcosm\u003e`_)\n=========\n\nIMPORTANT NOTE: Further development on the capability provided by this package will be performed in `txcosm \u003chttps://github.com/claws/txcosm\u003e`_\n\n.. contents::\n\n\nIntroduction\n------------\n\nNOTE: Pachube was the old name of what is now Cosm.com. This package continues to work with Cosm.com even though it is named after the old site name.\nHowever, no further development is planned in this txpachube package. Instead this repository has been copied and recreated as txcosm to mirror the new Cosm.com site name.\n\ntxpachube is a Python package implementing the v2 Cosm/Pachube `API \u003chttps://cosm.com/docs/v2/\u003e`_, based on the Twisted networking framework.\nUse txpachube to integrate non blocking access to the Pachube API into your Python Twisted application.\n\n\nDetails\n-------\n\ntxpachube implements the full v2 Cosm/Pachube API (Feeds, Datastreams, Datapoints, Triggers, Users, Keys) and many\nof the data structures (Unit, Location, Datapoint, Datastream, Environment, EnvironmentList, Trigger,\nTriggerList Key, KeyList, User, UserList) contained in requests and responses.\n\nThe data structures support encoding and decoding from JSON/XML formats. These structures are useful\nwhen building data to send to Cosm/Pachube and also for processing Cosm/Pachube data returned from queries.\n\nThe txpachube client methods take a data string argument that will be used as the body of the\nmessage sent to Pachube. How you generate this body data is up to you. You might choose to\nmanually create the data something like this::\n\n    # manually create feed data message body content\n    feed_data = {\"title\" : \"A Temporary Test Feed\",\n                 \"version\" : \"1.0.0\"}\n    json_feed_data = json.dumps(feed_data)\n\nThe txpachube package implements many of the data structures used in Pachube requests and\nresponse as Python objects. So the JSON formatted feed data above could also be generated\nusing these txpachube data structure objects like this::\n\n    # Define a dict of valid data structure keywords for use as\n    # key word arguments to the data structure initialiser.\n    #\n    env_kwargs = {txpachube.DataFields.Title : \"A Temporary Test Feed\",\n                  txpachube.DataFields.Version : \"1.0.0\"}\n    environment = txpachube.Environment(**env_kwargs)\n    json_feed_data = environment.encode()\n\nOr in a more compact form once you are familiar with a data strcture's valid DataField items::\n\n    environment = txpachube.Environment(title=\"A Temporary Test Feed\", version=\"1.0.0\")\n    json_feed_data = environment.encode()\n\ntxpachube also implements a client that connects to the beta PAWS service. This allows long\nrunning, persistent, connections to be made to the Pachube service. This type of client is\nuseful for applications which require realtime updates on change of status. Such realtime\nupdates are available through the subscription feature exposed in the beta PAWS service.\n\n\n\nSoftware Dependencies\n---------------------\n\n* Python\n* Twisted\n\n  - zope.interface\n  - pyOpenSSL (used by Twisted for https - in our case for secure access to Pachube)\n\n\nInstall\n-------\n\n1. Download txpachube archive::\n\n    $ git clone git://github.com/claws/txPachube.git\n\nFor other download options (zip, tarball) visit the github web page of `txpachube \u003chttps://github.com/claws/txPachube\u003e`_\n\n2. Install txpachube module into your Python distribution::\n\n    sudo python setup.py install\n\n3. Test::\n\n    $ python\n    \u003e\u003e\u003e import txpachube\n    \u003e\u003e\u003e\n\n\nExamples\n--------\n\nThese examples require you to have a Pachube account and an appropriately configured\n(permissions set to create, update, read, delete) Pachube API key is required.\n\nList Pachube feeds visible to the API key supplied::\n\n    #!/usr/bin/env python\n    # This example demonstrates a request for feeds visible to the\n    # supplied API key. It initialises the Client object with a\n    # default API key that will be used if no api_key argument is\n    # passed to the various API methods.\n    # Parameters can be passed to customise the default results.\n    # In this case only 'live' feeds and 'summary' content is\n    # being requested.\n\n    from twisted.internet import reactor, defer\n    import txpachube.client\n\n    # Paste your Pachube API key here\n    API_KEY = \"\"\n\n\n    @defer.inlineCallbacks\n    def demo():\n        client = txpachube.client.Client(api_key=API_KEY)\n        try:\n            feed_list = yield client.list_feeds(parameters={'status' : 'live', 'content' : 'summary'})\n            print \"Received feed list content:\\n%s\\n\" % feed_list\n        except Exception, ex:\n            print \"Error listing visible feeds: %s\" % str(ex)\n\n        reactor.callLater(0.1, reactor.stop)\n        defer.returnValue(True)\n\n\n    if __name__ == \"__main__\":\n\n        reactor.callWhenRunning(demo)\n        reactor.run()\n\n\nCreate a new feed::\n\n    #!/usr/bin/env python\n    # This example demonstrates the ability to create new feeds. It also\n    # shows an API key being passed to the create_feed method directly\n    # as no default key was passed to the Client object initialiser.\n    # No format needs to be specified because json is the default format\n    # used.\n\n    from twisted.internet import reactor, defer\n    import txpachube\n    import txpachube.client\n\n    # Paste your Pachube API key here\n    API_KEY = \"\"\n\n\n    @defer.inlineCallbacks\n    def demo():\n\n        client = txpachube.client.Client()\n        try:\n            environment = txpachube.Environment(title=\"A Temporary Test Feed\", version=\"1.0.0\")\n            new_feed_id = yield client.create_feed(api_key=API_KEY, data=environment.encode())\n            print \"Created new feed with id: %s\" % new_feed_id\n        except Exception, ex:\n            print \"Error creating new feed: %s\" % str(ex)\n\n        reactor.callLater(0.1, reactor.stop)\n        defer.returnValue(True)\n\n\n    if __name__ == \"__main__\":\n\n        reactor.callWhenRunning(demo)\n        reactor.run()\n\n\nUpdate a feed::\n\n    #!/usr/bin/env python\n    # This example show how a feed can be updated using your own generated\n    # data, in this case XML data.\n    # The Client object has been initialised with an API key and a feed id\n    # so they don't need to be passed to the update_feed method. The format\n    # argument is JSON by default so it must be explicitly set as this\n    # example is using XML.\n\n    from twisted.internet import reactor\n    import txpachube\n    import txpachube.client\n\n    # Paste your Pachube API key here\n    API_KEY = \"\"\n\n    # Paste you feed identifier here\n    FEED_ID = \"\"\n\n    # example feed update data\n    feed_data = \"\"\"\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n    \u003ceeml xmlns=\"http://www.eeml.org/xsd/0.5.1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"0.5.1\" xsi:schemaLocation=\"http://www.eeml.org/xsd/0.5.1 http://www.eeml.org/xsd/0.5.1/0.5.1.xsd\"\u003e\n      \u003cenvironment\u003e\n        \u003ctitle\u003ebridge19\u003c/title\u003e\n        \u003cstatus\u003elive\u003c/status\u003e\n        \u003cdescription\u003ebridge environment 19\u003c/description\u003e\n        \u003ctag\u003eTag1\u003c/tag\u003e\n        \u003ctag\u003eTag2\u003c/tag\u003e\n        \u003cdata id=\"3\"\u003e\n          \u003ccurrent_value\u003e-312\u003c/current_value\u003e\n          \u003cmax_value\u003e999.0\u003c/max_value\u003e\n          \u003cmin_value\u003e7.0\u003c/min_value\u003e\n        \u003c/data\u003e\n        \u003cdata id=\"0\"\u003e\n          \u003ccurrent_value\u003e11\u003c/current_value\u003e\n          \u003cmax_value\u003e211.0\u003c/max_value\u003e\n          \u003cmin_value\u003e7.0\u003c/min_value\u003e\n        \u003c/data\u003e\n        \u003cdata id=\"4\"\u003e\n          \u003ccurrent_value\u003e-3332\u003c/current_value\u003e\n        \u003c/data\u003e\n      \u003c/environment\u003e\n    \u003c/eeml\u003e\"\"\"\n\n\n    if __name__ == \"__main__\":\n\n        pachubeClient = txpachube.client.Client(api_key=API_KEY, feed_id=FEED_ID)\n\n        d = pachubeClient.update_feed(format=txpachube.DataFormats.XML, data=feed_data)\n        d.addCallback(lambda result: print \"Feed updated successfully:\\n%s\\n\" % result)\n        d.addErrback(lambda reason: print \"Error updating feed: %s\" % str(reason))\n        d.addCallback(reactor.stop)\n\n        reactor.run()\n\n\nRead a feed::\n\n    #!/usr/bin/env python\n    # This example demonstrates a request for feed data and uses\n    # additional parameters to restrict the datastreams returned.\n    # It initialises the Client object with a default API key and\n    # feed id so they do not need to be passed to the read_feed\n    # method.\n\n    from twisted.internet import reactor, defer\n    import txpachube.client\n\n    # Paste your Pachube API key here\n    API_KEY = \"\"\n\n    # Paste the feed identifier you wish to be read here\n    FEED_ID = \"\"\n\n\n    @defer.inlineCallbacks\n    def demo():\n\n        client = txpachube.client.Client(api_key=API_KEY, feed_id=FEED_ID)\n        try:\n            feed = yield client.read_feed(parameters={'datastream':'temperature'})\n            print \"Received feed content:\\n%s\\n\" % feed\n        except Exception, ex:\n            print \"Error reading feed: %s\" % str(ex)\n\n        reactor.callLater(0.1, reactor.stop)\n        defer.returnValue(True)\n\n\n    if __name__ == \"__main__\":\n\n        reactor.callWhenRunning(demo)\n        reactor.run()\n\n\n\nDelete a feed::\n\n    #!/usr/bin/env python\n    # This example demonstrates the ability to delete a feed.\n    # WARNING: This will REALLY delete the feed identifier listed. Make sure it is only a test feed.\n\n    from twisted.internet import reactor, defer\n    import txpachube.client\n\n    # Paste your Pachube API key here\n    API_KEY = \"\"\n\n    # Paste the feed identifier you wish to be DELETED here\n    FEED_ID = \"\"\n\n\n    @defer.inlineCallbacks\n    def demo():\n\n        client = txpachube.client.Client()\n        try:\n            feed_delete_status = yield client.delete_feed(api_key=API_KEY, feed_id=FEED_ID)\n            print \"Deleted feed: %s\" % feed_delete_status\n        except Exception, ex:\n            print \"Error deleting feed: %s\" % str(ex)\n\n        reactor.callLater(0.1, reactor.stop)\n        defer.returnValue(True)\n\n\n    if __name__ == \"__main__\":\n\n        reactor.callWhenRunning(demo)\n        reactor.run()\n\n\n\nUse the beta PAWS API to subscribe to a feed or datastream and receive updates\nwhenever the feed/datastream value changes::\n\n    #!/usr/bin/env python\n\n    from twisted.internet import reactor\n    import txpachube\n    import txpachube.client\n\n    # Paste your Pachube API key here\n    API_KEY = \"\"\n\n    # Paste the feed identifier you wish to monitor here\n    FEED_ID = \"\"\n\n    # Paste a datastream identifier from the feed here if you only want to\n    # monitor a particular datastream instead of the whole feed.\n    DATASTREAM_ID = \"\"\n\n    #\n    # Set up callback handlers\n    #\n\n    def updateHandler(dataStructure):\n        \"\"\"\n        Handle a txpachube data structure object generated as a result of a\n        subscription update message received from Pachube.\n\n        The data structure returned will vary depending on the resource subscribed to.\n        If a datastream is specified the returned data structure will be a txpachube.Datastream\n        object. If just a feed is specified then the returned data structure will be a\n        txpachube.Environment object.\n        \"\"\"\n        print \"Subscription update message received:\\n%s\\n\" % str(dataStructure)\n\n\n    def do_subscribe(connected, client, resource):\n        \"\"\" Subscribe to the specified resource if the connection is established \"\"\"\n\n        if connected:\n            print \"Connected to PAWS service\"\n\n            def handleSubscribeResponse(status):\n                print \"Subscribe response status: %s\" % status\n\n            print \"Subscribing for updates to: %s\" % resource\n            token, d = client.subscribe(resource, updateHandler)\n            print \"Subscription token is: %s\" % token\n            d.addCallback(handleSubscribeResponse)\n\n        else:\n            print \"Connection failed\"\n            reactor.callLater(0.1, reactor.stop)\n            return\n\n\n    if __name__ == '__main__':\n\n        if DATASTREAM_ID:\n            resource = \"/feeds/%s/datastreams/%s\" % (FEED_ID, DATASTREAM_ID)\n        else:\n            resource = \"/feeds/%s\" % (FEED_ID)\n\n        client = txpachube.client.PAWSClient(api_key=API_KEY)\n        d = client.connect()\n        d.addCallback(do_subscribe, client, resource)\n        reactor.run()\n\n\n\n\nExample use case scenario::\n\n    #!/usr/bin/env python\n\n    # This example demonstrates how you could use the txpachube module to\n    # help upload sensor data (in this scenario a CurrentCost device) to\n    # Cosm/Pachube.\n    # A txpachube.Environment data structure is generated and populated\n    # with current value data. All the implemented data structures\n    # support encoding to JSON (default) and XML (EEML).\n    #\n    # In this example the CurrentCost sensor object is derived from the\n    # separate txcurrentcost package. If you want to run this script\n    # you would need to obtain that package.\n    #\n\n    from twisted.internet import reactor\n    import txpachube\n    import txcurrentcost.monitor\n\n    # Paste your Pachube API key here\n    API_KEY = \"\"\n\n    # Paste the feed identifier you wish to be DELETED here\n    FEED_ID = \"\"\n\n    CurrentCostMonitorConfigFile = \"/path/to/your/config/file\"\n\n\n    class MyCurrentCostMonitor(txcurrentcost.monitor.Monitor):\n        \"\"\"\n        Extends the txcurrentCost.monitor.Monitor by implementing periodic update\n        handler to call a supplied data handler.\n        \"\"\"\n\n        def __init__(self, config_file, periodicUpdateDataHandler):\n            super(MyCurrentCostMonitor, self).__init__(config_file)\n            self.periodicUpdateDataHandler = periodicUpdateDataHandler\n\n        def periodicUpdateReceived(self, timestamp, temperature, sensor_type, sensor_instance, sensor_data):\n            if sensor_type == txcurrentcost.Sensors.ElectricitySensor:\n                if sensor_instance == txcurrentcost.Sensors.WholeHouseSensorId:\n                    self.periodicUpdateDataHandler(timestamp, temperature, sensor_data)\n\n\n    class Monitor(object):\n\n        def __init__(self, config):\n            self.temperature_datastream_id = \"temperature\"\n            self.energy_datastream_id = \"energy\"\n            self.pachube = txpachube.client.Client(api_key=API_KEY, feed_id=FEED_ID)\n            currentCostMonitorConfig = txcurrentcost.monitor.MonitorConfig(CurrentCostMonitorConfigFile)\n            self.sensor = txcurrentcost.monior.Monitor(currentCostMonitorConfig,\n                                                       self.handleCurrentCostPeriodicUpdateData)\n\n        def start(self):\n            \"\"\" Start sensor \"\"\"\n            self.sensor.start()\n\n        def stop(self):\n            \"\"\" Stop the sensor \"\"\"\n            self.sensor.stop()\n\n        def def handleCurrentCostPeriodicUpdateData(self, timestamp, temperature, watts_on_channels):\n            \"\"\" Handle latest sensor periodic update \"\"\"\n\n            # Populate a txpachube.Environment data structure object with latest data\n\n            environment = txpachube.Environment(version=\"1.0.0\")\n            environment.setCurrentValue(self.temperature_datastream_id, \"%.1f\" % temperature)\n            environment.setCurrentValue(self.energy_datastream_id, str(watts_on_channels[0]))\n\n            # Update the Pachube service with latest value(s)\n\n            d = self.pachube.update_feed(data=environment.encode())\n            d.addCallback(lambda result: print \"Pachube updated\")\n            d.addErrback(lambda reason: print \"Pachube update failed: %s\" % str(reason))\n\n\n    if __name__ == \"__main__\":\n        monitor = Monitor()\n        reactor.callWhenRunning(monitor.start)\n        reactor.run()\n\n\n\nTodo\n----\n\n* Add test cases\n* Investigate alternative installers that support uninstall/update options.\n* Complete implementation of PAWS client. Currently it only supports subscribe/unsubscribe\n  but it should implement everything the standard client supports.\n\n\n.. image:: https://ga-beacon.appspot.com/UA-29867375-2/txPachube/readme?pixel\n   :target: https://github.com/claws/txPachube\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclaws%2Ftxpachube","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclaws%2Ftxpachube","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclaws%2Ftxpachube/lists"}