From: Luca Olivetti Date: Sat, 15 Dec 2018 13:31:30 +0000 (+0100) Subject: added linudvb_rotor_external to control an actuator by spawning an external command X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0a1d52cb71cd1037cbe8c9f2926b2e3634349f48;p=thirdparty%2Ftvheadend.git added linudvb_rotor_external to control an actuator by spawning an external command --- diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 119a40933..b51d3215c 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -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; }; /* diff --git a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c index 86b2791de..b773aa0c7 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c @@ -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 diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index 673ad759a..bf818e474 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -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",