mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-05-09 14:55:34 +02:00
Use localized units for repeater display
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { RepeaterPane, NotFetched, LppSensorRow } from './repeaterPaneShared';
|
||||
import { useDistanceUnit } from '../../contexts/DistanceUnitContext';
|
||||
import type { RepeaterLppTelemetryResponse, PaneState } from '../../types';
|
||||
|
||||
export function LppTelemetryPane({
|
||||
@@ -12,6 +13,7 @@ export function LppTelemetryPane({
|
||||
onRefresh: () => void;
|
||||
disabled?: boolean;
|
||||
}) {
|
||||
const { distanceUnit } = useDistanceUnit();
|
||||
return (
|
||||
<RepeaterPane title="LPP Sensors" state={state} onRefresh={onRefresh} disabled={disabled}>
|
||||
{!data ? (
|
||||
@@ -21,7 +23,7 @@ export function LppTelemetryPane({
|
||||
) : (
|
||||
<div className="space-y-0.5">
|
||||
{data.sensors.map((sensor, i) => (
|
||||
<LppSensorRow key={i} sensor={sensor} />
|
||||
<LppSensorRow key={i} sensor={sensor} unitPref={distanceUnit} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -11,7 +11,8 @@ import {
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Button } from '../ui/button';
|
||||
import { Separator } from '../ui/separator';
|
||||
import { LPP_UNIT_MAP } from './repeaterPaneShared';
|
||||
import { lppDisplayUnit } from './repeaterPaneShared';
|
||||
import { useDistanceUnit } from '../../contexts/DistanceUnitContext';
|
||||
import type { TelemetryHistoryEntry, TelemetryLppSensor, Contact } from '../../types';
|
||||
|
||||
const MAX_TRACKED = 8;
|
||||
@@ -83,6 +84,7 @@ export function TelemetryHistoryPane({
|
||||
trackedTelemetryRepeaters,
|
||||
onToggleTrackedTelemetry,
|
||||
}: TelemetryHistoryPaneProps) {
|
||||
const { distanceUnit } = useDistanceUnit();
|
||||
const [metric, setMetric] = useState<string>('battery_volts');
|
||||
const [toggling, setToggling] = useState(false);
|
||||
|
||||
@@ -105,7 +107,7 @@ export function TelemetryHistoryPane({
|
||||
info.type_name.charAt(0).toUpperCase() +
|
||||
info.type_name.slice(1).replace(/_/g, ' ') +
|
||||
` Ch${info.channel}`;
|
||||
const unit = LPP_UNIT_MAP[info.type_name] ?? '';
|
||||
const { unit } = lppDisplayUnit(info.type_name, 0, distanceUnit);
|
||||
result.push({
|
||||
key: k,
|
||||
config: { label, unit, color: LPP_COLORS[colorIdx % LPP_COLORS.length] },
|
||||
@@ -115,7 +117,7 @@ export function TelemetryHistoryPane({
|
||||
colorIdx++;
|
||||
}
|
||||
return result;
|
||||
}, [entries]);
|
||||
}, [entries, distanceUnit]);
|
||||
|
||||
const allMetricKeys = useMemo(
|
||||
() => [...BUILTIN_METRICS, ...lppMetrics.map((m) => m.key)],
|
||||
@@ -145,13 +147,15 @@ export function TelemetryHistoryPane({
|
||||
packets_sent: d.packets_sent,
|
||||
uptime_seconds: d.uptime_seconds,
|
||||
};
|
||||
// Flatten LPP sensors into the point
|
||||
// Flatten LPP sensors into the point, converting units as needed
|
||||
for (const s of d.lpp_sensors ?? []) {
|
||||
point[lppKey(s)] = typeof s.value === 'number' ? s.value : undefined;
|
||||
if (typeof s.value === 'number') {
|
||||
point[lppKey(s)] = lppDisplayUnit(s.type_name, s.value, distanceUnit).value;
|
||||
}
|
||||
}
|
||||
return point;
|
||||
});
|
||||
}, [entries]);
|
||||
}, [entries, distanceUnit]);
|
||||
|
||||
const dataKeys =
|
||||
activeMetric === 'packets' ? ['packets_received', 'packets_sent'] : [activeMetric];
|
||||
|
||||
@@ -223,11 +223,26 @@ export const LPP_UNIT_MAP: Record<string, string> = {
|
||||
colour: '',
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the display unit and converted value for an LPP sensor,
|
||||
* respecting the user's unit preference for temperature.
|
||||
*/
|
||||
export function lppDisplayUnit(
|
||||
typeName: string,
|
||||
value: number,
|
||||
unitPref: 'metric' | 'imperial' | string
|
||||
): { unit: string; value: number } {
|
||||
if (typeName === 'temperature' && unitPref === 'imperial') {
|
||||
return { unit: '°F', value: (value * 9) / 5 + 32 };
|
||||
}
|
||||
return { unit: LPP_UNIT_MAP[typeName] ?? '', value };
|
||||
}
|
||||
|
||||
export function formatLppLabel(typeName: string): string {
|
||||
return typeName.charAt(0).toUpperCase() + typeName.slice(1).replace(/_/g, ' ');
|
||||
}
|
||||
|
||||
export function LppSensorRow({ sensor }: { sensor: LppSensor }) {
|
||||
export function LppSensorRow({ sensor, unitPref }: { sensor: LppSensor; unitPref?: string }) {
|
||||
const label = formatLppLabel(sensor.type_name);
|
||||
|
||||
if (typeof sensor.value === 'object' && sensor.value !== null) {
|
||||
@@ -248,10 +263,10 @@ export function LppSensorRow({ sensor }: { sensor: LppSensor }) {
|
||||
);
|
||||
}
|
||||
|
||||
const unit = LPP_UNIT_MAP[sensor.type_name] ?? '';
|
||||
const display = lppDisplayUnit(sensor.type_name, sensor.value as number, unitPref ?? 'metric');
|
||||
const formatted =
|
||||
typeof sensor.value === 'number'
|
||||
? `${sensor.value % 1 === 0 ? sensor.value : sensor.value.toFixed(2)}${unit ? ` ${unit}` : ''}`
|
||||
? `${display.value % 1 === 0 ? display.value : display.value.toFixed(2)}${display.unit ? ` ${display.unit}` : ''}`
|
||||
: String(sensor.value);
|
||||
|
||||
return <KvRow label={label} value={formatted} />;
|
||||
|
||||
@@ -6,7 +6,8 @@ import { Separator } from '../ui/separator';
|
||||
import { toast } from '../ui/sonner';
|
||||
import { api } from '../../api';
|
||||
import { formatTime } from '../../utils/messageParser';
|
||||
import { LPP_UNIT_MAP } from '../repeater/repeaterPaneShared';
|
||||
import { lppDisplayUnit } from '../repeater/repeaterPaneShared';
|
||||
import { useDistanceUnit } from '../../contexts/DistanceUnitContext';
|
||||
import { BulkDeleteContactsModal } from './BulkDeleteContactsModal';
|
||||
import type {
|
||||
AppSettings,
|
||||
@@ -45,6 +46,7 @@ export function SettingsDatabaseSection({
|
||||
onToggleTrackedTelemetry?: (publicKey: string) => Promise<void>;
|
||||
className?: string;
|
||||
}) {
|
||||
const { distanceUnit } = useDistanceUnit();
|
||||
const [retentionDays, setRetentionDays] = useState('14');
|
||||
const [cleaning, setCleaning] = useState(false);
|
||||
const [purgingDecryptedRaw, setPurgingDecryptedRaw] = useState(false);
|
||||
@@ -310,18 +312,18 @@ export function SettingsDatabaseSection({
|
||||
tx {d.packets_sent != null ? d.packets_sent.toLocaleString() : '?'}
|
||||
</span>
|
||||
{d.lpp_sensors?.map((s) => {
|
||||
const unit = LPP_UNIT_MAP[s.type_name] ?? '';
|
||||
const display = lppDisplayUnit(s.type_name, s.value, distanceUnit);
|
||||
const val =
|
||||
typeof s.value === 'number'
|
||||
? s.value % 1 === 0
|
||||
? s.value
|
||||
: s.value.toFixed(1)
|
||||
: s.value;
|
||||
typeof display.value === 'number'
|
||||
? display.value % 1 === 0
|
||||
? display.value
|
||||
: display.value.toFixed(1)
|
||||
: display.value;
|
||||
const label = s.type_name.charAt(0).toUpperCase() + s.type_name.slice(1);
|
||||
return (
|
||||
<span key={`${s.type_name}-${s.channel}`}>
|
||||
{label} {val}
|
||||
{unit ? ` ${unit}` : ''}
|
||||
{display.unit ? ` ${display.unit}` : ''}
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user