Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: add ability to send NMEA 2000 out with the Data Fiddler #1755

Merged
merged 8 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
133 changes: 93 additions & 40 deletions packages/server-admin-ui/src/views/Playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,16 @@ class Playground extends Component {
data: [],
deltas: [],
n2kJson: [],
n2kOutAvailable: false,
input,
inputIsJson: isJson(input),
sending: false,
sendingN2K: false,
activeTab: DELTAS_TAB_ID,
}

this.handleExecute = this.handleExecute.bind(this)
this.handleSendN2K = this.handleSendN2K.bind(this)
this.handleInput = this.handleInput.bind(this)
this.send = this.send.bind(this)
this.beautify = this.beautify.bind(this)
Expand All @@ -77,6 +80,10 @@ class Playground extends Component {
this.send(true)
}

handleSendN2K() {
this.send(false, true)
}

componentDidMount() {
if (this.state.input && this.state.input.length > 0) {
this.send(false)
Expand All @@ -95,14 +102,15 @@ class Playground extends Component {
deltas: [],
putResults: [],
n2kJson: [],
n2kOutAvailable: false,
error: 'invalid json',
jsonError: error.message,
activeTab: LINT_ERROR_TAB_ID,
})
}
}

send(sendToServer) {
send(sendToServer, sendToN2K) {
let start = this.state.input.trim().charAt(0)
if (start === '{' || start === '[') {
try {
Expand All @@ -117,6 +125,7 @@ class Playground extends Component {
deltas: [],
putResults: [],
n2kJson: [],
n2kOutAvailable: false,
error: 'invalid json',
jsonError: error.message,
activeTab: LINT_ERROR_TAB_ID,
Expand All @@ -125,11 +134,14 @@ class Playground extends Component {
}
}

const body = { value: this.state.input, sendToServer }
const body = { value: this.state.input, sendToServer, sendToN2K }
localStorage.setItem(inputStorageKey, this.state.input)
if (sendToServer) {
this.setState({ ...this.state, sending: true })
}
if (sendToN2K) {
this.setState({ ...this.state, sendingN2K: true })
}
fetch(`${window.serverRoutesPrefix}/inputTest`, {
method: 'POST',
credentials: 'include',
Expand All @@ -140,9 +152,9 @@ class Playground extends Component {
})
.then((response) => response.json())
.then((data) => {
if (sendToServer) {
if (sendToServer || sendToN2K) {
setTimeout(() => {
this.setState({ ...this.state, sending: false })
this.setState({ ...this.state, sending: false, sendingN2K: false })
}, 1000)
}
if (data.error) {
Expand All @@ -152,6 +164,7 @@ class Playground extends Component {
deltas: [],
putResults: [],
n2kJson: [],
n2kOutAvailable: false,
jsonError: null,
error: data.error,
})
Expand Down Expand Up @@ -198,6 +211,7 @@ class Playground extends Component {
data: values,
deltas: data.deltas,
n2kJson: data.n2kJson,
n2kOutAvailable: data.n2kOutAvailable,
putResults: data.putResults,
jsonError: null,
})
Expand All @@ -211,11 +225,12 @@ class Playground extends Component {
deltas: [],
putResults: [],
n2kJson: [],
n2kOutAvailable: false,
error: error.message,
jsonError: null,
})
if (sendToServer) {
this.setState({ ...this.state, sending: false })
if (sendToServer || sendToN2K) {
this.setState({ ...this.state, sending: false, sendingN2K: false })
}
})
}
Expand Down Expand Up @@ -245,7 +260,12 @@ class Playground extends Component {
<Col xs="12" md="12">
<FormText color="muted">
You can enter multi-line raw NMEA 2000, NMEA 0183 or
Signal K deltas (one delta or an array)
Signal K deltas (one delta or an array). For sending
PGNs out over the servers NMEA 2000 connection, use
one of the formats{' '}
<a href="/documentation/develop/plugins/deltas.html?highlight=NMEA%202000%20json#sending-nmea-2000-data-from-a-plugin">
here
</a>
</FormText>
<Input
type="textarea"
Expand All @@ -259,39 +279,71 @@ class Playground extends Component {
</Form>
</CardBody>
<CardFooter>
<Button
size="sm"
color="primary"
className="float-left"
disabled={!this.state.inputIsJson}
onClick={this.beautify}
>
<i className="fa fa-dot-circle-o" /> Beautify JSON
</Button>
<span
className="float-left"
style={{ paddingLeft: '10px', paddingTop: '0.25rem' }}
>
{' '}
{this.state.error && (
<p className="text-danger">{this.state.error}</p>
)}
</span>{' '}
<Button
size="sm"
color="primary"
onClick={this.handleExecute}
className="float-right"
>
<i
className={
this.state.sending
? 'fa fa-spinner fa-spin'
: 'fa fa-dot-circle-o'
}
/>{' '}
Send To Server
</Button>
<Row style={{ paddingBottom: '0.25rem' }}>
<Col>
<Button
size="sm"
color="primary"
className="float-left"
disabled={!this.state.inputIsJson}
onClick={this.beautify}
>
<i className="fa fa-dot-circle-o" /> Beautify JSON
</Button>
</Col>

<Col>
<Button
size="sm"
color="primary"
onClick={this.handleExecute}
className="float-right"
>
<i
className={
this.state.sending
? 'fa fa-spinner fa-spin'
: 'fa fa-dot-circle-o'
}
/>{' '}
Send To Server
</Button>
</Col>
</Row>
<Row style={{ paddingBottom: '0.25rem' }}>
<Col className="text-right">
<Button
size="sm"
color="primary"
disabled={
!(
this.state.n2kJson &&
this.state.n2kJson.length > 0 &&
this.state.n2kOutAvailable
)
}
onClick={this.handleSendN2K}
>
<i
className={
this.state.sendingN2K
? 'fa fa-spinner fa-spin'
: 'fa fa-dot-circle-o'
}
/>{' '}
Send as PGN to server&apos;s NMEA2000 connection
</Button>
</Col>
</Row>
<Row>
<Col>
<span className="float-right">
{this.state.error && (
<p className="text-danger">{this.state.error}</p>
)}
</span>
</Col>
</Row>
</CardFooter>
</Card>
</Col>
Expand Down Expand Up @@ -326,6 +378,7 @@ class Playground extends Component {
</NavLink>
</NavItem>
)}

{this.state.n2kJson && this.state.n2kJson.length > 0 && (
<NavItem>
<NavLink
Expand Down
24 changes: 22 additions & 2 deletions src/interfaces/playground.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,16 @@ const {

const serverRoutesPrefix = '/skServer'

let n2kOutAvailable = false

module.exports = function (app) {
const n2kMapper = new N2kMapper({ app }, app.propertyValues)
const pgnParser = new FromPgn({}, app.propertyValues)

app.on('nmea2000OutAvailable', () => {
n2kOutAvailable = true
})

const processors = {
n2k: (msgs, sendToServer) => {
const n2kJson = []
Expand All @@ -46,7 +52,7 @@ module.exports = function (app) {
return n2kMapper.toDelta(n2k)
}
})
return { deltas, n2kJson: n2kJson }
return { deltas, n2kJson: n2kJson, n2kOutAvailable }
},
'0183': (msgs) => {
const parser = new Parser0183({ app })
Expand Down Expand Up @@ -97,9 +103,10 @@ module.exports = function (app) {

app.post(`${serverRoutesPrefix}/inputTest`, (req, res) => {
const sendToServer = req.body.sendToServer
const sendToN2K = req.body.sendToN2K

if (
sendToServer &&
(sendToServer || sendToN2K) &&
!app.securityStrategy.isDummy() &&
!app.securityStrategy.allowConfigure(req)
) {
Expand All @@ -114,6 +121,13 @@ module.exports = function (app) {
return
}

if (sendToN2K && type != 'n2k-json' && type != 'n2k') {
res.status(400).json({
error: 'Please enter NMEA 2000 json format or Actisense format'
})
return
}

if (type === 'signalk') {
let puts = []
if (sendToServer) {
Expand Down Expand Up @@ -171,6 +185,12 @@ module.exports = function (app) {
} else {
res.json({ deltas: msgs })
}
} else if (sendToN2K) {
const event = type == 'n2k' ? 'nmea2000out' : 'nmea2000JsonOut'
msgs.forEach((msg) => {
app.emit(event, msg)
})
res.json({ deltas: [] })
} else {
try {
const data = processors[type](msgs, sendToServer)
Expand Down