]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
added linudvb_rotor_external to control an actuator by spawning an external command
authorLuca Olivetti <luca@ventoso.org>
Sat, 15 Dec 2018 13:31:30 +0000 (14:31 +0100)
committerJaroslav Kysela <perex@perex.cz>
Wed, 19 Dec 2018 14:15:46 +0000 (15:15 +0100)
src/input/mpegts/linuxdvb/linuxdvb_private.h
src/input/mpegts/linuxdvb/linuxdvb_rotor.c
src/input/mpegts/linuxdvb/linuxdvb_satconf.c

index 119a409334799af10ba66f5760ee180c8d70118c..b51d3215c43e2d5b87e474af593b5fdbf7e008c7 100644 (file)
@@ -282,6 +282,7 @@ struct linuxdvb_satconf
   int                    ls_last_tone_off;
   int                    ls_last_orbital_pos;
   int                    ls_last_queued_pos;
+  char                   *ls_external_cmd;
 };
 
 /*
index 86b2791de58920664c7cf59e521b97b2b8adc446..b773aa0c70ce1707f8fa792a4e8612e9e3966d15 100644 (file)
@@ -55,6 +55,8 @@ double gazimuth, gelevation;
 
 #endif
 
+#include "spawn.h"
+
 /* **************************************************************************
  * Class definition
  * *************************************************************************/
@@ -138,6 +140,30 @@ const idclass_t linuxdvb_rotor_gotox_class =
   }
 };
 
+const idclass_t linuxdvb_rotor_external_class =
+{
+  .ic_super       = &linuxdvb_rotor_class,
+  .ic_class       = "linuxdvb_rotor_external",
+  .ic_caption     = N_("TV Adapters - SatConfig - External Rotor"),
+  .ic_properties  = (const property_t[]) {
+    {
+      .type   = PT_U16,
+      .id     = "position",
+      .name   = N_("External position"),
+      .desc   = N_("Position to send to the external command"),
+      .off    = offsetof(linuxdvb_rotor_t, lr_position),
+    },
+    {
+      .type   = PT_DBL,
+      .id     = "sat_lon",
+      .name   = N_("Satellite longitude"),
+      .desc   = N_("Satellite longitude (like 9.0 (east) or -33.0 (west))."),
+      .off    = offsetof(linuxdvb_rotor_t, lr_sat_lon),
+    },
+    {}
+  }
+};
+
 const idclass_t linuxdvb_rotor_usals_class =
 {
   .ic_super       = &linuxdvb_rotor_class,
@@ -315,6 +341,49 @@ sat_angle( linuxdvb_rotor_t *lr, linuxdvb_satconf_ele_t *ls )
  * Class methods
  * *************************************************************************/
 
+static int
+linuxdvb_external_command
+  (linuxdvb_rotor_t *lr, linuxdvb_satconf_t *ls)
+{
+  int outlen = -1, rd = -1;
+  char outbuf[100];
+  char num[10];
+  char *argv[] = {NULL, num, NULL};
+  int ret = -1;
+
+  snprintf(num, sizeof(num), "%u", lr->lr_position);
+  if (spawn_and_give_stdout(ls->ls_external_cmd, argv, NULL, &rd, NULL, 1) >= 0) {
+    outlen = read(rd, outbuf, 99);
+    if (outlen>0) {
+      outbuf[outlen]=0;
+      tvhdebug(LS_DISEQC, "external command replied %s",outbuf);
+      if (outbuf[0]>='0' && outbuf[0]<='9')
+        ret=atoi(outbuf);
+    } else {
+      if (outlen==0)
+        tvherror(LS_DISEQC, "no output from external command");
+      else
+        tvherror(LS_DISEQC, "error reading from external command");
+    }
+  } else {
+    tvherror(LS_DISEQC, "cannot spawn external command");
+  }
+  if (rd>=0)
+    close(rd);
+  tvhinfo(LS_DISEQC, "linuxdvb_external_command moving to %d returned %d", lr->lr_position, ret);
+  return ret;
+}
+
+static int
+linuxdvb_external_grace
+  ( linuxdvb_rotor_t *lr, linuxdvb_satconf_t *ls)
+{
+  int ret=linuxdvb_external_command(lr, ls);
+  if (ret<0)
+    return ls->ls_max_rotor_move;
+  return ret;
+}
+
 static int
 linuxdvb_rotor_grace
   ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm )
@@ -323,6 +392,9 @@ linuxdvb_rotor_grace
   linuxdvb_satconf_t *ls = ld->ld_satconf->lse_parent;
   int newpos, delta, tunit, min, res;
 
+  if (idnode_is_instance(&lr->ld_id, &linuxdvb_rotor_external_class))
+      return linuxdvb_external_grace(lr, ls);
+
   if (!ls->ls_last_orbital_pos || ls->ls_motor_rate == 0)
     return ls->ls_max_rotor_move;
 
@@ -391,6 +463,15 @@ linuxdvb_rotor_gotox_tune
   return linuxdvb_rotor_grace((linuxdvb_diseqc_t*)lr,lm);
 }
 
+/* External */
+static int
+linuxdvb_rotor_external_tune
+  ( linuxdvb_rotor_t *lr, dvb_mux_t *lm,
+    linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls )
+{
+  return linuxdvb_external_command(lr, lsp);
+}
+
 /* USALS */
 static int
 linuxdvb_rotor_usals_tune
@@ -444,6 +525,9 @@ linuxdvb_rotor_tune
   /* GotoX */
   if (idnode_is_instance(&lr->ld_id, &linuxdvb_rotor_gotox_class))
     res = linuxdvb_rotor_gotox_tune(lr, lm, lsp, ls);
+  /* External */
+  else if (idnode_is_instance(&lr->ld_id, &linuxdvb_rotor_external_class))
+    res = linuxdvb_rotor_external_tune(lr, lm, lsp, ls);
   /* USALS */
   else
     res = linuxdvb_rotor_usals_tune(lr, lm, lsp, ls);
@@ -492,6 +576,10 @@ struct {
     .name = N_("GOTOX"),
     .idc  = &linuxdvb_rotor_gotox_class
   },
+  {
+    .name = N_("EXTERNAL"),
+    .idc  = &linuxdvb_rotor_external_class
+  },
   {
     .name = N_("USALS"),
     .idc  = &linuxdvb_rotor_usals_class
index 673ad759a34791df0a5f989de9cafe9ed2ceb55b..bf818e4744a54219833f7bc893e401817e876781 100644 (file)
@@ -756,6 +756,15 @@ const idclass_t linuxdvb_satconf_advanced_class =
       .opts     = PO_ADVANCED,
       .def.i    = 0
     },
+    {
+      .type     = PT_STR,
+      .id       = "external_cmd",
+      .name     = N_("External command"),
+      .desc     = N_("Command to move the dish with rotor external."),
+      .off      = offsetof(linuxdvb_satconf_t, ls_external_cmd),
+      .opts     = PO_ADVANCED,
+      .def.i    = 0
+    },
     {
       .type     = PT_U32,
       .id       = "motor_rate",