From 64c132ab978b5e14beca7d6017686f828650e321 Mon Sep 17 00:00:00 2001 From: hughbarney Date: Mon, 15 Nov 2021 21:19:02 +0000 Subject: [PATCH 1/4] Health: added bar charts --- apps.json | 10 +-- apps/health/ChangeLog | 1 + apps/health/app.js | 174 ++++++++++++++++++++++++++++++------------ 3 files changed, 132 insertions(+), 53 deletions(-) diff --git a/apps.json b/apps.json index 2ee8a0e49..f307a6feb 100644 --- a/apps.json +++ b/apps.json @@ -82,7 +82,7 @@ { "id": "health", "name": "Health Tracking", - "version": "0.06", + "version": "0.07", "description": "Logs health data and provides an app to view it (BETA - requires firmware 2v11)", "icon": "app.png", "tags": "tool,system,health", @@ -3467,7 +3467,7 @@ "id": "widgps", "name": "GPS Widget", "version": "0.03", - "description": "Tiny widget to show the power on/off status of the GPS. Require firmware v2.08.167 or later", + "description": "Tiny widget to show the power on/off status of the GPS", "icon": "widget.png", "type": "widget", "tags": "widget,gps", @@ -3481,7 +3481,7 @@ "id": "widhrt", "name": "HRM Widget", "version": "0.03", - "description": "Tiny widget to show the power on/off status of the Heart Rate Monitor. Requires firmware v2.08.167 or later", + "description": "Tiny widget to show the power on/off status of the Heart Rate Monitor", "icon": "widget.png", "type": "widget", "tags": "widget,hrm", @@ -3524,7 +3524,7 @@ "id": "widcom", "name": "Compass Widget", "version": "0.02", - "description": "Tiny widget to show the power on/off status of the Compass. Requires firmware v2.08.167 or later", + "description": "Tiny widget to show the power on/off status of the Compass", "icon": "widget.png", "type": "widget", "tags": "widget,compass", @@ -3665,7 +3665,7 @@ "id": "kitchen", "name": "Kitchen Combo", "version": "0.13", - "description": "Combination of the Stepo, Walkersclock, Arrow and Waypointer apps into a multiclock format. 'Everything but the kitchen sink'. Requires firmware v2.08.167 or later", + "description": "Combination of the Stepo, Walkersclock, Arrow and Waypointer apps into a multiclock format. 'Everything but the kitchen sink'", "icon": "kitchen.png", "type": "clock", "tags": "tool,outdoors,gps", diff --git a/apps/health/ChangeLog b/apps/health/ChangeLog index ef1b1bffc..5eb96a0ea 100644 --- a/apps/health/ChangeLog +++ b/apps/health/ChangeLog @@ -5,3 +5,4 @@ Don't restart HRM when changing apps if we've already got a good BPM value 0.05: Fix daily summary calculation 0.06: Fix daily health summary for movement (a line got deleted!) +0.07: Added coloured bar charts diff --git a/apps/health/app.js b/apps/health/app.js index 4d692e638..eae45c190 100644 --- a/apps/health/app.js +++ b/apps/health/app.js @@ -7,6 +7,8 @@ function setSettings(s) { } function menuMain() { + swipe_enabled = false; + clearButton(); E.showMenu({ "":{title:"Health Tracking"}, "< Back":()=>load(), @@ -18,6 +20,8 @@ function menuMain() { } function menuSettings() { + swipe_enabled = false; + clearButton(); var s=getSettings(); E.showMenu({ "":{title:"Health Tracking"}, @@ -32,6 +36,8 @@ function menuSettings() { } function menuStepCount() { + swipe_enabled = false; + clearButton(); E.showMenu({ "":{title:"Step Counting"}, "< Back":()=>menuMain(), @@ -41,6 +47,8 @@ function menuStepCount() { } function menuMovement() { + swipe_enabled = false; + clearButton(); E.showMenu({ "":{title:"Movement"}, "< Back":()=>menuMain(), @@ -50,6 +58,8 @@ function menuMovement() { } function menuHRM() { + swipe_enabled = false; + clearButton(); E.showMenu({ "":{title:"Heart Rate"}, "< Back":()=>menuMain(), @@ -66,14 +76,8 @@ function stepsPerHour() { g.clear(1); Bangle.drawWidgets(); g.reset(); - require("graph").drawBar(g, data, { - y:24, - miny: 0, - axes : true, - gridx : 6, - gridy : 500 - }); - Bangle.setUI("updown", ()=>menuStepCount()); + setButton(menuStepCount); + barChart("HOUR", data); } function stepsPerDay() { @@ -83,14 +87,8 @@ function stepsPerDay() { g.clear(1); Bangle.drawWidgets(); g.reset(); - require("graph").drawBar(g, data, { - y:24, - miny: 0, - axes : true, - gridx : 5, - gridy : 2000 - }); - Bangle.setUI("updown", ()=>menuStepCount()); + setButton(menuStepCount); + barChart("DAY", data); } function hrmPerHour() { @@ -105,14 +103,8 @@ function hrmPerHour() { g.clear(1); Bangle.drawWidgets(); g.reset(); - require("graph").drawBar(g, data, { - y:24, - miny: 0, - axes : true, - gridx : 6, - gridy : 20 - }); - Bangle.setUI("updown", ()=>menuHRM()); + setButton(menuHRM); + barChart("HOUR", data); } function hrmPerDay() { @@ -127,14 +119,8 @@ function hrmPerDay() { g.clear(1); Bangle.drawWidgets(); g.reset(); - require("graph").drawBar(g, data, { - y:24, - miny: 0, - axes : true, - gridx : 5, - gridy : 20 - }); - Bangle.setUI("updown", ()=>menuHRM()); + setButton(menuHRM); + barChart("DAY", data); } function movementPerHour() { @@ -144,14 +130,8 @@ function movementPerHour() { g.clear(1); Bangle.drawWidgets(); g.reset(); - require("graph").drawLine(g, data, { - y:24, - miny: 0, - axes : true, - gridx : 6, - ylabel : null - }); - Bangle.setUI("updown", ()=>menuMovement()); + setButton(menuMovement); + barChart("HOUR", data); } function movementPerDay() { @@ -161,14 +141,112 @@ function movementPerDay() { g.clear(1); Bangle.drawWidgets(); g.reset(); - require("graph").drawBar(g, data, { - y:24, - miny: 0, - axes : true, - gridx : 5, - ylabel : null - }); - Bangle.setUI("updown", ()=>menuMovement()); + setButton(menuMovement); + barChart("DAY", data); +} + +// Bar Chart Code + +const w = g.getWidth(); +const h = g.getHeight(); + +var data_len; +var chart_index; +var chart_max_datum; +var chart_label; +var chart_data; +var swipe_enabled = false; +var btn; + +// find the max value in the array, using a loop due to array size +function max(arr) { + var m = -Infinity; + + for(var i=0; i< arr.length; i++) + if(arr[i] > m) m = arr[i]; + return m; +} + +// find the end of the data, the array might be for 31 days but only have 2 days of data in it +function get_data_length(arr) { + var nlen = arr.length; + + for(var i = arr.length - 1; i > 0 && arr[i] == 0; i--) + nlen--; + + return nlen; +} + +function barChart(label, dt) { + data_len = get_data_length(dt); + chart_index = Math.max(data_len - 5, -5); // choose initial index that puts the last day on the end + chart_max_datum = max(dt); // find highest bar, for scaling + chart_label = label; + chart_data = dt; + drawBarChart(); + swipe_enabled = true; +} + +function drawBarChart() { + const bar_bot = 140; + const bar_width = (w - 2) / 9; // we want 9 bars, bar 5 in the centre + var bar_top; + var bar; + + g.setColor(g.theme.bg); + g.fillRect(0,24,w,h); + + for (bar = 1; bar < 10; bar++) { + if (bar == 5) { + g.setFont('6x8', 2); + g.setFontAlign(0,-1) + g.setColor(g.theme.fg); + g.drawString(chart_label + " " + (chart_index + bar -1) + " " + chart_data[chart_index + bar - 1], g.getWidth()/2, 150); + g.setColor("#00f"); + } else { + g.setColor("#0ff"); + } + + // draw a fake 0 height bar if chart_index is outside the bounds of the array + if ((chart_index + bar - 1) >= 0 && (chart_index + bar - 1) < data_len) + bar_top = bar_bot - 100 * (chart_data[chart_index + bar - 1]) / chart_max_datum; + else + bar_top = bar_bot; + + g.fillRect( 1 + (bar - 1)* bar_width, bar_bot, 1 + bar*bar_width, bar_top); + g.setColor(g.theme.fg); + g.drawRect( 1 + (bar - 1)* bar_width, bar_bot, 1 + bar*bar_width, bar_top); + } +} + +function next_bar() { + chart_index = Math.min(data_len - 5, chart_index + 1); +} + +function prev_bar() { + // HOUR data starts at index 0, DAY data starts at index 1 + chart_index = Math.max((chart_label == "DAY") ? -3 : -4, chart_index - 1); +} + +Bangle.on('swipe', dir => { + if (!swipe_enabled) return; + if (dir == 1) prev_bar(); else next_bar(); + drawBarChart(); +}); + +// use setWatch() as Bangle.setUI("updown",..) interacts with swipes +function setButton(fn) { + if (process.env.HWVERSION == 1) + btn = setWatch(fn, BTN2); + else + btn = setWatch(fn, BTN1); +} + +function clearButton() { + if (btn !== undefined) { + clearWatch(btn); + btn = undefined; + } } Bangle.loadWidgets(); From 537842a32109bcc0ab69d5cd2474a87518bbcd41 Mon Sep 17 00:00:00 2001 From: jeffyactive Date: Tue, 16 Nov 2021 08:05:41 -0500 Subject: [PATCH 2/4] Added emojuino v0.01 --- apps.json | 15 ++++ apps/emojuino/ChangeLog | 1 + apps/emojuino/README.md | 23 ++++++ apps/emojuino/emojuino-icon.js | 1 + apps/emojuino/emojuino.js | 145 +++++++++++++++++++++++++++++++++ apps/emojuino/emojuino.png | Bin 0 -> 1966 bytes 6 files changed, 185 insertions(+) create mode 100644 apps/emojuino/ChangeLog create mode 100644 apps/emojuino/README.md create mode 100644 apps/emojuino/emojuino-icon.js create mode 100644 apps/emojuino/emojuino.js create mode 100644 apps/emojuino/emojuino.png diff --git a/apps.json b/apps.json index f307a6feb..a0d543cd8 100644 --- a/apps.json +++ b/apps.json @@ -4215,5 +4215,20 @@ { "name": "qalarm.wid.js", "url": "widget.js" } ], "data": [{ "name": "qalarm.json" }] + }, + { + "id": "emojuno", + "name": "Emoji Broadcaster", + "shortName": "Emojuino", + "version": "0.01", + "description": "Emojis & Espruino: advertise Unicode emojis via BLE", + "icon": "emojuino.png", + "tags": "emoji", + "supports" : [ "BANGLEJS2" ], + "readme": "README.md", + "storage": [ + { "name": "emojuno.app.js", "url": "emojuino.js" }, + { "name": "emojuno.img", "url": "emojuino-icon.js", "evaluate": true } + ] } ] diff --git a/apps/emojuino/ChangeLog b/apps/emojuino/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/emojuino/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/emojuino/README.md b/apps/emojuino/README.md new file mode 100644 index 000000000..13879437e --- /dev/null +++ b/apps/emojuino/README.md @@ -0,0 +1,23 @@ +# Emojuino + +Emojis & Espruino! + +## Usage + +Select an emoji and then tap to transmit! + +## Features + +Currently implements a tiny subset of possible Unicode emojis. + +## Controls + +Swipe left/right to select the emoji to broadcast. Tap the screen to initiate the broadcast. Emoji will flash while broadcasting. + +## Requests + +[Contact reelyActive](https://www.reelyactive.com/contact/) for support/updates. + +## Creator + +Developed by [jeffyactive](https://github.com/jeffyactive) of [reelyActive](https://www.reelyactive.com) diff --git a/apps/emojuino/emojuino-icon.js b/apps/emojuino/emojuino-icon.js new file mode 100644 index 000000000..d56749250 --- /dev/null +++ b/apps/emojuino/emojuino-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkBiIAHkUoxGIwUiBxAAGiQVCAAeCkIWNCooADDBYWKDBYWEkc////+cyDBhxDCoQAD+YLDCw0YBQQVFAAYYCwIXFHQRDElGCJYgOCFw8vBwPyOgoJFGAg4BIoQWGDAhJCIwoLBHgYAGJQIjCIwguCnCRFRoeDGAZICAgOPFwaRGDAQfB/AwDBAYuCX44wDAgTrDBoIDBGYP/manBmYFBFYQPDwJeBD4iRGRoQ/FC4QqBEYIbERooTBCAeBNAIjBBQIDDAAggBG4IDDwQXBEQIDDUAgcCHASaBAYQTFMQpcFDYp+EEII9DAARRDFIIfDHIwXBVISlDC4YzD9wA0osFpwIF8lQqgWK8kAgEEBItABIIhGAAfgBoMABIoIChwX0jwED8oNBgoXFqAJBrwHD8IXEBwQNEEIYgFC4wAQ8MRC6sRC+BgULwIwHSINVpwuLC43kaAQABqgaHC4bZHAAkFqhGHGAovFAAYyDCwgwFL4IwGFxAwNFxIwG8lVCoSTEFw7bPCxAYNCxT0LIpIxMCpoyHFhI")) \ No newline at end of file diff --git a/apps/emojuino/emojuino.js b/apps/emojuino/emojuino.js new file mode 100644 index 000000000..3de92fa6c --- /dev/null +++ b/apps/emojuino/emojuino.js @@ -0,0 +1,145 @@ +/** + * Copyright reelyActive 2021 + * We believe in an open Internet of Things + */ + + +// Emojis are integer pairs with the form [ image, Unicode code point ] +// For code points see https://unicode.org/emoji/charts/emoji-list.html +const EMOJIS = [ + [ ':)', 0x1f642 ], // Slightly smiling + [ ':|', 0x1f610 ], // Neutral + [ ':(', 0x1f641 ], // Slightly frowning + [ '+1', 0x1f44d ], // Thumbs up + [ '-1', 0x1f44e ], // Thumbs down + [ '<3', 0x02764 ], // Heart +]; +const EMOJI_TRANSMISSION_MILLISECONDS = 5000; +const BLINK_PERIOD_MILLISECONDS = 500; +const TRANSMIT_BUZZ_MILLISECONDS = 200; +const CYCLE_BUZZ_MILLISECONDS = 50; + +// Non-user-configurable constants +const IMAGE_INDEX = 0; +const CODE_POINT_INDEX = 1; +const BTN_WATCH_OPTIONS = { repeat: true, debounce: 20, edge: "falling" }; +const UNICODE_CODE_POINT_ELIDED_UUID = [ 0x49, 0x6f, 0x49, 0x44, 0x55, + 0x54, 0x46, 0x2d, 0x33, 0x32 ]; + + +// Global variables +let emojiIndex = 0; +let isToggleOn = false; +let isTransmitting = false; +let lastDragX = 0; +let lastDragY = 0; + + +// Cycle through emojis +function cycleEmoji(isForward) { + if(isTransmitting) { return; } + + if(isForward) { + emojiIndex = (emojiIndex + 1) % EMOJIS.length; + } + else if(--emojiIndex < 0) { + emojiIndex = EMOJIS.length - 1; + } + + drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]); + Bangle.buzz(CYCLE_BUZZ_MILLISECONDS); +} + + +// Handle a touch: transmit displayed emoji +function handleTouch(zone, event) { + if(isTransmitting) { return; } + + let emoji = EMOJIS[emojiIndex]; + transmitEmoji(emoji[IMAGE_INDEX], emoji[CODE_POINT_INDEX], + EMOJI_TRANSMISSION_MILLISECONDS); + Bangle.buzz(TRANSMIT_BUZZ_MILLISECONDS); +} + + +// Transmit the given code point for the given duration in milliseconds, +// blinking the image once per second. +function transmitEmoji(image, codePoint, duration) { + let instance = [ 0x00, 0x00, (codePoint >> 24) & 0xff, + (codePoint >> 16) & 0xff, (codePoint >> 8) & 0xff, + codePoint & 0xff ]; + + require('ble_eddystone_uid').advertise(UNICODE_CODE_POINT_ELIDED_UUID, + instance); + isTransmitting = true; + + let displayIntervalId = setInterval(toggleImage, BLINK_PERIOD_MILLISECONDS, + image); + + setTimeout(terminateEmoji, duration, displayIntervalId); +} + + +// Terminate the emoji transmission +function terminateEmoji(displayIntervalId) { + NRF.setAdvertising({ }); + isTransmitting = false; + clearInterval(displayIntervalId); + drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]); +} + + +// Toggle the display between image/off +function toggleImage(image) { + if(isToggleOn) { + drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]); + } + else { + g.clear(); + } + isToggleOn = !isToggleOn; +} + + +// Draw the given emoji +function drawImage(image) { + g.clear(); + g.drawString(image, g.getWidth() / 2, g.getHeight() / 2); + g.flip(); +} + + +// Handle a drag event +function handleDrag(event) { + let isFingerReleased = (event.b === 0); + + if(isFingerReleased) { + let isHorizontalDrag = (Math.abs(lastDragX) >= Math.abs(lastDragY)) && + (lastDragX !== 0); + + if(isHorizontalDrag) { + cycleEmoji(lastDragX > 0); + } + } + else { + lastDragX = event.dx; + lastDragY = event.dy; + } +} + + +// Special function to handle display switch on +Bangle.on('lcdPower', (on) => { + if(on) { + drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]); + } +}); + + +// On start: display the first emoji and handle drag and touch events +g.clear(); +g.setFont('Vector', 80); +g.setFontAlign(0, 0); +drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]); +Bangle.on('touch', handleTouch); +Bangle.on('drag', handleDrag); diff --git a/apps/emojuino/emojuino.png b/apps/emojuino/emojuino.png new file mode 100644 index 0000000000000000000000000000000000000000..614cc025ea17ad4bb68c1530e7d6b62022c908fd GIT binary patch literal 1966 zcmV;f2T}NmP)LJKHJpZ9o4v%hLat-R-v2z)RjTneY4Fdow%p&un4r31H@y zrNicKUz;%@IsV@vQ7PsAVX4*rp{e9G-Din61uZJhvzO?@M=O-}>hp74uh7s#me>E^N;h`F)z8tX1 za(~$Bm19-ECx)I88+!Kp-kPr(KWX-fh|TL564_1luRBJjHR``SHo<#lyk_R0_sj(P zV9kCC%{Wb4PG6%7w;s^dyM_ZJb=*5hxQ=@04zDw6{g0~vSGX%u6>ai#; zM>TM8P}E*ZIh9KVWfkNpFoW5_Ttn4$@Xhd;OUR(csujGZ#C7gC-&&}Of*-EkPp7Wu ztC{MIlUxg$st?#9IPM{`sQFx?*^EscI|RoUsba5wmrk2cUse4LlvLPg?_dAWj4dbV z<8=qCBCL^jYjL)G{zpGj_%oW+fUkm{pNiP-=Qv@q@UHY-(N&T|z9!)#0%T zN2#)^S~AMXFQkzh4{1i85*oQ&O9Z^&srGgZ-grdKE1~tAxLNAZXv?o;Q^IdObB)@} zP1X!lzQlW4&vD-eEoh2>C%n~OpIIBHtGNv{pPbyzXI8vTY<_oT236RqBw;LrswjwM z5oa^zw@Z|j_khZUIc#GYMGZYIoGhWx76ET$kPpCWLsm6E>k<~XRcveSgXaRbw{%# zA*>M10%Sw1FvoIkOMRXIv;JH|)P#q+(yc#wQR*?Wic4$Pu(-8iL-$47q?`7BNjYDS z(@z!9X!KmNUDAfvgVLIZBeEcq*wa2} z!zz3FkdWuv&r2u~i?PSD1q(9PcCn5#f8#;1)Prk$Nc29b&y46nuLx*CQ|yDMh`7vb zsorj$r3l$sv+0(%#X_suNz$vq?ZQ&+TE)Xi#IAFH8*^${XGHIAJ|hB}Vh=pw?Eo^V z9>~t#Sz(P7cYYpsSdi7PzfWU+mg*<2-Z6cMVWsICv6K2N-C_FThKCtuML=8Zfwu@` z6YE{W)+}IyBIB=!JEIR@kcM#miuFCh*~hhskYXJ-WzxwU>Df`uHqS(!=U zSz#H&he^RHlad(q?#-x03;VyRsd`UsnUcb&PoEksXsbPLXdFPTFQLdtM*P{Wam^aN z*Bw`{)^)(BD81JO@9od-XUUgn1ywn*d%;2AFrAa|!NeQFIjde4yX;Vg}rTUCBq8Br&4hRo; zsWVQvl7F&MCIwSYo~#>!)28XY?uZ#x2ZV>(>w=^BCu_r5ZBo>TGY8{FjcU$TKmemM ztOX|hu80}TI=)qCLfeCH5}DgDfNx})G&m(pE?n@)%qi=km1%^3bO4h~8lHAe5)Ysi zXOT(M(@JEO|7OZ}EH`Ob|L6ePaTc01yJU4Wqk{(-W#f@zQf~kvqyBdxfENNy z2AmQr$?)MdOQ5$mqkjDuO`OOmI-1duBaH6f*XQcVKsEPc@M06rKTL*986K{$<7VvC z$$p@7<}gZ2V|4Z`qpB)huNFkMCXWM~fj9VbJ~SEDICQ8Uwzl;0V$`b_qcLL`tysb6 z#0gzrAu{=9{RfV6=EKqt>nUVD9Ma%P1nkui^?Z3k~=G``C~m z`;Q|0vcu2Q-DLkm!A&73wy_U2^q|-NW2Bz=507j4%;>`Us{jB107*qoM6N<$f~a%V AC;$Ke literal 0 HcmV?d00001 From a0837cbecf58a4732e7ea1e17623e8940bed2ede Mon Sep 17 00:00:00 2001 From: jeffyactive Date: Tue, 16 Nov 2021 08:12:12 -0500 Subject: [PATCH 3/4] Changed id from emojuno to emojuino to make links work --- apps.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps.json b/apps.json index a0d543cd8..560e3d949 100644 --- a/apps.json +++ b/apps.json @@ -4217,7 +4217,7 @@ "data": [{ "name": "qalarm.json" }] }, { - "id": "emojuno", + "id": "emojuino", "name": "Emoji Broadcaster", "shortName": "Emojuino", "version": "0.01", @@ -4227,8 +4227,8 @@ "supports" : [ "BANGLEJS2" ], "readme": "README.md", "storage": [ - { "name": "emojuno.app.js", "url": "emojuino.js" }, - { "name": "emojuno.img", "url": "emojuino-icon.js", "evaluate": true } + { "name": "emojuino.app.js", "url": "emojuino.js" }, + { "name": "emojuino.img", "url": "emojuino-icon.js", "evaluate": true } ] } ] From 2d76d0bd132e992068ad322a51393c1593e54c68 Mon Sep 17 00:00:00 2001 From: jeffyactive Date: Tue, 16 Nov 2021 10:04:55 -0500 Subject: [PATCH 4/4] Improved naming/documentation --- apps.json | 4 ++-- apps/emojuino/README.md | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/apps.json b/apps.json index 560e3d949..b02517aea 100644 --- a/apps.json +++ b/apps.json @@ -4218,10 +4218,10 @@ }, { "id": "emojuino", - "name": "Emoji Broadcaster", + "name": "Emojuino", "shortName": "Emojuino", "version": "0.01", - "description": "Emojis & Espruino: advertise Unicode emojis via BLE", + "description": "Emojis & Espruino: broadcast Unicode emojis via Bluetooth Low Energy.", "icon": "emojuino.png", "tags": "emoji", "supports" : [ "BANGLEJS2" ], diff --git a/apps/emojuino/README.md b/apps/emojuino/README.md index 13879437e..568d06dfb 100644 --- a/apps/emojuino/README.md +++ b/apps/emojuino/README.md @@ -2,22 +2,27 @@ Emojis & Espruino! + ## Usage -Select an emoji and then tap to transmit! +Select an emoji and then tap to transmit! The emoji will be recognised by [Pareto Anywhere](https://www.reelyactive.com/pareto/anywhere/) open source middleware and any other program which observes the [InteroperaBLE Identifier](https://reelyactive.github.io/interoperable-identifier/) open standard. + ## Features -Currently implements a tiny subset of possible Unicode emojis. +Currently implements a tiny subset of possible [Unicode emojis](https://unicode.org/emoji/charts/full-emoji-list.html) which are advertised as an [InteroperaBLE Identifier](https://reelyactive.github.io/interoperable-identifier/) encapsulated as Eddystone UID. + ## Controls -Swipe left/right to select the emoji to broadcast. Tap the screen to initiate the broadcast. Emoji will flash while broadcasting. +Swipe left/right to select the emoji to broadcast. Tap the screen to initiate the broadcast. Emoji will flash while broadcasting, which lasts for 5 seconds. + ## Requests [Contact reelyActive](https://www.reelyactive.com/contact/) for support/updates. + ## Creator Developed by [jeffyactive](https://github.com/jeffyactive) of [reelyActive](https://www.reelyactive.com)