diff --git a/pyaci/aci/AciCommand.py b/pyaci/aci/AciCommand.py index 04b6f83..5b177a0 100644 --- a/pyaci/aci/AciCommand.py +++ b/pyaci/aci/AciCommand.py @@ -39,7 +39,8 @@ def __init__(self, OpCode, data=[], length = 1): self.OpCode = OpCode self.Data = data if length != (len(self.Data) + 1): - logging.error("Length: %d, must be equal to the number of data items: %s plus 1 (for the opcode)",self.Len, str(self.Data)) + logging.error("Length: %d, must be equal to the number of data items:" \ + + " %s plus 1 (for the opcode)", self.Len, str(self.Data)) def serialize(self): pkt = [self.Len] @@ -48,131 +49,145 @@ def serialize(self): return pkt def __repr__(self): - return str.format("I am %s and my Length is %d, OpCode is 0x%02x and Data is %s" %(self.__class__.__name__, self.Len, self.OpCode, self.Data)) + return "I am %s and my Length is %d, OpCode is 0x%02x and Data is %s" % ( + self.__class__.__name__, self.Len, self.OpCode, self.Data) class AciEcho(AciCommandPkt): OpCode = 0x02 MAX_ECHO_LENGTH = 30 def __init__(self, data=[], length=1): if length > self.MAX_ECHO_LENGTH: - logging.error("ECHO command can have a maximum of %d byte packet size (including the opcode), not %d",MAX_ECHO_LENGTH,length) + logging.error("ECHO command can have a maximum of %d byte packet size" \ + + " (including the opcode), not %d", MAX_ECHO_LENGTH, length) else: - super(AciEcho, self).__init__(length=length,OpCode=self.OpCode, data = data) + super(AciEcho, self).__init__(length=length, OpCode=self.OpCode, data=data) class AciRadioReset(AciCommandPkt): OpCode = 0x0E Length = 1 def __init__(self): - super(AciRadioReset, self).__init__(length=self.Length,OpCode=self.OpCode) + super(AciRadioReset, self).__init__(length=self.Length, OpCode=self.OpCode) class AciAppCommand(AciCommandPkt): OpCode = 0x1A MAX_CMD_LENGTH = 28 def __init__(self, data=[], length=1): if length > self.MAX_CMD_LENGTH: - logging.error("App commands can have a maximum of %d byte packet size (including the opcode), not %d",MAX_CMD_LENGTH,length) + logging.error("App commands can have a maximum of %d byte packet size " \ + + "(including the opcode), not %d", MAX_CMD_LENGTH, length) else: - super(AciAppCommand, self).__init__(length=length,OpCode=self.OpCode, data = data) + super(AciAppCommand, self).__init__(length=length, OpCode=self.OpCode, + data=data) class AciInit(AciCommandPkt): OpCode = 0x70 Length = 10 def __init__(self, access_address, min_interval, channel): - payload = valueToByteArray(access_address,4) - payload.extend(valueToByteArray(min_interval,4)) - payload.extend(valueToByteArray(channel,1)) - super(AciInit, self).__init__(length=self.Length,OpCode=self.OpCode, data=payload) + payload = valueToByteArray(access_address, 4) + payload.extend(valueToByteArray(min_interval, 4)) + payload.extend(valueToByteArray(channel, 1)) + super(AciInit, self).__init__(length=self.Length, OpCode=self.OpCode, + data=payload) class AciValueSet(AciCommandPkt): OpCode = 0x71 MAX_VAL_LENGTH = 26 def __init__(self, handle, data, length=3): if length > self.MAX_VAL_LENGTH: - logging.error("VALUE_SET command can have a maximum of %d byte packet size (including the opcode), not %d",MAX_VAL_LENGTH,length) + logging.error("VALUE_SET command can have a maximum of %d byte packet size" \ + + " (including the opcode), not %d", MAX_VAL_LENGTH, length) else: - payload = valueToByteArray(handle,2) + payload = valueToByteArray(handle, 2) payload.extend(data) - super(AciValueSet, self).__init__(length=length, OpCode=self.OpCode, data=payload) + super(AciValueSet, self).__init__(length=length, OpCode=self.OpCode, + data=payload) class AciValueEnable(AciCommandPkt): OpCode = 0x72 Length = 3 def __init__(self, handle): - payload = valueToByteArray(handle,2) - super(AciValueEnable, self).__init__(length=self.Length, OpCode=self.OpCode, data=payload) + payload = valueToByteArray(handle, 2) + super(AciValueEnable, self).__init__(length=self.Length, OpCode=self.OpCode, + data=payload) class AciValueDisable(AciCommandPkt): OpCode = 0x73 Length = 3 def __init__(self, handle): - payload = valueToByteArray(handle,2) - super(AciValueDisable, self).__init__(length=self.Length, OpCode=self.OpCode, data=payload) + payload = valueToByteArray(handle, 2) + super(AciValueDisable, self).__init__(length=self.Length, OpCode=self.OpCode, + data=payload) class AciStart(AciCommandPkt): OpCode = 0x74 Length = 1 def __init__(self): - super(AciStart, self).__init__(length=self.Length,OpCode=self.OpCode) + super(AciStart, self).__init__(length=self.Length, OpCode=self.OpCode) class AciStop(AciCommandPkt): OpCode = 0x75 Length = 1 def __init__(self): - super(AciStop, self).__init__(length=self.Length,OpCode=self.OpCode) + super(AciStop, self).__init__(length=self.Length, OpCode=self.OpCode) class AciFlagSet(AciCommandPkt): OpCode = 0x76 Length = 5 def __init__(self, handle, flag_index, flag_value): - payload = valueToByteArray(handle,2) - payload.extend(valueToByteArray(flag_index,1)) - payload.extend(valueToByteArray(flag_value,1)) - super(AciFlagSet, self).__init__(length=self.Length,OpCode=self.OpCode, data=payload) + payload = valueToByteArray(handle, 2) + payload.extend(valueToByteArray(flag_index, 1)) + payload.extend(valueToByteArray(flag_value, 1)) + super(AciFlagSet, self).__init__(length=self.Length, OpCode=self.OpCode, + data=payload) class AciFlagGet(AciCommandPkt): OpCode = 0x77 Length = 4 def __init__(self, handle, flag_index): - payload = valueToByteArray(handle,2) - payload.extend(valueToByteArray(flag_index,1)) - super(AciFlagGet, self).__init__(length=self.Length,OpCode=self.OpCode, data=payload) + payload = valueToByteArray(handle, 2) + payload.extend(valueToByteArray(flag_index, 1)) + super(AciFlagGet, self).__init__(length=self.Length, OpCode=self.OpCode, + data=payload) class AciDfuData(AciCommandPkt): OpCode = 0x78 MAX_DFU_LENGTH = 26 def __init__(self, data=[], length=1): if length > self.MAX_DFU_LENGTH: - logging.error("DFU_DATA command can have a maximum of %d byte packet size (including the opcode), not %d",MAX_DFU_LENGTH,length) + logging.error("DFU_DATA command can have a maximum of %d byte packet size " \ + + "(including the opcode), not %d", MAX_DFU_LENGTH, length) else: - super(AciDfuData, self).__init__(length=length,OpCode=self.OpCode, data = data) + super(AciDfuData, self).__init__(length=length, OpCode=self.OpCode, + data=data) class AciValueGet(AciCommandPkt): OpCode = 0x7A Length = 3 def __init__(self, handle): - payload = valueToByteArray(handle,2) - super(AciValueGet, self).__init__(length=self.Length, OpCode=self.OpCode, data=payload) + payload = valueToByteArray(handle, 2) + super(AciValueGet, self).__init__(length=self.Length, OpCode=self.OpCode, + data=payload) class AciBuildVersionGet(AciCommandPkt): OpCode = 0x7B Length = 1 def __init__(self): - super(AciBuildVersionGet, self).__init__(length=self.Length,OpCode=self.OpCode) + super(AciBuildVersionGet, self).__init__(length=self.Length, OpCode=self.OpCode) class AciAccessAddressGet(AciCommandPkt): OpCode = 0x7C Length = 1 def __init__(self): - super(AciAccessAddressGet, self).__init__(length=self.Length,OpCode=self.OpCode) + super(AciAccessAddressGet, self).__init__(length=self.Length, OpCode=self.OpCode) class AciChannelGet(AciCommandPkt): OpCode = 0x7D Length = 1 def __init__(self): - super(AciChannelGet, self).__init__(length=self.Length,OpCode=self.OpCode) + super(AciChannelGet, self).__init__(length=self.Length, OpCode=self.OpCode) class AciIntervalMinMsGet(AciCommandPkt): OpCode = 0x7F Length = 1 def __init__(self): - super(AciIntervalMinMsGet, self).__init__(length=self.Length,OpCode=self.OpCode) + super(AciIntervalMinMsGet, self).__init__(length=self.Length, OpCode=self.OpCode) diff --git a/pyaci/aci/AciEvent.py b/pyaci/aci/AciEvent.py index dc34d3e..e53c437 100644 --- a/pyaci/aci/AciEvent.py +++ b/pyaci/aci/AciEvent.py @@ -62,21 +62,27 @@ def __init__(self, pkt): logging.error('Packet size must be > 1, packet contents: %s', str(pkt)) def __repr__(self): - return str.format("%s length:%d opcode:0x%02x data:%s" %(self.__class__.__name__, self.Len, self.OpCode, self.Data)) + return "%s length:%d opcode:0x%02x data:%s" % (self.__class__.__name__, + self.Len, self.OpCode, self.Data) class AciDeviceStarted(AciEventPkt): #OpCode = 0x81 def __init__(self,pkt): super(AciDeviceStarted, self).__init__(pkt) if self.Len != 4: - logging.error("Invalid length for %s event: %s", self.__class__.__name__, str(pkt)) + logging.error("Invalid length for %s event: %s", + self.__class__.__name__, str(pkt)) else: self.OperatingMode = pkt[2] self.HWError = pkt[3] self.DataCreditAvailable = pkt[4] def __repr__(self): - return str.format("%s length:%d opcode:0x%02x operating_mode:0x%02x hw_error:0x%02x data_credit_available:0x%02x" %(self.__class__.__name__, self.Len, self.OpCode, self.OperatingMode, self.HWError, self.DataCreditAvailable)) + return "%s length:%d opcode:0x%02x operating_mode:0x%02x hw_error:0x%02x " \ + + "data_credit_available:0x%02x" % (self.__class__.__name__, + self.Len, self.OpCode, + self.OperatingMode, self.HWError, + self.DataCreditAvailable) class AciEchoRsp(AciEventPkt): #OpCode = 0x82 @@ -88,14 +94,18 @@ class AciCmdRsp(AciEventPkt): def __init__(self,pkt): super(AciCmdRsp, self).__init__(pkt) if self.Len < 3: - logging.error("Invalid length for %s event: %s", self.__class__.__name__, str(pkt)) + logging.error("Invalid length for %s event: %s", + self.__class__.__name__, str(pkt)) else: self.CommandOpCode = pkt[2] self.StatusCode = pkt[3] self.Data = pkt[4:] def __repr__(self): - return str.format("%s length:%d opcode:0x%02x command_opcode:%s status_code:%s data:%s" %(self.__class__.__name__, self.Len, self.OpCode, AciCommand.AciCommandLookUp(self.CommandOpCode), AciStatusLookUp(self.StatusCode), self.Data)) + return "%s length:%d opcode:0x%02x command_opcode:%s status_code:%s data:%s" % ( + self.__class__.__name__, self.Len, self.OpCode, + AciCommand.AciCommandLookUp(self.CommandOpCode), + AciStatusLookUp(self.StatusCode), self.Data) class SensorValues(object): STATUS_JOSTLE_FLAG = 0x01 @@ -118,16 +128,21 @@ def __init__(self, sensor_id, data): self.data = data def __repr__(self): if self.is_valid: - return "SensorValues: sensor_id:{sensor_id} proximity_ids:{proximity_ids} proximity_rssi:{proximity_rssi} battery:{battery}, accel:({accel_x}, {accel_y}, {accel_z}), status:{status}, valid_time:{valid_time}".format(**vars(self)) + return "SensorValues: sensor_id:{sensor_id} proximity_ids:{proximity_ids} " \ + + "proximity_rssi:{proximity_rssi} battery:{battery}, accel:(" \ + + "{accel_x}, {accel_y}, {accel_z}), status:{status}, " \ + + "valid_time:{valid_time}".format(**vars(self)) else: - return "SensorValues: invalid data from sensor {sensor_id}: ({data})".format(sensor_id=self.sensor_id, data=self.data) + return "SensorValues: invalid data from sensor {sensor_id}: ({data})"\ + .format(**vars(self)) class AciEventNew(AciEventPkt): #OpCode = 0xB3 def __init__(self,pkt): super(AciEventNew, self).__init__(pkt) if self.Len < 3: - logging.error("Invalid length for %s event: %s", self.__class__.__name__, str(pkt)) + logging.error("Invalid length for %s event: %s", + self.__class__.__name__, str(pkt)) else: self.ValueHandle = (pkt[3] << 8) + pkt[2] self.VersionDelta = (pkt[5] << 8) + pkt[4] @@ -141,9 +156,12 @@ def sensor_values(self): def __repr__(self): if self.is_sensor_update(): - return str.format("%s(%d) %s" %(self.__class__.__name__, self.VersionDelta, self.sensor_values())) + return "%s(%d) %s" % (self.__class__.__name__, self.VersionDelta, + self.sensor_values()) else: - return str.format("%s length:%d opcode:0x%02x value_handle:0x%04x data:%s" %(self.__class__.__name__, self.Len, self.OpCode, self.ValueHandle, self.Data)) + return "%s length:%d opcode:0x%02x value_handle:0x%04x data:%s" % ( + self.__class__.__name__, self.Len, self.OpCode, + self.ValueHandle, self.Data) class AciEventUpdate(AciEventNew): #OpCode = 0xB4 @@ -164,10 +182,15 @@ class HeartbeatMsg(object): def __init__(self, data): if len(data) != 18: raise ValueError("Error: expected 18 bytes, got %s" % data) - (self.rssi, self.received_at, self.received_at_ms, self.local_clock_version, self.sensor_id, self.epoch_seconds, self.epoch_ms, self.clock_version) = unpack(' 5: - print(str.format("Sensor %d clock offset detected; issuing sync_time." %(hb.sensor_id))) + print("Sensor %d clock offset detected; issuing sync_time." % hb.sensor_id) self.sync_time() def get_sensor_updates(self): @@ -42,7 +42,7 @@ def get_sensor_updates(self): try: evt = self.aci.events_queue.get_nowait() self.last_event = time.time() - print(str.format("evt = %s" %(evt))) + print("evt = %s" % evt) if isinstance(evt, AciEvent.AciEventNew) and evt.is_sensor_update(): updates.append(evt.sensor_values()) elif isinstance(evt, AciEvent.AciEventAppEvt) and evt.is_heartbeat(): @@ -53,7 +53,8 @@ def get_sensor_updates(self): def run_app_command(self, command): data = command.serialize() - retval = self.aci.write_aci_cmd(AciCommand.AciAppCommand(data=data,length=len(data)+1)) + retval = self.aci.write_aci_cmd(AciCommand.AciAppCommand(data=data, + length=len(data)+1)) print("Events received: %s" % retval) return retval @@ -71,7 +72,8 @@ def radio_obs_from_update(self, update): for remote_id, rssi in zip(update.proximity_ids, update.proximity_rssi): ob_time = datetime.datetime.utcfromtimestamp(update.valid_time) if remote_id > 0 and rssi > 0: - obs.append(RadioObservation(self.classroom_id, update.sensor_id, remote_id, ob_time, -rssi)) + obs.append(RadioObservation(self.classroom_id, update.sensor_id, + remote_id, ob_time, -rssi)) return obs def accelerometer_measurement_from_update(self, update): @@ -91,26 +93,33 @@ def restart_serial(self): self.aci = AciUart.AciUart(port=device, baudrate=115200) self.last_event = time.time() - def handle_exceptions_with_sleep_retry(self, callable, sleep_duration, num_retries, description): + def handle_exceptions_with_sleep_retry(self, callable, sleep_duration, + num_retries, description): while (num_retries > 0): try: return callable() except Exception as e: - print(str.format("Exception while %s: %s" %(description, repr(e)))) + print("Exception while %s: %r" % (description, e)) num_retries = num_retries - 1 time.sleep(sleep_duration) def upload_radio_observations(self, obs): - self.handle_exceptions_with_sleep_retry(lambda: self.api.upload_radio_observations(obs), 1, 3, "uploading radio obs") + self.handle_exceptions_with_sleep_retry( + lambda: self.api.upload_radio_observations(obs), + 1, 3, "uploading radio obs") def upload_accelerometer_observations(self, obs): - self.handle_exceptions_with_sleep_retry(lambda: self.api.upload_accelerometer_observations(obs), 1, 3, "uploading accelerometer obs") + self.handle_exceptions_with_sleep_retry( + lambda: self.api.upload_accelerometer_observations(obs), + 1, 3, "uploading accelerometer obs") def upload_accelerometer_event(self, event_type, sensor_id, valid_time): ob_time = datetime.datetime.utcfromtimestamp(valid_time) events = [AccelerometerEvent(self.classroom_id, sensor_id, ob_time, event_type)] - self.handle_exceptions_with_sleep_retry(lambda: self.api.upload_accelerometer_events(events), 1, 3, "uploading accelerometer obs") + self.handle_exceptions_with_sleep_retry( + lambda: self.api.upload_accelerometer_events(events), + 1, 3, "uploading accelerometer obs") def handle_updates_from_serial(self, updates): if not self.options.dry_run: @@ -124,7 +133,8 @@ def handle_updates_from_serial(self, updates): if ob: accelerometer_obs.append(ob) if update.status & SensorValues.STATUS_JOSTLE_FLAG: - self.upload_accelerometer_event('jostle', update.sensor_id, update.valid_time) + self.upload_accelerometer_event('jostle', update.sensor_id, + update.valid_time) print("Jostle from %d" %(update.sensor_id)) if len(accelerometer_obs) > 0: self.upload_accelerometer_observations(accelerometer_obs) @@ -155,11 +165,13 @@ def run(self): if __name__ == '__main__': parser = ArgumentParser() - parser.add_argument("-c", "--config", dest="config", help="Configuration file, e.g. ~/.sensei.yaml") - parser.add_argument("-d", "--dry-run", dest="dry_run", help="Dry run. Do not actually upload anything") + parser.add_argument("-c", "--config", dest="config", + help="Configuration file, e.g. ~/.sensei.yaml") + parser.add_argument("-d", "--dry-run", dest="dry_run", + help="Dry run. Do not actually upload anything") options = parser.parse_args() - config_path = options.config or expanduser("~") + "/.sensei.yaml" + config_path = options.config or os.path.join(os.path.expanduser("~"), ".sensei.yaml") if os.path.isfile(config_path): with open(config_path, 'r') as stream: try: @@ -169,5 +181,5 @@ def run(self): except yaml.YAMLError as exc: print(exc) else: - print(str.format("Please configure settings in %s" %(config_path))) + print("Please configure settings in %s" % config_path) exit(-1)