Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 16 additions & 8 deletions app/src/main/java/com/github/miwu/ui/device/DeviceViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import com.github.miwu.utils.MiotDeviceClient
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.ReceiveChannel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import miwu.android.icon.generated.icon.AndroidIcons
import miwu.android.translate.AndroidTranslateHelper
import miwu.miot.kmp.utils.to
import miwu.miot.model.MiotUser
import miwu.miot.model.att.SpecAtt
import miwu.miot.model.miot.MiotDevice
import miwu.miot.provider.MiotSpecAttrProvider
import miwu.mock.MOCK_PREFIX
import miwu.mock.NormalMockMiotDeviceClient
import miwu.support.manager.MiotDeviceManager
import org.koin.core.component.KoinComponent

Expand All @@ -28,16 +28,23 @@ class DeviceViewModel(
private val specAttrProvider: MiotSpecAttrProvider
) : AndroidViewModel(application), MiotDeviceManager.Callback, KoinComponent {
private val logger = Logger()
private val device = savedStateHandle.get<String>("device")
private val _event = Channel<Event>()
private val isMockDevice: Boolean
val device = savedStateHandle.get<String>("device")
?.to<MiotDevice>()
?.getOrThrow()
?.takeIf { it.specType != null }
?.also { isMockDevice = it.specType!!.startsWith(MOCK_PREFIX) }
?.let {
if (isMockDevice) it.copy(specType = it.specType!!.substring(MOCK_PREFIX.length))
else it
}
?: error("MiotDevice is not found")
private val user = savedStateHandle.get<String>("user")
val user = savedStateHandle.get<String>("user")
?.to<MiotUser>()
?.getOrThrow()
?: error("MiotUser is not found")
private val miotDeviceClient = MiotDeviceClient(user)
private val _event = Channel<Event>()
val miotDeviceClient = if (isMockDevice) null else MiotDeviceClient(user)
val event: ReceiveChannel<Event> = _event
val isFromTile = savedStateHandle.get<Boolean>("isFromTile") ?: false
val manager by lazy {
Expand All @@ -49,7 +56,8 @@ class DeviceViewModel(
AndroidCache(application),
AndroidTranslateHelper,
Dispatchers.Main,
this
this,
::NormalMockMiotDeviceClient
)
}

Expand Down Expand Up @@ -80,6 +88,6 @@ class DeviceViewModel(
}

sealed interface Event {
object DeviceInitiated: Event
object DeviceInitiated : Event
}
}
13 changes: 13 additions & 0 deletions app/src/main/java/com/github/miwu/ui/main/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.github.miwu.ui.main.state.FragmentState.Normal
import com.github.miwu.utils.Logger
import fr.haan.resultat.fold
import kotlinx.coroutines.flow.map
import miwu.mock.MockMiotDevice


class MainViewModel(
Expand All @@ -27,6 +28,18 @@ class MainViewModel(
val home = miotRepository.currentHome
val scenes = home.map { it.getOrNull()?.scenes.orEmpty() }.asLiveData()
val devices = home.map { it.getOrNull()?.devices.orEmpty() }
.map {
it.toMutableList().apply {
add(
MockMiotDevice(
name = "Mock 窗帘",
did = "abcdef123456",
model = "cmjd.curtain.cmx82",
specType = "urn:miot-spec-v2:device:curtain:0000A00C:cmjd-cmx82:1:0000D031"
)
)
}
}
.map { device ->
device.sortedWith(
compareBy(
Expand Down
19 changes: 12 additions & 7 deletions app/src/main/res/layout/activity_device.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<variable
name="activity"
type="com.github.miwu.ui.device.DeviceActivity" />

<variable
name="viewModel"
type="com.github.miwu.ui.device.DeviceViewModel" />
Expand All @@ -27,8 +28,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:orientation="vertical"
tools:ignore="UseCompoundDrawables">
android:orientation="vertical">

<ImageView
android:layout_width="match_parent"
Expand All @@ -43,6 +43,11 @@
android:layout_marginTop="10dp"
android:text="@string/current_not_support" />

<TextView
style="@style/Wear.DescText"
android:text="@{viewModel.device.model}"
tools:text="model:114514:test"/>

</LinearLayout>

<LinearLayout
Expand Down Expand Up @@ -82,11 +87,11 @@
android:visibility="gone" />
</LinearLayout>

<!-- <com.github.miwu.view.AppButton-->
<!-- style="@style/Wear.AppButton"-->
<!-- android:onClick="@{() -> activity.onAddButtonClick()}"-->
<!-- android:text="@string/add_to_tile"-->
<!-- app:isVisible="@{!activity.isFromTile}" />-->
<!-- <com.github.miwu.view.AppButton-->
<!-- style="@style/Wear.AppButton"-->
<!-- android:onClick="@{() -> activity.onAddButtonClick()}"-->
<!-- android:text="@string/add_to_tile"-->
<!-- app:isVisible="@{!activity.isFromTile}" />-->

<com.github.miwu.view.AppButton
style="@style/Wear.AppButton"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ data class Urn(
* ```
*/
fun parseFrom(str: String) = str.split(":").let { parts ->
if (parts.size < 5 || parts[0] != "urn") error("Invalid URN string")
if (parts.size < 5 || parts[0] != "urn") error("Invalid URN string: $str")
val namespace = parts[1]
val type = parts[2]
if (type !in validType) error("Invalid type of urn")
Expand Down
33 changes: 33 additions & 0 deletions miot-api/src/commonMain/kotlin/miwu/miot/model/att/SpecAtt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ data class SpecAtt(
var descriptionTranslation: String = ""
}

/**
* @param valueRange 0: min, 1: max, 2: step
*/
@Serializable
data class Property(
@SerialName("access") val access: List<String>,
Expand All @@ -56,6 +59,36 @@ data class SpecAtt(
@Transient
var descriptionTranslation: String = ""

/**
* bool 布尔值: true/false
* uint8 无符号8位整型
* uint16 无符号16位整型
* uint32 无符号32位整型
* int8 有符号8位整型
* int16 有符号16位整型
* int32 有符号32位整型
* int64 有符号64位整型
* float 浮点数
* string 字符串
*/
fun getDefaultValue(): Any {
valueList?.firstOrNull()?.value?.let { return it }
val rangeMin = valueRange?.firstOrNull()
return when (type) {
"bool" -> false
"string" -> ""
"uint8" -> (rangeMin as? Int) ?: 0
"uint16" -> (rangeMin as? Int) ?: 0
"uint32" -> (rangeMin as? Long) ?: 0L
"int8" -> (rangeMin as? Int) ?: 0
"int16" -> (rangeMin as? Int) ?: 0
"int32" -> (rangeMin as? Int) ?: 0
"int64" -> (rangeMin as? Long) ?: 0L
"float" -> (rangeMin as? Number)?.toFloat() ?: 0f
else -> rangeMin ?: 0
}
}

@Serializable
data class Value(
@SerialName("description") val description: String,
Expand Down
65 changes: 65 additions & 0 deletions miwu-support/src/main/java/miwu/mock/MockMiotDevice.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package miwu.mock

import miwu.miot.model.miot.MiotDevice
import miwu.miot.model.miot.MiotDeviceExtra

const val MOCK_PREFIX = "mock-"

/**
* 构建 MockMiotDevice
*
* Mock 设备时, 填入默认的 specType 即可, 会自动加入 [MOCK_PREFIX]
*
* @param name 设备名称
* @param did 设备 ID
* @param model 设备型号
* @param isOnline 是否在线
* @param mac 设备 MAC 地址
* @param uid 设备归属用户 ID
*/
@Suppress("FunctionName")
fun MockMiotDevice(
name: String,
did: String,
model: String,
specType: String,
isOnline: Boolean = true,
mac: String = "00:00:00:00:00:00",
uid: String = "114514"
): MiotDevice {
return MiotDevice(
bssid = "",
cnt = null,
comFlag = 0,
did = did,
extra = MiotDeviceExtra(
fwVersion = null,
isSetPinCode = null,
isSubGroup = null,
mcuVersion = null,
pinCodeType = null,
platform = null,
showGroupMember = null
),
freqFlag = false,
hideMode = 0,
isOnline = isOnline,
lastOnline = null,
latitude = "",
localIp = null,
longitude = "",
mac = mac,
model = model,
name = name,
orderTime = 0,
parentId = "",
permitLevel = 0,
pid = 0,
rssi = 0,
showMode = 0,
specType = MOCK_PREFIX + specType,
ssid = null,
token = "",
uid = uid.toLong()
)
}
Loading
Loading