Created
April 24, 2017 01:08
-
-
Save juliusspencer/38469e524bfeb8b4c371d580b4caec1a to your computer and use it in GitHub Desktop.
Modified Weatherstation Codelab Activity to handle CPU temperature
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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