Skip to content

Commit

Permalink
Add identify ZCL cluster.
Browse files Browse the repository at this point in the history
  • Loading branch information
melair committed May 9, 2024
1 parent 8400e0c commit 817a66d
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 0 deletions.
30 changes: 30 additions & 0 deletions commands/local/identify/identify.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package identify

import "github.com/shimmeringbee/zcl"

const (
IdentifyTime = zcl.AttributeID(0x0000)
)

const (
IdentifyId = zcl.CommandIdentifier(0x00)
IdentifyQueryId = zcl.CommandIdentifier(0x01)
TriggerEffectId = zcl.CommandIdentifier(0x02)

IdentifyQueryResponseId = zcl.CommandIdentifier(0x00)
)

type Identify struct {
IdentifyTime uint16
}

type IdentifyQuery struct{}

type TriggerEffect struct {
EffectIdentifier uint8
EffectVariant uint8
}

type IdentifyQueryResponse struct {
Timeout uint16
}
116 changes: 116 additions & 0 deletions commands/local/identify/identify_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package identify

import (
"github.com/shimmeringbee/bytecodec"
"github.com/shimmeringbee/zcl"
"github.com/shimmeringbee/zigbee"
"github.com/stretchr/testify/assert"
"testing"
)

func Test_Identify(t *testing.T) {
t.Run("marshals and unmarshalls correctly", func(t *testing.T) {
expectedCommand := Identify{
IdentifyTime: 0x1122,
}
actualCommand := Identify{}
expectedBytes := []byte{0x22, 0x11}

actualBytes, err := bytecodec.Marshal(&expectedCommand)
assert.NoError(t, err)
assert.Equal(t, expectedBytes, actualBytes)

err = bytecodec.Unmarshal(expectedBytes, &actualCommand)
assert.NoError(t, err)
assert.Equal(t, expectedCommand, actualCommand)
})

t.Run("the message is registered in the command registry", func(t *testing.T) {
cr := zcl.NewCommandRegistry()
Register(cr)

id, err := cr.GetLocalCommandIdentifier(zcl.IdentifyId, zigbee.NoManufacturer, zcl.ClientToServer, &Identify{})
assert.NoError(t, err)
assert.Equal(t, IdentifyId, id)
})
}

func Test_IdentifyQuery(t *testing.T) {
t.Run("marshals and unmarshalls correctly", func(t *testing.T) {
expectedCommand := IdentifyQuery{}
actualCommand := IdentifyQuery{}
expectedBytes := []byte(nil)

actualBytes, err := bytecodec.Marshal(&expectedCommand)
assert.NoError(t, err)
assert.Equal(t, expectedBytes, actualBytes)

err = bytecodec.Unmarshal(expectedBytes, &actualCommand)
assert.NoError(t, err)
assert.Equal(t, expectedCommand, actualCommand)
})

t.Run("the message is registered in the command registry", func(t *testing.T) {
cr := zcl.NewCommandRegistry()
Register(cr)

id, err := cr.GetLocalCommandIdentifier(zcl.IdentifyId, zigbee.NoManufacturer, zcl.ClientToServer, &IdentifyQuery{})
assert.NoError(t, err)
assert.Equal(t, IdentifyQueryId, id)
})
}

func Test_TriggerEffect(t *testing.T) {
t.Run("marshals and unmarshalls correctly", func(t *testing.T) {
expectedCommand := TriggerEffect{
EffectIdentifier: 0x11,
EffectVariant: 0x22,
}
actualCommand := TriggerEffect{}
expectedBytes := []byte{0x11, 0x22}

actualBytes, err := bytecodec.Marshal(&expectedCommand)
assert.NoError(t, err)
assert.Equal(t, expectedBytes, actualBytes)

err = bytecodec.Unmarshal(expectedBytes, &actualCommand)
assert.NoError(t, err)
assert.Equal(t, expectedCommand, actualCommand)
})

t.Run("the message is registered in the command registry", func(t *testing.T) {
cr := zcl.NewCommandRegistry()
Register(cr)

id, err := cr.GetLocalCommandIdentifier(zcl.IdentifyId, zigbee.NoManufacturer, zcl.ClientToServer, &TriggerEffect{})
assert.NoError(t, err)
assert.Equal(t, TriggerEffectId, id)
})
}

func Test_IdentifyQueryResponse(t *testing.T) {
t.Run("marshals and unmarshalls correctly", func(t *testing.T) {
expectedCommand := IdentifyQueryResponse{
Timeout: 0x1122,
}
actualCommand := IdentifyQueryResponse{}
expectedBytes := []byte{0x22, 0x11}

actualBytes, err := bytecodec.Marshal(&expectedCommand)
assert.NoError(t, err)
assert.Equal(t, expectedBytes, actualBytes)

err = bytecodec.Unmarshal(expectedBytes, &actualCommand)
assert.NoError(t, err)
assert.Equal(t, expectedCommand, actualCommand)
})

t.Run("the message is registered in the command registry", func(t *testing.T) {
cr := zcl.NewCommandRegistry()
Register(cr)

id, err := cr.GetLocalCommandIdentifier(zcl.IdentifyId, zigbee.NoManufacturer, zcl.ServerToClient, &IdentifyQueryResponse{})
assert.NoError(t, err)
assert.Equal(t, IdentifyQueryResponseId, id)
})
}
14 changes: 14 additions & 0 deletions commands/local/identify/register.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package identify

import (
"github.com/shimmeringbee/zcl"
"github.com/shimmeringbee/zigbee"
)

func Register(cr *zcl.CommandRegistry) {
cr.RegisterLocal(zcl.IdentifyId, zigbee.NoManufacturer, zcl.ClientToServer, IdentifyId, &Identify{})
cr.RegisterLocal(zcl.IdentifyId, zigbee.NoManufacturer, zcl.ClientToServer, IdentifyQueryId, &IdentifyQuery{})
cr.RegisterLocal(zcl.IdentifyId, zigbee.NoManufacturer, zcl.ClientToServer, TriggerEffectId, &TriggerEffect{})

cr.RegisterLocal(zcl.IdentifyId, zigbee.NoManufacturer, zcl.ServerToClient, IdentifyQueryResponseId, &IdentifyQueryResponse{})
}

0 comments on commit 817a66d

Please sign in to comment.