def __init__(self, payload): if len(payload) != SERVICE_DATA_SIZE: print("ERROR: INVALID SERVICE DATA LENGTH", len(payload), payload) return self.opCode = payload[0] self.dataType = payload[1] self.crownstoneId = payload[2] self.switchState = payload[3] # TODO: make less ugly if self.switchState > 100: self.relayState = 1 self.igbtState = float(self.switchState - 128) / 100.0 self.flagBitmask = payload[4] self.temperature = Conversion.uint8_to_int8(payload[5]) self.powerFactor = float(Conversion.uint8_to_int8(payload[6])) / 127 self.powerUsageReal = float( Conversion.uint8_array_to_int16(payload[7:7 + 2])) / 8 self.energyUsed = Conversion.uint8_array_to_int32( payload[9:9 + 4]) * 64 self.partialTimestamp = Conversion.uint8_array_to_int16(payload[13:13 + 2]) self.validation = Conversion.uint8_array_to_int16(payload[15:15 + 2])
def parseOpCode5(serviceData, data): if len(data) == 18: if DeviceType.has_value(data[1]): serviceData.deviceType = DeviceType(data[1]) else: serviceData.deviceType = DeviceType.undefined serviceData.dataType = data[2] dataSlice = data[1:] if serviceData.dataType == 0: parseOpCode3_type0(serviceData, dataSlice) elif serviceData.dataType == 1: parseOpCode3_type1(serviceData, dataSlice) elif serviceData.dataType == 2: parseOpCode3_type2(serviceData, dataSlice) serviceData.rssiOfExternalCrownstone = Conversion.uint8_to_int8( dataSlice[15]) elif serviceData.dataType == 3: parseOpCode3_type3(serviceData, dataSlice) serviceData.rssiOfExternalCrownstone = Conversion.uint8_to_int8( dataSlice[15]) else: parseOpCode3_type0(serviceData, dataSlice)
def parseOpCode3_type0(serviceData, data): if len(data) == 16: # dataType = data[0] serviceData.stateOfExternalCrownstone = False serviceData.crownstoneId = data[1] serviceData.switchState = data[2] serviceData.flagsBitmask = data[3] # bitmask states bitmaskArray = Conversion.uint8_to_bit_array(serviceData.flagsBitmask) serviceData.dimmerReady = bitmaskArray[0] serviceData.dimmingAllowed = bitmaskArray[1] serviceData.hasError = bitmaskArray[2] serviceData.switchLocked = bitmaskArray[3] serviceData.timeIsSet = bitmaskArray[4] serviceData.switchCraftEnabled = bitmaskArray[5] serviceData.tapToToggleEnabled = bitmaskArray[6] serviceData.behaviourOverridden = bitmaskArray[7] serviceData.temperature = Conversion.uint8_to_int8(data[4]) powerFactor = Conversion.uint8_to_int8(data[5]) realPower = Conversion.uint16_to_int16( Conversion.uint8_array_to_uint16([data[6], data[7]])) serviceData.powerFactor = float(powerFactor) / 127.0 # we cannot have a 0 for a power factor.To avoid division by 0, we set it to be either 0.01 or -0.01 if 0 <= serviceData.powerFactor < 0.01: serviceData.powerFactor = 0.01 elif -0.01 < serviceData.powerFactor < 0: serviceData.powerFactor = -0.01 serviceData.powerUsageReal = float(realPower) / 8.0 serviceData.powerUsageApparent = serviceData.powerUsageReal / serviceData.powerFactor serviceData.accumulatedEnergy = Conversion.uint32_to_int32( Conversion.uint8_array_to_uint32( [data[8], data[9], data[10], data[11]])) serviceData.partialTimestamp = Conversion.uint8_array_to_uint16( [data[12], data[13]]) serviceData.uniqueIdentifier = serviceData.partialTimestamp if serviceData.timeIsSet: serviceData.timestamp = reconstructTimestamp( time.time(), serviceData.partialTimestamp) else: serviceData.timestamp = serviceData.partialTimestamp # this is now a counter globalBitmaskArray = Conversion.uint8_to_bit_array(data[14]) serviceData.behaviourEnabled = globalBitmaskArray[0] serviceData.validation = data[15]
def parseOpCode5(serviceData, data): if len(data) == 16: serviceData.dataType = data[0] if serviceData.dataType == 0: parseOpCode3_type0(serviceData, data) elif serviceData.dataType == 1: parseOpCode3_type1(serviceData, data) elif serviceData.dataType == 2: parseOpCode3_type2(serviceData, data) serviceData.rssiOfExternalCrownstone = Conversion.uint8_to_int8( data[15]) elif serviceData.dataType == 3: parseOpCode3_type3(serviceData, data) serviceData.rssiOfExternalCrownstone = Conversion.uint8_to_int8( data[15]) else: parseOpCode3_type0(serviceData, data)
def parseOpcode4_type0(serviceData, data): if len(data) == 17: # opCode = data[0] # dataType = data[1] serviceData.switchState = data[2] serviceData.flagsBitmask = data[3] # bitmask states bitmaskArray = Conversion.uint8_to_bit_array(serviceData.flagsBitmask) serviceData.dimmingAvailable = bitmaskArray[0] serviceData.dimmingAllowed = bitmaskArray[1] serviceData.hasError = bitmaskArray[2] serviceData.switchLocked = bitmaskArray[3] serviceData.timeIsSet = bitmaskArray[4] serviceData.temperature = Conversion.uint8_to_int8(data[4]) powerFactor = Conversion.uint8_to_int8(data[5]) realPower = Conversion.uint16_to_int16(Conversion.uint8_array_to_uint16([data[6], data[7]])) serviceData.powerFactor = float(powerFactor) / 127.0 # we cannot have a 0 for a power factor.To avoid division by 0, we set it to be either 0.01 or -0.01 if 0 <= serviceData.powerFactor < 0.01: serviceData.powerFactor = 0.01 elif -0.01 < serviceData.powerFactor < 0: serviceData.powerFactor = -0.01 serviceData.powerUsageReal = float(realPower) / 8.0 serviceData.powerUsageApparent = serviceData.powerUsageReal / serviceData.powerFactor serviceData.accumulatedEnergy = Conversion.uint32_to_int32( Conversion.uint8_array_to_uint32([ data[8], data[9], data[10], data[11] ]) ) serviceData.uniqueIdentifier = data[12]
def parseOpCode3_type1(serviceData, data): if len(data) == 17: # opCode = data[0] # dataType = data[1] serviceData.errorMode = True serviceData.crownstoneId = data[2] serviceData.errorsBitmask = Conversion.uint8_array_to_uint32([ data[3], data[4], data[5], data[6] ]) serviceData.errorTimestamp = Conversion.uint8_array_to_uint32([ data[7], data[8], data[9], data[10] ]) serviceData.flagsBitmask = data[11] # bitmask states bitmaskArray = Conversion.uint8_to_bit_array(serviceData.flagsBitmask) serviceData.dimmingAvailable = bitmaskArray[0] serviceData.dimmingAllowed = bitmaskArray[1] serviceData.hasError = bitmaskArray[2] serviceData.switchLocked = bitmaskArray[3] serviceData.timeIsSet = bitmaskArray[4] serviceData.switchCraftEnabled = bitmaskArray[5] serviceData.temperature = Conversion.uint8_to_int8(data[12]) serviceData.partialTimestamp = Conversion.uint8_array_to_uint16([data[13], data[14]]) serviceData.uniqueIdentifier = serviceData.partialTimestamp if serviceData.timeIsSet: serviceData.timestamp = reconstructTimestamp(time.time(), serviceData.partialTimestamp) else: serviceData.timestamp = serviceData.partialTimestamp # this is now a counter realPower = Conversion.uint16_to_int16( Conversion.uint8_array_to_uint16([ data[15], data[16] ]) ) serviceData.powerUsageReal = float(realPower) / 8.0 # this packet has no validation serviceData.validation = 0