#!/usr/bin/python
import requests, sys, json, time, random
import argparse

class Client(object):

    def __init__(self, master):
        # Read from config.ini / pub- and priv-key files etc ??
        self.id = None
        self.unit_type = None
        self.checkin_frequency = None
        self.priv_key = ".ssh/id_rsa"
        self.certificate = None

        # Replace with NFC discovery ??
        self.register_url = "http://%s/register-unit" % master
        self.checkin_url = None

        # Read config.ini
        with open('config.json') as config_fh:
            props = json.load( config_fh )

        self.unit_type = props['unit_type']
        self.checkin_frequency = props['checkin_frequency']

    def setup(self):

        with open('.ssh/id_rsa.csr') as csr_fh:
            csr = csr_fh.read()

        payload = {
            'unit_type': self.unit_type,
            'csr': csr
        }
        r = requests.post(self.register_url, data=payload)
        response = r.json()

        self.certificate_url = response['certificate_url']
        self.checkin_url = response['checkin_url']
        self.id = response['id']

        self.collect_certificate()
        self.schedule_checkin()

    def collect_certificate(self, backoff_interval=1):
        if backoff_interval > 9 or backoff_interval < 1:
            return

        for _ in xrange (backoff_interval):
            print "Requesting certificate from %s" % (self.certificate_url)
            r = requests.get(self.certificate_url)
            if r.status_code == requests.codes.ok:
                self.certificate = r.text
                print "Received certificate from %s" % (self.certificate_url)
                return
            else:
                time.sleep(backoff_interval)
        if not self.certificate:
            self.collect_certificate(backoff_interval*2)

    def schedule_checkin(self):
        backoff = 0
        while True:
            payload = {
                'unit_id': self.id,
                'readings': self.read()
            }
            # Throws error on timeout, must have fallback!
            try:
                requests.post(self.checkin_url, data=payload, timeout=5)
                print "%s sent to %s" % (payload, self.checkin_url)
                backoff = 0
            except requests.exceptions.ConnectTimeout:
                print "request timed out"
                backoff += 1

            sleeptime = min(self.checkin_frequency * pow(2, backoff), 60*15)
            time.sleep(sleeptime)

    def read(self):
        return [{
            'interface': 0,
            'value': random.random()*100
        }]


def parse_args():
    parser = argparse.ArgumentParser(prog='hasas_client')
    parser.add_argument('master',
        metavar='<master>',
        default='hasas.zza.no')
    return parser.parse_args()


def main():
    args = parse_args()
    c = Client(args.master)
    c.setup()

if __name__ == '__main__':
    main()

@@ -30,33 +30,74 @@
 ests
-, sys, json, time, random
+%0Aimport sys%0Aimport json%0Aimport time%0Aimport random%0Aimport threading
 %0Aimp
@@ -108,16 +108,29 @@
 argparse
+%0Aimport flask
 %0A%0Aclass 
@@ -534,24 +534,57 @@
 n_url = None
+%0A        self.registry_url = None
 %0A%0A        # 
@@ -791,24 +791,25 @@
 requency'%5D%0A%0A
+%0A
     def setu
@@ -817,17 +817,16 @@
 (self):%0A
-%0A
         
@@ -1186,24 +1186,77 @@
 eckin_url'%5D%0A
+        self.registry_url = response%5B'registry_url'%5D%0A
         self
@@ -1315,40 +1315,8 @@
 te()
-%0A        self.schedule_checkin()
 %0A%0A  
@@ -1976,24 +1976,100 @@
 def 
-schedule
+find_devices(self):%0A        requests.post(self.registry_url, timeout=5)%0A%0A%0A    def do
 _checkin
 (sel
@@ -2064,16 +2064,17 @@
 _checkin
+s
 (self):%0A
@@ -2711,16 +2711,252 @@
 ptime)%0A%0A
+    def do_listen(self):%0A        app = flask.Flask(__name__)%0A%0A        @app.route('/')%0A        def main():%0A            return flask.jsonify(%7B%0A                'response': 'Got it'%0A            %7D)%0A        app.run(host=%220.0.0.0%22, port=80)%0A%0A%0A
     def 
@@ -3066,16 +3066,29 @@
     %7D%5D%0A%0A
+%3C%3C%3C%3C%3C%3C%3C HEAD%0A
 %0Adef par
@@ -3283,16 +3283,54 @@
 rgs()%0A%0A%0A
+=======%0A%3E%3E%3E%3E%3E%3E%3E Add threads in client%0A
 def main
@@ -3385,16 +3385,16 @@
 master)%0A
-
     c.se
@@ -3398,16 +3398,100 @@
 .setup()
+%0A    threading.Thread(target=c.do_checkins)%0A    threading.Thread(target=c.do_listen)
 %0A%0Aif __n

Add threads in client