knxultimate
Version:
KNX IP protocol implementation for Node. This is the ENGINE of Node-Red KNX-Ultimate node.
142 lines (111 loc) • 2.91 kB
text/typescript
import { KNXAddressType } from '../KNXAddress'
export enum FrameType {
type0 = 0,
type1 = 1,
}
export enum OnOff {
off = 0,
on = 1,
}
export enum Priority {
Prio0 = 0,
Prio1 = 1,
Prio2 = 2,
Prio3 = 3,
}
const CONTROL_LENGTH = 2
export default class ControlField {
private control1: number
private control2: number
public length: number
constructor(
control1: number = ControlField.DEFAULT_CONTROL1,
control2: number = ControlField.DEFAULT_CONTROL2,
) {
this.control1 = control1
this.control2 = control2
this.length = CONTROL_LENGTH
}
set frameType(frameType: FrameType) {
this.control1 = (this.control1 & 0x7f) | (Number(frameType) << 7)
}
get frameType(): FrameType {
return (this.control1 & 0x80) >> 7
}
set repeat(repeat: OnOff) {
this.control1 = (this.control1 & 0xdf) | (Number(repeat) << 5)
}
get repeat(): OnOff {
return (this.control1 & 0x20) >> 5
}
set broadcast(broadcast: OnOff) {
this.control1 = (this.control1 & 0xef) | (Number(broadcast) << 4)
}
get broadcast(): OnOff {
return (this.control1 & 0x10) >> 4
}
set priority(priority: Priority) {
this.control1 = (this.control1 & 0xf3) | (Number(priority) << 2)
}
get priority(): Priority {
return (this.control1 & 0x0c) >> 2
}
set ack(ack: OnOff) {
this.control1 = (this.control1 & 0xfd) | (Number(ack) << 1)
}
get ack(): OnOff {
return (this.control1 & 0x02) >> 1
}
set error(error: OnOff) {
this.control1 = (this.control1 & 0xfe) | Number(error)
}
get error(): OnOff {
return this.control1 & 0x01
}
set addressType(type: KNXAddressType) {
this.control2 = (this.control2 & 0x7f) | (Number(type) << 7)
}
get addressType(): KNXAddressType {
return (this.control2 & 0x80) >> 7
}
set hopCount(hopCount: number) {
if (isNaN(hopCount) || (hopCount < 0 && hopCount > 7)) {
throw new Error('Invalid hop count')
}
this.control2 = (this.control2 & 0x8f) | (Number(hopCount) << 4)
}
get hopCount(): number {
return (this.control2 & 0x70) >> 4
}
set frameFormat(format: number) {
if (isNaN(format) || (format < 0 && format > 15)) {
throw new Error('Invalid frame format')
}
this.control2 = (this.control2 & 0xf0) | Number(format)
}
get frameFormat(): number {
return this.control2 & 0xf
}
static get DEFAULT_CONTROL1(): number {
return 0xbe
}
static get DEFAULT_CONTROL2(): number {
return 0xe0
}
static createFromBuffer(buffer: Buffer, offset: number = 0): ControlField {
if (offset + CONTROL_LENGTH >= buffer.length) {
throw new Error(
`offset ${offset} out of buffer range ${buffer.length}`,
)
}
const control1 = buffer.readUInt8(offset++)
const control2 = buffer.readUInt8(offset)
return new ControlField(control1, control2)
}
toBuffer(): Buffer {
const buffer = Buffer.alloc(this.length)
buffer.writeUInt8(this.control1, 0)
buffer.writeUInt8(this.control2, 1)
return buffer
}
}