Exemplo n.º 1
0
def manager_thread():
  # now loop
  thermal_sock = messaging.sub_sock('thermal')

  cloudlog.info("manager start")
  cloudlog.info({"environ": os.environ})

  # save boot log
  subprocess.call(["./loggerd", "--bootlog"], cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))

  params = Params()

  # start daemon processes
  for p in daemon_processes:
    start_daemon_process(p)

  # start persistent processes
  for p in persistent_processes:
    start_managed_process(p)

  # start frame
  pm_apply_packages('enable')
  start_frame()

  if os.getenv("NOBOARD") is None:
    start_managed_process("pandad")

  logger_dead = False

  while 1:
    msg = messaging.recv_sock(thermal_sock, wait=True)

    # uploader is gated based on the phone temperature
    if msg.thermal.thermalStatus >= ThermalStatus.yellow:
      kill_managed_process("uploader")
    else:
      start_managed_process("uploader")

    if msg.thermal.freeSpace < 0.05:
      logger_dead = True

    if msg.thermal.started:
      for p in car_started_processes:
        if p == "loggerd" and logger_dead:
          kill_managed_process(p)
        else:
          start_managed_process(p)
    else:
      logger_dead = False
      for p in reversed(car_started_processes):
        kill_managed_process(p)

    # check the status of all processes, did any of them die?
    running_list = ["%s%s\u001b[0m" % ("\u001b[32m" if running[p].is_alive() else "\u001b[31m", p) for p in running]
    cloudlog.debug(' '.join(running_list))

    # Exit main loop when uninstall is needed
    if params.get("DoUninstall", encoding='utf8') == "1":
      break
Exemplo n.º 2
0
def manager_thread():
    cloudlog.info("manager start")
    cloudlog.info({"environ": os.environ})

    # save boot log
    subprocess.call("./bootlog",
                    cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))

    params = Params()

    ignore = []
    if os.getenv("NOBOARD") is not None:
        ignore.append("pandad")
    if os.getenv("BLOCK") is not None:
        ignore += os.getenv("BLOCK").split(",")

    ensure_running(managed_processes.values(), started=False, not_run=ignore)

    started_prev = False
    sm = messaging.SubMaster(['deviceState'])
    pm = messaging.PubMaster(['managerState'])

    while True:
        sm.update()
        not_run = ignore[:]

        if sm['deviceState'].freeSpacePercent < 5:
            not_run.append("loggerd")

        started = sm['deviceState'].started
        driverview = params.get_bool("IsDriverViewEnabled")
        ensure_running(managed_processes.values(), started, driverview,
                       not_run)

        # trigger an update after going offroad
        if started_prev and not started and 'updated' in managed_processes:
            os.sync()
            managed_processes['updated'].signal(signal.SIGHUP)

        started_prev = started

        running_list = [
            "%s%s\u001b[0m" %
            ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
            for p in managed_processes.values() if p.proc
        ]
        cloudlog.debug(' '.join(running_list))

        # send managerState
        msg = messaging.new_message('managerState')
        msg.managerState.processes = [
            p.get_process_state_msg() for p in managed_processes.values()
        ]
        pm.send('managerState', msg)

        # TODO: let UI handle this
        # Exit main loop when uninstall is needed
        if params.get_bool("DoUninstall"):
            break
Exemplo n.º 3
0
    def upload(self, key, fn):
        try:
            sz = os.path.getsize(fn)
        except OSError:
            cloudlog.exception("upload: getsize failed")
            return False

        cloudlog.event("upload", key=key, fn=fn, sz=sz)

        cloudlog.debug("checking %r with size %r", key, sz)

        if sz == 0:
            try:
                # tag files of 0 size as uploaded
                setxattr(fn, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE)
            except OSError:
                cloudlog.event("uploader_setxattr_failed",
                               exc=self.last_exc,
                               key=key,
                               fn=fn,
                               sz=sz)
            success = True
        else:
            start_time = time.monotonic()
            cloudlog.debug("uploading %r", fn)
            stat = self.normal_upload(key, fn)
            if stat is not None and stat.status_code in (200, 201, 403, 412):
                cloudlog.event("upload_success" if stat.status_code != 412 else
                               "upload_ignored",
                               key=key,
                               fn=fn,
                               sz=sz,
                               debug=True)
                try:
                    # tag file as uploaded
                    setxattr(fn, UPLOAD_ATTR_NAME, UPLOAD_ATTR_VALUE)
                except OSError:
                    cloudlog.event("uploader_setxattr_failed",
                                   exc=self.last_exc,
                                   key=key,
                                   fn=fn,
                                   sz=sz)

                self.last_filename = fn
                self.last_time = time.monotonic() - start_time
                self.last_speed = (sz / 1e6) / self.last_time
                success = True
            else:
                cloudlog.event("upload_failed",
                               stat=stat,
                               exc=self.last_exc,
                               key=key,
                               fn=fn,
                               sz=sz,
                               debug=True)
                success = False

        return success
Exemplo n.º 4
0
def manager_thread():
  cloudlog.info("manager start")
  cloudlog.info({"environ": os.environ})

  params = Params()

  ignore = []
  if params.get("DongleId", encoding='utf8') == UNREGISTERED_DONGLE_ID:
    ignore += ["manage_athenad", "uploader"]
  if os.getenv("NOBOARD") is not None:
    ignore.append("pandad")
  if os.getenv("BLOCK") is not None:
    ignore += os.getenv("BLOCK").split(",")

  ensure_running(managed_processes.values(), started=False, not_run=ignore)

  started_prev = False
  sm = messaging.SubMaster(['deviceState'])
  pm = messaging.PubMaster(['managerState'])

  while True:
    sm.update()
    not_run = ignore[:]

    if sm['deviceState'].freeSpacePercent < 5:
      not_run.append("loggerd")

    started = sm['deviceState'].started
    driverview = params.get_bool("IsDriverViewEnabled")
    ensure_running(managed_processes.values(), started, driverview, not_run)

    # trigger an update after going offroad
    if started_prev and not started and 'updated' in managed_processes:
      os.sync()
      managed_processes['updated'].signal(signal.SIGHUP)

    started_prev = started

    running = ' '.join(["%s%s\u001b[0m" % ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
                       for p in managed_processes.values() if p.proc])
    print(running)
    cloudlog.debug(running)

    # send managerState
    msg = messaging.new_message('managerState')
    msg.managerState.processes = [p.get_process_state_msg() for p in managed_processes.values()]
    pm.send('managerState', msg)

    # Exit main loop when uninstall/shutdown/reboot is needed
    shutdown = False
    for param in ("DoUninstall", "DoShutdown", "DoReboot"):
      if params.get_bool(param):
        cloudlog.warning(f"Shutting down manager - {param} set")
        shutdown = True

    if shutdown:
      break
Exemplo n.º 5
0
def manager_thread():
    # now loop
    context = zmq.Context()
    thermal_sock = messaging.sub_sock(context, service_list['thermal'].port)

    cloudlog.info("manager start")
    cloudlog.info({"environ": os.environ})

    # save boot log
    subprocess.call(["./loggerd", "--bootlog"],
                    cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))

    for p in persistent_processes:
        start_managed_process(p)

    # start frame
    pm_apply_packages('enable')
    system("am start -n ai.comma.plus.frame/.MainActivity")

    if os.getenv("NOBOARD") is None:
        start_managed_process("pandad")

    params = Params()
    logger_dead = False

    while 1:
        # get health of board, log this in "thermal"
        msg = messaging.recv_sock(thermal_sock, wait=True)

        # uploader is gated based on the phone temperature
        if msg.thermal.thermalStatus >= ThermalStatus.yellow:
            kill_managed_process("uploader")
        else:
            start_managed_process("uploader")

        if msg.thermal.freeSpace < 0.05:
            logger_dead = True

        if msg.thermal.started:
            for p in car_started_processes:
                if p == "loggerd" and logger_dead:
                    kill_managed_process(p)
                else:
                    start_managed_process(p)
        else:
            logger_dead = False
            for p in car_started_processes:
                kill_managed_process(p)

        # check the status of all processes, did any of them die?
        for p in running:
            cloudlog.debug("   running %s %s" % (p, running[p]))

        # is this still needed?
        if params.get("DoUninstall") == "1":
            break
Exemplo n.º 6
0
    def __init__(self, CP, CarController, CarState):
        super().__init__(CP, CarController, CarState)

        cloudlog.debug("Using Mock Car Interface")

        self.sensor = messaging.sub_sock('sensorEvents')
        self.gps = messaging.sub_sock('gpsLocationExternal')

        self.speed = 0.
        self.prev_speed = 0.
        self.yaw_rate = 0.
        self.yaw_rate_meas = 0.
Exemplo n.º 7
0
def uploader_fn(exit_event):
    params = Params()
    dongle_id = params.get("DongleId", encoding='utf8')

    if dongle_id is None:
        cloudlog.info("uploader missing dongle_id")
        raise Exception("uploader can't start without dongle id")

    if TICI and not Path("/data/media").is_mount():
        cloudlog.warning("NVME not mounted")

    sm = messaging.SubMaster(['deviceState'])
    pm = messaging.PubMaster(['uploaderState'])
    uploader = Uploader(dongle_id, ROOT)

    backoff = 0.1
    while not exit_event.is_set():
        sm.update(0)
        offroad = params.get_bool("IsOffroad")
        network_type = sm[
            'deviceState'].networkType if not force_wifi else NetworkType.wifi
        if network_type == NetworkType.none:
            if allow_sleep:
                time.sleep(60 if offroad else 5)
            continue

        good_internet = network_type in [
            NetworkType.wifi, NetworkType.ethernet
        ]
        allow_raw_upload = params.get_bool("UploadRaw")

        d = uploader.next_file_to_upload(
            with_raw=allow_raw_upload and good_internet and offroad)
        if d is None:  # Nothing to upload
            if allow_sleep:
                time.sleep(60 if offroad else 5)
            continue

        key, fn = d

        cloudlog.debug("upload %r over %s", d, network_type)
        success = uploader.upload(key, fn)
        if success:
            backoff = 0.1
        elif allow_sleep:
            cloudlog.info("upload backoff %r", backoff)
            time.sleep(backoff + random.uniform(0, backoff))
            backoff = min(backoff * 2, 120)

        pm.send("uploaderState", uploader.get_msg())
        cloudlog.info("upload done, success=%r", success)
Exemplo n.º 8
0
  def __init__(self, CP, CarController, CarState):
    self.CP = CP
    self.CC = CarController

    cloudlog.debug("Using Mock Car Interface")

    # TODO: subscribe to phone sensor
    self.sensor = messaging.sub_sock('sensorEvents')
    self.gps = messaging.sub_sock('gpsLocation')

    self.speed = 0.
    self.prev_speed = 0.
    self.yaw_rate = 0.
    self.yaw_rate_meas = 0.
Exemplo n.º 9
0
  def __init__(self, CP, sendcan=None):

    self.CP = CP

    cloudlog.debug("Using Mock Car Interface")
    context = zmq.Context()

    # TODO: subscribe to phone sensor
    self.sensor = messaging.sub_sock(context, service_list['sensorEvents'].port)
    self.gps = messaging.sub_sock(context, service_list['gpsLocation'].port)

    self.speed = 0.
    self.prev_speed = 0.
    self.yaw_rate = 0.
    self.yaw_rate_meas = 0.
Exemplo n.º 10
0
def manager_thread() -> None:

  Process(name="road_speed_limiter", target=launcher, args=("selfdrive.road_speed_limiter", "road_speed_limiter")).start()
  cloudlog.bind(daemon="manager")
  cloudlog.info("manager start")
  cloudlog.info({"environ": os.environ})

  params = Params()

  ignore: List[str] = []
  if params.get("DongleId", encoding='utf8') in (None, UNREGISTERED_DONGLE_ID):
    ignore += ["manage_athenad", "uploader"]
  if os.getenv("NOBOARD") is not None:
    ignore.append("pandad")
  ignore += [x for x in os.getenv("BLOCK", "").split(",") if len(x) > 0]

  ensure_running(managed_processes.values(), started=False, not_run=ignore)

  sm = messaging.SubMaster(['deviceState', 'carParams'], poll=['deviceState'])
  pm = messaging.PubMaster(['managerState'])

  while True:
    sm.update()

    started = sm['deviceState'].started
    driverview = params.get_bool("IsDriverViewEnabled")
    ensure_running(managed_processes.values(), started=started, driverview=driverview, notcar=sm['carParams'].notCar, not_run=ignore)

    running = ' '.join("%s%s\u001b[0m" % ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
                       for p in managed_processes.values() if p.proc)
    print(running)
    cloudlog.debug(running)

    # send managerState
    msg = messaging.new_message('managerState')
    msg.managerState.processes = [p.get_process_state_msg() for p in managed_processes.values()]
    pm.send('managerState', msg)

    # Exit main loop when uninstall/shutdown/reboot is needed
    shutdown = False
    for param in ("DoUninstall", "DoShutdown", "DoReboot"):
      if params.get_bool(param):
        shutdown = True
        params.put("LastManagerExitReason", param)
        cloudlog.warning(f"Shutting down manager - {param} set")

    if shutdown:
      break
Exemplo n.º 11
0
    def __init__(self, CP, CarController):

        self.CP = CP
        self.CC = CarController

        cloudlog.debug("Using Mock Car Interface")

        # TODO: subscribe to phone sensor
        self.sensor = messaging.sub_sock(service_list['sensorEvents'].port)
        self.gps = messaging.sub_sock(service_list['gpsLocation'].port)

        self.speed = 0.
        self.prev_speed = 0.
        self.yaw_rate = 0.
        self.yaw_rate_meas = 0.

        self.rk = Ratekeeper(100, print_delay_threshold=2. / 1000)
Exemplo n.º 12
0
def ws_proxy_recv(ws, local_sock, ssock, end_event, global_end_event):
    while not (end_event.is_set() or global_end_event.is_set()):
        try:
            data = ws.recv()
            local_sock.sendall(data)
        except WebSocketTimeoutException:
            pass
        except Exception:
            cloudlog.exception("athenad.ws_proxy_recv.exception")
            break

    cloudlog.debug("athena.ws_proxy_recv closing sockets")
    ssock.close()
    local_sock.close()
    cloudlog.debug("athena.ws_proxy_recv done closing sockets")

    end_event.set()
Exemplo n.º 13
0
def jsonrpc_handler(end_event):
    dispatcher["startLocalProxy"] = partial(startLocalProxy, end_event)
    while not end_event.is_set():
        try:
            data = recv_queue.get(timeout=1)
            if "method" in data:
                cloudlog.debug(f"athena.jsonrpc_handler.call_method {data}")
                response = JSONRPCResponseManager.handle(data, dispatcher)
                send_queue.put_nowait(response.json)
            elif "id" in data and ("result" in data or "error" in data):
                log_recv_queue.put_nowait(data)
            else:
                raise Exception("not a valid request or response")
        except queue.Empty:
            pass
        except Exception as e:
            cloudlog.exception("athena jsonrpc handler failed")
            send_queue.put_nowait(json.dumps({"error": str(e)}))
Exemplo n.º 14
0
def uploader_fn(exit_event):
    cloudlog.info("uploader_fn")

    params = Params()
    dongle_id = params.get("DongleId").decode('utf8')

    if dongle_id is None:
        cloudlog.info("uploader missing dongle_id")
        raise Exception("uploader can't start without dongle id")

    if TICI and not Path("/data/media").is_mount():
        cloudlog.debug("NVME not mounted")

    sm = messaging.SubMaster(['deviceState'])
    uploader = Uploader(dongle_id, ROOT)

    backoff = 0.1
    while not exit_event.is_set():
        sm.update(0)
        on_wifi = force_wifi or sm[
            'deviceState'].networkType == NetworkType.wifi
        offroad = params.get("IsOffroad") == b'1'
        allow_raw_upload = params.get("IsUploadRawEnabled") != b"0"

        d = uploader.next_file_to_upload(
            with_raw=allow_raw_upload and on_wifi and offroad)
        if d is None:  # Nothing to upload
            if allow_sleep:
                time.sleep(60 if offroad else 5)
            continue

        key, fn = d

        cloudlog.event("uploader_netcheck", is_on_wifi=on_wifi)
        cloudlog.info("to upload %r", d)
        success = uploader.upload(key, fn)
        if success:
            backoff = 0.1
        elif allow_sleep:
            cloudlog.info("backoff %r", backoff)
            time.sleep(backoff + random.uniform(0, backoff))
            backoff = min(backoff * 2, 120)
        cloudlog.info("upload done, success=%r", success)
Exemplo n.º 15
0
def set_timezone(valid_timezones, timezone):
    if timezone not in valid_timezones:
        cloudlog.error(f"Timezone not supported {timezone}")
        return

    cloudlog.debug(f"Setting timezone to {timezone}")
    try:
        if TICI:
            tzpath = os.path.join("/usr/share/zoneinfo/", timezone)
            subprocess.check_call(
                f'sudo su -c "ln -snf {tzpath} /data/etc/tmptime && \
                              mv /data/etc/tmptime /data/etc/localtime"',
                shell=True)
            subprocess.check_call(
                f'sudo su -c "echo \"{timezone}\" > /data/etc/timezone"',
                shell=True)
        else:
            subprocess.check_call(f'sudo timedatectl set-timezone {timezone}',
                                  shell=True)
    except subprocess.CalledProcessError:
        cloudlog.exception(f"Error setting timezone to {timezone}")
Exemplo n.º 16
0
    def do_upload(self, key, fn):
        try:
            url_resp = self.api.get("v1.4/" + self.dongle_id + "/upload_url/",
                                    timeout=10,
                                    path=key,
                                    access_token=self.api.get_token())
            if url_resp.status_code == 412:
                self.last_resp = url_resp
                return

            url_resp_json = json.loads(url_resp.text)
            url = url_resp_json['url']
            headers = url_resp_json['headers']
            cloudlog.debug("upload_url v1.4 %s %s", url, str(headers))

            if fake_upload:
                cloudlog.debug(
                    f"*** WARNING, THIS IS A FAKE UPLOAD TO {url} ***")

                class FakeResponse():
                    def __init__(self):
                        self.status_code = 200

                self.last_resp = FakeResponse()
            else:
                with open(fn, "rb") as f:
                    if key.endswith('.bz2') and not fn.endswith('.bz2'):
                        data = bz2.compress(f.read())
                        data = io.BytesIO(data)
                    else:
                        data = f

                    self.last_resp = requests.put(url,
                                                  data=data,
                                                  headers=headers,
                                                  timeout=10)
        except Exception as e:
            self.last_exc = (e, traceback.format_exc())
            raise
Exemplo n.º 17
0
def ws_proxy_send(ws, local_sock, signal_sock, end_event):
    while not end_event.is_set():
        try:
            r, _, _ = select.select((local_sock, signal_sock), (), ())
            if r:
                if r[0].fileno() == signal_sock.fileno():
                    # got end signal from ws_proxy_recv
                    end_event.set()
                    break
                data = local_sock.recv(4096)
                if not data:
                    # local_sock is dead
                    end_event.set()
                    break

                ws.send(data, ABNF.OPCODE_BINARY)
        except Exception:
            cloudlog.exception("athenad.ws_proxy_send.exception")
            end_event.set()

    cloudlog.debug("athena.ws_proxy_send closing sockets")
    signal_sock.close()
    cloudlog.debug("athena.ws_proxy_send done closing sockets")
Exemplo n.º 18
0
def main() -> NoReturn:
    params = Params()
    tf = TimezoneFinder()

    # Get allowed timezones
    valid_timezones = subprocess.check_output(
        'timedatectl list-timezones', shell=True,
        encoding='utf8').strip().split('\n')

    while True:
        time.sleep(60)

        is_onroad = not params.get_bool("IsOffroad")
        if is_onroad:
            continue

        # Set based on param
        timezone = params.get("Timezone", encoding='utf8')
        if timezone is not None:
            cloudlog.debug("Setting timezone based on param")
            set_timezone(valid_timezones, timezone)
            continue

        location = params.get("LastGPSPosition", encoding='utf8')

        # Find timezone based on IP geolocation if no gps location is available
        if location is None:
            cloudlog.debug("Setting timezone based on IP lookup")
            try:
                r = requests.get("https://ipapi.co/timezone", timeout=10)
                if r.status_code == 200:
                    set_timezone(valid_timezones, r.text)
                else:
                    cloudlog.error(
                        f"Unexpected status code from api {r.status_code}")

                time.sleep(3600)  # Don't make too many API requests
            except requests.exceptions.RequestException:
                cloudlog.exception("Error getting timezone based on IP")
                continue

        # Find timezone by reverse geocoding the last known gps location
        else:
            cloudlog.debug("Setting timezone based on GPS location")
            try:
                location = json.loads(location)
            except Exception:
                cloudlog.exception("Error parsing location")
                continue

            timezone = tf.timezone_at(lng=location['longitude'],
                                      lat=location['latitude'])
            if timezone is None:
                cloudlog.error(
                    f"No timezone found based on location, {location}")
                continue
            set_timezone(valid_timezones, timezone)
Exemplo n.º 19
0
    def __init__(self, CP, CarController, CarState):
        self.CP = CP
        self.CC = CarController

        cloudlog.debug("Using Mock Car Interface")

        # TODO: subscribe to phone sensor
        self.sensor = messaging.sub_sock('sensorEvents')
        self.gps = messaging.sub_sock('gpsLocation')

        self.speed = 0.
        self.prev_speed = 0.
        self.yaw_rate = 0.
        self.yaw_rate_meas = 0.

        # dp
        # mock override constructor so we need to define here as well.
        self.dragon_toyota_stock_dsu = False
        self.dragon_enable_steering_on_signal = False
        self.dragon_allow_gas = False
        self.ts_last_check = 0.
        self.dragon_lat_ctrl = True
        self.dp_last_modified = None
        self.dp_gear_check = True
Exemplo n.º 20
0
def manager_thread():

  cloudlog.info("manager start")
  cloudlog.info({"environ": os.environ})

  # save boot log
  subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))

  # start daemon processes
  for p in daemon_processes:
    start_daemon_process(p)

  # start persistent processes
  for p in persistent_processes:
    start_managed_process(p)

  # start offroad
  if EON:
    pm_apply_packages('enable')
    start_offroad()

  if os.getenv("NOBOARD") is not None:
    del managed_processes["pandad"]

  if os.getenv("BLOCK") is not None:
    for k in os.getenv("BLOCK").split(","):
      del managed_processes[k]

  started_prev = False
  logger_dead = False
  params = Params()
  device_state_sock = messaging.sub_sock('deviceState')
  pm = messaging.PubMaster(['managerState'])

  while 1:
    msg = messaging.recv_sock(device_state_sock, wait=True)

    if msg.deviceState.freeSpacePercent < 5:
      logger_dead = True

    if msg.deviceState.started:
      for p in car_started_processes:
        if p == "loggerd" and logger_dead:
          kill_managed_process(p)
        else:
          start_managed_process(p)
    else:
      logger_dead = False
      driver_view = params.get("IsDriverViewEnabled") == b"1"

      # TODO: refactor how manager manages processes
      for p in reversed(car_started_processes):
        if p not in driver_view_processes or not driver_view:
          kill_managed_process(p)

      for p in driver_view_processes:
        if driver_view:
          start_managed_process(p)
        else:
          kill_managed_process(p)

      # trigger an update after going offroad
      if started_prev:
        os.sync()
        send_managed_process_signal("updated", signal.SIGHUP)

    started_prev = msg.deviceState.started

    # check the status of all processes, did any of them die?
    running_list = ["%s%s\u001b[0m" % ("\u001b[32m" if running[p].is_alive() else "\u001b[31m", p) for p in running]
    cloudlog.debug(' '.join(running_list))

    # send managerState
    states = []
    for p in managed_processes:
      state = log.ManagerState.ProcessState.new_message()
      state.name = p
      if p in running:
        state.running = running[p].is_alive()
        state.pid = running[p].pid
        state.exitCode = running[p].exitcode or 0
      states.append(state)
    msg = messaging.new_message('managerState')
    msg.managerState.processes = states
    pm.send('managerState', msg)

    # Exit main loop when uninstall is needed
    if params.get("DoUninstall", encoding='utf8') == "1":
      break
Exemplo n.º 21
0
def manager_thread():
    # now loop
    thermal_sock = messaging.sub_sock('thermal')

    if os.getenv("GET_CPU_USAGE"):
        proc_sock = messaging.sub_sock('procLog', conflate=True)

    cloudlog.info("manager start")
    cloudlog.info({"environ": os.environ})

    # save boot log
    subprocess.call(["./loggerd", "--bootlog"],
                    cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))

    params = Params()

    # start daemon processes
    for p in daemon_processes:
        start_daemon_process(p)

    # start persistent processes
    for p in persistent_processes:
        start_managed_process(p)

    # start offroad
    if ANDROID:
        pm_apply_packages('enable')
        start_offroad()

    if os.getenv("NOBOARD") is None:
        start_managed_process("pandad")

    if os.getenv("BLOCK") is not None:
        for k in os.getenv("BLOCK").split(","):
            del managed_processes[k]

    logger_dead = False

    start_t = time.time()
    first_proc = None

    while 1:
        msg = messaging.recv_sock(thermal_sock, wait=True)

        # heavyweight batch processes are gated on favorable thermal conditions
        if msg.thermal.thermalStatus >= ThermalStatus.yellow:
            for p in green_temp_processes:
                if p in persistent_processes:
                    kill_managed_process(p)
        else:
            for p in green_temp_processes:
                if p in persistent_processes:
                    start_managed_process(p)

        if msg.thermal.freeSpace < 0.05:
            logger_dead = True

        if msg.thermal.started and "driverview" not in running:
            for p in car_started_processes:
                if p == "loggerd" and logger_dead:
                    kill_managed_process(p)
                else:
                    start_managed_process(p)
        else:
            logger_dead = False
            for p in reversed(car_started_processes):
                kill_managed_process(p)
            # this is ugly
            if "driverview" not in running and params.get(
                    "IsDriverViewEnabled") == b"1":
                start_managed_process("driverview")
            elif "driverview" in running and params.get(
                    "IsDriverViewEnabled") == b"0":
                kill_managed_process("driverview")

        # check the status of all processes, did any of them die?
        running_list = [
            "%s%s\u001b[0m" %
            ("\u001b[32m" if running[p].is_alive() else "\u001b[31m", p)
            for p in running
        ]
        cloudlog.debug(' '.join(running_list))

        # Exit main loop when uninstall is needed
        if params.get("DoUninstall", encoding='utf8') == "1":
            break

        if os.getenv("GET_CPU_USAGE"):
            dt = time.time() - start_t

            # Get first sample
            if dt > 30 and first_proc is None:
                first_proc = messaging.recv_sock(proc_sock)

            # Get last sample and exit
            if dt > 90:
                last_proc = messaging.recv_sock(proc_sock, wait=True)

                cleanup_all_processes(None, None)
                sys.exit(print_cpu_usage(first_proc, last_proc))
Exemplo n.º 22
0
def manager_thread():
    cloudlog.info("manager start")
    cloudlog.info({"environ": os.environ})

    params = Params()

    dp_reg = params.get_bool('dp_reg')
    dp_logger = params.get_bool('dp_logger')
    dp_athenad = params.get_bool('dp_athenad')
    dp_uploader = params.get_bool('dp_uploader')
    dp_atl = params.get_bool('dp_atl')
    dp_jetson = params.get_bool('dp_jetson')
    dp_otisserv = params.get_bool('dp_otisserv')
    dp_mapd = params.get_bool('dp_mapd')
    if not dp_reg:
        dp_athenad = False
        dp_uploader = False
    # save boot log
    if dp_logger:
        subprocess.call("./bootlog",
                        cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))

    ignore = []
    if dp_jetson:
        ignore += ['dmonitoringmodeld', 'dmonitoringd']
    if not params.get_bool('dp_dashcamd'):
        ignore += ['dashcamd']
    if not params.get_bool('dp_updated'):
        ignore += ['updated']
    if not dp_logger:
        ignore += [
            'logcatd', 'loggerd', 'proclogd', 'logmessaged', 'tombstoned'
        ]
    if not dp_athenad:
        ignore += ['manage_athenad']
    if not dp_athenad and not dp_uploader:
        ignore += ['deleter']
    if not dp_mapd:
        ignore += ['mapd']
    if not dp_otisserv:
        ignore += ['otisserv']
    if not dp_mapd and not dp_otisserv and not params.get_bool('dp_gpxd'):
        ignore += ['gpxd']
    if params.get("DongleId", encoding='utf8') == UNREGISTERED_DONGLE_ID:
        ignore += ["manage_athenad", "uploader"]
    if os.getenv("NOBOARD") is not None:
        ignore.append("pandad")
    if os.getenv("BLOCK") is not None:
        ignore += os.getenv("BLOCK").split(",")

    ensure_running(managed_processes.values(), started=False, not_run=ignore)

    started_prev = False
    sm = messaging.SubMaster(['deviceState'])
    pm = messaging.PubMaster(['managerState'])

    while True:
        sm.update()
        not_run = ignore[:]

        if sm['deviceState'].freeSpacePercent < 5:
            not_run.append("loggerd")

        started = sm['deviceState'].started
        driverview = params.get_bool("IsDriverViewEnabled")
        ensure_running(managed_processes.values(), started, driverview,
                       not_run)

        # trigger an update after going offroad
        if started_prev and not started and 'updated' in managed_processes:
            os.sync()
            managed_processes['updated'].signal(signal.SIGHUP)

        started_prev = started

        running_list = [
            "%s%s\u001b[0m" %
            ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
            for p in managed_processes.values() if p.proc
        ]
        cloudlog.debug(' '.join(running_list))

        # send managerState
        msg = messaging.new_message('managerState')
        msg.managerState.processes = [
            p.get_process_state_msg() for p in managed_processes.values()
        ]
        pm.send('managerState', msg)

        # TODO: let UI handle this
        # Exit main loop when uninstall is needed
        if params.get_bool("DoUninstall"):
            break
Exemplo n.º 23
0
def manager_thread(spinner=None):
    shutdownd = Process(name="shutdownd",
                        target=launcher,
                        args=("selfdrive.shutdownd", ))
    shutdownd.start()

    if EON:
        pm_grant("com.neokii.openpilot",
                 "android.permission.ACCESS_FINE_LOCATION")
        appops_set("com.neokii.optool", "SU", "allow")
        system("am startservice com.neokii.optool/.MainService")
        system("am startservice com.neokii.openpilot/.MainService")

    cloudlog.info("manager start")
    cloudlog.info({"environ": os.environ})

    # save boot log
    #subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))

    ignore = []
    if os.getenv("NOBOARD") is not None:
        ignore.append("pandad")
    if os.getenv("BLOCK") is not None:
        ignore += os.getenv("BLOCK").split(",")

    # start offroad
    if EON and "QT" not in os.environ:
        pm_apply_packages('enable')
        start_offroad()

    ensure_running(managed_processes.values(), started=False, not_run=ignore)
    if spinner:  # close spinner when ui has started
        spinner.close()

    started_prev = False
    params = Params()
    sm = messaging.SubMaster(['deviceState'])
    pm = messaging.PubMaster(['managerState'])

    while True:
        sm.update()
        not_run = ignore[:]

        if sm['deviceState'].freeSpacePercent < 5:
            not_run.append("loggerd")

        started = sm['deviceState'].started
        driverview = params.get("IsDriverViewEnabled") == b"1"
        ensure_running(managed_processes.values(), started, driverview,
                       not_run)

        # trigger an update after going offroad
        if started_prev and not started and 'updated' in managed_processes:
            os.sync()
            managed_processes['updated'].signal(signal.SIGHUP)

        started_prev = started

        running_list = [
            "%s%s\u001b[0m" %
            ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
            for p in managed_processes.values() if p.proc
        ]
        cloudlog.debug(' '.join(running_list))

        # send managerState
        msg = messaging.new_message('managerState')
        msg.managerState.processes = [
            p.get_process_state_msg() for p in managed_processes.values()
        ]
        pm.send('managerState', msg)

        # Exit main loop when uninstall is needed
        if params.get("DoUninstall", encoding='utf8') == "1":
            break
Exemplo n.º 24
0
def manager_thread():

    if EON:
        Process(name="shutdownd",
                target=launcher,
                args=("selfdrive.shutdownd", )).start()
        system("am startservice com.neokii.optool/.MainService")

    Process(name="road_speed_limiter",
            target=launcher,
            args=("selfdrive.road_speed_limiter", )).start()

    cloudlog.info("manager start")
    cloudlog.info({"environ": os.environ})

    # save boot log
    #subprocess.call("./bootlog", cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))

    params = Params()

    ignore = []
    if params.get("DongleId", encoding='utf8') == UNREGISTERED_DONGLE_ID:
        ignore += ["manage_athenad", "uploader"]
    if os.getenv("NOBOARD") is not None:
        ignore.append("pandad")
    if os.getenv("BLOCK") is not None:
        ignore += os.getenv("BLOCK").split(",")

    ensure_running(managed_processes.values(), started=False, not_run=ignore)

    started_prev = False
    sm = messaging.SubMaster(['deviceState'])
    pm = messaging.PubMaster(['managerState'])

    while True:
        sm.update()
        not_run = ignore[:]

        if sm['deviceState'].freeSpacePercent < 5:
            not_run.append("loggerd")

        started = sm['deviceState'].started
        driverview = params.get_bool("IsDriverViewEnabled")
        ensure_running(managed_processes.values(), started, driverview,
                       not_run)

        # trigger an update after going offroad
        if started_prev and not started and 'updated' in managed_processes:
            os.sync()
            managed_processes['updated'].signal(signal.SIGHUP)

        started_prev = started

        running_list = [
            "%s%s\u001b[0m" %
            ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
            for p in managed_processes.values() if p.proc
        ]
        cloudlog.debug(' '.join(running_list))

        # send managerState
        msg = messaging.new_message('managerState')
        msg.managerState.processes = [
            p.get_process_state_msg() for p in managed_processes.values()
        ]
        pm.send('managerState', msg)

        # TODO: let UI handle this
        # Exit main loop when uninstall is needed
        if params.get_bool("DoUninstall"):
            break
Exemplo n.º 25
0
def log_handler(end_event):
    if PC:
        return

    log_files = []
    last_scan = 0
    while not end_event.is_set():
        try:
            curr_scan = sec_since_boot()
            if curr_scan - last_scan > 10:
                log_files = get_logs_to_send_sorted()
                last_scan = curr_scan

            # send one log
            curr_log = None
            if len(log_files) > 0:
                log_entry = log_files.pop()
                cloudlog.debug(
                    f"athena.log_handler.forward_request {log_entry}")
                try:
                    curr_time = int(time.time())
                    log_path = os.path.join(SWAGLOG_DIR, log_entry)
                    setxattr(log_path, LOG_ATTR_NAME,
                             int.to_bytes(curr_time, 4, sys.byteorder))
                    with open(log_path, "r") as f:
                        jsonrpc = {
                            "method": "forwardLogs",
                            "params": {
                                "logs": f.read()
                            },
                            "jsonrpc": "2.0",
                            "id": log_entry
                        }
                        log_send_queue.put_nowait(json.dumps(jsonrpc))
                        curr_log = log_entry
                except OSError:
                    pass  # file could be deleted by log rotation

            # wait for response up to ~100 seconds
            # always read queue at least once to process any old responses that arrive
            for _ in range(100):
                if end_event.is_set():
                    break
                try:
                    log_resp = json.loads(log_recv_queue.get(timeout=1))
                    log_entry = log_resp.get("id")
                    log_success = "result" in log_resp and log_resp[
                        "result"].get("success")
                    cloudlog.debug(
                        f"athena.log_handler.forward_response {log_entry} {log_success}"
                    )
                    if log_entry and log_success:
                        log_path = os.path.join(SWAGLOG_DIR, log_entry)
                        try:
                            setxattr(log_path, LOG_ATTR_NAME,
                                     LOG_ATTR_VALUE_MAX_UNIX_TIME)
                        except OSError:
                            pass  # file could be deleted by log rotation
                    if curr_log == log_entry:
                        break
                except queue.Empty:
                    if curr_log is None:
                        break

        except Exception:
            cloudlog.exception("athena.log_handler.exception")
Exemplo n.º 26
0
def uploader_fn(exit_event):
    params = Params()
    dongle_id = params.get("DongleId", encoding='utf8')

    transition_to_offroad_last = 0.
    disable_onroad_upload_offroad_transition_timeout = 900.  # wait until offroad for 15 minutes before starting uploads
    offroad_last = params.get_bool("IsOffroad")

    if dongle_id is None:
        cloudlog.info("uploader missing dongle_id")
        raise Exception("uploader can't start without dongle id")

    if TICI and not Path("/data/media").is_mount():
        cloudlog.warning("NVME not mounted")

    sm = messaging.SubMaster(['deviceState'])
    pm = messaging.PubMaster(['uploaderState'])
    uploader = Uploader(dongle_id, ROOT)

    backoff = 0.1
    while not exit_event.is_set():
        sm.update(0)

        offroad = params.get_bool("IsOffroad")
        t = sec_since_boot()
        if offroad and not offroad_last and t > 300.:
            transition_to_offroad_last = sec_since_boot()
        offroad_last = offroad

        network_type = sm[
            'deviceState'].networkType if not force_wifi else NetworkType.wifi
        if network_type == NetworkType.none:
            if allow_sleep:
                time.sleep(60 if offroad else 5)
            continue

        on_wifi = network_type == NetworkType.wifi
        allow_raw_upload = params.get_bool("UploadRaw")

        if Params().get_bool("DisableOnroadUploads"):
            if not offroad or (
                    transition_to_offroad_last > 0.
                    and t - transition_to_offroad_last <
                    disable_onroad_upload_offroad_transition_timeout):
                if not offroad:
                    cloudlog.info("not uploading: onroad uploads disabled")
                else:
                    wait_minutes = int(
                        disable_onroad_upload_offroad_transition_timeout / 60)
                    time_left = disable_onroad_upload_offroad_transition_timeout - (
                        t - transition_to_offroad_last)
                    if (time_left / 60. > 2.):
                        time_left_str = f"{int(time_left / 60)} minute(s)"
                    else:
                        time_left_str = f"{int(time_left)} seconds(s)"
                    cloudlog.info(
                        f"not uploading: waiting until offroad for {wait_minutes} minutes; {time_left_str} left"
                    )
                if allow_sleep:
                    time.sleep(60)
                continue

        d = uploader.next_file_to_upload(
            with_raw=allow_raw_upload and on_wifi and offroad)
        if d is None:  # Nothing to upload
            if allow_sleep:
                time.sleep(60 if offroad else 5)
            continue

        key, fn = d

        cloudlog.debug("upload %r over %s", d, network_type)
        success = uploader.upload(key, fn)
        if success:
            backoff = 0.1
        elif allow_sleep:
            cloudlog.info("upload backoff %r", backoff)
            time.sleep(backoff + random.uniform(0, backoff))
            backoff = min(backoff * 2, 120)

        pm.send("uploaderState", uploader.get_msg())
        cloudlog.info("upload done, success=%r", success)
Exemplo n.º 27
0
def manager_thread():
  global baseui_running

  # now loop
  context = zmq.Context()
  thermal_sock = messaging.pub_sock(context, service_list['thermal'].port)
  health_sock = messaging.sub_sock(context, service_list['health'].port)
  location_sock = messaging.sub_sock(context, service_list['gpsLocation'].port)

  cloudlog.info("manager start")
  cloudlog.info({"environ": os.environ})

  for p in persistent_processes:
    start_managed_process(p)

  manage_baseui(True)

  # do this before panda flashing
  setup_eon_fan()

  if os.getenv("NOBOARD") is None:
    start_managed_process("pandad")

  passive = bool(os.getenv("PASSIVE"))
  passive_starter = LocationStarter()

  started_ts = None
  logger_dead = False
  count = 0
  fan_speed = 0
  ignition_seen = False

  health_sock.RCVTIMEO = 1500

  while 1:
    # get health of board, log this in "thermal"
    td = messaging.recv_sock(health_sock, wait=True)
    location = messaging.recv_sock(location_sock)

    location = location.gpsLocation if location else None

    print td

    # replace thermald
    msg = read_thermal()

    # loggerd is gated based on free space
    statvfs = os.statvfs(ROOT)
    avail = (statvfs.f_bavail * 1.0)/statvfs.f_blocks

    # thermal message now also includes free space
    msg.thermal.freeSpace = avail
    with open("/sys/class/power_supply/battery/capacity") as f:
      msg.thermal.batteryPercent = int(f.read())
    with open("/sys/class/power_supply/battery/status") as f:
      msg.thermal.batteryStatus = f.read().strip()

    # TODO: add car battery voltage check
    max_temp = max(msg.thermal.cpu0, msg.thermal.cpu1,
                   msg.thermal.cpu2, msg.thermal.cpu3) / 10.0
    fan_speed = handle_fan(max_temp, fan_speed)
    msg.thermal.fanSpeed = fan_speed

    thermal_sock.send(msg.to_bytes())
    print msg

    # uploader is gated based on the phone temperature
    if max_temp > 85.0:
      cloudlog.warning("over temp: %r", max_temp)
      kill_managed_process("uploader")
    elif max_temp < 70.0:
      start_managed_process("uploader")

    if avail < 0.05:
      logger_dead = True

    # start constellation of processes when the car starts
    ignition = td is not None and td.health.started
    ignition_seen = ignition_seen or ignition

    params = Params()
    should_start = ignition and (params.get("HasAcceptedTerms") == "1")

    # start on gps in passive mode
    if passive and not ignition_seen:
      should_start = should_start or passive_starter.update(started_ts, location)

    # with 2% left, we killall, otherwise the phone is bricked
    should_start = should_start and avail > 0.02


    if should_start:
      if not started_ts:
        params.car_start()
        started_ts = sec_since_boot()
      for p in car_started_processes:
        if p == "loggerd" and logger_dead:
          kill_managed_process(p)
        else:
          start_managed_process(p)
      manage_baseui(False)
    else:
      manage_baseui(True)
      started_ts = None
      logger_dead = False
      for p in car_started_processes:
        kill_managed_process(p)

      # shutdown if the battery gets lower than 10%, we aren't running, and we are discharging
      if msg.thermal.batteryPercent < 5 and msg.thermal.batteryStatus == "Discharging":
        os.system('LD_LIBRARY_PATH="" svc power shutdown')

    # check the status of baseui
    baseui_running = 'com.baseui' in subprocess.check_output(["ps"])

    # check the status of all processes, did any of them die?
    for p in running:
      cloudlog.debug("   running %s %s" % (p, running[p]))

    # report to server once per minute
    if (count%60) == 0:
      cloudlog.event("STATUS_PACKET",
        running=running.keys(),
        count=count,
        health=(td.to_dict() if td else None),
        thermal=msg.to_dict())

    count += 1
Exemplo n.º 28
0
def manager_thread():
    # now loop
    thermal_sock = messaging.sub_sock('thermal')

    cloudlog.info("manager start")
    cloudlog.info({"environ": os.environ})

    params = Params()

    EnableLogger = int(params.get('OpkrEnableLogger'))

    #EnableLogger = (params.get("RecordFront") != b"0")

    if not EnableLogger:
        car_started_processes.remove('loggerd')
        persistent_processes.remove('logmessaged')
        persistent_processes.remove('uploader')
        persistent_processes.remove('logcatd')
        persistent_processes.remove('updated')
        persistent_processes.remove('deleter')
        persistent_processes.remove('tombstoned')
    else:
        # save boot log
        subprocess.call(["./loggerd", "--bootlog"],
                        cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))

    # start daemon processes
    for p in daemon_processes:
        start_daemon_process(p)

    # start persistent processes
    for p in persistent_processes:
        start_managed_process(p)

    # start offroad
    if ANDROID:
        pm_apply_packages('enable')
        start_offroad()

    if os.getenv("NOBOARD") is None:
        start_managed_process("pandad")

    if os.getenv("BLOCK") is not None:
        for k in os.getenv("BLOCK").split(","):
            del managed_processes[k]

    logger_dead = False

    while 1:
        msg = messaging.recv_sock(thermal_sock, wait=True)

        # heavyweight batch processes are gated on favorable thermal conditions
        if msg.thermal.thermalStatus >= ThermalStatus.yellow:
            for p in green_temp_processes:
                if p in persistent_processes:
                    kill_managed_process(p)
        else:
            for p in green_temp_processes:
                if p in persistent_processes:
                    start_managed_process(p)

        if msg.thermal.freeSpace < 0.05:
            logger_dead = True

        if msg.thermal.started and "driverview" not in running:
            for p in car_started_processes:
                if p == "loggerd" and logger_dead:
                    kill_managed_process(p)
                else:
                    start_managed_process(p)
        else:
            logger_dead = False
            for p in reversed(car_started_processes):
                kill_managed_process(p)
            # this is ugly
            if "driverview" not in running and params.get(
                    "IsDriverViewEnabled") == b"1":
                start_managed_process("driverview")
            elif "driverview" in running and params.get(
                    "IsDriverViewEnabled") == b"0":
                kill_managed_process("driverview")

        # check the status of all processes, did any of them die?
        running_list = [
            "%s%s\u001b[0m" %
            ("\u001b[32m" if running[p].is_alive() else "\u001b[31m", p)
            for p in running
        ]
        cloudlog.debug(' '.join(running_list))

        # Exit main loop when uninstall is needed
        if params.get("DoUninstall", encoding='utf8') == "1":
            break
Exemplo n.º 29
0
def manager_thread():
    # now loop
    context = zmq.Context()
    thermal_sock = messaging.pub_sock(context, service_list['thermal'].port)
    health_sock = messaging.sub_sock(context, service_list['health'].port)
    location_sock = messaging.sub_sock(context,
                                       service_list['gpsLocation'].port)

    cloudlog.info("manager start")
    cloudlog.info({"environ": os.environ})

    for p in persistent_processes:
        start_managed_process(p)

    # start frame
    system("am start -n ai.comma.plus.frame/.MainActivity")

    # do this before panda flashing
    setup_eon_fan()

    if os.getenv("NOBOARD") is None:
        start_managed_process("pandad")

    params = Params()

    passive = params.get("Passive") == "1"
    passive_starter = LocationStarter()

    started_ts = None
    logger_dead = False
    count = 0
    fan_speed = 0
    ignition_seen = False
    battery_was_high = False

    health_sock.RCVTIMEO = 1500

    while 1:
        # get health of board, log this in "thermal"
        td = messaging.recv_sock(health_sock, wait=True)
        location = messaging.recv_sock(location_sock)

        location = location.gpsLocation if location else None

        print td

        # replace thermald
        msg = read_thermal()

        # loggerd is gated based on free space
        statvfs = os.statvfs(ROOT)
        avail = (statvfs.f_bavail * 1.0) / statvfs.f_blocks

        # thermal message now also includes free space
        msg.thermal.freeSpace = avail
        with open("/sys/class/power_supply/battery/capacity") as f:
            msg.thermal.batteryPercent = int(f.read())
        with open("/sys/class/power_supply/battery/status") as f:
            msg.thermal.batteryStatus = f.read().strip()
        with open("/sys/class/power_supply/usb/online") as f:
            msg.thermal.usbOnline = bool(int(f.read()))

        # TODO: add car battery voltage check
        max_temp = max(msg.thermal.cpu0, msg.thermal.cpu1, msg.thermal.cpu2,
                       msg.thermal.cpu3) / 10.0
        bat_temp = msg.thermal.bat / 1000.
        fan_speed = handle_fan(max_temp, bat_temp, fan_speed)
        msg.thermal.fanSpeed = fan_speed

        msg.thermal.started = started_ts is not None
        msg.thermal.startedTs = int(1e9 * (started_ts or 0))

        thermal_sock.send(msg.to_bytes())
        print msg

        # uploader is gated based on the phone temperature
        if max_temp > 85.0:
            cloudlog.warning("over temp: %r", max_temp)
            kill_managed_process("uploader")
        elif max_temp < 70.0:
            start_managed_process("uploader")

        if avail < 0.05:
            logger_dead = True

        # start constellation of processes when the car starts
        ignition = td is not None and td.health.started
        ignition_seen = ignition_seen or ignition

        do_uninstall = params.get("DoUninstall") == "1"
        accepted_terms = params.get("HasAcceptedTerms") == "1"

        should_start = ignition

        # start on gps in passive mode
        if passive and not ignition_seen:
            should_start = should_start or passive_starter.update(
                started_ts, location)

        # with 2% left, we killall, otherwise the phone is bricked
        should_start = should_start and avail > 0.02

        # require usb power
        should_start = should_start and msg.thermal.usbOnline

        should_start = should_start and accepted_terms and (not do_uninstall)

        # if any CPU gets above 107 or the battery gets above 53, kill all processes
        # controls will warn with CPU above 95 or battery above 50
        if max_temp > 107.0 or msg.thermal.bat >= 53000:
            should_start = False

        if should_start:
            if not started_ts:
                params.car_start()
                started_ts = sec_since_boot()
            for p in car_started_processes:
                if p == "loggerd" and logger_dead:
                    kill_managed_process(p)
                else:
                    start_managed_process(p)
        else:
            started_ts = None
            logger_dead = False
            for p in car_started_processes:
                kill_managed_process(p)

            # shutdown if the battery gets lower than 5%, we aren't running, and we are discharging
            if msg.thermal.batteryPercent < 5 and msg.thermal.batteryStatus == "Discharging" and battery_was_high:
                os.system('LD_LIBRARY_PATH="" svc power shutdown')
            if msg.thermal.batteryPercent > 10:
                battery_was_high = True

        # check the status of all processes, did any of them die?
        for p in running:
            cloudlog.debug("   running %s %s" % (p, running[p]))

        # report to server once per minute
        if (count % 60) == 0:
            cloudlog.event("STATUS_PACKET",
                           running=running.keys(),
                           count=count,
                           health=(td.to_dict() if td else None),
                           thermal=msg.to_dict())

        if do_uninstall:
            break

        count += 1
Exemplo n.º 30
0
def manager_thread():
    # now loop
    thermal_sock = messaging.sub_sock('thermal')

    cloudlog.info("manager start")
    cloudlog.info({"environ": os.environ})

    # save boot log
    subprocess.call(["./loggerd", "--bootlog"],
                    cwd=os.path.join(BASEDIR, "selfdrive/loggerd"))

    params = Params()

    # start daemon processes
    for p in daemon_processes:
        start_daemon_process(p)

    # start persistent processes
    for p in persistent_processes:
        start_managed_process(p)

    # start offroad
    if ANDROID:
        pm_apply_packages('enable')
        start_offroad()

    if os.getenv("NOBOARD") is None:
        start_managed_process("pandad")

    if os.getenv("BLOCK") is not None:
        for k in os.getenv("BLOCK").split(","):
            del managed_processes[k]

    started_prev = False
    logger_dead = False

    while 1:
        msg = messaging.recv_sock(thermal_sock, wait=True)

        if msg.thermal.freeSpace < 0.05:
            logger_dead = True

        if msg.thermal.started:
            for p in car_started_processes:
                if p == "loggerd" and logger_dead:
                    kill_managed_process(p)
                else:
                    start_managed_process(p)
        else:
            logger_dead = False
            driver_view = params.get("IsDriverViewEnabled") == b"1"

            # TODO: refactor how manager manages processes
            for p in reversed(car_started_processes):
                if p not in driver_view_processes or not driver_view:
                    kill_managed_process(p)

            for p in driver_view_processes:
                if driver_view:
                    start_managed_process(p)
                else:
                    kill_managed_process(p)

            # trigger an update after going offroad
            if started_prev:
                send_managed_process_signal("updated", signal.SIGHUP)

        started_prev = msg.thermal.started

        # check the status of all processes, did any of them die?
        running_list = [
            "%s%s\u001b[0m" %
            ("\u001b[32m" if running[p].is_alive() else "\u001b[31m", p)
            for p in running
        ]
        cloudlog.debug(' '.join(running_list))

        # Exit main loop when uninstall is needed
        if params.get("DoUninstall", encoding='utf8') == "1":
            break