Showing 11 changed files with 222 additions and 16 deletions
+0 -0
Platform Decision - iOS 15.md → Documentation/Platform Decision - iOS 15.md
File renamed without changes.
+47 -0
Documentation/Project History.md
@@ -0,0 +1,47 @@
1
+# Project History
2
+
3
+## Origin
4
+
5
+This project started as a proof of concept for reverse engineering three Bluetooth-enabled USB meters sold under the Ruideng name:
6
+
7
+- `UM25(C) V2.0`
8
+- `UM34(C) V2.3`
9
+- `TC-66C`
10
+
11
+## Initial Goal
12
+
13
+The original goal was to discover how these devices expose their data over Bluetooth and to build a working software prototype capable of reading and displaying that data.
14
+
15
+## Progress Reached
16
+
17
+The project progressed to the point where data could be obtained from the devices.
18
+
19
+At that stage, active work stopped.
20
+
21
+## Current Knowledge Gaps
22
+
23
+At this point, the exact status of the reverse engineering effort is not fully known:
24
+
25
+- it is not clear which payload fields were fully decoded
26
+- it is not clear which payload fields remain unknown
27
+- it is not clear how complete the protocol understanding is for each model
28
+
29
+The project code itself is now the main surviving reference for what was achieved.
30
+
31
+## Available Resources
32
+
33
+The original external research resources are no longer available, except for what is already included in this repository.
34
+
35
+Because of that, the project should treat the existing source code and notes as the baseline for rebuilding protocol knowledge.
36
+
37
+## Current Direction
38
+
39
+The next stage is not to restart reverse engineering from scratch, but to document what is already present in the codebase and collect newly discovered materials in a structured way.
40
+
41
+That includes:
42
+
43
+- manuals
44
+- specifications
45
+- payload observations
46
+- protocol notes
47
+- reverse engineering findings for each supported meter model
+5 -0
Documentation/README.md
@@ -0,0 +1,5 @@
1
+# Documentation
2
+
3
+This folder contains project notes, platform decisions, and collected reverse engineering material.
4
+
5
+It is intended to keep the repository root focused on the app itself while preserving project context in one dedicated place.
+9 -0
Documentation/Research Resources/Manuals/README.md
@@ -0,0 +1,9 @@
1
+# Manuals
2
+
3
+Place product manuals, user guides, or archived copies of vendor documentation here.
4
+
5
+Recommended naming:
6
+
7
+- include model name
8
+- include version or revision when known
9
+- include source and date when possible
+19 -0
Documentation/Research Resources/Payload Notes/README.md
@@ -0,0 +1,19 @@
1
+# Payload Notes
2
+
3
+Use this folder for protocol-level findings.
4
+
5
+Examples:
6
+
7
+- packet captures
8
+- field maps
9
+- command and response notes
10
+- unknown byte ranges
11
+- per-model payload differences
12
+
13
+For each note, prefer recording:
14
+
15
+- model
16
+- firmware or hardware revision if known
17
+- sample payload
18
+- decoded meaning
19
+- confidence level
+19 -0
Documentation/Research Resources/README.md
@@ -0,0 +1,19 @@
1
+# Research Resources
2
+
3
+This folder is reserved for external and internal technical material gathered after the original proof-of-concept phase.
4
+
5
+Use it to collect:
6
+
7
+- manuals
8
+- vendor specifications
9
+- screenshots or extracts of device information
10
+- protocol notes
11
+- payload descriptions
12
+- decoded and undecoded field mappings
13
+- references to related external projects
14
+
15
+Suggested rule:
16
+
17
+- keep raw source material close to its origin
18
+- keep interpretation notes in Markdown
19
+- prefer small focused notes over large mixed documents
+3 -0
Documentation/Research Resources/Related Projects/README.md
@@ -0,0 +1,3 @@
1
+# Related Projects
2
+
3
+This folder tracks external projects that may help reconstruct protocol knowledge or validate naming and decoding choices.
+57 -0
Documentation/Research Resources/Related Projects/floriandotorg-um24c.md
@@ -0,0 +1,57 @@
1
+# floriandotorg/um24c
2
+
3
+Repository:
4
+
5
+- https://github.com/floriandotorg/um24c
6
+
7
+## Why it matters
8
+
9
+This appears to be a contemporary external project focused on the same family of Bluetooth USB power meters.
10
+
11
+It is relevant because it covers:
12
+
13
+- `UM24C`
14
+- `UM25C`
15
+- `UM34C`
16
+
17
+These overlap substantially with the devices targeted by this project.
18
+
19
+## Quick Notes
20
+
21
+From a quick inspection, the project appears to be a web UI built around Web Bluetooth and live plotting.
22
+
23
+Potentially useful areas:
24
+
25
+- model naming conventions
26
+- field naming choices
27
+- unit scaling assumptions
28
+- decoded status values
29
+- command / payload interpretation hints
30
+- UI ideas for live data presentation
31
+
32
+## Observations From Initial Review
33
+
34
+- The repository describes itself as a web UI for `UM24C/UM25C/UM34C` power meters.
35
+- It uses a JavaScript frontend rather than native iOS code.
36
+- It includes explicit model mappings such as:
37
+  - `0x0963 -> UM24C`
38
+  - `0x09c9 -> UM25C`
39
+  - `0x0d4c -> UM34C`
40
+- It also includes a charging mode map with values such as `QC2`, `QC3`, `DCP1.5A`, and `SAMSUNG`.
41
+
42
+## Limits
43
+
44
+- It does not appear to target `TC-66C`.
45
+- It should be treated as a secondary reference, not as ground truth.
46
+- Any payload interpretation borrowed from it should be validated against our own code and captures.
47
+
48
+## Suggested Use
49
+
50
+Use this project mainly for:
51
+
52
+- terminology alignment
53
+- comparison of decoded fields
54
+- cross-checking known model identifiers
55
+- identifying gaps in our current understanding
56
+
57
+Avoid assuming protocol equivalence without validation.
+10 -0
Documentation/Research Resources/Specifications/README.md
@@ -0,0 +1,10 @@
1
+# Specifications
2
+
3
+Place technical specifications, hardware notes, BLE service descriptions, and device capability summaries here.
4
+
5
+Useful content for this folder:
6
+
7
+- radio module details
8
+- service and characteristic UUID notes
9
+- device version comparisons
10
+- hardware revisions
+0 -11
Readme.rtf
@@ -1,11 +0,0 @@
1
-{\rtf1\ansi\ansicpg1252\cocoartf2511
2
-\cocoatextscaling0\cocoaplatform0{\fonttbl\f0\froman\fcharset0 Times-Roman;\f1\fswiss\fcharset0 ArialMT;}
3
-{\colortbl;\red255\green255\blue255;}
4
-{\*\expandedcolortbl;;}
5
-\paperw12240\paperh15840\margl1440\margr1440\vieww9000\viewh8400\viewkind0
6
-\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\partightenfactor0
7
-
8
-\f0\fs24 \cf0 Documenting code\
9
- {\field{\*\fldinst{HYPERLINK "https://sarunw.com/posts/swift-documentation/"}}{\fldrslt https://sarunw.com/posts/swift-documentation/}}\
10
-{\field{\*\fldinst{HYPERLINK "https://developer.apple.com/library/content/documentation/Xcode/Reference/xcode_markup_formatting_ref/Links.html#//apple_ref/doc/uid/TP40016497-CH18-SW1"}}{\fldrslt 
11
-\f1\fs30 https://developer.apple.com/library/content/documentation/Xcode/Reference/xcode_markup_formatting_ref/Links.html#//apple_ref/doc/uid/TP40016497-CH18-SW1}}}
+53 -5
USB Meter.xcodeproj/project.pbxproj
@@ -21,7 +21,6 @@
21 21
 		43567FE92443AD7C00000282 /* ICloudDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43567FE82443AD7C00000282 /* ICloudDefault.swift */; };
22 22
 		4360A34D241CBB3800B464F9 /* RSSIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4360A34C241CBB3800B464F9 /* RSSIView.swift */; };
23 23
 		4360A34F241D5CF100B464F9 /* MeterSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4360A34E241D5CF100B464F9 /* MeterSettingsView.swift */; };
24
-		437AEE1524249AAA0025C373 /* Readme.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 437AEE1424249AAA0025C373 /* Readme.rtf */; };
25 24
 		437D47D12415F91B00B7768E /* LiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437D47D02415F91B00B7768E /* LiveView.swift */; };
26 25
 		437D47D32415FB7E00B7768E /* Decimal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437D47D22415FB7E00B7768E /* Decimal.swift */; };
27 26
 		437D47D52415FD8C00B7768E /* RecordingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437D47D42415FD8C00B7768E /* RecordingView.swift */; };
@@ -53,7 +52,13 @@
53 52
 /* End PBXBuildFile section */
54 53
 
55 54
 /* Begin PBXFileReference section */
55
+		1C6B6B942A2D4F5100A0B001 /* Documentation README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
56 56
 		1C6B6B8A2A2D4F5100A0B001 /* Platform Decision - iOS 15.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "Platform Decision - iOS 15.md"; sourceTree = "<group>"; };
57
+		1C6B6B8B2A2D4F5100A0B001 /* Project History.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = "Project History.md"; sourceTree = "<group>"; };
58
+		1C6B6B8D2A2D4F5100A0B001 /* Research Resources README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
59
+		1C6B6B8F2A2D4F5100A0B001 /* Manuals README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
60
+		1C6B6B912A2D4F5100A0B001 /* Specifications README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
61
+		1C6B6B932A2D4F5100A0B001 /* Payload Notes README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
57 62
 		4308CF8524176CAB0002E80B /* DataGroupRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataGroupRowView.swift; sourceTree = "<group>"; };
58 63
 		4308CF872417770D0002E80B /* DataGroupsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataGroupsView.swift; sourceTree = "<group>"; };
59 64
 		430CB4FB245E07EB006525C2 /* ChevronView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChevronView.swift; sourceTree = "<group>"; };
@@ -67,7 +72,6 @@
67 72
 		43567FE82443AD7C00000282 /* ICloudDefault.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ICloudDefault.swift; sourceTree = "<group>"; };
68 73
 		4360A34C241CBB3800B464F9 /* RSSIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RSSIView.swift; sourceTree = "<group>"; };
69 74
 		4360A34E241D5CF100B464F9 /* MeterSettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeterSettingsView.swift; sourceTree = "<group>"; };
70
-		437AEE1424249AAA0025C373 /* Readme.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Readme.rtf; sourceTree = "<group>"; };
71 75
 		437D47D02415F91B00B7768E /* LiveView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LiveView.swift; sourceTree = "<group>"; };
72 76
 		437D47D22415FB7E00B7768E /* Decimal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Decimal.swift; sourceTree = "<group>"; };
73 77
 		437D47D42415FD8C00B7768E /* RecordingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordingView.swift; sourceTree = "<group>"; };
@@ -113,6 +117,52 @@
113 117
 /* End PBXFrameworksBuildPhase section */
114 118
 
115 119
 /* Begin PBXGroup section */
120
+		1C6B6B952A2D4F5100A0B001 /* Documentation */ = {
121
+			isa = PBXGroup;
122
+			children = (
123
+				1C6B6B942A2D4F5100A0B001 /* Documentation README.md */,
124
+				1C6B6B8A2A2D4F5100A0B001 /* Platform Decision - iOS 15.md */,
125
+				1C6B6B8B2A2D4F5100A0B001 /* Project History.md */,
126
+				1C6B6B8C2A2D4F5100A0B001 /* Research Resources */,
127
+			);
128
+			path = Documentation;
129
+			sourceTree = "<group>";
130
+		};
131
+		1C6B6B8C2A2D4F5100A0B001 /* Research Resources */ = {
132
+			isa = PBXGroup;
133
+			children = (
134
+				1C6B6B8D2A2D4F5100A0B001 /* Research Resources README.md */,
135
+				1C6B6B8E2A2D4F5100A0B001 /* Manuals */,
136
+				1C6B6B902A2D4F5100A0B001 /* Specifications */,
137
+				1C6B6B922A2D4F5100A0B001 /* Payload Notes */,
138
+			);
139
+			path = "Research Resources";
140
+			sourceTree = "<group>";
141
+		};
142
+		1C6B6B8E2A2D4F5100A0B001 /* Manuals */ = {
143
+			isa = PBXGroup;
144
+			children = (
145
+				1C6B6B8F2A2D4F5100A0B001 /* Manuals README.md */,
146
+			);
147
+			path = Manuals;
148
+			sourceTree = "<group>";
149
+		};
150
+		1C6B6B902A2D4F5100A0B001 /* Specifications */ = {
151
+			isa = PBXGroup;
152
+			children = (
153
+				1C6B6B912A2D4F5100A0B001 /* Specifications README.md */,
154
+			);
155
+			path = Specifications;
156
+			sourceTree = "<group>";
157
+		};
158
+		1C6B6B922A2D4F5100A0B001 /* Payload Notes */ = {
159
+			isa = PBXGroup;
160
+			children = (
161
+				1C6B6B932A2D4F5100A0B001 /* Payload Notes README.md */,
162
+			);
163
+			path = "Payload Notes";
164
+			sourceTree = "<group>";
165
+		};
116 166
 		4308CF89241777130002E80B /* Data Groups */ = {
117 167
 			isa = PBXGroup;
118 168
 			children = (
@@ -183,8 +233,7 @@
183 233
 		43CBF653240BF3EB00255B8B = {
184 234
 			isa = PBXGroup;
185 235
 			children = (
186
-				1C6B6B8A2A2D4F5100A0B001 /* Platform Decision - iOS 15.md */,
187
-				437AEE1424249AAA0025C373 /* Readme.rtf */,
236
+				1C6B6B952A2D4F5100A0B001 /* Documentation */,
188 237
 				43CBF65E240BF3EB00255B8B /* USB Meter */,
189 238
 				43CBF65D240BF3EB00255B8B /* Products */,
190 239
 				4347F01B28D717C1007EE7B1 /* Frameworks */,
@@ -335,7 +384,6 @@
335 384
 			files = (
336 385
 				43CBF66F240BF3ED00255B8B /* LaunchScreen.storyboard in Resources */,
337 386
 				43CBF66C240BF3ED00255B8B /* Preview Assets.xcassets in Resources */,
338
-				437AEE1524249AAA0025C373 /* Readme.rtf in Resources */,
339 387
 				43CBF669240BF3ED00255B8B /* Assets.xcassets in Resources */,
340 388
 			);
341 389
 			runOnlyForDeploymentPostprocessing = 0;