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

221 lines
5.4 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 "ehome.h"
#define PULSE_MULTIPLIER 3
#define MIN_PULSE_LENGTH 277
#define MAX_PULSE_LENGTH 287
#define AVG_PULSE_LENGTH 282
#define RAW_LENGTH 50
static int validate(void) {
if(ehome->rawlen == RAW_LENGTH) {
if(ehome->raw[ehome->rawlen-1] >= (MIN_PULSE_LENGTH*PULSE_DIV) &&
ehome->raw[ehome->rawlen-1] <= (MAX_PULSE_LENGTH*PULSE_DIV)) {
return 0;
}
}
return -1;
}
static void createMessage(int id, int state) {
ehome->message = json_mkobject();
json_append_member(ehome->message, "id", json_mknumber(id, 0));
if(state == 1) {
json_append_member(ehome->message, "state", json_mkstring("on"));
} else {
json_append_member(ehome->message, "state", json_mkstring("off"));
}
}
static void parseCode(void) {
int i = 0, binary[RAW_LENGTH/4];
if(ehome->rawlen>RAW_LENGTH) {
logprintf(LOG_ERR, "ehome: parsecode - invalid parameter passed %d", ehome->rawlen);
return;
}
for(i=0;i<ehome->rawlen-2;i+=4) {
if(ehome->raw[i+3] > (int)((double)AVG_PULSE_LENGTH*((double)PULSE_MULTIPLIER/2))) {
binary[i/4]=1;
} else {
binary[i/4]=0;
}
}
int id = binToDec(binary, 1, 3);
int state = binary[0];
createMessage(id, state);
}
static void createLow(int s, int e) {
int i;
for(i=s;i<=e;i+=4) {
ehome->raw[i]=AVG_PULSE_LENGTH;
ehome->raw[i+1]=(PULSE_MULTIPLIER*AVG_PULSE_LENGTH);
ehome->raw[i+2]=(PULSE_MULTIPLIER*AVG_PULSE_LENGTH);
ehome->raw[i+3]=AVG_PULSE_LENGTH;
}
}
static void createMed(int s, int e) {
int i;
for(i=s;i<=e;i+=4) {
ehome->raw[i]=(PULSE_MULTIPLIER*AVG_PULSE_LENGTH);
ehome->raw[i+1]=AVG_PULSE_LENGTH;
ehome->raw[i+2]=(PULSE_MULTIPLIER*AVG_PULSE_LENGTH);
ehome->raw[i+3]=AVG_PULSE_LENGTH;
}
}
static void createHigh(int s, int e) {
int i;
for(i=s;i<=e;i+=4) {
ehome->raw[i]=AVG_PULSE_LENGTH;
ehome->raw[i+1]=(PULSE_MULTIPLIER*AVG_PULSE_LENGTH);
ehome->raw[i+2]=AVG_PULSE_LENGTH;
ehome->raw[i+3]=(PULSE_MULTIPLIER*AVG_PULSE_LENGTH);
}
}
static void clearCode(void) {
createLow(0,47);
}
static void createId(int id) {
int binary[255];
int length = 0;
int i=0, x=0;
length = decToBinRev(id, binary);
for(i=0;i<=length;i++) {
if(binary[i]==1) {
x=i*4;
createHigh(4+x, 4+(x+3));
}
}
}
static void createState(int state) {
if(state == 0) {
createMed(0, 3);
} else {
createHigh(0, 3);
}
}
static void createFooter(void) {
ehome->raw[48]=(AVG_PULSE_LENGTH);
ehome->raw[49]=(PULSE_DIV*AVG_PULSE_LENGTH);
}
static int createCode(struct JsonNode *code) {
int id = -1;
int state = -1;
double itmp = 0;
if(json_find_number(code, "id", &itmp) == 0)
id = (int)round(itmp);
if(json_find_number(code, "off", &itmp) == 0)
state=0;
else if(json_find_number(code, "on", &itmp) == 0)
state=1;
if(id == -1 || state == -1) {
logprintf(LOG_ERR, "ehome: insufficient number of arguments");
return EXIT_FAILURE;
} else if(id > 7 || id < 0) {
logprintf(LOG_ERR, "ehome: invalid id range");
return EXIT_FAILURE;
} else {
createMessage(id, state);
clearCode();
createId(id);
createState(state);
createFooter();
ehome->rawlen = RAW_LENGTH;
}
return EXIT_SUCCESS;
}
static void printHelp(void) {
printf("\t -i --id=id\t\t\tcontrol a device with this id\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 ehomeInit(void) {
protocol_register(&ehome);
protocol_set_id(ehome, "ehome");
protocol_device_add(ehome, "ehome", "eHome Switches");
ehome->devtype = SWITCH;
ehome->hwtype = RF433;
ehome->minrawlen = RAW_LENGTH;
ehome->maxrawlen = RAW_LENGTH;
ehome->maxgaplen = MAX_PULSE_LENGTH*PULSE_DIV;
ehome->mingaplen = MIN_PULSE_LENGTH*PULSE_DIV;
options_add(&ehome->options, 'i', "id", OPTION_HAS_VALUE, DEVICES_ID, JSON_NUMBER, NULL, "^([0-4])$");
options_add(&ehome->options, 't', "on", OPTION_NO_VALUE, DEVICES_STATE, JSON_STRING, NULL, NULL);
options_add(&ehome->options, 'f', "off", OPTION_NO_VALUE, DEVICES_STATE, JSON_STRING, NULL, NULL);
options_add(&ehome->options, 0, "readonly", OPTION_HAS_VALUE, GUI_SETTING, JSON_NUMBER, (void *)0, "^[10]{1}$");
options_add(&ehome->options, 0, "confirm", OPTION_HAS_VALUE, GUI_SETTING, JSON_NUMBER, (void *)0, "^[10]{1}$");
ehome->parseCode=&parseCode;
ehome->createCode=&createCode;
ehome->printHelp=&printHelp;
ehome->validate=&validate;
}
#if defined(MODULE) && !defined(_WIN32)
void compatibility(struct module_t *module) {
module->name = "ehome";
module->version = "1.1";
module->reqversion = "6.0";
module->reqcommit = "84";
}
void init(void) {
ehomeInit();
}
#endif