Skip to content

Instantly share code, notes, and snippets.

@juliusspencer
Created April 24, 2017 01:08
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save juliusspencer/38469e524bfeb8b4c371d580b4caec1a to your computer and use it in GitHub Desktop.
Save juliusspencer/38469e524bfeb8b4c371d580b4caec1a to your computer and use it in GitHub Desktop.
Modified Weatherstation Codelab Activity to handle CPU temperature
/*
* Copyright 2017, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.androidthings.weatherstation;
import android.app.Activity;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.util.Log;
import com.google.android.things.contrib.driver.apa102.Apa102;
import com.google.android.things.contrib.driver.bmx280.Bmx280SensorDriver;
import com.google.android.things.contrib.driver.ht16k33.AlphanumericDisplay;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.text.DecimalFormat;
import java.util.Arrays;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
public class WeatherStationActivity extends Activity {
private static final String TAG = WeatherStationActivity.class.getSimpleName();
public static final String CPU_FILE_PATH = "/sys/class/thermal/thermal_zone0/temp";
private static final float HEATING_COEFFICIENT = 0.55f;
private static final long UPDATE_CPU_DELAY = 50;
private SensorManager mSensorManager;
// Default LED brightness
private static final int LEDSTRIP_BRIGHTNESS = 1;
private AlphanumericDisplay mDisplay;
private Apa102 mLedstrip;
private Bmx280SensorDriver mEnvironmentalSensorDriver;
private Float mCpuTemperature = 0f;
private Observable<Float> mCpuTemperatureObservable;
private Handler mHandler;
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "Weather Station Started");
// Initialize 7-segment display
try {
mDisplay = new AlphanumericDisplay(BoardDefaults.getI2cBus());
mDisplay.setEnabled(true);
mDisplay.display("0042");
Log.d(TAG, "Initialized I2C Display");
} catch (IOException e) {
throw new RuntimeException("Error initializing display", e);
}
// Initialize LED strip
try {
mLedstrip = new Apa102(BoardDefaults.getSpiBus(), Apa102.Mode.BGR);
mLedstrip.setBrightness(LEDSTRIP_BRIGHTNESS);
int[] colors = new int[7];
Arrays.fill(colors, Color.RED);
mLedstrip.write(colors);
Log.d(TAG, "Initialized SPI LED strip");
} catch (IOException e) {
throw new RuntimeException("Error initializing LED strip", e);
}
// Initialize temperature/pressure sensors
try {
mEnvironmentalSensorDriver = new Bmx280SensorDriver(BoardDefaults.getI2cBus());
// Register the drivers with the framework
mEnvironmentalSensorDriver.registerTemperatureSensor();
mEnvironmentalSensorDriver.registerPressureSensor();
Log.d(TAG, "Initialized I2C BMP280");
} catch (IOException e) {
throw new RuntimeException("Error initializing BMP280", e);
}
mSensorManager = getSystemService(SensorManager.class);
// create observable for CPI temperature
mCpuTemperatureObservable = getCpuTemperatureObservable();
mCpuTemperatureObservable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
mHandler = new Handler();
mHandler.post(mTemperatureRunnable);
}
private Runnable mTemperatureRunnable = new Runnable() {
@Override public void run() {
mCpuTemperatureObservable.subscribe(new Subscriber<Float>() {
@Override public void onCompleted() {
Log.e(WeatherStationActivity.TAG, "Completed.");
}
@Override public void onError(Throwable e) {
Log.e(WeatherStationActivity.TAG, "Error: " + e.getMessage());
}
@Override public void onNext(Float resultCpuTemperature) {
// Log.i(WeatherStationActivity.TAG, "Temp: " + resultCpuTemperature); // for debugging
mCpuTemperature = resultCpuTemperature;
}
});
mHandler.postDelayed(mTemperatureRunnable, UPDATE_CPU_DELAY);
}
};
@Override protected void onStart() {
super.onStart();
// Register for sensor events here
// Register the BMP280 temperature sensor
Sensor temperature = mSensorManager.getDynamicSensorList(Sensor.TYPE_AMBIENT_TEMPERATURE).get(0);
mSensorManager.registerListener(mSensorEventListener, temperature, SensorManager.SENSOR_DELAY_NORMAL);
// Register the BMP280 pressure sensor
Sensor pressure = mSensorManager.getDynamicSensorList(Sensor.TYPE_PRESSURE).get(0);
mSensorManager.registerListener(mSensorEventListener, pressure, SensorManager.SENSOR_DELAY_NORMAL);
}
@Override protected void onStop() {
super.onStop();
// Unregister for sensor events here
mSensorManager.unregisterListener(mSensorEventListener);
}
@Override protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mTemperatureRunnable);
// Close peripheral connections here
if (mDisplay != null) {
try {
mDisplay.clear();
mDisplay.setEnabled(false);
mDisplay.close();
} catch (IOException e) {
Log.e(TAG, "Error closing display", e);
} finally {
mDisplay = null;
}
}
if (mLedstrip != null) {
try {
mLedstrip.write(new int[7]);
mLedstrip.setBrightness(0);
mLedstrip.close();
} catch (IOException e) {
Log.e(TAG, "Error closing LED strip", e);
} finally {
mLedstrip = null;
}
}
if (mEnvironmentalSensorDriver != null) {
try {
mEnvironmentalSensorDriver.close();
} catch (IOException e) {
Log.e(TAG, "Error closing sensors", e);
} finally {
mEnvironmentalSensorDriver = null;
}
}
}
/**
* Update the 7-segment display with the latest temperature value.
*
* @param temperature Latest temperature value.
*/
private void updateTemperatureDisplay(float temperature) {
// Add code to write a value to the segment display
if (mDisplay != null) {
try {
// calculate temperature given proximity to CPU
if(mCpuTemperature > temperature) temperature =
(temperature - HEATING_COEFFICIENT * mCpuTemperature) / (1 - HEATING_COEFFICIENT);
mDisplay.display(new DecimalFormat("##").format(temperature));
} catch (IOException e) {
Log.e(TAG, "Error updating display", e);
}
}
}
/**
* Update LED strip based on the latest pressure value.
*
* @param pressure Latest pressure value.
*/
private void updateBarometerDisplay(float pressure) {
// Add code to send color data to the LED strip
if (mLedstrip != null) {
try {
int[] colors = RainbowUtil.getWeatherStripColors(pressure);
mLedstrip.write(colors);
} catch (IOException e) {
Log.e(TAG, "Error updating ledstrip", e);
}
}
}
// Callback when SensorManager delivers new data.
private SensorEventListener mSensorEventListener = new SensorEventListener() {
@Override public void onSensorChanged(SensorEvent event) {
final float value = event.values[0];
if (event.sensor.getType() == Sensor.TYPE_AMBIENT_TEMPERATURE) {
updateTemperatureDisplay(value);
}
if (event.sensor.getType() == Sensor.TYPE_PRESSURE) {
updateBarometerDisplay(value);
}
}
@Override public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.d(TAG, "accuracy changed: " + accuracy);
}
};
/**
* Creates an observable which reads the CPU temperature from the file system.
*
* @return the observable
*/
@NonNull private Observable<Float> getCpuTemperatureObservable() {
return Observable.create(new Observable.OnSubscribe<Float>() {
@Override public void call(Subscriber<? super Float> subscriber) {
RandomAccessFile reader = null;
try {
reader = new RandomAccessFile(CPU_FILE_PATH, "r");
String rawTemperature = reader.readLine();
float cpuTemperature = Float.parseFloat(rawTemperature) / 1000f;
// Log.i(WeatherStationActivity.TAG, "Parsed temp: " + cpuTemperature); // for debugging
subscriber.onNext(cpuTemperature);
} catch (IOException ex) {
ex.printStackTrace();
subscriber.onError(ex);
} finally {
if(reader != null) try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
subscriber.onError(e);
}
}
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment