接入基本设备
This commit is contained in:
parent
2f84f70a5f
commit
7729332f41
BIN
Assets/Resources/Images/Bluetooth_0.png
Normal file
BIN
Assets/Resources/Images/Bluetooth_0.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
104
Assets/Resources/Images/Bluetooth_0.png.meta
Normal file
104
Assets/Resources/Images/Bluetooth_0.png.meta
Normal file
@ -0,0 +1,104 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05133d14d67abd743954cf1d04471e99
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
BIN
Assets/Resources/Images/Bluetooth_2.png
Normal file
BIN
Assets/Resources/Images/Bluetooth_2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
104
Assets/Resources/Images/Bluetooth_2.png.meta
Normal file
104
Assets/Resources/Images/Bluetooth_2.png.meta
Normal file
@ -0,0 +1,104 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4990d472dee7f3b428ae030c3a2b936f
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -100
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: -1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -34,7 +34,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 124, y: -40}
|
||||
m_AnchoredPosition: {x: 60, y: -40}
|
||||
m_SizeDelta: {x: 62, y: 64}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
--- !u!1 &2745425216517653314
|
||||
@ -111,6 +111,43 @@ MonoBehaviour:
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!1 &2777627832895409916
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 2165555432541117810}
|
||||
m_Layer: 5
|
||||
m_Name: AntIcon
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &2165555432541117810
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 2777627832895409916}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 540031521672414432}
|
||||
- {fileID: 4177612200037049886}
|
||||
m_Father: {fileID: 6430829710355291381}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 24.4, y: 1}
|
||||
m_SizeDelta: {x: 44, y: 44}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1 &3159732546393567601
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -140,15 +177,15 @@ RectTransform:
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 540031521672414432}
|
||||
- {fileID: 4177612200037049886}
|
||||
- {fileID: 2165555432541117810}
|
||||
- {fileID: 7669984967702354254}
|
||||
m_Father: {fileID: 2716191576886074694}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 64, y: 64}
|
||||
m_SizeDelta: {x: 118, y: 64}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
--- !u!222 &6268486626046139400
|
||||
CanvasRenderer:
|
||||
@ -705,6 +742,80 @@ CanvasGroup:
|
||||
m_Interactable: 1
|
||||
m_BlocksRaycasts: 1
|
||||
m_IgnoreParentGroups: 0
|
||||
--- !u!1 &5162363420470615978
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 652708983550405284}
|
||||
- component: {fileID: 2795585007386087676}
|
||||
- component: {fileID: 6254887144258792832}
|
||||
m_Layer: 5
|
||||
m_Name: Image
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &652708983550405284
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5162363420470615978}
|
||||
m_LocalRotation: {x: 0.08715578, y: -0, z: -0, w: 0.9961947}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7669984967702354254}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 10, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 44, y: 44}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &2795585007386087676
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5162363420470615978}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &6254887144258792832
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 5162363420470615978}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 21300000, guid: 407dc13d102a8d842bbaa773773df936, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!1 &5440549946619805752
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@ -741,7 +852,7 @@ RectTransform:
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 1}
|
||||
m_AnchorMax: {x: 0.5, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: -90}
|
||||
m_AnchoredPosition: {x: 35.2, y: -90}
|
||||
m_SizeDelta: {x: 134, y: 34}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!222 &3527654833021650121
|
||||
@ -974,11 +1085,11 @@ RectTransform:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 6502171739230510504}
|
||||
m_LocalRotation: {x: 0.08715578, y: 0, z: 0, w: 0.9961947}
|
||||
m_LocalRotation: {x: 0.08715578, y: -0, z: -0, w: 0.9961947}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 6430829710355291381}
|
||||
m_Father: {fileID: 2165555432541117810}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 10, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
@ -1048,11 +1159,11 @@ RectTransform:
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 7066476020851680862}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 6430829710355291381}
|
||||
m_Father: {fileID: 2165555432541117810}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
@ -1175,6 +1286,117 @@ MonoBehaviour:
|
||||
m_VerticalOverflow: 0
|
||||
m_LineSpacing: 1
|
||||
m_Text: Searching...
|
||||
--- !u!1 &8591994605769169618
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 6521823677394231837}
|
||||
- component: {fileID: 743327725710735410}
|
||||
- component: {fileID: 1839312524778472856}
|
||||
m_Layer: 5
|
||||
m_Name: Ble
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &6521823677394231837
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8591994605769169618}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children: []
|
||||
m_Father: {fileID: 7669984967702354254}
|
||||
m_RootOrder: 0
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0, y: 1}
|
||||
m_AnchorMax: {x: 0, y: 1}
|
||||
m_AnchoredPosition: {x: 0, y: 0}
|
||||
m_SizeDelta: {x: 44, y: 44}
|
||||
m_Pivot: {x: 0, y: 1}
|
||||
--- !u!222 &743327725710735410
|
||||
CanvasRenderer:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8591994605769169618}
|
||||
m_CullTransparentMesh: 0
|
||||
--- !u!114 &1839312524778472856
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8591994605769169618}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
|
||||
m_Name:
|
||||
m_EditorClassIdentifier:
|
||||
m_Material: {fileID: 0}
|
||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
m_RaycastTarget: 1
|
||||
m_Maskable: 1
|
||||
m_OnCullStateChanged:
|
||||
m_PersistentCalls:
|
||||
m_Calls: []
|
||||
m_Sprite: {fileID: 21300000, guid: 05133d14d67abd743954cf1d04471e99, type: 3}
|
||||
m_Type: 0
|
||||
m_PreserveAspect: 0
|
||||
m_FillCenter: 1
|
||||
m_FillMethod: 4
|
||||
m_FillAmount: 1
|
||||
m_FillClockwise: 1
|
||||
m_FillOrigin: 0
|
||||
m_UseSpriteMesh: 0
|
||||
m_PixelsPerUnitMultiplier: 1
|
||||
--- !u!1 &8808031170711301744
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 7669984967702354254}
|
||||
m_Layer: 5
|
||||
m_Name: BleIcon
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!224 &7669984967702354254
|
||||
RectTransform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 8808031170711301744}
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_Children:
|
||||
- {fileID: 6521823677394231837}
|
||||
- {fileID: 652708983550405284}
|
||||
m_Father: {fileID: 6430829710355291381}
|
||||
m_RootOrder: 1
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||
m_AnchoredPosition: {x: -28.5, y: 1.4}
|
||||
m_SizeDelta: {x: 44, y: 44}
|
||||
m_Pivot: {x: 0.5, y: 0.5}
|
||||
--- !u!1001 &564608893206712879
|
||||
PrefabInstance:
|
||||
m_ObjectHideFlags: 0
|
||||
|
||||
@ -141,6 +141,7 @@ namespace Assets.Scripts.Apis
|
||||
|
||||
public async Task<JsonResult<object>> GetEarthData(double lat, double lon)
|
||||
{
|
||||
//CultureInfo.InvariantCulture
|
||||
var result = await GetAsync<JsonResult<object>>($"Map/GetEarthData?lat={ lat }&lon={ lon }");
|
||||
|
||||
return result;
|
||||
|
||||
@ -26,6 +26,20 @@ namespace Assets.Scripts.Devices
|
||||
get; protected set;
|
||||
}
|
||||
|
||||
public NetworkType Network { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// 信号强度
|
||||
/// 信号从0dbm~97dbm,个人建议是0~30是强,30~70是中,70~97是弱。
|
||||
/// </summary>
|
||||
public int SignalStrength { get; internal set; }
|
||||
|
||||
protected AbstractDevice(NetworkType networkType)
|
||||
{
|
||||
this.Network = networkType;
|
||||
}
|
||||
|
||||
|
||||
public abstract void Connect();
|
||||
|
||||
public abstract void Disconnect(bool save = true);
|
||||
|
||||
@ -26,7 +26,7 @@ namespace Assets.Scripts.Devices.Ant
|
||||
public readonly byte uid;
|
||||
|
||||
|
||||
public DataSourceBase(racerSportType sportType, bool isHuman)
|
||||
public DataSourceBase(racerSportType sportType, bool isHuman):base(NetworkType.ANT)
|
||||
{
|
||||
this.sportType = sportType;
|
||||
this.isHuman = isHuman;
|
||||
|
||||
@ -9,7 +9,7 @@ using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ant
|
||||
{
|
||||
public class FitDevice : AbstractAntDevice, ISpeedDevice, IPowerDevice, ICadenceDevice, IRequiresRiderWeight
|
||||
public class FitDevice : AbstractAntDevice, ISpeedDevice, IPowerDevice, ICadenceDevice, IRequiresRiderWeight, ITrainerDevice
|
||||
{
|
||||
public const int MAX_NO_EVENT_STOP_COUNT = 12;
|
||||
|
||||
|
||||
19
Assets/Scripts/Devices/Ant/Interfaces/ITrainerDevice.cs
Normal file
19
Assets/Scripts/Devices/Ant/Interfaces/ITrainerDevice.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ant.Interfaces
|
||||
{
|
||||
public interface ITrainerDevice
|
||||
{
|
||||
void SetErgMode(int targetPower);
|
||||
|
||||
void SetResistanceMode(double value);
|
||||
|
||||
void SetWindResistance(double? height = null);
|
||||
|
||||
void SetTrackResistance(double grade);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Devices/Ant/Interfaces/ITrainerDevice.cs.meta
Normal file
11
Assets/Scripts/Devices/Ant/Interfaces/ITrainerDevice.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 362cacfc69d803d478112e7c293cfa17
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -39,4 +39,10 @@ namespace Assets.Scripts.Devices.Ant
|
||||
Trainer,
|
||||
VirtualPower,
|
||||
}
|
||||
|
||||
public enum NetworkType
|
||||
{
|
||||
BLE,
|
||||
ANT
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
using Assets.Scripts.Ble.HeartRate;
|
||||
using Assets.Scripts.Ble.Service;
|
||||
using Assets.Scripts.Devices.Ant;
|
||||
using Assets.Scripts.Devices.Ble.Characteristic;
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -22,17 +24,23 @@ namespace Assets.Scripts.Devices.Ble
|
||||
|
||||
public override string Name { get => peripheralInfo.Name; protected set => base.Name = value; }
|
||||
|
||||
public BleDevice(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface, SensorType sensor) //: base(peripheralInfo)
|
||||
public List<ICharacteristic> Characteristics { get; protected set; } = new List<ICharacteristic>();
|
||||
|
||||
public BleDevice(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface, SensorType sensor) : base(NetworkType.BLE)
|
||||
{
|
||||
this.hwInterface = bleWinHwInterface;
|
||||
this.hwInterface.BluetoothStateChangedEvent += BluetoothStateChangedEvent;
|
||||
this.peripheralInfo = peripheralInfo;
|
||||
|
||||
base.Sensor = sensor;
|
||||
|
||||
|
||||
//base.Name = this.peripheralInfo.Name;
|
||||
|
||||
//Debug.Log(base.Name + "," + sensor.ToString());
|
||||
|
||||
Characteristics.Add(new BatteryLevel());
|
||||
Characteristics.Add(new ManufacturerNameCharacteristic());
|
||||
Characteristics.Add(new ModelNumberCharacteristic());
|
||||
}
|
||||
|
||||
public void ConnectToPeripheralIfPossible()
|
||||
@ -230,7 +238,7 @@ namespace Assets.Scripts.Devices.Ble
|
||||
public override void Disconnect(bool save = true)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
|
||||
this.hwInterface.DisconnectPeripheral(this.peripheralInfo, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,11 +43,19 @@ namespace Assets.Scripts.Devices.Ble
|
||||
{
|
||||
if (!discoveredDevices.ContainsKey(device.Peripheral.Address))
|
||||
{
|
||||
Debug.Log("发现设备" + device.Peripheral.Address + device.Peripheral.Name + ", type:" + device.SensorType);
|
||||
Debug.Log($"发现设备{ device.Peripheral.Address }, \t\tName:{ device.Peripheral.Name }, type:{ device.SensorType }");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(device.Peripheral.Name))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(device.SensorType == Ant.SensorType.Trainer)
|
||||
{
|
||||
//var device1 = new Ftms(device.Peripheral, hwInterface);
|
||||
//discoveredDevices.Add(device.Peripheral.Address, device1);
|
||||
|
||||
var device1 = new Tacx(device.Peripheral, hwInterface);
|
||||
discoveredDevices.Add(device.Peripheral.Address, device1);
|
||||
}
|
||||
else if(device.SensorType == Ant.SensorType.HeartRate)
|
||||
{
|
||||
@ -59,8 +67,18 @@ namespace Assets.Scripts.Devices.Ble
|
||||
var device1 = new CyclingPower(device.Peripheral, hwInterface);
|
||||
discoveredDevices.Add(device.Peripheral.Address, device1);
|
||||
}
|
||||
else if(device.SensorType == Ant.SensorType.SpeedCadence)
|
||||
{
|
||||
var device1 = new SpeedCadence(device.Peripheral, hwInterface);
|
||||
discoveredDevices.Add(device.Peripheral.Address, device1);
|
||||
}
|
||||
//discoveredDevices.Add(device.Peripheral.Address, new BleDevice(device.Peripheral, hwInterface, device.SensorType));
|
||||
}
|
||||
if (discoveredDevices.ContainsKey(device.Peripheral.Address))
|
||||
{
|
||||
discoveredDevices[device.Peripheral.Address].SignalStrength = device.Rssi;
|
||||
//Debug.Log($"设备{ device.Peripheral.Name }信号量:{ device.Rssi }");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
49
Assets/Scripts/Devices/Ble/Characteristic/BatteryLevel.cs
Normal file
49
Assets/Scripts/Devices/Ble/Characteristic/BatteryLevel.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
public class BatteryLevel : ICharacteristic
|
||||
{
|
||||
public Guid Uuid => ServiceUuids.Characteristics.BatteryLevel;
|
||||
|
||||
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.Battery).IdGuid;
|
||||
|
||||
private ICharacteristic _characteristicUnavailable = null;
|
||||
public ICharacteristic CharacteristicUnavailable
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._characteristicUnavailable;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsOptional
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public int BatteryLevelValue { get; private set; }
|
||||
|
||||
public void HandleAttributeReceived(byte[] data)
|
||||
{
|
||||
BatteryLevelValue = (int)data[0];
|
||||
|
||||
Debug.Log($"电量:{ BatteryLevelValue }");
|
||||
}
|
||||
|
||||
public void SetUnavailable()
|
||||
{
|
||||
this._characteristicUnavailable = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b654b3a52c37e6f47b9823953c8fd5d1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,57 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
public class CyclingPowerMeasurement: ICharacteristic
|
||||
{
|
||||
public Guid Uuid
|
||||
{
|
||||
get
|
||||
{
|
||||
return ServiceUuids.Characteristics.CyclingPowerMeasurement;
|
||||
}
|
||||
}
|
||||
|
||||
public Guid ServiceUuid
|
||||
{
|
||||
get
|
||||
{
|
||||
return ServiceUuids.Get(ServiceUuids.CyclingPower).IdGuid;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool IsOptional
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private double wheelCircumference;
|
||||
|
||||
public int Power { get; private set; }
|
||||
|
||||
public CyclingPowerMeasurement(double wheelCircumference)
|
||||
{
|
||||
this.wheelCircumference = wheelCircumference;
|
||||
}
|
||||
|
||||
public void HandleAttributeReceived(byte[] data)
|
||||
{
|
||||
|
||||
this.Power = BitConverter.ToInt16(data, 2);
|
||||
}
|
||||
|
||||
public void SetUnavailable()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b0646295dbaa0a4e951de9bd391e475
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,271 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using Assets.Scripts.Devices.Ble.Extension;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
public class CyclingSpeedCadenceMeasurement : ICharacteristic
|
||||
{
|
||||
private CyclingSpeedCadenceMeasurement.IUpdate _currentUpdate;
|
||||
private CyclingSpeedCadenceMeasurement.IUpdate _previousUpdate = new CyclingSpeedCadenceMeasurement.NullUpdate();
|
||||
private const byte MaxNoEvents = (byte)4;
|
||||
private byte _noCadenceEventCount;
|
||||
private byte _noSpeedEventCount;
|
||||
|
||||
|
||||
public Guid Uuid => ServiceUuids.Characteristics.CscMeasurement;
|
||||
|
||||
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.CyclingSpeedCadence).IdGuid;
|
||||
|
||||
public bool IsOptional => false;
|
||||
|
||||
public double Speed { get; private set; }
|
||||
public int Cadence { get; private set; }
|
||||
|
||||
public double WheelCircumference { private get; set; }
|
||||
|
||||
public CyclingSpeedCadenceMeasurement(double wheelCircumference)
|
||||
{
|
||||
this.WheelCircumference = wheelCircumference;
|
||||
}
|
||||
|
||||
public void HandleAttributeReceived(byte[] data)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
//Debug.Log(string.Join(",", data));
|
||||
|
||||
this._currentUpdate = new CyclingSpeedCadenceMeasurement.Update(data);
|
||||
this.HandleCadenceUpdate();
|
||||
this.HandleSpeedUpdate();
|
||||
this._previousUpdate = this._currentUpdate;
|
||||
}
|
||||
|
||||
private void HandleCadenceUpdate()
|
||||
{
|
||||
if (this._currentUpdate.HasCadence && (int)this._currentUpdate.CadenceEventCount != (int)this._previousUpdate.CadenceEventCount)
|
||||
{
|
||||
this._noCadenceEventCount = (byte)0;
|
||||
if (this.CadenceTimeDifference() <= 0)
|
||||
return;
|
||||
this.Cadence = this.CalculateCadence();
|
||||
}
|
||||
else
|
||||
{
|
||||
this._noCadenceEventCount = (byte)((uint)this._noCadenceEventCount + 1U);
|
||||
if ((int)this._noCadenceEventCount < 4)
|
||||
return;
|
||||
this.Cadence = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleSpeedUpdate()
|
||||
{
|
||||
if (this._currentUpdate.HasSpeed && (int)this._currentUpdate.SpeedEventCount != (int)this._previousUpdate.SpeedEventCount)
|
||||
{
|
||||
this._noSpeedEventCount = (byte)0;
|
||||
double num = this.CalculateSpeed();
|
||||
if (num >= 150.0)
|
||||
return;
|
||||
this.Speed = num;
|
||||
}
|
||||
else
|
||||
{
|
||||
this._noSpeedEventCount = (byte)((uint)this._noSpeedEventCount + 1U);
|
||||
if ((int)this._noSpeedEventCount < 4)
|
||||
return;
|
||||
this.Speed = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
private int CalculateCadence()
|
||||
{
|
||||
int num = this.CadenceEventDifference() * 61440 / this.CadenceTimeDifference();
|
||||
if (num > (int)byte.MaxValue)
|
||||
return (int)byte.MaxValue;
|
||||
if (num < 0)
|
||||
return 0;
|
||||
return num;
|
||||
}
|
||||
|
||||
private int CadenceTimeDifference()
|
||||
{
|
||||
if ((int)this._currentUpdate.CadenceTime1024 > (int)this._previousUpdate.CadenceTime1024)
|
||||
return (int)this._currentUpdate.CadenceTime1024 - (int)this._previousUpdate.CadenceTime1024;
|
||||
return (int)ushort.MaxValue - (int)this._previousUpdate.CadenceTime1024 + (int)this._currentUpdate.CadenceTime1024 + 1;
|
||||
}
|
||||
|
||||
private int CadenceEventDifference()
|
||||
{
|
||||
if ((int)this._currentUpdate.CadenceEventCount > (int)this._previousUpdate.CadenceEventCount)
|
||||
return (int)this._currentUpdate.CadenceEventCount - (int)this._previousUpdate.CadenceEventCount;
|
||||
return (int)ushort.MaxValue - (int)this._previousUpdate.CadenceEventCount + (int)this._currentUpdate.CadenceEventCount + 1;
|
||||
}
|
||||
|
||||
private double CalculateSpeed()
|
||||
{
|
||||
double num = (double)(ulong)(this.WheelCircumference / 10.0 * 36864.0 * (double)this.SpeedEventDifference() / (double)this.SpeedTimeDifference()) / 1000.0;
|
||||
if (num >= 0.0)
|
||||
return num;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
private int SpeedTimeDifference()
|
||||
{
|
||||
if ((int)this._currentUpdate.SpeedTime1024 > (int)this._previousUpdate.SpeedTime1024)
|
||||
return (int)this._currentUpdate.SpeedTime1024 - (int)this._previousUpdate.SpeedTime1024;
|
||||
return (int)ushort.MaxValue - (int)this._previousUpdate.SpeedTime1024 + (int)this._currentUpdate.SpeedTime1024 + 1;
|
||||
}
|
||||
|
||||
private uint SpeedEventDifference()
|
||||
{
|
||||
if (this._currentUpdate.SpeedEventCount > this._previousUpdate.SpeedEventCount)
|
||||
return this._currentUpdate.SpeedEventCount - this._previousUpdate.SpeedEventCount;
|
||||
return (uint)(-1 - (int)this._previousUpdate.SpeedEventCount + (int)this._currentUpdate.SpeedEventCount + 1);
|
||||
}
|
||||
|
||||
public void SetUnavailable()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private interface IUpdate
|
||||
{
|
||||
bool HasCadence { get; }
|
||||
|
||||
bool HasSpeed { get; }
|
||||
|
||||
uint SpeedEventCount { get; }
|
||||
|
||||
ushort SpeedTime1024 { get; }
|
||||
|
||||
ushort CadenceEventCount { get; }
|
||||
|
||||
ushort CadenceTime1024 { get; }
|
||||
}
|
||||
|
||||
private class Update : CyclingSpeedCadenceMeasurement.IUpdate
|
||||
{
|
||||
private static readonly byte WheelRevolutionsFlagBit = (byte)0;
|
||||
private static readonly byte CrankRevolutionsFlagBit = (byte)1;
|
||||
private readonly byte[] _data;
|
||||
|
||||
private byte Flags
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._data[0];
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasCadence
|
||||
{
|
||||
get
|
||||
{
|
||||
return PrimitiveExtensions.IsBitSet(this.Flags, (int)CyclingSpeedCadenceMeasurement.Update.CrankRevolutionsFlagBit);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasSpeed
|
||||
{
|
||||
get
|
||||
{
|
||||
return PrimitiveExtensions.IsBitSet(this.Flags, (int)CyclingSpeedCadenceMeasurement.Update.WheelRevolutionsFlagBit);
|
||||
}
|
||||
}
|
||||
|
||||
public uint SpeedEventCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return BitConvertHelper.ToUInt32(this._data, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public ushort SpeedTime1024
|
||||
{
|
||||
get
|
||||
{
|
||||
return BitConvertHelper.ToUInt16(this._data, 5);
|
||||
}
|
||||
}
|
||||
|
||||
public ushort CadenceEventCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return BitConvertHelper.ToUInt16(this._data, this.HasSpeed ? 7 : 1);
|
||||
}
|
||||
}
|
||||
|
||||
public ushort CadenceTime1024
|
||||
{
|
||||
get
|
||||
{
|
||||
return BitConvertHelper.ToUInt16(this._data, this.HasSpeed ? 9 : 3);
|
||||
}
|
||||
}
|
||||
|
||||
public Update(byte[] data)
|
||||
{
|
||||
this._data = data;
|
||||
}
|
||||
}
|
||||
|
||||
private class NullUpdate : CyclingSpeedCadenceMeasurement.IUpdate
|
||||
{
|
||||
public bool HasCadence
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasSpeed
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public uint SpeedEventCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
|
||||
public ushort SpeedTime1024
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ushort)0;
|
||||
}
|
||||
}
|
||||
|
||||
public ushort CadenceEventCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ushort)0;
|
||||
}
|
||||
}
|
||||
|
||||
public ushort CadenceTime1024
|
||||
{
|
||||
get
|
||||
{
|
||||
return (ushort)0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0ea4d73295288ad4a9f561a37246110a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,45 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
public class FtmsFitnessMachineFeature : ICharacteristic
|
||||
{
|
||||
public Guid Uuid => ServiceUuids.Characteristics.FitnessMachineFeature;
|
||||
|
||||
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.Ftms).IdGuid;
|
||||
|
||||
public bool IsOptional => false;
|
||||
|
||||
public bool IsInclinationSupported
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public bool IsInclinationTargetSettingSupported
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public void HandleAttributeReceived(byte[] data)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
if (data.Length != 8)
|
||||
return;
|
||||
this.IsInclinationSupported = ByteExtensions.IsFlagSet(data[0], (byte)8);
|
||||
//this.ResistanceLevelSupported = ByteExtensions.IsFlagSet(data[0], sbyte.MinValue);
|
||||
|
||||
this.IsInclinationTargetSettingSupported = ByteExtensions.IsFlagSet(data[4], 2);
|
||||
}
|
||||
|
||||
public void SetUnavailable()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6095c96152da4c47870708061e1d5ac
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
220
Assets/Scripts/Devices/Ble/Characteristic/FtmsIndoorBikeData.cs
Normal file
220
Assets/Scripts/Devices/Ble/Characteristic/FtmsIndoorBikeData.cs
Normal file
@ -0,0 +1,220 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
public class FtmsIndoorBikeData : ICharacteristic
|
||||
{
|
||||
private readonly ushort? _instantSpeedSubject = new ushort?();
|
||||
private readonly ushort? _averageSpeedSubject = new ushort?();
|
||||
private readonly ushort? _instantCadenceSubject = new ushort?();
|
||||
private readonly ushort? _averageCadenceSubject = (new ushort?());
|
||||
private readonly uint? _totalDistanceSubject = (new uint?());
|
||||
private readonly short? _resistanceLevelSubject = (new short?());
|
||||
private readonly short? _instantPowerSubject = (new short?());
|
||||
private readonly short? _averagePowerSubject = (new short?());
|
||||
private readonly ushort? _totalEnergySubject = (new ushort?());
|
||||
private readonly ushort? _energyPerHourSubject = (new ushort?());
|
||||
private readonly byte? _energyPerMinuteSubject = (new byte?());
|
||||
private readonly byte? _heartRateSubject = (new byte?());
|
||||
private readonly byte? _metabolicEquivalentSubject = (new byte?());
|
||||
private readonly ushort? _elapsedTimeSubject = (new ushort?());
|
||||
private readonly ushort? _remainingTimeSubject = (new ushort?());
|
||||
|
||||
public short? InstantPower
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._instantPowerSubject;
|
||||
}
|
||||
}
|
||||
public ushort? InstantCadence
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._instantCadenceSubject;
|
||||
}
|
||||
}
|
||||
public ushort? InstantSpeed
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._instantSpeedSubject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Guid Uuid => ServiceUuids.Characteristics.IndoorBikeData;
|
||||
|
||||
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.Ftms).IdGuid;
|
||||
|
||||
public bool IsOptional => false;
|
||||
|
||||
public void HandleAttributeReceived(byte[] data)
|
||||
{
|
||||
if(data.Length < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<FtmsIndoorBikeData.IndoorBikeDataField> list = new List<FtmsIndoorBikeData.IndoorBikeDataField>();
|
||||
if (!ByteExtensions.IsFlagSetAtPosition(data[0], (byte)0))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousSpeed);
|
||||
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)1))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.AverageSpeed);
|
||||
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)2))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousCadence);
|
||||
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)3))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.AverageCadence);
|
||||
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)4))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.TotalDistance);
|
||||
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)5))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.ResistanceLevel);
|
||||
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)6))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousPower);
|
||||
if (ByteExtensions.IsFlagSetAtPosition(data[0], (byte)7))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.AveragePower);
|
||||
if (ByteExtensions.IsFlagSetAtPosition(data[1], (byte)0))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.ExpendedEnergy);
|
||||
if (ByteExtensions.IsFlagSetAtPosition(data[1], (byte)1))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.HeartRate);
|
||||
if (ByteExtensions.IsFlagSetAtPosition(data[1], (byte)2))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.MetabolicEquivalent);
|
||||
if (ByteExtensions.IsFlagSetAtPosition(data[1], (byte)3))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.ElapsedTime);
|
||||
if (ByteExtensions.IsFlagSetAtPosition(data[1], (byte)4))
|
||||
list.Add(FtmsIndoorBikeData.IndoorBikeDataField.RemainingTime);
|
||||
int offset = 2;
|
||||
foreach (FtmsIndoorBikeData.IndoorBikeDataField field in list)
|
||||
offset += this.ParseField(data, offset, field);
|
||||
}
|
||||
|
||||
public void SetUnavailable()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private int ParseField(byte[] attribute, int offset, FtmsIndoorBikeData.IndoorBikeDataField field)
|
||||
{
|
||||
int fieldSize = FtmsIndoorBikeData.GetFieldSize(field);
|
||||
if (attribute.Length < fieldSize + offset)
|
||||
throw new ArgumentException("attribute");
|
||||
switch (field)
|
||||
{
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousSpeed:
|
||||
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._instantSpeedSubject);
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.AverageSpeed:
|
||||
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._averageSpeedSubject);
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousCadence:
|
||||
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._instantCadenceSubject);
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.AverageCadence:
|
||||
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._averageCadenceSubject);
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.TotalDistance:
|
||||
ICharacteristicExtensions.HandleUint24AttributeValue((ICharacteristic)this, attribute, offset, this._totalDistanceSubject);
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.ResistanceLevel:
|
||||
ICharacteristicExtensions.HandleShortAttributeValue((ICharacteristic)this, attribute, offset, this._resistanceLevelSubject);
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousPower:
|
||||
ICharacteristicExtensions.HandleShortAttributeValue((ICharacteristic)this, attribute, offset, this._instantPowerSubject);
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.AveragePower:
|
||||
ICharacteristicExtensions.HandleShortAttributeValue((ICharacteristic)this, attribute, offset, this._averagePowerSubject);
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.ExpendedEnergy:
|
||||
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._totalEnergySubject);
|
||||
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset + 2, this._energyPerHourSubject);
|
||||
ICharacteristicExtensions.HandleByteAttributeValue((ICharacteristic)this, attribute, offset + 4, this._energyPerMinuteSubject);
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.HeartRate:
|
||||
ICharacteristicExtensions.HandleByteAttributeValue((ICharacteristic)this, attribute, offset, this._heartRateSubject);
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.MetabolicEquivalent:
|
||||
ICharacteristicExtensions.HandleByteAttributeValue((ICharacteristic)this, attribute, offset, this._metabolicEquivalentSubject);
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.ElapsedTime:
|
||||
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._elapsedTimeSubject);
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.RemainingTime:
|
||||
ICharacteristicExtensions.HandleUshortAttributeValue((ICharacteristic)this, attribute, offset, this._remainingTimeSubject);
|
||||
break;
|
||||
}
|
||||
return fieldSize;
|
||||
}
|
||||
|
||||
private static int GetFieldSize(FtmsIndoorBikeData.IndoorBikeDataField field)
|
||||
{
|
||||
int num = 0;
|
||||
switch (field)
|
||||
{
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousSpeed:
|
||||
num = 2;
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.AverageSpeed:
|
||||
num = 2;
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousCadence:
|
||||
num = 2;
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.AverageCadence:
|
||||
num = 2;
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.TotalDistance:
|
||||
num = 3;
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.ResistanceLevel:
|
||||
num = 2;
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.InstantaneousPower:
|
||||
num = 2;
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.AveragePower:
|
||||
num = 2;
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.ExpendedEnergy:
|
||||
num = 5;
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.HeartRate:
|
||||
num = 1;
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.MetabolicEquivalent:
|
||||
num = 1;
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.ElapsedTime:
|
||||
num = 2;
|
||||
break;
|
||||
case FtmsIndoorBikeData.IndoorBikeDataField.RemainingTime:
|
||||
num = 2;
|
||||
break;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
private enum IndoorBikeDataField
|
||||
{
|
||||
InstantaneousSpeed,
|
||||
AverageSpeed,
|
||||
InstantaneousCadence,
|
||||
AverageCadence,
|
||||
TotalDistance,
|
||||
ResistanceLevel,
|
||||
InstantaneousPower,
|
||||
AveragePower,
|
||||
ExpendedEnergy,
|
||||
HeartRate,
|
||||
MetabolicEquivalent,
|
||||
ElapsedTime,
|
||||
RemainingTime,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e3577d5802131984c9463ba280183935
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,4 +1,5 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -8,7 +9,7 @@ using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
public class HeartRateMeasurement
|
||||
public class HeartRateMeasurement : ICharacteristic
|
||||
{
|
||||
public Guid Uuid
|
||||
{
|
||||
@ -26,6 +27,13 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsOptional
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private HrmFormat Format { get; set; }
|
||||
|
||||
// Token: 0x170005EB RID: 1515
|
||||
@ -39,7 +47,7 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
if (this.Format == HrmFormat.Short)
|
||||
{
|
||||
this.BeatsPerMinute = BitConvertHelper.ToUInt8(data, 1);
|
||||
Debug.Log("心率:" + this.BeatsPerMinute);
|
||||
//Debug.Log("心率:" + this.BeatsPerMinute);
|
||||
return;
|
||||
}
|
||||
if (data.Length < 3)
|
||||
@ -49,6 +57,10 @@ namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
this.BeatsPerMinute = BitConvertHelper.ToUInt16(data, 1);
|
||||
}
|
||||
|
||||
public void SetUnavailable()
|
||||
{
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum HrmFlags
|
||||
{
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
public static class ICharacteristicExtensions
|
||||
{
|
||||
public static void HandleByteAttributeValue(this ICharacteristic characteristic, byte[] attribute, int offset, byte? subject)
|
||||
{
|
||||
if (attribute.Length < 1 + offset)
|
||||
throw new ArgumentException("attribute");
|
||||
byte num = attribute[offset];
|
||||
subject =new byte?(num);
|
||||
}
|
||||
|
||||
public static void HandleShortAttributeValue(this ICharacteristic characteristic, byte[] attribute, int offset, short? subject)
|
||||
{
|
||||
if (attribute.Length < 2 + offset)
|
||||
throw new ArgumentException("attribute");
|
||||
short num = BitConverter.ToInt16(attribute, offset);
|
||||
subject= new short?(num);
|
||||
}
|
||||
|
||||
public static void HandleUshortAttributeValue(this ICharacteristic characteristic, byte[] attribute, int offset, ushort? subject)
|
||||
{
|
||||
if (attribute.Length < 2 + offset)
|
||||
throw new ArgumentException("attribute");
|
||||
ushort num = BitConverter.ToUInt16(attribute, offset);
|
||||
subject =new ushort?(num);
|
||||
}
|
||||
|
||||
public static void HandleUint24AttributeValue(this ICharacteristic characteristic, byte[] attribute, int offset, uint? subject)
|
||||
{
|
||||
if (attribute.Length < 4 + offset - 1)
|
||||
throw new ArgumentException("attribute");
|
||||
byte[] numArray = new byte[4];
|
||||
Buffer.BlockCopy((Array)attribute, offset, (Array)numArray, 0, 3);
|
||||
uint num = BitConverter.ToUInt32(numArray, 0);
|
||||
subject = (new uint?(num));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 238bc68320174c9429b5958b5207b2c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,31 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
public class ManufacturerNameCharacteristic : ICharacteristic
|
||||
{
|
||||
public Guid Uuid => ServiceUuids.Characteristics.ManufactureNameString;
|
||||
|
||||
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.DeviceInformation).IdGuid;
|
||||
|
||||
public bool IsOptional => true;
|
||||
|
||||
public void HandleAttributeReceived(byte[] data)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
Debug.Log(Encoding.UTF8.GetString(data));
|
||||
}
|
||||
|
||||
public void SetUnavailable()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f0a2af64ce8fe84cbdf0e5a14bbc8ae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -0,0 +1,31 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
public class ModelNumberCharacteristic : ICharacteristic
|
||||
{
|
||||
public Guid Uuid => ServiceUuids.Characteristics.ModelNumber;
|
||||
|
||||
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.DeviceInformation).IdGuid;
|
||||
|
||||
public bool IsOptional => true;
|
||||
|
||||
public void HandleAttributeReceived(byte[] data)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
Debug.Log($"model number:\t{ Encoding.UTF8.GetString(data) }");
|
||||
}
|
||||
|
||||
public void SetUnavailable()
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef489f56607ba2540b8954b67e1a4d3e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
205
Assets/Scripts/Devices/Ble/Characteristic/TacxFecNotify.cs
Normal file
205
Assets/Scripts/Devices/Ble/Characteristic/TacxFecNotify.cs
Normal file
@ -0,0 +1,205 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
public class TacxFecNotify : ICharacteristic
|
||||
{
|
||||
public Guid Uuid => ServiceUuids.Characteristics.TacxFecRead;
|
||||
|
||||
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.TacxBle).IdGuid;
|
||||
|
||||
public virtual bool IsOptional
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public double Speed { get; set; }
|
||||
|
||||
private int _Power;
|
||||
public int Power
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Power;
|
||||
}
|
||||
set
|
||||
{
|
||||
_Power = DeviceValueFilter.Power(value);
|
||||
//Debug.Log(_Power);
|
||||
}
|
||||
}
|
||||
|
||||
private int _Cadence;
|
||||
public int Cadence
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Cadence;
|
||||
}
|
||||
set
|
||||
{
|
||||
_Cadence = DeviceValueFilter.Cadence(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleAttributeReceived(byte[] data)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
var responseId = data[2];
|
||||
|
||||
if (responseId != (byte)ANT_Managed_Library.ANT_ReferenceLibrary.ANTMessageID.BROADCAST_DATA_0x4E)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var data1 = data.Skip(3).ToArray();
|
||||
var pageNumber = data1[1];
|
||||
switch (pageNumber)
|
||||
{
|
||||
case 16:
|
||||
{
|
||||
HandleGeneralDataPage(data1.Skip(1).ToArray());
|
||||
}
|
||||
break;
|
||||
case 19:
|
||||
{
|
||||
//lastInstCadence = data1[5];
|
||||
}
|
||||
break;
|
||||
case 21: //bike data
|
||||
case 22: //Row data, same format as bike for cad and power
|
||||
case 20: //Elliptical, same format as bike for cad and power
|
||||
case 24: //Nordic Skier, same format as bike for cad and power
|
||||
{
|
||||
//lastInstCadence = data1[5];
|
||||
//lastInstPower = (ushort)(data1[6] + (data1[7] << 8));
|
||||
//System.Console.Out.WriteLine("Cadence:" + response.messageContents[5] + ",Power:" + (response.messageContents[6] + (response.messageContents[7] << 8)));
|
||||
//System.Console.Out.WriteLine("SPM:"+response.messageContents[5]+"Power:"+(response.messageContents[6] + (response.messageContents[7] << 8)));
|
||||
}
|
||||
break;
|
||||
case 25:
|
||||
|
||||
HandleTrainerDataPage(data1.Skip(1).ToArray());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleGeneralDataPage(byte[] dataPayload)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte equipmentType = dataPayload[1];
|
||||
byte elapsedTime = dataPayload[2];
|
||||
byte distanceTraveled = dataPayload[3];
|
||||
|
||||
//byte heartRate = dataPayload[6];
|
||||
//FecPageHandler.HeartRateDataSource heartRateDataSource = (FecPageHandler.HeartRateDataSource)(dataPayload[7] & 3);
|
||||
//bool traveledEnabled = (dataPayload[7] & 4) == 1;
|
||||
//bool distanceTraveledEnabled = (dataPayload[7] & 8) == 1;
|
||||
//FecPageHandler.FeState feState = (FecPageHandler.FeState)(dataPayload[7] & 128);
|
||||
//bool lapToggle = (dataPayload[7] & 128) == 1;
|
||||
//this._fecGeneralData = new FecGeneralData(equipmentType, elapsedTime, distanceTraveled, (short)num, feState, lapToggle, heartRate, heartRateDataSource, traveledEnabled, distanceTraveledEnabled);
|
||||
bool traveledEnabled = ((int)dataPayload[7] & 4) == 1;
|
||||
bool distanceTraveledEnabled = ((int)dataPayload[7] & 8) == 1;
|
||||
|
||||
int num1 = (int)dataPayload[4] | (int)dataPayload[5] << 8; // Instantaneous speed, m/s
|
||||
Speed = (double)num1 / 1000.0 * 60.0 * 60.0 / 1000.0; //转换成公里/小时
|
||||
//Console.WriteLine(num1 +"-----"+Speed);
|
||||
//fecDevice.UpdateSpeed(new double?(value));
|
||||
//PubCommData.Speed = num2;
|
||||
|
||||
//byte? b2 = (heartRate == 255) ? null : new byte?(heartRate);
|
||||
//int? xl = b2.HasValue ? new int?((int)b2.GetValueOrDefault()) : 0;
|
||||
//Console.WriteLine("最新速度" + Speed);
|
||||
//Console.WriteLine("最新心率" + xl);
|
||||
|
||||
//string str = "";
|
||||
//for (int i = 0; i < response.messageContents.Length; i++)
|
||||
//{
|
||||
// str += "," + response.messageContents[i];
|
||||
//}
|
||||
//PubCommData.sp = "速度:" + str;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleTrainerDataPage(byte[] dataPayload)
|
||||
{
|
||||
//if (response.messageContents.Length < 11) break;
|
||||
//double value = 0;
|
||||
//for (int i = 0; i < response.messageContents.Length; i++)
|
||||
//{
|
||||
// if (i < 8)
|
||||
// {
|
||||
// value += response.messageContents[i];
|
||||
// }
|
||||
//}
|
||||
|
||||
//double value1 = response.messageContents[10] * 256 + response.messageContents[9];
|
||||
|
||||
|
||||
//double power = response.messageContents[7] * 256 + response.messageContents[6];
|
||||
//Console.WriteLine("power:" + power);
|
||||
//PubCommData.power = power;
|
||||
|
||||
try
|
||||
{
|
||||
if (dataPayload[5] > 0)
|
||||
{
|
||||
//Console.WriteLine(dataPayload[5] + "," + dataPayload[6]);//瞬时功率
|
||||
}
|
||||
byte num1 = dataPayload[1];
|
||||
byte num2 = dataPayload[2];
|
||||
int accumulatedPower = (int)dataPayload[3] | (int)dataPayload[4] << 8;
|
||||
int instantaneousPower = (int)dataPayload[5] | ((int)dataPayload[6] & 15) << 8; //Watts
|
||||
bool bikePowerCalibrationRequired = ((int)dataPayload[6] >> 4 & 1) == 1;
|
||||
bool resistanceCalibrationRequired = ((int)dataPayload[6] >> 5 & 1) == 1;
|
||||
bool userConfigurationRequired = ((int)dataPayload[6] >> 6 & 1) == 1;
|
||||
bool speedIsTooLow = ((int)dataPayload[7] & 1) == 1;
|
||||
bool speedIsTooHigh = ((int)dataPayload[7] & 2) == 1;
|
||||
|
||||
//PubCommData.power = instantaneousPower;
|
||||
Power = instantaneousPower;
|
||||
|
||||
//bool bikePowerCalibrationRequired = (response.messageContents[6] >> 4 & 1) == 1;
|
||||
//bool resistanceCalibrationRequired = (response.messageContents[6] >> 5 & 1) == 1;
|
||||
//bool flag = (response.messageContents[6] >> 6 & 1) == 1;
|
||||
//bool speedIsTooLow = (response.messageContents[7] & 1) == 1;
|
||||
//bool speedIsTooHigh = (response.messageContents[7] & 2) == 1;
|
||||
//FecPageHandler.FeState feState = (FecPageHandler.FeState)(dataPayload[7] & 112);
|
||||
//bool lapToggle = (dataPayload[7] & 128) == 1;
|
||||
//this._fecTrainerData = new FecTrainerData((int)eventCount, (int)b, accumulatedPower, num, bikePowerCalibrationRequired, resistanceCalibrationRequired, flag, speedIsTooLow, speedIsTooHigh, feState, lapToggle);
|
||||
//device.UpdatePower(new int?(num));
|
||||
byte? nullable = (int)num2 == (int)byte.MaxValue ? new byte?() : new byte?(num2);
|
||||
int? cadence = nullable.HasValue ? new int?((int)nullable.GetValueOrDefault()) : new int?();
|
||||
this.Cadence = cadence.GetValueOrDefault();
|
||||
|
||||
//Console.WriteLine($"power:{ instantaneousPower },Cadence:{ cadence }, data:{ string.Join(",", dataPayload) }");
|
||||
|
||||
if (!userConfigurationRequired)
|
||||
return;
|
||||
//UpdateUserConfiguration();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public virtual void SetUnavailable()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 640f21041d0bf6347b1e48669c9a8691
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
39
Assets/Scripts/Devices/Ble/Characteristic/TacxFecWrite.cs
Normal file
39
Assets/Scripts/Devices/Ble/Characteristic/TacxFecWrite.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Interfaces;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Characteristic
|
||||
{
|
||||
public class TacxFecWrite : ICharacteristic
|
||||
{
|
||||
public virtual bool IsOptional
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public Guid Uuid => ServiceUuids.Characteristics.TacxFecRead;
|
||||
|
||||
public Guid ServiceUuid => ServiceUuids.Get(ServiceUuids.TacxBle).IdGuid;
|
||||
|
||||
public void HandleAttributeReceived(byte[] data)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void WriteMessageToControlPoint()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void SetUnavailable()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c9564a0124aa5946b25bdd1a97ade2c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,5 +1,6 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ant.Interfaces;
|
||||
using Assets.Scripts.Devices.Ble.Characteristic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -12,12 +13,16 @@ namespace Assets.Scripts.Devices.Ble.Devices
|
||||
public class CyclingPower : BleDevice, IPowerDevice
|
||||
{
|
||||
private List<BleServiceInfo> Services;
|
||||
private CyclingPowerMeasurement cyclingPowerMeasurement;
|
||||
public CyclingPower(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Power)
|
||||
{
|
||||
|
||||
cyclingPowerMeasurement = new CyclingPowerMeasurement(1920);
|
||||
base.Characteristics.Add(cyclingPowerMeasurement);
|
||||
bleWinHwInterface.CharacteristicReadEvent += CharacteristicReadMainCallback;
|
||||
}
|
||||
|
||||
public int Power { get => 999; set => throw new NotImplementedException(); }
|
||||
public int Power { get => cyclingPowerMeasurement.Power; set => throw new NotImplementedException(); }
|
||||
|
||||
protected override void CreateServices(List<BleServiceInfo> discoveredServices)
|
||||
{
|
||||
@ -35,7 +40,7 @@ namespace Assets.Scripts.Devices.Ble.Devices
|
||||
|
||||
this.hwInterface.SubscribeCharacteristic(character, (hw, cha, res) =>
|
||||
{
|
||||
Debug.Log("1111111111111111111111");
|
||||
//Debug.Log("1111111111111111111111");
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -46,7 +51,22 @@ namespace Assets.Scripts.Devices.Ble.Devices
|
||||
|
||||
private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
|
||||
{
|
||||
Debug.Log("main call" + string.Join(",", response.Data));
|
||||
//Debug.Log("power main call" + string.Join(",", response.Data));
|
||||
|
||||
//Debug.Log(characteristic.MatchGuid(cyclingPowerMeasurement.Uuid));
|
||||
//Debug.Log(characteristic.Service.MatchGuid(cyclingPowerMeasurement.ServiceUuid));
|
||||
//if (characteristic.MatchGuid(cyclingPowerMeasurement.Uuid))
|
||||
//{
|
||||
// cyclingPowerMeasurement.HandleAttributeReceived(response.Data);
|
||||
|
||||
//}
|
||||
foreach (var item in base.Characteristics)
|
||||
{
|
||||
if (characteristic.MatchGuid(item.Uuid))
|
||||
{
|
||||
item.HandleAttributeReceived(response.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ant.Interfaces;
|
||||
using Assets.Scripts.Devices.Ble.Characteristic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -8,19 +9,119 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Devices
|
||||
{
|
||||
public class Ftms : BleDevice, IPowerDevice
|
||||
public class Ftms : BleDevice, ISpeedDevice, IPowerDevice, ICadenceDevice, ITrainerDevice
|
||||
{
|
||||
|
||||
public int Power { get => _ftmsIndoorBikeData.InstantPower.GetValueOrDefault(0); set => throw new NotImplementedException(); }
|
||||
public double Speed { get => _ftmsIndoorBikeData.InstantSpeed.GetValueOrDefault(0); set => throw new NotImplementedException(); }
|
||||
public int Cadence { get => _ftmsIndoorBikeData.InstantCadence.GetValueOrDefault(0); set => throw new NotImplementedException(); }
|
||||
|
||||
private FtmsIndoorBikeData _ftmsIndoorBikeData;
|
||||
|
||||
private List<BleServiceInfo> Services;
|
||||
private BleCharacteristicInfo controlPointCharacteristic;
|
||||
|
||||
public Ftms(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) :base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Trainer)
|
||||
{
|
||||
this._ftmsIndoorBikeData = new FtmsIndoorBikeData();
|
||||
base.Characteristics.Add(this._ftmsIndoorBikeData);
|
||||
|
||||
base.Characteristics.Add(new FtmsFitnessMachineFeature());
|
||||
|
||||
bleWinHwInterface.CharacteristicReadEvent += CharacteristicReadMainCallback;
|
||||
|
||||
}
|
||||
|
||||
public int Power { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
|
||||
|
||||
protected override void CreateServices(List<BleServiceInfo> discoveredServices)
|
||||
{
|
||||
this.Services = discoveredServices;
|
||||
|
||||
foreach (var service in this.Services)
|
||||
{
|
||||
hwInterface.DiscoverCharacteristic(service, (hwInterface, service1, response) =>
|
||||
{
|
||||
foreach (var character in response.Data)
|
||||
{
|
||||
if (character.MatchGuid(ServiceUuids.Characteristics.IndoorBikeData))
|
||||
{
|
||||
//Debug.Log("功率功能");
|
||||
|
||||
this.hwInterface.SubscribeCharacteristic(character, (hw, cha, res) =>
|
||||
{
|
||||
//Debug.Log("1111111111111111111111");
|
||||
});
|
||||
}
|
||||
else if (character.MatchGuid(ServiceUuids.Characteristics.FitnessMachineControlPoint))
|
||||
{
|
||||
this.controlPointCharacteristic = character;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
|
||||
{
|
||||
foreach (var item in base.Characteristics)
|
||||
{
|
||||
if (characteristic.MatchGuid(item.Uuid))
|
||||
{
|
||||
//Debug.Log(string.Join(",", response.Data));
|
||||
item.HandleAttributeReceived(response.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetErgMode(int targetPower)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
byte[] bytes = BitConverter.GetBytes(targetPower);
|
||||
this.hwInterface.WriteCharacteristic(this.controlPointCharacteristic, new byte[3] {
|
||||
(byte)5,
|
||||
bytes[0],
|
||||
bytes[1]
|
||||
});
|
||||
}
|
||||
|
||||
public void SetResistanceMode(double value)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
var data = new byte[]
|
||||
{
|
||||
(byte)4,
|
||||
(byte)0.1
|
||||
};
|
||||
}
|
||||
|
||||
public void SetWindResistance(double? height = null)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 轨道阻力
|
||||
/// </summary>
|
||||
/// <param name="grade"></param>
|
||||
public void SetTrackResistance(double grade)
|
||||
{
|
||||
if (this.State != Ant.DeviceState.Connected)
|
||||
return;
|
||||
if (controlPointCharacteristic == null)
|
||||
return;
|
||||
|
||||
short windSpeed = 0;
|
||||
short value2 = (short)(grade);
|
||||
byte rollingResistanceCoefficient = (byte)(0.004 * 10000);
|
||||
byte windResistanceCoefficient = 0;
|
||||
var data = new List<byte>();// { 17, (byte)windSpeed, (byte)value2, rollingResistanceCoefficient, windResistanceCoefficient };
|
||||
data.Add(17);
|
||||
data.AddRange(BitConverter.GetBytes(windSpeed));
|
||||
data.AddRange(BitConverter.GetBytes(value2));
|
||||
data.AddRange(BitConverter.GetBytes(rollingResistanceCoefficient));
|
||||
data.AddRange(BitConverter.GetBytes(windResistanceCoefficient));
|
||||
|
||||
|
||||
this.hwInterface.WriteCharacteristic(this.controlPointCharacteristic, data.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,14 +18,13 @@ namespace Assets.Scripts.Devices.Ble.Devices
|
||||
private HeartRateMeasurement heartRateMeasurement;
|
||||
public HeartRate(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.HeartRate)
|
||||
{
|
||||
Debug.Log("创建心率设备");
|
||||
heartRateMeasurement = new HeartRateMeasurement();
|
||||
|
||||
|
||||
base.Characteristics.Add(heartRateMeasurement);
|
||||
|
||||
bleWinHwInterface.CharacteristicReadEvent += CharacteristicReadMainCallback;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override void CreateServices(List<BleServiceInfo> discoveredServices)
|
||||
{
|
||||
//throw new NotImplementedException();
|
||||
@ -33,18 +32,33 @@ namespace Assets.Scripts.Devices.Ble.Devices
|
||||
|
||||
foreach (var service in this.Services)
|
||||
{
|
||||
//Debug.Log($"11111 "+ service.Id.ToString());
|
||||
hwInterface.DiscoverCharacteristic(service, (hwInterface, service1, response) =>
|
||||
{
|
||||
foreach (var character in response.Data)
|
||||
{
|
||||
if (character.MatchGuid(heartRateMeasurement.Uuid))
|
||||
{
|
||||
Debug.Log("心率功能");
|
||||
|
||||
this.hwInterface.SubscribeCharacteristic(character, (hw, cha, res) =>
|
||||
{
|
||||
Debug.Log("1111111111111111111111");
|
||||
//Debug.Log($"心率计subscribe char:{ }");
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
foreach (var item in Characteristics.Where(c=>c.IsOptional))
|
||||
{
|
||||
//Debug.Log(item.GetType() + "服务可用"+ item.Uuid.ToString() +", service:" + item.ServiceUuid);
|
||||
var ccc = response.Data.FirstOrDefault(r => r.MatchGuid(item.Uuid));
|
||||
if (ccc == null)
|
||||
{
|
||||
item.SetUnavailable();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log(item.GetType() + "服务可用");
|
||||
|
||||
GetBatteryLevel(ccc);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -52,10 +66,26 @@ namespace Assets.Scripts.Devices.Ble.Devices
|
||||
|
||||
}
|
||||
|
||||
public void GetBatteryLevel(BleCharacteristicInfo bbbb)
|
||||
{
|
||||
this.hwInterface.ReadCharacteristic(bbbb, (hwInterface1, characteristic1, response1) => {
|
||||
Debug.Log("read收到消息:" + string.Join(",", response1));
|
||||
});
|
||||
}
|
||||
|
||||
private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
|
||||
{
|
||||
Debug.Log("main call" + string.Join(",", response.Data));
|
||||
heartRateMeasurement.HandleAttributeReceived(response.Data);
|
||||
//Debug.Log("heart rate main call" + string.Join(",", response.Data));
|
||||
|
||||
foreach (var item in base.Characteristics)
|
||||
{
|
||||
if (characteristic.MatchGuid(item.Uuid))
|
||||
{
|
||||
item.HandleAttributeReceived(response.Data);
|
||||
}
|
||||
}
|
||||
|
||||
//heartRateMeasurement.HandleAttributeReceived(response.Data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
103
Assets/Scripts/Devices/Ble/Devices/SpeedCadence.cs
Normal file
103
Assets/Scripts/Devices/Ble/Devices/SpeedCadence.cs
Normal file
@ -0,0 +1,103 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ant.Interfaces;
|
||||
using Assets.Scripts.Devices.Ble.Characteristic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Devices
|
||||
{
|
||||
public class SpeedCadence : BleDevice, ISpeedDevice, ICadenceDevice
|
||||
{
|
||||
private CyclingSpeedCadenceMeasurement _cyclingSpeedCadenceMeasurement;
|
||||
public int Cadence { get => _cyclingSpeedCadenceMeasurement.Cadence; set => throw new NotImplementedException(); }
|
||||
public double Speed { get => _cyclingSpeedCadenceMeasurement.Speed; set => throw new NotImplementedException(); }
|
||||
|
||||
private double _wheelCircumference;
|
||||
private List<BleServiceInfo> Services;
|
||||
public SpeedCadence(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.SpeedCadence)
|
||||
{
|
||||
Debug.Log("创建速度踏频设备");
|
||||
_cyclingSpeedCadenceMeasurement = new CyclingSpeedCadenceMeasurement(this._wheelCircumference);
|
||||
base.Characteristics.Add(_cyclingSpeedCadenceMeasurement);
|
||||
|
||||
bleWinHwInterface.CharacteristicReadEvent += CharacteristicReadMainCallback;
|
||||
}
|
||||
|
||||
public void SetWheelCircumference(double value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void CreateServices(List<BleServiceInfo> discoveredServices)
|
||||
{
|
||||
this.Services = discoveredServices;
|
||||
|
||||
foreach (var service in this.Services)
|
||||
{
|
||||
//Debug.Log($"11111 "+ service.Id.ToString());
|
||||
hwInterface.DiscoverCharacteristic(service, (hwInterface, service1, response) =>
|
||||
{
|
||||
Debug.Log($"设备{ this.Name }的char: { string.Join("\r\n", response.Data.Select(d=>d.Id)) }");
|
||||
foreach (var character in response.Data)
|
||||
{
|
||||
if (character.MatchGuid(_cyclingSpeedCadenceMeasurement.Uuid))
|
||||
{
|
||||
this.hwInterface.SubscribeCharacteristic(character, (hw, cha, res) =>
|
||||
{
|
||||
//Debug.Log("1111111111111111111111");
|
||||
});
|
||||
continue;
|
||||
}
|
||||
}
|
||||
foreach (var item in Characteristics.Where(c => c.IsOptional))
|
||||
{
|
||||
//Debug.Log(item.GetType() + "服务可用"+ item.Uuid.ToString() +", service:" + item.ServiceUuid);
|
||||
var ccc = response.Data.FirstOrDefault(r => r.MatchGuid(item.Uuid));
|
||||
if (ccc == null)
|
||||
{
|
||||
item.SetUnavailable();
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log(item.GetType() + "服务可用");
|
||||
|
||||
GetBatteryLevel(ccc);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void GetBatteryLevel(BleCharacteristicInfo bbbb)
|
||||
{
|
||||
this.hwInterface.ReadCharacteristic(bbbb, (hwInterface1, characteristic1, response1) => {
|
||||
Debug.Log("read收到消息:" + string.Join(",", response1));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
|
||||
{
|
||||
//Debug.Log("power main call" + string.Join(",", response.Data));
|
||||
|
||||
//Debug.Log(characteristic.MatchGuid(cyclingPowerMeasurement.Uuid));
|
||||
//Debug.Log(characteristic.Service.MatchGuid(cyclingPowerMeasurement.ServiceUuid));
|
||||
//if (characteristic.MatchGuid(cyclingPowerMeasurement.Uuid))
|
||||
//{
|
||||
// cyclingPowerMeasurement.HandleAttributeReceived(response.Data);
|
||||
|
||||
//}
|
||||
foreach (var item in base.Characteristics)
|
||||
{
|
||||
if (characteristic.MatchGuid(item.Uuid))
|
||||
{
|
||||
item.HandleAttributeReceived(response.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Devices/Ble/Devices/SpeedCadence.cs.meta
Normal file
11
Assets/Scripts/Devices/Ble/Devices/SpeedCadence.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3fc83bb07e841d04bb491332cdfeb669
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
262
Assets/Scripts/Devices/Ble/Devices/Tacx.cs
Normal file
262
Assets/Scripts/Devices/Ble/Devices/Tacx.cs
Normal file
@ -0,0 +1,262 @@
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Devices.Ant;
|
||||
using Assets.Scripts.Devices.Ant.Interfaces;
|
||||
using Assets.Scripts.Devices.Ble.Characteristic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Devices
|
||||
{
|
||||
public class Tacx : BleDevice, IPowerDevice, ICadenceDevice, ISpeedDevice, ITrainerDevice
|
||||
{
|
||||
public int Power { get => tacxFecNotify.Power; set => throw new NotImplementedException(); }
|
||||
public int Cadence { get => tacxFecNotify.Cadence; set => throw new NotImplementedException(); }
|
||||
public double Speed { get => tacxFecNotify.Speed; set => throw new NotImplementedException(); }
|
||||
|
||||
private List<BleServiceInfo> Services;
|
||||
|
||||
private TacxFecNotify tacxFecNotify;
|
||||
private BleCharacteristicInfo tacxFecWriteCharacteristic;
|
||||
|
||||
private TacxFecWrite tacxFecWrite;
|
||||
|
||||
/// <summary>
|
||||
/// 当前坡度,当切换到其他模式的时候,需要把坡度设置为0
|
||||
/// </summary>
|
||||
private double _grade = 0;
|
||||
|
||||
public Tacx(BlePeripheralInfo peripheralInfo, BleWinHwInterface bleWinHwInterface) : base(peripheralInfo, bleWinHwInterface, Ant.SensorType.Trainer)
|
||||
{
|
||||
tacxFecNotify = new TacxFecNotify();
|
||||
base.Characteristics.Add(tacxFecNotify);
|
||||
|
||||
tacxFecWrite = new TacxFecWrite();
|
||||
base.Characteristics.Add(tacxFecWrite);
|
||||
|
||||
bleWinHwInterface.CharacteristicReadEvent += CharacteristicReadMainCallback;
|
||||
|
||||
//bleWinHwInterface.WriteCharacteristic()
|
||||
}
|
||||
|
||||
protected override void CreateServices(List<BleServiceInfo> discoveredServices)
|
||||
{
|
||||
this.Services = discoveredServices;
|
||||
|
||||
foreach (var service in this.Services)
|
||||
{
|
||||
hwInterface.DiscoverCharacteristic(service, (hwInterface, service1, response) =>
|
||||
{
|
||||
foreach (var character in response.Data)
|
||||
{
|
||||
if (character.MatchGuid(ServiceUuids.Characteristics.TacxFecRead))
|
||||
{
|
||||
//Debug.Log("功率功能");
|
||||
|
||||
this.hwInterface.SubscribeCharacteristic(character, (hw, cha, res) =>
|
||||
{
|
||||
//Debug.Log("1111111111111111111111");
|
||||
});
|
||||
}
|
||||
else if (character.MatchGuid(ServiceUuids.Characteristics.TacxFecWrite))
|
||||
{
|
||||
this.tacxFecWriteCharacteristic = character;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void CharacteristicReadMainCallback(BleWinHwInterface hwInterface, BleCharacteristicInfo characteristic, BleResponse<byte[]> response)
|
||||
{
|
||||
foreach (var item in base.Characteristics)
|
||||
{
|
||||
if (characteristic.MatchGuid(item.Uuid))
|
||||
{
|
||||
//Debug.Log(string.Join(",", response.Data));
|
||||
item.HandleAttributeReceived(response.Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetErgMode(int targetPower)
|
||||
{
|
||||
Debug.Log("目标功率1");
|
||||
if (this.State != Ant.DeviceState.Connected)
|
||||
return;
|
||||
if (tacxFecWriteCharacteristic == null)
|
||||
return;
|
||||
Debug.Log($"目标功率:{ targetPower }");
|
||||
List<byte> data = new List<byte> { 164, 9, 79, 5, 49,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
(byte)(targetPower & byte.MaxValue),
|
||||
(byte)(targetPower >> 8 & byte.MaxValue)
|
||||
};
|
||||
byte checksum = (byte)0;
|
||||
data.ForEach(b => checksum ^= b);
|
||||
data.Add(checksum);
|
||||
|
||||
this.hwInterface.WriteCharacteristic(this.tacxFecWriteCharacteristic, data.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 阻力模式
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
public void SetResistanceMode(double value)
|
||||
{
|
||||
if (this.State != Ant.DeviceState.Connected)
|
||||
return;
|
||||
if (tacxFecWriteCharacteristic == null)
|
||||
return;
|
||||
if(_grade > 0)
|
||||
{
|
||||
this.SetTrackResistance(0);
|
||||
}
|
||||
|
||||
double resistance = value / 100 * 200;
|
||||
|
||||
List<byte> data = new List<byte> { 164, 9, 79, 5, 48,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
(byte)resistance
|
||||
};
|
||||
byte checksum = (byte)0;
|
||||
data.ForEach(b => checksum ^= b);
|
||||
data.Add(checksum);
|
||||
|
||||
this.hwInterface.WriteCharacteristic(this.tacxFecWriteCharacteristic, data.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 风阻
|
||||
/// </summary>
|
||||
/// <param name="height">海拔高度,单位米</param>
|
||||
public void SetWindResistance(double? height = null)
|
||||
{
|
||||
if (this.State != Ant.DeviceState.Connected)
|
||||
return;
|
||||
if (tacxFecWriteCharacteristic == null)
|
||||
return;
|
||||
|
||||
if (_grade > 0)
|
||||
{
|
||||
this.SetTrackResistance(0);
|
||||
}
|
||||
|
||||
byte windResistance = 0;
|
||||
|
||||
if (height.HasValue)
|
||||
{
|
||||
//Wind Resistance Coefficient [kg/m] = Frontal Surface Area [m2] x Drag Coefficient x Air Density[kg / m3]
|
||||
var wr = 0.40 * 1.0 * AirDensity.GetAirDensity(height.Value);
|
||||
if (wr > 1.86)
|
||||
{
|
||||
wr = 1.86;
|
||||
}
|
||||
windResistance = (byte)(Convert.ToInt32(Math.Round(wr, 2) / 0.01));
|
||||
|
||||
Console.WriteLine($"风阻系数:{ windResistance }");
|
||||
}
|
||||
|
||||
byte id = 79;
|
||||
byte size = 9;
|
||||
byte channel = 5;
|
||||
List<byte> data = new List<byte> { 164, size, id, channel, 50,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
windResistance,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
};
|
||||
byte checksum = (byte)0;
|
||||
data.ForEach(b => checksum ^= b);
|
||||
data.Add(checksum);
|
||||
|
||||
this.hwInterface.WriteCharacteristic(this.tacxFecWriteCharacteristic, data.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 轨道阻力
|
||||
/// </summary>
|
||||
/// <param name="grade">坡度百分比的值,单位是%</param>
|
||||
public void SetTrackResistance(double grade)
|
||||
{
|
||||
if (this.State != Ant.DeviceState.Connected)
|
||||
return;
|
||||
if (tacxFecWriteCharacteristic == null)
|
||||
return;
|
||||
|
||||
_grade = grade;
|
||||
if (_grade > 15)
|
||||
{
|
||||
_grade = 15;
|
||||
}
|
||||
else if (_grade < -5)
|
||||
{
|
||||
_grade = -5;
|
||||
}
|
||||
|
||||
var gradeValue = Convert.ToInt32((grade + 200) * 100);
|
||||
var gradeBytes = BitConverter.GetBytes(gradeValue);
|
||||
|
||||
byte id = 79;
|
||||
byte size = 9;
|
||||
byte channel = 5;
|
||||
List<byte> data = new List<byte> { 164, size, id, channel, 51,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
byte.MaxValue,
|
||||
gradeBytes[0],
|
||||
gradeBytes[1],
|
||||
byte.MaxValue,
|
||||
};
|
||||
byte checksum = (byte)0;
|
||||
data.ForEach(b => checksum ^= b);
|
||||
data.Add(checksum);
|
||||
|
||||
this.hwInterface.WriteCharacteristic(this.tacxFecWriteCharacteristic, data.ToArray());
|
||||
}
|
||||
|
||||
private void UpdateUserConfiguration(double weight)
|
||||
{
|
||||
var _weight = (int)(weight * 100);
|
||||
if (this.State != Ant.DeviceState.Connected)
|
||||
return;
|
||||
if (tacxFecWriteCharacteristic == null)
|
||||
return;
|
||||
|
||||
byte id = 79;
|
||||
byte size = 4;
|
||||
byte channel = 5;
|
||||
List<byte> data = new List<byte> { 164, size, id, channel, 55,
|
||||
(byte) (_weight & (int) byte.MaxValue),
|
||||
(byte) (_weight >> 8 & (int) byte.MaxValue),
|
||||
byte.MaxValue,
|
||||
(byte) 143,
|
||||
(byte) 12,
|
||||
(byte) 70,
|
||||
(byte) 0
|
||||
};
|
||||
byte checksum = (byte)0;
|
||||
data.ForEach(b => checksum ^= b);
|
||||
data.Add(checksum);
|
||||
|
||||
this.hwInterface.WriteCharacteristic(this.tacxFecWriteCharacteristic, data.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Devices/Ble/Devices/Tacx.cs.meta
Normal file
11
Assets/Scripts/Devices/Ble/Devices/Tacx.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d133d5406fc475841a781b88d91dc139
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
21
Assets/Scripts/Devices/Ble/Extension/PrimitiveExtensions.cs
Normal file
21
Assets/Scripts/Devices/Ble/Extension/PrimitiveExtensions.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Extension
|
||||
{
|
||||
public static class PrimitiveExtensions
|
||||
{
|
||||
public static bool IsBitSet(this byte value, int position)
|
||||
{
|
||||
return ((uint)value & (uint)(1 << position)) > 0U;
|
||||
}
|
||||
|
||||
public static bool IsBitSet(this ushort value, int position)
|
||||
{
|
||||
return ((uint)value & (uint)(1 << position)) > 0U;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d49278e3c0c3a8a43bc1145abf67a5c0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/Scripts/Devices/Ble/Interfaces.meta
Normal file
8
Assets/Scripts/Devices/Ble/Interfaces.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3f0cb374472e52419b47f6e6d582341
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
20
Assets/Scripts/Devices/Ble/Interfaces/ICharacteristic.cs
Normal file
20
Assets/Scripts/Devices/Ble/Interfaces/ICharacteristic.cs
Normal file
@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Interfaces
|
||||
{
|
||||
public interface ICharacteristic
|
||||
{
|
||||
Guid Uuid { get; }
|
||||
Guid ServiceUuid { get; }
|
||||
|
||||
bool IsOptional { get; }
|
||||
|
||||
void HandleAttributeReceived(byte[] data);
|
||||
|
||||
void SetUnavailable();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e333c9c3812a8654c87353be9e87e84e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -16,7 +16,7 @@ namespace Assets.Scripts.Ble.Scan
|
||||
public BlePeripheralInfo Peripheral { get; }
|
||||
public int Rssi { get; }
|
||||
|
||||
public SensorType SensorType { get; }
|
||||
public SensorType SensorType { get; internal set; }
|
||||
public BleAdvertisementInfo(BlePeripheralInfo peripheral, int rssi, bool connectible, List<Guid> services, byte[] manufactureData, SensorType sensor)
|
||||
{
|
||||
this.Peripheral = peripheral;
|
||||
@ -26,6 +26,8 @@ namespace Assets.Scripts.Ble.Scan
|
||||
//this.ManufactureData = manufactureData;
|
||||
|
||||
this.SensorType = sensor;
|
||||
|
||||
Index = 1;
|
||||
}
|
||||
|
||||
private readonly List<Guid> services;
|
||||
@ -36,5 +38,14 @@ namespace Assets.Scripts.Ble.Scan
|
||||
return this.services;
|
||||
}
|
||||
}
|
||||
|
||||
public void TryAddService(Guid service)
|
||||
{
|
||||
if (this.services.Contains(service))
|
||||
return;
|
||||
this.services.Add(service);
|
||||
}
|
||||
|
||||
public int Index { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
||||
namespace Assets.Scripts.Ble
|
||||
{
|
||||
/// <summary>
|
||||
/// rouvy里的 WinBlePeripheralInfo类
|
||||
/// r里的 WinBlePeripheralInfo类
|
||||
/// </summary>
|
||||
public class BleDeviceProxy
|
||||
{
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
using Assets.Scripts.Ble.Win;
|
||||
using Assets.Scripts.Devices.Ant;
|
||||
using Assets.Scripts.Devices.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Win;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -96,53 +97,90 @@ namespace Assets.Scripts.Ble
|
||||
|
||||
private void WatcherScanInfoReceived(WclBleMainThread sender, long address, string name, int rssi, CPPBridge.WclBleAdvertisementType packetType, Guid? service)
|
||||
{
|
||||
//Debug.Log($"address:{ address }, name:{ name }, service:{ (service == null ? "" : service.Value.ToString()) }");
|
||||
//if(address != 224160707349234)
|
||||
//{
|
||||
//return;
|
||||
//}
|
||||
if (service.HasValue)
|
||||
{
|
||||
//Debug.Log($"address:{ address }, name:{ name }, service:{ (service == null ? "" : service.Value.ToString()) }");
|
||||
}
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
if (pCache.ContainsKey(address.ToString()))
|
||||
{
|
||||
((pCache[address.ToString()].Peripheral) as WinBlePeripheralInfo).SetName(name);
|
||||
(pCache[address.ToString()].Peripheral as WinBlePeripheralInfo).SetName(name);
|
||||
}
|
||||
}
|
||||
//Debug.Log("service:" + service.ToString()+",name:" + name);
|
||||
if (service.HasValue && ServiceUuids.Services.Select(s => s.IdGuid).Any(x => x.Equals(service.Value)))
|
||||
if (!service.HasValue || ServiceUuids.Services.Select(s => s.IdGuid).All(x => !x.Equals(service.Value)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
SensorType sensor = SensorType.None;
|
||||
List<Guid> services = null;
|
||||
if (service != null)
|
||||
{
|
||||
SensorType sensor = SensorType.None;
|
||||
List<Guid> services = null;
|
||||
if (service != null)
|
||||
{
|
||||
|
||||
services = new List<Guid> { service.Value };
|
||||
foreach(var item in ServiceUuids.Services)
|
||||
services = new List<Guid> { service.Value };
|
||||
foreach(var item in ServiceUuids.Services)
|
||||
{
|
||||
if(item.IdGuid != service.Value)
|
||||
{
|
||||
if(item.IdGuid != service.Value)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(item.IdByteArray == ServiceUuids.Ftms)
|
||||
{
|
||||
sensor = SensorType.Trainer;
|
||||
}
|
||||
else if(item.IdByteArray == ServiceUuids.HeartRate)
|
||||
{
|
||||
sensor = SensorType.HeartRate;
|
||||
}
|
||||
else if(item.IdByteArray == ServiceUuids.CyclingPower)
|
||||
{
|
||||
sensor = SensorType.Power;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
};
|
||||
if(item.IdByteArray == ServiceUuids.Ftms)
|
||||
{
|
||||
sensor = SensorType.Trainer;
|
||||
}
|
||||
else if(item.IdByteArray == ServiceUuids.HeartRate)
|
||||
{
|
||||
sensor = SensorType.HeartRate;
|
||||
}
|
||||
else if(item.IdByteArray == ServiceUuids.CyclingPower)
|
||||
{
|
||||
sensor = SensorType.Power;
|
||||
//sensor = SensorType.Trainer;
|
||||
}
|
||||
else if(item.IdByteArray == ServiceUuids.CyclingSpeedCadence)
|
||||
{
|
||||
sensor = SensorType.SpeedCadence;
|
||||
}
|
||||
else if(item.IdByteArray == ServiceUuids.TacxBle)
|
||||
{
|
||||
sensor = SensorType.Trainer;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (!pCache.ContainsKey(address.ToString())) {
|
||||
var device = new BleAdvertisementInfo(new WinBlePeripheralInfo(address.ToString(), name), rssi, true, services, null, sensor);
|
||||
pCache.Add(address.ToString(), device);
|
||||
if (!pCache.ContainsKey(address.ToString()))
|
||||
{
|
||||
var device = new BleAdvertisementInfo(new WinBlePeripheralInfo(address.ToString(), name), rssi, true, services, null, sensor);
|
||||
pCache.Add(address.ToString(), device);
|
||||
|
||||
WclBleGattThread gattClient = this.SetUpGattClient(device.Peripheral);
|
||||
//this.ConnectInternal(gattClient);
|
||||
WclBleGattThread gattClient = this.SetUpGattClient(device.Peripheral);
|
||||
//this.ConnectInternal(gattClient);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Debug.Log(sensor);
|
||||
//pCache[address.ToString()].SensorType = sensor;
|
||||
foreach (var item in services)
|
||||
{
|
||||
pCache[address.ToString()].TryAddService(item);
|
||||
}
|
||||
pCache[address.ToString()].Index++;
|
||||
if(pCache[address.ToString()].SensorType == SensorType.Power && pCache[address.ToString()].Services.Any(s=> s.Equals(ServiceUuids.Get(ServiceUuids.TacxBle).IdGuid)))
|
||||
{
|
||||
pCache[address.ToString()].SensorType = SensorType.Trainer;
|
||||
//Debug.Log("纠正为trainer, "+ pCache[address.ToString()].Index);
|
||||
}
|
||||
|
||||
_discoveredCallback?.Invoke(pCache[address.ToString()]);
|
||||
|
||||
if (pCache[address.ToString()].Index > 4 || pCache[address.ToString()].SensorType != SensorType.Power)
|
||||
{
|
||||
_discoveredCallback?.Invoke(pCache[address.ToString()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,8 +217,11 @@ namespace Assets.Scripts.Ble
|
||||
|
||||
private void ConnectInternal(WclBleGattThread gattClient)
|
||||
{
|
||||
int num = gattClient.Connect();
|
||||
Debug.Log("连接设备返回" + num);
|
||||
//Task.Run(() =>
|
||||
//{
|
||||
int num = gattClient.Connect();
|
||||
Debug.Log("连接设备返回" + num);
|
||||
//});
|
||||
}
|
||||
|
||||
internal void DisconnectPeripheral(BlePeripheralInfo peripheral, Action callback)
|
||||
@ -323,7 +364,10 @@ namespace Assets.Scripts.Ble
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.characteristicsDiscoveredCallbacks.Add(service, callback);
|
||||
if (!this.characteristicsDiscoveredCallbacks.ContainsKey(service))
|
||||
{
|
||||
this.characteristicsDiscoveredCallbacks.Add(service, callback);
|
||||
}
|
||||
int num = gattThread.DiscoverCharacteristics(service);
|
||||
if (WclBleErrors.IsSuccessCode(num))
|
||||
{
|
||||
@ -355,11 +399,29 @@ namespace Assets.Scripts.Ble
|
||||
this.GattCharacteristicSubscribed(gattThread, characteristic, response);
|
||||
}
|
||||
|
||||
public void WriteCharacteristic(BleCharacteristicInfo characteristic, byte[] data)
|
||||
{
|
||||
var gattThread = this.wclBleMainThread.GetGattThread(characteristic.Peripheral);
|
||||
if(gattThread == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int num = gattThread.WriteCharacteristic(characteristic, data);
|
||||
if (WclBleErrors.IsSuccessCode(num))
|
||||
{
|
||||
Debug.Log("设置命令成功");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.wclBleMainThread.Dispose();
|
||||
this.wclBleMainThread = null;
|
||||
hwInterface = null;
|
||||
pCache.Clear();
|
||||
}
|
||||
|
||||
public void ReadCharacteristic(BleCharacteristicInfo characteristic, CharacteristicReadCallback callback)
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Assets.Scripts.Devices.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Win;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Assets.Scripts.Devices.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Win;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
43
Assets/Scripts/Devices/Ble/Win/WclAlertableWait.cs
Normal file
43
Assets/Scripts/Devices/Ble/Win/WclAlertableWait.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Win
|
||||
{
|
||||
internal class WclAlertableWait
|
||||
{
|
||||
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "WCLWait")]
|
||||
[return: MarshalAs(UnmanagedType.U4)]
|
||||
public static extern uint Wait([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.SysInt, SizeParamIndex = 1)][In] IntPtr[] Handle, [MarshalAs(UnmanagedType.U4)][In] uint Cnt, [MarshalAs(UnmanagedType.U4)][In] uint Timeout);
|
||||
|
||||
// Token: 0x0600207E RID: 8318
|
||||
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "WCLFlushApc")]
|
||||
[return: MarshalAs(UnmanagedType.U4)]
|
||||
public static extern uint FlushApc();
|
||||
|
||||
// Token: 0x0600207F RID: 8319
|
||||
[DllImport("WclBlePluginCPP.dll", CallingConvention = CallingConvention.StdCall, EntryPoint = "WCLSetApcSync")]
|
||||
public static extern void SetApcSync();
|
||||
|
||||
// Token: 0x04001189 RID: 4489
|
||||
public const uint WAIT_OBJECT_0 = 0U;
|
||||
|
||||
// Token: 0x0400118A RID: 4490
|
||||
public const uint WAIT_IO_COMPLETION = 192U;
|
||||
|
||||
// Token: 0x0400118B RID: 4491
|
||||
public const uint WAIT_TIMEOUT = 258U;
|
||||
|
||||
// Token: 0x0400118C RID: 4492
|
||||
public const uint WAIT_FAILED = 4294967295U;
|
||||
|
||||
// Token: 0x0400118D RID: 4493
|
||||
public const uint INFINITE = 4294967295U;
|
||||
|
||||
// Token: 0x0400118E RID: 4494
|
||||
public const string GuidTemplate = "0000XXXX-0000-1000-8000-00805F9B34FB";
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Devices/Ble/Win/WclAlertableWait.cs.meta
Normal file
11
Assets/Scripts/Devices/Ble/Win/WclAlertableWait.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4ec3942a1d98efc4eb36cd00001109b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -1,15 +1,16 @@
|
||||
using Assets.Scripts.Ble.Win;
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Ble.Win;
|
||||
using Assets.Scripts.Ble.Win.CPPBridge;
|
||||
using Assets.Scripts.Devices.Ble;
|
||||
using Assets.Scripts.Devices.Ble.Win;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Ble
|
||||
namespace Assets.Scripts.Devices.Ble.Win
|
||||
{
|
||||
internal class WclBleGattThread
|
||||
{
|
||||
@ -163,7 +164,12 @@ namespace Assets.Scripts.Ble
|
||||
private readonly long address;
|
||||
|
||||
public BlePeripheralInfo Peripheral { get; }
|
||||
|
||||
private Thread thread;
|
||||
private ConcurrentQueue<Action> actions = new ConcurrentQueue<Action>();
|
||||
private bool start = false;
|
||||
private ManualResetEvent sEvent;
|
||||
private AutoResetEvent aEvent;
|
||||
private ManualResetEvent tEvent;
|
||||
internal WclBleGattThread(BlePeripheralInfo bleDevice, IntPtr radio)
|
||||
{
|
||||
this.Peripheral = bleDevice;
|
||||
@ -175,10 +181,84 @@ namespace Assets.Scripts.Ble
|
||||
|
||||
public bool Start()
|
||||
{
|
||||
this.SetUpWorkerThread();
|
||||
if (this.start)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
this.start = true;
|
||||
|
||||
this.sEvent = new ManualResetEvent(false);
|
||||
this.tEvent = new ManualResetEvent(false);
|
||||
this.aEvent = new AutoResetEvent(false);
|
||||
|
||||
//thread = new Thread(new ThreadStart(ThreadProc));
|
||||
// this.sEvent.Set();
|
||||
|
||||
// IntPtr[] handle = new IntPtr[]
|
||||
// {
|
||||
// this.tEvent.SafeWaitHandle.DangerousGetHandle(),
|
||||
// this.aEvent.SafeWaitHandle.DangerousGetHandle()
|
||||
// };
|
||||
// while (WclAlertableWait.Wait(handle, 2U, WclAlertableWait.INFINITE) != WclAlertableWait.WAIT_OBJECT_0)
|
||||
// {
|
||||
// Action action;
|
||||
// if (this.actions.TryDequeue(out action))
|
||||
// {
|
||||
// if (action != null)
|
||||
// {
|
||||
// Debug.Log("连接设备");
|
||||
// action();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// }));
|
||||
//thread.Start();
|
||||
|
||||
//this.sEvent.WaitOne();
|
||||
ThreadProc();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
Debug.Log("停止");
|
||||
start = false;
|
||||
thread?.Abort();
|
||||
|
||||
}
|
||||
|
||||
private void ThreadProc()
|
||||
{
|
||||
this.SetUpWorkerThread();
|
||||
//this.sEvent.Set();
|
||||
//this.DoWorkerLoop();
|
||||
|
||||
//this.CleanUpWorkerThread();
|
||||
//this.InternalCleanUp();
|
||||
}
|
||||
|
||||
private void CleanUpWorkerThread()
|
||||
{
|
||||
this.gatt.Disconnect();
|
||||
this.gatt.Dispose();
|
||||
this.gatt = null;
|
||||
}
|
||||
private void InternalCleanUp()
|
||||
{
|
||||
this.sEvent.Close();
|
||||
this.sEvent.Dispose();
|
||||
this.sEvent = null;
|
||||
|
||||
this.aEvent.Close();
|
||||
this.aEvent.Dispose();
|
||||
this.aEvent = null;
|
||||
|
||||
this.tEvent.Close();
|
||||
this.tEvent.Dispose();
|
||||
this.tEvent = null;
|
||||
}
|
||||
|
||||
private void SetUpWorkerThread()
|
||||
{
|
||||
this.gatt = new WclBleGattClient(this.address, this.rPtr)
|
||||
@ -189,6 +269,28 @@ namespace Assets.Scripts.Ble
|
||||
};
|
||||
}
|
||||
|
||||
private void DoWorkerLoop()
|
||||
{
|
||||
IntPtr[] handle = new IntPtr[]
|
||||
{
|
||||
this.tEvent.SafeWaitHandle.DangerousGetHandle(),
|
||||
this.aEvent.SafeWaitHandle.DangerousGetHandle()
|
||||
};
|
||||
while (WclAlertableWait.Wait(handle, 2U, 4294967295U) != 0U)
|
||||
{
|
||||
//this.InvokeQueuedActions();
|
||||
Action action;
|
||||
if (this.actions.TryDequeue(out action))
|
||||
{
|
||||
if (action != null)
|
||||
{
|
||||
Debug.Log("连接设备");
|
||||
action();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCharacteristicChanged(WclBleGattClient connection, ushort handle, byte[] value)
|
||||
{
|
||||
if (!this.subscribedCharHandles.ContainsKey(handle)) {
|
||||
@ -260,6 +362,10 @@ namespace Assets.Scripts.Ble
|
||||
public int Connect()
|
||||
{
|
||||
this.gatt.Connect();
|
||||
//this.actions.Enqueue(() =>
|
||||
//{
|
||||
// this.gatt.Connect();
|
||||
//});
|
||||
return WclBleErrors.WCL_E_SUCCESS;
|
||||
}
|
||||
|
||||
@ -381,6 +487,21 @@ namespace Assets.Scripts.Ble
|
||||
this.gattCharacteristicsSubscribed(this, characteristic, response);
|
||||
}
|
||||
|
||||
public int WriteCharacteristic(BleCharacteristicInfo characteristicInfo, byte[] data)
|
||||
{
|
||||
if (!this.charMapping.ContainsKey(characteristicInfo))
|
||||
{
|
||||
return WclBleErrors.WCL_E_CONNECTION_NOT_ACTIVE;
|
||||
}
|
||||
GattCharacteristic gCh = this.charMapping[characteristicInfo];
|
||||
|
||||
int result = this.gatt.WriteCharacteristic(gCh, data);
|
||||
|
||||
|
||||
return WclBleErrors.WCL_E_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
private class WinBleCharacteristicInfo : BleCharacteristicInfo
|
||||
{
|
||||
// Token: 0x06003F85 RID: 16261 RVA: 0x000EA274 File Offset: 0x000E8474
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using Assets.Scripts.Ble.CPPBridge;
|
||||
using Assets.Scripts.Ble;
|
||||
using Assets.Scripts.Ble.CPPBridge;
|
||||
using Assets.Scripts.Devices.Ble;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -8,7 +9,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Ble
|
||||
namespace Assets.Scripts.Devices.Ble.Win
|
||||
{
|
||||
internal class WclBleMainThread
|
||||
{
|
||||
@ -99,6 +100,12 @@ namespace Assets.Scripts.Ble
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Debug.Log("停止thread");
|
||||
foreach (var item in this.gattClients.Values)
|
||||
{
|
||||
item.Stop();
|
||||
}
|
||||
|
||||
wclBleManager.Dispose();
|
||||
}
|
||||
|
||||
|
||||
215
Assets/Scripts/Devices/Ble/Win/WclBleThread.cs
Normal file
215
Assets/Scripts/Devices/Ble/Win/WclBleThread.cs
Normal file
@ -0,0 +1,215 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
|
||||
namespace Assets.Scripts.Devices.Ble.Win
|
||||
{
|
||||
internal abstract class WclBleThread
|
||||
{
|
||||
// Token: 0x170005E2 RID: 1506
|
||||
// (get) Token: 0x06002114 RID: 8468 RVA: 0x000890FE File Offset: 0x000872FE
|
||||
public bool IsRunning
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.started || this.IsTerminating;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x170005E3 RID: 1507
|
||||
// (get) Token: 0x06002115 RID: 8469 RVA: 0x00089112 File Offset: 0x00087312
|
||||
public bool IsTerminating
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.terminating;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x170005E4 RID: 1508
|
||||
// (get) Token: 0x06002116 RID: 8470 RVA: 0x0008911C File Offset: 0x0008731C
|
||||
public bool CanLoadWork
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.IsRunning && !this.IsTerminating;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x06002117 RID: 8471
|
||||
protected abstract void SetUpWorkerThread();
|
||||
|
||||
// Token: 0x06002118 RID: 8472
|
||||
protected abstract void CleanUpWorkerThread();
|
||||
|
||||
// Token: 0x06002119 RID: 8473 RVA: 0x00089131 File Offset: 0x00087331
|
||||
protected void TreadProcInitialized()
|
||||
{
|
||||
this.sEvent.Set();
|
||||
}
|
||||
|
||||
// Token: 0x0600211A RID: 8474 RVA: 0x0008913F File Offset: 0x0008733F
|
||||
protected void ProcessPendingAPCMessages()
|
||||
{
|
||||
while (WclAlertableWait.FlushApc() != 0U)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x0600211B RID: 8475 RVA: 0x00089148 File Offset: 0x00087348
|
||||
protected void InternalCleanUp()
|
||||
{
|
||||
this.sEvent.Close();
|
||||
this.sEvent.Dispose();
|
||||
this.sEvent = null;
|
||||
this.aEvent.Close();
|
||||
this.aEvent.Dispose();
|
||||
this.aEvent = null;
|
||||
this.tEvent.Close();
|
||||
this.tEvent.Dispose();
|
||||
this.tEvent = null;
|
||||
this.terminating = false;
|
||||
}
|
||||
|
||||
// Token: 0x0600211C RID: 8476 RVA: 0x000891B5 File Offset: 0x000873B5
|
||||
private void ThreadProc()
|
||||
{
|
||||
this.SetUpWorkerThread();
|
||||
this.sEvent.Set();
|
||||
this.DoWorkerLoop();
|
||||
this.CleanUpWorkerThread();
|
||||
this.InternalCleanUp();
|
||||
}
|
||||
|
||||
// Token: 0x0600211D RID: 8477 RVA: 0x000891DC File Offset: 0x000873DC
|
||||
private void DoWorkerLoop()
|
||||
{
|
||||
IntPtr[] handle = new IntPtr[]
|
||||
{
|
||||
this.tEvent.SafeWaitHandle.DangerousGetHandle(),
|
||||
this.aEvent.SafeWaitHandle.DangerousGetHandle()
|
||||
};
|
||||
while (WclAlertableWait.Wait(handle, 2U, 4294967295U) != 0U && !this.terminating)
|
||||
{
|
||||
this.InvokeQueuedActions();
|
||||
if (this.terminating)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x0600211E RID: 8478 RVA: 0x0008923C File Offset: 0x0008743C
|
||||
public virtual bool Start()
|
||||
{
|
||||
if (this.IsRunning)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
this.sEvent = new ManualResetEvent(false);
|
||||
this.tEvent = new ManualResetEvent(false);
|
||||
this.aEvent = new AutoResetEvent(false);
|
||||
this.wThread = new Thread(new ThreadStart(this.ThreadProc));
|
||||
this.wThread.Start();
|
||||
this.sEvent.WaitOne();
|
||||
this.started = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Token: 0x0600211F RID: 8479 RVA: 0x000892B0 File Offset: 0x000874B0
|
||||
public virtual bool Stop()
|
||||
{
|
||||
if (!this.started || this.IsTerminating)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
this.terminating = true;
|
||||
this.tEvent.Set();
|
||||
this.wThread = null;
|
||||
this.ClearActionQueue();
|
||||
this.started = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Token: 0x06002120 RID: 8480 RVA: 0x000892FD File Offset: 0x000874FD
|
||||
protected bool EnqueueAction(Action action)
|
||||
{
|
||||
if (this.CanLoadWork)
|
||||
{
|
||||
this.aQueue.Enqueue(action);
|
||||
this.aEvent.Set();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Token: 0x06002121 RID: 8481 RVA: 0x00089324 File Offset: 0x00087524
|
||||
protected void ClearActionQueue()
|
||||
{
|
||||
Action action;
|
||||
while (this.aQueue.TryDequeue(out action))
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x06002122 RID: 8482 RVA: 0x00089340 File Offset: 0x00087540
|
||||
protected void InvokeQueuedActions()
|
||||
{
|
||||
while (this.DequeueAdnInvokeAction())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x06002123 RID: 8483 RVA: 0x0008934C File Offset: 0x0008754C
|
||||
protected bool DequeueAdnInvokeAction()
|
||||
{
|
||||
Action action = this.TryDequActione();
|
||||
if (action == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
action();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Token: 0x06002124 RID: 8484 RVA: 0x0008936C File Offset: 0x0008756C
|
||||
private Action TryDequActione()
|
||||
{
|
||||
if (!this.CanLoadWork)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Action result;
|
||||
if (!this.aQueue.TryDequeue(out result))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Token: 0x04001341 RID: 4929
|
||||
protected ManualResetEvent tEvent;
|
||||
|
||||
// Token: 0x04001342 RID: 4930
|
||||
protected AutoResetEvent aEvent;
|
||||
|
||||
// Token: 0x04001343 RID: 4931
|
||||
private readonly ConcurrentQueue<Action> aQueue = new ConcurrentQueue<Action>();
|
||||
|
||||
// Token: 0x04001344 RID: 4932
|
||||
protected ManualResetEvent sEvent;
|
||||
|
||||
// Token: 0x04001345 RID: 4933
|
||||
protected Thread wThread;
|
||||
|
||||
// Token: 0x04001346 RID: 4934
|
||||
protected volatile bool terminating;
|
||||
|
||||
// Token: 0x04001347 RID: 4935
|
||||
private volatile bool started;
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Devices/Ble/Win/WclBleThread.cs.meta
Normal file
11
Assets/Scripts/Devices/Ble/Win/WclBleThread.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25f702c985f2a1b41990cc8fcdcb0450
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Scripts.Devices
|
||||
{
|
||||
@ -45,6 +46,7 @@ namespace Assets.Scripts.Devices
|
||||
var adapter = adapters.FirstOrDefault(a => a.Interface == connectionInterface);
|
||||
if(adapter != null)
|
||||
{
|
||||
Debug.Log("bbbbbb " + (adapter.GetState().ToString()));
|
||||
return adapter.GetState();
|
||||
}
|
||||
return DeviceAdapterState.Unavailable;
|
||||
|
||||
@ -10,6 +10,7 @@ public class DeviceItem : Selectable, IEventSystemHandler, IPointerClickHandler
|
||||
{
|
||||
private bool isOn;
|
||||
private Text mText;
|
||||
private Text mType;
|
||||
public AbstractDevice DeviceInfo
|
||||
{
|
||||
get;set;
|
||||
@ -18,6 +19,7 @@ public class DeviceItem : Selectable, IEventSystemHandler, IPointerClickHandler
|
||||
protected override void Awake()
|
||||
{
|
||||
mText = this.transform.Find("Name").GetComponent<Text>();
|
||||
mType = this.transform.Find("Type").GetComponent<Text>();
|
||||
}
|
||||
|
||||
// Start is called before the first frame update
|
||||
@ -25,11 +27,17 @@ public class DeviceItem : Selectable, IEventSystemHandler, IPointerClickHandler
|
||||
{
|
||||
//this.currentSelectionState = SelectionState.Selected
|
||||
|
||||
mText.text = DeviceInfo.Name + "-" + DeviceInfo.DeviceNumber;
|
||||
mText.text = DeviceInfo.Name;// + "-" + DeviceInfo.DeviceNumber;
|
||||
if(DeviceInfo.Network == NetworkType.ANT)
|
||||
{
|
||||
mText.text += "-" + DeviceInfo.DeviceNumber;
|
||||
}
|
||||
//if(DeviceInfo.State == DeviceState.Connected)
|
||||
{
|
||||
// this.SetSelectedStyle();
|
||||
}
|
||||
|
||||
mType.text = DeviceInfo.Network.ToString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ public class MainNav : MonoBehaviour
|
||||
var device = this.transform.Find("Device");
|
||||
UIManager.AddEvent(device.gameObject, EventTriggerType.PointerClick, x =>
|
||||
{
|
||||
Debug.Log("click device");
|
||||
//Debug.Log("click device");
|
||||
UIManager.ShowDevicePanel();
|
||||
});
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
using DG.Tweening;
|
||||
using Assets.Scripts.Devices.Ble.Devices;
|
||||
|
||||
public class DeviceController : PFUIPanel
|
||||
{
|
||||
@ -21,6 +22,11 @@ public class DeviceController : PFUIPanel
|
||||
RectTransform circulo;
|
||||
private GameObject statusText;
|
||||
|
||||
private Image bleStatus;
|
||||
private Sprite ble0;
|
||||
private Sprite ble1;
|
||||
RectTransform bleCirculo;
|
||||
|
||||
private bool _available = false;
|
||||
private bool Available
|
||||
{
|
||||
@ -54,11 +60,38 @@ public class DeviceController : PFUIPanel
|
||||
}
|
||||
}
|
||||
|
||||
private bool _bleAvailable = false;
|
||||
private bool BleAvailable
|
||||
{
|
||||
get
|
||||
{
|
||||
return _bleAvailable;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _bleAvailable)
|
||||
return;
|
||||
_bleAvailable = value;
|
||||
if (_bleAvailable)
|
||||
{
|
||||
bleStatus.sprite = ble1;
|
||||
DOTween.Kill(bleCirculo, false);
|
||||
bleCirculo.GetComponent<Image>().sprite = circuloCompleto;
|
||||
}
|
||||
else
|
||||
{
|
||||
bleStatus.sprite = ble0;
|
||||
bleCirculo.GetComponent<Image>().sprite = circuloCarga;
|
||||
bleCirculo.DOLocalRotate(new Vector3(0, 0, 360), 1f, RotateMode.FastBeyond360).SetEase(Ease.Linear).SetLoops(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
Debug.Log("device awake");
|
||||
//Debug.Log("device awake");
|
||||
}
|
||||
|
||||
// Start is called before the first frame update
|
||||
@ -83,14 +116,13 @@ public class DeviceController : PFUIPanel
|
||||
// Debug.Log("aaaaaaaaaaaaaa");
|
||||
//});
|
||||
|
||||
var bg = this.transform.Find("Status").Find("Bg");
|
||||
antStatus = bg.Find("Ant+").GetComponent<Image>();
|
||||
var bg = this.transform.Find("Status").Find("Bg");
|
||||
|
||||
statusText = this.transform.Find("Status").Find("GameObject").gameObject;
|
||||
statusText.SetActive(false);
|
||||
|
||||
|
||||
circulo = bg.Find("Image").GetComponent<RectTransform>();
|
||||
antStatus = bg.Find("AntIcon/Ant+").GetComponent<Image>();
|
||||
circulo = bg.Find("AntIcon/Image").GetComponent<RectTransform>();
|
||||
//circulo.DORotate(new Vector3(0, 0, 360), 1.5f, RotateMode.Fast).SetLoops(-1);
|
||||
circulo.DOLocalRotate(new Vector3(0, 0, 360), 1f, RotateMode.FastBeyond360).SetEase(Ease.Linear).SetLoops(-1);
|
||||
|
||||
@ -99,7 +131,42 @@ public class DeviceController : PFUIPanel
|
||||
circuloCarga = Resources.Load<Sprite>("Images/icon-circulo-carga");
|
||||
circuloCompleto = Resources.Load<Sprite>("Images/icon-circulo-completo");
|
||||
|
||||
|
||||
bleStatus = bg.Find("BleIcon/Ble").GetComponent<Image>();
|
||||
bleCirculo = bg.Find("BleIcon/Image").GetComponent<RectTransform>();
|
||||
bleCirculo.DOLocalRotate(new Vector3(0, 0, 360), 1f, RotateMode.FastBeyond360).SetEase(Ease.Linear).SetLoops(-1);
|
||||
ble0 = Resources.Load<Sprite>("Images/Bluetooth_0");
|
||||
ble1 = Resources.Load<Sprite>("Images/Bluetooth_2");
|
||||
|
||||
base.SetRounded(bg, 64);
|
||||
|
||||
|
||||
//var text = this.transform.Find("InputField").GetComponent<InputField>();
|
||||
|
||||
//var btn = this.transform.Find("Button").GetComponent<Button>();
|
||||
//btn.onClick.AddListener(() =>
|
||||
//{
|
||||
// //Debug.Log(text.text);
|
||||
// var device = App.MainDeviceAdapter.GetDevices().FirstOrDefault(d => d.State == DeviceState.Connected && d.Sensor == SensorType.HeartRate);
|
||||
// if(device == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// //(device as HeartRate).GetBatteryLevel();
|
||||
|
||||
|
||||
// //(device as Tacx).SetResistanceMode(int.Parse(text.text));
|
||||
|
||||
// //if (device is Tacx)
|
||||
// //{
|
||||
// // (device as Tacx).SetTrackResistance(double.Parse(text.text));
|
||||
// //}
|
||||
// //else if(device is FitDevice)
|
||||
// //{
|
||||
// // (device as FitDevice).SetErgMode(100* 4);
|
||||
// //}
|
||||
|
||||
//});
|
||||
}
|
||||
|
||||
|
||||
@ -109,9 +176,11 @@ public class DeviceController : PFUIPanel
|
||||
timer -= Time.deltaTime;
|
||||
if (timer <= 0)
|
||||
{
|
||||
//Available = AntConnector.Instance().IsAvailable;
|
||||
Available = App.MainDeviceAdapter.GetState(Assets.Scripts.Devices.ConnectionInterface.ANT) == Assets.Scripts.Devices.DeviceAdapterState.On;
|
||||
|
||||
|
||||
BleAvailable = App.MainDeviceAdapter.GetState(Assets.Scripts.Devices.ConnectionInterface.BLE) == Assets.Scripts.Devices.DeviceAdapterState.On;
|
||||
//Debug.Log("ble available:" + App.MainDeviceAdapter.GetState(Assets.Scripts.Devices.ConnectionInterface.BLE).ToString());
|
||||
|
||||
timer = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user