MNH Gedankensprudel

nicht nur ein stilles Wasser

Raw code in pilight gui mit eigenen Protokoll 2

01.10.15 (Allgemein)

Nun komm der in diesen Beitrag bereits versprochene zweite Teil…

On Off SoOONY DAS GEHT*

Ganz so arg müssen wir uns nicht ärgern. Doch leider wird es auch nicht mit einen einfachen on/off funktionieren. Damit ihr nicht noch ZWEIHUNDERT PULS bekommt mache ich mal weiter.

nach einen ausführen der install.sh sollte das Protokoll zwar schon auswählbar und kompilierbar sein doch ein:

sudo pilight-send -H
Usage: pilight-send -p protocol [options]
         -H --help                      display this message
         -V --version                   display version
         -p --protocol=protocol         the protocol that you want to control
         -S --server=x.x.x.x            connect to server address
         -P --port=xxxx                 connect to server port
         -F --settings                  settings file

The supported protocols are:
         brennenstuhl                   Brennenstuhl Comfort
         byebyestandbye                 Bye Bye Standbye Switches
         clarus_switch                  Clarus Switches
         cleverwatts                    Cleverwatts Switches
         coco_switch                    CoCo Technologies Switches
         cogex                          Cogex Switches
         dio_switch                     D-IO Switches
         elro_ad                        Elro Home Easy Advanced Switches
         elro_hc                        Elro Home Control Switches
         elro_he                        Elro Home Easy Switches
         generic_dimmer                 Generic Dimmers
         generic_screen                 Generic Screens
         generic_switch                 Generic Switches
         generic_weather                Generic Weather Stations
         home_easy_old                  Old Home Easy Switches
         impuls                         Impuls Switches
         intertechno_old                Old Intertechno Switches
         intertechno_switch             Intertechno Switches
         kaku_dimmer                    KlikAanKlikUit Dimmers
         kaku_screen                    KlikAanKlikUit Screens
         kaku_screen_old                Old KlikAanKlikUit Screens
         kaku_switch                    KlikAanKlikUit Switches
         kaku_switch_old                Old KlikAanKlikUit Switches
         nexa_switch                    Nexa Switches
         openweathermap                 Open Weather Map API
         pollin                         Pollin Switches
         program                        Start / Stop / State of a program
         quigg_switch                   Quigg Switches
         raw                            Raw Codes
         relay                          GPIO Connected Relays
         rev1_switch                    Rev Switches v1
         rev2_switch                    Rev Switches v2
         rev3_switch                    Rev Switches v3
         selectremote                   SelectRemote Switches
         silvercrest                    Silvercrest Switches
         unitech                        Unitech Switches
         wunderground                   Weather Underground API
         x10                            x10 based devices

liefert leider noch nicht den gewünschten erfolg, wie wir unter „The supported protocols are“ sehen.

Quelltext

Fangen wir also mal an, uns den Quelltext anzuschauen. Also Zurück zu bhc9938d.c und dort die Init Funktion. Den dort müssen wir noch eigne dinge bekanntgeben.

//...
void bhc9938dInit(void) {
    protocol_register(&bhc9938d);
    protocol_set_id(bhc9938d, "bhc9938d");
    protocol_device_add(bhc9938d, "bhc9938d", "BHC9938D protocol");
    bhc9938d -> devtype = RAW;
    bhc9938d -> printHelp = &bhc9938dPrintHelp;
}
//...

beschäftigen wir uns zunächst mit printHelp hier setzen wir einen Funktionszeiger in diesen Fall auf eine Funktion die bhc9938dPrintHelp heißt. Ich würde hier ein ähnliches Namensschema vorschlagen also protokollnameFunktion um Namenskonflikte zu vermeiden.
mit einer pasenden Methode sind wir also schon so weit Hilfetexte auszugeben:

static void bhc9938dPrintHelp(void) {
    printf("\t Ich bin ein  Hilfreicher Text\n");
}

was noch fehlt sind die Parameter zum steuern und natürlich das Senden dafür ergänzen wir wieder die Initfunktion

void bhc9938dInit(void) {
    protocol_register(&bhc9938d);
    protocol_set_id(bhc9938d, "bhc9938d");
    protocol_device_add(bhc9938d, "bhc9938d", "BHC9938D protocol");
    
    options_add(&bhc9938d->options, 'u', "unit", OPTION_HAS_VALUE, CONFIG_ID, JSON_NUMBER, NULL, "^(3[012]?|[012][0-9]|[0-9]{1})$");
    options_add(&bhc9938d->options, 't', "on", OPTION_NO_VALUE, CONFIG_STATE, JSON_STRING, NULL, NULL);
    options_add(&bhc9938d->options, 'f', "off", OPTION_NO_VALUE, CONFIG_STATE, JSON_STRING, NULL, NULL);
    
    bhc9938d -> devtype = RAW;
    bhc9938d -> printHelp = &bhc9938dPrintHelp;
    bhc9938d -> createCode = &bhc9938dCreateCode;
}

options_add rufe ich hier gleich dreimal auf, einmal für Unit eine einfache numerische ID in meinen Fall von 1-3, und jeweils einmal für on und off.
Des weiteren noch ein Pointer auf die bhc9938dCreateCode Funktion die dem Protokoll das eigentliche leben Einhaucht.
Der Komplette Kode schaut bei mir dann so aus:

/*
 * File:   bhc9938d.c
 * Author: Michael Hegenbarth (carschrotter) <mnh@mn-hegenbarth.de>
 *
 * Created on 23. Januar 2015, 13:19
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>

#include "../../pilight.h"
#include "common.h"
#include "protocol.h"
#include "log.h"
#include "json.h"
#include "bhc9938d.h"

#ifndef MODULE

__attribute__((weak))
#endif
    
const char * indent = "ttttt";

typedef enum { OFF, ON, UNKNOWN=-1 } switchState;

/*
 * code all codes for on and off state from piligt debug
 */
const char * codes[2][3] = {
    {
    "160 480 480 160 160 480 480 160 160 480 480 160 160 480 480 160 160 480 160 480 160 480 480 160 160 480 480 160 160 480 480 160 160 480 160 480 480 160 480 160 480 160 480 160 160 480 160 480 160 5440",
    "160 480 480 160 160 480 480 160 160 480 480 160 160 480 480 160 160 480 160 480 160 640 480 160 160 640 480 160 160 480 480 160 480 160 480 160 160 640 160 480 480 160 480 160 160 480 160 480 160 5440",
    "160 640 480 160 160 640 480 160 160 480 480 160 160 640 480 160 160 640 160 480 160 480 480 160 160 480 480 160 480 160 480 160 160 480 160 480 160 640 160 480 480 160 480 160 160 480 160 480 160 5440"
    }, //off codes (index 0)
    {
    "161 483 483 161 161 483 483 161 1683 483 161 161 483 483 161 161 644 161 483 161 483 483 161 161 483 483 161 161 483 483 161 161 483 161 644 483 161 483 161 161 483 161 483 483 161 483 161 161 5474",
    "160 480 480 160 160 480 480 160 160 480 480 160 160 640 480 160 160 480 160 480 160 480 480 160 160 480 480 160 160 480 480 320 480 160 480 160 160 480 160 480 160 480 160 640 480 160 480 160 160 5440",
    "160 480 480 160 160 480 480 160 160 480 480 160 160 480 480 160 160 640 160 480 160 480 480 160 160 480 480 160 480 160 480 160 160 480 160 480 160 480 160 480 160 480 160 480 480 160 480 160 160 5440"
    } //On codes (index 1)
};
bool strIsInt(const char * str, int * result){
    char * rest = NULL;
    int tmp = (int) strtol(str, &rest, 10);
    result = &tmp;
    return (bool) !(rest != NULL);
}


static void bhc9938dPrintHelp(void) {
    printf("t -u --unit=unitnumberttcontrol a device with this unitcodet (1|2|3)n");
    printf("t -t --ontttsend an on signaln");
    printf("t -f --offtttsend an off signaln");
/*
    printf("t -d --device="raw"ttraw code to tur on device n");
    printf("t -f -rawOff="raw"ttraw code to tur off device n");
    printf("%sraw code is devided by spacesn", indent);
    printf("%s(just like the output of debug)n", indent);
*/
}

static int bhc9938dCreateCode(JsonNode * code) {
    int unit = -1;
    switchState sState = UNKNOWN;
    double itmp = 0;
    
    int codeIndex = 0;
    
    char * rcode = NULL;
    char * pch = NULL;
    int i = 0;

    if(json_find_number(code, "unit", &itmp) == 0){
        unit = (int)round(itmp);
    }
    
    if(json_find_number(code, "off", &itmp) == 0){
        sState=OFF;
    } else if(json_find_number(code, "on", &itmp) == 0){
        sState=ON;
    }
    if(unit == -1 || sState == -1) {
        logprintf(LOG_ERR, "bhc9938d: insufficient number of arguments");
        return EXIT_FAILURE;
    } else if(unit > 4 || unit < 0) {
        logprintf(LOG_ERR, "bhc9938d: invalid unit range");
        return EXIT_FAILURE;
    } else {
    codeIndex = unit -1;
    rcode = strdup(codes[sState][codeIndex]);
    
    printf("nindex:t%dnsState:t%dncode:%sn", codeIndex, sState, rcode);
    
    pch = strtok(rcode, " ");

    while (pch != NULL) {
        
        bhc9938d -> raw[i] = atoi(pch);
        pch = strtok(NULL, " ");

        i++;
    }

    sfree((void *) &rcode);

    bhc9938d -> rawlen = i;
    }
    return EXIT_SUCCESS;
}

/*
// BHC9938D bhc9938d
*/
void bhc9938dInit(void) {
    protocol_register(&bhc9938d);
    protocol_set_id(bhc9938d, "bhc9938d");
    protocol_device_add(bhc9938d, "bhc9938d", "BHC9938D protocol");
    
    options_add(&bhc9938d->options, 'u', "unit", OPTION_HAS_VALUE, CONFIG_ID, JSON_NUMBER, NULL, "^(3[012]?|[012][0-9]|[0-9]{1})$");
    options_add(&bhc9938d->options, 't', "on", OPTION_NO_VALUE, CONFIG_STATE, JSON_STRING, NULL, NULL);
    options_add(&bhc9938d->options, 'f', "off", OPTION_NO_VALUE, CONFIG_STATE, JSON_STRING, NULL, NULL);
    
    bhc9938d -> devtype = RAW;
    bhc9938d -> printHelp = &bhc9938dPrintHelp;
    bhc9938d -> createCode = &bhc9938dCreateCode;
}

#ifdef MODULE

void compatibility(struct module_t *module) {
    module -> name = "bhc9938d";
    module -> version = "0.1";
    module -> reqversion = "5.0";
    module -> reqcommit = NULL;
}

void init(void) {
    bhc9938dInit();
}
#endif

Quellcode Bei GitHub als Gist

*Mus man gesehen haben um das zu verstehen

Carschrotter
ist leidenschaftlicher Technik Fan beigester von allen was mit dem Web zu tuen hat und Vollblut Nerd. Deshalb war auch sein Ausbildung zum Fachinformatiker ein logischer schritt.

Kommentar schreiben

I accept that my given data and my IP address is sent to a server in the USA only for the purpose of spam prevention through the Akismet program.More information on Akismet and GDPR.

XHTML: Sie können diese Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre prompt="" escaped="">