Files
OpenMQTT-Gateway/lib/ESPiLight/src/pilight/libs/pilight/protocols/433.92/pollin.c
T
2018-09-21 18:02:15 +01:00

231 lines
6.3 KiB
C
Executable File

/*
Copyright (C) 2014 CurlyMo
This file is part of pilight.
pilight is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
pilight is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with pilight. If not, see <http://www.gnu.org/licenses/>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../../core/pilight.h"
#include "../../core/common.h"
#include "../../core/dso.h"
#include "../../core/log.h"
#include "../protocol.h"
#include "../../core/binary.h"
#include "../../core/gc.h"
#include "pollin.h"
#define PULSE_MULTIPLIER 3
#define MIN_PULSE_LENGTH 296
#define MAX_PULSE_LENGTH 306
#define AVG_PULSE_LENGTH 301
#define RAW_LENGTH 50
static int validate(void) {
if(pollin->rawlen == RAW_LENGTH) {
if(pollin->raw[pollin->rawlen-1] >= (MIN_PULSE_LENGTH*PULSE_DIV) &&
pollin->raw[pollin->rawlen-1] <= (MAX_PULSE_LENGTH*PULSE_DIV)) {
return 0;
}
}
return -1;
}
static void createMessage(int systemcode, int unitcode, int state) {
pollin->message = json_mkobject();
json_append_member(pollin->message, "systemcode", json_mknumber(systemcode, 0));
json_append_member(pollin->message, "unitcode", json_mknumber(unitcode, 0));
if(state == 0) {
json_append_member(pollin->message, "state", json_mkstring("on"));
} else {
json_append_member(pollin->message, "state", json_mkstring("off"));
}
}
static void parseCode(void) {
int binary[RAW_LENGTH/4], x = 0, i = 0;
if(pollin->rawlen>RAW_LENGTH) {
logprintf(LOG_ERR, "pollin: parsecode - invalid parameter passed %d", pollin->rawlen);
return;
}
for(x=0;x<pollin->rawlen-2;x+=4) {
if(pollin->raw[x+3] > (int)((double)AVG_PULSE_LENGTH*((double)PULSE_MULTIPLIER/2))) {
binary[i++] = 1;
} else {
binary[i++] = 0;
}
}
int systemcode = binToDec(binary, 0, 4);
int unitcode = binToDec(binary, 5, 9);
int state = binary[11];
createMessage(systemcode, unitcode, state);
}
static void createLow(int s, int e) {
int i;
for(i=s;i<=e;i+=4) {
pollin->raw[i]=(AVG_PULSE_LENGTH);
pollin->raw[i+1]=(PULSE_MULTIPLIER*AVG_PULSE_LENGTH);
pollin->raw[i+2]=(PULSE_MULTIPLIER*AVG_PULSE_LENGTH);
pollin->raw[i+3]=(AVG_PULSE_LENGTH);
}
}
static void createHigh(int s, int e) {
int i;
for(i=s;i<=e;i+=4) {
pollin->raw[i]=(AVG_PULSE_LENGTH);
pollin->raw[i+1]=(PULSE_MULTIPLIER*AVG_PULSE_LENGTH);
pollin->raw[i+2]=(AVG_PULSE_LENGTH);
pollin->raw[i+3]=(PULSE_MULTIPLIER*AVG_PULSE_LENGTH);
}
}
static void clearCode(void) {
createLow(0,47);
}
static void createSystemCode(int systemcode) {
int binary[255];
int length = 0;
int i=0, x=0;
length = decToBinRev(systemcode, binary);
for(i=0;i<=length;i++) {
if(binary[i]==1) {
x=i*4;
createHigh(x, x+3);
}
}
}
static void createUnitCode(int unitcode) {
int binary[255];
int length = 0;
int i=0, x=0;
length = decToBinRev(unitcode, binary);
for(i=0;i<=length;i++) {
if(binary[i]==1) {
x=i*4;
createHigh(20+x, 20+x+3);
}
}
}
static void createState(int state) {
if(state == 1) {
createHigh(44, 47);
}
}
static void createFooter(void) {
pollin->raw[48]=(AVG_PULSE_LENGTH);
pollin->raw[49]=(PULSE_DIV*AVG_PULSE_LENGTH);
}
static int createCode(struct JsonNode *code) {
int systemcode = -1;
int unitcode = -1;
int state = -1;
double itmp = -1;
if(json_find_number(code, "systemcode", &itmp) == 0)
systemcode = (int)round(itmp);
if(json_find_number(code, "unitcode", &itmp) == 0)
unitcode = (int)round(itmp);
if(json_find_number(code, "off", &itmp) == 0)
state=1;
else if(json_find_number(code, "on", &itmp) == 0)
state=0;
if(systemcode == -1 || unitcode == -1 || state == -1) {
logprintf(LOG_ERR, "pollin: insufficient number of arguments");
return EXIT_FAILURE;
} else if(systemcode > 31 || systemcode < 0) {
logprintf(LOG_ERR, "pollin: invalid systemcode range");
return EXIT_FAILURE;
} else if(unitcode > 31 || unitcode < 0) {
logprintf(LOG_ERR, "pollin: invalid unitcode range");
return EXIT_FAILURE;
} else {
createMessage(systemcode, unitcode, state);
clearCode();
createSystemCode(systemcode);
createUnitCode(unitcode);
createState(state);
createFooter();
pollin->rawlen = RAW_LENGTH;
}
return EXIT_SUCCESS;
}
static void printHelp(void) {
printf("\t -s --systemcode=systemcode\tcontrol a device with this systemcode\n");
printf("\t -u --unitcode=unitcode\t\tcontrol a device with this unitcode\n");
printf("\t -t --on\t\t\tsend an on signal\n");
printf("\t -f --off\t\t\tsend an off signal\n");
}
#if !defined(MODULE) && !defined(_WIN32)
__attribute__((weak))
#endif
void pollinInit(void) {
protocol_register(&pollin);
protocol_set_id(pollin, "pollin");
protocol_device_add(pollin, "pollin", "Pollin Switches");
pollin->devtype = SWITCH;
pollin->hwtype = RF433;
pollin->minrawlen = RAW_LENGTH;
pollin->maxrawlen = RAW_LENGTH;
pollin->maxgaplen = MAX_PULSE_LENGTH*PULSE_DIV;
pollin->mingaplen = MIN_PULSE_LENGTH*PULSE_DIV;
options_add(&pollin->options, 's', "systemcode", OPTION_HAS_VALUE, DEVICES_ID, JSON_NUMBER, NULL, "^(3[012]?|[012][0-9]|[0-9]{1})$");
options_add(&pollin->options, 'u', "unitcode", OPTION_HAS_VALUE, DEVICES_ID, JSON_NUMBER, NULL, "^(3[012]?|[012][0-9]|[0-9]{1})$");
options_add(&pollin->options, 't', "on", OPTION_NO_VALUE, DEVICES_STATE, JSON_STRING, NULL, NULL);
options_add(&pollin->options, 'f', "off", OPTION_NO_VALUE, DEVICES_STATE, JSON_STRING, NULL, NULL);
options_add(&pollin->options, 0, "readonly", OPTION_HAS_VALUE, GUI_SETTING, JSON_NUMBER, (void *)0, "^[10]{1}$");
options_add(&pollin->options, 0, "confirm", OPTION_HAS_VALUE, GUI_SETTING, JSON_NUMBER, (void *)0, "^[10]{1}$");
pollin->parseCode=&parseCode;
pollin->createCode=&createCode;
pollin->printHelp=&printHelp;
pollin->validate=&validate;
}
#if defined(MODULE) && !defined(_WIN32)
void compatibility(struct module_t *module) {
module->name = "pollin";
module->version = "2.4";
module->reqversion = "6.0";
module->reqcommit = "84";
}
void init(void) {
pollinInit();
}
#endif