mirror of
https://github.com/SlimeVR/SlimeVR-Server.git
synced 2026-04-06 02:01:58 +02:00
More provisioning errors (#1404)
Co-authored-by: Butterscotch! <bscotchvanilla@gmail.com>
This commit is contained in:
@@ -107,12 +107,12 @@ skeleton_bone-HEAD = Head Shift
|
||||
skeleton_bone-HEAD-desc =
|
||||
This is the distance from your headset to the middle of your head.
|
||||
To adjust it, shake your head left to right as if you're disagreeing and modify
|
||||
it until any movement in other trackers is negligible.
|
||||
it until any movement in other trackers is negligible.
|
||||
skeleton_bone-NECK = Neck Length
|
||||
skeleton_bone-NECK-desc =
|
||||
This is the distance from the middle of your head to the base of your neck.
|
||||
To adjust it, move your head up and down as if you're nodding or tilt your head
|
||||
to the left and right and modify it until any movement in other trackers is negligible.
|
||||
To adjust it, move your head up and down as if you're nodding or tilt your head
|
||||
to the left and right and modify it until any movement in other trackers is negligible.
|
||||
skeleton_bone-torso_group = Torso length
|
||||
skeleton_bone-torso_group-desc =
|
||||
This is the distance from the base of your neck to your hips.
|
||||
@@ -184,40 +184,40 @@ skeleton_bone-SKELETON_OFFSET-desc =
|
||||
skeleton_bone-SHOULDERS_DISTANCE = Shoulders Distance
|
||||
skeleton_bone-SHOULDERS_DISTANCE-desc =
|
||||
This is the vertical distance from the base of your neck to your shoulders.
|
||||
To adjust it, set Upper Arm Length to 0 and modify it until your virtual elbow trackers
|
||||
To adjust it, set Upper Arm Length to 0 and modify it until your virtual elbow trackers
|
||||
line up vertically with your real shoulders.
|
||||
skeleton_bone-SHOULDERS_WIDTH = Shoulders Width
|
||||
skeleton_bone-SHOULDERS_WIDTH-desc =
|
||||
This is the horizontal distance from the base of your neck to your shoulders.
|
||||
To adjust it, set Upper Arm Length to 0 and modify it until your virtual elbow trackers
|
||||
To adjust it, set Upper Arm Length to 0 and modify it until your virtual elbow trackers
|
||||
line up horizontally with your real shoulders.
|
||||
skeleton_bone-arm_group = Arm length
|
||||
skeleton_bone-arm_group-desc =
|
||||
This is the distance from your shoulders to your wrists.
|
||||
To adjust it, adjust Shoulders Distance properly, set Hand Distance Y
|
||||
To adjust it, adjust Shoulders Distance properly, set Hand Distance Y
|
||||
to 0 and modify it until your hand trackers line up with your wrists.
|
||||
skeleton_bone-UPPER_ARM = Upper Arm Length
|
||||
skeleton_bone-UPPER_ARM-desc =
|
||||
This is the distance from your shoulders to your elbows.
|
||||
To adjust it, adjust Arm Length properly and modify it until
|
||||
To adjust it, adjust Arm Length properly and modify it until
|
||||
your elbow trackers line up with your real elbows.
|
||||
skeleton_bone-LOWER_ARM = Lower Arm Length
|
||||
skeleton_bone-LOWER_ARM-desc =
|
||||
This is the distance from your elbows to your wrists.
|
||||
To adjust it, adjust Arm Length properly and modify it until
|
||||
To adjust it, adjust Arm Length properly and modify it until
|
||||
your elbow trackers line up with your real elbows.
|
||||
skeleton_bone-HAND_Y = Hand Distance Y
|
||||
skeleton_bone-HAND_Y-desc =
|
||||
This is the vertical distance from your wrists to the middle of your hand.
|
||||
To adjust it for motion capture, adjust Arm Length properly and modify it until your
|
||||
hand trackers line up vertically with the middle of your hands.
|
||||
To adjust it for elbow tracking from your controllers, set Arm Length to 0 and
|
||||
To adjust it for elbow tracking from your controllers, set Arm Length to 0 and
|
||||
modify it until your elbow trackers line up vertically with your wrists.
|
||||
skeleton_bone-HAND_Z = Hand Distance Z
|
||||
skeleton_bone-HAND_Z-desc =
|
||||
This is the horizontal distance from your wrists to the middle of your hand.
|
||||
To adjust it for motion capture, set it to 0.
|
||||
To adjust it for elbow tracking from your controllers, set Arm Length to 0 and
|
||||
To adjust it for elbow tracking from your controllers, set Arm Length to 0 and
|
||||
modify it until your elbow trackers line up horizontally with your wrists.
|
||||
skeleton_bone-ELBOW_OFFSET = Elbow Offset
|
||||
skeleton_bone-ELBOW_OFFSET-desc =
|
||||
@@ -913,6 +913,17 @@ onboarding-connect_tracker-connection_status-looking_for_server = Looking for se
|
||||
onboarding-connect_tracker-connection_status-connection_error = Unable to connect to Wi-Fi
|
||||
onboarding-connect_tracker-connection_status-could_not_find_server = Could not find the server
|
||||
onboarding-connect_tracker-connection_status-done = Connected to the Server
|
||||
onboarding-connect_tracker-connection_status-no_serial_log = Could not get logs from the tracker
|
||||
onboarding-connect_tracker-connection_status-no_serial_device_found = Could not find a tracker from USB
|
||||
onboarding-connect_serial-error-modal-no_serial_log = Is the tracker turned on?
|
||||
onboarding-connect_serial-error-modal-no_serial_log-desc = Make sure the tracker is turned on and connected to your computer
|
||||
onboarding-connect_serial-error-modal-no_serial_device_found = No trackers detected
|
||||
onboarding-connect_serial-error-modal-no_serial_device_found-desc =
|
||||
Please connect a tracker with the provided usb cable to your computer and turn the tracker on.
|
||||
If this does not work:
|
||||
- try with another usb cable
|
||||
- try with another usb port
|
||||
- try reinstalling the SlimeVR server and select "USB Drivers" in the components section
|
||||
# $amount (Number) - Amount of trackers connected (this is a number, but you can use CLDR plural rules for your language)
|
||||
# More info on https://www.unicode.org/cldr/cldr-aux/charts/22/supplemental/language_plural_rules.html
|
||||
# English in this case only has 2 plural rules, which are "one" and "other",
|
||||
|
||||
BIN
gui/public/videos/turn-on-tracker.webm
Normal file
BIN
gui/public/videos/turn-on-tracker.webm
Normal file
Binary file not shown.
@@ -10,6 +10,7 @@ export function BaseModal({
|
||||
}: {
|
||||
isOpen: boolean;
|
||||
children: ReactNode;
|
||||
appendClasses?: string;
|
||||
important?: boolean;
|
||||
closeable?: boolean;
|
||||
} & ReactModal.Props) {
|
||||
@@ -31,7 +32,8 @@ export function BaseModal({
|
||||
classNames(
|
||||
'items-center focus:ring-transparent focus:ring-offset-transparent',
|
||||
'focus:outline-transparent outline-none bg-background-60 p-6 rounded-lg m-2',
|
||||
'text-background-10'
|
||||
'text-background-10',
|
||||
props.appendClasses
|
||||
)
|
||||
}
|
||||
>
|
||||
|
||||
@@ -22,6 +22,7 @@ import { useIsRestCalibrationTrackers } from '@/hooks/imu-logic';
|
||||
import './ConnectTracker.scss';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import { connectedIMUTrackersAtom } from '@/store/app-store';
|
||||
import { BaseModal } from '@/components/commons/BaseModal';
|
||||
|
||||
const statusLabelMap = {
|
||||
[WifiProvisioningStatus.NONE]:
|
||||
@@ -42,12 +43,25 @@ const statusLabelMap = {
|
||||
'onboarding-connect_tracker-connection_status-connection_error',
|
||||
[WifiProvisioningStatus.COULD_NOT_FIND_SERVER]:
|
||||
'onboarding-connect_tracker-connection_status-could_not_find_server',
|
||||
[WifiProvisioningStatus.NO_SERIAL_LOGS_ERROR]:
|
||||
'onboarding-connect_tracker-connection_status-no_serial_log',
|
||||
[WifiProvisioningStatus.NO_SERIAL_DEVICE_FOUND]:
|
||||
'onboarding-connect_tracker-connection_status-no_serial_device_found',
|
||||
};
|
||||
|
||||
const errorLabelMap = {
|
||||
[WifiProvisioningStatus.NO_SERIAL_LOGS_ERROR]:
|
||||
'onboarding-connect_serial-error-modal-no_serial_log',
|
||||
[WifiProvisioningStatus.NO_SERIAL_DEVICE_FOUND]:
|
||||
'onboarding-connect_serial-error-modal-no_serial_device_found',
|
||||
};
|
||||
|
||||
const statusProgressMap = {
|
||||
[WifiProvisioningStatus.NONE]: 0,
|
||||
[WifiProvisioningStatus.SERIAL_INIT]: 0.2,
|
||||
[WifiProvisioningStatus.NO_SERIAL_DEVICE_FOUND]: 0.2,
|
||||
[WifiProvisioningStatus.OBTAINING_MAC_ADDRESS]: 0.3,
|
||||
[WifiProvisioningStatus.NO_SERIAL_LOGS_ERROR]: 0.3,
|
||||
[WifiProvisioningStatus.PROVISIONING]: 0.4,
|
||||
[WifiProvisioningStatus.CONNECTING]: 0.6,
|
||||
[WifiProvisioningStatus.LOOKING_FOR_SERVER]: 0.8,
|
||||
@@ -64,6 +78,7 @@ export function ConnectTrackersPage() {
|
||||
const { sendRPCPacket, useRPCPacket } = useWebsocketAPI();
|
||||
const [provisioningStatus, setProvisioningStatus] =
|
||||
useState<WifiProvisioningStatus>(WifiProvisioningStatus.NONE);
|
||||
const [ignoreError, setIgnoreError] = useState(false);
|
||||
|
||||
applyProgress(0.4);
|
||||
|
||||
@@ -94,9 +109,22 @@ export function ConnectTrackersPage() {
|
||||
}
|
||||
);
|
||||
|
||||
const isError =
|
||||
provisioningStatus === WifiProvisioningStatus.CONNECTION_ERROR ||
|
||||
provisioningStatus === WifiProvisioningStatus.COULD_NOT_FIND_SERVER;
|
||||
const isError = useMemo(
|
||||
() =>
|
||||
[
|
||||
WifiProvisioningStatus.CONNECTION_ERROR,
|
||||
WifiProvisioningStatus.COULD_NOT_FIND_SERVER,
|
||||
WifiProvisioningStatus.NO_SERIAL_LOGS_ERROR,
|
||||
WifiProvisioningStatus.NO_SERIAL_DEVICE_FOUND,
|
||||
].includes(provisioningStatus),
|
||||
[provisioningStatus]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isError) {
|
||||
setIgnoreError(false);
|
||||
}
|
||||
}, [isError]);
|
||||
|
||||
const progressBarClass = useMemo(() => {
|
||||
if (isError) {
|
||||
@@ -121,7 +149,7 @@ export function ConnectTrackersPage() {
|
||||
default:
|
||||
return SlimeState.JUMPY;
|
||||
}
|
||||
}, [provisioningStatus]);
|
||||
}, [provisioningStatus, isError]);
|
||||
|
||||
const currentTip = useMemo(
|
||||
() =>
|
||||
@@ -132,125 +160,170 @@ export function ConnectTrackersPage() {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="connect-tracker-layout h-full">
|
||||
<div style={{ gridArea: 's' }} className="p-4">
|
||||
<Typography variant="main-title">
|
||||
{l10n.getString('onboarding-connect_tracker-title')}
|
||||
</Typography>
|
||||
<Typography color="secondary">
|
||||
{l10n.getString('onboarding-connect_tracker-description-p0-v1')}
|
||||
</Typography>
|
||||
<Typography color="secondary">
|
||||
{l10n.getString('onboarding-connect_tracker-description-p1-v1')}
|
||||
</Typography>
|
||||
<div className="flex flex-col gap-2 py-5">
|
||||
<ArrowLink
|
||||
to="/settings/serial"
|
||||
state={{ SerialPort: 'Auto' }}
|
||||
direction="right"
|
||||
variant={state.alonePage ? 'boxed-2' : 'boxed'}
|
||||
>
|
||||
{l10n.getString('onboarding-connect_tracker-issue-serial')}
|
||||
</ArrowLink>
|
||||
<>
|
||||
<BaseModal
|
||||
isOpen={
|
||||
!ignoreError &&
|
||||
[
|
||||
WifiProvisioningStatus.NO_SERIAL_LOGS_ERROR,
|
||||
WifiProvisioningStatus.NO_SERIAL_DEVICE_FOUND,
|
||||
].includes(provisioningStatus)
|
||||
}
|
||||
appendClasses={'w-xl max-w-xl mobile:w-full'}
|
||||
closeable
|
||||
onRequestClose={() => {
|
||||
setIgnoreError(true);
|
||||
}}
|
||||
>
|
||||
<div className="flex flex-col items-center gap-2 ">
|
||||
<Localized id={(errorLabelMap as any)[provisioningStatus]}>
|
||||
<Typography variant="main-title"></Typography>
|
||||
</Localized>
|
||||
<Localized id={`${(errorLabelMap as any)[provisioningStatus]}-desc`}>
|
||||
<Typography
|
||||
variant="standard"
|
||||
whitespace="whitespace-pre-wrap"
|
||||
block
|
||||
></Typography>
|
||||
</Localized>
|
||||
<video
|
||||
src="/videos/turn-on-tracker.webm"
|
||||
loop
|
||||
autoPlay
|
||||
className="w-full aspect-video rounded-md mt-2"
|
||||
></video>
|
||||
<div className="flex gap-3 pt-5 justify-end w-full">
|
||||
<Button
|
||||
variant="tertiary"
|
||||
onClick={() => {
|
||||
setIgnoreError(true);
|
||||
}}
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Localized
|
||||
id={currentTip}
|
||||
elems={{ em: <em className="italic"></em>, b: <b></b> }}
|
||||
>
|
||||
<TipBox>Conditional tip</TipBox>
|
||||
</Localized>
|
||||
</BaseModal>
|
||||
<div className="connect-tracker-layout h-full">
|
||||
<div style={{ gridArea: 's' }} className="p-4">
|
||||
<Typography variant="main-title">
|
||||
{l10n.getString('onboarding-connect_tracker-title')}
|
||||
</Typography>
|
||||
<Typography color="secondary">
|
||||
{l10n.getString('onboarding-connect_tracker-description-p0-v1')}
|
||||
</Typography>
|
||||
<Typography color="secondary">
|
||||
{l10n.getString('onboarding-connect_tracker-description-p1-v1')}
|
||||
</Typography>
|
||||
<div className="flex flex-col gap-2 py-5">
|
||||
<ArrowLink
|
||||
to="/settings/serial"
|
||||
state={{ SerialPort: 'Auto' }}
|
||||
direction="right"
|
||||
variant={state.alonePage ? 'boxed-2' : 'boxed'}
|
||||
>
|
||||
{l10n.getString('onboarding-connect_tracker-issue-serial')}
|
||||
</ArrowLink>
|
||||
</div>
|
||||
<Localized
|
||||
id={currentTip}
|
||||
elems={{ em: <em className="italic"></em>, b: <b></b> }}
|
||||
>
|
||||
<TipBox>Conditional tip</TipBox>
|
||||
</Localized>
|
||||
|
||||
<div
|
||||
className={classNames(
|
||||
'rounded-xl h-24 flex gap-2 p-3 lg:w-full mt-4 relative',
|
||||
state.alonePage ? 'bg-background-60' : 'bg-background-70',
|
||||
isError && 'border-2 border-status-critical'
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
'flex flex-col justify-center fill-background-10 absolute',
|
||||
'right-5 bottom-8'
|
||||
'rounded-xl h-24 flex gap-2 p-3 lg:w-full mt-4 relative',
|
||||
state.alonePage ? 'bg-background-60' : 'bg-background-70',
|
||||
isError && 'border-2 border-status-critical'
|
||||
)}
|
||||
>
|
||||
<LoaderIcon slimeState={slimeStatus}></LoaderIcon>
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
'flex flex-col justify-center fill-background-10 absolute',
|
||||
'right-5 bottom-8'
|
||||
)}
|
||||
>
|
||||
<LoaderIcon slimeState={slimeStatus}></LoaderIcon>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col grow self-center">
|
||||
<Typography bold>
|
||||
{l10n.getString('onboarding-connect_tracker-usb')}
|
||||
</Typography>
|
||||
<div className="flex fill-background-10 gap-1">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(statusLabelMap[provisioningStatus])}
|
||||
<div className="flex flex-col grow self-center">
|
||||
<Typography bold>
|
||||
{l10n.getString('onboarding-connect_tracker-usb')}
|
||||
</Typography>
|
||||
<div className="flex fill-background-10 gap-1">
|
||||
<Typography color="secondary">
|
||||
{l10n.getString(statusLabelMap[provisioningStatus])}
|
||||
</Typography>
|
||||
</div>
|
||||
<ProgressBar
|
||||
progress={statusProgressMap[provisioningStatus]}
|
||||
height={14}
|
||||
animated={true}
|
||||
colorClass={progressBarClass}
|
||||
></ProgressBar>
|
||||
</div>
|
||||
<ProgressBar
|
||||
progress={statusProgressMap[provisioningStatus]}
|
||||
height={14}
|
||||
animated={true}
|
||||
colorClass={progressBarClass}
|
||||
></ProgressBar>
|
||||
</div>
|
||||
<div className="flex flex-row mt-4 gap-3">
|
||||
<Button
|
||||
variant="secondary"
|
||||
state={{ alonePage: state.alonePage }}
|
||||
to="/onboarding/wifi-creds"
|
||||
>
|
||||
{state.alonePage
|
||||
? l10n.getString('onboarding-connect_tracker-back')
|
||||
: l10n.getString('onboarding-previous_step')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
to={
|
||||
state.alonePage
|
||||
? '/'
|
||||
: bnoExists
|
||||
? '/onboarding/calibration-tutorial'
|
||||
: '/onboarding/assign-tutorial'
|
||||
}
|
||||
className="ml-auto"
|
||||
>
|
||||
{l10n.getString('onboarding-connect_tracker-next')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-row mt-4 gap-3">
|
||||
<Button
|
||||
variant="secondary"
|
||||
state={{ alonePage: state.alonePage }}
|
||||
to="/onboarding/wifi-creds"
|
||||
>
|
||||
{state.alonePage
|
||||
? l10n.getString('onboarding-connect_tracker-back')
|
||||
: l10n.getString('onboarding-previous_step')}
|
||||
</Button>
|
||||
<Button
|
||||
variant="primary"
|
||||
to={
|
||||
state.alonePage
|
||||
? '/'
|
||||
: bnoExists
|
||||
? '/onboarding/calibration-tutorial'
|
||||
: '/onboarding/assign-tutorial'
|
||||
}
|
||||
className="ml-auto"
|
||||
>
|
||||
{l10n.getString('onboarding-connect_tracker-next')}
|
||||
</Button>
|
||||
<div style={{ gridArea: 't' }} className="flex items-center px-5">
|
||||
<Typography color="secondary" bold>
|
||||
{l10n.getString('onboarding-connect_tracker-connected_trackers', {
|
||||
amount: connectedIMUTrackers.length,
|
||||
})}
|
||||
</Typography>
|
||||
</div>
|
||||
<div style={{ gridArea: 'c' }} className="xs:overflow-y-auto">
|
||||
<div className="grid lg:grid-cols-2 md:grid-cols-1 gap-2 pr-1 mx-5 py-4">
|
||||
{Array.from({
|
||||
...connectedIMUTrackers,
|
||||
length: Math.max(connectedIMUTrackers.length, 1),
|
||||
}).map((tracker, index) => (
|
||||
<div key={index}>
|
||||
{!tracker && (
|
||||
<div
|
||||
className={classNames(
|
||||
'rounded-xl h-16 animate-pulse',
|
||||
state.alonePage ? 'bg-background-80' : 'bg-background-70'
|
||||
)}
|
||||
></div>
|
||||
)}
|
||||
{tracker && (
|
||||
<TrackerCard
|
||||
tracker={tracker.tracker}
|
||||
device={tracker.device}
|
||||
smol
|
||||
></TrackerCard>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ gridArea: 't' }} className="flex items-center px-5">
|
||||
<Typography color="secondary" bold>
|
||||
{l10n.getString('onboarding-connect_tracker-connected_trackers', {
|
||||
amount: connectedIMUTrackers.length,
|
||||
})}
|
||||
</Typography>
|
||||
</div>
|
||||
<div style={{ gridArea: 'c' }} className="xs:overflow-y-auto">
|
||||
<div className="grid lg:grid-cols-2 md:grid-cols-1 gap-2 pr-1 mx-5 py-4">
|
||||
{Array.from({
|
||||
...connectedIMUTrackers,
|
||||
length: Math.max(connectedIMUTrackers.length, 1),
|
||||
}).map((tracker, index) => (
|
||||
<div key={index}>
|
||||
{!tracker && (
|
||||
<div
|
||||
className={classNames(
|
||||
'rounded-xl h-16 animate-pulse',
|
||||
state.alonePage ? 'bg-background-80' : 'bg-background-70'
|
||||
)}
|
||||
></div>
|
||||
)}
|
||||
{tracker && (
|
||||
<TrackerCard
|
||||
tracker={tracker.tracker}
|
||||
device={tracker.device}
|
||||
smol
|
||||
></TrackerCard>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -244,15 +244,15 @@ class AndroidSerialHandler(val activity: AppCompatActivity) :
|
||||
|
||||
override fun getCurrentPort(): SlimeSerialPort? = this.currentPort
|
||||
|
||||
private fun addLog(str: String) {
|
||||
private fun addLog(str: String, server: Boolean = true) {
|
||||
LogManager.info("[Serial] $str")
|
||||
listeners.forEach { it.onSerialLog(str) }
|
||||
listeners.forEach { it.onSerialLog(str, server) }
|
||||
}
|
||||
|
||||
override fun onNewData(data: ByteArray?) {
|
||||
if (data != null) {
|
||||
val s = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(data)).toString()
|
||||
addLog(s)
|
||||
addLog(s, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class SerialRebootHandler(
|
||||
currentPort = null
|
||||
}
|
||||
|
||||
override fun onSerialLog(str: String) {
|
||||
override fun onSerialLog(str: String, ignored: Boolean) {
|
||||
if (str.contains("starting up...")) {
|
||||
val foundPort = watchRestartQueue.find { it.first.id == currentPort?.portLocation }
|
||||
if (foundPort != null) {
|
||||
|
||||
@@ -65,7 +65,7 @@ public class RPCProvisioningHandler implements ProvisioningListener {
|
||||
FlatBufferBuilder fbb = new FlatBufferBuilder(32);
|
||||
|
||||
WifiProvisioningStatusResponse.startWifiProvisioningStatusResponse(fbb);
|
||||
WifiProvisioningStatusResponse.addStatus(fbb, status.getId());
|
||||
WifiProvisioningStatusResponse.addStatus(fbb, status.id);
|
||||
int update = WifiProvisioningStatusResponse.endWifiProvisioningStatusResponse(fbb);
|
||||
int outbound = rpcHandler
|
||||
.createRPCMessage(fbb, RpcMessage.WifiProvisioningStatusResponse, update);
|
||||
|
||||
@@ -71,7 +71,7 @@ public class RPCSerialHandler implements SerialListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSerialLog(String str) {
|
||||
public void onSerialLog(String str, boolean server) {
|
||||
FlatBufferBuilder fbb = new FlatBufferBuilder(32);
|
||||
|
||||
int logOffset = fbb.createString(str);
|
||||
|
||||
@@ -26,6 +26,7 @@ public class ProvisioningHandler implements SerialListener {
|
||||
private final Timer provisioningTickTimer = new Timer("ProvisioningTickTimer");
|
||||
private long lastStatusChange = -1;
|
||||
private byte connectRetries = 0;
|
||||
private boolean hasLogs = false;
|
||||
private final byte MAX_CONNECTION_RETRIES = 1;
|
||||
private final VRServer vrServer;
|
||||
|
||||
@@ -45,6 +46,7 @@ public class ProvisioningHandler implements SerialListener {
|
||||
|
||||
public void start(String ssid, String password, String port) {
|
||||
this.isRunning = true;
|
||||
this.hasLogs = false;
|
||||
this.ssid = ssid;
|
||||
this.password = password;
|
||||
this.preferredPort = port;
|
||||
@@ -54,6 +56,7 @@ public class ProvisioningHandler implements SerialListener {
|
||||
|
||||
public void stop() {
|
||||
this.isRunning = false;
|
||||
this.hasLogs = false;
|
||||
this.ssid = null;
|
||||
this.password = null;
|
||||
this.connectRetries = 0;
|
||||
@@ -63,6 +66,7 @@ public class ProvisioningHandler implements SerialListener {
|
||||
|
||||
public void initSerial(String port) {
|
||||
this.provisioningStatus = ProvisioningStatus.SERIAL_INIT;
|
||||
this.hasLogs = false;
|
||||
|
||||
try {
|
||||
boolean openResult = false;
|
||||
@@ -93,27 +97,43 @@ public class ProvisioningHandler implements SerialListener {
|
||||
|
||||
|
||||
public void provisioningTick() {
|
||||
if (this.provisioningStatus == ProvisioningStatus.OBTAINING_MAC_ADDRESS)
|
||||
this.tryObtainMacAddress();
|
||||
|
||||
if (
|
||||
this.provisioningStatus == ProvisioningStatus.CONNECTION_ERROR
|
||||
|| this.provisioningStatus == ProvisioningStatus.DONE
|
||||
)
|
||||
!hasLogs
|
||||
&& this.provisioningStatus == ProvisioningStatus.OBTAINING_MAC_ADDRESS
|
||||
&& System.currentTimeMillis() - this.lastStatusChange > 1_000
|
||||
) {
|
||||
this.changeStatus(ProvisioningStatus.NO_SERIAL_LOGS_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
this.provisioningStatus == ProvisioningStatus.SERIAL_INIT
|
||||
&& vrServer.serialHandler.getKnownPorts().findAny().isEmpty()
|
||||
&& System.currentTimeMillis() - this.lastStatusChange > 15_000
|
||||
) {
|
||||
this.changeStatus(ProvisioningStatus.NO_SERIAL_DEVICE_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
if (System.currentTimeMillis() - this.lastStatusChange > 10000) {
|
||||
if (
|
||||
System.currentTimeMillis() - this.lastStatusChange
|
||||
> this.provisioningStatus.getTimeout()
|
||||
) {
|
||||
if (
|
||||
this.provisioningStatus == ProvisioningStatus.NONE
|
||||
|| this.provisioningStatus == ProvisioningStatus.SERIAL_INIT
|
||||
)
|
||||
this.initSerial(this.preferredPort);
|
||||
else if (
|
||||
this.provisioningStatus == ProvisioningStatus.OBTAINING_MAC_ADDRESS
|
||||
|| this.provisioningStatus == ProvisioningStatus.PROVISIONING
|
||||
)
|
||||
this.tryObtainMacAddress();
|
||||
else if (this.provisioningStatus == ProvisioningStatus.CONNECTING)
|
||||
this.changeStatus(ProvisioningStatus.CONNECTION_ERROR);
|
||||
else if (this.provisioningStatus == ProvisioningStatus.LOOKING_FOR_SERVER)
|
||||
this.changeStatus(ProvisioningStatus.COULD_NOT_FIND_SERVER);
|
||||
else if (!this.provisioningStatus.isError()) {
|
||||
this.changeStatus(ProvisioningStatus.CONNECTION_ERROR); // TIMEOUT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,9 +154,17 @@ public class ProvisioningHandler implements SerialListener {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSerialLog(@NotNull String str) {
|
||||
public void onSerialLog(@NotNull String str, boolean server) {
|
||||
if (!isRunning)
|
||||
return;
|
||||
if (!server) {
|
||||
this.hasLogs = true;
|
||||
if (provisioningStatus == ProvisioningStatus.NO_SERIAL_LOGS_ERROR) {
|
||||
// Recover the onboarding process if the user turned on the
|
||||
// tracker afterward
|
||||
this.changeStatus(ProvisioningStatus.OBTAINING_MAC_ADDRESS);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
provisioningStatus == ProvisioningStatus.OBTAINING_MAC_ADDRESS && str.contains("mac:")
|
||||
@@ -190,8 +218,8 @@ public class ProvisioningHandler implements SerialListener {
|
||||
}
|
||||
|
||||
public void changeStatus(ProvisioningStatus status) {
|
||||
this.lastStatusChange = System.currentTimeMillis();
|
||||
if (this.provisioningStatus != status) {
|
||||
this.lastStatusChange = System.currentTimeMillis();
|
||||
this.listeners
|
||||
.forEach(
|
||||
(l) -> l
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package dev.slimevr.serial;
|
||||
|
||||
import solarxr_protocol.rpc.WifiProvisioningStatus;
|
||||
|
||||
|
||||
public enum ProvisioningStatus {
|
||||
|
||||
NONE(WifiProvisioningStatus.NONE),
|
||||
SERIAL_INIT(WifiProvisioningStatus.SERIAL_INIT),
|
||||
PROVISIONING(WifiProvisioningStatus.PROVISIONING),
|
||||
OBTAINING_MAC_ADDRESS(WifiProvisioningStatus.OBTAINING_MAC_ADDRESS),
|
||||
CONNECTING(WifiProvisioningStatus.CONNECTING),
|
||||
CONNECTION_ERROR(WifiProvisioningStatus.CONNECTION_ERROR),
|
||||
LOOKING_FOR_SERVER(WifiProvisioningStatus.LOOKING_FOR_SERVER),
|
||||
COULD_NOT_FIND_SERVER(WifiProvisioningStatus.COULD_NOT_FIND_SERVER),
|
||||
DONE(WifiProvisioningStatus.DONE);
|
||||
|
||||
public final int id;
|
||||
|
||||
ProvisioningStatus(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package dev.slimevr.serial
|
||||
|
||||
import solarxr_protocol.rpc.WifiProvisioningStatus
|
||||
|
||||
enum class ProvisioningStatus(@JvmField val id: Int, val isError: Boolean, val timeout: Int = 10_000) {
|
||||
NONE(WifiProvisioningStatus.NONE, false, 3_000),
|
||||
SERIAL_INIT(WifiProvisioningStatus.SERIAL_INIT, false, 3_000),
|
||||
PROVISIONING(WifiProvisioningStatus.PROVISIONING, false),
|
||||
OBTAINING_MAC_ADDRESS(WifiProvisioningStatus.OBTAINING_MAC_ADDRESS, false),
|
||||
CONNECTING(WifiProvisioningStatus.CONNECTING, false, 30_000),
|
||||
CONNECTION_ERROR(WifiProvisioningStatus.CONNECTION_ERROR, true),
|
||||
LOOKING_FOR_SERVER(WifiProvisioningStatus.LOOKING_FOR_SERVER, false),
|
||||
COULD_NOT_FIND_SERVER(WifiProvisioningStatus.COULD_NOT_FIND_SERVER, true),
|
||||
NO_SERIAL_LOGS_ERROR(WifiProvisioningStatus.NO_SERIAL_LOGS_ERROR, true),
|
||||
NO_SERIAL_DEVICE_FOUND(WifiProvisioningStatus.NO_SERIAL_DEVICE_FOUND, true),
|
||||
DONE(WifiProvisioningStatus.DONE, false),
|
||||
}
|
||||
@@ -23,7 +23,9 @@ abstract class SerialPort {
|
||||
interface SerialListener {
|
||||
fun onSerialConnected(port: SerialPort)
|
||||
fun onSerialDisconnected()
|
||||
fun onSerialLog(str: String)
|
||||
|
||||
// var server indicates if the log is injected by the server (not an actual serial log)
|
||||
fun onSerialLog(str: String, server: Boolean)
|
||||
fun onNewSerialDevice(port: SerialPort)
|
||||
|
||||
// This is called when the serial diver does not see the device anymore
|
||||
|
||||
@@ -204,9 +204,9 @@ class DesktopSerialHandler :
|
||||
}
|
||||
}
|
||||
|
||||
fun addLog(str: String) {
|
||||
fun addLog(str: String, server: Boolean = true) {
|
||||
LogManager.info("[Serial] $str")
|
||||
listeners.forEach { it.onSerialLog(str) }
|
||||
listeners.forEach { it.onSerialLog(str, server) }
|
||||
}
|
||||
|
||||
override fun getListeningEvents(): Int = (
|
||||
@@ -219,7 +219,7 @@ class DesktopSerialHandler :
|
||||
SerialPort.LISTENING_EVENT_DATA_RECEIVED -> {
|
||||
val newData = event.receivedData
|
||||
val s = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(newData)).toString()
|
||||
addLog(s)
|
||||
addLog(s, false)
|
||||
}
|
||||
|
||||
SerialPort.LISTENING_EVENT_PORT_DISCONNECTED -> {
|
||||
|
||||
Submodule solarxr-protocol updated: 74cdc8b7be...3e87ab0a33
Reference in New Issue
Block a user