funlogic-io/zwave-serialapi

View on GitHub
lib/serialapi/functions/func-utils.js

Summary

Maintainability
A
0 mins
Test Coverage
const consts = require('../consts')
const formats = require('./formats')
const arrayReader = require('../../utils/array-reader')

function buildRequestEncoder (funcId, dataEncoder) {
  return (request, metaIn) => {
    const data = dataEncoder(request, metaIn) || []
    const result = Object.assign({}, request)
    Object.defineProperty(result, 'meta', { value: Object.assign({}, metaIn, { funcId, data }) })
    return result
  }
}

function buildResponseDecoder (funcId, dataDecoder) {
  return (dataFrame, metaIn) => {
    if (dataFrame.funcId === funcId && dataFrame.type === consts.RESPONSE) {
      const data = [...dataFrame.params]
      const response = {}
      const metaOut = dataDecoder(arrayReader(data), response, metaIn) || {}
      Object.defineProperty(response, 'meta', { value: Object.assign(metaOut, metaIn, { funcId, data }) })
      return response
    }
  }
}

function buildCallbackDecoder (funcId, dataDecoder) {
  return (dataFrame, metaIn) => {
    if (dataFrame.funcId === funcId && dataFrame.type === consts.REQUEST) {
      const data = [...dataFrame.params]
      const request = {}
      const metaOut = dataDecoder(arrayReader(data), request, metaIn) || {}
      return Object.defineProperty(request, 'meta', { value: Object.assign(metaOut, metaIn, { funcId, data }) })
    }
  }
}

function buildNoParameterRequestEncoder (funcId) {
  return buildRequestEncoder(funcId, () => [])
}

function buildCallbackIdOnlyRequestEncoder (funcId) {
  return buildRequestEncoder(funcId, (request, metaIn) => [metaIn.callbackId])
}

function buildBooleanResponseDecoder (funcId) {
  return buildResponseDecoder(funcId, (reader, response) => {
    response.success = reader.readByte(b => b !== 0)
    return { hasCallback: response.success }
  })
}

function decodeRxStatus (rxStatus) {
  return {
    routeLocked: (rxStatus & consts.RECEIVE_STATUS_ROUTED_BUSY) === consts.RECEIVE_STATUS_ROUTED_BUSY,
    lowPower: (rxStatus & consts.RECEIVE_STATUS_LOW_POWER) === consts.RECEIVE_STATUS_LOW_POWER,
    frameType: formats.frameTypeFormat.format(rxStatus & 0x1C),
    foreignFrame: (rxStatus & consts.RECEIVE_STATUS_FOREIGN_FRAME) === consts.RECEIVE_STATUS_FOREIGN_FRAME,
    foreignHome: (rxStatus & consts.RECEIVE_STATUS_FOREIGN_HOMEID) === consts.RECEIVE_STATUS_FOREIGN_HOMEID
  }
}

function decodeNodeInformation (nif) {
  if (nif.length === 0) return
  const reader = arrayReader(nif)
  const result = {}
  result.basicClass = reader.readByte()
  result.genericClass = reader.readByte()
  result.specificClass = reader.readByte()
  result.commandClasses = []
  for (let cc = reader.readByte(); cc !== undefined; cc = reader.readByte()) {
    result.commandClasses.push(cc)
  }
  return result
}

module.exports = {
  buildRequestEncoder,
  buildResponseDecoder,
  buildCallbackDecoder,
  buildNoParameterRequestEncoder,
  buildCallbackIdOnlyRequestEncoder,
  buildBooleanResponseDecoder,

  decodeRxStatus,
  decodeNodeInformation
}