Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0c57618
feat: update device server fn, include sensors in device
jona159 Oct 15, 2025
188139c
feat: put action
jona159 Oct 15, 2025
3b3b701
feat: put route
jona159 Oct 15, 2025
9aa79ef
feat: put tests
jona159 Oct 15, 2025
ebd4ca5
Merge branch 'dev' into feat/update-box
jona159 Oct 22, 2025
77d4895
feat: more tests for grouptags
jona159 Oct 22, 2025
25a6f51
feat: add icon field to sensor schema
jona159 Oct 22, 2025
45c8fb7
Merge branch 'dev' into feat/update-box
jona159 Oct 26, 2025
4cbe9d3
feat: update sensors
jona159 Oct 26, 2025
c281206
feat: extend enum
jona159 Oct 26, 2025
2250877
fix: include icon in sensor schema
jona159 Oct 26, 2025
3c7fca2
fix: lint
jona159 Nov 5, 2025
96026c2
feat: add feinstaub addon tests
jona159 Nov 5, 2025
bf358c1
feat: add addon definitions
jona159 Nov 5, 2025
545592e
feat: check addon field
jona159 Nov 5, 2025
514d90d
fix: rm dupliate update device function
jona159 Nov 12, 2025
7543325
fix: adjustmenets to edit box component to use updateDevice
jona159 Nov 12, 2025
70f3c2b
Merge branch 'dev' into feat/update-box
jona159 Nov 12, 2025
dc648a8
feat: extend model definitions
jona159 Nov 12, 2025
2f263a5
fix: rm custom from model definitions
jona159 Nov 12, 2025
fdeb59e
fix: broken tests due to model and sensor parameters
jona159 Nov 12, 2025
c2b0bc4
fix: only pass model if no sensors provided
jona159 Nov 12, 2025
16b6010
fix: handle model and sensors in create device
jona159 Nov 12, 2025
ded2ec4
fix: rm model
jona159 Nov 12, 2025
f647ff6
fix: rename test grouptag
jona159 Nov 12, 2025
812a413
fix: delete data after test, fix tags test
jona159 Nov 12, 2025
9351dcd
fix: indentation
jona159 Nov 12, 2025
36036ce
fix :types
jona159 Nov 12, 2025
0c4aa1e
Merge branch 'dev' into feat/update-box
jona159 Nov 19, 2025
a296dc2
fix: response utils
jona159 Nov 19, 2025
6646aba
fix: rm model from text box
jona159 Nov 19, 2025
6579967
Merge branch 'dev' into feat/update-box
jona159 Nov 19, 2025
2bc693d
fix: rm ts ignore
jona159 Nov 19, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
181 changes: 93 additions & 88 deletions app/lib/device-transform.ts
Original file line number Diff line number Diff line change
@@ -1,102 +1,107 @@
import { type Device, type Sensor } from '~/schema';
import { type Device, type Sensor } from '~/schema'

export type DeviceWithSensors = Device & {
sensors: Sensor[];
};
sensors: Sensor[]
}

export type TransformedDevice = {
_id: string;
name: string;
description: string | null;
image: string | null;
link: string | null;
grouptag: string[];
exposure: string | null;
model: string | null;
latitude: number;
longitude: number;
useAuth: boolean | null;
public: boolean | null;
status: string | null;
createdAt: Date;
updatedAt: Date;
expiresAt: Date | null;
userId: string;
sensorWikiModel?: string | null;
currentLocation: {
type: "Point";
coordinates: number[];
timestamp: string;
};
lastMeasurementAt: string;
loc: Array<{
type: "Feature";
geometry: {
type: "Point";
coordinates: number[];
timestamp: string;
};
}>;
integrations: {
mqtt: {
enabled: boolean;
};
};
sensors: Array<{
_id: string;
title: string | null;
unit: string | null;
sensorType: string | null;
lastMeasurement: {
value: string;
createdAt: string;
} | null;
}>;
};
_id: string
name: string
description: string | null
image: string | null
link: string | null
grouptag: string[]
exposure: string | null
model: string | null
latitude: number
longitude: number
useAuth: boolean | null
public: boolean | null
status: string | null
createdAt: Date
updatedAt: Date
expiresAt: Date | null
userId: string
sensorWikiModel?: string | null
currentLocation: {
type: 'Point'
coordinates: number[]
timestamp: string
}
lastMeasurementAt: string
loc: Array<{
type: 'Feature'
geometry: {
type: 'Point'
coordinates: number[]
timestamp: string
}
}>
integrations: {
mqtt: {
enabled: boolean
}
}
sensors: Array<{
_id: string
title: string | null
unit: string | null
sensorType: string | null
lastMeasurement: {
value: string
createdAt: string
} | null
}>
}

/**
* Transforms a device with sensors from database format to openSenseMap API format
* @param box - Device object with sensors from database
* @returns Transformed device in openSenseMap API format
*
*
* Note: Converts lastMeasurement.value from number to string to match API specification
*/
export function transformDeviceToApiFormat(
box: DeviceWithSensors
box: DeviceWithSensors,
): TransformedDevice {
const { id, tags, sensors, ...rest } = box;
const timestamp = box.updatedAt.toISOString();
const coordinates = [box.longitude, box.latitude];

return {
_id: id,
grouptag: tags || [],
...rest,
currentLocation: {
type: "Point",
coordinates,
timestamp
},
lastMeasurementAt: timestamp,
loc: [{
geometry: { type: "Point", coordinates, timestamp },
type: "Feature"
}],
integrations: { mqtt: { enabled: false } },
sensors: sensors?.map((sensor) => ({
_id: sensor.id,
title: sensor.title,
unit: sensor.unit,
sensorType: sensor.sensorType,
lastMeasurement: sensor.lastMeasurement
? {
createdAt: sensor.lastMeasurement.createdAt,
// Convert numeric values to string to match API specification
value: typeof sensor.lastMeasurement.value === 'number'
? String(sensor.lastMeasurement.value)
: sensor.lastMeasurement.value,
}
: null,
})) || [],
};
const { id, tags, sensors, ...rest } = box
const timestamp = box.updatedAt.toISOString()
const coordinates = [box.longitude, box.latitude]

return {
_id: id,
grouptag: tags || [],
...rest,
currentLocation: {
type: 'Point',
coordinates,
timestamp,
},
lastMeasurementAt: timestamp,
loc: [
{
geometry: { type: 'Point', coordinates, timestamp },
type: 'Feature',
},
],
integrations: { mqtt: { enabled: false } },
sensors:
sensors?.map((sensor) => ({
_id: sensor.id,
title: sensor.title,
unit: sensor.unit,
sensorType: sensor.sensorType,
icon: sensor.icon,
lastMeasurement: sensor.lastMeasurement
? {
createdAt: sensor.lastMeasurement.createdAt,
// Convert number to string to match API specification
value:
typeof sensor.lastMeasurement.value === 'number'
? String(sensor.lastMeasurement.value)
: sensor.lastMeasurement.value,
}
: null,
})) || [],
}
}
Loading
Loading