CycloneTechnology/ChaMP

View on GitHub
champ-ipmi/src/main/scala/com/cyclone/ipmi/protocol/sdr/FullSdrKeyAndBody.scala

Summary

Maintainability
A
2 hrs
Test Coverage
package com.cyclone.ipmi.protocol.sdr

import akka.util.ByteString
import com.cyclone.ipmi.codec._

import scalaz.Scalaz._

/**
  * Contains the key and body of a full sensor record
  */
case class FullSdrKeyAndBody(
  sensorId: SensorId,
  ownerId: SensorOwnerId,
  ownerLun: SensorOwnerLun,
  sensorNumber: SensorNumber,
  entityId: EntityId,
  entityInstance: EntityInstance,
  sensorInitialization: SensorInitialization,
  sensorCapabilities: SensorCapabilities,
  sensorType: SensorType,
  sensorMasks: SensorMasks,
  sensorUnits: SensorUnits,
  linearization: Linearization,
  analogDataFormat: AnalogDataFormat,
  readingFactors: ReadingFactors,
  sensorDirection: SensorDirection,
  nominalReading: Option[RawSensorValue],
  normalMaximum: Option[RawSensorValue],
  normalMinimum: Option[RawSensorValue],
  sensorMaxumumReading: RawSensorValue,
  sensorMinimumReading: RawSensorValue,
  positiveGoingThresholdHysteresis: Hysteresis,
  negativeGoingThresholdHysteresis: Hysteresis
) extends SdrKeyAndBody
    with AnalogSdrKeyAndBody
    with EventSdrKeyAndBody {
  val sensorIds: Seq[SensorId] = Seq(sensorId)
  val sensorNumbers: Seq[SensorNumber] = Seq(sensorNumber)
  val recordType: SensorDataRecordType = SensorDataRecordType.Full
  val optSensorType = Some(sensorType)
}

object FullSdrKeyAndBody {
  implicit val decoder: Decoder[FullSdrKeyAndBody] = new Decoder[FullSdrKeyAndBody] {

    def decode(data: ByteString): FullSdrKeyAndBody = {
      val iterator = data.iterator
      val is = iterator.asInputStream

      val ownerId = is.readByte.as[SensorOwnerId]
      val ownerLun = is.readByte.as[SensorOwnerLun]
      val sensorNumber = is.readByte.as[SensorNumber]

      val entityId = is.readByte.as[EntityId]
      val entityInstance = is.readByte.as[EntityInstance]

      val sensorInit = is.readByte.as[SensorInitialization]
      val sensorCaps = is.readByte.as[SensorCapabilities]
      val sensorType = is.readByte.as[SensorType]

      val eventReadingType = is.readByte.as[EventReadingType]

      val sensorMasks =
        is.read(6).as[SensorMasks](SensorMasks.decoder(eventReadingType, sensorType))

      val sensorUnitsBytes = is.read(3)

      val analogDataFormat = sensorUnitsBytes.as[AnalogDataFormat]

      val sensorUnits = sensorUnitsBytes.as[SensorUnits]

      val linearization = is.readByte.as[Linearization]

      val readingFactorBytes = is.read(6)
      val readingFactor = readingFactorBytes.as[ReadingFactors]

      val sensorDirection = readingFactorBytes(4).as[SensorDirection]

      val analogCharacteristics = is.readByte.as[AnalogCharacteristics]
      val nominalReading = is.readByte.map(
        b => analogCharacteristics.nominalReadingSpecified.option(b.as[RawSensorValue])
      )
      val normalMaximum =
        is.readByte.map(b => analogCharacteristics.normalMaxSpecified.option(b.as[RawSensorValue]))
      val normalMinimum =
        is.readByte.map(b => analogCharacteristics.normalMinSpecified.option(b.as[RawSensorValue]))

      val sensorMaximum = is.readByte.as[RawSensorValue]
      val sensorMinimum = is.readByte.as[RawSensorValue]

      // Ignore sensor thresholds - only set if set threshold bit set
      // and can more easily get from Get Sensor Threshold command
      is.skip(6)

      val positiveGoingHyst = is.readByte.as[Hysteresis]
      val negativeGoingHyst = is.readByte.as[Hysteresis]

      // Reserved
      is.skip(2)

      // OEM
      is.skip(1)

      val sensorId = iterator.toByteString.as[SensorId]

      FullSdrKeyAndBody(
        ownerId = ownerId,
        ownerLun = ownerLun,
        sensorNumber = sensorNumber,
        entityId = entityId,
        entityInstance = entityInstance,
        sensorInitialization = sensorInit,
        sensorCapabilities = sensorCaps,
        sensorType = sensorType,
        sensorMasks = sensorMasks,
        sensorUnits = sensorUnits,
        linearization = linearization,
        analogDataFormat = analogDataFormat,
        readingFactors = readingFactor,
        sensorDirection = sensorDirection,
        nominalReading = nominalReading,
        normalMaximum = normalMaximum,
        normalMinimum = normalMinimum,
        sensorMaxumumReading = sensorMaximum,
        sensorMinimumReading = sensorMinimum,
        positiveGoingThresholdHysteresis = positiveGoingHyst,
        negativeGoingThresholdHysteresis = negativeGoingHyst,
        sensorId = sensorId
      )
    }
  }
}