* setChannel(ch, v) in Berry
* try
* t2
* b
* fx
* update to berry with autogenerated files
* Add debug to find out whether the submodule is really checked out
* Revert "Add debug to find out whether the submodule is really checked out"
This reverts commit 40ec2f667716aa20180305ec7c3f1e61e88394c8.
* Add src/berry checkout to every build
* berry separate file p1
* #define ENABLE_OBK_BERRY 1 on Beken only
* Compile in obkSimulator
Compiles, but crashes in parser.
Seems like the Berry code has not been tested under MSVC2017.
* Checkout with submodules in obkSimulator workflow
* berry with ffs msvc fix
* berry autogen fiasco fix
* OpenBK7231T compiles from official berry, handle prebuild
Breaks obkSimulator
* Fix botched rebase on .gitmodules
* Build in msvc with a berry prebuild step (requires python)
* MSVC: also extend include directories for Release
* Fix BK723x build, extract common berry build rules into berry.mk
* Fix OpenBL602 build
This doesn't actually compile berry for OpenBL602, but makes compile
errors go away and marks where further work will be needed.
* working delayMs
Test Plan:
```
berry state = 1; var tick; def tick() state = 1 - state; channelSet(1, state); delayMs(1000, tick); end; tick();
```
can be stopped with `stopAllScripts`
* only use os_realloc on PLATFORM_BK7231T
* Move as much berry logic as possible out of cmd_script
* Guard more with ENABLE_OBK_BERRY
* upload script
* file operations & working import
* enough to implement "Advanced turn off after time with timer on UI and timer setting on UI and kept in flash"
* experiments
* clang-format -i src/berry/be_*.{h,c} src/cmnds/cmd_berry.c
* Remove redundant hfile != NULL
Calling with hfile == NULL would be bug in some other part of the code
* Don't checkout other submodules for simulator build
* remove stray debug & .user files
* Use be_newcomobj
* Build sim on linux
* build linux sim [2]
* threads & tests
* Leave enabled on Windows, disable on BEKEN
* SIM_RunWindow fix?
* allow "startScript test.be" as a shorthand for "berry import test" ??
* test?
* fix /
* test arg
* test2
* test
* test add
* fx
* test
* just checking if i can use import without module?
* test with module
* CMD_StopBerry fix?
* run obk command from berry? probably not good idea due to the stack size, will delay execution later?
* str arg
* test to see if i have to repeat import
* submit unfinished code
* concat tst
* more tests
* fix copy/paste mistake, add fib test
* fx
* channelSet
* fx
* try
* tester.fib(11)
* rename
---------
Co-authored-by: Tester23 <85486843+openshwprojects@users.noreply.github.com>
Co-authored-by: NonPIayerCharacter <18557343+NonPIayerCharacter@users.noreply.github.com>
4.2 KiB
Berry
What
Berry is a lightweight scripting language designed for small embedded systems. In OpenBeken, Berry provides a more powerful alternative to the built-in scripting system, with features like:
- Object-oriented programming
- First-class functions and closures
- Proper exception handling
- Module system for code organization
- Rich standard library
Why
While OpenBeken's built-in scripting is great for simple automation tasks, Berry offers several advantages:
- More structured programming with proper functions and classes
- Better error handling with try/catch
- More powerful data structures (maps, lists, etc.)
- Ability to create reusable modules
- Familiar syntax for those coming from languages like Python or JavaScript
How to Enable Berry
Berry is currently enabled by default on some platforms (like WINDOWS), but not on all platforms.
To enable Berry on other platforms:
- Edit
src/obk_config.h - Find your platform's section (e.g.,
#elif PLATFORM_W600) - Add the following line within your platform's section:
#define ENABLE_OBK_BERRY 1 - Recompile and flash your firmware
If you're unsure which platform you're using, check the existing entries in obk_config.h and look for the section that matches your device.
Basic Usage
To run Berry code, use the berry command followed by your code:
berry print("Hello from Berry!")
You can also create Berry script files with the .be extension and load them:
berry import mymodule
Caveats and Limitations
Note: Berry support in OpenBeken is currently experimental. The API and functionality may change in future releases without notice.
- The Berry API is not finalized and may change between firmware versions
- When using Berry alongside traditional OBK scripts, be aware that Berry uses thread IDs starting at 5000
- Using thread IDs above 5000 in traditional OBK scripts may cause unexpected behavior or conflicts with Berry threads
- Berry consumes more RAM than traditional scripts, so complex scripts may lead to memory issues on devices with limited RAM
- Error handling is still being improved, so some errors may not provide helpful messages
Key Functions
setChannel(channel, value)- Set a channel valuegetChannel(channel)- Get a channel valuescriptDelayMs(ms, function)- Run a function after a delay, returns a thread IDaddChangeHandler(event, relation, value, function)- Run a function when an event occurs, returns a thread IDcancel(threadId)- Cancel a delayed function or event handler by its thread ID
Examples
Toggle a relay every second
def toggle_relay()
current = getChannel(1)
setChannel(1, 1 - current)
scriptDelayMs(1000, toggle_relay)
end
toggle_relay()
React to events
# Store the handler ID so we can cancel it later if needed
handler_id = addChangeHandler("Channel3", "=", 1, def()
print("Button pressed!")
setChannel(1, 1) # Turn on relay
end)
# Later, to cancel the handler:
# cancel(handler_id)
Cancelling timers and event handlers
# Create a repeating timer that toggles a relay every second
def setup_toggle()
def toggle_relay()
current = getChannel(1)
setChannel(1, 1 - current)
return scriptDelayMs(1000, toggle_relay) # Return the new timer ID
end
return toggle_relay() # Start the timer and return its ID
end
# Set up a button handler that cancels the timer when pressed
def setup_cancel_button()
return addChangeHandler("Channel3", "=", 1, def()
print("Cancelling the toggle timer")
cancel(toggle_timer_id)
# We could also cancel ourselves with: cancel(button_handler_id)
end)
end
# Start everything
toggle_timer_id = setup_toggle()
button_handler_id = setup_cancel_button()
# To cancel everything later:
# cancel(toggle_timer_id)
# cancel(button_handler_id)
Create a module
Create a file named mymodule.be:
mymodule = module("mymodule")
mymodule.init = def(self)
print("Module initialized")
return self
end
mymodule.toggle_channel = def(self, channel)
current = getChannel(channel)
setChannel(channel, 1 - current)
end
return mymodule
Then use it:
import mymodule
mymodule.toggle_channel(1)