Welcome to the Winkyscript extension
This extension supports the development of Winkyscript programs and is experimental.
Winkyscript is brought to you by Mainbot and is the programming language used to drive Winky.
More information about Winkyscript can be found in the Winkyscript reference documentation. The URL is protected for the time being, because the Winkyscript language is currently in beta testing. If you wish to have access to the documentation and believe you have a good reason to, drop us a note through our contact form.
No support whatsoever is provided for the time being, unless you have a special arrangement with Mainbot.
⚠ Warning ⚠
This extension uses native modules and will not work "as is". Worst, it'll kill VS Code's extension host out of the box.
Don't panic, though, there is a solution! See the installation section below for guidance.
Table of contents
Features
Winky control
The extension allows you to control your Winky through a Bluetooth interface or the WinkyRelay application. It will emit a number of information messages in VS Code's output window. Make sure you select Winkyscript client in the output window's selection drop box.
The Bluetooth interface offers the most performance, but requires some work for set up. Refer to the Requirements and following sections for more on the matter.
The WinkyRelay application requires no additional set up and emulates the Bluetooth connexion through TCP/IP. All you need is a mobile device to run the application and a WiFi connexion to that device. The application is available on request from Mainbot (use our contact form), for the time being as an APK for Android device or on Testflight for Apple devices.
The native Bluetooth connection, though harder to set up, offers much faster firmware upgrades (2 to 3 minutes against 15 to 20 through WinkyRelay); other than that, both methods offer similar functionality. The following commands are available:
- Winky: Connect (Shift+Alt+W,C) will display a list of Winkies and WinkyRelays detected in the neighborhood. You can pick one of the Winkies or WinkyRelays to connect to. Once connected, the name of the Winky or WinkyRelay is displayed in the right hand corner of the status bar (in the case of WinkyRelay, both the name of the relay and that of the Winky it is connected to are displayed); when placing the mouse over that name, a small popup window shows basic information about the Winky: unique ID, battery status and firmware version numbers. Clicking on the name will pop a menu with available Winky commands.
- Winky: Disconnect (Shift+Alt+W,K) disconnects the currently connected Winky or WinkyRelay (as you might have guessed 😁).
- Winky: Rename (Shift+Alt+W,R) allows you to rename the currently connected Winky.
- Winky: Run (Shift+Alt+W,Z) runs the currently registered script (see Script execution and control).
- Winky: Set maximum volume (Shift+Alt+W,V) sets Winky's maximum sound volume.
- Winky: Stop (Shift+Alt+W,S) aborts a currently running script.
- Winky: Upgrade will force a firmware upgrade of the connected Winky. Note that upon connecting a Winky, an automatic check of the firmware version is performed, and the upgrade is systematically proposed in case Winky's firmware is out of date. See Upgrading a Winky below for more.
- Bluetooth: Restart allows you to reinitialize the VS Code Bluetooth subsystem. See No Winky in range for more.
All commands can be invoked from the command palette, or from the quick-pick menu that pops when clicking on the status bar item that represents the currently connected Winky.
Syntax highlighting
For best results with Syntax Highlighting, set the default color theme to Winkyscript Dark in your user or workspace Workbench settings (workbench.colorTheme
). There is no light theme available for the time being.
Script assembly and disassembly
Script assembly is the operation that translates a textual Winkyscript representation (.wst file) into
its equivalent binary representation (.wsb file). Script disassembly refers to the reverse operation, from
binary to textual representation.
The following commands are provided, which can be invoked from the command palette, or from the explorer or editor title tab context menus:
- Winkyscript: Assemble (Shift+Alt+W,A) takes a .wst text file and converts it into a .wsb binary file. The basename of the file is preserved; the output file is placed in the
./out
folder (the output can be changed through the extension settings). If a file with the same name exists in the output folder, it is overwritten without warning. This command is only available in the palette when the current file is a Winkyscript text file (.wst extension).
- Winkyscript: Disassemble (Shift+Alt+W,D) performs the reverse operation, and takes a .wsb binary file and converts it into a .wst text file. As for assembly, the basename of the file is preserved; the output file is placed in the
./out
folder, and if a file with the same name exists in the output folder, it is overwritten without warning. This command is only available in the palette when the current file is a Winkyscript binary file (.wsb extension).
- Winkyscript: Dump enables inspection of .wsb binary files. It creates a new editor window, displaying the binary and corresponding textual representations side by side. This command is available wherever Winkyscript: Disassemble is.
Script execution and control
Starting with version 12 of Winky's firmware, it is possible to send and execute scripts on Winky.
The following commands are provided to this avail:
- Winkyscript: Execute (Shift+Alt+W,X): executes a script in remote control mode.
- Winkyscript: Register (Shift+Alt+W,G): registers a script with Winky. Registered scripts are committed to flash memory and can be played afterward either using the Winky: Run command below when connected, or by performing a 2-finger tap on the touch area at the back of Winky's head. Winky currently supports only one registered script at a time. Any registration of a new script will overwrite the previous script.
- Winkyscript: Delete script (Shift+Alt+W,L): Deletes a script from Winky's internal memory.
- Winky: Run (Shift+Alt+W,Z) runs the currently registered script.
- Winky: Stop (Shitf+ALt+W,S): aborts a currently running script. Scripts launched with Winkyscript: Execute or Winky: Run can also be aborted by disconnecting from Winky.
These commands may be invoked through the command palette, through context menus on editor title tabs and the explorer for .wsb and .wst files, or from the quick-pick menu invoked by clicking on the status bar item that represents the currently connected Winky.
Script execution is traced to the output window when the winkyscript.debug.traceScripts
setting is properly set (defaults to no trace).
As of version 13 of Winky's firmware, debug capabilities have been added that allow to monitor and control a script's execution directly on Winky.
Before you can start a debug session, you need to create a default launch.json
file from the Run and Debug side panel: just click on create a launch.json file, select the Winkyscript Debug environment in the dropdown box that shows, save the file and forget about it forever.
To debug a script, open it in the editor, connect to Winky if not already done, and hit F5, or click on the small Run button at the top of the Run and Debug panel.
This will start a standard VS Code debugging session on the current script. The cursor will be automatically positioned for you on the first instruction following the Task Main instruction of the script. From then on, you can:
- add and remove breakpoints,
- use the continue, step into, step over or step out commands from the debug toolbar,
- view the contents of the program stack, the data stack, and all variables
- add watches
- and log messages (including line numbers and variable contents) to the debug console (see below)
Happy Winkyscripting!
⚠ Most script-related commands won't work on firware versions 11 or lower.
Resource download
The extension implements two commands to download sound and eye pattern resources to Winky (starting with f/w v16):
- Winky: Send sound sends a sound file to Winky. This command is available from the command palette, the editor tab context menu or the explorer context menu, when the selected file name ends with a .mp3 extension.
- Winky: Send eye pattern sends an eye pattern file to Winky. This command is available from the command palette, the editor tab context menu or the explorer context menu, when the selected file name ends with a .eye extension.
Sound files should be mono, 22050 samples per second, MP3-encoded files.
Eye pattern files are text files structured as follows:
- The first line is a string header which indicate the encoding used for the pattern. It can be one of
EYE_LCR
(left copies right), EYE_LMR
(left mirrors right) or EYE_TWO
(two patterns):
- In
EYE_LCR
or EYE_LMR
encoding, each line contains a 64-bit integer value in hexadecimal string representation (without prefix, underscores allowed). This value represents an LED pattern for the right eye (the most significant byte in the value being for the topmost LED line). In EYE_LCR
encoding, the left eye will be an exact copy of the right eye; in EYE_LMR
mode, the left eye is a mirrored copy of the right eye.
- In
EYE_TWO
encoding, the lines go in pairs, where the first line represents the pattern for the right eye, and the second one, the pattern for the left eye.
As an example, the file below contains an animated pattern which will show an horizontal line moving from the bottom to the top of both eyes:
EYE_LCR
FF
FF_00
FF_00_00
FF_00_00_00
FF_00_00_00_00
FF_00_00_00_00_00
FF_00_00_00_00_00_00
FF_00_00_00_00_00_00_00
Logging to the debug console
You can log messages to the debug console using specially formatted comments in the script. An example
is shown in the figure below:
Log instructions are located in comments. Note that logging instructions are only taken into account in a comment following an instruction, not on a comment line on its own without any executable instruction.
A log instruction consists in the log
keyword, followed by a string expression within parentheses, e.g. log(Something to log)
. Everything between the parentheses will be printed to the debug console when the related instruction is executed.
Macros can be used in log messages, and will be substituted on the fly at the time of execution. A macro is in the form ${XX:pppp}
where $
, {
and }
must be typed as is, X
is a macro instruction, pppp
an optional parameter to the macro instruction, and :
a literal separator between instruction and parameter. The following macros are supported:
${L}
: stands for the current line number
${V:NNNN}
: allows to log the content of the variable named NNNN
Macros are case insentive, i.e., ${l}
and ${L}
are equivalent.
The script in the example above will log the following to the debug console when run in debug mode:
Requirements
The Winkyscript extension only runs on Windows for the time being.
You MUST follow the installation instructions in the section below to
properly set up the Bluetooth interface and make this work.
The Bluetooth functionality requires a Bluetooth 4.0 or later adapter
(I'm using this one).
Completing the installation
The Winkyscript extension gets access to Bluetooth communication through the
@abandonware/noble module, which relies on
so called "native" modules (pieces of code specifically compiled for the platform you want to run on, as opposed to
standard javascript modules interpreted by the node.js engine).
VS Code currently offers no support for native modules within extensions. Therefore, the solution to make it work
is kind of ugly (though relatively simple), and requires some end-user involvement. Obviously, I don't pretend
that this is the best way of doing things...
If anybody knows better, help will be greatly appreciated.
Now, it is assumed that if you're choosing to write Winkyscript with VS Code, you have a bit of a hacker's mind, and
the overall setup shouldn't be too hard to come by... 😁🤪
Follow this step-by-step walkthrough, and you'll be ready to go in a few minutes:
Install the Winkyscript extension (if you're reading this file, you most likely have...)
Install the following applications if you don't have them on your system yet (if you don't know whether you have them, you probably don't...):
- Node.js: Install the long-term-support (LTS) version from the nodejs.org web site. Note that this should also install the Windows build tools, so that step below should no longer be necessary.
- Python: Install version 3 from the python.org web site. Make sure you check the option to add Python to your
path in the installer.
- [No longer required? see above] Windows build tools: install from an elevated (administrator) mode command-prompt window with
npm install --global windows-build-tools
(this one takes time...)
Insert the Bluetooth dongle (see the Requirements section) into a USB port on your PC and install the proper WinUSB driver for it:
- Download the Zadig Tool
- Run the Zadig tool (you need administrative privilege to do this).
- From the Options menu, select the List all devices entry
- From the dropdown box below the main menu, pick your Bluetooth dongle
- Click on Install driver (or Replace driver)
- Wait for a while
- Voilà...
Open a command-prompt terminal
Change directory to %USERPROFILE%\.vscode\extensions\winky-pyt.winkyscript-x.y.z
, where
x.y.z
is the version number of the installed Winkyscript extension
Run npm install
from the command prompt.
It'll take a while, add quite a bunch of stuff to your machine (all under the node_modules
folder), but when it's done,
you should be up and running.
Restart VS Code, and voilà.
So now what if this fails and the extenson host keeps dying ? Well, it may be because the version of VS Code you use
expects a newer version of Electron for the precompiled modules; drop me a note, and I'll try and fix it (if you're
using this extension, you probably know how to reach me... 😁)
Note that you will need to re-run steps 4-7 above everytime the extension gets updated.
Extension Settings
This extension contributes the following settings:
winkyscript.assembler.outputFolder
: Specifies where the output files (assembled or disassembled) go.
winkyscript.assembler.stopOnError
: Specifies whether the assembler should stop when it encounters an error or continue and try parsing the rest of the script after the error.
winkyscript.communityServer.firmwareModules
: Do not interfere with this one. Only change this if advised by Mainbot. Changing this setting unknowingly may screw up the firmware upgrade process.
winkyscript.communityServer.verboseHttpLogging
: Provide gory details about HTTP transactions with the community server. May be useful to debug server connection issues.
winkyscript.debug.notificationDelay
: Specifies, in milliseconds, the delay to be inserted between successive debug notifications. This to avoid overloading the machine running the VS Code debugger. The default value is 2. You may have to adjust this value if you are loosing notifications, based on the power of your machine (e.g. if variable values appear not to be always reflected correctly by VS Code).
winkyscript.debug.stepSize
: Specifies the number of instructions run for each debug step.
winkyscript.debug.traceDownload
: Specifies whether to display reassembly notifications during resource (script, sound or eye pattern) download.
winkyscript.debug.traceScripts
: Specifies whether and how to trace Winky's command execution in the output window.
winkyscript.languageServer.maximumNumberOfProblems
: Controls the maximum number of problems produced by the Winkyscript language server.
winkyscript.winky.keepConnectionToDeadWinkies
: Specifies whether to keep the Bluetooth connection to a Winky that no longer notifies its battery state.
winkyscript.winkyRelay.port
: The network port on which to scan for WinkyRelays. Defaults to 8080, unless you've changed it on WinkyRelay.
winkyscript.winkyRelay.timeOut
: The amount of time (ms) elapsed since the latest WinkyRelay broadcast after which we declare that said WinkyRelay is no longer available on the network.
Usage notes
Upgrading a Winky
When upgrading a connected Winky, the first thing that happens is that Winky gets restarted in a special mode, where it no longer advertizes its name, but a special name WIN_OTA (or a variant thereof, depending on the version of the Winky).
The sequence of event from a user standpoint is the following:
Connect to Winky or to a WinkyRelay connected to Winky.
Issue the Winky: Upgrade command (or accept the system's suggestion, if it has been detected that your Winky is out-of-date).
Winky will disconnect, and you will see an error message signalling that the connection to Winky has been lost.
This is normal behavior, don't worry.
if you're connected through Bluetooth, a warning will then pop about a Winky in OTA upgrade mode that has been found. Click on the Resume upgrade
button to continue with the process.
If you're connected through WinkyRelay, reconnect the Winky named WIN_OTA to the relay, and the upgrade will resume automatically.
If the upgrade process ever gets interrupted, your Winky will be stranded in WIN_OTA land, where it offers absolutely no signs of life, other than advertising over Bluetooth (so that your system or a WinkyRelay should detect it). Don't panic. Just issue a new Winky: Connect command and connect to the Winky named WIN_OTA. The system will detect Winky's state, and offer to resume the upgrade. In some rare cases, the system may not be able to detect the Winky; should this happen, just restart VS Code.
Known Issues
Connecting to Winky after VS Code startup
To avoid uselessly burdening VS Code, the Winkyscript extension only starts if a number of conditions are met,
such as when a Winkyscript file is open or when you execute a Winkyscript- or Winky-related command.
In particular, if you try to connect to a Winky and the extension has not started yet (e.g., if you have just started VS Code
on a brand new folder and no Winkyscript files where previously open), the first Winky: Connect may fail with a No Winky in range! message;
this is because the Winky: Connect command just started the extension, and it has had no time yet to detect your Winky.
In this case, simply re-issue the Winky: Connect command.
No Winky in range
Under rare circumstances, the Bluetooth interface may get out of sync and loose track of a properly advertising Winky.
If you get the message No Winky in range! or you don't see your Winky listed when you invoke Winky: Connect,
use the Bluetooth: Restart command to reinitialize the Bluetooth subsystem.
In the unlikely event where this would still not solve the problem, just restart
your VS Code instance. That will take care of it (if it still does not, restart your Winky and check with some other
means whether it is indeed advertising).