diff --git a/lgxtypes/counter.go b/lgxtypes/counter.go new file mode 100644 index 0000000..5f6363e --- /dev/null +++ b/lgxtypes/counter.go @@ -0,0 +1,78 @@ +package lgxtypes + +import ( + "encoding/binary" + "io" +) + +type COUNTER struct { + PRE int32 + ACC int32 + CU bool // bit 31 + CD bool // bit 30 + DN bool // bit 29 + OV bool // bit 28 - set if we wrap over 2,147,483,648 to -2,147,483,648 + UN bool // bit 27 - set if we wrap over -2,147,483,648 to 2,147,483,648 +} + +func (t COUNTER) Pack(w io.Writer) int { + + var CtrlWord uint32 + if t.CU { + CtrlWord |= 1 << 31 + } + if t.CD { + CtrlWord |= 1 << 30 + } + if t.DN { + CtrlWord |= 1 << 29 + } + if t.OV { + CtrlWord |= 1 << 28 + } + if t.UN { + CtrlWord |= 1 << 27 + } + + err := binary.Write(w, binary.LittleEndian, CtrlWord) + if err != nil { + return 0 + } + + err = binary.Write(w, binary.LittleEndian, t.PRE) + if err != nil { + return 4 + } + err = binary.Write(w, binary.LittleEndian, t.ACC) + if err != nil { + return 8 + } + + return 12 +} + +func (t *COUNTER) Unpack(r io.Reader) (int, error) { + var CtrlWord uint32 + err := binary.Read(r, binary.LittleEndian, &CtrlWord) + if err != nil { + return 0, err + } + + t.CU = CtrlWord&(1<<31) != 0 + t.CD = CtrlWord&(1<<30) != 0 + t.DN = CtrlWord&(1<<29) != 0 + t.OV = CtrlWord&(1<<28) != 0 + t.UN = CtrlWord&(1<<27) != 0 + + err = binary.Read(r, binary.LittleEndian, &(t.PRE)) + if err != nil { + return 4, err + } + + err = binary.Read(r, binary.LittleEndian, &(t.ACC)) + if err != nil { + return 8, err + } + + return 12, nil +} diff --git a/tests/readcounter_test.go b/tests/readcounter_test.go new file mode 100644 index 0000000..a9eab7c --- /dev/null +++ b/tests/readcounter_test.go @@ -0,0 +1,84 @@ +package gologix_tests + +import ( + "bytes" + "testing" + + "github.com/danomagnum/gologix" + "github.com/danomagnum/gologix/lgxtypes" +) + +func TestCounterRead(t *testing.T) { + var cnt lgxtypes.COUNTER + + client := gologix.NewClient("192.168.2.241") + err := client.Connect() + if err != nil { + t.Error(err) + return + } + defer func() { + err := client.Disconnect() + if err != nil { + t.Errorf("problem disconnecting. %v", err) + } + }() + + //have, err := gologix.ReadPacked[udt2](client, "Program:gologix_tests.ReadUDT2") + err = client.Read("Program:gologix_tests.TestCounter", &cnt) + + if err != nil { + t.Errorf("problem reading counter data: %v", err) + return + } + + if cnt.PRE != 562855 { + t.Errorf("Expected preset of 2,345 but got %d ", cnt.PRE) + } + + if cnt.ACC != 632 { + t.Errorf("Expected ACC of 0 but got %d", cnt.ACC) + } + + if cnt.DN { + t.Error("Expected counter !DN") + } + + if cnt.CU { + t.Error("Expected counter !CU") + } + + if cnt.CD { + t.Error("Expected counter !CD") + } + + // make sure we can go the other way and recover it. + b := bytes.Buffer{} + _ = gologix.Pack(&b, gologix.CIPPack{}, cnt) + var cnt2 lgxtypes.COUNTER + _, err = gologix.Unpack(&b, gologix.CIPPack{}, &cnt2) + if err != nil { + t.Errorf("problem unpacking timer: %v", err) + } + + if cnt.ACC != cnt2.ACC { + t.Errorf("ACC didn't recover properly. %d != %d", cnt.ACC, cnt2.ACC) + } + + if cnt.PRE != cnt2.PRE { + t.Errorf("PRE didn't recover properly. %d != %d", cnt.PRE, cnt2.PRE) + } + + if cnt.DN != cnt2.DN { + t.Errorf("DN didn't recover properly. %v != %v", cnt.DN, cnt2.DN) + } + + if cnt.CU != cnt2.CU { + t.Errorf("CU didn't recover properly. %v != %v", cnt.CU, cnt2.CU) + } + + if cnt.CD != cnt2.CD { + t.Errorf("CD didn't recover properly. %v != %v", cnt.CD, cnt2.CD) + } + +}