551 lines
19 KiB
Go
551 lines
19 KiB
Go
package statusupdate
|
|
|
|
import (
|
|
"math"
|
|
"time"
|
|
|
|
"src.dualinventive.com/go/dinet/ditime"
|
|
"src.dualinventive.com/go/dinet/rpc"
|
|
)
|
|
|
|
// StatusUpdate is a status-update via CP3000
|
|
type StatusUpdate struct {
|
|
MCUState uint16
|
|
RCState uint16
|
|
SwitchState uint16
|
|
MCULocalState uint16
|
|
NATWSCounter uint64
|
|
NATWSDirection int64
|
|
BACalibrated float64
|
|
Frequency int64
|
|
RMS uint64
|
|
BAActual float64
|
|
BatSelected int64
|
|
Battery1 float64
|
|
Battery2 float64
|
|
TempOnboard float64
|
|
TempNTC float64
|
|
GSMRSSI int64
|
|
GSMBER int64
|
|
GPSLatitude float64
|
|
GPSLongitude float64
|
|
GPSAltitude float64
|
|
GPSHDOP float64
|
|
GPSSpeed float64
|
|
GPSHeading float64
|
|
GPSTime time.Time
|
|
Tilt struct {
|
|
X float64
|
|
Y float64
|
|
Z float64
|
|
}
|
|
WCPUState uint32
|
|
MCUPersistent uint32
|
|
GPSFIX GpsFixType
|
|
Fields StatUpdateField
|
|
}
|
|
|
|
// GpsFixType is the type of Fix (or no fix) by a device
|
|
type GpsFixType byte
|
|
|
|
const (
|
|
// GpsFixTypeAutonomous autonomous fix
|
|
GpsFixTypeAutonomous GpsFixType = 'A'
|
|
// GpsFixTypeStationary stationary fix
|
|
GpsFixTypeStationary GpsFixType = 'S'
|
|
// GpsFixTypeDifferential differential fix
|
|
GpsFixTypeDifferential GpsFixType = 'D'
|
|
// GpsFixTypeEstimated estimated fix
|
|
GpsFixTypeEstimated GpsFixType = 'E'
|
|
// GpsFixTypeInitFromMCU fix from MCU config
|
|
GpsFixTypeInitFromMCU GpsFixType = 'I'
|
|
// GpsFixTypeInvalid no fix
|
|
GpsFixTypeInvalid GpsFixType = 'N'
|
|
// GpsFixTypeUninitialized no fix (uninitialized)
|
|
GpsFixTypeUninitialized GpsFixType = 'U'
|
|
)
|
|
|
|
// StatUpdateField is a mask which indicates which field is updated in the $UPDT status
|
|
type StatUpdateField uint32
|
|
|
|
const (
|
|
// StatUpdateAll all fields
|
|
StatUpdateAll StatUpdateField = 0xFFFFFFFF
|
|
// StatUpdateZKL3000 all ZKL 3000 fields
|
|
StatUpdateZKL3000 StatUpdateField = 0xFFFFFFF3
|
|
// StatUpdateState system state
|
|
StatUpdateState StatUpdateField = 0x0001
|
|
// StatUpdateWcpuState modem state (or communication device in general)
|
|
StatUpdateWcpuState StatUpdateField = 0x0002
|
|
// StatUpdatePMGT power management
|
|
StatUpdatePMGT StatUpdateField = 0x0004
|
|
// StatUpdateSwitch switch state
|
|
StatUpdateSwitch StatUpdateField = 0x0008
|
|
// StatUpdateRMS measurement, RMS^2
|
|
StatUpdateRMS StatUpdateField = 0x0010
|
|
// StatUpdateBA measurement, b/a
|
|
StatUpdateBA StatUpdateField = 0x0020
|
|
// StatUpdateNATWS measurement, detection counter and direction
|
|
StatUpdateNATWS StatUpdateField = 0x0040
|
|
// StatUpdateAutocal measurement, calibrated b/a and frequency
|
|
StatUpdateAutocal StatUpdateField = 0x0080
|
|
// StatUpdateBattSel battery selection
|
|
StatUpdateBattSel StatUpdateField = 0x0800
|
|
// StatUpdateBatt1Level battery #1 level (V)
|
|
StatUpdateBatt1Level StatUpdateField = 0x0100
|
|
// StatUpdateBatt2Level battery #2 level (V)
|
|
StatUpdateBatt2Level StatUpdateField = 0x0200
|
|
// StatUpdateIntTemp internal temperature sensor (C; on-board sensor on ZKL3000)
|
|
StatUpdateIntTemp StatUpdateField = 0x1000
|
|
// StatUpdateExtTemp external temperature sensor(s) (C; external NTC on ZKL3000)
|
|
StatUpdateExtTemp StatUpdateField = 0x2000
|
|
// StatUpdateGPS GPS co-ordinates and additional info
|
|
StatUpdateGPS StatUpdateField = 0x4000
|
|
// StatUpdateGSM GSM RSSI and BER
|
|
StatUpdateGSM StatUpdateField = 0x8000
|
|
// StatUpdateTime time field present
|
|
StatUpdateTime StatUpdateField = 0x00010000
|
|
// StatUpdateTimeSource time source present in time field (internal use)
|
|
StatUpdateTimeSource StatUpdateField = 0x00020000
|
|
// StatUpdateSW3000Temperature temperature sensor of the Switch 3000
|
|
StatUpdateSW3000Temperature StatUpdateField = 0x00100000
|
|
// StatUpdateTilt tilt sensor
|
|
StatUpdateTilt StatUpdateField = 0x00200000
|
|
// StatUpdateVibration vibration sensor
|
|
StatUpdateVibration StatUpdateField = 0x00400000
|
|
)
|
|
|
|
const voltageDiff = 0.001
|
|
|
|
func mustSend(s *StatusUpdate, field StatUpdateField) bool {
|
|
return (s.Fields & field) == field
|
|
}
|
|
|
|
// Battery1Voltage returns the Battery1 voltage
|
|
func (s *StatusUpdate) Battery1Voltage() float64 {
|
|
return s.Battery1
|
|
}
|
|
|
|
// Battery1State returns the Battery1 state
|
|
func (s *StatusUpdate) Battery1State() rpc.BatteryState {
|
|
return decodeBatState((s.MCUState & 0x0F00) >> 8)
|
|
}
|
|
|
|
// Battery2Voltage returns the Battery2 voltage
|
|
func (s *StatusUpdate) Battery2Voltage() float64 {
|
|
return s.Battery2
|
|
}
|
|
|
|
// Battery2State returns the Battery2 state
|
|
func (s *StatusUpdate) Battery2State() rpc.BatteryState {
|
|
return decodeBatState((s.MCUState & 0x0F000) >> 12)
|
|
}
|
|
|
|
// Charger1State returns the charger 1 state
|
|
func (s *StatusUpdate) Charger1State() rpc.ChargerState {
|
|
// If the pm3000 charging bit is set, the pm3000 is charging
|
|
if s.RCState&0x04 == 0x04 {
|
|
return rpc.ChargerStateCharging
|
|
}
|
|
// The pm3000 is not charging. If bat2 is available, there is a charger.
|
|
switch s.Battery2State() {
|
|
case rpc.BatteryStateFull, rpc.BatteryStateHalf, rpc.BatteryStateLow, rpc.BatteryStateCritical, rpc.BatteryStateEmpty:
|
|
return rpc.ChargerStateConnected
|
|
default:
|
|
return rpc.ChargerStateDisconnected
|
|
}
|
|
}
|
|
|
|
// GPS returns the GPS position and HDOP
|
|
func (s *StatusUpdate) GPS() rpc.GPSSensorData {
|
|
return rpc.GPSSensorData{
|
|
HDOP: s.GPSHDOP,
|
|
Latitude: s.GPSLatitude,
|
|
Longitude: s.GPSLongitude,
|
|
}
|
|
}
|
|
|
|
// RSSI returns the RSSI
|
|
func (s *StatusUpdate) RSSI() int64 {
|
|
return s.GSMRSSI
|
|
}
|
|
|
|
// BER returns the BER
|
|
func (s *StatusUpdate) BER() int64 {
|
|
return s.GSMBER
|
|
}
|
|
|
|
// DetectionQuality returns the detection quality
|
|
func (s *StatusUpdate) DetectionQuality() float64 {
|
|
val := (100 * (1 - (math.Pow(s.BAActual-0.125, 4) / math.Pow(s.BACalibrated-0.125, 4))))
|
|
if val < 0 {
|
|
return 0
|
|
}
|
|
return val
|
|
}
|
|
|
|
// DetectionStatus returns if the detection is OK
|
|
func (s *StatusUpdate) DetectionStatus() bool {
|
|
return s.MCUState&0x2 == 0x2
|
|
}
|
|
|
|
// RelayOpen is a reused bitfield which indicates the rail-contact during sleep
|
|
func (s *StatusUpdate) RelayOpen() bool {
|
|
return s.MCUState&0x8 == 0x8
|
|
}
|
|
|
|
// Measurement returns if the measurement is on
|
|
func (s *StatusUpdate) Measurement() bool {
|
|
return s.MCUState&0x1 == 0x1
|
|
}
|
|
|
|
// Ba returns the Ba
|
|
func (s *StatusUpdate) Ba() float64 {
|
|
return s.BAActual
|
|
}
|
|
|
|
// Freq returns the Frequency
|
|
func (s *StatusUpdate) Freq() int64 {
|
|
return s.Frequency
|
|
}
|
|
|
|
// SectionsShort returns which sections have a short
|
|
func (s *StatusUpdate) SectionsShort() rpc.SectionsShort {
|
|
return decodeSWBatteryShort(s.SwitchState & 0xF)
|
|
}
|
|
|
|
// SectionsBattery returns which sections have battery power
|
|
func (s *StatusUpdate) SectionsBattery() rpc.SectionsShort {
|
|
return decodeSWBatteryShort((s.SwitchState & 0xF00) >> 8)
|
|
}
|
|
|
|
// SwitchShort returns if the short is on
|
|
func (s *StatusUpdate) SwitchShort() bool {
|
|
// This checks if sections 1 and 4 or 2 and 3 are shorted. When either of this
|
|
// is true, the switch is on
|
|
return (s.SwitchState&0x9 == 0x9) || (s.SwitchState&0x6 == 0x6)
|
|
}
|
|
|
|
// KeySwitch returns the key switch state
|
|
func (s *StatusUpdate) KeySwitch() rpc.KeyswitchState {
|
|
switch s.RCState & 0xC {
|
|
case 0x0: // operational
|
|
return rpc.KeyswitchStateOperational
|
|
case 0x4: // on
|
|
return rpc.KeyswitchStateOn
|
|
case 0x8: // off
|
|
return rpc.KeyswitchStateOff
|
|
}
|
|
return rpc.KeyswitchStateUnknown
|
|
}
|
|
|
|
// CRTMTemperature1 returns the Temperature1 for the CRTM
|
|
func (s *StatusUpdate) CRTMTemperature1() float64 {
|
|
return s.TempOnboard
|
|
}
|
|
|
|
// CRTMTemperature2 returns the Temperature2 for the CRTM
|
|
func (s *StatusUpdate) CRTMTemperature2() float64 {
|
|
return s.TempNTC
|
|
}
|
|
|
|
// Released returns true when the switch is released. This is set when the token is stored successfully
|
|
func (s *StatusUpdate) Released() bool {
|
|
return s.MCUPersistent&0x80 == 0x80
|
|
}
|
|
|
|
// ErrSecureHandshake returns true when the security check is not passed (programming of the device is locked)
|
|
func (s *StatusUpdate) ErrSecureHandshake() bool {
|
|
return s.WCPUState&0x1 == 0x1
|
|
}
|
|
|
|
// ErrMeasurementFailed returns if there is a measurement error
|
|
func (s *StatusUpdate) ErrMeasurementFailed() bool {
|
|
return s.MCUState&0x4 == 0x4
|
|
}
|
|
|
|
// ErrUARTMcu returns if there is an UART MCU error
|
|
func (s *StatusUpdate) ErrUARTMcu() bool {
|
|
return s.WCPUState&0x10 == 0x10
|
|
}
|
|
|
|
// ErrUARTGPS returns if there is an UART GPS error
|
|
func (s *StatusUpdate) ErrUARTGPS() bool {
|
|
return s.WCPUState&0x20 == 0x20
|
|
}
|
|
|
|
// ErrMCU returns if there is a MCU error
|
|
func (s *StatusUpdate) ErrMCU() bool {
|
|
return s.WCPUState&0x80 == 0x80
|
|
}
|
|
|
|
// ErrSwitch3000Timeout returns if there is a switch 3000 timeout
|
|
func (s *StatusUpdate) ErrSwitch3000Timeout() bool {
|
|
return s.SwitchState&0x10 == 0x10
|
|
}
|
|
|
|
// ErrSwitch3000 returns if there is a switch 3000 error
|
|
func (s *StatusUpdate) ErrSwitch3000() bool {
|
|
return s.SwitchState&0x20 == 0x20
|
|
}
|
|
|
|
func decodeBatState(state uint16) rpc.BatteryState {
|
|
switch state {
|
|
case 0x00: // ok
|
|
return rpc.BatteryStateFull
|
|
case 0x01: // alarm
|
|
return rpc.BatteryStateCritical
|
|
case 0x03: // leeg
|
|
return rpc.BatteryStateEmpty
|
|
case 0x07: // verwijderd
|
|
return rpc.BatteryStateRemoved
|
|
}
|
|
return rpc.BatteryState(-1)
|
|
}
|
|
|
|
func decodeSWBatteryShort(data uint16) rpc.SectionsShort {
|
|
var sections rpc.SectionsShort
|
|
sections.State = ((data & 0xF) == 0xF)
|
|
sections.Section1 = ((data & 0x1) == 0x1)
|
|
sections.Section2 = ((data & 0x2) == 0x2)
|
|
sections.Section3 = ((data & 0x4) == 0x4)
|
|
sections.Section4 = ((data & 0x8) == 0x8)
|
|
return sections
|
|
}
|
|
|
|
// CheckBattery1 checks if Battery1 is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckBattery1(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if math.Abs(s.Battery1Voltage()-n.Battery1Voltage()) >= voltageDiff || mustSend(s, StatUpdateBatt1Level) {
|
|
return append(data, rpc.SensorBattery1Voltage.Data(n.Battery1Voltage()))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckBattery1State checks if the state of Battery1 is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckBattery1State(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
sBat1State := s.Battery1State()
|
|
nBat1State := n.Battery1State()
|
|
if sBat1State != nBat1State || mustSend(s, StatUpdateState) {
|
|
return append(data, rpc.SensorBattery1State.Data(nBat1State))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckBattery2 checks if Battery2 is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckBattery2(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if math.Abs(s.Battery2-n.Battery2) >= voltageDiff || mustSend(s, StatUpdateBatt2Level) {
|
|
return append(data, rpc.SensorBattery2Voltage.Data(n.Battery2))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckBattery2State checks if the state of Battery2 is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckBattery2State(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
sBat2State := s.Battery2State()
|
|
nBat2State := n.Battery2State()
|
|
if sBat2State != nBat2State || mustSend(s, StatUpdateState) {
|
|
return append(data, rpc.SensorBattery2State.Data(nBat2State))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckCharger1State checks if the charger1 state is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckCharger1State(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
sChargerState := s.Charger1State()
|
|
nChargerState := n.Charger1State()
|
|
if sChargerState != nChargerState || mustSend(s, StatUpdatePMGT) || mustSend(s, StatUpdateState) {
|
|
return append(data, rpc.SensorCharger1State.Data(nChargerState))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckGPS checks if GPS data is changed, has a fix and appends the sensor value
|
|
func (s *StatusUpdate) CheckGPS(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if n.GPSFIX != GpsFixTypeAutonomous && n.GPSFIX != GpsFixTypeStationary &&
|
|
n.GPSFIX != GpsFixTypeDifferential && n.GPSFIX != GpsFixTypeEstimated {
|
|
return data
|
|
}
|
|
|
|
if s.GPSTime != n.GPSTime || mustSend(s, StatUpdateGPS) {
|
|
return append(data, rpc.SensorGPS.Data(n.GPS(), ditime.FromTime(n.GPSTime)))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckRSSI checks if the RSSI is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckRSSI(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if s.RSSI() != n.RSSI() || mustSend(s, StatUpdateGSM) {
|
|
return append(data, rpc.SensorRSSI.Data(n.RSSI()))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckBER checks if the BER is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckBER(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if s.BER() != n.BER() || mustSend(s, StatUpdateGSM) {
|
|
return append(data, rpc.SensorBER.Data(n.BER()))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckDetectionQuality checks if the detection quality is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckDetectionQuality(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
sQuality := s.DetectionQuality()
|
|
nQuality := n.DetectionQuality()
|
|
if (math.Abs(sQuality-nQuality) >= 0.01) || mustSend(s, StatUpdateBA) || mustSend(s, StatUpdateAutocal) {
|
|
return append(data, rpc.ZKLSensorDetectionQuality.Data(nQuality))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckDetectionStatus checks if the status of the detection is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckDetectionStatus(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if s.DetectionStatus() != n.DetectionStatus() || mustSend(s, StatUpdateState) {
|
|
return append(data, rpc.ZKLSensorDetection.Data(n.DetectionStatus()))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckMeasurement checks if the measurement state is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckMeasurement(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if s.Measurement() != n.Measurement() || mustSend(s, StatUpdateState) {
|
|
return append(data, rpc.ZKLSensorMeasurement.Data(n.Measurement()))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckBAActual checks if the current B/A value is changed and appends the sensor value
|
|
func (s *StatusUpdate) CheckBAActual(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if (math.Abs(s.Ba()-n.Ba()) >= 0.001) || mustSend(s, StatUpdateBA) {
|
|
return append(data, rpc.ZKLSensorBa.Data(n.Ba()))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckFrequency checks if the Frequency is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckFrequency(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if s.Freq() != n.Freq() || mustSend(s, StatUpdateAutocal) {
|
|
return append(data, rpc.ZKLSensorFrequency.Data(n.Freq()))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckSWShort checks if the switch state of the short is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckSWShort(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
sShort := s.SectionsShort()
|
|
nShort := n.SectionsShort()
|
|
if sShort != nShort || mustSend(s, StatUpdateSwitch) {
|
|
return append(data, rpc.ZKLRCSensorSectionsShort.Data(nShort))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckSWBattery checks if the switch battery state is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckSWBattery(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
sBattery := s.SectionsBattery()
|
|
nBattery := n.SectionsBattery()
|
|
if sBattery != nBattery || mustSend(s, StatUpdateSwitch) {
|
|
return append(data, rpc.ZKLRCSensorSectionsBattery.Data(nBattery))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckSwitchState checks if the short-circuit is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckSwitchState(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if s.SwitchShort() != n.SwitchShort() || mustSend(s, StatUpdatePMGT) {
|
|
return append(data, rpc.ZKLRCSensorSwitchShort.Data(n.SwitchShort()))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckKeyswitch checks if the charger1 state is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckKeyswitch(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
sSwitch := s.KeySwitch()
|
|
nSwitch := n.KeySwitch()
|
|
if sSwitch != nSwitch || mustSend(s, StatUpdatePMGT) {
|
|
return append(data, rpc.ZKLRCSensorKeySwitch.Data(nSwitch))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckRMS checks if the RMS is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckRMS(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if s.RMS != n.RMS || mustSend(s, StatUpdateRMS) {
|
|
return append(data, rpc.ZKLSensorRMS.Data(n.RMS))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckBAAutocal checks if the BAAutoCal is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckBAAutocal(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if s.BACalibrated != n.BACalibrated || mustSend(s, StatUpdateAutocal) {
|
|
return append(data, rpc.ZKLSensorBAAutocal.Data(n.BACalibrated))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckCRTMTemperature1 checks if the temperature is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckCRTMTemperature1(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
return s.CheckTempOnboard(data, n, &rpc.CRTMSensorTemperature1)
|
|
}
|
|
|
|
// CheckCRTMTemperature2 checks if the temperature is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckCRTMTemperature2(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
return s.CheckTempNTC(data, n, &rpc.CRTMSensorTemperature2)
|
|
}
|
|
|
|
// CheckTempOnboard checks if the temperature is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckTempOnboard(data []*rpc.ResultValueItem, n *StatusUpdate,
|
|
sensor *rpc.Sensor) []*rpc.ResultValueItem {
|
|
if s.TempOnboard != n.TempOnboard || mustSend(s, StatUpdateIntTemp) {
|
|
return append(data, sensor.Data(n.TempOnboard))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckTempNTC checks if the temperature is changed and appends the sensor-value
|
|
func (s *StatusUpdate) CheckTempNTC(data []*rpc.ResultValueItem, n *StatusUpdate,
|
|
sensor *rpc.Sensor) []*rpc.ResultValueItem {
|
|
if s.TempNTC != n.TempNTC || mustSend(s, StatUpdateExtTemp) {
|
|
return append(data, sensor.Data(n.TempNTC))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckRailContact checks if the rail contact bit is set and appends a sensor value
|
|
func (s *StatusUpdate) CheckRailContact(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if s.DetectionStatus() != n.DetectionStatus() || mustSend(s, StatUpdateState) {
|
|
return append(data, rpc.CRTMSensorRailContact.Data(n.DetectionStatus()))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckRailContactSleep checks if the rail contact sleep bit is set and appends a sensor value
|
|
func (s *StatusUpdate) CheckRailContactSleep(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
if s.RelayOpen() != n.RelayOpen() || mustSend(s, StatUpdateState) {
|
|
return append(data, rpc.CRTMSensorRailContactSleep.Data(n.RelayOpen()))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// CheckTilt checks if the tilt-data is present and appends the sensor value
|
|
func (s *StatusUpdate) CheckTilt(data []*rpc.ResultValueItem, n *StatusUpdate) []*rpc.ResultValueItem {
|
|
|
|
// Translate all values to milli-G's
|
|
oldX := int32(s.Tilt.X * 1000)
|
|
oldY := int32(s.Tilt.Y * 1000)
|
|
oldZ := int32(s.Tilt.Z * 1000)
|
|
newX := int32(n.Tilt.X * 1000)
|
|
newY := int32(n.Tilt.Y * 1000)
|
|
newZ := int32(n.Tilt.Z * 1000)
|
|
|
|
if oldX != newX || oldY != newY || oldZ != newZ || mustSend(s, StatUpdateTilt) {
|
|
return append(data, rpc.CRTMSensorAcceleration.Data(map[string]int32{
|
|
"X": newX,
|
|
"Y": newY,
|
|
"Z": newZ,
|
|
}))
|
|
}
|
|
return data
|
|
}
|