Precompile main.py with the micropython binary image for esp8266 - esp8266

There is boot.py available by default in the micropython image.
I have tested a code, in the python module main.py. I would like to do the following
I would like to compile a image, so it makes it easier to flash it to more than 10 devices and I do not have to start webrepl.
is there a way to stop boot messages that says micropython version number etc.?
I tried the following: apparently they are already activated:
https://forum.micropython.org/viewtopic.php?t=2334
I successfully compiled an image using the following:
https://cdn-learn.adafruit.com/downloads/pdf/building-and-running-micropython-on-the-esp8266.pdf
Question:
how to create an image with main.py, where should this file go in this folder /home/vagrant/micropython/esp8266 ?

You need to change micropython\esp8266\modules\inisetup.py.
In this file, a block of code writes boot.py file at micropython start-up. Like below
with open("boot.py", "w") as f:
f.write("""\
# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
import gc
#import webrepl
#webrepl.start()
gc.collect()
import mymain
""")
Notice last line import mymain. Copy your mymain.py file to the micropython\esp8266\modules directory.
mymain.py file should not have if __name__ == '__main__' block, so that it is executed at import. All other files that mymain is importing should also be in the modules directory. After building the code, all required files will get included with the binary.

1) boot.py is generated by the following script:
/home/vagrant/micropython/esp8266/script/inisetup.py
the function: setup() writes boot.py to the filesystem at every start up.
this would be the place to add main.py also writing it in the file.
or to add it in scripts and start it with boot.py
2) stop boot messages: "performing initial checks" is on inisetup.py. some are on port_diag.py in the scripts folder.

Related

Juypterlab | ipyfilechooser ignores start_path option with UNC paths and also local paths

I started working with Jupyterlab to analyse bunches of CSV files.
It is installed and run within an virtual environment on a windows PC (Windows 10, Python 3.9, JupyterLab 3.5.2).
As the filenames often change and our paths are quite deep I thought a file dialogue would be a good starting point to get data in.
I searched a while and found that ipyfilechooser could be my friend.
So I created a Jupyter Notebook and started with this code block:
import ipywidgets
from ipyfilechooser import FileChooser
chooser = FileChooser(
accept='.csv', # only show CSV files
multiple=False, # allow only one file
# optional starting path
start_path=r'\\sglx-srv1\geschaeft\MESSPLATZ'
)
display(chooser)
After executing this block a chooser widget appeared and I could select a folder or file, also from a UNC path (network drive).
But the setting of the start_path was always ignored and the dialogue always started from the folder the notebook itself is stored in.
I tried any variant I could find to quote the path, but with no luck.
It was not possible to let the file chooser start from any specified path neither local nor UNC.
What is wrong here? Is it a bug in my code or elsewhere?

Directory in kivy going to home directory rather than to the directory of the main.py in mac but not in Windows

I have an unusual situation. I have a perfectly functional kivy app. Essentially, it uses FileChooserIconView and takes the root
`FileChooserIconView:
filters: [root.selected]
size_hint: (1, 0.4)`
so that with this function
`def selected(self, directory, filename):
# This function extracts the selected folder using
#the information from FileChooser
# This function takes as input:
# -filename: The filename of each file in each directory
# This function gives the output:
# -the full path to the directory with the selected folder
self.ids.mypath.text = os.path.join(os.path.dirname(filename), '') `
I can extract the directory of interest (rather than every single file in the directory).
The app extracts the directory of interest with FileChooser and uses it to extract all files there recursively and process them.
It works perfectly in Spyder in Windows. I package it in Windows and it works perfectly as an independent exe (finds all files that it needs for uploading and works perfectly).
It works perfectly in Spyder in Mac. However, I package it in Mac and it is completely unable to find the local files. This is my problem. Once packaged in mac, instead of looking for the local files in the dist folder, it looks for them in the mac home directory. It requires to read a file that is actually in the dist folder, but the app does not look for it there. It looks for it in the mac home directory.
I have tried to put the current directory where the main.py is (in the dist folder) using several methods, including
filename = inspect.getframeinfo(inspect.currentframe()).filename
path = os.path.dirname(os.path.abspath(filename))
from the question
How to properly determine current script directory?
but still it looks to the mac home directory instead of the directory where the main.py is.
I tried to change directory using the path above, but still goes to the mac home directory.
When I use print(os.getcwd()) in the main.py file it prints the correct directory when used in Spyder, but it goes to the mac home directory after packaging. I am really stuck and I could not find a similar question.
Any help much appreciated.
Thank you very much for all the comments, especially John Anderson who put me in the right track. They made my search much easier.
Finally, I solved it.
When you package an app you should reference the location of the main.py. I was using __file__ and, when the app is not packaged, that works and that is why it worked in Spyder. However, when the app is packaged, the correct way to find the main.py folder is sys._MEIPASS
That it is, as simple as using sys._MEIPASS
For more detail, the link https://pyinstaller.readthedocs.io/en/stable/runtime-information.html#using-file-and-sys-meipass provided by John Anderson is great.

Pyinstaller adding data files

I'm struggling with pyinstaller. Whenever I build this specific script with a kivy GUI and a .kv file, and run the .exe after the build, I get a fatal error:
IOError: [Errno 2] No such file or directory: 'main.kv'
I've tried adding the .kv file, as well as a mdb and dsn file (for pypyodbc) using --add-data, but I get an error: unrecognized arguments: --add-data'main.kv'. (There were more --add-data arguments for the other files mentioned.)
Are there any solutions for this or maybe alternative methods?
As others (#Anson Chan, #schlimmchen) have said:
If you want to add some extra files, you should use Adding Data Files.
Two ways to implement
Command Line: add parameter to --add-data
Spec file: add parameter to datas=
Generated when running pyinstaller the first time.
Then later you can edit your *.spec file.
Then running pyinstaller will directly use your *.spec file.
Parameter Logic
Parameter in --add-data or datas=:
--add-data:
format: {source}{os_separator}{destination}
os_separator:
Windows: ;
Mac/Linux/Unix: :
source and destination
Logic:
source: path to single or multiple files, supporting glob syntax. Tells PyInstaller where to find the file(s).
destination
file or files: destination folder which will contain your source files at run time.
* NOTE: NOT the destination file name.
folder: destination folder path, which is RELATIVE to the destination root, NOT an absolute path.
Examples:
Single file: 'src/README.txt:.'
multiple files: '/mygame/sfx/*.mp3:sfx'
folder: '/mygame/data:data'
datas=
Format: list or tuple.
Examples: see the following.
added_files = [
( 'src/README.txt', '.' ),
( '/mygame/data', 'data' ),
( '/mygame/sfx/*.mp3', 'sfx' )
]
a = Analysis(...
datas = added_files,
...
)
Your case
For your (Windows OS) here is:
--add-data in command line
pyinstaller -F --add-data "main.kv;." yourtarget.py
OR:
datas= in yourtarget.spec file, see following:
a = Analysis(...
datas = ["main.kv", "."],
...
)
If you check pyinstaller -h for help, you can find --add-data option works like this [--add-data <SRC;DEST or SRC:DEST>]. So in your case try
pyinstaller -F --add-data "main.kv;main.kv" yourtarget.py
The solution is to run: pyi-makespec yourscript.py
Then edit the yourscript.spec script and add the files under datas in a= Analysis.
datas=[ ( '/pathToYourFile/main.kv', '.' )]
then run pyinstaller yourscript.spec
should be good after that.
Next -F or --onefile option is assumed when running pyinstaller.
Note that (MacOS Monterey, 12.2 here) the expected folder hierarchy w/in you .app file will be similar to this,
pyinstaller does not add files nor create necessary folders into any of the folders of this folder structure; at least not in any apparent way. You won't find them.
However, when the application runs, a temporary folder is used under /var/folders which is very different from the folder structure in point 1. above. print(os.path.dirname(__file__)) while running the application will reveal which exact temporary folder is used each time it runs. For convenience, let's call it my_app_tmp_folder i.e. your app runs under the folder /var/folder/my_app_tmp_folder
Then, pyinstaller adds data files or creates necessary directories w/in this temporary folder. In other words, when the application runs, all added files will be there and according to the specified folder structure (through --add-data option). print(os.listdir(os.path.dirname(__file__))) will show system and application needed files and folders.
Bottom line: Files specified w/ --add-data option will be visible w/in /var/folder/my_app_tmp_folder when running and not w/in the *.app folder.
Some useful links from documentation:
https://pyinstaller.readthedocs.io/en/stable/runtime-information.html#using-file
https://pyinstaller.readthedocs.io/en/stable/spec-files.html#adding-files-to-the-bundle
https://pyinstaller.readthedocs.io/en/stable/operating-mode.html#bundling-to-one-file
My application had this issue and a subsequent issue that is likely, if not inevitable.
1. --add-data for a kv file
Use --add-data as in the answer by crifan.
2. Kivy still can't find the file
Once PyInstaller has the kv file in the correct directory, Kivy still can't find the file.
Possible Symptoms:
GUI launches, but screen is black and empty.
An AttributeError error that depends on the application code.
AttributeError Examples:
This question
My own case:
AttributeError: 'NoneType' object has no attribute 'ids'
Fortunately, this answer solves the problem.

Dart pub global run can't resolve script name

I have a simple dart project that has one executable in bin folder (test.dart). I have activated it with dart global activate and now I can run it directly with just typing the name of that executable file.
Inside that dart file I would like to know the path of that script. Basically for now I'm just printing something like this:
print('1: ' + Platform.script.toString());
print('2: ' + Platform.script.path);
print('3: ' + Platform.executable);
print('4: ' + Platform.packageRoot);
print('5: ' + Platform.resolvedExecutable);
When I run it directly:
test
or with pub:
pub global run test
or even with package name:
pub global run test:test
I always get the same result:
1: http://localhost:53783/test.dart
2: /test.dart
3: E:\apps\dart-sdk\bin\dart
4:
5: E:\apps\dart-sdk\bin\dart.exe
The issue here is that I can't get the absolute path for test.dart file.
When I run it like this:
dart /path/to/project/bin/test.dart
I get what I need:
1: file:///E:/projects/dart/test/bin/test.dart
2: /E:/projects/dart/test/bin/test.dart
3: dart
4:
5: E:\apps\dart-sdk\bin\dart.exe
Is there a way how to get absolute path for a script that is currently running, regardless of a way how it was executed?
tl;dr: There's not a great way of doing what you want, but it's in the works.
The notion of a "path for a script that is currently running" is more complicated than it might sound at first blush. There are a number of ways that the Dart ecosystem invokes main(). Off the top of my head, here are a few:
Manually running the file with dart.
Running the file in an isolate.
Compiling the file to a snapshot and either manually running it or running it in an isolate.
Automatically compiling the file to a cached executable and running that either in a subprocess or in an isolate.
Adding a wrapper script that imports the file and invokes main(), and either running that in a subprocess or in an isolate.
Serving the file over HTTP, and running it either in a subprocess or in an isolate.
In some of these cases, the "script that is running" is actually a wrapper, not the original file you authored. In others, it's a snapshot that may have no inherent knowledge of the file from which it was created. In others, the file has been modified by transformers and the actual Dart code that's running isn't on disk at all.
I suspect what you're actually looking for isn't the executable URL itself, but the location of your package's files. We're working on a collection of APIs that will make this possible, as well as a resource package that will provide a nice API for dealing with your packages' resources.
Until that lands, there is a dart:mirrors hack you can use. If you give one of your library files an explicit library tag, say library my.cool.package, you can write:
var libPath = currentMirrorSystem().findLibrary(#my.cool.package).uri.path;
This will give you the path to your library, which you can use to figure out where your package's lib/ files live.
If you want a reliable way to access the current file while running in pub you'll need to use mirrors.
Here's a sample usage with dartdoc tests - https://github.com/dart-lang/dartdoc/blob/41a5e4d3f6e0084a9bc2af80546da331789f410d/test/compare_output_test.dart#L17
import 'dart:mirrors';
Uri get _currentFileUri =>
(reflect(main) as ClosureMirror).function.location.sourceUri;
void main() { ... }
Not particularly pretty, but it's easy to just put into a util file.

Chrome Cordova Translation Issue

Im trying to translate my chrome app to ios. I run the command cca create myapp --copy-from=manifest.json Some errors exist cp: copyFileSync: could not write to dest file (code=ENAMETOOLONG): $PATH_TO_PROJECT/project/platforms/ios/www/platform/..../www/platform/config.xml
where .... is 40 repeated directories of /www/platform
The translation succeeds and im able to run my project with android however, when trying to run in xcode i see an almost identical error saying File name too long.
Anyone have simmilar issues? Anyone able to get ios translations to run?
This is the result of a bug in the way we "import" your project when you specify --copy-from or --link-to arguments to cca create when your import directory is the same as your output directory.
Since the import in your example is a parent folder of the output, it copies itself over and over, recursively until the system kills the process. We have added protection against doing this (by warning during cca create if we detect this case), but that version hasn't released to npm just yet (sorry!).
The fix for the issue is simple: just create your project in another directory that is outside of your packaged app! i.e., either:
# From within packaged app directory
cca create ../myapp --copy-from=./manifest.json
or
# From outside packaged app directory
cca create myapp --copy-from=$APP_DIR/manifest.json

Resources