OSDN Git Service

Theta制御のコマンドを組み込む。
authorMRSa <mrsa@myad.jp>
Thu, 11 Feb 2021 02:51:17 +0000 (11:51 +0900)
committerMRSa <mrsa@myad.jp>
Thu, 11 Feb 2021 02:51:17 +0000 (11:51 +0900)
.idea/dictionaries/MRSa.xml [new file with mode: 0644]
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/MainActivity.kt
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/IThetaHardwareControl.kt [new file with mode: 0644]
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/ThetaHardwearControl.kt [new file with mode: 0644]
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/IOperationCallback.kt [new file with mode: 0644]
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/ThetaBracketingControl.kt [new file with mode: 0644]
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/ThetaMovieRecordingControl.kt [new file with mode: 0644]
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/ThetaOptionSetControl.kt [new file with mode: 0644]
app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/ThetaSingleShotControl.kt [new file with mode: 0644]

diff --git a/.idea/dictionaries/MRSa.xml b/.idea/dictionaries/MRSa.xml
new file mode 100644 (file)
index 0000000..b9e8d1a
--- /dev/null
@@ -0,0 +1,7 @@
+<component name="ProjectDictionaryState">
+  <dictionary name="MRSa">
+    <words>
+      <w>oled</w>
+    </words>
+  </dictionary>
+</component>
\ No newline at end of file
index 943b028..f9a36f3 100644 (file)
@@ -8,9 +8,12 @@ import com.theta360.pluginlibrary.receiver.KeyReceiver
 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)
@@ -99,4 +102,5 @@ class MainActivity : PluginActivity()
 //    - 119 : Fn Button (Z1 Only)
 //
 //
+//   http://localhost:8080/
 //
diff --git a/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/IThetaHardwareControl.kt b/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/IThetaHardwareControl.kt
new file mode 100644 (file)
index 0000000..9d4c0d7
--- /dev/null
@@ -0,0 +1,28 @@
+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)
+
+}
diff --git a/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/ThetaHardwearControl.kt b/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/ThetaHardwearControl.kt
new file mode 100644 (file)
index 0000000..0c52f1d
--- /dev/null
@@ -0,0 +1,126 @@
+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()
+        }
+    }
+
+}
diff --git a/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/IOperationCallback.kt b/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/IOperationCallback.kt
new file mode 100644 (file)
index 0000000..1aa1746
--- /dev/null
@@ -0,0 +1,6 @@
+package jp.osdn.gokigen.thetathoughtshutter.theta.operation
+
+interface IOperationCallback
+{
+    fun operationExecuted(result : Int, resultStr : String?)
+}
diff --git a/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/ThetaBracketingControl.kt b/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/ThetaBracketingControl.kt
new file mode 100644 (file)
index 0000000..5be81c0
--- /dev/null
@@ -0,0 +1,107 @@
+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
+    }
+}
diff --git a/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/ThetaMovieRecordingControl.kt b/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/ThetaMovieRecordingControl.kt
new file mode 100644 (file)
index 0000000..1f26dfd
--- /dev/null
@@ -0,0 +1,107 @@
+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
diff --git a/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/ThetaOptionSetControl.kt b/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/ThetaOptionSetControl.kt
new file mode 100644 (file)
index 0000000..570079a
--- /dev/null
@@ -0,0 +1,57 @@
+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
+    }
+}
diff --git a/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/ThetaSingleShotControl.kt b/app/src/main/java/jp/osdn/gokigen/thetathoughtshutter/theta/operation/ThetaSingleShotControl.kt
new file mode 100644 (file)
index 0000000..0b65ba7
--- /dev/null
@@ -0,0 +1,130 @@
+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
+    }
+}