2 """Tracking code for Breadcrumb. Mainly glue between other components."""
4 # Copyright (C) 2008 Laurens Van Houtven <lvh at laurensvh.be>
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 """The central class for handling GPS tracking."""
24 def __init__(self
, host
= None, port
= None):
25 self
.network_interface
= net
.UDPClient(host
= host
, port
= port
)
26 self
.gps
= None # See connect_to_gps()
27 self
.messages
= collections
.deque()
28 self
.last_point
= None
31 """Starts the main tracking cycle.
33 This iterates over the gps attribute, which produces points.
35 for new_point
in self
.gps
:
36 if new_point
is not None: # new point
37 if self
.last_point
is None:
38 self
.last_point
= new_point
40 elif self
.last_point
< new_point
:
41 self
.last_point
.update(new_point
)
48 logging
.debug("No more data from the GPS! Fake device?")
51 """Sends the tracker's current point.
53 Also tries to send a handler message together with the point, unless
54 that point already has one. In that case, a second crumb is sent
55 immediately afterwards that has nothing but the handler message. This
56 prevents clients that send a handler message with *every* point from
57 blocking all other handler messages permanently.
61 if not has_message(self
.last_point
):
66 self
.network_interface
.send_point(self
.last_point
)
67 self
.last_point
.clear_message()
70 point
= self
.next_message()
71 self
.networkinterface
.sendpoint(point
)
73 def next_message(self
, point
= {}):
74 """Gets the next handler message from the queue and adds it to a point.
76 Uses an empty dict if no point is provided.
78 The point is always returned. This is useful if no point was provided.
81 id, msg
= self
.messages
.popleft()
82 point
.update({'handlerid': id, 'handlermessage': msg
})
86 def has_message(point
):
87 """Returns True if the point has a handler message, False otherwise."""
88 for attr
in ('handlerid', 'handlermessage'):