Skip to content

Commit

Permalink
Add question display
Browse files Browse the repository at this point in the history
  • Loading branch information
bcopy committed Oct 13, 2024
1 parent 7ea0354 commit 93f68bc
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 21 deletions.
11 changes: 6 additions & 5 deletions doc/homie-device-hierarchy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,8 @@ devices:
name: Display Luminosity
datatype: integer
unit: "%"
vote:
name: Voting round
vote-X:
name: Voting round X
state: ready
nodes:
config:
Expand All @@ -283,9 +283,10 @@ devices:
question-statement:
name: Question Statement
datatype: string
voting-open:
name: Voting Status
datatype: boolean
state:
name: Voting state
datatype: enum
format: ready,active,finished
total-votes:
name: Total Votes Cast
datatype: integer
Expand Down
35 changes: 34 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,23 @@
"build": "webpack --mode production"
},
"bin": {
"create-test-players": "./src/bin/create-test-players.js"
"create-test-players": "./src/bin/create-test-players.js",
"create-vote-device": "./src/bin/create-vote-device.js"
},
"dependencies": {
"@cmcrobotics/homie-lit": "^0.7.3",
"@tweenjs/tween.js": "25.0.0",
"aframe": "^1.6.0",
"aframe-draw-component": "^1.5.0",
"aframe-extras": "^7.5.1",
"aframe-htmlembed-component": "^1.0.0",
"aframe-label": "^0.1.3",
"aframe-orbit-controls": "^1.3.2",
"aframe-textwrap-component": "^1.0.1",
"browserify-zlib": "^0.2.0",
"buffer": "^6.0.3",
"https-browserify": "^1.0.0",
"js-yaml": "^4.1.0",
"lit-html": "^3.2.1",
"loglevel": "^1.9.2",
"mqtt": "^4.3.7",
Expand All @@ -29,7 +33,8 @@
"reveal.js": "^5.1.0",
"rxjs": "^7.8.0",
"stream-http": "^3.2.0",
"url": "^0.11.4"
"url": "^0.11.4",
"uuid": "^10.0.0"
},
"devDependencies": {
"copy-webpack-plugin": "^12.0.2",
Expand Down
32 changes: 32 additions & 0 deletions public/questions/vote-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
questions:
- question-id: Q1
question-statement: "What is the capital of France?"
option-1: "London"
option-2: "Berlin"
option-3: "Paris"
option-4: "Madrid"
correct-option: 3

- question-id: Q2
question-statement: "Which planet is known as the Red Planet?"
option-1: "Venus"
option-2: "Mars"
option-3: "Jupiter"
option-4: "Saturn"
correct-option: 2

- question-id: Q3
question-statement: "Who painted the Mona Lisa?"
option-1: "Vincent van Gogh"
option-2: "Pablo Picasso"
option-3: "Leonardo da Vinci"
option-4: "Michelangelo"
correct-option: 3

- question-id: Q4
question-statement: "Some Super Long Question that makes little sense but it's okay it'll be fine and then "
option-1: "Long long long answer that's just very very long just fine fine fine just fine fine fine and then some more"
option-2: "Long long long answer that's just very very long just fine fine fine just fine fine fine and then some more"
option-3: "Long long long answer that's just very very long just fine fine fine just fine fine fine and then some more"
option-4: "Long long long answer that's just very very long just fine fine fine just fine fine fine and then some more"
correct-option: 3
2 changes: 2 additions & 0 deletions public/quizz.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@

<a-sky src="#skybox" ></a-sky>

<a-entity id="questions" position="0 6 27"></a-entity>


<a-entity id="teams" position="0 0.1 28"></a-entity>

Expand Down
113 changes: 113 additions & 0 deletions src/bin/create-vote-device.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env node

const mqtt = require('mqtt');
const { v4: uuidv4 } = require('uuid');
const yaml = require('js-yaml');
const fs = require('fs');

// MQTT broker URL - replace with your actual MQTT broker URL
const brokerUrl = 'mqtt://localhost:1883';

// Function to read YAML file
function readYamlFile(filePath) {
try {
const fileContents = fs.readFileSync(filePath, 'utf8');
const data = yaml.load(fileContents);
return data;
} catch (e) {
console.log(e);
return null;
}
}

// Function to create and publish vote device
function createVoteDevice(question) {
const client = mqtt.connect(brokerUrl);

client.on('connect', () => {
console.log('Connected to MQTT broker');

const deviceId = `vote-${uuidv4()}`;
const baseTopic = 'homie/'+deviceId;

// Publish device properties
client.publish(`${baseTopic}/$homie`, '4.0', { retain: true });
client.publish(`${baseTopic}/$name`, `Vote ${question['question-id']}`, { retain: true });
client.publish(`${baseTopic}/$nodes`, 'config', { retain: true });

// Publish config node properties
client.publish(`${baseTopic}/config/$name`, 'Vote Configuration', { retain: true });
client.publish(`${baseTopic}/config/$type`, 'vote-config', { retain: true });
client.publish(`${baseTopic}/config/$properties`, 'question-id,question-statement,option-1,option-2,option-3,option-4,correct-option,state', { retain: true });

// Publish question-id property
client.publish(`${baseTopic}/config/question-id`, question['question-id'], { retain: true });
client.publish(`${baseTopic}/config/question-id/$name`, 'Question ID', { retain: true });
client.publish(`${baseTopic}/config/question-id/$datatype`, 'string', { retain: true });
client.publish(`${baseTopic}/config/question-id/$settable`, 'false', { retain: true });

// Publish question-statement property
client.publish(`${baseTopic}/config/question-statement`, question['question-statement'], { retain: true });
client.publish(`${baseTopic}/config/question-statement/$name`, 'Question Statement', { retain: true });
client.publish(`${baseTopic}/config/question-statement/$datatype`, 'string', { retain: true });
client.publish(`${baseTopic}/config/question-statement/$settable`, 'false', { retain: true });

// Publish individual option properties
for (let i = 1; i <= 4; i++) {
const optionKey = `option-${i}`;
client.publish(`${baseTopic}/config/${optionKey}`, question[optionKey], { retain: true });
client.publish(`${baseTopic}/config/${optionKey}/$name`, `Option ${i}`, { retain: true });
client.publish(`${baseTopic}/config/${optionKey}/$datatype`, 'string', { retain: true });
client.publish(`${baseTopic}/config/${optionKey}/$settable`, 'false', { retain: true });
}

// Publish correct-option property
client.publish(`${baseTopic}/config/correct-option`, question['correct-option'].toString(), { retain: true });
client.publish(`${baseTopic}/config/correct-option/$name`, 'Correct Option', { retain: true });
client.publish(`${baseTopic}/config/correct-option/$datatype`, 'integer', { retain: true });
client.publish(`${baseTopic}/config/correct-option/$settable`, 'false', { retain: true });
client.publish(`${baseTopic}/config/correct-option/$format`, '1:4', { retain: true });

// Publish state property
client.publish(`${baseTopic}/config/state`, 'ready', { retain: true });
client.publish(`${baseTopic}/config/state/$name`, 'State', { retain: true });
client.publish(`${baseTopic}/config/state/$datatype`, 'enum', { retain: true });
client.publish(`${baseTopic}/config/state/$settable`, 'true', { retain: true });
client.publish(`${baseTopic}/config/state/$format`, 'ready,active,finished', { retain: true });

console.log(`Vote device created with ID: ${deviceId}`);
console.log('Question ID:', question['question-id']);
console.log('Question Statement:', question['question-statement']);
console.log('Options:');
for (let i = 1; i <= 4; i++) {
console.log(` Option ${i}:`, question[`option-${i}`]);
}
console.log('Correct Option:', question['correct-option']);

client.end();
});

client.on('error', (error) => {
console.error('Error:', error);
client.end();
});
}

// Main execution
const args = process.argv.slice(2);
if (args.length !== 2) {
console.log('Usage: node create-vote-device.js <path-to-yaml-file> <question-index>');
process.exit(1);
}

const yamlFilePath = args[0];
const questionIndex = parseInt(args[1]);

const voteConfig = readYamlFile(yamlFilePath);
if (!voteConfig || !voteConfig.questions || questionIndex >= voteConfig.questions.length) {
console.log('Invalid YAML file or question index');
process.exit(1);
}

const selectedQuestion = voteConfig.questions[questionIndex];
createVoteDevice(selectedQuestion);
4 changes: 3 additions & 1 deletion src/quizz-scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import './components/look-towards';
import 'aframe-extras';
import 'aframe-label';
import 'aframe-htmlembed-component';
import 'aframe-draw-component';
import 'aframe-textwrap-component';


// Polyfill global Buffer
Expand All @@ -18,6 +20,6 @@ window.Buffer = Buffer;

AFRAME.registerComponent('scene-controller', {
init: function() {
this.controller = new QuizzSceneController('ws://localhost:9001', 'teams');
this.controller = new QuizzSceneController('ws://localhost:9001', 'teams', 'questions');
}
});
Loading

0 comments on commit 93f68bc

Please sign in to comment.