def _walk_after_teleport(self, walk_distance_post_teleport) -> float: """ Args: walk_distance_post_teleport: Returns: Distance walked in one way """ lat_offset, lng_offset = get_lat_lng_offsets_by_distance( walk_distance_post_teleport) to_walk = get_distance_of_two_points_in_meters( float(self.current_location.lat), float(self.current_location.lng), float(self.current_location.lat) + lat_offset, float(self.current_location.lng) + lng_offset) self.logger.info("Walking roughly: {:.2f}m", to_walk) time.sleep(0.3) self._communicator.walk_from_to( self.current_location, Location(self.current_location.lat + lat_offset, self.current_location.lng + lng_offset), WALK_AFTER_TELEPORT_SPEED) self.logger.debug("Walking back") time.sleep(0.3) self._communicator.walk_from_to( Location(self.current_location.lat + lat_offset, self.current_location.lng + lng_offset), self.current_location, WALK_AFTER_TELEPORT_SPEED) self.logger.debug("Done walking") return to_walk
def _get_relations_in_range_within_time(self, queue, max_radius): relations = {} for event in queue: for other_event in queue: if (event[1].lat == other_event[1].lat and event[1].lng == other_event[1].lng and event not in relations.keys()): relations[event] = [] distance = get_distance_of_two_points_in_meters( event[1].lat, event[1].lng, other_event[1].lat, other_event[1].lng) # we will always build relations from the event at hand subtracted by the event inspected timedelta = event[0] - other_event[0] if 0 <= distance <= max_radius * 2 and 0 <= timedelta <= self.max_timedelta_seconds: if event not in relations.keys(): relations[event] = [] # avoid duplicates already_present = False for relation in relations[event]: if (relation[0][1].lat == other_event[1].lat and relation[0][1].lng == other_event[1].lng): already_present = True if not already_present: relations[event].append( Relation(other_event, distance, timedelta)) return relations
def _check_data_distance(self, data): max_radius = self._mapping_manager.routemanager_get_max_radius( self._routemanager_name) if not max_radius: return True max_radius: int = self._applicationArgs.maximum_valid_distance \ if max_radius < self._applicationArgs.maximum_valid_distance else max_radius mode = self._mapping_manager.routemanager_get_mode( self._routemanager_name) if mode in ["mon_mitm", "iv_mitm"]: data_to_check = "wild_pokemon" else: data_to_check = "forts" lat_sum, lng_sum, counter = 0, 0, 0 if data_to_check == "forts": for cell in data: if cell[data_to_check]: cell_id = cell["id"] if cell_id < 0: cell_id = cell_id + 2**64 lat, lng, alt = S2Helper.get_position_from_cell(cell_id) counter += 1 lat_sum += lat lng_sum += lng else: for cell in data: for element in cell[data_to_check]: counter += 1 lat_sum += element["latitude"] lng_sum += element["longitude"] if counter == 0: return None avg_lat = lat_sum / counter avg_lng = lng_sum / counter distance = get_distance_of_two_points_in_meters( float(avg_lat), float(avg_lng), float(self.current_location.lat), float(self.current_location.lng)) if distance > max_radius: logger.debug2( "Data is too far away!! avg location {}, {} from " "data with self.current_location location {}, {} - that's a " "{}m distance with max_radius {} for mode {}", avg_lat, avg_lng, self.current_location.lat, self.current_location.lng, distance, max_radius, mode) return False else: logger.debug( "Data distance is ok! found avg location {}, {} " "from data with self.current_location location {}, {} - that's " "a {}m distance with max_radius {} for mode {}", avg_lat, avg_lng, self.current_location.lat, self.current_location.lng, distance, max_radius, mode) return True
def _get_route_manager_settings_and_distance_to_current_location(self): if not self._mapping_manager.routemanager_present(self._routemanager_name) \ or self._stop_worker_event.is_set(): raise InternalStopWorkerException routemanager_settings = self._mapping_manager.routemanager_get_settings( self._routemanager_name) distance = get_distance_of_two_points_in_meters( float(self.last_location.lat), float(self.last_location.lng), float(self.current_location.lat), float(self.current_location.lng)) self.logger.debug('Moving {} meters to the next position', round(distance, 2)) return distance, routemanager_settings
def walk_from_to(self, location_from: Location, location_to: Location, speed: float) -> Optional[MessageTyping]: # calculate the time it will take to walk and add it to the timeout! distance = get_distance_of_two_points_in_meters( location_from.lat, location_from.lng, location_to.lat, location_to.lng) # speed is in kmph, distance in m # we want m/s -> speed / 3.6 speed_meters = speed / 3.6 seconds_traveltime = distance / speed_meters return self.__run_get_gesponse("geo walk {} {} {} {} {}\r\n".format(location_from.lat, location_from.lng, location_to.lat, location_to.lng, speed), self.__command_timeout + seconds_traveltime)
def _get_count_and_coords_in_circle_within_timedelta( self, middle, relations, earliest_timestamp, latest_timestamp, max_radius): inside_circle = [] highest_timedelta = 0 if self.useS2: region = s2sphere.CellUnion( S2Helper.get_S2cells_from_circle(middle.lat, middle.lng, self.max_radius, self.S2level)) for event_relations in relations: # exclude previously clustered events... if len(event_relations) == 4 and event_relations[3]: inside_circle.append(event_relations) continue distance = get_distance_of_two_points_in_meters( middle.lat, middle.lng, event_relations[1].lat, event_relations[1].lng) event_in_range = 0 <= distance <= max_radius if self.useS2: event_in_range = region.contains( s2sphere.LatLng.from_degrees( event_relations[1].lat, event_relations[1].lng).to_point()) # timedelta of event being inspected to the earliest timestamp timedelta_end = latest_timestamp - event_relations[0] timedelta_start = event_relations[0] - earliest_timestamp if timedelta_end < 0 and event_in_range: # we found an event starting past the current latest timestamp, let's update the latest_timestamp latest_timestamp_temp = latest_timestamp + abs(timedelta_end) if latest_timestamp_temp - earliest_timestamp <= self.max_timedelta_seconds: latest_timestamp = latest_timestamp_temp highest_timedelta = highest_timedelta + abs(timedelta_end) inside_circle.append(event_relations) elif timedelta_start < 0 and event_in_range: # we found an event starting before earliest_timestamp, let's check that... earliest_timestamp_temp = earliest_timestamp - \ abs(timedelta_start) if latest_timestamp - earliest_timestamp_temp <= self.max_timedelta_seconds: earliest_timestamp = earliest_timestamp_temp highest_timedelta = highest_timedelta + \ abs(timedelta_start) inside_circle.append(event_relations) elif timedelta_end >= 0 and timedelta_start >= 0 and event_in_range: # we found an event within our current timedelta and proximity, just append it to the list inside_circle.append(event_relations) return len( inside_circle), inside_circle, highest_timedelta, latest_timestamp
def walkFromTo(self, startLat, startLng, destLat, destLng, speed): with self.__sendMutex: # calculate the time it will take to walk and add it to the timeout! distance = get_distance_of_two_points_in_meters( startLat, startLng, destLat, destLng) # speed is in kmph, distance in m # we want m/s -> speed / 3.6 speed_meters = speed / 3.6 seconds_traveltime = distance / speed_meters response = self.websocket_handler.send_and_wait( self.worker_id, self.worker_instance_ref, "geo walk {} {} {} {} {}\r\n".format(startLat, startLng, destLat, destLng, speed), self.__command_timeout + seconds_traveltime) return response
def _generate_locations(distance: float, geofence_helper: GeofenceHelper): south, east, north, west = geofence_helper.get_polygon_from_fence() corners = [ Location(south, east), Location(south, west), Location(north, east), Location(north, west) ] # get the center center = get_middle_of_coord_list(corners) # get the farthest to the center... farthest_dist = 0 for corner in corners: dist_temp = get_distance_of_two_points_in_meters( center.lat, center.lng, corner.lat, corner.lng) if dist_temp > farthest_dist: farthest_dist = dist_temp # calculate step_limit, round up to reduce risk of losing stuff step_limit = math.ceil(farthest_dist / distance) # This will loop thorugh all the rings in the hex from the centre # moving outwards logger.info("Calculating positions for init scan") num_cores = multiprocessing.cpu_count() with multiprocessing.Pool(processes=num_cores) as pool: temp = [pool.apply(S2Helper._generate_star_locs, args=( center, distance, i)) for i in range(1, step_limit)] results = [item for sublist in temp for item in sublist] results.append(Location(center.lat, center.lng)) logger.info("Filtering positions for init scan") # Geofence results. if geofence_helper is not None and geofence_helper.is_enabled(): results = geofence_helper.get_geofenced_coordinates(results) if not results: logger.error('No cells regarded as valid for desired scan area. Check your provided geofences. ' 'Aborting.') else: logger.info("Ordering location") results = S2Helper.order_location_list_rows(results) return results
def _is_location_within_allowed_range(self, latest_location): self.logger.debug2( "Checking (data) location reported by {} at {} against real data location {}", self._origin, self.current_location, latest_location) distance_to_data = get_distance_of_two_points_in_meters( float(latest_location.lat), float(latest_location.lng), float(self.current_location.lat), float(self.current_location.lng)) max_distance_of_mode = self._mapping_manager.routemanager_get_max_radius( self._routemanager_name) max_distance_for_worker = self._applicationArgs.maximum_valid_distance if max_distance_for_worker > max_distance_of_mode > MINIMUM_DISTANCE_ALLOWANCE_FOR_GMO: # some modes may be too strict (e.g. quests with 0.0001m calculations for routes) # yet, the route may "require" a stricter ruling than max valid distance max_distance_for_worker = max_distance_of_mode self.logger.debug2("Distance of worker {} to (data) location: {}", self._origin, distance_to_data) if distance_to_data > max_distance_for_worker: self.logger.debug( "Location too far from worker position, max distance allowed: {}m", max_distance_for_worker) return distance_to_data <= max_distance_for_worker
def _wait_for_data(self, timestamp: float = None, proto_to_wait_for=106, timeout=None): if timestamp is None: timestamp = time.time() if timeout is None: timeout = self.get_devicesettings_value("mitm_wait_timeout", 45) # since the GMOs may only contain mons if we are not "too fast" (which is the case when teleporting) after # waiting a certain period of time (usually the 2nd GMO), we will multiply the timeout by 2 for mon-modes mode = self._mapping_manager.routemanager_get_mode( self._routemanager_name) if mode in ["mon_mitm", "iv_mitm" ] or self._mapping_manager.routemanager_get_init( self._routemanager_name): timeout *= 2 # let's fetch the latest data to add the offset to timeout (in case device and server times are off...) latest = self._mitm_mapper.request_latest(self._origin) timestamp_last_data = latest.get("timestamp_last_data", 0) timestamp_last_received = latest.get("timestamp_receiver", 0) # we can now construct the rough estimate of the diff of time of mobile vs time of server, subtract our # timestamp by the diff # TODO: discuss, probably wiser to add to timeout or get the diff of how long it takes for RGC to issue a cmd timestamp = timestamp - (timestamp_last_received - timestamp_last_data) self.logger.info('Waiting for data after {}', datetime.fromtimestamp(timestamp)) data_requested = LatestReceivedType.UNDEFINED failover_timestamp: int = time.time() while data_requested == LatestReceivedType.UNDEFINED and \ (timestamp + timeout >= int(time.time()) and int(failover_timestamp + timeout) >= int(time.time())) \ and not self._stop_worker_event.is_set(): latest = self._mitm_mapper.request_latest(self._origin) latest_location: Optional[Location] = latest.get("location", None) check_data = True if (proto_to_wait_for == 106 and latest_location is not None and latest_location.lat != 0.0 and latest_location.lng != 0.0): self.logger.debug( "Checking worker location {} against real data location {}", self.current_location, latest_location) distance_to_data = get_distance_of_two_points_in_meters( float(latest_location.lat), float(latest_location.lng), float(self.current_location.lat), float(self.current_location.lng)) max_distance_of_mode = self._mapping_manager.routemanager_get_max_radius( self._routemanager_name) max_distance_for_worker: int = self._applicationArgs.maximum_valid_distance \ if max_distance_of_mode < self._applicationArgs.maximum_valid_distance else max_distance_of_mode self.logger.debug("Distance of worker {} to data location: {}", self._origin, distance_to_data) if max_distance_for_worker and distance_to_data > max_distance_for_worker: self.logger.debug( "Real data too far from worker position, waiting...") check_data = False if check_data: data_requested = self._wait_data_worker( latest, proto_to_wait_for, timestamp) if not self._mapping_manager.routemanager_present(self._routemanager_name) \ or self._stop_worker_event.is_set(): self.logger.error("killed while sleeping") raise InternalStopWorkerException time.sleep(1) position_type = self._mapping_manager.routemanager_get_position_type( self._routemanager_name, self._origin) if position_type is None: self.logger.warning( "Mappings/Routemanagers have changed, stopping worker to be created again" ) raise InternalStopWorkerException if data_requested != LatestReceivedType.UNDEFINED: self.logger.success('Got the data requested') self._reboot_count = 0 self._restart_count = 0 self._rec_data_time = datetime.now() self._mitm_mapper.collect_location_stats( self._origin, self.current_location, 1, self._waittime_without_delays, position_type, time.time(), self._mapping_manager.routemanager_get_mode( self._routemanager_name), self._transporttype) else: # TODO: timeout also happens if there is no useful data such as mons nearby in mon_mitm mode, we need to # TODO: be more precise (timeout vs empty data) self.logger.warning("Timeout waiting for data") self._mitm_mapper.collect_location_stats( self._origin, self.current_location, 0, self._waittime_without_delays, position_type, 0, self._mapping_manager.routemanager_get_mode( self._routemanager_name), self._transporttype) self._restart_count += 1 restart_thresh = self.get_devicesettings_value("restart_thresh", 5) reboot_thresh = self.get_devicesettings_value("reboot_thresh", 3) if self._mapping_manager.routemanager_get_route_stats( self._routemanager_name, self._origin) is not None: if self._init: restart_thresh = self.get_devicesettings_value( "restart_thresh", 5) * 2 reboot_thresh = self.get_devicesettings_value( "reboot_thresh", 3) * 2 if self._restart_count > restart_thresh: self._reboot_count += 1 if self._reboot_count > reboot_thresh \ and self.get_devicesettings_value("reboot", True): self.logger.error("Too many timeouts - Rebooting device") self._reboot(mitm_mapper=self._mitm_mapper) raise InternalStopWorkerException # self._mitm_mapper. self._restart_count = 0 self.logger.error("Too many timeouts - Restarting game") self._restart_pogo(True, self._mitm_mapper) self.worker_stats() return data_requested
def statistics_detection_worker_data(self): minutes = request.args.get('minutes', 120) worker = request.args.get('worker') # spawns mon = [] mon_iv = [] raid = [] quest = [] usage = [] data = self._db_stats_reader.get_detection_count(minutes=minutes, worker=worker) for dat in data: mon.append([dat[0] * 1000, int(dat[2])]) mon_iv.append([dat[0] * 1000, int(dat[3])]) raid.append([dat[0] * 1000, int(dat[4])]) quest.append([dat[0] * 1000, int(dat[5])]) usage.append({'label': 'Mon', 'data': mon}) usage.append({'label': 'Mon_IV', 'data': mon_iv}) usage.append({'label': 'Raid', 'data': raid}) usage.append({'label': 'Quest', 'data': quest}) # locations avg locations_avg = [] data = self._db_stats_reader.get_avg_data_time(minutes=minutes, worker=worker) for dat in data: dtime = datetime.datetime.fromtimestamp(dat[0]).strftime( self._datetimeformat) locations_avg.append({ 'dtime': dtime, 'ok_locations': dat[3], 'avg_datareceive': float(dat[4]), 'transporttype': dat[1], 'type': dat[5] }) # locations ok = [] nok = [] sumloc = [] locations = [] data = self._db_stats_reader.get_locations(minutes=minutes, worker=worker) for dat in data: ok.append([dat[0] * 1000, int(dat[3])]) nok.append([dat[0] * 1000, int(dat[4])]) sumloc.append([dat[0] * 1000, int(dat[2])]) locations.append({'label': 'Locations', 'data': sumloc}) locations.append({'label': 'Locations_ok', 'data': ok}) locations.append({'label': 'Locations_nok', 'data': nok}) # dataratio loctionratio = [] data = self._db_stats_reader.get_locations_dataratio(minutes=minutes, worker=worker) if len(data) > 0: for dat in data: loctionratio.append({'label': dat[3], 'data': dat[2]}) else: loctionratio.append({'label': '', 'data': 0}) # all spaws all_spawns = [] data = self._db_stats_reader.get_detection_count(grouped=False, worker=worker) all_spawns.append({'type': 'Mon', 'amount': int(data[0][2])}) all_spawns.append({'type': 'Mon_IV', 'amount': int(data[0][3])}) all_spawns.append({'type': 'Raid', 'amount': int(data[0][4])}) all_spawns.append({'type': 'Quest', 'amount': int(data[0][5])}) # raw detection data detections_raw = [] data, data2 = self._db_stats_reader.get_detection_raw(minutes=minutes, worker=worker) for dat in data: detections_raw.append({ 'type': dat[1], 'id': dat[2], 'count': dat[3] }) for dat in data2: detections_raw.append({ 'type': dat[1], 'id': dat[2], 'count': dat[3] }) # location raw location_raw = [] last_lat = 0 last_lng = 0 distance = 0 data = self._db_stats_reader.get_location_raw(minutes=minutes, worker=worker) for dat in data: if last_lat != 0 and last_lng != 0: distance = round( get_distance_of_two_points_in_meters( last_lat, last_lng, dat[1], dat[2]), 2) last_lat = dat[1] last_lng = dat[2] if last_lat == 0 and last_lng == 0: last_lat = dat[1] last_lng = dat[2] if dat[1] == 0 and dat[2] == 0: distance = '' location_raw.append({ 'lat': dat[1], 'lng': dat[2], 'distance': distance, 'type': dat[3], 'data': dat[4], 'fix_ts': datetime.datetime.fromtimestamp(dat[5]).strftime( self._datetimeformat), 'data_ts': datetime.datetime.fromtimestamp(dat[6]).strftime( self._datetimeformat), 'transporttype': dat[8] }) workerstats = { 'avg': locations_avg, 'receiving': usage, 'locations': locations, 'ratio': loctionratio, 'allspawns': all_spawns, 'detections_raw': detections_raw, 'location_raw': location_raw } return jsonify(workerstats)
def _check_if_stop_was_nearby_and_update_location(self, gmo_cells): self.logger.info("Checking stops around current location ({}) for deleted stops.", self.current_location) stops: Dict[str, Tuple[Location, datetime]] = self._db_wrapper.get_stop_ids_and_locations_nearby( self.current_location ) self.logger.debug("Checking if GMO contains location changes or DB has stops that are already deleted. In DB: " "{}. GMO cells: {}", str(stops), gmo_cells) # stops may contain multiple stops now. We can check each ID (key of dict) with the IDs in the GMO. # Then cross check against the location. If that differs, we need to update/delete the entries in the DB for cell in gmo_cells: forts: list = cell.get("forts", None) if not forts: continue for fort in forts: latitude: float = fort.get("latitude", None) longitude: float = fort.get("longitude", None) fort_id: str = fort.get("id", None) if not latitude or not longitude or not fort_id: self.logger.warning("Cannot process fort without id, lat or lon") continue location_last_updated: Tuple[Location, datetime] = stops.get(fort_id) if location_last_updated is None: # new stop we have not seen before, MITM processors should take care of that self.logger.debug2("Stop not in DB (in range) with ID {} at {}, {}", fort_id, latitude, longitude) continue else: stops.pop(fort_id) stop_location_known, last_updated = location_last_updated if stop_location_known.lat == latitude and stop_location_known.lng == longitude: # Location of fort has not changed self.logger.debug2("Fort {} has not moved", fort_id) continue else: # now we have a location from DB for the given stop we are currently processing but does not equal # the one we are currently processing, thus SAME fort_id # now update the stop self.logger.warning("Updating fort {} with previous location {} now placed at {}, {}", fort_id, str(stop_location_known), latitude, longitude) self._db_wrapper.update_pokestop_location(fort_id, latitude, longitude) timedelta_to_consider_deletion = timedelta(days=3) for fort_id in stops.keys(): # Call delete of stops that have been not been found within 100m range of current position stop_location_known, last_updated = stops[fort_id] self.logger.debug("Considering stop {} at {} (last updated {}) for deletion", fort_id, stop_location_known, last_updated) if last_updated and last_updated > datetime.now() - timedelta_to_consider_deletion: self.logger.info("Stop considered for deletion was last updated recently, not gonna delete it for now.", last_updated) continue distance_to_location = get_distance_of_two_points_in_meters(float(stop_location_known.lat), float(stop_location_known.lng), float(self.current_location.lat), float(self.current_location.lng)) self.logger.debug("Distance to {} at {} (last updated {})", fort_id, stop_location_known, last_updated) if distance_to_location < 100: self.logger.warning( "Deleting stop {} at {} since it could not be found in the GMO but was present in DB and within " "100m of worker ({}m) and was last updated more than 3 days ago ()", fort_id, str(stop_location_known), distance_to_location, last_updated) self._db_wrapper.delete_stop(stop_location_known.lat, stop_location_known.lng) self._mapping_manager.routemanager_add_coords_to_be_removed(self._routemanager_name, stop_location_known.lat, stop_location_known.lng)
def _move_to_location(self): if not self._mapping_manager.routemanager_present(self._routemanager_name) \ or self._stop_worker_event.is_set(): raise InternalStopWorkerException routemanager_settings = self._mapping_manager.routemanager_get_settings( self._routemanager_name) # get the distance from our current position (last) to the next gym (cur) distance = get_distance_of_two_points_in_meters( float(self.last_location.lat), float(self.last_location.lng), float(self.current_location.lat), float(self.current_location.lng)) logger.debug('Moving {} meters to the next position', round(distance, 2)) if not self._mapping_manager.routemanager_get_init( self._routemanager_name): speed = routemanager_settings.get("speed", 0) max_distance = routemanager_settings.get("max_distance", None) else: speed = int(25) max_distance = int(200) if (speed == 0 or (max_distance and 0 < max_distance < distance) or (self.last_location.lat == 0.0 and self.last_location.lng == 0.0)): logger.debug("main: Teleporting...") self._transporttype = 0 self._communicator.set_location( Location(self.current_location.lat, self.current_location.lng), 0) # the time we will take as a starting point to wait for data... cur_time = math.floor(time.time()) delay_used = self.get_devicesettings_value('post_teleport_delay', 7) # Test for cooldown / teleported distance TODO: check this block... if self.get_devicesettings_value('cool_down_sleep', False): if distance > 10000: delay_used = 15 elif distance > 5000: delay_used = 10 elif distance > 2500: delay_used = 8 logger.debug("Need more sleep after Teleport: {} seconds!", str(delay_used)) # curTime = math.floor(time.time()) # the time we will take as a starting point to wait for data... walk_distance_post_teleport = self.get_devicesettings_value( 'walk_after_teleport_distance', 0) if 0 < walk_distance_post_teleport < distance: # TODO: actually use to_walk for distance lat_offset, lng_offset = get_lat_lng_offsets_by_distance( walk_distance_post_teleport) to_walk = get_distance_of_two_points_in_meters( float(self.current_location.lat), float(self.current_location.lng), float(self.current_location.lat) + lat_offset, float(self.current_location.lng) + lng_offset) logger.info("Walking roughly: {}", str(to_walk)) time.sleep(0.3) self._communicator.walk_from_to( self.current_location, Location(self.current_location.lat + lat_offset, self.current_location.lng + lng_offset), 11) logger.debug("Walking back") time.sleep(0.3) self._communicator.walk_from_to( Location(self.current_location.lat + lat_offset, self.current_location.lng + lng_offset), self.current_location, 11) logger.debug("Done walking") time.sleep(1) else: logger.info("main: Walking...") self._transporttype = 1 self._communicator.walk_from_to(self.last_location, self.current_location, speed) # the time we will take as a starting point to wait for data... cur_time = math.floor(time.time()) logger.debug2("Done walking, fetching time to sleep") delay_used = self.get_devicesettings_value('post_walk_delay', 7) logger.debug2("Sleeping for {}s".format(str(delay_used))) time.sleep(float(delay_used)) self.set_devicesettings_value("last_location", self.current_location) self.last_location = self.current_location self._waittime_without_delays = time.time() return cur_time, True
def _move_to_location(self): if not self._mapping_manager.routemanager_present(self._routemanager_name) \ or self._stop_worker_event.is_set(): raise InternalStopWorkerException routemanager_settings = self._mapping_manager.routemanager_get_settings( self._routemanager_name) distance = get_distance_of_two_points_in_meters( float(self.last_location.lat), float(self.last_location.lng), float(self.current_location.lat), float(self.current_location.lng)) self.logger.debug('Moving {} meters to the next position', round(distance, 2)) delay_used = 0 self.logger.debug("Getting time") speed = routemanager_settings.get("speed", 0) max_distance = routemanager_settings.get("max_distance", None) if (speed == 0 or (max_distance and 0 < max_distance < distance) or (self.last_location.lat == 0.0 and self.last_location.lng == 0.0)): self.logger.debug("main: Teleporting...") self._transporttype = 0 self._communicator.set_location( Location(self.current_location.lat, self.current_location.lng), 0) # the time we will take as a starting point to wait for data... cur_time = math.floor(time.time()) delay_used = self.get_devicesettings_value('post_teleport_delay', 0) speed = 16.67 # Speed can be 60 km/h up to distances of 3km if self.last_location.lat == 0.0 and self.last_location.lng == 0.0: self.logger.info('Starting fresh round - using lower delay') else: if distance >= 1335000: speed = 180.43 # Speed can be abt 650 km/h elif distance >= 1100000: speed = 176.2820513 elif distance >= 1020000: speed = 168.3168317 elif distance >= 1007000: speed = 171.2585034 elif distance >= 948000: speed = 166.3157895 elif distance >= 900000: speed = 164.8351648 elif distance >= 897000: speed = 166.1111111 elif distance >= 839000: speed = 158.9015152 elif distance >= 802000: speed = 159.1269841 elif distance >= 751000: speed = 152.6422764 elif distance >= 700000: speed = 151.5151515 elif distance >= 650000: speed = 146.3963964 elif distance >= 600000: speed = 142.8571429 elif distance >= 550000: speed = 138.8888889 elif distance >= 500000: speed = 134.4086022 elif distance >= 450000: speed = 129.3103448 elif distance >= 400000: speed = 123.4567901 elif distance >= 350000: speed = 116.6666667 elif distance >= 328000: speed = 113.8888889 elif distance >= 300000: speed = 108.6956522 elif distance >= 250000: speed = 101.6260163 elif distance >= 201000: speed = 90.54054054 elif distance >= 175000: speed = 85.78431373 elif distance >= 150000: speed = 78.125 elif distance >= 125000: speed = 71.83908046 elif distance >= 100000: speed = 64.1025641 elif distance >= 90000: speed = 60 elif distance >= 80000: speed = 55.55555556 elif distance >= 70000: speed = 50.72463768 elif distance >= 60000: speed = 47.61904762 elif distance >= 45000: speed = 39.47368421 elif distance >= 40000: speed = 35.0877193 elif distance >= 35000: speed = 32.40740741 elif distance >= 30000: speed = 29.41176471 elif distance >= 25000: speed = 27.77777778 elif distance >= 20000: speed = 27.77777778 elif distance >= 15000: speed = 27.77777778 elif distance >= 10000: speed = 23.80952381 elif distance >= 8000: speed = 26.66666667 elif distance >= 5000: speed = 22.34137623 elif distance >= 4000: speed = 22.22222222 delay_used = distance / speed if delay_used > 7200: # There's a maximum of 2 hours wait time delay_used = 7200 self.logger.debug("Need more sleep after Teleport: {} seconds!", int(delay_used)) else: delay_used = distance / ( speed / 3.6) # speed is in kmph , delay_used need mps self.logger.info("main: Walking {} m, this will take {} seconds", distance, delay_used) self._transporttype = 1 self._communicator.walk_from_to(self.last_location, self.current_location, speed) # the time we will take as a starting point to wait for data... cur_time = math.floor(time.time()) delay_used = self.get_devicesettings_value('post_walk_delay', 0) walk_distance_post_teleport = self.get_devicesettings_value( 'walk_after_teleport_distance', 0) if 0 < walk_distance_post_teleport < distance: # TODO: actually use to_walk for distance lat_offset, lng_offset = get_lat_lng_offsets_by_distance( walk_distance_post_teleport) to_walk = get_distance_of_two_points_in_meters( float(self.current_location.lat), float(self.current_location.lng), float(self.current_location.lat) + lat_offset, float(self.current_location.lng) + lng_offset) self.logger.info("Walking roughly: {:.2f}m", to_walk) time.sleep(0.3) self._communicator.walk_from_to( self.current_location, Location(self.current_location.lat + lat_offset, self.current_location.lng + lng_offset), 11) self.logger.debug("Walking back") time.sleep(0.3) self._communicator.walk_from_to( Location(self.current_location.lat + lat_offset, self.current_location.lng + lng_offset), self.current_location, 11) self.logger.debug("Done walking") time.sleep(1) delay_used -= ( to_walk / 3.05 ) - 1. # We already waited for a bit because of this walking part if delay_used < 0: delay_used = 0 if self._init: delay_used = 5 if self.get_devicesettings_value('last_action_time', None) is not None: timediff = time.time() - self.get_devicesettings_value( 'last_action_time', 0) self.logger.info("Timediff between now and last action time: {}", int(timediff)) delay_used = delay_used - timediff elif self.get_devicesettings_value( 'last_action_time', None) is None and not self._level_mode: self.logger.info( 'Starting first time - we wait because of some default pogo delays ...' ) delay_used = 20 else: self.logger.debug("No last action time found - no calculation") delay_used = -1 if self.get_devicesettings_value('screendetection', True) and \ self._WordToScreenMatching.return_memory_account_count() > 1 and delay_used >= self._rotation_waittime \ and self.get_devicesettings_value('account_rotation', False) and not self._level_mode: # Waiting time to long and more then one account - switch! (not level mode!!) self.logger.info( 'Could use more then 1 account - switch & no cooldown') self.switch_account() delay_used = -1 if delay_used < 0: self._current_sleep_time = 0 self.logger.info('No need to wait before spinning, continuing...') else: delay_used = math.floor(delay_used) self.logger.info("Real sleep time: {} seconds: next action {}", delay_used, datetime.now() + timedelta(seconds=delay_used)) cleanupbox: bool = False lastcleanupbox = self.get_devicesettings_value( 'last_cleanup_time', None) self._current_sleep_time = delay_used self.worker_stats() if lastcleanupbox is not None: if time.time() - lastcleanupbox > 900: # just cleanup if last cleanup time > 15 minutes ago cleanupbox = True else: cleanupbox = True self._mapping_manager.routemanager_set_worker_sleeping( self._routemanager_name, self._origin, delay_used) while time.time() <= int(cur_time) + int(delay_used): if delay_used > 200 and cleanupbox and not self._enhanced_mode: self.clear_thread_task = ClearThreadTasks.BOX cleanupbox = False if not self._mapping_manager.routemanager_present(self._routemanager_name) \ or self._stop_worker_event.is_set(): self.logger.error("Worker was killed while sleeping") self._current_sleep_time = 0 raise InternalStopWorkerException time.sleep(1) self._current_sleep_time = 0 self.set_devicesettings_value("last_location", self.current_location) self.last_location = self.current_location return cur_time, True
def _generate_locations(distance: float, geofence_helper: GeofenceHelper): south, east, north, west = geofence_helper.get_polygon_from_fence() corners = [ Location(south, east), Location(south, west), Location(north, east), Location(north, west) ] # get the center center = get_middle_of_coord_list(corners) # get the farthest to the center... farthest_dist = 0 for corner in corners: dist_temp = get_distance_of_two_points_in_meters( center.lat, center.lng, corner.lat, corner.lng) if dist_temp > farthest_dist: farthest_dist = dist_temp # calculate step_limit, round up to reduce risk of losing stuff step_limit = math.ceil(farthest_dist / distance) # This will loop thorugh all the rings in the hex from the centre # moving outwards logger.info("Calculating positions for init scan") num_cores = multiprocessing.cpu_count() with multiprocessing.Pool(processes=num_cores) as pool: temp = [ pool.apply(S2Helper._generate_star_locs, args=(center, distance, i)) for i in range(1, step_limit) ] results = [item for sublist in temp for item in sublist] results.append(Location(center.lat, center.lng)) # for ring in range(1, step_limit): # for i in range(0, 6): # # Star_locs will contain the locations of the 6 vertices of # # the current ring (90,150,210,270,330 and 30 degrees from # # origin) to form a star # star_loc = S2Helper.get_new_coords(center, distance * ring, # 90 + 60 * i) # for j in range(0, ring): # # Then from each point on the star, create locations # # towards the next point of star along the edge of the # # current ring # loc = S2Helper.get_new_coords(star_loc, distance * j, 210 + 60 * i) # results.append(loc) logger.info("Filtering positions for init scan") # Geofence results. if geofence_helper is not None and geofence_helper.is_enabled(): results = geofence_helper.get_geofenced_coordinates(results) if not results: logger.error( 'No cells regarded as valid for desired scan area. ' 'Check your provided geofences. Aborting.') else: logger.info("Ordering location") results = S2Helper.order_location_list_rows(results) return results