Skip to content

Commit 2447d9f

Browse files
committed
Add CSV validation warnings and example CSV files
Signed-off-by: Pranav-0440 <pranavghorpade61@gmail.com>
1 parent 62ed950 commit 2447d9f

8 files changed

Lines changed: 397 additions & 368 deletions

File tree

doc/examples/csv/README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# CSV Import Examples
2+
3+
This directory contains example CSV files for testing the CSV import functionality in EditDor.
4+
5+
## Files
6+
7+
### `valid.csv`
8+
A valid CSV file with correct data types and Modbus entities. This file should import without warnings.
9+
10+
**Valid Types:**
11+
- `number`
12+
- `string`
13+
- `boolean`
14+
15+
**Valid Modbus Entities:**
16+
- `HoldingRegister`
17+
- `InputRegister`
18+
- `Coil`
19+
- `DiscreteInput`
20+
21+
### `invalid.csv`
22+
A CSV file with intentional validation errors to demonstrate the warning system. When imported, this file will trigger the following warnings:
23+
24+
1. **Row 2, type**: `number123` is invalid (should be `number`, `string`, or `boolean`)
25+
2. **Row 2, modbus:entity**: `holdingregister` is invalid (case-sensitive, should be `HoldingRegister`)
26+
3. **Row 3, modbus:entity**: `InvalidRegister` is not a recognized Modbus entity
27+
4. **Row 4, type**: `invalid_type` is not a valid type
28+
5. **Row 5, modbus:entity**: `coil` is invalid (case-sensitive, should be `Coil`)
29+
30+
## Usage
31+
32+
1. Open EditDor
33+
2. Select "Thing Description" or "Thing Model"
34+
3. Click "Load a CSV File"
35+
4. Select either `valid.csv` or `invalid.csv`
36+
5. Observe the results:
37+
- `valid.csv`: Should load successfully without warnings
38+
- `invalid.csv`: Should display validation warnings but still load the data
39+
40+
## CSV Format
41+
42+
Required columns:
43+
- `name`: Property name (required)
44+
- `type`: Data type (number, string, or boolean)
45+
- `modbus:entity`: Modbus entity type
46+
- `modbus:address`: Modbus address (required)
47+
- `modbus:unitID`: Modbus unit ID
48+
- `modbus:quantity`: Number of registers
49+
- `modbus:zeroBasedAddressing`: Boolean (true/false)
50+
- `modbus:function`: Modbus function code
51+
- `modbus:mostSignificantByte`: Boolean (true/false)
52+
- `modbus:mostSignificantWord`: Boolean (true/false)
53+
- `href`: Property endpoint path
54+
55+
Note: The validation is case-insensitive for Modbus entities, so `coil`, `Coil`, and `COIL` are all treated as equivalent.

doc/examples/csv/invalid.csv

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name,type,modbus:entity,modbus:address,modbus:unitID,modbus:quantity,modbus:zeroBasedAddressing,modbus:function,modbus:mostSignificantByte,modbus:mostSignificantWord,href
2+
temp1,number123,holdingregister,40001,1,1,false,03,true,false,/temp
3+
humidity,number,InvalidRegister,40002,1,1,false,04,false,false,/humidity
4+
pressure,invalid_type,HoldingRegister,40003,1,2,true,03,true,true,/pressure
5+
status,string,coil,00001,1,1,false,01,false,false,/status
6+
alarm,boolean,DiscreteInput,10001,1,1,false,02,false,false,/alarm

doc/examples/csv/valid.csv

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name,type,modbus:entity,modbus:address,modbus:unitID,modbus:quantity,modbus:zeroBasedAddressing,modbus:function,modbus:mostSignificantByte,modbus:mostSignificantWord,href
2+
temperature,number,HoldingRegister,40001,1,1,false,03,true,false,/temp
3+
humidity,number,InputRegister,40002,1,1,false,04,false,false,/humidity
4+
pressure,number,HoldingRegister,40003,1,2,true,03,true,true,/pressure
5+
status,boolean,Coil,00001,1,1,false,01,false,false,/status
6+
alarm,boolean,DiscreteInput,10001,1,1,false,02,false,false,/alarm

src/components/App/CreateTd.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,24 @@ const CreateTd: React.FC<CreateTdProps> = ({
8585
throw new Error("CSV file is empty.");
8686
}
8787

88-
const data = parseCsv(csvContent, true);
88+
const { data, warnings } = parseCsv(csvContent, true);
8989

9090
const parsed = mapCsvToProperties(data);
9191
if (!parsed || Object.keys(parsed).length === 0) {
9292
throw new Error("No valid properties found in the CSV file.");
9393
}
9494

9595
setProperties(parsed);
96-
setError({ open: false, message: "" });
96+
97+
// Display warnings if any
98+
if (warnings.length > 0) {
99+
const warningMessage = warnings
100+
.map((w) => `Row ${w.row}, column "${w.column}": ${w.message}`)
101+
.join("\n");
102+
setError({ open: true, message: `Warnings:\n${warningMessage}` });
103+
} else {
104+
setError({ open: false, message: "" });
105+
}
97106
} catch (err) {
98107
setProperties({});
99108
setError({

0 commit comments

Comments
 (0)