BirdBlox-FinchBlox-JS-Frontend
所属分类:android开发
开发工具:JavaScript
文件大小:0KB
下载次数:0
上传日期:2023-05-12 18:03:48
上 传 者:
sh-1993
说明: 新蜂鸟iOS和Android应用程序的HTML JS网站组件。允许使用Snap对蜂鸟进行编程-像int...,
(The HTML/JS website component of the new Hummingbird iOS and Android apps. Allows the Hummingbird to be programmed using a Snap!-like interface.)
文件列表:
.idea/ (0, 2022-10-27)
.idea/Git.iml (363, 2022-10-27)
.idea/codeStyleSettings.xml (281, 2022-10-27)
.idea/dictionaries/ (0, 2022-10-27)
.idea/dictionaries/Tom.xml (550, 2022-10-27)
.idea/inspectionProfiles/ (0, 2022-10-27)
.idea/inspectionProfiles/Project_Default.xml (377, 2022-10-27)
.idea/jsLibraryMappings.xml (187, 2022-10-27)
.idea/markdown-navigator.xml (4167, 2022-10-27)
.idea/markdown-navigator/ (0, 2022-10-27)
.idea/markdown-navigator/profiles_settings.xml (104, 2022-10-27)
.idea/misc.xml (289, 2022-10-27)
.idea/modules.xml (258, 2022-10-27)
.idea/vcs.xml (180, 2022-10-27)
.idea/watcherTasks.xml (139, 2022-10-27)
.idea/workspace.xml (151582, 2022-10-27)
AppIcon.png (4594, 2022-10-27)
Block/ (0, 2022-10-27)
Block/Block.js (58501, 2022-10-27)
Block/CommandBlock.js (822, 2022-10-27)
Block/DoubleLoopBlock.js (772, 2022-10-27)
Block/HatBlock.js (615, 2022-10-27)
Block/LoopBlock.js (823, 2022-10-27)
Block/PredicateBlock.js (571, 2022-10-27)
Block/ReporterBlock.js (799, 2022-10-27)
BlockContainers/ (0, 2022-10-27)
BlockContainers/BlockStack.js (28890, 2022-10-27)
BlockContainers/DisplayStack.js (7590, 2022-10-27)
BlockDefsAndList/ (0, 2022-10-27)
BlockDefsAndList/BlockDefs_control.js (22410, 2022-10-27)
BlockDefsAndList/BlockDefs_deviceWithMicrobit.js (18148, 2022-10-27)
BlockDefsAndList/BlockDefs_deviceWithPorts.js (11630, 2022-10-27)
BlockDefsAndList/BlockDefs_fbColor.js (9686, 2022-10-27)
BlockDefsAndList/BlockDefs_fbMotion.js (12972, 2022-10-27)
BlockDefsAndList/BlockDefs_fbSound.js (4664, 2022-10-27)
BlockDefsAndList/BlockDefs_finch.js (19887, 2022-10-27)
BlockDefsAndList/BlockDefs_flutter.js (5844, 2022-10-27)
BlockDefsAndList/BlockDefs_hummingbird.js (5229, 2022-10-27)
BlockDefsAndList/BlockDefs_hummingbirdbit.js (6513, 2022-10-27)
... ...
# BirdBlox
1. [Overview (for backend developers)](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#overview-for-backend-developers)
2. [Request list](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#request-list)
3. [Overview (for frontend developers)](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#overview-for-frontend-developers)
4. [BirdBlox translations](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#birdblox-translations)
## Overview (for backend developers)
This is the code for the BirdBlox JavaScript frontend.
It is responsible for handling all the UI, block execution,
etc. for the BirdBlox application. It is designed to run
inside of a containing application (iOS or Android apps,
for example). Anything the js code can't do by itself
(issuing bluetooth commands, showing dialogs, saving files) is
passed on to the containing application (backend) in the
form of get/post requests. To ensure the backend always has
an updated version of the frontend, clone the frontend's
git repo into the backend and to a pull when changes are made.
For debugging purposes, you can also set the frontend to be
automatically downloaded from git on launch, but this is
not used in the release version.
The responsibilities of the backend are the following:
* Display the HTML/JS frontend in some sort of webview
that the user can interact with.
* Connect to and communicate with bluetooth-enabled robots.
* Provide sensor information (accelerometers, etc.) from the
device to the frontend when requested.
* Display dialogs when requested.
* Play sounds when requested.
* Save, open, and delete files to app storage.
* Track which file is currently open.
* Record sounds to the currently open file
* Export/import files to/from other applications on the
device.
* Save/access key-value pairs used to store settings.
The frontend uses GET/POST requests to send messages to the backend.
GET requests are normally used, but POST requests are used for saving files.
HTTP response codes are used to signal errors. Unless otherwise specified,
any 200-type code can be used to signal success and any 400 or 500 code
can signal an error.
The backend sends messages to the frontend by directly calling a frontend
function in `CallbackManager.js`. These functions return a boolean that is
`true` if the request succeeded and `false` if the request is malformed.
This is for debugging purposes only, so there is no need to check for and
handle the `false` case.
On iOS, we have switched to a more direct method of communication (instead of
GET/POST), where the JS calls swift functions to send messages. It directly calls
the function `window.webkit.messageHandlers.serverSubstitute.postMessage`, passing
a JSON object containing the data that would normally be transferred using HTTP.
This enabled us to remove the server from the iOS backend.
## Request list
* [Bluetooth scanning](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#bluetooth-scanning)
* [Robot blocks](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#robot-blocks)
* [Tablet sensors](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#tablet-sensors)
* [Dialogs](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#dialogs)
* [Settings](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#settings)
* [File management](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#file-management)
* [Cloud storage](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#cloud-storage)
* [Sounds](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#sounds)
* [Error logging](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#error-logging)
* [Miscellaneous](https://github.com/BirdBrainTechnologies/BirdBlox-FinchBlox-JS-Frontend/blob/master/#miscellaneous)
### Bluetooth scanning
The backend and frontend communicate about specific Bluetooth robots
using the robots' ids. On Android, Mac Addresses are used as ids while
iOS provides its own unique Bluetooth ids. All requests mentioning a
specific robot will have an `id=[device_id]` parameter.
The frontend will initialize bluetooth scans using the `robot/startDiscover`
request. These scans last for a reasonable amount of time as
to not drain the battery. The backend then calls
`CallbackManager.robot.discovered` with the list of discovered devices every
time a new device is found. The frontend will call `robot/stopDiscover` to
request that a scan be ended. If the scan times out before `stopDiscover` is
called, the backend calls `CallbackManager.robot.discoverTimeOut`, and
the frontend might restart the scan. In any other case that a scan stops (including
when the frontend calls `robot/stopDiscover`), `CallbackManager.robot.stopDiscover`
is called.
#### /robot/startDiscover
Request format:
http://localhost:22179/robot/startDiscover?type=[robotType]
Example request:
http://localhost:22179/robot/startDiscover?type=hummingbird
When received, the backend begins a scan of unpaired devices of the specified
type. If it is currently scanning for a different type of device, that scan
is stopped and results are cleared. If a scan of the specified type is already
occurring, no action is taken.
#### /robot/stopDiscover
Request format:
http://localhost:22179/robot/stopDiscover
Stops the current scan if any.
#### CallbackManager.robot.discovered
Callback signature:
CallbackManager.robot.discovered(robotTypeId: string, robotList: string) -> boolean
robotList - A percent encoded JSON array of objects, each containing name and id fields
Example call:
CallbackManager.robot.discovered("flutter", encoded);
where encoded is '[{"id":"my_id","name":"my_name"}]' percent encoded
Called any time a new device is discovered during a scan
#### CallbackManager.robot.discoverTimeOut
Callback signature:
CallbackManager.robot.discoverTimeOut(robotTypeId: string) -> boolean
Example call:
CallbackManager.robot.discoverTimeOut("hummingbird");
Tells the frontend that the discover timed out so the frontend has a chance to
start the discover again.
#### CallbackManager.robot.stopDiscover
Callback signature:
CallbackManager.robot.stopDiscover(robotTypeId: string) -> boolean
Example call:
CallbackManager.robot.stopDiscover("hummingbird");
Tells the frontend that the discover stopped so the frontend has a chance to
start the discover again. Called any time a scan stops unless it timed out.
### Robot connection/disconnection
The frontend will tell the backend when to connect to or disconnect from a robot using the
`/robot/connect` and `robot/disconnect` requests.
The backend maintains a list of devices the frontend wants to connect to, and
devices are instantaneously added or removed from that list as the frontend
requests. The frontend has a similar list (visible to the user in the ConnectMultipleDialog)
and it is important that these lists on the frontend and backend are always in sync.
One the backend adds a device to this list (which we'll call the **connection list**),
it attempts to connect to the device itself (asynchronously). The backend
then calls `CallbackManager.robot.updateStatus` with `isConnected = true` when the
device does connect and makes the same call with `isConnected = false` if the device
ever unexpectedly disconnects. However, no devices should be removed from the connection
list without the frontend's knowledge. If the frontend disconnects from a robot, it
is removed from the connection list and treated as if it is disconnected while
the actual disconnection occurs asynchronously.
On connection to the robot, the backend checks the firmware version. If the firmware is out
of date but still compatible with the app it calls `CallbackManager.robot.updateFirmwareStatus`.
If the firmware is incompatible, it calls `CallbackManager.robot.disconnectIncompatible` and
immediately removes the robot from the connection list. This is the only time where the
backend removes something from the list without the frontend making a request.
#### /robot/connect
Request format:
http://localhost:22179/robot/connect?id=[robotId]&type=[robotType]
Example request:
http://localhost:22179/robot/connect?id=SomeMacAddress&type=flutter
Tells the backend to connect to a device. If the device is on the devices found during the
last scan, the backend adds it to the connection list and tries to connect to it. Otherwise
it returns a 404.
#### /robot/disconnect
Request format:
http://localhost:22179/robot/disconnect?id=[robotId]&type=[robotType]
Example request:
http://localhost:22179/robot/disconnect?id=SomeMacAddress&type=flutter
Tells the backend to disconnect from a device. If the device is on the connection list, it
removes it from the list and tries to disconnect from it. Otherwise, it returns a 404.
#### CallbackManager.robot.updateStatus
Callback signature:
CallbackManager.robot.updateStatus(robotId: string, isConnected: boolean) -> boolean
isConnected - Whether the backend is able to communicate with the robot
Example call:
CallbackManager.robot.updateStatus("myrobotid", true);
Tells the frontend whether a given robot is in good communication with the backend.
When the robot is first connected, the fronted assumes isConnected is false.
This function should be called with `isConnected = true` as soon as the robot
connects, and with `isConnected = false` if it subsequently unexpectedly disconnects.
#### CallbackManager.robot.updateFirmwareStatus
Callback signature:
CallbackManager.robot.updateFirmwareStatus(robotId: string, status: string) -> boolean
status - ["upToDate"|"old"|"incompatible"]
Example call:
CallbackManager.robot.updateFirmwareStatus("myrobotid", "old");
Tells the frontend the status of the robot's firmware. Frontend initially assumes
firmware is up to date, so the function should be called with `status = "old"` if
the backend discovers that the firmware is old but compatible. If the backend finds
the firmware to be incompatible, `CallbackManager.robot.disconnectIncompatible`
should be used instead.
#### CallbackManager.robot.disconnectIncompatible
Callback signature:
CallbackManager.robot.disconnectIncompatible(robotId: string,
oldFirmware: string, minFirmware: string) -> boolean
oldFirmware - percent encoded version of firmware that was on the robot
minFirmware - percent encoded minimum version of firmware the backend requires
Example call:
CallbackManager.robot.disconnectIncompatible("myrobotid", "1.3", "2.0");
Tells the frontend that a robot has been removed from the connection list because its
firmware was incompatible. The frontend will then remove the device from its own
connection list and notify the user of the incompatible firmware, providing an option
to view instructions to update the firmware.
#### /robot/showUpdateInstructions
Request format:
http://localhost:22179/robot/showUpdateInstructions?type=[robotTypeId]
Example request:
http://localhost:22179/robot/showUpdateInstructions?type=hummingbird
When received, the backend redirects the user to a website containing instructions
to update the firmware of their device. The website may depend on the type of robot.
Currently this website is
http://www.hummingbirdkit.com/learning/installing-birdblox#BurnFirmware
#### /robot/showInfo
Request format:
http://localhost:22179/robot/showFirmwareInfo?type=[robotTypeId]&id=[robotId]
If the firmware of the robot is up to date, this command presents an alert dialog with
the text and a single option "Dismiss":
Hummingbird Peripheral
Name: [robot name from mac address]
Bluetooth Name: [actual gap name]
Hardware Version: [hardware version]
Firmware Version: [firmware version]
If the firmware isn't up to date, an additional line, `Firmware update available` is
included with options "Dismiss" and "Update firmware", which links to the update page.
### Robot blocks
These commands are used for blocks that control the inputs/outputs of the robots.
Some commands (like the tri-led command) are shared between different types of
robots. Since the BLE command may vary by robot type, a parameter `type` is
provided for all commands. A robot is is also provided. The only exception is the
`/robot/stopAll` command, since it affects all robots.
On the backend, sensor values are regularly polled and cached so that the
sensor requests can be immediately responded to with the cached values. For outputs,
the has a state object which represents the state of all the outputs
of a given robot. When an output request is made, the state is modified. It is then
regularly synced with the robot using a set all BLE command. To prevent states from
being missed (for example, if the user turns the LED on and off quickly), the backend
actually tracks the current and pending states of the outputs, and only processes
a command when the relevant output for that command has the same value in both states.
Otherwise, the command waits in a queue. More detail can be found in the backend code.
All robot commands should return an error response code if the specified device is
not connected.
#### /robot/stopAll
Request format:
http://localhost:22179/robot/stopAll
Turns off all the robot's outputs (LEDs, motors, servos, etc). On backends using the
direct call system, also empties the queue of unprocessed robot block requests.
#### /robot/in
Request format:
http://localhost:22179/robot/in?sensor=[s]&type=[t]&id=[id]&port=[p]
type - ["sensor"|"temperature"|"distance"|"sound"|"light"|"soil"]
Example request:
http://localhost:22179/robot/in?sensor=distance&type=flutter&id=robotid&port=2
Example response:
3.6
Returns the sensor value of the robot. Might be scaled differently depending on the
type of sensor
#### /robot/out/servo
Request format:
http://localhost:22179/robot/out/servo?angle=[a]&type=[t]&id=[id]&port=[p]
angle - int from 0 to 180
#### /robot/out/motor
Request format:
http://localhost:22179/robot/out/motor?speed=[s]&type=[t]&id=[id]&port=[p]
angle - int from -100 to 100
#### /robot/out/vibration
Request format:
http://localhost:22179/robot/out/vibration?intensity=[i]&type=[t]&id=[id]&port=[p]
intensity - int from 0 to 100
#### /robot/out/led
Request format:
http://localhost:22179/robot/out/led?intensity=[i]&type=[t]&id=[id]&port=[p]
intensity - int from 0 to 100
#### /robot/out/triled
Request format:
http://localhost:22179/robot/out/triled?red=[r]&green=[g]&blue=[b]&type=[t]&id=[id]&port=[p]
red - int from 0 to 100
green - int from 0 to 100
blue - int from 0 to 100
#### /robot/out/buzzer
Request format:
http://localhost:22179/robot/out/triled?volume=[v]&frequency=[f]&type=[t]&id=[id]&port=[p]
volume - int from 0 to 100
frequency - int from 0 to 20000
### Tablet sensors
Different tablets have varying sensors that can be read using the sensor
blocks. The frontend is told the reading and availability of sensors using the below requests
If the tablet doesn't have the necessary permissions or hardware for a request, it should
return an error and in the response body include a description of the error that can be shown
to the user.
#### /tablet/availableSensors
Request format:
http://localhost:22179/tablet/availableSensors
Example response:
"accelerometer\nbarometer\nmicrophone\ngps"
Returns a `"\n"` separated list of sensors the device supports. For technical reasons,
iOS always returns `""` to this request and uses the callback functions to give this
information instead.
#### CallbackManager.tablet.availableSensors
Callback signature:
CallbackManager.robot.availableSensors(sensorList: string) -> boolean
sensorList - percent encoded, "\n" separated list of sensors the device supports
Example call:
CallbackManager.robot.availableSensors(sensorList);
where sensorList is the percent encoded form of "accelerometer\nbarometer\nmicrophone\ngps"
#### CallbackManager.tablet.addSensor
Callback signature:
CallbackManager.robot.addSensor(sensor: string) -> boolean
sensor - ["accelerometer", "barometer", "microphone", "gps"]
Tells the frontend to add the sensor to the list of supported sensors.
#### CallbackManager.tablet.removeSensor
Callback signature:
CallbackManager.robot.removeSensor(sensor: string) -> boolean
sensor - ["accelerometer", "barometer", "microphone", "gps"]
Tells the frontend to remove the sensor from the list of supported sensors.
#### /tablet/shake
Request format:
http://localhost:22179/tablet/shake
Example responses:
true
false
Returns whether the tablet was shaken. After returning true, it returns false on
subsequent calls until the tablet is shaken again.
#### /tablet/ssid
Request format:
http://localhost:22179/tablet/ssid
Example responses:
My WiFi
null
Returns the name of the WiFi the tablet is connected to or `null` if it is not connected
to anything.
#### /tablet/pressure
Request format:
http://localhost:22179/tablet/pressure
Example responses:
104.3
Returns the a pressure in kilopascals
#### /tablet/altitude
Request format:
http://localhost:22179/tablet/altitude
Example responses:
-1.245
Returns the change in the device's altitude (in meters) since the app was opened.
This is determined using the device's barometer
#### /tablet/orientation
Request format:
http://localhost:22179/tablet/altitude
Example responses:
Faceup
Landscape: home button on left
Landscape: home button on right
Portrait: home button on bottom
Portrait: home button on top
Facedown
In between
Returns a string indicating the device's orientation.
#### /tablet/acceleration
Request format:
http://localhost:22179/tablet/acceleration
Example response:
7.432 4.295 -1.568
Returns the change in the device's acceleration in the x, y, and z directions, separated
by spaces. This should be the total acceleration (including gravity)
#### /tablet/location
Request format:
http://localhost:22179/tablet/location
Example response:
100.456 70.823
Returns the latitude and longitude separated by spaces. Prompts for location permission
if not granted yet.
### Dialogs
There are three main types of dialogs: prompt, choice, alert. Prompt dialogs let the
user enter text. Choice dialogs give the user two options to choose from. Alert dialog
contain text and only one option.
Dialogs are presented in response to http requests. When the user responds, a function in
the CallbackManager should be called. Only one dialog will be requested at a time. Dialogs
that are presented for a reason other than the commands below do not need to call
CallbackManager functions.
#### /tablet/dialog
Request format:
http://localhost:22179/tablet/dialog?title=[t]&question=[q]&prefill=[pr]&placeholder=[pl]&selectAll=[sa]
title - The text to show in the top of the dialog
question - The text to show in the body of the dialog
prefill - (possibly "") The text that should already be in the dialog
placeholder - (possibly "") The text to show in gray when nothing has been entered yet
selectAll - ["true"|"false"], whether the prefill text should start out as selected
Shows a dialog and calls `CallbackManager.dialog.promptResponded` when it is responded to.
#### /tablet/choice
Request format:
http://localhost:22179/tablet/choice?title=[t]&question=[q]&button1=[bn1]&button2=[bn2]
title - The text to show in the top of the dialog
question - The text to show in the body of the dialog
button1 - The text to show on the first button
button2 - (optional) The text to show on the secon ... ...
近期下载者:
相关文件:
收藏者: