@jjlmoya/utils-hardware 1.24.0 → 1.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/package.json +2 -1
  2. package/src/category/index.ts +3 -1
  3. package/src/entries.ts +7 -1
  4. package/src/index.ts +2 -0
  5. package/src/tests/locale_completeness.test.ts +2 -2
  6. package/src/tests/tool_validation.test.ts +2 -2
  7. package/src/tool/keyboardChatterTest/bibliography.astro +15 -0
  8. package/src/tool/keyboardChatterTest/bibliography.ts +20 -0
  9. package/src/tool/keyboardChatterTest/component.astro +353 -0
  10. package/src/tool/keyboardChatterTest/entry.ts +30 -0
  11. package/src/tool/keyboardChatterTest/i18n/de.ts +232 -0
  12. package/src/tool/keyboardChatterTest/i18n/en.ts +232 -0
  13. package/src/tool/keyboardChatterTest/i18n/es.ts +232 -0
  14. package/src/tool/keyboardChatterTest/i18n/fr.ts +232 -0
  15. package/src/tool/keyboardChatterTest/i18n/id.ts +232 -0
  16. package/src/tool/keyboardChatterTest/i18n/it.ts +232 -0
  17. package/src/tool/keyboardChatterTest/i18n/ja.ts +232 -0
  18. package/src/tool/keyboardChatterTest/i18n/ko.ts +232 -0
  19. package/src/tool/keyboardChatterTest/i18n/nl.ts +232 -0
  20. package/src/tool/keyboardChatterTest/i18n/pl.ts +232 -0
  21. package/src/tool/keyboardChatterTest/i18n/pt.ts +232 -0
  22. package/src/tool/keyboardChatterTest/i18n/ru.ts +232 -0
  23. package/src/tool/keyboardChatterTest/i18n/sv.ts +232 -0
  24. package/src/tool/keyboardChatterTest/i18n/tr.ts +232 -0
  25. package/src/tool/keyboardChatterTest/i18n/zh.ts +232 -0
  26. package/src/tool/keyboardChatterTest/index.ts +12 -0
  27. package/src/tool/keyboardChatterTest/keyboard-chatter-test.css +512 -0
  28. package/src/tool/keyboardChatterTest/logic.ts +23 -0
  29. package/src/tool/keyboardChatterTest/seo.astro +16 -0
  30. package/src/tool/keyboardChatterTest/ui.ts +34 -0
  31. package/src/tool/webBluetoothBleScanner/bibliography.astro +14 -0
  32. package/src/tool/webBluetoothBleScanner/bibliography.ts +16 -0
  33. package/src/tool/webBluetoothBleScanner/component.astro +339 -0
  34. package/src/tool/webBluetoothBleScanner/entry.ts +29 -0
  35. package/src/tool/webBluetoothBleScanner/i18n/de.ts +233 -0
  36. package/src/tool/webBluetoothBleScanner/i18n/en.ts +233 -0
  37. package/src/tool/webBluetoothBleScanner/i18n/es.ts +233 -0
  38. package/src/tool/webBluetoothBleScanner/i18n/fr.ts +233 -0
  39. package/src/tool/webBluetoothBleScanner/i18n/id.ts +233 -0
  40. package/src/tool/webBluetoothBleScanner/i18n/it.ts +233 -0
  41. package/src/tool/webBluetoothBleScanner/i18n/ja.ts +233 -0
  42. package/src/tool/webBluetoothBleScanner/i18n/ko.ts +233 -0
  43. package/src/tool/webBluetoothBleScanner/i18n/nl.ts +233 -0
  44. package/src/tool/webBluetoothBleScanner/i18n/pl.ts +233 -0
  45. package/src/tool/webBluetoothBleScanner/i18n/pt.ts +233 -0
  46. package/src/tool/webBluetoothBleScanner/i18n/ru.ts +233 -0
  47. package/src/tool/webBluetoothBleScanner/i18n/sv.ts +233 -0
  48. package/src/tool/webBluetoothBleScanner/i18n/tr.ts +233 -0
  49. package/src/tool/webBluetoothBleScanner/i18n/zh.ts +233 -0
  50. package/src/tool/webBluetoothBleScanner/index.ts +11 -0
  51. package/src/tool/webBluetoothBleScanner/logic.ts +79 -0
  52. package/src/tool/webBluetoothBleScanner/seo.astro +15 -0
  53. package/src/tool/webBluetoothBleScanner/ui.ts +41 -0
  54. package/src/tool/webBluetoothBleScanner/web-bluetooth-ble-scanner.css +406 -0
  55. package/src/tools.ts +3 -1
@@ -0,0 +1,233 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { WebBluetoothBleScannerUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
5
+
6
+ const slug = 'tarayici-ble-web-bluetooth';
7
+ const title = 'Web Bluetooth BLE Tarayıcı';
8
+ const description = 'Tarayıcıdan yakındaki Bluetooth Low Energy cihazlarını tarayın, sunulan GATT servis UUIDlerini inceleyin ve IoT veya giyilebilir donanımınızın keşfedilebilir olup olmadığını test edin.';
9
+
10
+ const faqData = [
11
+ {
12
+ question: 'Bir web sitesi izinsiz Bluetooth cihazlarını tarayabilir mi?',
13
+ answer: 'Hayır. Web Bluetooth her zaman bir kullanıcı hareketi ve tarayıcı izin seçicisi gerektirir. Bu araç yalnızca açıkça seçtiğiniz cihazı görür ve MAC adreslerini, cihaz kimliklerini veya tarama sonuçlarını saklamaz.',
14
+ },
15
+ {
16
+ question: 'Tarayıcı neden yakındaki her BLE cihazını göstermiyor?',
17
+ answer: 'Tarayıcılar Bluetooth\'u sessiz bir arka plan tarayıcısı olarak değil, bir izin seçicisi aracılığıyla kasıtlı olarak sunar. Bazı cihazlar ayrıca tanıtım yapmayı durdurur, adını gizler, eşleştirme gerektirir veya yalnızca bağlantıdan sonra servisleri açar.',
18
+ },
19
+ {
20
+ question: 'Hangi tarayıcılar Web Bluetooth\'u destekler?',
21
+ answer: 'Web Bluetooth en iyi Chrome ve Edge gibi Chromium tabanlı masaüstü tarayıcılarda desteklenir. Genellikle HTTPS veya localhost gerektirir ve birçok Firefox, Safari ve iOS tarayıcı yapılandırmasında kullanılamaz.',
22
+ },
23
+ {
24
+ question: 'Giyilebilir bir cihazdan özel sensör verilerini okuyabilir mi?',
25
+ answer: 'Yalnızca cihaz uyumlu GATT servisleri sunarsa ve tarayıcı erişim izni verirse. Birçok ticari giyilebilir cihaz, genel bir tarayıcı tarayıcısının çözemediği satıcı uygulamaları, şifreleme, eşleştirme veya özel özellikler gerektirir.',
26
+ },
27
+ {
28
+ question: 'GATT servis UUIDleri nedir?',
29
+ answer: 'Bir GATT servis UUID\'si, Pil Servisi, Kalp Atış Hızı, Cihaz Bilgisi veya maker ve IoT donanımı tarafından kullanılan özel bir satıcı servisi gibi Bluetooth Low Energy özellik grubunu tanımlar.',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: 'Uyumlu bir tarayıcı kullanın',
36
+ text: 'Aracı Chrome veya Edge\'de HTTPS veya localhost üzerinden açın, ardından bilgisayarda veya telefonda Bluetooth\'un etkin olduğundan emin olun.',
37
+ },
38
+ {
39
+ name: 'Donanımı tanıtım moduna alın',
40
+ text: 'BLE cihazını uyandırın, kapatıp açın, eşleştirme düğmesine basın veya tarayıcı izin seçicisinde görünmesi için tanıtım modunu açın.',
41
+ },
42
+ {
43
+ name: 'Ortamı tarayın',
44
+ text: 'Ortamı Tara düğmesine basın ve incelemek istediğiniz BLE cihazını seçin. Tarayıcı izin iletişim kutusu, sayfaya hangi cihazın görünür olacağını tam olarak kontrol eder.',
45
+ },
46
+ {
47
+ name: 'GATT servislerini okuyun',
48
+ text: 'Bağlantıdan sonra, standart Bluetooth profillerini, özel firmware servislerini ve cihazın beklediğiniz veri yolunu sunup sunmadığını belirlemek için servis UUID kartlarını inceleyin.',
49
+ },
50
+ ];
51
+
52
+ const faqSchema: WithContext<FAQPage> = {
53
+ '@context': 'https://schema.org',
54
+ '@type': 'FAQPage',
55
+ mainEntity: faqData.map((item) => ({
56
+ '@type': 'Question',
57
+ name: item.question,
58
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
59
+ })),
60
+ };
61
+
62
+ const howToSchema: WithContext<HowTo> = {
63
+ '@context': 'https://schema.org',
64
+ '@type': 'HowTo',
65
+ name: title,
66
+ description,
67
+ step: howToData.map((step, i) => ({
68
+ '@type': 'HowToStep',
69
+ position: i + 1,
70
+ name: step.name,
71
+ text: step.text,
72
+ })),
73
+ };
74
+
75
+ const appSchema: WithContext<SoftwareApplication> = {
76
+ '@context': 'https://schema.org',
77
+ '@type': 'SoftwareApplication',
78
+ name: title,
79
+ description,
80
+ applicationCategory: 'DeveloperApplication',
81
+ operatingSystem: 'All',
82
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' },
83
+ inLanguage: 'tr',
84
+ };
85
+
86
+ export const content: ToolLocaleContent<WebBluetoothBleScannerUI> = {
87
+ slug,
88
+ title,
89
+ description,
90
+ faq: faqData,
91
+ bibliography,
92
+ howTo: howToData,
93
+ schemas: [faqSchema, howToSchema, appSchema],
94
+ seo: [
95
+ {
96
+ type: 'title',
97
+ text: 'IoT, Giyilebilir Cihazlar ve Maker Donanımı için Çevrimiçi BLE Test Cihazı',
98
+ level: 2,
99
+ },
100
+ {
101
+ type: 'paragraph',
102
+ html: 'Bu Web Bluetooth tarayıcı, yakındaki bir Bluetooth Low Energy cihazının bir tarayıcıdan keşfedilebilir olup olmadığını ve izin verildikten sonra hangi GATT servislerini sunduğunu test etmenizi sağlar. ESP32 firmware, Arduino BLE taslakları, akıllı sensörler, fitness giyilebilirleri, klavyeler, özel işaretçiler, çevre monitörleri ve yerel bir mobil uygulama oluşturmadan önce prototip donanımın hata ayıklaması için kullanışlıdır.',
103
+ },
104
+ {
105
+ type: 'message',
106
+ title: 'Gizlilik modeli',
107
+ html: 'GameBob MAC adreslerini, cihaz kimliklerini, adları, UUIDleri, sinyal verilerini veya tarama geçmişini saklamaz. Tarayıcı izin seçicisi, sayfanın hangi tek cihaza erişebileceğine karar verir ve sonuçlar mevcut tarayıcı oturumunuzda kalır.',
108
+ },
109
+ {
110
+ type: 'table',
111
+ headers: ['Ne görüyorsunuz', 'Ne anlama geliyor', 'Sonraki adımda ne kontrol edilmeli'],
112
+ rows: [
113
+ ['Cihaz adı', 'Donanım bir ad yayınlıyorsa, tanıtılan Bluetooth adı.', 'Boşsa, firmware tanıtım verilerini kontrol edin veya test sırasında bilinen bir ad öneki kullanın.'],
114
+ ['Cihaz kimliği', 'Tarayıcı kapsamlı bir tanımlayıcı, gerçek genel MAC adresi değil.', 'Yalnızca bu tarayıcı oturumu için kullanın; evrensel bir donanım seri numarası olarak değerlendirmeyin.'],
115
+ ['GATT servis UUIDleri', 'Bağlantı kabul edildikten sonra sunulan servis grupları.', 'Standart UUIDleri Bluetooth SIG listesi veya firmware servis tablonuzla karşılaştırın.'],
116
+ ['Özel servis', 'Satıcıya veya projeye özgü bir UUID.', 'Özellikleri ve izinleri eşlemek için firmware\'inizi, mobil uygulama profilinizi veya BLE belgelerinizi açın.'],
117
+ ],
118
+ },
119
+ {
120
+ type: 'title',
121
+ text: 'Tarayıcı Bluetooth Taraması Neden Farklıdır',
122
+ level: 3,
123
+ },
124
+ {
125
+ type: 'paragraph',
126
+ html: 'Yerel BLE tarayıcı uygulamaları genellikle birçok yakın cihazdan sürekli tanıtımlar gösterir. Web Bluetooth kasıtlı olarak daha katıdır: sayfa güvenli bir bağlamda açılmalı, tarama bir kullanıcı tıklamasıyla başlamalı ve tarayıcı bir izin seçicisi gösterir. Bu, kullanıcıları sessiz izlemeden korurken geliştiricilere JavaScript\'ten seçili BLE donanımına bağlanmanın pratik bir yolunu sunar.',
127
+ },
128
+ {
129
+ type: 'comparative',
130
+ items: [
131
+ {
132
+ title: 'Web Bluetooth tarayıcı',
133
+ description: 'Hızlı firmware doğrulama, demolarda, destek akışlarında, sınıf laboratuvarlarında ve kurulum sürtünmesinin önemli olduğu tarayıcı tabanlı teşhisler için en iyisidir.',
134
+ },
135
+ {
136
+ title: 'Yerel BLE uygulaması',
137
+ description: 'Arka plan taraması, RSSI günlüğü, eşleştirme iş akışları, şifreli satıcı protokolleri, büyük özellik ağaçları ve uzun vadeli saha teşhisi için daha iyidir.',
138
+ },
139
+ ],
140
+ },
141
+ {
142
+ type: 'title',
143
+ text: 'Bir BLE Cihazının Görünmemesinin Yaygın Nedenleri',
144
+ level: 3,
145
+ },
146
+ {
147
+ type: 'list',
148
+ items: [
149
+ 'Bluetooth işletim sistemi düzeyinde devre dışı veya tarayıcının Bluetooth izni yok.',
150
+ 'Cihaz başka bir telefona, dizüstü bilgisayara, satıcı uygulamasına veya ağ geçidine bağlı ve tanıtım yapmayı durdurdu.',
151
+ 'Donanım yalnızca başlatmadan sonra veya bir eşleştirme düğmesine basıldıktan sonra kısa bir süre için tanıtım yapar.',
152
+ 'Tarayıcı Chromium tabanlı değil, sayfa HTTPS üzerinden sunulmuyor veya platform Web Bluetooth\'u engelliyor.',
153
+ 'Firmware üretici verilerini tanıtır ancak yerel adı gizler, bu nedenle seçici isimsiz bir cihaz gösterebilir.',
154
+ 'Cihaz, servisler okunabilir hale gelmeden önce eşleştirme, şifreleme veya özel kimlik doğrulama gerektirir.',
155
+ ],
156
+ },
157
+ {
158
+ type: 'title',
159
+ text: 'Hata Ayıklama Sırasında GATT UUIDleri Nasıl Kullanılır',
160
+ level: 3,
161
+ },
162
+ {
163
+ type: 'paragraph',
164
+ html: 'Servis UUIDleri ile başarılı bir bağlantı, tarayıcının çevre birimine ulaşabileceğini ve çevre biriminin GATT tablosunun en azından bir kısmını sunduğunu gösterir. Pil Servisi, Cihaz Bilgisi, Kalp Atış Hızı, İnsan Arayüz Cihazı ve Çevresel Algılama gibi standart servislerin tanınması kolaydır. Özel UUIDler genellikle firmware\'e özgü işlevlere işaret eder ve kaynak kodunuzdan veya satıcı belgelerinden özellik haritasına ihtiyaç duyar.',
165
+ },
166
+ {
167
+ type: 'table',
168
+ headers: ['Belirti', 'Olası neden', 'Pratik çözüm'],
169
+ rows: [
170
+ ['İzin seçici boş', 'Cihaz tanıtım yapmıyor veya tarayıcı desteği eksik.', 'Cihazı yeniden başlatın, eşleştirme modunu etkinleştirin, yaklaşın veya Chrome/Edge\'de tekrar deneyin.'],
171
+ ['Bağlantı hemen başarısız oluyor', 'Cihaz meşgul, menzil dışında veya tarayıcı bağlantısını reddediyor.', 'Satıcı uygulamalarını kesin ve çevre birimini bilgisayarın yakınında tutun.'],
172
+ ['Hiçbir servis listelenmiyor', 'GATT kullanılamıyor, servisler gizli veya bu UUIDler için erişim verilmedi.', 'Firmware testlerinde bilinen isteğe bağlı servisleri ekleyin veya yerel bir BLE aracıyla inceleyin.'],
173
+ ['Yalnızca özel UUIDler görünüyor', 'Donanım satıcıya özgü firmware servisleri kullanıyor.', 'UUIDleri kaynak kodu sabitleriyle eşleyin ve özelliklerin okuma/yazma izinlerini belgeleyin.'],
174
+ ],
175
+ },
176
+ {
177
+ type: 'title',
178
+ text: 'Güvenlik ve Gizlilik Sınırları',
179
+ level: 3,
180
+ },
181
+ {
182
+ type: 'list',
183
+ items: [
184
+ 'Sayfa, arka planda yakındaki Bluetooth cihazlarını sessizce toplayamaz.',
185
+ 'Tarayıcı gerçek MAC adreslerini gizleyebilir ve bunun yerine kapsamlı bir cihaz kimliği sağlayabilir.',
186
+ 'Erişim yalnızca kullanıcı tarama düğmesine tıkladıktan ve bir cihaz seçtikten sonra başlar.',
187
+ 'Sonuçlar GameBob tarafından yüklenmez veya saklanmaz.',
188
+ 'Hassas ticari cihazlar, bu genel tarayıcının atlayamayacağı şifreleme veya satıcı eşleştirme akışı gerektirebilir.',
189
+ ],
190
+ },
191
+ ],
192
+ ui: {
193
+ unsupportedTitle: 'Web Bluetooth kullanılamıyor',
194
+ unsupportedBody: 'Masaüstü veya Android\'de Chrome veya Edge\'i deneyin, Bluetooth\'u etkinleştirin ve sayfayı HTTPS veya localhost üzerinden açın.',
195
+ secureContext: 'Web Bluetooth güvenli bir HTTPS sayfası veya localhost gerektirir. Aracı güvenli bir kaynaktan yeniden yükleyin ve tekrar deneyin.',
196
+ scanButton: 'Ortamı Tara',
197
+ scanning: 'Taranıyor',
198
+ reconnect: 'Tekrar tara',
199
+ disconnect: 'Bağlantıyı kes',
200
+ privacyTitle: 'Tasarım gereği gizlilik',
201
+ privacyBody: 'GameBob MAC adreslerini, cihaz kimliklerini, adları, UUIDleri veya tarama geçmişini saklamaz. Tarayıcı yalnızca sizin seçtiğiniz cihazı sunar.',
202
+ deviceLabel: 'Seçilen cihaz',
203
+ nameFallback: 'İsimsiz BLE cihazı',
204
+ idLabel: 'Tarayıcı cihaz kimliği',
205
+ servicesLabel: 'GATT servisleri',
206
+ noServices: 'Bu bağlantı için okunabilir birincil servis döndürülmedi.',
207
+ statusIdle: 'Yakındaki BLE donanımını taramaya hazır',
208
+ statusPermission: 'Tarayıcı izin seçicisi bekleniyor',
209
+ statusConnecting: 'Seçilen BLE cihazına bağlanılıyor',
210
+ statusConnected: 'Bağlandı ve servisler yüklendi',
211
+ statusDisconnected: 'Cihaz bağlantısı kesildi',
212
+ statusCancelled: 'Hiçbir BLE cihazı seçilmedi veya bu cihazda Bluetooth kapalı/kullanılamıyor.',
213
+ statusUnavailable: 'Bluetooth bu cihazda kapalı, engellenmiş veya yok gibi görünüyor. Bluetooth\'u etkinleştirin veya BLE adaptörü olan bir donanımdan deneyin.',
214
+ statusError: 'Bluetooth taraması başarısız oldu',
215
+ signalUnknown: 'Sinyal gücü tarayıcı seçicisi tarafından kontrol edilir',
216
+ gattUnavailable: 'Bu cihaz tarayıcıya bir GATT sunucusu sunmadı',
217
+ customServiceName: 'Özel veya satıcıya özgü servis',
218
+ serviceGenericAccess: 'Genel Erişim',
219
+ serviceGenericAttribute: 'Genel Özellik',
220
+ serviceDeviceInformation: 'Cihaz Bilgisi',
221
+ serviceHeartRate: 'Kalp Atış Hızı',
222
+ serviceBattery: 'Pil Servisi',
223
+ serviceHumanInterfaceDevice: 'İnsan Arayüz Cihazı',
224
+ serviceCyclingSpeedCadence: 'Bisiklet Hızı ve Kadans',
225
+ serviceEnvironmentalSensing: 'Çevresel Algılama',
226
+ serviceUserData: 'Kullanıcı Verileri',
227
+ serviceFitnessMachine: 'Fitness Makinesi',
228
+ uuidHelp: 'UUIDler Bluetooth servislerini tanımlar. Standart servisler otomatik olarak adlandırılır; satıcıya özgü UUIDler firmware veya cihaz belgelerinize ihtiyaç duyar.',
229
+ compatibilityHint: 'Bluetooth etkinken Chromium tabanlı tarayıcılarda en iyi şekilde çalışır. Web Bluetooth kasıtlı olarak izin sınırlıdır ve yakındaki her tanıtıcıyı göstermeyebilir.',
230
+ serviceCountSingular: 'servis',
231
+ serviceCountPlural: 'servis',
232
+ },
233
+ };
@@ -0,0 +1,233 @@
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import type { ToolLocaleContent } from '../../../types';
3
+ import type { WebBluetoothBleScannerUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
5
+
6
+ const slug = 'web-bluetooth-ble-scanner';
7
+ const title = 'Web Bluetooth BLE 扫描器';
8
+ const description = '从浏览器扫描附近的蓝牙低功耗设备,检查暴露的 GATT 服务 UUID,并测试您的 IoT 或可穿戴硬件是否可被发现。';
9
+
10
+ const faqData = [
11
+ {
12
+ question: '网站可以未经许可扫描蓝牙设备吗?',
13
+ answer: '不可以。Web Bluetooth 始终需要用户手势和浏览器权限选择器。此工具只能看到您明确选择的设备,不会存储 MAC 地址、设备 ID 或扫描结果。',
14
+ },
15
+ {
16
+ question: '为什么扫描器不显示附近所有的 BLE 设备?',
17
+ answer: '浏览器有意通过权限选择器公开蓝牙,而不是作为静默后台扫描器。某些设备还会停止广播、隐藏名称、要求配对或仅在连接后才公开服务。',
18
+ },
19
+ {
20
+ question: '哪些浏览器支持 Web Bluetooth?',
21
+ answer: 'Web Bluetooth 在 Chrome 和 Edge 等基于 Chromium 的桌面浏览器中获得最佳支持。通常需要 HTTPS 或 localhost,在许多 Firefox、Safari 和 iOS 浏览器配置中不可用。',
22
+ },
23
+ {
24
+ question: '这能读取可穿戴设备的私有传感器数据吗?',
25
+ answer: '仅当设备公开兼容的 GATT 服务且浏览器授予访问权限时才可以。许多商用可穿戴设备需要厂商应用、加密、绑定或专有特性,通用浏览器扫描器无法解码。',
26
+ },
27
+ {
28
+ question: '什么是 GATT 服务 UUID?',
29
+ answer: 'GATT 服务 UUID 标识一组蓝牙低功耗功能,如电池服务、心率、设备信息或创客和 IoT 硬件使用的自定义厂商服务。',
30
+ },
31
+ ];
32
+
33
+ const howToData = [
34
+ {
35
+ name: '使用兼容的浏览器',
36
+ text: '在 Chrome 或 Edge 中通过 HTTPS 或 localhost 打开工具,然后确保计算机或手机上已启用蓝牙。',
37
+ },
38
+ {
39
+ name: '将硬件置于广播模式',
40
+ text: '唤醒 BLE 设备,重新上电,按下配对按钮或打开其广播模式,使其出现在浏览器权限选择器中。',
41
+ },
42
+ {
43
+ name: '扫描环境',
44
+ text: '按下扫描环境并选择要检查的 BLE 设备。浏览器权限对话框精确控制哪个设备对页面可见。',
45
+ },
46
+ {
47
+ name: '读取 GATT 服务',
48
+ text: '连接后,查看服务 UUID 卡片以识别标准蓝牙配置文件、自定义固件服务以及设备是否公开了您期望的数据路径。',
49
+ },
50
+ ];
51
+
52
+ const faqSchema: WithContext<FAQPage> = {
53
+ '@context': 'https://schema.org',
54
+ '@type': 'FAQPage',
55
+ mainEntity: faqData.map((item) => ({
56
+ '@type': 'Question',
57
+ name: item.question,
58
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
59
+ })),
60
+ };
61
+
62
+ const howToSchema: WithContext<HowTo> = {
63
+ '@context': 'https://schema.org',
64
+ '@type': 'HowTo',
65
+ name: title,
66
+ description,
67
+ step: howToData.map((step, i) => ({
68
+ '@type': 'HowToStep',
69
+ position: i + 1,
70
+ name: step.name,
71
+ text: step.text,
72
+ })),
73
+ };
74
+
75
+ const appSchema: WithContext<SoftwareApplication> = {
76
+ '@context': 'https://schema.org',
77
+ '@type': 'SoftwareApplication',
78
+ name: title,
79
+ description,
80
+ applicationCategory: 'DeveloperApplication',
81
+ operatingSystem: 'All',
82
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'USD' },
83
+ inLanguage: 'zh',
84
+ };
85
+
86
+ export const content: ToolLocaleContent<WebBluetoothBleScannerUI> = {
87
+ slug,
88
+ title,
89
+ description,
90
+ faq: faqData,
91
+ bibliography,
92
+ howTo: howToData,
93
+ schemas: [faqSchema, howToSchema, appSchema],
94
+ seo: [
95
+ {
96
+ type: 'title',
97
+ text: '适用于 IoT、可穿戴设备和创客硬件的在线 BLE 测试器',
98
+ level: 2,
99
+ },
100
+ {
101
+ type: 'paragraph',
102
+ html: '此 Web Bluetooth 扫描器可让您测试附近的蓝牙低功耗设备是否可从浏览器发现,以及授予权限后公开了哪些 GATT 服务。在调试 ESP32 固件、Arduino BLE 草图、智能传感器、健身可穿戴设备、键盘、自定义信标、环境监测器和原型硬件时非常有用,无需先构建原生移动应用。',
103
+ },
104
+ {
105
+ type: 'message',
106
+ title: '隐私模型',
107
+ html: 'GameBob 不会存储 MAC 地址、设备 ID、名称、UUID、信号数据或扫描历史记录。浏览器权限选择器决定页面可以访问哪个单一设备,结果保留在当前浏览器会话中。',
108
+ },
109
+ {
110
+ type: 'table',
111
+ headers: ['您看到的内容', '含义', '下一步检查'],
112
+ rows: [
113
+ ['设备名称', '硬件广播的蓝牙名称(如果有)。', '如果为空,请检查固件广播数据或在测试期间使用已知的名称前缀。'],
114
+ ['设备 ID', '浏览器范围的标识符,而非原始公共 MAC 地址。', '仅用于此浏览器会话;不要将其视为通用硬件序列号。'],
115
+ ['GATT 服务 UUID', '接受连接后公开的服务组。', '将标准 UUID 与 Bluetooth SIG 列表或您的固件服务表进行对比。'],
116
+ ['自定义服务', '厂商特定或项目特定的 UUID。', '打开您的固件、移动应用配置文件或 BLE 文档以映射特性和权限。'],
117
+ ],
118
+ },
119
+ {
120
+ type: 'title',
121
+ text: '为什么浏览器蓝牙扫描有所不同',
122
+ level: 3,
123
+ },
124
+ {
125
+ type: 'paragraph',
126
+ html: '原生 BLE 扫描器应用通常显示来自许多附近设备的连续广播。Web Bluetooth 有意更加严格:页面必须在安全上下文中打开,扫描必须从用户点击启动,浏览器显示权限选择器。这保护用户免受静默跟踪,同时为开发人员提供了从 JavaScript 连接到选定 BLE 硬件的实用方式。',
127
+ },
128
+ {
129
+ type: 'comparative',
130
+ items: [
131
+ {
132
+ title: 'Web Bluetooth 扫描器',
133
+ description: '最适合快速固件验证、演示、支持流程、课堂实验室和安装摩擦重要的基于浏览器的诊断。',
134
+ },
135
+ {
136
+ title: '原生 BLE 应用',
137
+ description: '更适合后台扫描、RSSI 记录、配对工作流、加密厂商协议、大型特性树和长期现场诊断。',
138
+ },
139
+ ],
140
+ },
141
+ {
142
+ type: 'title',
143
+ text: 'BLE 设备不出现的常见原因',
144
+ level: 3,
145
+ },
146
+ {
147
+ type: 'list',
148
+ items: [
149
+ '蓝牙在操作系统级别已禁用,或浏览器没有蓝牙权限。',
150
+ '设备已连接到其他手机、笔记本电脑、厂商应用或网关,并已停止广播。',
151
+ '硬件仅在启动后或按下配对按钮后的短暂窗口期内广播。',
152
+ '浏览器不基于 Chromium,页面未通过 HTTPS 提供,或平台阻止了 Web Bluetooth。',
153
+ '固件广播制造商数据但隐藏了本地名称,因此选择器可能显示未命名设备。',
154
+ '设备需要绑定、加密或专有身份验证,服务才能可读。',
155
+ ],
156
+ },
157
+ {
158
+ type: 'title',
159
+ text: '调试期间如何使用 GATT UUID',
160
+ level: 3,
161
+ },
162
+ {
163
+ type: 'paragraph',
164
+ html: '服务 UUID 连接成功表示浏览器可以访问外设,并且外设至少公开了其 GATT 表的一部分。标准服务如电池服务、设备信息、心率、人机接口设备和环境感知很容易识别。自定义 UUID 通常指向固件特定功能,需要源代码或厂商文档中的特性映射。',
165
+ },
166
+ {
167
+ type: 'table',
168
+ headers: ['症状', '可能原因', '实用解决方案'],
169
+ rows: [
170
+ ['权限选择器为空', '设备未广播或缺少浏览器支持。', '重启设备,启用配对模式,靠近或在 Chrome/Edge 中重试。'],
171
+ ['连接立即失败', '设备忙碌、超出范围或拒绝浏览器连接。', '断开厂商应用并将外设靠近计算机。'],
172
+ ['未列出服务', 'GATT 不可用,服务被隐藏,或未授予这些 UUID 的访问权限。', '在固件测试中添加已知的可选服务,或使用原生 BLE 工具检查。'],
173
+ ['仅出现自定义 UUID', '硬件使用厂商特定的固件服务。', '将 UUID 映射到源代码常量并记录特性的读/写权限。'],
174
+ ],
175
+ },
176
+ {
177
+ type: 'title',
178
+ text: '安全与隐私限制',
179
+ level: 3,
180
+ },
181
+ {
182
+ type: 'list',
183
+ items: [
184
+ '页面无法在后台静默收集附近的蓝牙设备。',
185
+ '浏览器可能隐藏真实 MAC 地址,提供范围化的设备 ID。',
186
+ '访问仅在用户点击扫描按钮并选择设备后才开始。',
187
+ '结果不会被 GameBob 上传或存储。',
188
+ '敏感的商用设备可能需要加密或厂商配对流程,此通用扫描器无法绕过。',
189
+ ],
190
+ },
191
+ ],
192
+ ui: {
193
+ unsupportedTitle: 'Web Bluetooth 不可用',
194
+ unsupportedBody: '在桌面或 Android 上尝试 Chrome 或 Edge,启用蓝牙并通过 HTTPS 或 localhost 打开页面。',
195
+ secureContext: 'Web Bluetooth 需要安全的 HTTPS 页面或 localhost。从安全来源重新加载工具并重试。',
196
+ scanButton: '扫描环境',
197
+ scanning: '扫描中',
198
+ reconnect: '重新扫描',
199
+ disconnect: '断开连接',
200
+ privacyTitle: '设计即隐私',
201
+ privacyBody: 'GameBob 不会存储 MAC 地址、设备 ID、名称、UUID 或扫描历史记录。浏览器仅公开您选择的设备。',
202
+ deviceLabel: '已选设备',
203
+ nameFallback: '未命名 BLE 设备',
204
+ idLabel: '浏览器设备 ID',
205
+ servicesLabel: 'GATT 服务',
206
+ noServices: '此连接未返回可读的主服务。',
207
+ statusIdle: '准备扫描附近 BLE 硬件',
208
+ statusPermission: '等待浏览器权限选择器',
209
+ statusConnecting: '正在连接到选定的 BLE 设备',
210
+ statusConnected: '已连接并加载服务',
211
+ statusDisconnected: '设备已断开连接',
212
+ statusCancelled: '未选择 BLE 设备,或此设备上蓝牙已关闭/不可用。',
213
+ statusUnavailable: '此设备上蓝牙似乎已关闭、被阻止或不存在。启用蓝牙或从具有 BLE 适配器的硬件尝试。',
214
+ statusError: '蓝牙扫描失败',
215
+ signalUnknown: '信号强度由浏览器选择器控制',
216
+ gattUnavailable: '此设备未向浏览器公开 GATT 服务器',
217
+ customServiceName: '自定义或厂商特定服务',
218
+ serviceGenericAccess: '通用访问',
219
+ serviceGenericAttribute: '通用属性',
220
+ serviceDeviceInformation: '设备信息',
221
+ serviceHeartRate: '心率',
222
+ serviceBattery: '电池服务',
223
+ serviceHumanInterfaceDevice: '人机接口设备',
224
+ serviceCyclingSpeedCadence: '骑行速度与踏频',
225
+ serviceEnvironmentalSensing: '环境感知',
226
+ serviceUserData: '用户数据',
227
+ serviceFitnessMachine: '健身器材',
228
+ uuidHelp: 'UUID 标识蓝牙服务。标准服务自动命名;厂商特定 UUID 需要您的固件或设备文档。',
229
+ compatibilityHint: '在启用蓝牙的 Chromium 浏览器中效果最佳。Web Bluetooth 有意受权限限制,可能不会显示所有附近的广播者。',
230
+ serviceCountSingular: '个服务',
231
+ serviceCountPlural: '个服务',
232
+ },
233
+ };
@@ -0,0 +1,11 @@
1
+ import { webBluetoothBleScanner } from './entry';
2
+ import type { ToolDefinition } from '../../types';
3
+
4
+ export * from './entry';
5
+
6
+ export const WEB_BLUETOOTH_BLE_SCANNER_TOOL: ToolDefinition = {
7
+ entry: webBluetoothBleScanner,
8
+ Component: () => import('./component.astro'),
9
+ SEOComponent: () => import('./seo.astro'),
10
+ BibliographyComponent: () => import('./bibliography.astro'),
11
+ };
@@ -0,0 +1,79 @@
1
+ export interface BleServiceSummary {
2
+ uuid: string;
3
+ name: string;
4
+ }
5
+
6
+ export interface BleDeviceSummary {
7
+ name: string;
8
+ id: string;
9
+ connected: boolean;
10
+ services: BleServiceSummary[];
11
+ }
12
+
13
+ export interface BleDeviceSummaryInput {
14
+ name: string;
15
+ id: string;
16
+ connected: boolean;
17
+ serviceUuids: string[];
18
+ labels: BleServiceLabels;
19
+ }
20
+
21
+ export interface BleServiceLabels {
22
+ customServiceName: string;
23
+ serviceGenericAccess: string;
24
+ serviceGenericAttribute: string;
25
+ serviceDeviceInformation: string;
26
+ serviceHeartRate: string;
27
+ serviceBattery: string;
28
+ serviceHumanInterfaceDevice: string;
29
+ serviceCyclingSpeedCadence: string;
30
+ serviceEnvironmentalSensing: string;
31
+ serviceUserData: string;
32
+ serviceFitnessMachine: string;
33
+ }
34
+
35
+ export const optionalBleServices = [
36
+ 'generic_access',
37
+ 'generic_attribute',
38
+ 'device_information',
39
+ 'battery_service',
40
+ 'heart_rate',
41
+ 'human_interface_device',
42
+ 'cycling_speed_and_cadence',
43
+ 'environmental_sensing',
44
+ 'user_data',
45
+ 'fitness_machine',
46
+ ];
47
+
48
+ export function normalizeBleUuid(uuid: string): string {
49
+ return uuid.toLowerCase();
50
+ }
51
+
52
+ export function describeBleService(uuid: string, labels: BleServiceLabels): string {
53
+ const knownServices: Record<string, string> = {
54
+ '00001800-0000-1000-8000-00805f9b34fb': labels.serviceGenericAccess,
55
+ '00001801-0000-1000-8000-00805f9b34fb': labels.serviceGenericAttribute,
56
+ '0000180a-0000-1000-8000-00805f9b34fb': labels.serviceDeviceInformation,
57
+ '0000180d-0000-1000-8000-00805f9b34fb': labels.serviceHeartRate,
58
+ '0000180f-0000-1000-8000-00805f9b34fb': labels.serviceBattery,
59
+ '00001812-0000-1000-8000-00805f9b34fb': labels.serviceHumanInterfaceDevice,
60
+ '00001816-0000-1000-8000-00805f9b34fb': labels.serviceCyclingSpeedCadence,
61
+ '0000181a-0000-1000-8000-00805f9b34fb': labels.serviceEnvironmentalSensing,
62
+ '0000181c-0000-1000-8000-00805f9b34fb': labels.serviceUserData,
63
+ '00001826-0000-1000-8000-00805f9b34fb': labels.serviceFitnessMachine,
64
+ };
65
+
66
+ return knownServices[normalizeBleUuid(uuid)] ?? labels.customServiceName;
67
+ }
68
+
69
+ export function summarizeBleDevice(input: BleDeviceSummaryInput): BleDeviceSummary {
70
+ return {
71
+ name: input.name,
72
+ id: input.id,
73
+ connected: input.connected,
74
+ services: input.serviceUuids.map((uuid) => ({
75
+ uuid,
76
+ name: describeBleService(uuid, input.labels),
77
+ })),
78
+ };
79
+ }
@@ -0,0 +1,15 @@
1
+ ---
2
+ import { SEORenderer } from '@jjlmoya/utils-shared';
3
+ import { webBluetoothBleScanner } from './index';
4
+ import type { KnownLocale } from '../../types';
5
+
6
+ interface Props {
7
+ locale?: KnownLocale;
8
+ }
9
+
10
+ const { locale = 'en' } = Astro.props;
11
+ const content = await webBluetoothBleScanner.i18n[locale]?.();
12
+ if (!content) return null;
13
+ ---
14
+
15
+ {content.seo?.length > 0 && <SEORenderer content={{ locale, sections: content.seo }} />}
@@ -0,0 +1,41 @@
1
+ export interface WebBluetoothBleScannerUI extends Record<string, string> {
2
+ unsupportedTitle: string;
3
+ unsupportedBody: string;
4
+ secureContext: string;
5
+ scanButton: string;
6
+ scanning: string;
7
+ reconnect: string;
8
+ disconnect: string;
9
+ privacyTitle: string;
10
+ privacyBody: string;
11
+ deviceLabel: string;
12
+ nameFallback: string;
13
+ idLabel: string;
14
+ servicesLabel: string;
15
+ noServices: string;
16
+ statusIdle: string;
17
+ statusPermission: string;
18
+ statusConnecting: string;
19
+ statusConnected: string;
20
+ statusDisconnected: string;
21
+ statusCancelled: string;
22
+ statusUnavailable: string;
23
+ statusError: string;
24
+ signalUnknown: string;
25
+ gattUnavailable: string;
26
+ customServiceName: string;
27
+ serviceGenericAccess: string;
28
+ serviceGenericAttribute: string;
29
+ serviceDeviceInformation: string;
30
+ serviceHeartRate: string;
31
+ serviceBattery: string;
32
+ serviceHumanInterfaceDevice: string;
33
+ serviceCyclingSpeedCadence: string;
34
+ serviceEnvironmentalSensing: string;
35
+ serviceUserData: string;
36
+ serviceFitnessMachine: string;
37
+ uuidHelp: string;
38
+ compatibilityHint: string;
39
+ serviceCountSingular: string;
40
+ serviceCountPlural: string;
41
+ }