etpi

package module
v0.2.0-alpha Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2017 License: MIT Imports: 11 Imported by: 0

README

This is a libary to communicate with commercial alarm panels using the EnvisaLink TPI interface. It currently only works with DSC alarm panels

This is currently alpha-grade software. It has only been tested with an EnvisaLink4 module.

Documentation for the Envisalink TPI interface can be found here.

Apple HomeKit integration

The library was designed with the goal of integrating a DSC panel with Apple's HomeKit using an EnvisaLink4 module. There are more capabilities of the TPI interface that were not necessary for that goal, and have been left uncompleted so far.

The repository includes one command that employ the library, etpid. Instructions for one way to set up a Raspberry Pi with these utilities can be found here: Deployment to a Raspberry Pi

cmd/etpid

etpid utility is a bridge between the EnvisaLink panel and Apple HomeKit to implement a SecuritySystem servicee.

It has a dependency on the HomeControl library for HomeKit by brutella.

Once running, etpid advertises a new accessory named "EnvisaLink". It is paired with a manual code "32191123".

Usage

import "github.com/lazyeights/etpi"

etpiAddr := "192.168.1.24:4025"
pwd := "user"
code := "12345"

panel := etpi.NewPanel()
panel.OnZoneEvent(handleZone)
panel.OnPartitionEvent(handlePartition)
panel.OnKeypadEvent(handleKeypad)

// Connect to Envisalink. Connect will login to the Envisalink module, set the current date and time, and poll for the panel's current status.
if err := panel.Connect(etpiAddr, pwd, code); err != nil {
    panic("could not connect to Envisalink")
}
defer panel.Disconnect()

// Print the initial panel status
status := panel.Status()
fmt.Printf("%+v\n", status)

The library emits events for partitions, zones, and the keyboard that are handled by callback functions:

func handlePartition(partition int, status etpi.PartitionStatus) {
	fmt.Println("partition=%d, status=%+v", partition, status)
    if status := etpi.PartitionStatusAlarm {
        fmt.Println("ALARM TRIGGERED!")
    }
}

Documentation

Index

Constants

View Source
const (
	CommandPoll                         = "000"
	CommandStatusReport                 = "001"
	CommandLogin                        = "005"
	CommandSetTimeAndDate               = "010"
	CommandPartitionArmControlAway      = "030"
	CommandPartitionArmControlStay      = "031"
	CommandPartitionArmControlZeroEntry = "032"
	CommandPartitionDisarmControl       = "040"
	CommandCode                         = "200"
	CommandAck                          = "500"
	CommandCommandError                 = "501"
	CommandSystemError                  = "502"
	CommandLoginStatus                  = "505"
	CommandKeypadLed                    = "510"
	CommandZoneAlarm                    = "601"
	CommandZoneTamper                   = "603"
	CommandZoneFault                    = "605"
	CommandZoneOpen                     = "609"
	CommandZoneRestored                 = "610"
	CommandPartitionReady               = "650"
	CommandPartitionNotReady            = "651"
	CommandPartitionArmed               = "652"
	CommandPartitionDisarmed            = "655"
	CommandPartitionAlarm               = "654"
	CommandPartitionExitDelay           = "656"
	CommandPartitionEntryDelay          = "657"
	CommandPartitionBusy                = "673"
	CommandPartitionSpecialClosing      = "701"
	CommandTroubleOn                    = "840"
	CommandTroubleOff                   = "841"
	CommandCodeRequired                 = "900"
)
View Source
const (
	ArmAway = iota + 1
	ArmStay
	ArmNoEntryDelay
)
View Source
const (
	ZoneStatusAlarm = iota + 1
	ZoneStatusTamper
	ZoneStatusFault
	ZoneStatusOpen
	ZoneStatusRestored
)
View Source
const (
	PartitionStatusReady = iota + 1
	PartitionStatusNotReady
	PartitionStatusArmedAway
	PartitionStatusArmedStay
	PartitionStatusArmedZeroEntryAway
	PartitionStatusArmedZeroEntryStay
	PartitionStatusAlarm
	PartitionStatusDisarmed
	PartitionStatusExitDelay
	PartitionStatusEntryDelay
	PartitionStatusFailedToArm
	PartitionStatusBusy
)
View Source
const UnknownStatus = 0

Variables

View Source
var ErrAPICommandInvalidLength = errors.New("invalid length")
View Source
var ErrAPICommandNotSupported = errors.New("command not supported")
View Source
var ErrAPICommandPartitionError = errors.New("requested partition is out of bounds")
View Source
var ErrAPICommandSyntaxError = errors.New("syntax error")
View Source
var ErrAPIInvalidCharacters = errors.New("invalid characters")
View Source
var ErrAPISystemNotArmed = errors.New("system not armed")
View Source
var ErrAPISystemNotReadytoArm = errors.New("system not ready, either not secure, in exit-delay, or already armed")
View Source
var ErrAPIUserCodenotRequired = errors.New("user code not required")
View Source
var ErrCommandError = errors.New("command error, bad checksum")

Functions

This section is empty.

Types

type ArmMode

type ArmMode int

type Client

type Client interface {
	Connect(string, string, string) error
	Disconnect()
	Send(Command) error
	Status() error
	HandleZoneState(func(int, ZoneStatus))
	HandlePartitionState(func(int, PartitionStatus))
	HandleKeypadState(func(KeypadStatus))
}

func NewClient

func NewClient() Client

type Command

type Command struct {
	Code string
	Data string
}

func NewCommandFromBytes

func NewCommandFromBytes(p []byte) (*Command, error)

func (Command) String

func (c Command) String() string

func (Command) WriteTo

func (cmd Command) WriteTo(w io.Writer) (int64, error)

type KeypadStatus

type KeypadStatus struct {
	Backlight bool
	Fire      bool
	Program   bool
	Trouble   bool
	Bypass    bool
	Memory    bool
	Armed     bool
	Ready     bool
}

type Panel

type Panel interface {

	// Connect opens the connection to the Envisalink panel, logs in using
	// the supplied password, and upon a successful connection will set the
	// correct date/time of the alarm system.
	Connect(host string, pwd string, code string) error

	// Disconnect closes the connection to the Envisalink panel.
	Disconnect()

	// Arm attempts to arm a partition according to the supplied mode
	// (e.g., Stay, Away).
	Arm(partition int, mode ArmMode) error

	// Disarm attempts to disarm a partition.
	Disarm(partition int) error

	// SetTime sets the time for the alarm panel.
	SetTime(time.Time) error

	// OnPartitionEvent sets a calledback for whenever a partition event
	// occurs.
	OnPartitionEvent(func(int, PartitionStatus))

	// OnZoneEvent sets a calledback for whenever a zone event occurs.
	OnZoneEvent(func(int, ZoneStatus))

	// OnKeypadEvent sets a callback for whenever a keypad event occurs.
	OnKeypadEvent(func(KeypadStatus))

	// Status returns the current partition, zone, and keypad status.
	Status() *PanelStatus

	// Poll queries the Envisalink module to send its latest update.
	Poll() error
}

Panel is the primary interface for connecting to an alarm panel with the Envisalink TPI module.

Usage:

import "github.com/lazyeights/etpi"

etpiAddr := "192.168.1.24:4025"
pwd := "user"
code := "12345"

panel := etpi.NewPanel()
panel.OnZoneEvent(handleZone)
panel.OnPartitionEvent(handlePartition)
panel.OnKeypadEvent(handleKeypad)

if err := panel.Connect(etpiAddr, pwd, code); err != nil {
	panic("could not connect to Envisalink")
}
defer panel.Disconnect()

status := panel.Status()
fmt.Printf("%+v\n", status)

func NewPanel

func NewPanel() Panel

NewPanel creates a new Panel interface.

type PanelStatus

type PanelStatus struct {
	Zone      []ZoneStatus
	Partition []PartitionStatus
	Keypad    KeypadStatus
}

type PartitionStatus

type PartitionStatus int

func (PartitionStatus) String

func (p PartitionStatus) String() string

type ZoneStatus

type ZoneStatus int

func (ZoneStatus) String

func (z ZoneStatus) String() string

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL