Author Topic: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100  (Read 139293 times)

0 Members and 1 Guest are viewing this topic.

Offline mycal

  • Member
  • *
  • Posts: 24
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #300 on: May 08, 2014, 04:33:30 PM »
FYI here is the output of the 00:70 packet when adjusting the history interval.

I do know that this packet does affect the sending of the 00:70 packet, I was pretty sure at one time that it was in seconds, IE:
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 00 f0

caused a 00:70 packet to be sent every 240 seconds,  I know I did adjust it down to 5 seconds and it worked.   I cannot find my notes on this but as far as I could tell it only affected this packet, but I did not play with the fields or set the upper bytes to FF FF ...

-M



All these assume
Request:
HTTP_IDENTIFY: xxx:00:xxx:70


15 Min:
------------------------------------------------------
Reply from server:

HTTP_FLAGS:  70:00
00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 00 f0
 

30 min:
------------------------------------------------------
Reply from server:

HTTP_FLAGS:  70:00
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 04 d7 


1hr:
------------------------------------------------------
Reply from server:

HTTP_FLAGS:  70:00
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 04 b8 


2hr:
------------------------------------------------------
Reply from server:

HTTP_FLAGS:  70:00
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 04 c5 

Offline skydvrz

  • Senior Contributor
  • ****
  • Posts: 224
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #301 on: May 08, 2014, 05:28:36 PM »
Epoch information is also sent by the GW in the 30 byte 0101 packet.  It should be fairly easy to derive the interval from that.  The 30 byte packet is not sent very often though.

Offline keckec

  • Senior Member
  • **
  • Posts: 62
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #302 on: May 08, 2014, 07:38:29 PM »
Epoch information is also sent by the GW in the 30 byte 0101 packet.  It should be fairly easy to derive the interval from that.  The 30 byte packet is not sent very often though.
Following is my take on what some of the various length packets are about, including the 30-byte packets. I think the 30-byte packets are the last packet of a longer dump of history data, which starts with a 210-byte packet if there is enough data to fill one. The 30-byte packets start with 0x2164, same as the 210-byte ones, which I think this is a data type indicator. In each of these the first 8 bytes are a header. Bytes 4 & 5 of that are the epoch, which I think might actually be the address in memory where the next piece of history data will be written.

Bytes 6 & 7 are an address 0x12 higher than the address of the newest history record in the packet. History in the packet is chronologically reversed, so the most recent is sent as the first record in the packet. The address of the oldest record in the packet is in the 2 bytes before the 2-byte crc at the end of the packet, regardless of the overall packet size. The oldest address of a packet is the same as that in bytes 6 & 7 of the previous packet. Records seem to be 18 bytes long (0x12 == the increment value of the address, or epoch), and 11 records fit into a 210-byte packet: 8 bytes header, + (11 records * 18 bytes/record) + 2 bytes starting address + 2 bytes crc = 210 bytes total. Other numbers of records fit in various length packets: 30,48, 66, 84, 102, 120, 138, 156, 174, 192, and 210 bytes, corresponding to 1 through 11 history records each. I've seen all these length packets come from the GW.

If a 0101 0x2164 packet is the final one in the dump, the address in bytes 6 & 7 is the same as the address in bytes 4 & 5. I think bytes 4 & 5 contain the address of the next history record to be dumped, 0x12 bytes higher than the most recent one in the packet, and bytes 6 & 7 contain the address of the next place history should be saved. If the last history record dumped is the last one, these two addresses will be the same. I've found this is always the case for 0101 packets starting with 0x2164 that are less than 210 bytes long. It may be the case of some of the 210-byte packets as well, if the amount of history being dumped happens to just fit in 210-byte packets, but I haven't checked this.
« Last Edit: May 08, 2014, 07:50:31 PM by keckec »

Offline skydvrz

  • Senior Contributor
  • ****
  • Posts: 224
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #303 on: May 08, 2014, 10:06:46 PM »
I think that in the context of a single user system with either an embedded database or a local MySQL DB engine, a server app will not have the same problems LCX does.  Things like oversubscription and flaky software.  Is it worth putting a lot of effort into parsing the historical data when we have everything we need in the 197 byte 0101 packet?

The only people that would need historical data would be the folks that want to shut their computers off at night.  That might be dangerous to your data if you forget to turn it back on in the morning and overrun your history buffer.

Offline keckec

  • Senior Member
  • **
  • Posts: 62
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #304 on: May 09, 2014, 12:40:24 AM »
I think that in the context of a single user system with either an embedded database or a local MySQL DB engine, a server app will not have the same problems LCX does.  Things like oversubscription and flaky software.  Is it worth putting a lot of effort into parsing the historical data when we have everything we need in the 197 byte 0101 packet?
I agree. I wasn't suggesting to include it in anything you're doing. It was mainly to share what I've found, in case it would help anyone.

Offline 10ACTony

  • Senior Member
  • **
  • Posts: 71
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #305 on: May 14, 2014, 05:29:10 PM »
WOW it's quiet again.  4 days without a peep.
//
No trees were destroyed in the sending of this message though a significant number of electrons were terribly inconvenienced.
//

Offline skydvrz

  • Senior Contributor
  • ****
  • Posts: 224
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #306 on: May 14, 2014, 06:29:02 PM »
I am busy with the next release!

Offline 10ACTony

  • Senior Member
  • **
  • Posts: 71
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #307 on: May 15, 2014, 11:19:55 AM »
I am busy with the next release!

 =D>
//
No trees were destroyed in the sending of this message though a significant number of electrons were terribly inconvenienced.
//

Offline skydvrz

  • Senior Contributor
  • ****
  • Posts: 224
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #308 on: May 20, 2014, 09:38:22 PM »
Update:

I have improved my packet dissector so that it can handle nybble offsets into packets.  The old one could not handle some fields that did not start on byte boundaries. This hid some of the more obscure data fields.  While none of the new fields are needed by WU, they may be useful if you are saving data to your own MySQL database for later analysis.

The new SDP packet dissector:

Code: [Select]
UNIT sssSDP;

INTERFACE

TYPE
    TDTBytes =
        (
        DTYr,
        DTMo,
        DTD,
        DTH,
        DTM
        );

    TBCDDateTime = ARRAY[TDTBytes] OF Byte;
    TRainArray   = ARRAY[0..11] OF Byte;
    TWindHist    = ARRAY[0..3] OF Byte;
    TKWord       = ARRAY[0..1] OF Byte;
    TRainElement = ARRAY[0..3] OF Byte;
    TBP          = ARRAY[0..1] OF Byte;
 
    // self-reading record - conversion done elsewhere
    TSDPRecA = PACKED RECORD
    PRIVATE
        Flags: ARRAY[0..196] OF Byte;  // payload goes here
        FUNCTION GetBCDDateTime(CONST Index : Integer) : TBCDDateTime;
        FUNCTION GetBP(CONST Index : Integer) : TBP;
        FUNCTION GetByte(CONST Index : Integer) : Byte;
        FUNCTION GetRainArray(CONST Index : Integer) : TRainArray;
        FUNCTION GetRainElement(CONST Index : Integer) : TRainElement;
        FUNCTION GetWindHist(CONST Index : Integer) : TWindHist;
        FUNCTION GetWord(CONST Index : Integer) : TKWord;
        PROCEDURE FillResult(VAR R; CONST BuffSize, aIndex : Integer);
    PUBLIC
        PROCEDURE Dump;  // debug only
        PROCEDURE WriteProp(VAR F : TextFile; CONST PropName : STRING; VAR Prop; PropSize : Byte); // debug only
        // index is $OOOOOOLL where O=field offset in nybbles into payload and LL= length in nybbles of the field
        // Property getters shift all nybbles in a field to the rightmost position (on odd length fields)
        PROPERTY PacketID: Byte index $0002 Read GetByte;
        PROPERTY Status: TKWord index $0603 Read GetWord;
        PROPERTY DTMaxIT: TBCDDateTime index $090a Read GetBCDDateTime;
        PROPERTY DtMinIT: TBCDDateTime index $130a Read GetBCDDateTime;
        PROPERTY MaxIT: TKWord index $1d03 Read GetWord;
        PROPERTY MinIT: TKWord index $2203 Read GetWord;
        PROPERTY CurrIT: TKWord index $2703 Read GetWord;
        PROPERTY DtMaxOT: TBCDDateTime index $2d0a Read GetBCDDateTime;
        PROPERTY DtMinOT: TBCDDateTime index $370a Read GetBCDDateTime;
        PROPERTY MaxOT: TKWord index $4103 Read GetWord;
        PROPERTY MinOT: TKWord index $4603 Read GetWord;
        PROPERTY CurrOT: TKWord index $4b03 Read GetWord;
        PROPERTY DtUnknown1: TBCDDateTime index $510a Read GetBCDDateTime;
        PROPERTY DtUnknown2: TBCDDateTime index $5b0a Read GetBCDDateTime;
        PROPERTY DtUnknown3: TBCDDateTime index $650a Read GetBCDDateTime;  // invalid date in test case
        PROPERTY CurrOT2: TKWord index $6403 Read GetWord;
        PROPERTY Stat2: Byte index $7202 Read GetByte;
        PROPERTY DtMaxIH: TBCDDateTime index $740a Read GetBCDDateTime;
        PROPERTY DtMinIH: TBCDDateTime index $7e0a Read GetBCDDateTime;
        PROPERTY MaxIH: Byte index $8802 Read GetByte;
        PROPERTY MinIH: Byte index $8a02 Read GetByte;
        PROPERTY CurIH: Byte index $8c02 Read GetByte;
        PROPERTY DtMaxOH: TBCDDateTime index $8e0a Read GetBCDDateTime;
        PROPERTY DtMinOH: TBCDDateTime index $980a Read GetBCDDateTime; // this may have wrong offset - invalid date in test case
        PROPERTY MaxOH: Byte index $a202 Read GetByte;
        PROPERTY MinOH: Byte index $a402 Read GetByte;
        PROPERTY CurrOH: Byte index $a602 Read GetByte;
        PROPERTY DtUnknown4: TBCDDateTime index $d40a Read GetBCDDateTime;
        PROPERTY DtLast1HrRain: TBCDDateTime index $ea0a Read GetBCDDateTime;
        PROPERTY DtLastRainReset: TBCDDateTime index $1010a Read GetBCDDateTime;
        PROPERTY RainHistory: TRainArray index $10b17 Read GetRainArray; // break elements into separate properties?
        PROPERTY RFTotal: TRainElement index $11208 Read GetRainElement;
        PROPERTY AvgWind: TKWord index $12204 Read GetWord;
        PROPERTY WindDirHist: TWindHist index $12a06 Read GetWindHist;
        PROPERTY DtMaxGust: TBCDDateTime index $1300a Read GetBCDDateTime;
        PROPERTY MaxGust: TKWord index $13a04 Read GetWord;
        PROPERTY CurrGust: TKWord index $14004 Read GetWord;
        PROPERTY WindStat: TKWord index $14404 Read GetWord;
        PROPERTY WindDirHist2: TWindHist index $14806 Read GetWindHist;
        PROPERTY CurrBP: TBP index $14f04 Read GetBP;
        PROPERTY BPDelta: TWindHist index $15306 Read GetWindHist; // this is a guess
        PROPERTY MinBp: TBP index $15904 Read GetBP;
        PROPERTY MaxBp: TBP index $16304 Read GetBP;
        PROPERTY DtUnknown5: TBCDDateTime index $16c0a Read GetBCDDateTime; // bp related?
        PROPERTY DtUnknown6: TBCDDateTime index $1760a Read GetBCDDateTime; // bp related?
        PROPERTY CheckSum: TKword index $18604 Read GetWord;
    END;

IMPLEMENTATION

USES
    dgLib,
    SysUtils;

{ TSDPRecA }

// debug only - not typically used
PROCEDURE TSDPRecA.Dump;
VAR
    Dt : TBCDDateTime;
    R :  TRainArray;
    Wh : TWindHist;
    W :  TKWord;
    B :  Byte;
    F :  TextFile;
    BP : TBP;
BEGIN
    AssignFile(F, 'junk.txt');
    Rewrite(F);

    B := PacketID;
    WriteProp(F, 'PacketID', B, SizeOf(Byte));   // Byte

    W := Status;
    WriteProp(F, 'Status', W, SizeOf(TKWord));   // TTemp

    Dt := DTMaxIT;
    WriteProp(F, 'DTMaxIT', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    Dt := DtMinIT;
    WriteProp(F, 'DtMinIT', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    W := MaxIT;
    WriteProp(F, 'MaxIT', W, SizeOf(TKWord));   // TKWord

    W := MinIT;
    WriteProp(F, 'MinIT', W, SizeOf(TKWord));   // TKWord

    W := CurrIT;
    WriteProp(F, 'CurrIT', W, SizeOf(TKWord));   // TKWord

    Dt := DtMinOT;
    WriteProp(F, 'DtMinOT', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    W := MaxOT;
    WriteProp(F, 'MaxOT', W, SizeOf(TKWord));   // TKWord

    W := MinOT;
    WriteProp(F, 'MinOT', W, SizeOf(TKWord));   // TKWord

    W := CurrOT;
    WriteProp(F, 'CurrOT', W, SizeOf(TKWord));   // TKWord

    Dt := DtUnknown1;
    WriteProp(F, 'DtUnknown1', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    Dt := DtUnknown2;
    WriteProp(F, 'DtUnknown2', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    Dt := DtUnknown3;
    WriteProp(F, 'DtUnknown3', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    W := CurrOT2;
    WriteProp(F, 'CurrOT2', W, SizeOf(TKWord));   // TKWord

    B := Stat2;
    WriteProp(F, 'Stat2', B, SizeOf(Byte));   // Byte

    Dt := DtMaxIH;
    WriteProp(F, 'DtMaxIH', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    Dt := DtMinIH;
    WriteProp(F, 'DtMinIH', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    B := MaxIH;
    WriteProp(F, 'MaxIH', B, SizeOf(Byte));   // Byte

    B := MinIH;
    WriteProp(F, 'MinIH', B, SizeOf(Byte));   // Byte

    Dt := DtMaxOH;
    WriteProp(F, 'DtMaxOH', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    Dt := DtMinOH;
    WriteProp(F, 'DtMinOH', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    B := MaxOH;
    WriteProp(F, 'MaxOH', B, SizeOf(Byte));   // Byte

    B := MinOH;
    WriteProp(F, 'MinOH', B, SizeOf(Byte));   // Byte

    B := CurrOH;
    WriteProp(F, 'CurrOH', B, SizeOf(Byte));   // Byte

    Dt := DtUnknown4;
    WriteProp(F, 'DtUnknown4', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    Dt := DtLast1HrRain;
    WriteProp(F, 'DtLast1HrRain', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    Dt := DtLastRainReset;
    WriteProp(F, 'DtLastRainReset', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    R := RainHistory;
    WriteProp(F, 'RainHistory', R, SizeOf(TRainArray));   // TRainArray

    W := AvgWind;
    WriteProp(F, 'AvgWind', W, SizeOf(TKWord));   // TKWord

    Wh := WindDirHist;
    WriteProp(F, 'WindDirHist', Wh, SizeOf(TWindHist));   // TWindHist

    Dt := DtMaxGust;
    WriteProp(F, 'DtMaxGust', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    W := MaxGust;
    WriteProp(F, 'MaxGust', W, SizeOf(TKWord));   // TKWord

    W := CurrGust;
    WriteProp(F, 'CurrGust', W, SizeOf(TKWord));   // TKWord

    W := WindStat;
    WriteProp(F, 'WindStat', W, SizeOf(TKWord));   // TKWord

    Wh := WindDirHist2;
    WriteProp(F, 'WindDirHist2', Wh, SizeOf(TWindHist));   // TWindHist

    BP := CurrBP;
    WriteProp(F, 'CurrBP', BP, SizeOf(TBP));   // TKWord

    Wh := BPDelta;
    WriteProp(F, 'BPDelta', Wh, SizeOf(TWindHist));   // TWindHist

    BP := MinBp;
    WriteProp(F, 'MinBp', BP, SizeOf(TBP));   // TKWord

    BP := MaxBp;
    WriteProp(F, 'MaxBp', BP, SizeOf(TBP));   // TBP

    Dt := DtUnknown5;
    WriteProp(F, 'DtUnknown5', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    Dt := DtUnknown6;
    WriteProp(F, 'DtUnknown6', Dt, SizeOf(TBCDDateTime));   // TBCDDateTime

    W := CheckSum;
    WriteProp(F, 'CheckSum', W, SizeOf(TKword));   // TKword

    CloseFile(F);
END;

// fill output buffer R with the contents of the payload, at the given offset
// and expected field length
PROCEDURE TSDPRecA.FillResult(VAR R; CONST BuffSize, aIndex : Integer);
VAR
    I,
    NybOffset : Integer;
    NrNybs :    Integer;
    Mask :      Integer;
    INyb :      Integer;
    Nt,
    B :         Byte;
    Buff :      TByteArray Absolute R;
    IBuff :     Integer;
BEGIN
    NrNybs    := aIndex AND $FF;
    NybOffset := aIndex SHR 8;

    IF (NrNybs SHR 1) > Buffsize THEN
        RAISE Exception.Create('Buffer Overrun Detected');

    FillChar(Buff, BuffSize, 0); // clear the buffer - set it to all zeros

                                 // field is located completely on natural byte boundary, so just copy bytes
    IF (NOT Odd(NybOffset)) AND (NOT Odd(NrNybs)) THEN BEGIN
        FOR I := 0 TO (NrNybs DIV 2) - 1 DO
            Buff[I] := Flags[(NybOffset DIV 2) + I];
        EXIT;
    END;

    // field was not on byte boundary, so do nybble copy
    FOR INyb := NybOffset TO NybOffset + NrNybs - 1 DO BEGIN
        // get the nybble we want from the flag array and put it into Nt
        B := Flags[INyb DIV 2];

        // calculate where we want to put the nybbles in the output buffer
        IBuff := (INyb - NybOffset) DIV 2;

        IF Odd(INyb) THEN BEGIN
            Nt          := (B AND $F);                         // get the right nybble
            Buff[IBuff] := (Buff[IBuff] AND $F) OR (Nt SHL 4); // or it into the proper place in the output buffer
        END
        ELSE BEGIN
            Nt          := (B AND $F0) SHR 4; // get the left nybble
            Buff[IBuff] := (Buff[IBuff] AND $F0) OR Nt;
        END;
    END;

    // shift all nybbles 4 bits to right, if there is dead space on the far right of the output buffer
    IF Odd(NrNybs) THEN BEGIN
        // go backwards through the output buffer
        FOR INyb := NrNybs DIV 2 DOWNTO 1 DO BEGIN
            Buff[INyb]     := Buff[INyb] SHR 4;               // shift it right one nybble
            B              := (Buff[INyb - 1] AND $0F) SHL 4; // get neighbor low nybble on left and shift it to high nybble
            Buff[INyb]     := Buff[INyb] OR B;                // move it to current byte
            Buff[INyb - 1] := Buff[INyb - 1] SHR 4;           // shift neighbors upper nybble into lower nybble
        END; // shampoo, rinse and repeat
    END;
END;

FUNCTION TSDPRecA.GetBCDDateTime(CONST Index : Integer) : TBCDDateTime;
BEGIN
    FillResult(Result, SizeOf(Result), Index);
END;

FUNCTION TSDPRecA.GetBP(CONST Index : Integer) : TBP;
BEGIN
    FillResult(Result, SizeOf(Result), Index);
END;

FUNCTION TSDPRecA.GetRainArray(CONST Index : Integer) : TRainArray;
BEGIN
    FillResult(Result, SizeOf(Result), Index);
END;

FUNCTION TSDPRecA.GetRainElement(CONST Index : Integer) : TRainElement;
BEGIN
    FillResult(Result, SizeOf(Result), Index);
END;

FUNCTION TSDPRecA.GetByte(CONST Index : Integer) : Byte;
BEGIN
    FillResult(Result, SizeOf(Result), Index);
END;

FUNCTION TSDPRecA.GetWindHist(CONST Index : Integer) : TWindHist;
BEGIN
    FillResult(Result, SizeOf(Result), Index);
END;

FUNCTION TSDPRecA.GetWord(CONST Index : Integer) : TKword;
BEGIN
    FillResult(Result, SizeOf(Result), Index);
END;

PROCEDURE TSDPRecA.WriteProp(VAR F : TextFile; CONST PropName : STRING; VAR Prop; PropSize : Byte);
VAR
    B : TByteArray Absolute Prop;
    I : Integer;
BEGIN
    Write(F, PadTrim(PropName, 20));
    FOR I := 0 TO PropSize - 1 DO
        Write(F, IntToHex(B[I], 2) + ' ');
    WRITELN(F);
END;

END.


Offline keckec

  • Senior Member
  • **
  • Posts: 62
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #309 on: May 21, 2014, 03:25:25 PM »
Here is my current layout for the 197-byte data packets. I have a few more experiments to run to look for more, and may get to that this weekend. There is likely nothing new here that is important for WU, but I may use a few for my stuff.

http://www.keckec.com/weather/LCX_Data_Layout.pdf

Several data fields are followed in the packet by fields that are almost always 0. Some of these I have verified contain data valid flags. I suspect some of the others may as well. Ones connected by RF links are relatively easy to test, but the ones which aren't (inside temp/humidity, for instance), may be impossible to verify without unsoldering some parts.

There are some I've listed as all-time max and min values. They may be in fact be automatically reset on some schedule such as yearly, or maybe Jun 30 -> July 1. I did test for reset over a new-year transition by setting the clock ahead to Dec 31, but nothing was reset. There may be a way to remotely reset these, but I haven't tried.

Corrections & comments welcome
« Last Edit: May 21, 2014, 03:48:01 PM by keckec »

Offline skydvrz

  • Senior Contributor
  • ****
  • Posts: 224
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #310 on: May 22, 2014, 08:33:23 PM »
Here is my current layout for the 197-byte data packets.
http://www.keckec.com/weather/LCX_Data_Layout.pdf

Do you have a spreadsheet version of that PDF?  A CDF or other machine-readable file would be fine too.

I need to make a bunch of notes and the PDF is a bit of a pain since I have to write in the margins of a printout  :?

TIA!

Offline skydvrz

  • Senior Contributor
  • ****
  • Posts: 224
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #311 on: May 22, 2014, 10:00:21 PM »
Keckec:

There may be a problem with Min Outside Temp at nybble-offset $46.  Mine calculates out to -15F.  The display says my min OT was 35F.  All the other temps seem OK so far.

Offline keckec

  • Senior Member
  • **
  • Posts: 62
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #312 on: May 23, 2014, 10:39:24 AM »
Skydvrz,

Thanks for looking this over.

Do you have a spreadsheet version of that PDF?
The spreadsheet is here:
http://www.keckec.com/weather/LcxLayout.ods
The notes are in a different file, which grabs the spreadsheet from disk to make the pdf. You'll probably have to tell it where the spreadsheet is on your system. Anyway, it's here:
http://www.keckec.com/weather/DataLayoutNotes.odt

There may be a problem with Min Outside Temp at nybble-offset $46.  Mine calculates out to -15F.  The display says my min OT was 35F.  All the other temps seem OK so far.
Hmmm.  It seems to be working here. My raw data right now is 0x542, which is coming out to 57.56F. Here is the php code that converts to deg F.
Code: [Select]
function bcd2int(&$nybs,$startn,$len)
{
    $retval = 0;
    for ($i = 0; $i < $len; $i++)
    { 
        if ($nybs[$startn+$i] > 9)
        { 
            return -1;
        }
        $retval = $retval * 10 + $nybs[$startn+$i];
    }
    return $retval;
}

function temp2str(&$nybs,$startn)
{
    $retstr = "";
    $val = bcd2int($nybs,$startn,3);
    if ($val < 0)
    {
        return "  N/A ";
    }
    $otemp = $val / 10.0 - 40.0;
    $otemp = $otemp * 9.0 / 5 + 32.0;
    $retstr .= sprintf("%6.2f",$otemp);
    return $retstr;
}
« Last Edit: May 23, 2014, 10:41:28 AM by keckec »

Offline skydvrz

  • Senior Contributor
  • ****
  • Posts: 224
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #313 on: May 23, 2014, 11:11:04 AM »
I use a similar algorithm to calculate Fahrenheit, plus I use the same function for all temperature fields.  All the other ones are OK.

Maybe the value found at that offset (Nybble $46) is not what you think?

I will check the raw numbers tonight try to get a handle on what is going on.

I am successfully storing all the "new" sensor fields in MySQL.

Offline keckec

  • Senior Member
  • **
  • Posts: 62
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #314 on: May 26, 2014, 10:28:51 AM »
I made a correction to the layout. The all-time minimum outside temperature should be at nybble 0x6a, not 0x181, and it's actually wind chill. I don't know what the 3-nybble field at 0x181 is, but it still looks like a temperature. I've updated the spreadsheet:
http://www.keckec.com/weather/LcxLayout.ods

Offline 10ACTony

  • Senior Member
  • **
  • Posts: 71
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #315 on: May 26, 2014, 05:42:38 PM »
I made a correction to the layout. The all-time minimum outside temperature should be at nybble 0x6a, not 0x181, and it's actually wind chill. I don't know what the 3-nybble field at 0x181 is, but it still looks like a temperature. I've updated the spreadsheet:
http://www.keckec.com/weather/LcxLayout.ods

Thanks for the info, but you do know that the spreadsheet errors when opening because it can't access your note file.

//
No trees were destroyed in the sending of this message though a significant number of electrons were terribly inconvenienced.
//

Offline skydvrz

  • Senior Contributor
  • ****
  • Posts: 224
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #316 on: May 26, 2014, 09:11:48 PM »
I got the new improved SDP packet dissector storing data to MySQL.  I also updated ssMonitor to display the new fields. 

There are a few minor problems with some of the new fields.  The one I mentioned before remains, plus I noticed a couple others.  I have circled them on the screen shot of the new SkySpy tab found below.  OT Min is at (nybble) offset $46.  OT All time low is at offset $6a. Unknown date is at offset $112.  OH Min Date is at offset $98


Offline keckec

  • Senior Member
  • **
  • Posts: 62
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #317 on: May 27, 2014, 10:44:35 AM »
There are a few minor problems with some of the new fields.  The one I mentioned before remains, plus I noticed a couple others.  I have circled them on the screen shot of the new SkySpy tab found below.  OT Min is at (nybble) offset $46.  OT All time low is at offset $6a. Unknown date is at offset $112.  OH Min Date is at offset $98
The unknown date is the same in your data as mine. Somewhere I saw in LCX documentation that the initial value for dates is 1/1/2013. I assume this date is unused.
The difference between our OT min and OT all-time low fields is odd. Don't know where the differences lie.

Here is a hex dump of the nybbles from my station this morning. If you have something similar, could you post it. Maybe there's more than one format, maybe a firmware version difference. Maybe there's a clue in the unidentified nybbles.
Code: [Select]
by nyb |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|2|3|3|3|3|3|3|3|3|3|3|3|3|3|3|3|3
te ble |0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f
00 000 |0|1|6|4|1|0|2|1|0|1|4|0|5|1|6|1|7|3|5|1|4|0|5|1|7|0|7|3|0|7|0|7|0|0|5|8|9|0|0|6|4|5|0|0|0|1|4|0|5|2|6|1|7|3|8|1|4|0|5|2|6|2|3|0
20 040 |1|6|6|6|0|0|5|5|4|0|0|5|8|8|0|0|4|1|4|0|5|1|5|1|2|2|1|1|4|0|5|2|5|1|8|1|1|8|3|6|0|0|4|3|6|0|0|5|8|8|0|0|1|4|0|5|2|5|2|2|3|8|1|4
40 080 |0|5|1|7|0|7|2|9|5|7|2|0|5|1|1|4|0|5|2|7|0|6|3|1|1|4|0|5|2|6|1|7|4|1|8|7|5|1|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
60 0c0 |0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|4|0|3|0|1|0|3|5|9|0|0|2|6|0|5|0|0|0|0|0|0|1|4|0|4|1|9|0|9|0|3|0|0|1|0|0|6|0|0|0|0|0|0
80 100 |0|1|4|0|5|0|1|1|7|3|1|0|0|0|0|0|0|0|1|3|0|1|0|1|0|0|0|0|0|0|0|0|0|0|0|0|f|c|0|0|5|0|2|4|4|4|4|3|1|4|0|5|2|7|0|6|2|6|0|4|5|c|0|0
a0 140 |0|1|b|0|0|0|1|0|2|4|4|4|4|3|0|2|9|9|5|1|0|1|4|2|0|2|9|6|9|1|0|0|5|5|0|3|0|2|9|1|0|2|5|8|1|4|0|2|2|8|1|6|2|4|1|4|0|1|1|3|1|0|1|9
c0 180 |0|4|5|3|0|3|7|2|c|f

Offline keckec

  • Senior Member
  • **
  • Posts: 62
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #318 on: May 27, 2014, 03:15:12 PM »
Thanks for the info, but you do know that the spreadsheet errors when opening because it can't access your note file.
Sorry, I renamed one of the files but didn't update the one on the web site. I think this should work...
http://www.keckec.com/weather/LcxLayout.ods
http://www.keckec.com/weather/LCX_Data_Layout.odt
Downloading both files to the same directory should work.

Offline 10ACTony

  • Senior Member
  • **
  • Posts: 71
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #319 on: May 30, 2014, 01:28:32 AM »
It's not in nybbles, but here's one of my SDP packet.


00000000h: 01 64 20 21 01 40 20 21 33 61 40 41 51 10 06 83
00000010h: 00 58 70 06 58 00 01 40 52 61 44 11 40 30 30 74
00000020h: 67 49 00 30 20 06 52 00 11 40 52 61 44 11 40 30
00000030h: 30 70 37 49 00 22 50 06 52 00 14 04 27 17 14 14
00000040h: 02 27 08 00 65 19 54 14 03 06 05 06 14 03 26 14
00000050h: 09 91 23 67 00 00 00 00 00 00 00 00 01 34 93 00
00000060h: 00 00 00 00 00 00 00 00 15 22 14 03 03 10 59 00
00000070h: 73 01 00 00 00 14 03 28 17 51 00 27 86 00 00 00
00000080h: 00 00 00 00 00 A0 46 93 02 13 01 01 00 00 00 00
00000090h: 00 00 B4 00 50 44 55 35 14 04 04 01 59 10 50 00
000000a0h: 01 B0 00 10 44 55 35 02 99 51 01 42 02 95 10 99
000000b0h: 93 03 05 81 03 55 14 04 28 16 20 14 02 06 09 50
000000c0h: 05 84 07 6A F6
//
No trees were destroyed in the sending of this message though a significant number of electrons were terribly inconvenienced.
//

Offline keckec

  • Senior Member
  • **
  • Posts: 62
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #320 on: May 30, 2014, 07:18:24 PM »
10ACTony,

Thanks for sending the data packet. Here's what I see in it for the fields Skydvrz found to be out of range.
Min outside temp at nybble 0x46: raw=0x302 -> 14.4F (at 3/3/14 07:46)
All-time Low OT w/wind chill at nybble 0x6a: raw=0x225 -> +0.5F  (at 3/3/14 07:03)
Date/time of min outside humidity at nybble 0x98: 3/26/14 14:09

I don't know where you are. Do these values look at all reasonable?

Skydvrz's data packet had some odd values for those fields.
« Last Edit: May 31, 2014, 09:39:53 AM by keckec »

Offline 10ACTony

  • Senior Member
  • **
  • Posts: 71
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #321 on: June 01, 2014, 12:49:17 AM »
10ACTony,

Thanks for sending the data packet. Here's what I see in it for the fields Skydvrz found to be out of range.
Min outside temp at nybble 0x46: raw=0x302 -> 14.4F (at 3/3/14 07:46)
All-time Low OT w/wind chill at nybble 0x6a: raw=0x225 -> +0.5F  (at 3/3/14 07:03)
Date/time of min outside humidity at nybble 0x98: 3/26/14 14:09

I don't know where you are. Do these values look at all reasonable?

Skydvrz's data packet had some odd values for those fields.

The min outside temp, date and time are exactly whats on my station, as is the date time of the min outside humidity.  Looking at the wind chill it's also very possible.
//
No trees were destroyed in the sending of this message though a significant number of electrons were terribly inconvenienced.
//

Offline keckec

  • Senior Member
  • **
  • Posts: 62
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #322 on: June 06, 2014, 03:22:42 PM »
Here's more info on setting the time interval to save history...

Two bytes control how often history is saved. Each time it is saved, the address to write the next history record (aka epoch) is incremented by 0x12. This is controlled by bytes 0x14 and 0x1f of the 38-byte 14:01 packet (which also sets console time). The "cloud" servers always set both bytes to the same value, and I've only done it that way. Intervals below 10 minutes also seem to speed up how often the SDP is sent. Here are the intervals for various values of these bytes:
Code: [Select]
Val  Interval
 0   1 minute
 1   5 minutes
 2   10 minutes
 3   15 minutes
 4   20 minutes
 5   30 minutes
 6   1 hour
 7   2 hours (saves on even hours, local time)
There may be valid higher values for these bytes, and there may be a value which disables saving history altogether. This might stop the epoch from incrementing. I haven't looked for that.

I have the history data format figured out, but have a few more details to work out on how to tell the console/gateway what to send. I'll post here when I get more.
« Last Edit: July 21, 2014, 11:10:49 AM by keckec »

Offline mycal

  • Member
  • *
  • Posts: 24
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #323 on: June 11, 2014, 12:32:53 AM »

I had a few hrs to work on the code today,  I took a snapshot that keckec has updated and modified it to upload to weather underground.

It doesn't have the fix to stop sending 210 byte packets or anything, but it does seem to work well:

http://www.wunderground.com/personal-weather-station/dashboard?ID=KCAPETAL29

Code Snapshot is here:

https://github.com/lowerpower/LaCrosse



Offline mycal

  • Member
  • *
  • Posts: 24
Re: LaCrosse Wireless Internet Gateway Model GW1000U ERF-100
« Reply #324 on: June 12, 2014, 02:35:22 PM »

FYI you need to create a file on your webserver called php.log and make sure the webserver owns it or it is chmod 777

If you don't you will get an error and it the software will not work.

I added a second weather station using this software to Weather Underground.

http://www.wunderground.com/personal-weather-station/dashboard?ID=KCACLEAR4