Android Environmental sensors…

くそ…。

Environmental sensors:

These sensors measure various environmental parameters, such as ambient air temperature and pressure, illumination, and humidity. This category includes barometers, photometers, and thermometers.

関係してるのが TYPE_RELATIVE_HUMIDITYTYPE_AMBIENT_TEMPERATURETYPE_PRESSURETYPE_LIGHT

やってみる:

android.txt
1 title=Android Environmental Sensors Demo
2 author=hhsprings
3 orientation=all
environmental_sensors.py
 1 # -*- coding: utf-8 -*-
 2 from copy import deepcopy
 3 from jnius import PythonJavaClass, java_method, autoclass, cast
 4 from plyer.platforms.android import activity
 5 from kivy.logger import Logger
 6 
 7 Context = autoclass('android.content.Context')
 8 Sensor = autoclass('android.hardware.Sensor')
 9 SensorManager = autoclass('android.hardware.SensorManager')
10 
11 _SENSORS_TYPE_NAMES = {
12     Sensor.TYPE_RELATIVE_HUMIDITY: 'TYPE_RELATIVE_HUMIDITY',
13     Sensor.TYPE_AMBIENT_TEMPERATURE: 'TYPE_AMBIENT_TEMPERATURE',
14     Sensor.TYPE_PRESSURE: 'TYPE_PRESSURE',
15     Sensor.TYPE_LIGHT: 'TYPE_LIGHT',
16 }
17 
18 
19 class _SensorListener(PythonJavaClass):
20     __javainterfaces__ = ['android/hardware/SensorEventListener']
21 
22     def __init__(self, sensor_manager, sensor_type):
23         super(_SensorListener, self).__init__()
24         self.SensorManager = sensor_manager
25         self.sensor = self.SensorManager.getDefaultSensor(sensor_type)
26         if not self.sensor:
27             Logger.warn("can't detect sensor (type={}) on your device.".format(
28                     _SENSORS_TYPE_NAMES[sensor_type]))
29 
30         self.values = None
31 
32     def enable(self):
33         self.SensorManager.registerListener(self, self.sensor,
34             SensorManager.SENSOR_DELAY_NORMAL)
35 
36     def disable(self):
37         self.SensorManager.unregisterListener(self, self.sensor)
38 
39     @java_method('(Landroid/hardware/SensorEvent;)V')
40     def onSensorChanged(self, event):
41         self.values = deepcopy(event.values)
42 
43     @java_method('(Landroid/hardware/Sensor;I)V')
44     def onAccuracyChanged(self, sensor, accuracy):
45         # Maybe, do something in future?
46         pass
47 
48 
49 class _SingleRawSensor(object):
50     def __init__(self, sensor_type):
51         self._sensor_type = sensor_type
52         self.SensorManager = cast('android.hardware.SensorManager',
53             activity.getSystemService(Context.SENSOR_SERVICE))
54         self._bState = False
55 
56     def enable(self):
57         if not self._bState:
58             self._listener = _SensorListener(
59                 self.SensorManager, self._sensor_type)
60             self._listener.enable()
61             #
62             self._bState = True
63 
64     def disable(self):
65         if self._bState:
66             self._bState = False
67             #
68             self._listener.disable()
69             del self._listener
70 
71     @property
72     def value(self):
73         if self._bState and self._listener.values:
74             return self._listener.values[0]
75 
76     def __del__(self):
77         if self._bState:
78             self._disable()
79         super(self.__class__, self).__del__()
80 
81 
82 # 
83 relativeHumiditySensor = _SingleRawSensor(Sensor.TYPE_RELATIVE_HUMIDITY)
84 ambientTemperatureSensor = _SingleRawSensor(Sensor.TYPE_AMBIENT_TEMPERATURE)
85 pressureSensor = _SingleRawSensor(Sensor.TYPE_PRESSURE)
86 lightSensor = _SingleRawSensor(Sensor.TYPE_LIGHT)
main.py
 1 # -*- coding: utf-8 -*-
 2 from kivy.lang import Builder
 3 from kivy.app import App
 4 from kivy.clock import Clock
 5 from kivy.properties import StringProperty
 6 from environmental_sensors import (
 7     relativeHumiditySensor,
 8     ambientTemperatureSensor,
 9     pressureSensor,
10     lightSensor)
11 
12 kv = '''
13 BoxLayout:
14     RstDocument:
15         id: result
16         text: app.result
17 '''
18 class AndroidEnvironmentalSensorsDemoApp(App):
19     result = StringProperty()
20 
21     def build(self):
22         relativeHumiditySensor.enable()
23         ambientTemperatureSensor.enable()
24         pressureSensor.enable()
25         lightSensor.enable()
26         Clock.schedule_interval(self.do_interval, 1.)
27         return Builder.load_string(kv)
28 
29     def do_interval(self, *args, **kwargs):
30         RH = relativeHumiditySensor.value
31         T = ambientTemperatureSensor.value
32         P = pressureSensor.value
33         L = lightSensor.value
34         self.result = """
35 * RH: {} [%]
36 * T: {} [degree Celsius]
37 * P: {} [hPa]
38 * L: {} [SI lux]
39 
40 """.format(RH, T, P, L)
41         
42 if __name__ == '__main__':
43     AndroidEnvironmentalSensorsDemoApp().run()

うぐ…。

気温と相対湿度が取れると結構色んな計算出来て面白いのだがなぁ…。一応、気温⇒飽和水蒸気圧(hPa)⇒水蒸気分圧 = 飽和水蒸気圧 * 湿度RH[%]⇒露点温度(Dew Point Temperature)、と求めていくことが出来る…のだが、面白いことに Android API の公式説明で露点温度と絶対湿度の簡易計算式が説明されてたりする。うぅこれをやりたかったのだが…。

ただ、TYPE_LIGHT はこれと組み合わせれば面白いかもな、とも思うし、TYPE_PRESSURE で原始的な気圧高度計を今更作って遊べたりもするし…まぁ…。ないもんはない、諦めるしかないし。

つーかスマホを購入するのに、どんなセンサー搭載されてるか、なんてことで選ばんよね…。(さすがにジャイロセンサーの有無みたいに選ぶ基準になりうるのもあるけど。)