/****************************************************************************/
/* Copyright (c) 2015 MBARI                                                 */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
/* Summary  : Command interface to the CANBus power buoy controllers.       */
/* Filename : pbcmd.c                                                       */
/* Author   : Henthorn                                                      */
/* Project  : Power Buoy                                                    */
/* Version  : 1.0                                                           */
/* Created  : 04/10/2015                                                    */
/* Modified : 09/11/2018 Add tf commands                                    */
/* Archived :                                                               */
/****************************************************************************/
/* Modification History:                                                    */
/****************************************************************************/
/*                                                                          */
/* This application is the entry point for many (if not all) the Power Buoy */
/* controller commands. The design is similar to 'busybox' where argv[0]    */
/* determines what command is executed. Soft-links to this program are used */
/* for each supported command. To illustrate:                               */
/*  $                                                                       */
/*  $ ls -l  ~/bin                                                          */
/*  -rwxr-xr-x 1 henthorn dialout 12107 Apr 8 17:26 pbcmd                   */
/*  lrwxrwxrwx 1 henthorn dialout    11 Apr 9 09:52 bender -> pbcmd         */
/*  $                                                                       */
/*  $ bender on   # runs pbcmd with argv[0] == "bender"                     */
/*                                                                          */
/* Issue command 'pbcmd' for help on the supported commands                 */
/*  $                                                                       */
/*  $ pbcmd                                                                 */
/*                                                                          */
/****************************************************************************/

#include "pbcmd.h"

// Structure used by main to dispatch commands.
// When adding a command, declare it in pbcmd.h,
// implement it in cmd_code.c, and add
// an entry to the command array below.
//
struct PB_CMD {
   char* name;            // command line name (i.e., "bender")
   char* desc;            // short description ("Bends the battery controller")
   int (*f)(int, char**);
};

struct PB_CMD pb_cmds[] = {
   {        "bender", "Sets the state of the bender module", bender},
   { "reset_battery", "Reset battery controller (caution - no args)\n", reset_bc},

   {          "pump", "Spring Controller pump  off or on for a time in minutes <= 127", pump},
   {         "valve", "Spring Controller valve off or on for a time in seconds <= 127", valve},
   {        "tether", "Spring Controller tether power on or off", tether},
   {  "reset_spring", "Reset Spring Controller (caution - no args)\n", reset_sc},

   {         "scale", "Set the power controller scale", scale},
   {       "retract", "Set the power controller retract", retract},
   {          "vmax", "Set the power controller max voltage", vmax},
   {          "imax", "Set the maximum battery charge current of the power controller", imax},
   {          "draw", "Set the maximum battery current draw of the power controller", max_batt_draw},
   {     "batt_mode", "Set the battery charge mode of the power controller", batt_mode},
   {          "gain", "Set the gain scheduler gain", gain},
   {       "vstddev", "Set the gain scheduler target voltage", vstddev},
   {     "wind_curr", "Set the wind current limit of the power controller", wind_curr},
   {"bias_wind_curr", "Set the wind current bias of the power controller", bias_wind_curr},
   { "can_pack_rate", "Set the CANBUS packet rate from the power controller", can_pack_rate},
   {"stopchargemode", "Set the stop charge mode option on or off", scm},
   {   "reset_power", "Reset Power Controller (caution - no args)\n", reset_pc},

   {          "tf_SetPos", "Open/close the doors in the heave-cone", tf_setpos},
   {    "tf_SetActualPos", "Open/close the doors in the heave-cone", tf_setactualpos},
   {         "tf_SetMode", "Set controller mode", tf_setmode},
   {   "tf_SetChargeMode", "Set Battery Charge mode", tf_setchargemode},
   { "tf_SetStateMachine", "Set Battery Charge mode", tf_setstatemachine},
   {      "tf_SetCurrLim", "Set controller current limit", tf_setcurrlim},
   {        "tf_WatchDog", "Toggle controller watchdog (caution - no args)", tf_watchdog},
   {           "tf_Reset", "Reset Controller (caution - no args)\n", tf_reset},

// The following commands, including all rudder commands, are
// dormant (non-visible) as of August 29 2018  -Henthorn
// 
#if 0
   {    "set_torque", "Set the torque", set_torque},
   {       "set_rpm", "Set the RPM", set_rpm},

   {        "rcmode", "Set Rudder Controller Mode", rcmode},
   {         "rcpos", "Set Rudder Position", rcpos},
   {      "rctarget", "Set Rudder Heading Target", rctarget},
   {         "rchdg", "Set Default Rudder Heading", rchdg},
   {      "rcfilter", "Set Rudder Heading Filter TC", rcfilter},
   {      "rcperiod", "Set Rudder Controller Update Period", rcperiod},
   {       "rcpgain", "Set Rudder Controller Proportional Gain", rcpgain},
   {       "rcigain", "Set Rudder Controller Integral Gain", rcigain},
   {       "rcdgain", "Set Rudder Controller Derivative Gain", rcdgain},
   {      "rcmaxpos", "Set Rudder Controller max rudder position", rcmaxpos},
   {    "rcdeadband", "Set Rudder Controller deadband", rcdeadband},
   {  "reset_rudder", "Reset Rudder Controller", rcreset},
#endif

   //{      "hv", "Battery Controller high voltage on or off", hv}, // removed
   // {"next", "Next command example", next},

   {NULL, NULL, NULL}   // always the last one
};


void pbcmd_usage()
{
   printf("pbcmd: Multi-call command Power Buoy dispatcher\n"
          "Supported commands:\n");
   int i = 0;
   while(pb_cmds[i].name != NULL)
   {
      printf("* %18s  - %s\n", pb_cmds[i].name, pb_cmds[i].desc);
      i++;
   }
   printf("\nFor help on a command use the command name, i.e., \"bender\"\n");
   printf("\nExcept the reset commands which take no arguments.\n");
   printf("\nDO NOT enter reset_power and expect to get help. The command will execute!\n");
}

int main(int argc, char **argv)
{
   // Finally, execute the command function
   //

   int i = 0;
   while(pb_cmds[i].name != NULL)
   {
      if (!strcasecmp(argv[0], pb_cmds[i].name))
      {
         printf("Executing %s to %s...\n", pb_cmds[i].name, pb_cmds[i].desc);
         return (pb_cmds[i].f)(argc, argv);
      }

      i++;
   }

   // If execution reaches this point then a sort of version skew has occurred
   // 
   pbcmd_usage();
   return 0;
}

