• 10 dec 2017: forum version update. In case of issues use this topic.
  • 30 nov 2017: pilight moved servers. In case of issues use this topic.
Hello There, Guest! Login Register


Quigg GT-1000
#21
(01-11-2015, 04:17 PM)curlymo Wrote: @RinusW, can you by any chance make this into a pilight protocol?

Yes, I can and I will. Probably within a week or so. Maybe sooner, depends on .. well you know
 
Reply
#22
Cool!
 
Reply
#23
@RinusW
Hi, thx for your 'SendQuiggCode.pl' scripts!
I've tried it and they also work for my switches GT-FSI-07!

Code:
pi@Raspi1 ~/EasyHome $ ./SendQuiggCode.pl 5 A ON
For group-id 5 there is no codeseq# 2. Using 1 instead!
Code#1 for switch 5:A-ON = 010100011111101110110000
pi@Raspi1 ~/EasyHome $ ./SendQuiggCode.pl 5 A OFF
For group-id 5 there is no codeseq# 2. Using 1 instead!
Code#1 for switch 5:A-OFF = 010100100011110000100000
pi@Raspi1 ~/EasyHome $ ./SendQuiggCode.pl 5 B ON
Code#1 for switch 5:B-ON = 010111111110011101110100
pi@Raspi1 ~/EasyHome $ ./SendQuiggCode.pl 5 B OFF
For group-id 5 there is no codeseq# 4. Using 1 instead!
Code#1 for switch 5:B-OFF = 010100100011110000100100
pi@Raspi1 ~/EasyHome $ ./SendQuiggCode.pl 5 C ON
For group-id 5 there is no codeseq# 3. Using 1 instead!
Code#1 for switch 5:C-ON = 010100011111101110111100
pi@Raspi1 ~/EasyHome $ ./SendQuiggCode.pl 5 C OFF
For group-id 5 there is no codeseq# 2. Using 1 instead!
Code#1 for switch 5:C-OFF = 010101110001101000011100
pi@Raspi1 ~/EasyHome $ ./SendQuiggCode.pl 5 D ON
For group-id 5 there is no codeseq# 2. Using 1 instead!
Code#1 for switch 5:D-ON = 010111011100000110010010
pi@Raspi1 ~/EasyHome $ ./SendQuiggCode.pl 5 D OFF
Code#1 for switch 5:D-OFF = 010100111001111001000010
pi@Raspi1 ~/EasyHome $ ./SendQuiggCode.pl 5 M ON
Code#1 for switch 5:M-ON = 010110001000110110101010
pi@Raspi1 ~/EasyHome $ ./SendQuiggCode.pl 5 M OFF
For group-id 5 there is no codeseq# 4. Using 1 instead!
Code#1 for switch 5:M-OFF = 010110100111010000111010
pi@Raspi1 ~/EasyHome $

Every command works fine and the remote can be used too.
Well done! I'm waiting for the protocol ....
 
Reply
#24
@markus2004
Thanks for the feedback. Nice to hear that my assumptions were correct.

I was able to find and verify all the codes for group-id 5. I added them tot the script. So please download and reinstall this script.
I would also like to know if you can program your switch from pilight using another group-id (say group-id 14 would be a good candidate). You can do this by putting your switch in program mode and then say: ./SendQuiggCode.pl 14 A ON

Keep me informed :-)
 
Reply
#25
@RinusW: I'm on a business trip this week. I'll try your new script on saturday an keep you informed. Did you update the script in post #19?. Markus
 
Reply
#26
@markus2004: N.P. and yes, I updated the script in post # 19

@all:
Super-codes for Quigg GT-FSI-08 switches with GT-1000 RC
While I was playing around with code sequences for my switches I made an error and put a too large number in a wrong place. Suddenly all my switches got crazy and switched on and off and on and off and ... Well, you get the idea. This is how discoveries are made.
Analyzing what happens, I discovered a kind of super code sequence for these switches. We all know the Master key on the remote that switches on and off all switches in the same group. But these super codes go beyond that: they switch on and off all switches in all groups at the same time. Even switches that were never be used and as a consequence are not programmed, or switches with erased memories, do react to these super codes.
Writing the code sequence as
<4 bit group-id><16 bit random><4 bit unit-id>
super codes are found in all groups with id 0,1,4,5,8,9,12 and 13.
The unit-id is always equal to 8 or '1000'.
The random code should be equal to '1111000000dddddd' where the d's stand for the binary representation of the numbers for the:
on-codes: 5,8,12,13,21,24,28,29,37,40,44,45,53,56,60,61
off-codes: 0,6,14,15,16,22,30,31,32,38,46,47,48,54,62,63
Further investigation revealed that the 6 zero bits in the random sequence could in fact be replaced with any 6-bit sequence, leading to even more super codes.
Some examples of valid super codes based on the above scheme are:
on:
'000011110000000001011000', '000111110000000010001000', '010011110000000101011000', '010111110000000110001000',
'100011110000001001011000', '100111110000001010001000', '110011110000001011001000', '110111110000001111001000'
off:
'000011110000000000001000', '000111110000000001101000', '010011110000000011101000', '010111110000000101101000',
'100011110000000111101000', '100111110000001001101000', '110011110000001011101000', '110111110000001011111000'

I also developed a perl script for using these super codes. You can copy the script and install it in the home directory of your RPi. Then after giving execute rights call it with ./QuiggSuperCode.pl <on|off> Optionally you can add a number between 1..8 to select a particular code.
I am not sure about the implication of this super code yet, but I will make it available in my implementation of a protocol.
And now the script, based on my earlier script:
Code:
#!/usr/bin/perl
## This script creates raw super code sequences for Quigg GT-FSI-08 switches and compatibles.
## The script is based on a script published earlier by Lary_Loose
## see http://forum.pilight.org/Thread-Lidl-radio-outlets?page=2
##
## All codes are testen and do work with the Quigg switches.
## If needed adjust the pilight-send path in the $exe variable.
##
## You  need to specify state (on,off). You may specify the code sequence to use (1..8) and the number of repeats.
## Notice that a code sequence is repeated 2 times.

use strict;
use warnings;

if (@ARGV < 1)
{
    use File::Basename;
    printf("usage:\n %s <state> [codeseq] [repeat]\n", basename($0));
    printf("  state:  [ on off ]\n");
    printf("  codeseq:[1 .. 8]\n");
    printf("  repeat: [ 0 1 2 ... ]\n");
    exit 1;
}

my $exe = '/usr/local/bin/pilight-send -p raw -c ';
my $istate = (uc($ARGV[0]) eq 'ON') ? 1 : 0;
my $codeseq = (($ARGV[1]) ? $ARGV[1] : (int(rand(8))+1))-1;
my $repeat = ($ARGV[2]) ? $ARGV[2] : 0;

my @superoncode = (
# on codes for all switches
    '00001111000000000101', '00011111000000001000', '01001111000000010101', '01011111000000011000',
    '10001111000000100101', '10011111000000101000', '11001111000000101100', '11011111000000111100'
    );
my @superoffcode = (
# off codes for all switches
    '00001111000000000000', '00011111000000000110', '01001111000000001110', '01011111000000010110',
    '10001111000000011110', '10011111000000100110', '11001111000000101110', '11011111000000101111'
    );


my $starthi = 350;
my $startlo = 2340;
my $highmark = 1100;
my $highspace = 440;
my $lowmark = 330;
my $lowspace = 1210;
my $starter = "$starthi $startlo";
my $footer = "200";
my $high = "$highmark $highspace";
my $low = "$lowmark $lowspace";

my $bincode = ($istate == 1) ? $superoncode[$codeseq] : $superoffcode[$codeseq];
$bincode = $bincode.'1000';
printf("SuperCode#%s = %s\n",$codeseq+1, $bincode);

my @rawcode;
for my $i (0 .. (length($bincode)-1))
{
    push(@rawcode, (substr($bincode, $i, 1) eq '1') ? $high : $low);
}
for my $i (0 .. $repeat)
{
    my $out = `$exe "$starter @rawcode $starter @rawcode $footer"`;
    my $rc = $? >> 8;
    print $out;
    if ($rc) { exit $rc; }
}
exit 0;
 
Reply
#27
Hello RinusW!
I tested the new version of post #19 and I could program my switches GT-FSI-07 to a new id (14).
But only channel 'd' didn't work. Please, can you have a look?

Code:
pi@Raspi1 ~/EasyHome $ ./SendQuiggCodeNeu.pl 14 a on
Code#2 for switch 14:A-on = 111010111101101000011100
pi@Raspi1 ~/EasyHome $ ./SendQuiggCodeNeu.pl 14 b on
Code#3 for switch 14:B-on = 111001000000110011100101
pi@Raspi1 ~/EasyHome $ ./SendQuiggCodeNeu.pl 14 c on
Code#2 for switch 14:C-on = 111010101011101101111110
pi@Raspi1 ~/EasyHome $ ./SendQuiggCodeNeu.pl 14 d on
Code#4 for switch 14:D-on = 111000100101000110010111
pi@Raspi1 ~/EasyHome $ ./SendQuiggCodeNeu.pl 14 m on

As well i tried your new supercodes - and it works fine! Really a good job!
 
Reply
#28
@markus2004
hmmm, that is strange and unexpected. The code you showed is OK and is one of the four on-codes for quigg switch D. You do know that you can select one of the other codes, just by specifying a codesec? Eg ./SendQuiggCodeNeu.pl 14 d on 2 will use codeseq 2. If you don't specify one of the four codes will be used at random. So try one of the other codes?

Btw, my implementation of the protocol is more or less finished. Just trying to find a few more codes. So, I will publish the protocol implementation very soon now.
 
Reply
#29
@RinusW
I did some other tests with my switch and actually it reacts sometimes really abnormally. So it seems the switch has a hardware defect.

Now I changed the switch to another one and reran all the tests from yesterday. With the new switch everthing is OK!

Sorry for circumstances.

Your new protocol with a good documentation ;-) will become a big sucess!
Best wishes Markus
 
Reply
#30
Protocol implementation for GT-1000

I finished the development of a protocol implementation for Quigg GT-1000 RC with Quigg GT-FSI-08 switchable outlets. Although only tested with these switches, it is believed that the switchable outlets from Lidl and Brennenstuhl are compatible.

The implementation contains code sequences for group-id's as they are known and tested. A group-id contains a group of switches that can be controlled by a single RC. At the moment the group-id's 1, 3, 5, 9, 10, 14 and 15 are (partly) implemented. Partly because for some group-id's not all 4 codes per switch action are known yet. But that is not a real problem. If the group-id of your RC is not implemented that is not a problem either, because a switch can belong to different groups at the same time. So in that case: just select a different group to use with the pilight system.

The implementation supports also the so called super codes. These are code sequences that switch on and off all switches independent of the groups they belong to. Just specify that you want to use a super code and the on or off state, after which all your switches will switch to the desired state.

The RC GT-1000 sends pulse sequences with two different start pulses and no pauses in between. The short start pulse indicates a switch action, while the long start pulse is needed to program/self-learn a switch. In order to mimic this behavior the protocol implementation does send a code sequence three times in a row, the first two with a short start pulse, and the last one with the long start pulse. Testing shows that in this way a switch can be programmed (self-learned) in a reliable way using the pilight system. But this also implies that the message to the pilight-daemon is a long one, consisting of 150 bits, and the duration in the order of 120 ms. Therefore I advise to set the “send-repeats” in the settings.json file to a low value.

You call this protocol the same way as comparable protocol implementations. The parameters are:
-p = specify the protocol to use, in this case quigg_gt1000
-i = specify the group id, range 0 .. 15, can be omitted when using -s parameter
-u = specify the unit or switch to use, range 0..3, can be omitted when using -a or -s parameter
-a = use all switches in the given group, the -u parameter can be omitted and is irrelevant
-s = use all switches in all groups, the -u and -i parameters can be omitted and are irrelevant
-t = set state of selected switch(es) to on, either -t or -f but never both should be present
-f = set state of selected switch(es) to off, either -t or -f but never both should be present
The next two parameters are optional:
-n = specify the code sequence to use, range 0..3 (range 0..7 for the super codes (-s)). If the specified sequence does not exists, sequence 0 will be used instead. If not specified a sequence will be selected at random.

Some valid calls and their meaning are (everything between { and } is optional):
pilight-send -p quigg_gt1000 -i [0..15] -u [0..3] [-t|-f] {-n [0..3]}
switch on or off the specified switch (-u) belonging to group (-i) optionally using specified codeseq (-n)
pilight-send -p quigg_gt1000 -i [0..15] -a [-t|-f] {-n [0..3]}
switch on or off all switches belonging to group (-i) optionally using specified codeseq (-n)
pilight-send -p quigg_gt1000 -s [-t|-f] {-n [0..7]}
switch on or off all compatible switches optionally using specified codeseq (-n)

When using the Web-GUI use “unit”: 4 in the config.json file for the master switch (“all”: 1) and “id”: 16 with “unit”: 5 for the super code switch (“super”: 1).

Succes!
Both the header and the c-source files should be placed in /pilight/libs/protocols
The header file: quigg_gt1000.h
Code:
/*
    Copyright (C) 2014 CurlyMo & wo_rasp & RvW

    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/>
*/
/* Protocol quigg_gt1000 is an implementation of a protocol for the Quigg GT-FSI-08 switches
   with GT-1000 remote. It is believed that they are compatible with the Lidl and Brennenstuhl outlets
   RvW, jan 2015
*/

#ifndef _PROTOCOL_QUIGG_GT1000_H_
#define _PROTOCOL_QUIGG_GT1000_H_

/* function and data declarations */
struct protocol_t *quigg_gt1000;
void quigg_gt1000Init(void);
void quigg_gt1000PrintHelp(void);
int quigg_gt1000CreateCode(JsonNode *code);
void quigg_gt1000CreateMessage(int, int, int, int);

#endif

And the c-source file: quigg_gt1000.c
Code:
/*
    Copyright (C) 2015 CurlyMo & wo_rasp & RvW

    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/>
*/
/* Protocol quigg_gt1000 is an implementation of a protocol for the Quigg GT-FSI-08 switches
   with GT-1000 remote. It is believed that they are compatible with the Lidl and Brennenstuhl outlets
   RvW, jan 2015
   This implementation mimics the GT-1000 remote control with extensions
   These switches listen to the next command string of 24 bit:
   |-|0-----------4|5---------20|21------24|
   |S| group-id[4] | random[16] |unit-id[4]|
   |-|-------------|------------|----------|
   where:
   S=Start, a short high pulse of 350 us followed by a low of 2350 us
   group-id[4]= 4 logic bits for the group-id code, range 0..15
   unit-id[4]= 4 bits for the unit code for switches 1..4. Two different coding schemes are used
   random[16]= a 16 bit sequence where no bits seems to have a specific function. Each action
   for each switch uses 4 codes (40 in total for one group-id) that are transmitted in a rolling sequence by the RC
   Although codes are reused within a single group, for the sake of code simplicity and readability
   this implementation will not use this fact. So we will implement a table with 16*40 = 640 "random" codes
  
   A logic bit is encoded by the position of the high to low transition in the 1540 us bit window.
   A logic 1 therefore is encoded by a mark(high) of 1100 us followed by a space(low) of 440 us.
   A logic 0 is encoded by a mark of 330 us followed by a space of 1210 us
  
   The total message consists of 24 bit + start pulse, and has therefore a duration 39660 us
   There is no space between the repetition of a message, so the next message immediately follows the previous message
  
   To program a switch the RC uses a second type of start pulse with a mark(high) of 3000us and a space(low) of 7300us
   In order to be able to program switches from pilight, this implementation mimics this behavior by
   transmitting two normal code sequences followed by a program sequence with this long start pulse.
   This implies that the compete message in fact consists of 75 bits and a short footer.
*/

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

#include "../../pilight.h"
#include "common.h"
#include "log.h"
#include "protocol.h"
#include "hardware.h"
#include "binary.h"
#include "gc.h"
#include "quigg_gt1000.h"

/* define the basic protocol Mark-Space pulse width and other values*/
#define START_MARK 350
#define START_SPACE 2340
#define PROG_MARK 3000
#define PROG_SPACE 7300
#define SHORT_MARK  330
#define LONG_SPACE  1210
#define LONG_MARK   1100
#define SHORT_SPACE 440
#define FOOTER_MARK 200

#define BIN_LENGTH 24    /* binary command string contains 24 bit */
#define RAW_LENGTH 151    /* raw prot consist of 151 mark-space values incl footer */

int codetab[16][40] = {
    /* the next table contains the random codes (bits 4..19) of the 4 code sequences for
     * each off-on action for each switch 0..3 in each group-id 0..15.
     * For each group-id a separate array is created where de codes are stored in the next order:
     * off-codes 0..3 for switch 0, on-codes 0..3 for switch 0,
     * off-codes 0..3 for switch 1, on-codes 0..3 for switch 1,
     * off-codes 0..3 for switch 2, on-codes 0..3 for switch 2,
     * off-codes 0..3 for switch 3, on-codes 0..3 for switch 3,
     * off-codes 0..3 for all, on-codes 0..3 for all
     * If a code is unknown 0 is substituted, f.e. for group-id 0 no codes are known, so all 40 values are 0
     */
    /* code 0 */
    { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 },
    /* code 1 */
    { 0x616A,0xCF71,0x7AE2,0xB639, 0xF59B,0xE923,0x14C4,0x32A7,
      0x616A,0xB639,0xCF71,0x7AE2, 0x14C4,0x32A7,0xF59B,0xE923,
      0xCF71,0x616A,0x7AE2,0xB639, 0xE923,0xF59B,0x14C4,0x32A7,
      0x14C4,0xE923,0xF59B,0x32A7, 0x7AE2,0x616A,0xCF71,0xB639,
      0x14C4,0xE923,0xF59B,0x32A7, 0x7AE2,0x616A,0xB639,0xCF71 },
    /* code 2 */
    { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 },
    /* code 3 */
    { 0x32D7,0x7D4B,0x9482,0xC818, 0x067A,0x2901,0xB1B6,0xEA35,
      0x5B5C,0x6364,0x85F9,0xFEED, 0x1FA0,0x4CCF,0xA793,0xD02E,
      0x067A,0x2901,0xB1B6,0xEA35, 0x32D7,0x7D4B,0x9482,0xC818,
      0x1FA0,0x4CCF,0xA793,0xD02E, 0x5B5C,0x6364,0x85F9,0xFEED,
      0x067A,0x2901,0xB1B6,0xEA35, 0x32D7,0x7D4B,0x9482,0xC818 },
    /* code 4 */
    { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 },
    /* code 5 */
    { 0x23C2,0x71A1,0x88DA,0xDC19, 0x1FBB,0x39E4,0xA743,0xFE77,
      0x23C2,0x71A1,0x88DA,0xDC19, 0x1FBB,0x39E4,0xA743,0xFE77,
      0x23C2,0x71A1,0x88DA,0xDC19, 0x1FBB,0x39E4,0xA743,0xFE77,
      0x1FBB,0x39E4,0xA743,0xFE77, 0x23C2,0x71A1,0x88DA,0xDC19,
      0x1FBB,0x39E4,0xA743,0xFE77, 0x23C2,0x71A1,0x88DA,0xDC19 },
    /* code 6 */
    { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 },
    /* code 7 */
    { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 },
    /* code 8 */
    { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 },
    /* code 9 */
    { 0x1B1A,0x75C1,0xC0A2,0, 0x02FB,0x6EE7,0,0,
      0x1B1A,0x75C1,0xC0A2,0, 0x02FB,0x6EE7,0,0,
      0x1B1A,0x75C1,0xC0A2,0, 0x02FB,0x6EE7,0,0,
      0x02FB,0x6EE7,0,0, 0x1B1A,0x75C1,0xC0A2,0,
      0x02FB,0x6EE7,0,0, 0x1B1A,0x75C1,0xC0A2,0 },
    /* code 10 */
    { 0x9E98,0xC2AB,0xE057,0xF4F2, 0x460A,0x6971,0x77E6,0xBB25,
      0x0CBD,0x1589,0x51C4,0x8FDC, 0x2313,0x386F,0xAD3E,0xDA40,
      0x460A,0x6971,0x77E6,0xBB25, 0x9E98,0xC2AB,0xE057,0xF4F2,
      0x2313,0x386F,0xAD3E,0xDA40, 0x0CBD,0x1589,0x51C4,0x8FDC,
      0x460A,0x6971,0x77E6,0xBB25, 0x9E98,0xC2AB,0xE057,0xF4F2 },
    /* code 11 */
    { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 },
    /* code 12 */
    { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 },
    /* code 13 */
    { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0 },
    /* code 14 */
    { 0xE692,0x98F8,0x577B,0xABB7, 0x0AD6,0xBDA1,0xC465,0x6F4A,
      0xF234,0x89EC,0x2519,0x715D, 0x1383,0xDC2F,0x40CE,0x3E00,
      0x0AD6,0xBDA1,0xC465,0x6F4A, 0xE692,0x98F8,0x577B,0xABB7,
      0x1383,0xDC2F,0x40CE,0x3E00, 0xF234,0x89EC,0x2519,0x715D,
      0x0AD6,0xBDA1,0xC465,0x6F4A, 0xE692,0x98F8,0x577B,0xABB7 },
    /* code 15 */
    { 0x1067,0x3D02,0x9B1B,0, 0x2636,0x6C81,0xE5B5,0xF1FA,
      0x432D,0x54CC,0x8A79,0xC7D4, 0x7290,0xA85F,0xDFEE,0,
      0x2636,0x6C81,0xE5B5,0xF1FA, 0x1067,0x3D02,0x9B1B,0,
      0x7290,0xA85F,0xDFEE,0, 0x432D,0x54CC,0x8A79,0xC7D4,
      0x2636,0x6C81,0xE5B5,0xF1FA, 0x1067,0x3D02,0x9B1B,0 }
};

int unittab[2][5] = {
    /* This table defines the coding of the unit-id or switch-id. Two coding scemes are used
     * I call them first and second generation switches. They encode the unit-id in  a different way.
     */
    /* first gen group-id = 1, 5, 9, 12 */
    { 0x0, 0x4, 0xC, 0x2, 0xA }, /* these are 1st gen switch-codes for switch 0..3 and all */
    /* second gen all other */
    { 0xC, 0x5, 0xE, 0x7, 0x2 }    /* 2nd gen switch-codes */
};

int gentab[16] =
    /* This table defines the switch generation for each group-id
     * A 0 at location x means group-id x belongs to first generation, and a 1 means second generation
     */
     /* for now only group-id 1,5,9 and 12 are first generation */
    {1,0,1,1,1,0,1,1,1,0,1,1,0,1,1,1};

#define NRSUPERMASK 0x07
#define NRSUPERCODES (NRSUPERMASK+1)    /* we will use 8 on and 8 off supercodes */
/* make sure the number of Supercodes is always a power of 2, i.e. 2,4,8,16 ... */
int supercodes[2*NRSUPERCODES] = {
    /* since with supercodes group-id is irrelevant, the codes consist of the first 20 bits of the code sequence */
    /* OFF codes */
    0x0F000,0x1F006,0x4F00E,0x5F016,0x8F01E,0x9F026,0xCF02E,0xDF02F,
    /* ON codes */
    0x0F005,0x1F008,0x4F015,0x5F018,0x8F025,0x9F028,0xCF02C,0xDF03C };

/* declare my own binary code string */
char bincode[BIN_LENGTH+1];    /* +1 because we convert this to a string later on, so we need place for the last 0x00 */

int quigg_gt1000FillLow(int idx)
{    /* fill in the mark-space code for a logic Low = short pulse*/    
    quigg_gt1000->raw[idx++] = SHORT_MARK;
    quigg_gt1000->raw[idx++] = LONG_SPACE;
    return idx;
}

int quigg_gt1000FillHigh(int idx)
{    /* fill in the mark-space code for a logic High = long pulse*/    
    quigg_gt1000->raw[idx++] = LONG_MARK;
    quigg_gt1000->raw[idx++] = SHORT_SPACE;
    return idx;
}

void quigg_gt1000NumtoBin(int idx, int num, int len)
{    /* fill in bits idx to idx+len-1 for number, msb first */
    for( len--; len>=0; len--)
    {    
        bincode[idx+len] = (num&1); /* value is lsb num */
        num = num>>1; /* shift number 1 place to right, so 2th bit becomes lsb */
    }
}

int quigg_gt1000FillRawCode(void )
{    /* convert binary code in bincode[] to raw Mark-Space combis for this protocol */
    /* the complete RawCode consist of <startpulse><bincode><startpulse><bincode><progpulse><bincode><footer> */

    int idx = 0; /* the index into the raw matrix, starting with 0 */
    int cnt;
    
    quigg_gt1000->raw[idx++] = START_MARK; /* always start with start pulse */
    quigg_gt1000->raw[idx++] = START_SPACE;
    for( cnt=0; cnt<BIN_LENGTH; cnt++)
        idx = (bincode[cnt]==1)?quigg_gt1000FillHigh(idx):quigg_gt1000FillLow(idx);
    quigg_gt1000->raw[idx++] = START_MARK; /* start second sequence*/
    quigg_gt1000->raw[idx++] = START_SPACE;
    for( cnt=0; cnt<BIN_LENGTH; cnt++)
        idx = (bincode[cnt]==1)?quigg_gt1000FillHigh(idx):quigg_gt1000FillLow(idx);
    quigg_gt1000->raw[idx++] = PROG_MARK; /* program sequence */
    quigg_gt1000->raw[idx++] = PROG_SPACE;
    for( cnt=0; cnt<BIN_LENGTH; cnt++)
        idx = (bincode[cnt]==1)?quigg_gt1000FillHigh(idx):quigg_gt1000FillLow(idx);
    quigg_gt1000->raw[idx++] = FOOTER_MARK;
    return idx;
}

int quigg_gt1000FillBinCode(int id,int unit,int state, int codeseq)
{
    int genindex, rcodeindex;
    
    /* encode id */    
    quigg_gt1000NumtoBin(0, id, 4); /* first 4 bits [0..3] is id-code */
    
    /* encode the right random code, depends on id, state and unit, state=0,1 */
    rcodeindex= 8*unit + 4*state; /*calculate second index into codetab*/
    if( codetab[id][rcodeindex + codeseq] == 0 )    /* no random code available? */
    {    /* then try first index */
        if(  codetab[id][rcodeindex] == 0 ) /* and no first code available? */
        {    logprintf(LOG_ERR, "\nquigg_gt1000: no random code available for this switch action");
            return EXIT_FAILURE;
        }
        else {
            logprintf(LOG_WARNING, "\nquigg_gt1000: seq#%d not available for this switch action, using #0 instead", codeseq);
            codeseq = 0;
        }
    }
    /* now we have an index for a valid random code, so put it in our codetab  starting at position 4 */
    quigg_gt1000NumtoBin(4, codetab[id][rcodeindex + codeseq], 16);
    
    /* encode the unit part of the command */
    /* key1..4 represents unit0..3, encoding depends on generation */
    /* master key results in unit=4, encoding depends on generation */
    genindex = gentab[id];    /* get 0 or 1 depending on generation of group-id */
    quigg_gt1000NumtoBin(20,unittab[genindex][unit], 4); /* get unit-id from tab and encode starting at pos 20 */
    return EXIT_SUCCESS;
}

void quigg_gt1000FillSuperBinCode(int state, int codeseq)
{    
    /* encode the right random supercode, depends on state=0,1 and codeseq*/
   quigg_gt1000NumtoBin(0, supercodes[NRSUPERCODES*state + codeseq], 20);
    
    /* encode the unit part of the command, is always 1000 or 8 */
    quigg_gt1000NumtoBin(20, 8, 4);
}

void quigg_gt1000Init(void) {
    // initialize datastruct for this protocol

    protocol_register(&quigg_gt1000);
    protocol_set_id(quigg_gt1000, "Quigg_gt1000");
    protocol_device_add(quigg_gt1000, "quigg_gt1000", "Quigg GT-1000 protocol");
    
    quigg_gt1000->hwtype = RF433;
    quigg_gt1000->devtype = SWITCH;
    
    quigg_gt1000->printHelp = &quigg_gt1000PrintHelp;
    quigg_gt1000->createCode = &quigg_gt1000CreateCode;
    
    quigg_gt1000->rawlen = RAW_LENGTH;    
    quigg_gt1000->binlen = BIN_LENGTH;    
    quigg_gt1000->txrpt = 1;        /* repeat xmit code 1 times */
    
    options_add(&quigg_gt1000->options, 't', "on", OPTION_NO_VALUE, CONFIG_STATE, JSON_STRING, NULL, NULL);
    options_add(&quigg_gt1000->options, 'f', "off", OPTION_NO_VALUE, CONFIG_STATE, JSON_STRING, NULL, NULL);
    options_add(&quigg_gt1000->options, 'u', "unit", OPTION_HAS_VALUE, CONFIG_ID, JSON_NUMBER, NULL, "^([0-5])$");
    options_add(&quigg_gt1000->options, 'i', "id", OPTION_HAS_VALUE, CONFIG_ID, JSON_NUMBER, NULL, "^(1[0-6]|[0-9])$");
    options_add(&quigg_gt1000->options, 'a', "all", OPTION_NO_VALUE, CONFIG_SETTING, JSON_NUMBER, NULL, NULL);
    options_add(&quigg_gt1000->options, 's', "super", OPTION_NO_VALUE, CONFIG_SETTING, JSON_NUMBER, NULL, NULL);
    options_add(&quigg_gt1000->options, 0, "gui-readonly", OPTION_HAS_VALUE, CONFIG_SETTING, JSON_NUMBER, (void *)0, "^[10]{1}$");
    options_add(&quigg_gt1000->options, 'n', "num", OPTION_HAS_VALUE, CONFIG_SETTING, JSON_NUMBER, NULL, "^([0-3])$");
}

void quigg_gt1000PrintHelp(void) // print help for this protocol (send -p <name> -H)
{
    printf("\t This is help for the Quigg GT-1000 with GT-FSI-08 switches\n");
    printf("\t -t --on\tsend an on signal\n");
    printf("\t -f --off\tsend an off signal\n");
    printf("\t -u --unit=unit\tcontrol a device with this unit code\n");
    printf("\t -i --id=id\tcontrol a device with this id\n");
    printf("\t -a --all\tcontrol all devices with this id\n");
    printf("\t -s --super\tcontrol all devices regardless of id\n");
    printf("\t -n --num\toptional use random (super)code sequence num 0..3(%d)\n", NRSUPERCODES-1);
    printf("Valid calls to pilight-send are: \n");
    printf("pilight-send -p quigg_gt1000 -i [0..15] -u [0..3] [-f|-t] {-n [0..3]}\n");
    printf("pilight-send -p quigg_gt1000 -i [0..15] -a [-f|-t] {-n [0..3]}\n");
    printf("pilight-send -p quigg_gt1000 -s [-f|-t] {-n [0..7]}\n");
    printf("where everything between { and } is optional.\n");
    
}

int quigg_gt1000CreateCode(JsonNode *code) // function to create the raw code
{
    int id = -1;
    int unit = -1;
    int all = 0;
    int super = 0;
    int state = -1;
    int seq = -1;
    double itmp = -1;

    if(json_find_number(code, "num", &itmp) == 0)
        seq = (int)round(itmp);
    if(json_find_number(code, "id", &itmp) == 0)
        id = (int)round(itmp);
    if(json_find_number(code, "unit", &itmp) == 0)
        unit = (int)round(itmp);
    if(json_find_number(code, "all", &itmp) == 0)
        all = (int)round(itmp);
    if(json_find_number(code, "super", &itmp) == 0)
        super = (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(seq == -1) /* no seqnr was given, a random seqnr will be used */
    {    srand ((unsigned int)time (0));    /* seed the random generator with current time */
        seq = rand() & ((super == 1)? NRSUPERMASK:0x03); /* use last bits of random number */
    }

    if((id == -1 && super==0) || (unit == -1 && all==0 && super==0) || state == -1) {
        logprintf(LOG_ERR, "\nquigg_gt1000: insufficient number of arguments");
        return EXIT_FAILURE;
    } else if((id >15 || id < 0) && super == 0) {
        logprintf(LOG_ERR, "\nquigg_gt1000: invalid id range");
        return EXIT_FAILURE;
    } else if((unit > 3 || unit < 0) && all == 0 && super == 0){
        logprintf(LOG_ERR, "\nquigg_gt1000: invalid unit range");
        return EXIT_FAILURE;
    } else if(((seq > 3 || seq < 0) && super == 0) || ((seq >= NRSUPERCODES || seq < 0) && super != 0)){
        logprintf(LOG_ERR, "\nquigg_gt1000: invalid optional seq number");
        return EXIT_FAILURE;
    } else
    {
        if(all == 1) /* all overrides unit selection */
            unit = 4;
         /* first create binary command string */
        if(super == 1)    /* do we want supercodes?  */
        {    /* for supercodes we use a non-existend id and unit */
            id = 16; /* this does only influence the CreateMessage and not the bin code generation */
            unit = 5;
            quigg_gt1000FillSuperBinCode( state, seq); /*create binary supercode string */
        }
        else if( quigg_gt1000FillBinCode( id, unit, state, seq) != EXIT_SUCCESS)
            return EXIT_FAILURE; /* failure because no codeseq was available */
            
        /* and now convert binary to Mark-Space combis */
        if( quigg_gt1000FillRawCode() != quigg_gt1000->rawlen)
        {
            /* this Error should never occur. It indicates a wrong raw protocol length or misaligned fill */
            logprintf(LOG_ERR, "\nquigg_gt1000: raw index not correct");
            return EXIT_FAILURE;
        }    
        quigg_gt1000CreateMessage(id, unit, state, seq);
    }
    return EXIT_SUCCESS;
}

void quigg_gt1000CreateMessage( int id, int unit, int state, int seq)
{
    int i;
    
    for( i=0; i< BIN_LENGTH; i++)
        bincode[i] = bincode[i] | 0x30; /* convert bin 0,1 into char 0,1 */
    bincode[BIN_LENGTH] = '\0'; /* end of string */
    quigg_gt1000->message = json_mkobject();
    json_append_member(quigg_gt1000->message, "id", json_mknumber(id));
    json_append_member(quigg_gt1000->message, "unit", json_mknumber(unit));
    json_append_member(quigg_gt1000->message, "seq", json_mknumber(seq));
    if(state == 1)
        json_append_member(quigg_gt1000->message, "state", json_mkstring("on"));
    else
        json_append_member(quigg_gt1000->message, "state", json_mkstring("off"));
    json_append_member(quigg_gt1000->message, "code", json_mkstring(bincode));
}
 
Reply
  


Possibly Related Threads...
Thread Author Replies Views Last Post
  QUIGG GT9000 (Globaltronics/ALDI) NeoFlo 139 68,881 10-02-2019, 05:01 PM
Last Post: blackzombie
  Brennenstuhl RCR CE1 1011 with QUIGG GT9000 Protocol scootermacro 1 332 06-27-2019, 06:20 PM
Last Post: scootermacro
  quigg gt7000 Dimmer wchristi 11 8,246 04-30-2015, 09:25 AM
Last Post: wo_rasp
  Quigg Screens curlymo 6 4,073 01-31-2015, 07:33 PM
Last Post: curlymo
  QUIGG (Globaltronics/ALDI) neevedr 49 33,821 01-12-2015, 10:01 AM
Last Post: wo_rasp
  Kaku PAT-103 / PAR-1000 davem 0 2,199 04-20-2014, 10:51 PM
Last Post: davem
  Alecto WS-1000 koffie 1 2,111 12-30-2013, 10:19 PM
Last Post: curlymo
  [Fully Supported] IT PA3-1000 nett_flanders 55 23,205 09-11-2013, 04:42 PM
Last Post: Bram

Forum Jump:


Browsing: 1 Guest(s)