Exemple #1
0
    def encode(self, dataframe: DataFrame):
        """Encode telemetry data matching the BEEP-BOB interface.
        
        https://gist.github.com/vkuhlen/51f7968266659f37d076bd66d57cdbbd
        https://github.com/Hiverize/FiPy/blob/master/logger/beep.py
        
        Example::
        
            {
                't': 22.66734,
                'h': 52.41612,
                'p': 1002.334,
                'weight': 10.0,
                't_i_1': 23.1875,
                't_i_2': 23.125,
                't_i_3': 23.125,
                't_i_4': 23.1875
            }

        :param data: 

        """

        # Rename all fields to designated BEEP-BOB fields.
        egress_data = {}
        mapping = self.settings.get('sensor_telemetry_map')
        mapping['key'] = 'key'
        for sensor_field, telemetry_field in mapping.items():
            sensor_field = sensor_field.lower()
            if sensor_field in dataframe.data_in:
                egress_data[telemetry_field] = dataframe.data_in[sensor_field]

        dataframe.data_out = egress_data
Exemple #2
0
    def serialize(self, dataframe: DataFrame):
        """

        :param data: defined in terkin/model.py

        moves & reformats data from dataframe.data_out to dataframe.payload_out

        """

        # Serialize payload.
        if self.format == TelemetryClient.FORMAT_URLENCODED:
            payload = urlencode(dataframe.data_out)

        elif self.format == TelemetryClient.FORMAT_JSON:
            payload = json.dumps(dataframe.data_out)

        elif self.format == TelemetryClient.FORMAT_CAYENNELPP:
            payload = to_cayenne_lpp(dataframe)

        elif self.format == TelemetryClient.FORMAT_CSV:
            raise NotImplementedError(
                'Serialization format "CSV" not implemented yet')

        else:
            raise ValueError('Unknown serialization format "{}"'.format(
                self.format))

        # Apply content encoding.
        if self.content_encoding in (None, self.CONTENT_ENCODING_IDENTITY):
            pass

        elif self.content_encoding == self.CONTENT_ENCODING_BASE64:
            payload = to_base64(payload)

        dataframe.payload_out = payload
Exemple #3
0
    def transmit(self, dataframe: DataFrame, uri=None, serialize=True):
        """
        :param dataframe:
        :param uri:  (Default value = None)
        :param serialize:  (Default value = True)
        """

        # Submit telemetry data using HTTP POST request
        # Serialization: x-www-form-urlencoded

        # Compute target URI.
        if uri:
            real_uri = uri
        else:
            real_uri = self.uri

        suffix = self.uri_suffixes.get(self.transport,
                                       '').format(**self.__dict__)
        real_uri = real_uri + suffix

        # Resolve handler by URI.
        handler = self.get_handler(real_uri)

        # Prepare dataframe for egress.
        dataframe.payload_out = dataframe.data_out
        if serialize:
            self.serialize(dataframe)

        # Submit dataframe to handler.
        return handler.send(dataframe)
Exemple #4
0
    def encode(self, dataframe: DataFrame):
        """

        :param dataframe: defined in terkin/model.py

        move data_in to data_out (why?)

        """
        dataframe.data_out = dataframe.data_in
    def read_sensors(self) -> DataFrame:
        """
        Read measurements from all sensor objects that have been registered in the sensor_manager.
        Reading is done with the read() function of each respective sensor object.
        """

        # Power up sensor peripherals.
        self.sensor_manager.power_on()

        # Collect observations.
        data = {}
        richdata = {}
        readings = []

        # Iterate all registered sensors.
        sensors = self.sensor_manager.sensors
        log.info('Reading %s sensor ports', len(sensors))
        for sensor in sensors:

            # Signal sensor reading to user.
            sensorname = sensor.__class__.__name__
            log.info('Reading sensor port "%s"', sensorname)

            # Read sensor port.
            try:

                # Disable garbage collector to guarantee reasonable
                # realtime behavior before invoking sensor reading.
                with gc_disabled():
                    sensor_outcome = sensor.read()

                # Power off HX711 after reading
                if "HX711Sensor" in sensorname:
                    sensor.power_off()

                # Backward compat.
                if isinstance(sensor_outcome, SensorReading):
                    sensor_reading = sensor_outcome
                else:
                    sensor_reading = SensorReading()
                    sensor_reading.sensor = sensor
                    sensor_reading.data = sensor_outcome

                sensor_data = sensor_reading.data

                # Evaluate sensor outcome.
                if sensor_data is None or sensor_data is AbstractSensor.SENSOR_NOT_INITIALIZED:
                    continue

                # Round values according to sensor settings.
                if sensor.settings.get('decimals') is not None:
                    for key, value in sensor_data.items():
                        sensor_data[key] = round(
                            sensor_data[key], sensor.settings.get('decimals'))

                # Add sensor reading to observations.
                data.update(sensor_data)

                # Record reading for prettified output.
                self.record_reading(sensor, sensor_data, richdata)

                readings.append(sensor_reading)

            except Exception as ex:
                # Because of the ``gc_disabled`` context manager used above,
                # the propagation of exceptions has to be tweaked like that.
                log.exc(ex, 'Reading sensor "%s" failed', sensorname)

            # Feed the watchdog.
            self.device.watchdog.feed()

            # Clean up memory after reading each sensor object.
            #self.device.run_gc()

        # Debugging: Print sensor data before running telemetry.
        prettify_log = self.settings.get('sensors.prettify_log', False)
        if prettify_log:
            from terkin.util import ddformat
            log.info('Sensor data:\n\n%s', ddformat(richdata, indent=11))
        else:
            log.info('Sensor data:  %s', data)

        # Capture all sensor readings.
        result = DataFrame()
        result.readings = readings
        result.data_in = data

        return result