Options
All
  • Public
  • Public/Protected
  • All
Menu

elk-client

styled with prettier Greenkeeper badge Travis Coveralls Dev Dependencies

A module for connecting to an Elk M1 security system over a TCP connection.

Usage

Install with NPM or Yarn

npm install elk-client
// or
yarn add elk-client
import { ElkClient } from 'elk-client';

// Parse a message

const client = new ElkClient({
  connection: { 
    host: 'elkm1.example.net',
    secure: true,
  },
  username: 'myelkm1username',
  password: 'supersecret!',
});

client
  .connect()
  .then(() => client.getArmingStatus())    
  .then((armingStatus) => {
    const area1 = armingStatus.getAreaStatus(1);
    console.log('Area 1 status:', ArmingLevel[area1.armingLevel])
  })
  .then(() => client.disconnect())
  .then(() => {
    console.log('Done!');
  })
  .catch((err) => {
    console.error(err);
  });

Device discovery

Devices can be discovered using UDP broadcast messages. Only M1XEP and C1M1 devices can be discovered. This is not documented by Elk Products, but this is how the ElkRP2 software does it's discovery.

import { ElkDiscoveryClient } from 'elk-client';

const discoveryClient = new ElkDiscoveryClient();
discoveryClient
  .start()
  .then((devices) => {
    console.log(`Found `${devices.length}` devices!);
  })
  .catch((err) => {
    console.error(err);
  });

You can optionally limit the device types requested and adjust the timeout, broadcast address, and port used:

import { ElkDiscoveryClient, ElkDeviceType } from 'elk-client';

const discoveryClient = new ElkDiscoveryClient({
  // Only look for M1XEP devices
  deviceTypes: [ElkDeviceType.M1XEP],

  // Use port 9000 instead
  // NOTE: This probably won't ever work if you change the port!
  port: 9000,

  // Wait 10 seconds instead of the 5 second default
  timeout: 10000,

  // Use a different broadcast address (default is 255.255.255.255)
  broadcastAddress: "192.168.1.255",
});

discoveryClient
  .start()
  .then((devices) => {
    console.log(`Found `${devices.length}` devices!);
  })
  .catch((err) => {
    console.error(err);
  });

Index

Type aliases

DataListener

DataListener: function

Type declaration

    • (data: string): void
    • Parameters

      • data: string

      Returns void

DisconnectedListener

DisconnectedListener: function

Type declaration

ErrorListener

ErrorListener: function

Type declaration

    • (error: Error): void
    • Parameters

      • error: Error

      Returns void

StateChangeListener

StateChangeListener: function

Type declaration

Events

authenticated

  • authenticated(): void
  • Emitted when authentication has completed succesfully. This should be followed by a "ready" event.

    asmemberof

    ElkClientEvents

    Returns void

authenticating

  • authenticating(): void
  • Emitted when authentication has begun. This is typically triggered when the Elk M1 requests a username, after the "connected" event.

    asmemberof

    ElkClientEvents

    Returns void

connected

  • connected(): void
  • Emitted when a connection was successfully established. The client may still need to authenticate before it becomes "ready".

    asmemberof

    ElkClientEvents

    Returns void

disconnected

  • disconnected(error?: Error): void
  • Emitted whenever the underlying connection disconnects. An error will be included if it caused the disconnect.

    asmemberof

    ElkClientEvents

    Parameters

    Returns void

error

  • error(error: Error): void
  • Emitted whenever an error occurs. The underlying connection will be disconnected after this, if it hasn't already.

    asmemberof

    ElkClientEvents

    Parameters

    • error: Error

    Returns void

message

  • message(message: ElkMessage): void
  • Emitted whenever a message is recevied from the Elk M1.

    asmemberof

    ElkClientEvents

    Parameters

    • message: ElkMessage

    Returns void

ok

  • ok(): void
  • Emitted when the client receives an "OK" response the panel. This is not a typical panel "message", but a special type of response the panel sends in very specific cases.

    asmemberof

    ElkClientEvents

    Returns void

ready

  • ready(): void
  • Emitted when the client is ready to send/receive events. It means we have successfully connected and authenticated (if a username and password was supplied). If no username was supplied, but the panel requires authentication, this event may still be emitted, followed by an "error" event indicating that authentication failed.

    asmemberof

    ElkClientEvents

    Returns void

Variables

Const C1M1_DISCOVERY_ID

C1M1_DISCOVERY_ID: Buffer = Buffer.from('C1M1ID', 'ascii')

Const C1M1_MSG

C1M1_MSG: Buffer = Buffer.from([67, 49, 77, 49, 32, // ID0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, // MAC192, 168, 1, 100, // IP8, 53, // port22, 33, // secure port67, 49, 77, 49, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,])

Const DEFAULT_CONNECT_TIMEOUT

DEFAULT_CONNECT_TIMEOUT: number = 60 * 1000

The default connect timeout value when not specified.

Const DEFAULT_HOST

DEFAULT_HOST: "192.168.0.251" = "192.168.0.251"

The default host name to use when one is not specified.

192.168.0.251 is the default IP address that the Elk M1 assigns to itself when it is not given one by a DHCP server or when it is expicitly reset.

Const DEFAULT_INSECURE_PORT

DEFAULT_INSECURE_PORT: 2101 = 2101

The default port to connect to when using an insecure connection.

Const DEFAULT_RESPONSE_TIMEOUT

DEFAULT_RESPONSE_TIMEOUT: number = 30 * 1000

The default timeout for command responses when not specified.

Const DEFAULT_SECURE_PORT

DEFAULT_SECURE_PORT: 2601 = 2601

The default port to connect to when using a secure connection.

Const LOGIN_FAILURE

LOGIN_FAILURE: "Username/Password not found." = "Username/Password not found."

The control panel sends this when logging in fails.

Const LOGIN_SUCCESSFUL

LOGIN_SUCCESSFUL: "Elk-M1XEP: Login successful." = "Elk-M1XEP: Login successful."

The control panel sends this when logging in is susccessful

Const M1XEP_DISCOVERY_ID

M1XEP_DISCOVERY_ID: Buffer = Buffer.from('XEPID', 'ascii')

Const M1XEP_MSG

M1XEP_MSG: Buffer = Buffer.from([77, 49, 88 , 69, 80, // ID0x12, 0x34, 0x56, 0xab, 0xcd, 0xef, // MAC10, 10, 1, 202, // IP3, 9, // port73, 32, 97, 109, 32, 97, 110, 32, 77, 49, 88, 69, 80, 33, 32, 32, // name0, 0, 0, 0, 0, 0, 0, 0, 0, // unused])

Const PASSWORD_REQUEST

PASSWORD_REQUEST: "Password: " = "Password: "

The control panel sends this when prompting for a password.

Const USERNAME_REQUEST

USERNAME_REQUEST: "Username: " = "Username: "

The control panel sends this when prompting for a username.

Const connect

connect: Mock<any, any> = jest.fn().mockResolvedValue({})

Const disconnect

disconnect: Mock<any, any> = jest.fn().mockResolvedValue({})

Const sendCommandForResponseTypeTests

sendCommandForResponseTypeTests: [keyof ElkClientCommands, object, object, undefined | any[], undefined | string][] = [['getArmingStatus', ArmingStatusRequest, ArmingStatusReport],['getAlarmsByZone', AlarmByZoneRequest, AlarmByZoneReport],['getControlOutputStatus', ControlOutputStatusRequest, ControlOutputStatusReport],['getKeypadAreaAssignments', KeypadAreaAssigmentsRequest, KeypadAreaAssignments],['getTemperatureData', TemperatureDataRequest, TemperatureData],['getRealTimeClock', RealTimeClockDataRequest, RealTimeClockDataReply],['setRealTimeClock',RealTimeClockDataWrite,RealTimeClockDataReply,[2017, 5, 15, DayOfWeek.Monday, 11, 32, 44],],['getDescription',TextDescriptionRequest,TextDescriptionReply,[TextDescriptionType.AreaName, 3],],['getTroubleStatus', SystemTroubleStatusRequest, SystemTroubleStatusReply],['getOmnistat2Data', Omnistat2Request, Omnistat2Reply, ['fooo']],['getVersionNumber', VersionNumberRequest, VersionNumberReply],['getZonePartitions', ZonePartitionRequest, ZonePartitionReport],['getZoneStatus', ZoneStatusRequest, ZoneStatusReport],['getZoneDefinitions', ZoneDefinitionRequest, ZoneDefinitionData],]

Methods that send a command and wait for a response based solely on the response class type.

Const sendCommandOnlyTest

sendCommandOnlyTest: [keyof ElkClientCommands, function, object, any][] = [['arm',cmd => cmd.arm(2, ArmingLevel.ArmedStay, '1234'),Arm,{ areaNumber: 2, armingLevel: ArmingLevel.ArmedStay, userCode: '1234' },],['disarm',cmd => cmd.disarm(4, '567891'),Arm,{ areaNumber: 4, armingLevel: ArmingLevel.Disarm, userCode: '567891' },],['setControlOutputOff', cmd => cmd.setControlOutputOff(13), ControlOutputOff, { output: 13 }],['setControlOutputOn', cmd => cmd.setControlOutputOn(79), ControlOutputOn, { output: 79 }],['toggleControlOutput', cmd => cmd.toggleControlOutput(20), ControlOutputToggle, { output: 20 }],['displayTextOnScreen',cmd =>cmd.displayTextOnScreen(3, 'Hello', 'There', DisplayTextClearOption.ClearWithStarKey, true),DisplayTextOnScreen,{areaNumber: 3,beep: true,clearOption: DisplayTextClearOption.ClearWithStarKey,firstLine: 'Hello',secondLine: 'There',subMessageType: 'm',timeout: 0,},],['clearTextOnScreen',cmd => cmd.clearTextOnScreen(5, false),DisplayTextOnScreen,{areaNumber: 5,beep: false,},],['setPlcDevice',cmd => cmd.setPlcDevice('house', 3, PlcFunctionCode.Bright, 67, 1000),PlcDeviceControl,{houseCode: 'house',unitCode: 3,functionCode: PlcFunctionCode.Bright,extendedCode: 67,onTime: 1000,},],['setPlcDeviceOff',cmd => cmd.setPlcDeviceOff('Cherry', 41),PlcDeviceOff,{ houseCode: 'Cherry', unitCode: 41 },],['setPlcDeviceOn',cmd => cmd.setPlcDeviceOn('Banana', 10),PlcDeviceOn,{ houseCode: 'Banana', unitCode: 10 },],['togglePlcDevice',cmd => cmd.togglePlcDevice('Apple', 4),PlcDeviceToggle,{ houseCode: 'Apple', unitCode: 4 },],['speakWord', cmd => cmd.speakWord(42), SpeakWord, { wordNumber: 42 }],['speakPhrase', cmd => cmd.speakPhrase(100), SpeakPhrase, { phraseNumber: 100 }],['activateTask', cmd => cmd.activateTask(4), TaskActivation, { taskNumber: 4 }],['triggerZone', cmd => cmd.triggerZone(32), ZoneTrigger, { zoneNumber: 32 }],]

Methods that only send a command and don't wait for a reply.

Const write

write: Mock<any, any> = jest.fn().mockResolvedValue({})

Functions

createSecureSocket

  • createSecureSocket(options: object): TLSSocket

createSocket

  • createSocket(__namedParameters: object): Socket

decode

extractIpAddress

  • extractIpAddress(buffer: Buffer, startIndex: number): string
  • Extracts an IP address from 4 bytes of a data buffer

    Parameters

    • buffer: Buffer

      The data buffer

    • startIndex: number

      The index within the buffer where the IP address is specified.

    Returns string

extractMacAddress

  • extractMacAddress(buffer: Buffer, startIndex: number, separator?: string): string
  • Extracts a MAC address from 6 bytes of a data buffer

    Parameters

    • buffer: Buffer

      The data buffer

    • startIndex: number

      The index within the buffer where the MAC address is specified.

    • Default value separator: string = ":"

    Returns string

extractPort

  • extractPort(buffer: Buffer, startIndex: number): number
  • Extracts a port number from 2 bytes of a data buffer

    Parameters

    • buffer: Buffer

      The data buffer

    • startIndex: number

      The index within the buffer where the port is specified.

    Returns number

mockCreateSocketConnectsSuccessfully

  • mockCreateSocketConnectsSuccessfully(waitMs?: number, modifier?: undefined | function): void

withTimeout

  • withTimeout<T>(timeoutMs: number, promise: Promise<T>): Promise<T>
  • Wraps a promise in a new promise that will reject if the promise is not resolved or rejected within the timeout provided.

    Type parameters

    • T

    Parameters

    • timeoutMs: number
    • promise: Promise<T>

    Returns Promise<T>

Object literals

Const DEFAULT_DISCOVERY_OPTIONS

DEFAULT_DISCOVERY_OPTIONS: object

broadcastAddress

broadcastAddress: string = "255.255.255.255"

deviceTypes

deviceTypes: undefined = undefined

port

port: number = 2362

timeout

timeout: number = 5000

Const DEFAULT_OPTIONS

DEFAULT_OPTIONS: object

The default connection options to use if secure === false

connectTimeout

connectTimeout: number = 30 * 1000

host

host: string = DEFAULT_HOST

idleTimeout

idleTimeout: number = 60 * 1000

port

port: number = DEFAULT_INSECURE_PORT

secure

secure: false = false

Const SECURE_DEFAULT_OPTIONS

SECURE_DEFAULT_OPTIONS: object

The default connection options to use if secure === true

port

port: number = DEFAULT_SECURE_PORT

secure

secure: true = true

Const STATE_CHANGE_EVENT_NAMES

STATE_CHANGE_EVENT_NAMES: object

A map of connection states to the name of the event that they emit when the connection is changed to that state.

__computed

__computed: string = "disconnecting"

Legend

  • Module
  • Object literal
  • Variable
  • Function
  • Function with type parameter
  • Index signature
  • Type alias
  • Type alias with type parameter
  • Enumeration
  • Enumeration member
  • Property
  • Method
  • Interface
  • Interface with type parameter
  • Constructor
  • Property
  • Method
  • Index signature
  • Class
  • Class with type parameter
  • Constructor
  • Property
  • Method
  • Accessor
  • Index signature
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Inherited accessor
  • Protected property
  • Protected method
  • Protected accessor
  • Private property
  • Private method
  • Private accessor
  • Static property
  • Static method

Generated using TypeDoc