Exemplo n.º 1
0
    def _do_iteration(self):
        log_info('Starting a new iteration')

        date = datetime.utcnow()

        # Update the solution tank state
        solution_tank_was_full = self.solution_tank_is_full
        self.solution_tank_is_full = self.solution_tank.is_full()

        # Volume is unknown and pH sensor can be dry
        if not self.solution_tank_is_full:
            raise Exception('Solution tank is empty')

        # Skip one more iteration to let the pH readings stabilize
        if not solution_tank_was_full:
            raise Exception('Solution tank has been empty for a while')

        temperature, _, ph = drop_uncertainty(*self.ph.get_t_v_ph())
        if not in_range(ph, self.valid_ph_range):
            raise FatalException('Invalid pH: {:~.3gP}'.format(ph))
        if not in_range(temperature, self.valid_ph_temperature_range):
            raise FatalException(
                'Invalid pH temperature: {:~.3gP}'.format(temperature))

        if hasattr(self, 'temperature'):
            temperature = self.temperature.get_temperature()

        supply_tank_volume = drop_uncertainty(self.supply_tank.get_volume())
        if not in_range(supply_tank_volume,
                        self.valid_supply_tank_volume_range):
            raise FatalException('Invalid supply tank volume: {:~.3gP}'.format(
                supply_tank_volume))

        nutrients = self._estimate_nutrients(ph)

        data = {
            'date': date.strftime('%Y-%m-%dT%H:%M:%SZ'),
            'temperature_C': '%.1f' % temperature.m_as('degC'),
            'pH': '%.2f' % ph.m_as('pH'),
            'supply_tank_L': '%.0f' % supply_tank_volume.m_as('L'),
            'nutrients_mL': '%.1f' % nutrients.m_as('mL')
        }

        retry(lambda: self.database.append(data), 'Database append failed')

        # Data is already in DB, ignore Thingspeak errors
        retry(lambda: self.thingspeak.append(data),
              'Thingspeak append failed',
              rethrow=False)

        # We only add nutrients after their amount was logged to DB
        self.pump_x.pump(nutrients)
        self.pump_y.pump(nutrients)
Exemplo n.º 2
0
 def test_rings(self):
     sl = {}
     for addr in self.client.procs:
         sl[addr] = self.client.GetSuccessorList(addr).server_addrs
     rings = [list(self.client.procs.keys())[0]]
     print(rings)
     print(sl)
     print(list(self.client.procs.keys()))
     for _ in range(len(self.client.procs) - 1):
         rings.append(sl[rings[-1]][0])
     print(rings)
     # test rings correctness
     self.assertEqual(len(rings), len(self.client.procs))
     self.assertEqual(sorted(rings), sorted(self.client.procs.keys()))
     rings = rings * 3
     for i in range(1, self.client.n + 2):
         self.assertTrue(
             in_range(self.hash(rings[i - 1]), self.hash(rings[i]),
                      self.hash(rings[i + 1])))
     # test successor list correctness
     for addr in self.client.procs:
         self.assertEqual(len(sl[addr]),
                          self.client.config['successor_list_len'])
         for x in sl[addr]:
             self.assertTrue(x in self.client.procs.keys())
         rid = rings.index(addr)
         self.assertEqual(
             sl[addr], rings[rid + 1:rid + 1 +
                             self.client.config['successor_list_len']])
     # test predecessor correctness
     p = {}
     for addr in self.client.procs:
         p[addr] = self.client.GetPredecessor(addr).server_addr
         self.assertTrue(p[addr] in self.client.procs.keys())
         rid = rings.index(addr) + len(self.client.procs.keys())
         self.assertEqual(rings[rid - 1], p[addr])
     # test finger table correctness
     f = {}
     for addr in self.client.procs:
         f[addr] = self.client.GetFingers(addr).server_addrs
         print(addr, f[addr])
         self.assertEqual(len(f[addr]), self.client.config['mbits'] + 1)
         for x in f[addr][1:]:
             self.assertTrue(x in self.client.procs.keys())
         hashed_addr = self.hash(addr)
         for i in range(1, self.client.config['mbits'] + 1):
             f_hashed_addr = (hashed_addr+(1 << (i-1)))\
                 & ((1 << self.client.config['mbits'])-1)
             rid = rings.index(f[addr][i])
             self.assertTrue(
                 in_range(self.hash(rings[rid - 1]), f_hashed_addr,
                          self.hash(rings[rid]))
                 or f_hashed_addr == self.hash(rings[rid]))
Exemplo n.º 3
0
 def rebuild_subplaylist(self, date_range,
                         aperture_range, shutter_range, focal_range):
     """Narrow down the selected images in the playlist"""
     aperture_steps = self.frame.aperture_select.steps
     shutter_steps = self.frame.shutter_select.steps
     focal_steps = self.frame.focal_select.steps
     
     self.sub_playlist = [self.playlist[ind] for ind in range(len(self.playlist)) if
             in_range(self.date_vals[ind], date_range) and
             in_range(aperture_steps.index(self.aperture_vals[ind]),
                      aperture_range) and
             in_range(shutter_steps.index(self.shutter_vals[ind]), shutter_range) and
             in_range(focal_steps.index(self.focal_vals[ind]), focal_range)]
Exemplo n.º 4
0
 def move(self, x, y):
     if not utils.in_range(self.x, x, .05):
         if self.x < x:
             self.x += self.myinc
         elif self.x > x:
             self.x -= self.myinc
         else:
             self.x = x
     # ---------------------------
     if not utils.in_range(self.y, y, .05):
         if self.y < y:
             self.y += self.myinc
         elif self.y > y:
             self.y -= self.myinc
         else:
             self.y = y
Exemplo n.º 5
0
 def FindSuccessor(self, id):
     successor = None
     plen = 0
     if in_range(self.hashed_addr, id,
                 self.hashed_successor) or id == self.hashed_successor:
         successor = self.successor
     else:
         nxt_addrs = self.ClosestPrecedingNode(id)
         mprint('nxt addr', id, nxt_addrs)
         while len(nxt_addrs):
             nxt_addr = nxt_addrs[0]
             nxt_addrs = nxt_addrs[1:]
             try:
                 with grpc.insecure_channel(nxt_addr) as channel:
                     stub = cpg.chordStub(channel)
                     res = stub.GetSuccessor(
                         cp.GetSuccessorRequest(id=str(id)),
                         timeout=self.config['rpc_timeout'])
                     successor = res.server_addr
                     plen = res.path_length + 1
                 break
             except Exception as e:
                 mprint("fs", e)
     # mprint('get suc', successor)
     return successor, plen
Exemplo n.º 6
0
 def Get(self, req, ctx):
     if self.leave:
         raise Exception('Leave')
         return
     mprint('get', req.key, type(req.id))
     key, id = req.key, int(req.id)
     if self.hashed_predecessor and (in_range(self.hashed_predecessor, id,
                                              self.hashed_addr)
                                     or id == self.hashed_addr):
         if key in self.store:
             return cp.GetResponse(val=self.store[key]['val'],
                                   server_addr=self.addr,
                                   code=cp.Success)
         else:
             return cp.GetResponse(server_addr=self.addr,
                                   code=cp.KEY_NOT_EXIST)
     else:
         nxt_addr, _ = self.FindSuccessor(id)
         try:
             with grpc.insecure_channel(nxt_addr) as channel:
                 stub = cpg.chordStub(channel)
                 return stub.Get(cp.GetRequest(key=req.key, id=str(req.id)),
                                 timeout=self.config['rpc_timeout'])
         except Exception as e:
             mprint('get', e)
     return cp.GetResponse(code=cp.Error)
Exemplo n.º 7
0
 def Put(self, req, ctx):
     if self.leave:
         raise Exception('Leave')
         return
     key, val, id = req.key, req.val, int(req.id)
     if self.hashed_predecessor and (in_range(self.hashed_predecessor, id,
                                              self.hashed_addr)
                                     or id == self.hashed_addr):
         self.store[key] = {'val': val, 'id': id}
         with grpc.insecure_channel(self.predecessor) as channel:
             stub = cpg.chordStub(channel)
             stub.DirectPut(cp.DirectPutRequest(
                 key=key,
                 id=str(id),
                 val=val,
                 uuid=uuid.uuid4().hex,
                 remaining=self.config['max_failures']),
                            timeout=self.config['rpc_timeout'] *
                            self.config['max_failures'])
         return cp.PutResponse(code=cp.Success)
     else:
         nxt_addr, _ = self.FindSuccessor(id)
         try:
             with grpc.insecure_channel(nxt_addr) as channel:
                 stub = cpg.chordStub(channel)
                 return stub.Put(cp.PutRequest(key=req.key,
                                               val=req.val,
                                               id=str(req.id)),
                                 timeout=self.config['rpc_timeout'])
         except Exception as e:
             mprint('put', e)
     return cp.PutResponse(code=cp.Error)
Exemplo n.º 8
0
 def DeleteRange(self, req, ctx):
     if self.leave:
         raise Exception('Leave')
         return
     from_id, to_id = int(req.from_id), int(req.to_id)
     for k in list(self.store.keys()):
         id = self.store[k]['id']
         if id == from_id or id == to_id or in_range(from_id, id, to_id):
             del self.store[k]
     return cp.DeleteRangeResponse()
Exemplo n.º 9
0
 def ClosestPrecedingNode(self, id):
     res = []
     for i in range(self.config['mbits'], 0, -1):
         if self.fingers[i] and in_range(
                 self.hashed_addr, self.fingers[i]['hashed_addr'], id):
             if self.fingers[i]['addr'] not in res:
                 res.append(self.fingers[i]['addr'])
     for x in self.successor_list:
         if x and x not in res:
             res.append(x)
     return res
Exemplo n.º 10
0
 def GetRange(self, req, ctx):
     if self.leave:
         raise Exception('Leave')
         return
     from_id, to_id = int(req.from_id), int(req.to_id)
     keys, vals = [], []
     for k in self.store.keys():
         id = self.store[k]['id']
         if id == from_id or id == to_id or in_range(from_id, id, to_id):
             keys.append(k)
             vals.append(self.store[k]['val'])
     return cp.GetRangeResponse(keys=keys, vals=vals)
Exemplo n.º 11
0
    def Stabilize(self):
        mprint('stable')
        try:
            x = None
            while self.successor_list[0]:
                self.successor = self.successor_list[0]
                self.hashed_successor = self.hash(self.successor)
                mprint('stable', self.successor)
                try:
                    if self.addr != self.successor:
                        with grpc.insecure_channel(self.successor) as channel:
                            stub = cpg.chordStub(channel)
                            res = stub.GetPredecessor(
                                cp.Null(), timeout=self.config['rpc_timeout'])
                            mprint('pred', self.successor, res)
                            x = res.server_addr
                    else:
                        x = self.predecessor
                    break
                except Exception as e:
                    self.successor_list = self.successor_list[1:] + [None]
                    mprint('s1', e, self.successor_list)

            if x:
                hashed_x = self.hash(x)
                if in_range(self.hashed_addr, hashed_x, self.hashed_successor):
                    self.successor = x
                    self.hashed_successor = self.hash(self.successor)
                    self.successor_list = [self.successor
                                           ] + self.successor_list[:-1]
                    print('update sl', self.successor_list)
            self.successor = self.successor_list[0]
            if self.addr != self.successor:
                with grpc.insecure_channel(self.successor) as channel:
                    stub = cpg.chordStub(channel)
                    res = stub.Notify(cp.NotifyRequest(server_addr=self.addr),
                                      timeout=self.config['rpc_timeout'])
                    res = stub.GetSuccessorList(
                        cp.Null(), timeout=self.config['rpc_timeout'])
                    self.successor_list = [self.successor
                                           ] + res.server_addrs[:-1]
            else:
                self._Notify(self.addr)
        except Exception as e:
            import traceback as tb
            mprint('s2', self.successor_list, e, tb.format_stack())
            pass
Exemplo n.º 12
0
 def _Notify(self, addr):
     hashed_addr = self.hash(addr)
     # mprint("not", addr)
     if self.predecessor == None or in_range(self.hashed_predecessor,
                                             hashed_addr, self.hashed_addr):
         self.predecessor = addr
         self.hashed_predecessor = hashed_addr
         with grpc.insecure_channel(self.predecessor) as channel:
             stub = cpg.chordStub(channel)
             res = stub.GetRange(
                 cp.GetRangeRequest(
                     from_id=str((self.hashed_predecessor + 1)
                                 & ((1 << self.config['mbits']) - 1)),
                     to_id=str(self.hashed_addr)))
             for k, v in zip(res.keys, res.vals):
                 self.store[k] = {'val': v, 'id': self.hash(k)}
         self._DoReplicate(self.config['max_failures'], uuid.uuid4().hex)
Exemplo n.º 13
0
 def test_find_successor(self):
     sl = {}
     for addr in self.client.procs:
         sl[addr] = self.client.GetSuccessorList(addr).server_addrs
     rings = [list(self.client.procs.keys())[0]]
     for _ in range(len(self.client.procs) - 1):
         rings.append(sl[rings[-1]][0])
     print(rings)
     for i in range(1000):
         hi = self.hash(str(i))
         n = {
             self.client.Get(addr, str(i)).server_addr
             for addr in self.client.procs
         }
         self.assertEqual(len(n), 1)
         n = list(n)[0]
         hn = self.hash(n)
         p = self.client.GetPredecessor(n).server_addr
         hp = self.hash(p)
         self.assertTrue(in_range(hp, hi, hn) or hn == hi)
Exemplo n.º 14
0
def get_large_baseline(self):
    """Creates the large random baseline."""
    base_nodes = np.array([[5, 5], [5, 7], [3, 4]])
    num_unknown_nodes = 100
    sensor_range = 25,
    size_of_square = 100
    seed = 1337

    np.random.seed(1337)
    self.N = num_unknown_nodes
    self.base = base_nodes
    (self.B, _) = base_nodes.shape
    self.x_true = np.random.uniform(size=(self.N, 2)) * size_of_square
    self.nodes = np.concatenate((self.base, self.x_true))

    self._base_map = np.concatenate((np.ones((self.B)), np.zeros(self.N)))
    self.node_true_dist_mat = cross_distance(self.nodes)
    self.in_range_mat = in_range(self.node_true_dist_mat, sensor_range)

    return self
Exemplo n.º 15
0
 def Own(self, id):
     return in_range(self.hashed_predecessor, id,
                     self.hashed_addr) or id == self.hashed_addr