package com.gizwits.reactnativegizwitssdkv5 import com.facebook.react.bridge.Callback import com.facebook.react.bridge.ReactApplicationContext import com.facebook.react.bridge.ReactContextBaseJavaModule import com.facebook.react.bridge.ReactMethod import com.facebook.react.bridge.ReadableMap import com.facebook.react.bridge.WritableMap import com.facebook.react.modules.core.DeviceEventManagerModule import com.gizwits.smart.sdk.GizDevice import com.gizwits.smart.sdk.GizSDKManager import com.gizwits.smart.sdk.bluetooth.bleCapability import com.gizwits.smart.sdk.common.GizConfiguration import com.gizwits.smart.sdk.common.ProvideWiFiCredentialsEvent import com.gizwits.smart.sdk.core.capacity.CapacityTypes import com.gizwits.smart.sdk.core.network.model.GizDeviceLocalTimerParams import com.gizwits.smart.sdk.exception.GizException import com.gizwits.smart.sdk.lan.lanCapability import com.gizwits.smart.sdk.mqtt.mqttCapability import com.gizwits.smart.sdk.mqtt.queryBoundDevices import com.gizwits.smart.sdk.ota.GizOTAFirmwareType import com.gizwits.smart.sdk.ota.OTAProgressData import com.google.gson.Gson import com.google.gson.JsonArray import com.google.gson.JsonObject import com.google.gson.annotations.SerializedName import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.json.JSONObject data class GizBindParams( @SerializedName("id") override val id: String, @SerializedName("alias") val alias: String, @SerializedName("remark") val remark: String, ) : DeviceParams data class UpdateDeviceInfoParams( @SerializedName("id") override val id: String, @SerializedName("alias") val alias: String, @SerializedName("remark") val remark: String, ) : DeviceParams data class GizGetDPParams( @SerializedName("id") override val id: String, @SerializedName("type") val type: CapacityTypes, @SerializedName("attrs") val attrs: JsonArray?, ) : DeviceParams data class GizSendDPParams( @SerializedName("id") override val id: String, @SerializedName("type") val type: CapacityTypes, @SerializedName("data") val data: String, ) : DeviceParams data class GizUnBindParams( @SerializedName("id") override val id: String, ): DeviceParams data class GizConnectParams( @SerializedName("id") override val id: String, @SerializedName("type") val type: CapacityTypes ): DeviceParams data class GizDisConnectParams( @SerializedName("id") override val id: String, @SerializedName("type") val type: CapacityTypes ): DeviceParams data class GizRegisterDeviceParams( @SerializedName("id") override val id: String, ): DeviceParams data class GizProvideWiFiCredentialsParams( @SerializedName("id") override val id: String, @SerializedName("type") val type: CapacityTypes, @SerializedName("ssid") val ssid: String, @SerializedName("password") val password: String, @SerializedName("timeout") val timeout: Long, ): DeviceParams data class GizStopProvideWiFiCredentialsParams( @SerializedName("id") override val id: String, @SerializedName("type") val type: CapacityTypes, ): DeviceParams data class GizGetDeviceInfoParams( @SerializedName("id") override val id: String, @SerializedName("type") val type: CapacityTypes ): DeviceParams data class GizCheckUpdateParams( @SerializedName("id") override val id: String, @SerializedName("type") val type: CapacityTypes, @SerializedName("firmwareType") val firmwareType: GizOTAFirmwareType ): DeviceParams data class StopUpgradeParams( @SerializedName("id") override val id: String, @SerializedName("type") val type: CapacityTypes, ): DeviceParams data class QueryTimerParams( @SerializedName("id") override val id: String, @SerializedName("type") val type: CapacityTypes, ): DeviceParams data class DeleteTimerParams( @SerializedName("id") override val id: String, @SerializedName("type") val type: CapacityTypes, @SerializedName("timerId") val timerId: Int, ): DeviceParams data class CreateTimerParams( @SerializedName("id") override val id: String, @SerializedName("type") val type: CapacityTypes, @SerializedName("data") val data: GizDeviceLocalTimerParams, ): DeviceParams class RNGizDeviceManagerModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { enum class EventName(val value: String) { GizOTAProgressEvent("GizOTAProgressEvent"), GizProvideWiFiCredentialsEvent("GizProvideWiFiCredentialsEvent"), } fun jsonObjectToPairs(jsonObject: JsonObject): Array> { val pairs = mutableListOf>() for ((key, value) in jsonObject.entrySet()) { val pair = key to value pairs.add(pair) } return pairs.toTypedArray() } override fun getName() = "RNGizDeviceManagerModule" @ReactMethod fun sendDp(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, GizSendDPParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { try { val gson = Gson() val jsonObject = gson.fromJson(config.data, JsonObject::class.java) val attrs = jsonObjectToPairs(jsonObject) val res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.sendDp(*attrs) CapacityTypes.LAN -> device.lanCapability.sendDp(*attrs) CapacityTypes.MQTT -> device.mqttCapability.sendDp(*attrs) } GizRNCallbackManager.callbackWithResult(callback = result, result = res) }catch (e: Exception) { GizRNCallbackManager.callbackWithResult(callback = result, result = Result.failure(e)) } } } } @ReactMethod fun getDp(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, GizGetDPParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { var res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.getDp(config.attrs) CapacityTypes.LAN -> device.lanCapability.getDp(config.attrs) CapacityTypes.MQTT -> device.mqttCapability.getDp(config.attrs) } if (res.isSuccess) { var jsonObject = res.getOrNull() ?: JSONObject() val newRes = JSONObject() newRes.put("success", true) newRes.put("data", JSONObject(jsonObject.toString())) result.invoke(null, GizRNCallbackManager.jsonObject2WriteableMap(newRes)) } else { GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } } @ReactMethod fun getDeviceInfo(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, GizGetDeviceInfoParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.getDeviceInfo() CapacityTypes.LAN -> device.lanCapability.getDeviceInfo() CapacityTypes.MQTT -> device.mqttCapability.getDeviceInfo() } GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } @ReactMethod fun updateDeviceInfo(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, UpdateDeviceInfoParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = device.updateDeviceInfo(config.alias, config.remark) GizRNCallbackManager.callbackWithResult(callback = result, result = res) // if (res.isSuccess) { // GizSDKManager.queryBoundDevices() // } } } } @ReactMethod fun bind(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, GizBindParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = device.bind(config.alias, config.remark) GizRNCallbackManager.callbackWithResult(callback = result, result = res) // if (res.isSuccess) { // GizSDKManager.queryBoundDevices() // } } } } @ReactMethod fun unBind(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, GizUnBindParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = device.unBind() GizRNCallbackManager.callbackWithResult(callback = result, result = res) if (res.isSuccess) { GizSDKManager.queryBoundDevices() } } } } @ReactMethod fun stopProvideWiFiCredentials(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, GizStopProvideWiFiCredentialsParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.stopProvideWiFiCredentials() CapacityTypes.LAN -> device.lanCapability.stopProvideWiFiCredentials() CapacityTypes.MQTT -> device.mqttCapability.stopProvideWiFiCredentials() } GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } fun wiFiCredentialsEventHandler(device: GizDevice, event: ProvideWiFiCredentialsEvent) { val jsonObject = JSONObject() val dataObject = JSONObject() when (event) { is ProvideWiFiCredentialsEvent.GIZ_CONNECT_SUCCESS -> { dataObject.put("event", "GIZ_CONNECT_SUCCESS") } is ProvideWiFiCredentialsEvent.GIZ_CONFIG_SEND_SUCCESS -> { dataObject.put("event", "GIZ_CONFIG_SEND_SUCCESS") } is ProvideWiFiCredentialsEvent.GIZ_CONFIG_RECV_SUCCESS -> { dataObject.put("event", "GIZ_CONFIG_RECV_SUCCESS") } is ProvideWiFiCredentialsEvent.GIZ_ROUTER_CONNECT_RESULT -> { dataObject.put("event", "GIZ_ROUTER_CONNECT_RESULT") dataObject.put("code", event.code) dataObject.put("message", event.message) } is ProvideWiFiCredentialsEvent.GIZ_CONFIG_SUCCESS -> { dataObject.put("event", "GIZ_CONFIG_SUCCESS") } } jsonObject.put("data", dataObject) jsonObject.put("device", device.toJsonObject()) sendEvent( EventName.GizProvideWiFiCredentialsEvent.name, GizRNCallbackManager.jsonObject2WriteableMap(jsonObject) ) } @ReactMethod fun provideWiFiCredentials(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, GizProvideWiFiCredentialsParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.provideWiFiCredentials( config.ssid, config.password, config.timeout, processHandler = { wiFiCredentialsEventHandler(device, it) } ) CapacityTypes.LAN -> device.lanCapability.provideWiFiCredentials( config.ssid, config.password, config.timeout, processHandler = { wiFiCredentialsEventHandler(device, it) } ) CapacityTypes.MQTT -> device.mqttCapability.provideWiFiCredentials( config.ssid, config.password, config.timeout, processHandler = { wiFiCredentialsEventHandler(device, it) } ) } GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } @ReactMethod fun register(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, GizRegisterDeviceParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = device.register() GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } @ReactMethod fun connect(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, GizConnectParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.connect() CapacityTypes.LAN -> device.lanCapability.connect() CapacityTypes.MQTT -> device.mqttCapability.connect() } GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } @ReactMethod fun disConnect(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, GizDisConnectParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.disConnect() CapacityTypes.LAN -> device.lanCapability.disConnect() CapacityTypes.MQTT -> device.mqttCapability.disConnect() } GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } @ReactMethod fun checkUpdate(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, GizCheckUpdateParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.checkUpdate(config.firmwareType) CapacityTypes.LAN -> device.lanCapability.checkUpdate(config.firmwareType) CapacityTypes.MQTT -> device.mqttCapability.checkUpdate(config.firmwareType) } GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } fun handleStartUpgradeProgress(event: OTAProgressData, device: GizDevice) { val jsonObject = JSONObject() val dataObject = JSONObject() dataObject.put("percentage", event.percentage) dataObject.put("event", event.event.value) jsonObject.put("data", dataObject) jsonObject.put("device", device.toJsonObject()) sendEvent( EventName.GizOTAProgressEvent.name, GizRNCallbackManager.jsonObject2WriteableMap(jsonObject) ) } @ReactMethod fun startUpgrade(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, GizCheckUpdateParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = when(config.type) { CapacityTypes.BLE -> { device.bleCapability.startUpgrade(config.firmwareType, processHandler = { handleStartUpgradeProgress(it, device) }) } CapacityTypes.LAN -> device.lanCapability.startUpgrade(config.firmwareType, processHandler = { handleStartUpgradeProgress(it, device) }) CapacityTypes.MQTT -> device.mqttCapability.startUpgrade(config.firmwareType, processHandler = { handleStartUpgradeProgress(it, device) }) } GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } @ReactMethod fun cancelUpgrade(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, StopUpgradeParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.cancelUpgrade() CapacityTypes.LAN -> device.lanCapability.cancelUpgrade() CapacityTypes.MQTT -> device.mqttCapability.cancelUpgrade() } GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } @ReactMethod fun queryTimer(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, QueryTimerParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.queryTimer() CapacityTypes.LAN -> device.lanCapability.queryTimer() CapacityTypes.MQTT -> device.mqttCapability.queryTimer() } GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } @ReactMethod fun deleteTimer(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, DeleteTimerParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.deleteTimer(config.timerId) CapacityTypes.LAN -> device.lanCapability.deleteTimer(config.timerId) CapacityTypes.MQTT -> device.mqttCapability.deleteTimer(config.timerId) } GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } @ReactMethod fun createTimer(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, CreateTimerParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.createTimer(config.data) CapacityTypes.LAN -> device.lanCapability.createTimer(config.data) CapacityTypes.MQTT -> device.mqttCapability.createTimer(config.data) } GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } @ReactMethod fun editTimer(options: ReadableMap, result: Callback) { val (config, device) = RNGizParamsChecker.checkDeviceAndParams(options, result, CreateTimerParams::class.java) if (config !=null && device !=null) { CoroutineScope(Dispatchers.IO).launch { val res = when(config.type) { CapacityTypes.BLE -> device.bleCapability.editTimer(config.data) CapacityTypes.LAN -> device.lanCapability.editTimer(config.data) CapacityTypes.MQTT -> device.mqttCapability.editTimer(config.data) } GizRNCallbackManager.callbackWithResult(callback = result, result = res) } } } fun sendEvent(name:String, data: WritableMap?) { reactApplicationContext .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java) .emit(name, data) } }