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, ",", car_trip);
  s = stp_ul(s, ",", car_odometer);
  s = stp_i(s, ",", car_speed);
  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_msgp_tpms(char stat)
{
  char k, *s;
  long p;

#if 0
  if ((car_tpms_t[0] == 0) && (car_tpms_t[1] == 0) &&
          (car_tpms_t[2] == 0) && (car_tpms_t[3] == 0))
    return stat; // No TPMS, no report
  // ...new stat fn: No TMPS = one report with stale=-1
#endif

  s = stp_rom(net_scratchpad, "MP-0 W");
  for (k = 0; k < 4; k++)
  {
    if (car_tpms_t[k] > 0)
    {
      p = (long) ((float) car_tpms_p[k] / 0.2755);
      s = stp_l2f(s, NULL, p, 1);
      s = stp_i(s, ",", car_tpms_t[k] - 40);
      s = stp_rom(s, ",");
    }
    else
    {
      s = stp_rom(s, "0,0,");
    }
  }
  s = stp_i(s, NULL, car_stale_tpms);

  return net_msg_encode_statputs(stat, &crc_tpms);
}
char net_msgp_group(char stat, char groupnumber, char *groupname)
{
  char *s;

  s = stp_s(net_scratchpad, "MP-0 g", groupname);
  s = stp_i(s, ",", car_SOC);
  s = stp_i(s, ",", car_speed);
  s = stp_i(s, ",", car_direction);
  s = stp_i(s, ",", car_altitude);
  s = stp_i(s, ",", car_gpslock);
  s = stp_i(s, ",", car_stale_gps);
  s = stp_latlon(s, ",", car_latitude);
  s = stp_latlon(s, ",", car_longitude);

  if (groupnumber == 1)
    return net_msg_encode_statputs(stat, &crc_group1);
  else
    return net_msg_encode_statputs(stat, &crc_group2);
}
char net_msgp_gps(char stat)
{
  char *s;

  s = stp_latlon(net_scratchpad, "MP-0 L", car_latitude);
  s = stp_latlon(s, ",", car_longitude);
  s = stp_i(s, ",", car_direction);
  s = stp_i(s, ",", car_altitude);
  s = stp_i(s, ",", car_gpslock);
  s = stp_i(s, ",", car_stale_gps);

  return net_msg_encode_statputs(stat, &crc_gps);
}
char net_msgp_capabilities(char stat)
{
  char *s;

  s = stp_rom(net_scratchpad, "MP-0 V");
  if ((can_capabilities != NULL) && (can_capabilities[0] != 0))
  {
    s = stp_rom(s, can_capabilities);
    s = stp_rom(s, ",");
  }
  s = stp_rom(s, "C1-6,C40-41,C49");

  return net_msg_encode_statputs(stat, &crc_capabilities);
}
char net_msgp_firmware(char stat)
{
  // Send firmware version and GSM signal level
  char *s;
  unsigned char hwv = 1;
#ifdef OVMS_HW_V2
  hwv = 2;
#endif

  s = stp_i(net_scratchpad, "MP-0 F", ovms_firmware[0]);
  s = stp_i(s, ".", ovms_firmware[1]);
  s = stp_i(s, ".", ovms_firmware[2]);
  s = stp_s(s, "/", par_get(PARAM_VEHICLETYPE));
  s = stp_i(s, "/V", hwv);
  s = stp_s(s, ",", car_vin);
  s = stp_i(s, ",", net_sq);
  s = stp_i(s, ",", sys_features[FEATURE_CANWRITE]);
  s = stp_s(s, ",", car_type);
  s = stp_s(s, ",", car_gsmcops);

  return net_msg_encode_statputs(stat, &crc_firmware);
}
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);
}
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, ",", MI2KM(car_idealrange));
    s = stp_i(s, ",", MI2KM(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);

  return net_msg_encode_statputs(stat, &crc_stat);
}