Added SNR and refactored types
Some checks failed
Test and build / Test and lint (push) Failing after 35s
Test and build / Build collector (push) Failing after 37s
Test and build / Build receiver (push) Failing after 37s

This commit is contained in:
2026-03-06 09:06:08 +01:00
parent e83df1c143
commit 247c827291
27 changed files with 2533 additions and 615 deletions

View File

@@ -12,10 +12,10 @@ import SignalCellularAltIcon from '@mui/icons-material/SignalCellularAlt';
import StorageIcon from '@mui/icons-material/Storage';
import { Packet } from '../../protocols/meshcore';
import { NodeType, PayloadType, RouteType } from '../../protocols/meshcore.types';
import { NodeType, PayloadType, RouteType } from '../../types/protocol/meshcore.types';
import { MeshCoreStream } from '../../services/MeshCoreStream';
import type { MeshCoreMessage } from '../../services/MeshCoreStream';
import type { Payload, AdvertPayload } from '../../protocols/meshcore.types';
import type { Payload, AdvertPayload } from '../../types/protocol/meshcore.types';
import API from '../../services/API';
import MeshCoreServiceImpl from '../../services/MeshCoreService';
import { base64ToBytes } from '../../util';
@@ -37,17 +37,36 @@ export {
type MeshCoreNodePoint,
} from './MeshCoreContext';
export const payloadNameByValue = Object.fromEntries(
Object.entries(PayloadType).map(([name, value]) => [value, name])
) as Record<number, string>;
export const payloadNameByValue: Record<number, string> = {
[PayloadType.REQUEST]: 'Request',
[PayloadType.RESPONSE]: 'Response',
[PayloadType.TEXT]: 'Private Message',
[PayloadType.ACK]: 'Acknowledgement',
[PayloadType.ADVERT]: 'Advertisement',
[PayloadType.GROUP_TEXT]: 'Group Message',
[PayloadType.GROUP_DATA]: 'Group Data',
[PayloadType.ANON_REQ]: 'Anonymous Request',
[PayloadType.PATH]: 'Path',
[PayloadType.TRACE]: 'Trace',
[PayloadType.MULTIPART]: 'Multipart',
[PayloadType.CONTROL]: 'Control',
[PayloadType.RAW_CUSTOM]: 'Custom',
};
export const nodeTypeNameByValue = Object.fromEntries(
Object.entries(NodeType).map(([name, value]) => [value, name])
) as Record<number, string>;
export const nodeTypeNameByValue: Record<number, string> = {
[NodeType.TYPE_UNKNOWN]: 'Unknown',
[NodeType.TYPE_CHAT_NODE]: 'Chat Node',
[NodeType.TYPE_REPEATER]: 'Repeater',
[NodeType.TYPE_ROOM_SERVER]: 'Room Server',
[NodeType.TYPE_SENSOR]: 'Sensor',
};
export const routeTypeNameByValue = Object.fromEntries(
Object.entries(RouteType).map(([name, value]) => [value, name])
) as Record<number, string>;
export const routeTypeNameByValue: Record<number, string> = {
[RouteType.TRANSPORT_FLOOD]: 'Transport Flood',
[RouteType.FLOOD]: 'Flood',
[RouteType.DIRECT]: 'Direct',
[RouteType.TRANSPORT_DIRECT]: 'Transport Direct',
};
export const payloadValueByName = Object.fromEntries(
Object.entries(PayloadType).map(([name, value]) => [name, value])
@@ -56,31 +75,31 @@ export const payloadValueByName = Object.fromEntries(
export const PayloadTypeIcon: React.FC<{ payloadType: number }> = ({ payloadType }) => {
switch (payloadType) {
case PayloadType.REQUEST:
return <ArrowForwardIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <ArrowForwardIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
case PayloadType.RESPONSE:
return <ArrowBackIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <ArrowBackIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
case PayloadType.TEXT:
return <PersonIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <PersonIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
case PayloadType.ACK:
return <ReplyIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <ReplyIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
case PayloadType.ADVERT:
return <SignalCellularAltIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <SignalCellularAltIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
case PayloadType.GROUP_TEXT:
return <PersonIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <PersonIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
case PayloadType.GROUP_DATA:
return <StorageIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <StorageIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
case PayloadType.ANON_REQ:
return <ArrowForwardIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <ArrowForwardIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
case PayloadType.PATH:
return <RouteIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <RouteIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
case PayloadType.TRACE:
return <RouteIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <RouteIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
case PayloadType.MULTIPART:
return <BrandingWatermarkIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <BrandingWatermarkIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
case PayloadType.CONTROL:
return <SensorsIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <SensorsIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
case PayloadType.RAW_CUSTOM:
return <QuestionMarkIcon className="meshcore-payload-icon" titleAccess={payloadDisplayByValue[payloadType]} />;
return <QuestionMarkIcon className="meshcore-payload-icon" titleAccess={payloadNameByValue[payloadType]} />;
default:
return <QuestionMarkIcon className="meshcore-payload-icon" titleAccess="Unknown" />;
}
@@ -282,6 +301,10 @@ const toMapPoints = (packets: MeshCorePacketRecord[]): MeshCoreNodePoint[] => {
const byNode = new Map<string, MeshCoreNodePoint>();
packets.forEach((packet) => {
if (!packet.path || packet.path.length === 0) {
return;
}
const nodeId = packet.path[0].toString(16).padStart(2, '0');
const existing = byNode.get(nodeId);
@@ -346,6 +369,8 @@ export const MeshCoreDataProvider: React.FC<{ children: React.ReactNode }> = ({
raw,
decodedPayload,
payloadSummary: summarizePayload(packet.payload_type, decodedPayload, payloadBytes),
snr: packet.snr,
rssi: packet.rssi,
};
});
@@ -383,6 +408,8 @@ export const MeshCoreDataProvider: React.FC<{ children: React.ReactNode }> = ({
decodedPayload: message.decodedPayload,
payloadSummary: '',
radioName: message.radioName,
snr: message.snr,
rssi: message.rssi,
};
// Extract details from raw packet