--- /dev/null
+<component name="ProjectDictionaryState">
+ <dictionary name="MRSa">
+ <words>
+ <w>oled</w>
+ </words>
+ </dictionary>
+</component>
\ No newline at end of file
import com.theta360.pluginlibrary.values.LedColor
import com.theta360.pluginlibrary.values.LedTarget
import jp.osdn.gokigen.thetathoughtshutter.R.layout
+import jp.osdn.gokigen.thetathoughtshutter.theta.ThetaHardwareControl
class MainActivity : PluginActivity()
{
+ private val thetaHardwareControl = ThetaHardwareControl(this)
+
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
// - 119 : Fn Button (Z1 Only)
//
//
+// http://localhost:8080/
//
--- /dev/null
+import android.graphics.Bitmap
+import com.theta360.pluginlibrary.values.LedColor
+import com.theta360.pluginlibrary.values.LedTarget
+import com.theta360.pluginlibrary.values.TextArea
+
+interface IThetaHardwareControl
+{
+ // LEDを制御する
+ // device : 操作対象LED (LED3 - LED8)
+ // period : -1 : OFF, 0 : ON, それ以外 :点滅 (250 - 2000)
+ // color : 点滅時のみ有効
+ fun controlLED(device: LedTarget, period: Int, color: LedColor = LedColor.BLUE)
+
+ // LEDの明るさを設定する (LED1, LED2, OLED)
+ // device : 操作対象LED
+ // brightness : 明るさ (0 - 100, default: 25)
+ fun brightnessLED(device: LedTarget, brightness : Int = 25)
+
+ // OLEDにビットマップを表示する
+ fun controlOLED(period: Int, bitmap: Bitmap? = null)
+
+ // OLEDに文字を表示する
+ fun controlOLED(textMap: Map<TextArea?, String?>)
+
+ // pluginで OLEDを使用するかどうか設定する
+ fun useOLED(enable : Boolean = true)
+
+}
--- /dev/null
+package jp.osdn.gokigen.thetathoughtshutter.theta
+
+import IThetaHardwareControl
+import android.graphics.Bitmap
+import com.theta360.pluginlibrary.activity.PluginActivity
+import com.theta360.pluginlibrary.values.LedColor
+import com.theta360.pluginlibrary.values.LedTarget
+import com.theta360.pluginlibrary.values.OledDisplay
+import com.theta360.pluginlibrary.values.TextArea
+
+class ThetaHardwareControl(private val activity: PluginActivity) : IThetaHardwareControl
+{
+ override fun controlLED(device: LedTarget, period: Int, color: LedColor)
+ {
+ try {
+ activity.runOnUiThread {
+ try
+ {
+ when (period) {
+ 0 -> activity.notificationLedShow(device)
+ -1 -> activity.notificationLedHide(device)
+ else -> activity.notificationLedBlink(device, color, period)
+ }
+ }
+ catch (e : Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ override fun brightnessLED(device: LedTarget, brightness : Int)
+ {
+ try {
+ activity.runOnUiThread {
+ try
+ {
+ activity.notificationLedBrightnessSet(device, brightness)
+ }
+ catch (e : Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ override fun controlOLED(period: Int, bitmap: Bitmap?)
+ {
+ try {
+ activity.runOnUiThread {
+ try
+ {
+ if (bitmap != null)
+ {
+ when (period)
+ {
+ 0 -> activity.notificationOledImageShow(bitmap)
+ -1 -> activity.notificationOledHide()
+ else -> activity.notificationOledImageBlink(bitmap, period)
+ }
+ }
+ else
+ {
+ activity.notificationOledHide()
+ }
+ }
+ catch (e : Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ override fun controlOLED(textMap: Map<TextArea?, String?>)
+ {
+ try {
+ activity.runOnUiThread {
+ try
+ {
+ if (textMap.isEmpty())
+ {
+ activity.notificationOledHide()
+ }
+ else
+ {
+ activity.notificationOledTextShow(textMap)
+ }
+ }
+ catch (e : Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ override fun useOLED(enable : Boolean)
+ {
+ try {
+ activity.runOnUiThread {
+ try
+ {
+ activity.notificationOledDisplaySet(if (enable) { OledDisplay.DISPLAY_PLUGIN } else { OledDisplay.DISPLAY_BASIC })
+ }
+ catch (e : Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+}
--- /dev/null
+package jp.osdn.gokigen.thetathoughtshutter.theta.operation
+
+interface IOperationCallback
+{
+ fun operationExecuted(result : Int, resultStr : String?)
+}
--- /dev/null
+package jp.osdn.gokigen.thetathoughtshutter.theta.operation
+
+import android.util.Log
+import jp.osdn.gokigen.thetathoughtshutter.utils.SimpleHttpClient
+
+class ThetaBracketingControl(private val executeUrl : String = "http://192.168.1.1")
+{
+ private val httpClient = SimpleHttpClient()
+ private var isCapturing = false
+
+ fun bracketingControl(useOSCv2 : Boolean)
+ {
+ try
+ {
+ if (!(isCapturing))
+ {
+ startCapture()
+ }
+ else
+ {
+ stopCapture()
+ }
+ isCapturing = !isCapturing
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ private fun startCapture(shootingMode : String = "interval")
+ {
+ //Log.v(TAG, "startCapture() ")
+ try
+ {
+ val thread = Thread {
+ try
+ {
+ val shootUrl = "${executeUrl}/osc/commands/execute"
+ val postData = "{\"name\":\"camera.startCapture\",\"parameters\":{\"timeout\":0, \"mode\":\"$shootingMode\"}}"
+ Log.v(TAG, " start Capture : $postData")
+
+ val result: String? = httpClient.httpPostWithHeader(shootUrl, postData, null, "application/json;charset=utf-8", timeoutMs)
+ if ((result != null)&&(result.isNotEmpty()))
+ {
+ Log.v(TAG, " startCapture() : $result")
+ }
+ else
+ {
+ Log.v(TAG, "startCapture() reply is null. $postData $shootUrl")
+ }
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ thread.start()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ private fun stopCapture()
+ {
+ //Log.v(TAG, "stopCapture() ")
+ try
+ {
+ val thread = Thread {
+ try
+ {
+ val shootUrl = "${executeUrl}/osc/commands/execute"
+ val postData = "{\"name\":\"camera.stopCapture\",\"parameters\":{\"timeout\":0}}"
+
+ Log.v(TAG, " stop Capture : $postData")
+
+ val result: String? = httpClient.httpPostWithHeader(shootUrl, postData, null, "application/json;charset=utf-8", timeoutMs)
+ if ((result != null)&&(result.isNotEmpty()))
+ {
+ Log.v(TAG, " stopCapture() : $result")
+ }
+ else
+ {
+ Log.v(TAG, "stopCapture() reply is null. $postData $shootUrl")
+ }
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ thread.start()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ companion object
+ {
+ private val TAG = ThetaBracketingControl::class.java.simpleName
+ private const val timeoutMs = 6000
+ }
+}
--- /dev/null
+package jp.osdn.gokigen.thetathoughtshutter.theta.operation
+
+import android.util.Log
+import jp.osdn.gokigen.thetathoughtshutter.utils.SimpleHttpClient
+
+class ThetaMovieRecordingControl(private val executeUrl : String = "http://192.168.1.1")
+{
+ private val httpClient = SimpleHttpClient()
+ private var isCapturing = false
+
+ fun movieControl()
+ {
+ try
+ {
+ if (!(isCapturing))
+ {
+ startCapture()
+ }
+ else
+ {
+ stopCapture()
+ }
+ isCapturing = !isCapturing
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ private fun startCapture()
+ {
+ Log.v(TAG, "startCapture()")
+ try
+ {
+ val thread = Thread {
+ try
+ {
+ val shootUrl = "${executeUrl}/osc/commands/execute"
+ val postData = "{\"name\":\"camera.startCapture\",\"parameters\":{\"timeout\":0}}"
+
+ Log.v(TAG, " start Capture : $postData")
+ val result: String? = httpClient.httpPostWithHeader(shootUrl, postData, null, "application/json;charset=utf-8", timeoutMs)
+ if ((result != null)&&(result.isNotEmpty()))
+ {
+ Log.v(TAG, " startCapture() : $result")
+ }
+ else
+ {
+ Log.v(TAG, "startCapture() reply is null. $postData (${shootUrl})")
+ }
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ thread.start()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ private fun stopCapture()
+ {
+ Log.v(TAG, "stopCapture()")
+ try
+ {
+ val thread = Thread {
+ try
+ {
+ val shootUrl = "${executeUrl}/osc/commands/execute"
+ val postData = "{\"name\":\"camera.stopCapture\",\"parameters\":{\"timeout\":0}}"
+
+ Log.v(TAG, " stop Capture : $postData")
+
+ val result: String? = httpClient.httpPostWithHeader(shootUrl, postData, null, "application/json;charset=utf-8", timeoutMs)
+ if ((result != null)&&(result.isNotEmpty()))
+ {
+ Log.v(TAG, " stopCapture() : $result")
+ }
+ else
+ {
+ Log.v(TAG, "stopCapture() reply is null. $postData (${shootUrl})")
+ }
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ thread.start()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ companion object
+ {
+ private val TAG = ThetaMovieRecordingControl::class.java.simpleName
+ private const val timeoutMs = 6000
+ }
+}
\ No newline at end of file
--- /dev/null
+package jp.osdn.gokigen.thetathoughtshutter.theta.operation
+
+import android.util.Log
+import jp.osdn.gokigen.thetathoughtshutter.utils.SimpleHttpClient
+
+class ThetaOptionSetControl(private val executeUrl : String = "http://192.168.1.1")
+{
+ private val httpClient = SimpleHttpClient()
+
+ /**
+ *
+ *
+ */
+ fun setOptions(options: String, callBack: IOperationCallback? = null)
+ {
+ //Log.v(TAG, "setOptions() MSG : $options")
+ try
+ {
+ val thread = Thread {
+ try
+ {
+ val setOptionsUrl = "${executeUrl}/osc/commands/execute"
+ val postData = "{\"name\":\"camera.setOptions\",\"parameters\":{\"timeout\":0, \"options\": {$options}}}"
+ val result: String? = httpClient.httpPostWithHeader(setOptionsUrl, postData, null, "application/json;charset=utf-8", timeoutMs)
+ if ((result != null) && (result.isNotEmpty()))
+ {
+ Log.v(TAG, " setOptions() : $result (${setOptionsUrl})")
+ callBack?.operationExecuted(0, result)
+ }
+ else
+ {
+ Log.v(TAG, "setOptions() reply is null or empty. $postData (${setOptionsUrl})")
+ callBack?.operationExecuted(-1, "")
+ }
+ }
+ catch (e: Exception)
+ {
+ Log.v(TAG, "setOptions() Exception : $options")
+ e.printStackTrace()
+ callBack?.operationExecuted(-1, e.localizedMessage)
+ }
+ }
+ thread.start()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ callBack?.operationExecuted(-1, e.localizedMessage)
+ }
+ }
+
+ companion object
+ {
+ private val TAG = ThetaOptionSetControl::class.java.simpleName
+ private const val timeoutMs = 1500
+ }
+}
--- /dev/null
+package jp.osdn.gokigen.thetathoughtshutter.theta.operation
+
+import android.util.Log
+import jp.osdn.gokigen.thetathoughtshutter.utils.SimpleHttpClient
+import org.json.JSONObject
+
+class ThetaSingleShotControl(private val executeUrl : String = "http://192.168.1.1")
+{
+ private val httpClient = SimpleHttpClient()
+
+ /**
+ *
+ *
+ */
+ fun singleShot()
+ {
+ Log.v(TAG, "singleShot()")
+ try
+ {
+ val thread = Thread {
+ try
+ {
+ val shootUrl = "${executeUrl}/osc/commands/execute"
+ val postData = "{\"name\":\"camera.takePicture\",\"parameters\":{\"timeout\":0}}"
+ val result: String? = httpClient.httpPostWithHeader(shootUrl, postData, null, "application/json;charset=utf-8", timeoutMs)
+ if ((result != null)&&(result.isNotEmpty()))
+ {
+ Log.v(TAG, " singleShot() : $result")
+
+ // 画像処理が終わるまで待つ
+ waitChangeStatus()
+ }
+ else
+ {
+ Log.v(TAG, "singleShot() reply is null. $shootUrl")
+ }
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+ thread.start()
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ /**
+ * 撮影状態が変わるまで待つ。
+ * (ただし、タイムアウト時間を超えたらライブビューを再開させる)
+ */
+ private fun waitChangeStatus()
+ {
+ val getStateUrl = "${executeUrl}/osc/state"
+ val maxWaitTimeoutMs = 9000 // 最大待ち時間 (単位: ms)
+ var fingerprint = ""
+ try
+ {
+ val result: String? = httpClient.httpPost(getStateUrl, "", timeoutMs)
+ if ((result != null)&&(result.isNotEmpty()))
+ {
+ val jsonObject = JSONObject(result)
+ fingerprint = jsonObject.getString("fingerprint")
+
+ // 現在の状態(ログを出す)
+ Log.v(TAG, " $getStateUrl $result ($fingerprint)")
+ }
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+
+ try
+ {
+ val firstTime = System.currentTimeMillis()
+ var currentTime = firstTime
+ while (currentTime - firstTime < maxWaitTimeoutMs)
+ {
+ // ... 状態を見て次に進める
+ val result: String? = httpClient.httpPost(getStateUrl, "", timeoutMs)
+ if ((result != null)&&(result.isNotEmpty()))
+ {
+ val jsonObject = JSONObject(result)
+ val currentFingerprint = jsonObject.getString("fingerprint")
+
+ // ログを出してみる
+ // Log.v(TAG, " " + getStateUrl + " ( " + result + " ) " + "(" + fingerprint + " " + current_fingerprint + ")");
+ if (fingerprint != currentFingerprint)
+ {
+ // fingerprintが更新された!
+ break
+ }
+ Log.v(TAG, " ----- NOW PROCESSING ----- : $fingerprint")
+ }
+ waitMs(750)
+ currentTime = System.currentTimeMillis()
+ }
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ /**
+ *
+ *
+ */
+ private fun waitMs(waitMs: Int)
+ {
+ try
+ {
+ Thread.sleep(waitMs.toLong())
+ }
+ catch (e: Exception)
+ {
+ e.printStackTrace()
+ }
+ }
+
+ companion object
+ {
+ private val TAG = ThetaSingleShotControl::class.java.simpleName
+ private const val timeoutMs = 6000
+ }
+}