Skip to content

Commit

Permalink
Kevin/pat device integration (#3997)
Browse files Browse the repository at this point in the history
* add env var to skip paper handler hardware check

* pollworker screen supports disabled paper handler hardware check

* add basic mock driver and allow server to start without hardware

* support PAT status detection in state machine

* add support for PAT input and calibration

* update readme and package files

* clean up rebase

* update comment

* PR feedback

* restructure for portrait screen orientation

* fix state machine test

* update copy

* add frontend tests

* fix backend tests

* default case to throwIllegalValue

* fix rebase
  • Loading branch information
kshen0 authored Oct 10, 2023
1 parent 45d53da commit 267a0d7
Show file tree
Hide file tree
Showing 41 changed files with 1,642 additions and 376 deletions.
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ REACT_APP_VX_CAST_VOTE_RECORD_OPTIMIZATION_EXCLUDE_REDUNDANT_METADATA=TRUE
REACT_APP_VX_DISABLE_BALLOT_BOX_CHECK=FALSE
REACT_APP_VX_CONVERTER=ms-sems
REACT_APP_VX_PRECINCT_REPORT_DESTINATION=thermal-sheet-printer
REACT_APP_VX_DISABLE_BALLOT_BOX_CHECK=FALSE
REACT_APP_VX_SKIP_PAPER_HANDLER_HARDWARE_CHECK=FALSE
15 changes: 15 additions & 0 deletions apps/mark-scan/backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@ Follow the instructions in the [VxSuite README](../../../README.md)
You generally should not need to run the backend directly. Instead, run the
frontend, which will automatically run the backend.

For the backend to recognize the USB PAT switch you may need to extend your udev
rules. Create or edit `/etc/udev/rules.d/50-usb-hid.rules` with:

```
SUBSYSTEM=="input", GROUP="input", MODE="0666"
SUBSYSTEM=="usb", ATTR{idVendor}=="0a95", ATTR{idProduct}=="0012", MODE="0666", GROUP="plugdev"
KERNEL=="hidraw*", ATTRS{idVendor}=="0a95", ATTRS{idProduct}=="0012", MODE="0666", GROUP="plugdev"
```

then run

```
sudo udevadm control --reload-rules && sudo udevadm trigger
```

```sh
cd apps/mark/frontend
pnpm start
Expand Down
3 changes: 3 additions & 0 deletions apps/mark-scan/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"@votingworks/grout": "workspace:*",
"@votingworks/image-utils": "workspace:*",
"@votingworks/logging": "workspace:*",
"@votingworks/message-coder": "workspace:*",
"@votingworks/types": "workspace:*",
"@votingworks/usb-drive": "workspace:*",
"@votingworks/utils": "workspace:*",
Expand All @@ -57,6 +58,7 @@
"fs-extra": "^11.1.1",
"js-sha256": "^0.9.0",
"luxon": "^3.0.0",
"node-hid": "^2.1.2",
"rxjs": "^7.8.1",
"tmp": "^0.2.1",
"uuid": "^9.0.0",
Expand All @@ -71,6 +73,7 @@
"@types/jest": "^29.5.3",
"@types/luxon": "^3.0.0",
"@types/node": "16.18.23",
"@types/node-hid": "^1.3.2",
"@types/tmp": "^0.2.3",
"@types/uuid": "^9.0.2",
"@votingworks/test-utils": "workspace:*",
Expand Down
17 changes: 17 additions & 0 deletions apps/mark-scan/backend/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import {
InterpretedBmdPage,
} from '@votingworks/types';
import {
BooleanEnvironmentVariableName,
isElectionManagerAuth,
isFeatureFlagEnabled,
singlePrecinctSelectionFor,
} from '@votingworks/utils';

Expand Down Expand Up @@ -181,10 +183,25 @@ export function buildApi(
},

setAcceptingPaperState(): void {
if (
isFeatureFlagEnabled(
BooleanEnvironmentVariableName.SKIP_PAPER_HANDLER_HARDWARE_CHECK
)
) {
return;
}

assert(stateMachine);

stateMachine.setAcceptingPaper();
},

setPatDeviceIsCalibrated(): void {
assert(stateMachine, 'No state machine');

stateMachine.setPatDeviceIsCalibrated();
},

printBallot(input: { pdfData: Buffer }): void {
assert(stateMachine);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { join } from 'path';
import { LogSource, Logger } from '@votingworks/logging';
import { createWorkspace } from '../../util/workspace';
import { MARK_SCAN_WORKSPACE } from '../../globals';
import { DEV_PAPER_HANDLER_STATUS_POLLING_INTERVAL_MS } from '../constants';
import {
AUTH_STATUS_POLLING_INTERVAL_MS,
DEV_DEVICE_STATUS_POLLING_INTERVAL_MS,
} from '../constants';
import {
PaperHandlerStateMachine,
getPaperHandlerStateMachine,
Expand Down Expand Up @@ -79,13 +82,14 @@ export async function main(): Promise<number> {
'Could not get paper handler driver. Is a paper handler device connected?'
);

const stateMachine = await getPaperHandlerStateMachine(
driver,
const stateMachine = await getPaperHandlerStateMachine({
workspace,
auth,
logger,
DEV_PAPER_HANDLER_STATUS_POLLING_INTERVAL_MS
);
driver,
devicePollingIntervalMs: DEV_DEVICE_STATUS_POLLING_INTERVAL_MS,
authPollingIntervalMs: AUTH_STATUS_POLLING_INTERVAL_MS,
});
assert(stateMachine !== undefined, 'Unexpected undefined state machine');

stateMachine.setAcceptingPaper();
Expand Down
11 changes: 7 additions & 4 deletions apps/mark-scan/backend/src/custom-paper-handler/constants.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
export const PAPER_HANDLER_STATUS_POLLING_INTERVAL_MS = 200;
export const DEVICE_STATUS_POLLING_INTERVAL_MS = 200;
export const AUTH_STATUS_POLLING_INTERVAL_MS = 200;

// Slower interval for limited hardware
export const DEV_PAPER_HANDLER_STATUS_POLLING_INTERVAL_MS = 750;
export const DEV_AUTH_STATUS_POLLING_INTERVAL_MS = 750;
export const DEV_DEVICE_STATUS_POLLING_INTERVAL_MS = 1000;
export const DEV_AUTH_STATUS_POLLING_INTERVAL_MS = 1000;

export const PAPER_HANDLER_STATUS_POLLING_TIMEOUT_MS = 30_000;
export const DEVICE_STATUS_POLLING_TIMEOUT_MS = 30_000;
export const AUTH_STATUS_POLLING_TIMEOUT_MS = 30_000;
export const RESET_DELAY_MS = 8_000;
export const RESET_AFTER_JAM_DELAY_MS = 3_000;
Expand All @@ -15,3 +15,6 @@ export const DELAY_BEFORE_DECLARING_REAR_JAM_MS = 3_000;

export const SCAN_DPI = 72;
export const PRINT_DPI = 200;

export const ORIGIN_VENDOR_ID = 0x0a95;
export const ORIGIN_SWIFTY_PRODUCT_ID = 0x0012;
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
PaperHandlerDriver,
MinimalWebUsbDevice,
PaperHandlerStatus,
defaultPaperHandlerStatus,
} from '@votingworks/custom-paper-handler';
import { dirSync } from 'tmp';
import { Logger, fakeLogger } from '@votingworks/logging';
Expand All @@ -12,7 +13,6 @@ import {
getPaperHandlerStateMachine,
} from './state_machine';
import { Workspace, createWorkspace } from '../util/workspace';
import { defaultPaperHandlerStatus } from '../../test/app_helpers';

// Use shorter polling interval in tests to reduce run times
const TEST_POLLING_INTERVAL_MS = 10;
Expand Down Expand Up @@ -44,13 +44,14 @@ beforeEach(async () => {
.spyOn(driver, 'getPaperHandlerStatus')
.mockImplementation(() => Promise.resolve(defaultPaperHandlerStatus()));

machine = (await getPaperHandlerStateMachine(
driver,
machine = (await getPaperHandlerStateMachine({
workspace,
auth,
logger,
TEST_POLLING_INTERVAL_MS
)) as PaperHandlerStateMachine;
driver,
devicePollingIntervalMs: TEST_POLLING_INTERVAL_MS,
authPollingIntervalMs: TEST_POLLING_INTERVAL_MS,
})) as PaperHandlerStateMachine;
});

afterEach(() => {
Expand Down
Loading

0 comments on commit 267a0d7

Please sign in to comment.