char net_msgp_environment(char stat)
{
  char *s;
  unsigned long park;

  if (car_parktime == 0)
    park = 0;
  else
    park = car_time - car_parktime;

  s = stp_i(net_scratchpad, "MP-0 D", car_doors1);
  s = stp_i(s, ",", car_doors2);
  s = stp_i(s, ",", car_lockstate);
  s = stp_i(s, ",", car_tpem);
  s = stp_i(s, ",", car_tmotor);
  s = stp_i(s, ",", car_tbattery);
  s = stp_i(s, ",", (can_mileskm=='M') ? car_trip : KmFromMi(car_trip));
  s = stp_ul(s, ",", (can_mileskm=='M') ? car_odometer : KmFromMi(car_odometer));
  s = stp_i(s, ",", car_speed); // no conversion, stored in user unit
  s = stp_ul(s, ",", park);
  s = stp_i(s, ",", car_ambient_temp);
  s = stp_i(s, ",", car_doors3);
  s = stp_i(s, ",", car_stale_temps);
  s = stp_i(s, ",", car_stale_ambient);
  s = stp_l2f(s, ",", car_12vline, 1);
  s = stp_i(s, ",", car_doors4);
  s = stp_l2f(s, ",", car_12vline_ref, 1);
  s = stp_i(s, ",", car_doors5);

  return net_msg_encode_statputs(stat, &crc_environment);
}
char *net_prep_stat(char *s)
{
  // convert distance values as needed
  unsigned int estrange = car_estrange;
  unsigned int idealrange = car_idealrange;
  unsigned long odometer = car_odometer;
  const rom char *unit = " mi";
  if (can_mileskm == 'K')
  {
    estrange = KmFromMi(estrange);
    idealrange = KmFromMi(idealrange);
    odometer = KmFromMi(odometer);
    unit = " km";
  }

  if (car_time != 0)
    {
    char *p = par_get(PARAM_TIMEZONE);
    s = stp_time(s, NULL, car_time + timestring_to_mins(p)*60L);
    s = stp_rom(s, "\r ");
    }

  if (car_coolingdown>=0)
    {
    s = stp_i(s, "Cooldown: ", car_tbattery);
    s = stp_i(s, "C/",car_cooldown_tbattery);
    s = stp_i(s, "C (",car_coolingdown);
    s = stp_i(s, "cycles, ",car_cooldown_timelimit);
    s = stp_rom(s, "mins remain)");
    }

  if (car_doors1bits.ChargePort)
  {
    char fShowVA = TRUE;
    // Charge port door is open, we are charging
    switch (car_chargemode)
    {
    case 0x00:
      s = stp_rom(s, "Standard - "); // Charge Mode Standard
      break;
    case 0x01:
      s = stp_rom(s, "Storage - "); // Storage
      break;
    case 0x03:
      s = stp_rom(s, "Range - "); // Range
      break;
    case 0x04:
      s = stp_rom(s, "Performance - "); // Performance
    }
    switch (car_chargestate)
    {
    case 0x01:
      s = stp_rom(s, "Charging"); // Charge State Charging
      break;
    case 0x02:
      s = stp_rom(s, "Charging, Topping off"); // Topping off
      break;
    case 0x04:
      s = stp_rom(s, "Charging Done"); // Done
      fShowVA = FALSE;
      break;
    case 0x0d:
      s = stp_rom(s, "Preparing"); // Preparing
      break;
    case 0x0f:
      s = stp_rom(s, "Charging, Heating"); // Heating
      break;
    default:
      s = stp_rom(s, "Charging Stopped"); // Stopped
      fShowVA = FALSE;
      break;
    }
//  this causes ACC to think the charge port door has been closed and opened,
//  which then causes it to do something that makes the coolant pump come on
//  car_doors1bits.ChargePort = 0; // MJ Close ChargePort, will open next CAN Reading
    if (fShowVA)
    {
      s = stp_i(s, "\r ", car_linevoltage);
      s = stp_i(s, "V/", car_chargecurrent);
      s = stp_rom(s, "A");
      if (car_chargefull_minsremaining >= 0)
        {
        s = stp_i(s,"\r Full: ",car_chargefull_minsremaining);
        s = stp_rom(s," mins");
        }
      if (car_chargelimit_soclimit > 0)
        {
        s = stp_i(s, "\r ", car_chargelimit_soclimit);
        s = stp_i(s,"%: ",car_chargelimit_minsremaining);
        s = stp_rom(s," mins");
        }
      if (car_chargelimit_rangelimit > 0)
        {
        s = stp_i(s, "\r ", (can_mileskm == 'K')?KmFromMi(car_chargelimit_rangelimit):car_chargelimit_rangelimit);
        s = stp_rom(s, unit);
        s = stp_i(s,": ",car_chargelimit_minsremaining);
        s = stp_rom(s," mins");
        }
    }
  }
  else
  {
    s = stp_rom(s, "Not charging");
  }

  s = stp_i(s, "\r SOC: ", car_SOC);
  s = stp_rom(s, "%");

  if (idealrange != 0)
    {
    s = stp_i(s, "\r Ideal Range: ", idealrange);
    s = stp_rom(s, unit);
    }
  if (estrange != 0)
    {
    s = stp_i(s, "\r Est. Range: ", estrange);
    s = stp_rom(s, unit);
    }
  if (odometer != 0)
    {
    s = stp_l2f_h(s, "\r ODO: ", odometer, 1);
    s = stp_rom(s, unit);
    }
  if (car_cac100 != 0)
    {
    s = stp_l2f_h(s, "\r CAC: ", (unsigned long)car_cac100, 2);
    }

  return s;
}
char net_msgp_stat(char stat)
{
  char *p, *s;

  p = par_get(PARAM_MILESKM);

  s = stp_i(net_scratchpad, "MP-0 S", car_SOC);
  s = stp_s(s, ",", p);
  s = stp_i(s, ",", car_linevoltage);
  s = stp_i(s, ",", car_chargecurrent);

  switch (car_chargestate)
  {
  case 0x01:
    s = stp_rom(s, ",charging");
    break;
  case 0x02:
    s = stp_rom(s, ",topoff");
    break;
  case 0x04:
    s = stp_rom(s, ",done");
    break;
  case 0x0d:
    s = stp_rom(s, ",prepare");
    break;
  case 0x0f:
    s = stp_rom(s, ",heating");
    break;
  default:
    s = stp_rom(s, ",stopped");
  }

  switch (car_chargemode)
  {
  case 0x00:
    s = stp_rom(s, ",standard");
    break;
  case 0x01:
    s = stp_rom(s, ",storage");
    break;
  case 0x03:
    s = stp_rom(s, ",range");
    break;
  case 0x04:
    s = stp_rom(s, ",performance");
    break;
  default:
    s = stp_rom(s, ",");
  }

  if (*p == 'M') // Kmh or Miles
  {
    s = stp_i(s, ",", car_idealrange);
    s = stp_i(s, ",", car_estrange);
  }
  else
  {
    s = stp_i(s, ",", KmFromMi(car_idealrange));
    s = stp_i(s, ",", KmFromMi(car_estrange));
  }

  s = stp_i(s, ",", car_chargelimit);
  s = stp_i(s, ",", car_chargeduration);
  s = stp_i(s, ",", car_charge_b4);
  s = stp_i(s, ",", car_chargekwh);
  s = stp_i(s, ",", car_chargesubstate);
  s = stp_i(s, ",", car_chargestate);
  s = stp_i(s, ",", car_chargemode);
  s = stp_i(s, ",", car_timermode);
  s = stp_i(s, ",", car_timerstart);
  s = stp_i(s, ",", car_stale_timer);
  s = stp_l2f(s, ",", (unsigned long)car_cac100, 2);
  s = stp_i(s, ",", car_chargefull_minsremaining);
  s = stp_i(s, ",", car_chargelimit_minsremaining);
  s = stp_i(s, ",", car_chargelimit_rangelimit);
  s = stp_i(s, ",", car_chargelimit_soclimit);
  s = stp_i(s, ",", car_coolingdown);
  s = stp_i(s, ",", car_cooldown_tbattery);
  s = stp_i(s, ",", car_cooldown_timelimit);
  s = stp_i(s, ",", car_chargeestimate);

  return net_msg_encode_statputs(stat, &crc_stat);
}