1 <!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0 Strict//EN"
2 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3 <html xmlns=
"http://www.w3.org/1999/xhtml" dir=
"ltr">
5 <meta http-equiv=
"Content-Type" content=
"text/html;charset=utf-8" />
6 <title>Petter Reinholdtsen
</title>
7 <link rel=
"stylesheet" type=
"text/css" media=
"screen" href=
"https://people.skolelinux.org/pere/blog/style.css" />
8 <link rel=
"stylesheet" type=
"text/css" media=
"screen" href=
"https://people.skolelinux.org/pere/blog/vim.css" />
9 <link rel=
"alternate" title=
"RSS Feed" href=
"https://people.skolelinux.org/pere/blog/index.rss" type=
"application/rss+xml" />
14 <a href=
"https://people.skolelinux.org/pere/blog/">Petter Reinholdtsen
</a>
23 <div class=
"title"><a href=
"https://people.skolelinux.org/pere/blog/Speech_to_text__she_APTly_whispered__how_hard_can_it_be_.html">Speech to text, she APTly whispered, how hard can it be?
</a></div>
24 <div class=
"date">23rd April
2023</div>
25 <div class=
"body"><p>While visiting a convention during Eastern, it occurred to me that
26 it would be great if I could have a digital Dictaphone with
27 transcribing capabilities, providing me with texts to cut-n-paste into
28 stuff I need to write. The background is that long drives often bring
29 up the urge to write on texts I am working on, which of course is out
30 of the question while driving. With the release of
31 <a href=
"https://github.com/openai/whisper/">OpenAI Whisper
</a>, this
32 seem to be within reach with Free Software, so I decided to give it a
33 go. OpenAI Whisper is a Linux based neural network system to read in
34 audio files and provide text representation of the speech in that
35 audio recording. It handle multiple languages and according to its
36 creators even can translate into a different language than the spoken
37 one. I have not tested the latter feature. It can either use the CPU
38 or a GPU with CODA support. As far as I can tell, CODA in practice
39 limit that feature to NVidia graphics cards. I have few of those, as
40 they do not work great with free software drivers, and have not tested
41 the GPU option. While looking into the matter, I did discover some
42 work to provide CODA support on non-NVidia GPUs, and some work with
43 the library used by Whisper to port it to other GPUs, but have not
44 spent much time looking into GPU support yet. I've so far used an old
45 X220 laptop as my test machine, and only transcribed using its
48 <p>As it from a privacy standpoint is unthinkable to use computers
49 under control of someone else (aka a "cloud" service) to transcribe
50 ones thoughts and personal notes, I want to run the transcribing
51 system locally on my own computers. The only sensible approach to me
52 is to make the effort I put into this available for any Linux user and
53 to upload the needed packages into Debian. Looking at Debian Bookworm, I
54 discovered that only three packages were missing,
55 <a href=
"https://bugs.debian.org/1034307">tiktoken
</a>,
56 <a href=
"https://bugs.debian.org/1034144">triton
</a>, and
57 <a href=
"https://bugs.debian.org/1034091">openai-whisper
</a>. For a while
59 <a href=
"https://bugs.debian.org/1034286">ffmpeg-python
</a> was
61 <a href=
"https://github.com/kkroening/ffmpeg-python/issues/760">upstream
62 seem to have vanished
</a> I found it safer
63 <a href=
"https://github.com/openai/whisper/pull/1242">to rewrite
64 whisper
</a> to stop depending on in than to introduce ffmpeg-python
65 into Debian. I decided to place these packages under the umbrella of
66 <a href=
"https://salsa.debian.org/deeplearning-team">the Debian Deep
67 Learning Team
</a>, which seem like the best team to look after such
68 packages. Discussing the topic within the group also made me aware
69 that the triton package was already a future dependency of newer
70 versions of the torch package being planned, and would be needed after
71 Bookworm is released.
</p>
73 <p>All required code packages have been now waiting in
74 <a href=
"https://ftp-master.debian.org/new.html">the Debian NEW
75 queue
</a> since Wednesday, heading for Debian Experimental until
76 Bookworm is released. An unsolved issue is how to handle the neural
77 network models used by Whisper. The default behaviour of Whisper is
78 to require Internet connectivity and download the model requested to
79 <tt>~/.cache/whisper/
</tt> on first invocation. This obviously would
80 fail
<a href=
"https://people.debian.org/~bap/dfsg-faq.html">the
81 deserted island test of free software
</a> as the Debian packages would
82 be unusable for someone stranded with only the Debian archive and solar
83 powered computer on a deserted island.
</p>
85 <p>Because of this, I would love to include the models in the Debian
86 mirror system. This is problematic, as the models are very large
87 files, which would put a heavy strain on the Debian mirror
88 infrastructure around the globe. The strain would be even higher if
89 the models change often, which luckily as far as I can tell they do
90 not. The small model, which according to its creator is most useful
91 for English and in my experience is not doing a great job there
92 either, is
462 MiB (deb is
414 MiB). The medium model, which to me
93 seem to handle English speech fairly well is
1.5 GiB (deb is
1.3 GiB)
94 and the large model is
2.9 GiB (deb is
2.6 GiB). I would assume
95 everyone with enough resources would prefer to use the large model for
96 highest quality. I believe the models themselves would have to go
97 into the non-free part of the Debian archive, as they are not really
98 including any useful source code for updating the models. The
99 "source", aka the model training set, according to the creators
100 consist of "
680,
000 hours of multilingual and multitask supervised
101 data collected from the web", which to me reads material with both
102 unknown copyright terms, unavailable to the general public. In other
103 words, the source is not available according to the Debian Free
104 Software Guidelines and the model should be considered non-free.
</p>
106 <p>I asked the Debian FTP masters for advice regarding uploading a
107 model package on their IRC channel, and based on the feedback there it
108 is still unclear to me if such package would be accepted into the
109 archive. In any case I wrote build rules for a
110 <a href=
"https://salsa.debian.org/deeplearning-team/openai-whisper-model">OpenAI
111 Whisper model package
</a> and
112 <a href=
"https://github.com/openai/whisper/pull/1257">modified the
113 Whisper code base
</a> to prefer shared files under
<tt>/usr/
</tt> and
114 <tt>/var/
</tt> over user specific files in
<tt>~/.cache/whisper/
</tt>
115 to be able to use these model packages, to prepare for such
116 possibility. One solution might be to include only one of the models
117 (small or medium, I guess) in the Debian archive, and ask people to
118 download the others from the Internet. Not quite sure what to do
119 here, and advice is most welcome (use the debian-ai mailing list).
</p>
121 <p>To make it easier to test the new packages while I wait for them to
122 clear the NEW queue, I created an APT source targeting bookworm. I
123 selected Bookworm instead of Bullseye, even though I know the latter
124 would reach more users, is that some of the required dependencies are
125 missing from Bullseye and I during this phase of testing did not want
126 to backport a lot of packages just to get up and running.
</p>
128 <p>Here is a recipe to run as user root if you want to test OpenAI
129 Whisper using Debian packages on your Debian Bookworm installation,
130 first adding the APT repository GPG key to the list of trusted keys,
131 then setting up the APT repository and finally installing the packages
132 and one of the models:
</p>
135 curl https://geekbay.nuug.no/~pere/openai-whisper/D78F5C4796F353D211B119E28200D9B589641240.asc \
136 -o /etc/apt/trusted.gpg.d/pere-whisper.asc
137 mkdir -p /etc/apt/sources.list.d
138 cat
> /etc/apt/sources.list.d/pere-whisper.list
<<EOF
139 deb https://geekbay.nuug.no/~pere/openai-whisper/ bookworm main
140 deb-src https://geekbay.nuug.no/~pere/openai-whisper/ bookworm main
143 apt install openai-whisper
146 <p>The package work for me, but have not yet been tested on any other
147 computer than my own. With it, I have been able to (badly) transcribe
148 a
2 minute
40 second Norwegian audio clip to test using the small
149 model. This took
11 minutes and around
2.2 GiB of RAM. Transcribing
150 the same file with the medium model gave a accurate text in
77 minutes
151 using around
5.2 GiB of RAM. My test machine had too little memory to
152 test the large model, which I believe require
11 GiB of RAM. In
153 short, this now work for me using Debian packages, and I hope it will
154 for you and everyone else once the packages enter Debian.
</p>
156 <p>Now I can start on the audio recording part of this project.
</p>
158 <p>As usual, if you use Bitcoin and want to show your support of my
159 activities, please send Bitcoin donations to my address
160 <b><a href=
"bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b
</a></b>.
</p>
165 Tags:
<a href=
"https://people.skolelinux.org/pere/blog/tags/debian">debian
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/english">english
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/multimedia">multimedia
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/video">video
</a>.
170 <div class=
"padding"></div>
173 <div class=
"title"><a href=
"https://people.skolelinux.org/pere/blog/rtlsdr_scanner__software_defined_radio_frequency_scanner_for_Linux____nice_free_software.html">rtlsdr-scanner, software defined radio frequency scanner for Linux - nice free software
</a></div>
174 <div class=
"date"> 7th April
2023</div>
175 <div class=
"body"><p>Today I finally found time to track down a useful radio frequency
176 scanner for my software defined radio. Just for fun I tried to locate
177 the radios used in the areas, and a good start would be to scan all
178 the frequencies to see what is in use. I've tried to find a useful
179 program earlier, but ran out of time before I managed to find a useful
180 tool. This time I was more successful, and after a few false leads I
181 found a description of
182 <a href=
"https://www.kali.org/tools/rtlsdr-scanner/">rtlsdr-scanner
183 over at the Kali site
</a>, and was able to track down
184 <a href=
"https://gitlab.com/kalilinux/packages/rtlsdr-scanner.git">the
185 Kali package git repository
</a> to build a deb package for the
186 scanner. Sadly the package is missing from the Debian project itself,
187 at least in Debian Bullseye. Two runtime dependencies,
188 <a href=
"https://gitlab.com/kalilinux/packages/python-visvis.git">python-visvis
</a>
190 <a href=
"https://gitlab.com/kalilinux/packages/python-rtlsdr.git">python-rtlsdr
</a>
191 had to be built and installed separately. Luckily '
<tt>gbp
192 buildpackage
</tt>' handled them just fine and no further packages had
193 to be manually built. The end result worked out of the box after
196 <p>My initial scans for FM channels worked just fine, so I knew the
197 scanner was functioning. But when I tried to scan every frequency
198 from
100 to
1000 MHz, the program stopped unexpectedly near the
199 completion. After some debugging I discovered USB software radio I
200 used rejected frequencies above
948 MHz, triggering a unreported
201 exception breaking the scan. Changing the scan to end at
957 worked
202 better. I similarly found the lower limit to be around
15, and ended
203 up with the following full scan:
</p>
205 <p><a href=
"https://people.skolelinux.org/pere/blog/images/2023-04-07-radio-freq-scanning.png"><img src=
"https://people.skolelinux.org/pere/blog/images/2023-04-07-radio-freq-scanning.png" width=
"100%"></a></p>
207 <p>Saving the scan did not work, but exporting it as a CSV file worked
208 just fine. I ended up with around
477k CVS lines with dB level for
209 the given frequency.
</p>
211 <p>The save failure seem to be a missing UTF-
8 encoding issue in the
212 python code. Will see if I can find time to send a patch
213 <a href=
"https://github.com/CdeMills/RTLSDR-Scanner/">upstream
</a>
214 later to fix this exception:
</p>
217 Traceback (most recent call last):
218 File "/usr/lib/python3/dist-packages/rtlsdr_scanner/main_window.py", line
485, in __on_save
219 save_plot(fullName, self.scanInfo, self.spectrum, self.locations)
220 File "/usr/lib/python3/dist-packages/rtlsdr_scanner/file.py", line
408, in save_plot
221 handle.write(json.dumps(data, indent=
4))
222 TypeError: a bytes-like object is required, not 'str'
223 Traceback (most recent call last):
224 File "/usr/lib/python3/dist-packages/rtlsdr_scanner/main_window.py", line
485, in __on_save
225 save_plot(fullName, self.scanInfo, self.spectrum, self.locations)
226 File "/usr/lib/python3/dist-packages/rtlsdr_scanner/file.py", line
408, in save_plot
227 handle.write(json.dumps(data, indent=
4))
228 TypeError: a bytes-like object is required, not 'str'
231 <p>As usual, if you use Bitcoin and want to show your support of my
232 activities, please send Bitcoin donations to my address
233 <b><a href=
"bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b
</a></b>.
</p>
238 Tags:
<a href=
"https://people.skolelinux.org/pere/blog/tags/debian">debian
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/english">english
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/nice free software">nice free software
</a>.
243 <div class=
"padding"></div>
246 <div class=
"title"><a href=
"https://people.skolelinux.org/pere/blog/OpenSnitch_available_in_Debian_Sid_and_Bookworm.html">OpenSnitch available in Debian Sid and Bookworm
</a></div>
247 <div class=
"date">25th February
2023</div>
248 <div class=
"body"><p>Thanks to the efforts of the OpenSnitch lead developer Gustavo
249 Iñiguez Goya allowing me to sponsor the upload,
250 <a href=
"https://tracker.debian.org/pkg/opensnitch">the interactive
251 application firewall OpenSnitch
</a> is now available in Debian
252 Testing, soon to become the next stable release of Debian.
</p>
254 <p>This is a package which set up a network firewall on one or more
255 machines, which is controlled by a graphical user interface that will
256 ask the user if a program should be allowed to connect to the local
257 network or the Internet. If some background daemon is trying to dial
258 home, it can be blocked from doing so with a simple mouse click, or by
259 default simply by not doing anything when the GUI question dialog pop
260 up. A list of all programs discovered using the network is provided
261 in the GUI, giving the user an overview of how the machine(s) programs
264 <p>OpenSnitch was uploaded for NEW processing about a month ago, and I
265 had little hope of it getting accepted and shaping up in time for the
266 package freeze, but the Debian ftpmasters proved to be amazingly quick
267 at checking out the package and it was accepted into the archive about
268 week after the first upload. It is now team maintained under the Go
269 language team umbrella. A few fixes to the default setup is only in
270 Sid, and should migrate to Testing/Bookworm in a week.
</p>
272 <p>During testing I ran into an
273 <a href=
"https://github.com/evilsocket/opensnitch/issues/813">issue
274 with Minecraft server broadcasts disappearing
</a>, which was quickly
275 resolved by the developer with a patch and a proposed configuration
276 change. I've been told this was caused by the Debian packages default
277 use if /proc/ information to track down kernel status, instead of the
278 newer eBPF module that can be used. The reason is simply that
279 upstream and I have failed to find a way to build the eBPF modules for
280 OpenSnitch without a complete configured Linux kernel source tree,
281 which as far as we can tell is unavailable as a build dependency in
282 Debian. We tried unsuccessfully so far to use the kernel-headers
283 package. It would be great if someone could provide some clues how to
284 build eBPF modules on build daemons in Debian, possibly without the full
287 <p>As usual, if you use Bitcoin and want to show your support of my
288 activities, please send Bitcoin donations to my address
289 <b><a href=
"bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b
</a></b>.
</p>
294 Tags:
<a href=
"https://people.skolelinux.org/pere/blog/tags/debian">debian
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/english">english
</a>.
299 <div class=
"padding"></div>
302 <div class=
"title"><a href=
"https://people.skolelinux.org/pere/blog/Is_the_desktop_recommending_your_program_for_opening_its_files_.html">Is the desktop recommending your program for opening its files?
</a></div>
303 <div class=
"date">29th January
2023</div>
304 <div class=
"body"><p>Linux desktop systems
305 <a href=
"https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html">have
306 standardized
</a> how programs present themselves to the desktop
307 system. If a package include a .desktop file in
308 /usr/share/applications/, Gnome, KDE, LXDE, Xfce and the other desktop
309 environments will pick up the file and use its content to generate the
310 menu of available programs in the system. A lesser known fact is that
311 a package can also explain to the desktop system how to recognize the
312 files created by the program in question, and use it to open these
313 files on request, for example via a GUI file browser.
</p>
315 <p>A while back I ran into a package that did not tell the desktop
316 system how to recognize its files and was not used to open its files
317 in the file browser and fixed it. In the process I wrote a simple
318 debian/tests/ script to ensure the setup keep working. It might be
319 useful for other packages too, to ensure any future version of the
320 package keep handling its own files.
</p>
322 <p>For this to work the file format need a useful MIME type that can
323 be used to identify the format. If the file format do not yet have a
324 MIME type, it should define one and preferably also
325 <a href=
"https://www.iana.org/assignments/media-types/media-types.xhtml">register
326 it with IANA
</a> to ensure the MIME type string is reserved.
</p>
328 <p>The script uses the
<tt>xdg-mime
</tt> program from xdg-utils to
329 query the database of standardized package information and ensure it
330 return sensible values. It also need the location of an example file
331 for xdg-mime to guess the format of.
</p>
336 # Author: Petter Reinholdtsen
337 # License: GPL v2 or later at your choice.
339 # Validate the MIME setup, making sure motor types have
340 # application/vnd.openmotor+yaml associated with them and is connected
341 # to the openmotor desktop file.
345 mimetype="application/vnd.openmotor+yaml"
346 testfile="test/data/real/o3100/motor.ric"
347 mydesktopfile="openmotor.desktop"
349 filemime="$(xdg-mime query filetype "$testfile")"
351 if [ "$mimetype" != "$filemime" ] ; then
353 echo "error: xdg-mime claim motor file MIME type is $filemine, not $mimetype"
355 echo "success: xdg-mime report correct mime type $mimetype for motor file"
358 desktop=$(xdg-mime query default "$mimetype")
360 if [ "$mydesktopfile" != "$desktop" ]; then
362 echo "error: xdg-mime claim motor file should be handled by $desktop, not $mydesktopfile"
364 echo "success: xdg-mime agree motor file should be handled by $mydesktopfile"
370 <p>It is a simple way to ensure your users are not very surprised when
371 they try to open one of your file formats in their file browser.
</p>
373 <p>As usual, if you use Bitcoin and want to show your support of my
374 activities, please send Bitcoin donations to my address
375 <b><a href=
"bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b
</a></b>.
</p>
380 Tags:
<a href=
"https://people.skolelinux.org/pere/blog/tags/debian">debian
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/english">english
</a>.
385 <div class=
"padding"></div>
388 <div class=
"title"><a href=
"https://people.skolelinux.org/pere/blog/Opensnitch__the_application_level_interactive_firewall__heading_into_the_Debian_archive.html">Opensnitch, the application level interactive firewall, heading into the Debian archive
</a></div>
389 <div class=
"date">22nd January
2023</div>
390 <div class=
"body"><p>While reading a
391 <a href=
"https://sneak.berlin/20230115/macos-scans-your-local-files-now/">blog
392 post claiming MacOS X recently started scanning local files and
393 reporting information about them to Apple
</a>, even on a machine where
394 all such callback features had been disabled, I came across a
395 description of the Little Snitch application for MacOS X. It seemed
396 like a very nice tool to have in the tool box, and I decided to see if
397 something similar was available for Linux.
</p>
399 <p>It did not take long to find
400 <a href=
"https://github.com/evilsocket/opensnitch">the OpenSnitch
401 package
</a>, which has been in development since
2017, and now is in
402 version
1.5.0. It has had a
403 <a href=
"https://bugs.debian.org/909567">request for Debian
404 packaging
</a> since
2018, but no-one completed the job so far. Just
405 for fun, I decided to see if I could help, and I was very happy to
407 <a href=
"https://github.com/evilsocket/opensnitch/issues/304">upstream
408 want a Debian package too
</a>.
</p>
410 <p>After struggling a bit with getting the program to run, figuring
411 out building Go programs (and a little failed detour to look at eBPF
412 builds too - help needed), I am very happy to report that I am
413 sponsoring upstream to maintain the package in Debian, and it has
414 since this morning been waiting in NEW for the ftpmasters to have a
415 look. Perhaps it can get into the archive in time for the Bookworm
418 <p>As usual, if you use Bitcoin and want to show your support of my
419 activities, please send Bitcoin donations to my address
420 <b><a href=
"bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b
</a></b>.
</p>
425 Tags:
<a href=
"https://people.skolelinux.org/pere/blog/tags/debian">debian
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/english">english
</a>.
430 <div class=
"padding"></div>
433 <div class=
"title"><a href=
"https://people.skolelinux.org/pere/blog/LinuxCNC_MQTT_publisher_component.html">LinuxCNC MQTT publisher component
</a></div>
434 <div class=
"date"> 8th January
2023</div>
435 <div class=
"body"><p>I watched
<a href=
"https://yewtu.be/watch?v=jmKUV3aNLjk">a
2015
436 video from Andreas Schiffler
</a> the other day, where he set up
437 <a href=
"https://linuxcnc.org/">LinuxCNC
</a> to send status
438 information to the MQTT broker IBM Bluemix. As I also use MQTT for
439 graphing, it occured to me that a generic MQTT LinuxCNC component
440 would be useful and I set out to implement it. Today I got the first
441 draft limping along and submitted as
442 <a href=
"https://github.com/LinuxCNC/linuxcnc/pull/2253">a patch to the
443 LinuxCNC project
</a>.
</p>
445 <p>The simple part was setting up the MQTT publishing code in Python.
446 I already have set up other parts submitting data to my Mosquito MQTT
447 broker, so I could reuse that code. Writing a LinuxCNC component in
448 Python as new to me, but using existing examples in the code
449 repository and the extensive documentation, this was fairly straight
450 forward. The hardest part was creating a automated test for the
451 component to ensure it was working. Testing it in a simulated
452 LinuxCNC machine proved very useful, as I discovered features I needed
453 that I had not thought of yet, and adjusted the code quite a bit to
454 make it easier to test without a operational MQTT broker
457 <p>The draft is ready and working, but I am unsure which LinuxCNC HAL
458 pins I should collect and publish by default (in other words, the
459 default set of information pieces published), and how to get the
460 machine name from the LinuxCNC INI file. The latter is a minor
461 detail, but I expect it would be useful in a setup with several
462 machines available. I am hoping for feedback from the experienced
463 LinuxCNC developers and users, to make the component even better
464 before it can go into the mainland LinuxCNC code base.
</p>
466 <p>Since I started on the MQTT component, I came across
467 <a href=
"https://yewtu.be/watch?v=Bqa2grG0XtA">another video from Kent
468 VanderVelden
</a> where he combine LinuxCNC with a set of screen glasses
469 controlled by a Raspberry Pi, and it occured to me that it would
470 be useful for such use cases if LinuxCNC also provided a REST API for
471 querying its status. I hope to start on such component once the MQTT
472 component is working well.
</p>
474 <p>As usual, if you use Bitcoin and want to show your support of my
475 activities, please send Bitcoin donations to my address
476 <b><a href=
"bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b
</a></b>.
</p>
481 Tags:
<a href=
"https://people.skolelinux.org/pere/blog/tags/debian">debian
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/english">english
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/linuxcnc">linuxcnc
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/robot">robot
</a>.
486 <div class=
"padding"></div>
489 <div class=
"title"><a href=
"https://people.skolelinux.org/pere/blog/ONVIF_IP_camera_management_tool_finally_in_Debian.html">ONVIF IP camera management tool finally in Debian
</a></div>
490 <div class=
"date">24th December
2022</div>
491 <div class=
"body"><p>Merry Christmas to you all. Here is a small gift to all those with
492 IP cameras following the
<a href=
"https://www.onvif.org/">ONVIF
493 specification
</a>. There is finally a nice command line and GUI tool
494 in Debian to manage ONVIF IP cameras. After working with upstream for
495 a few months and sponsoring the upload, I am very happy to report that
496 the
<a href=
"https://tracker.debian.org/libonvif">libonvif package
</a>
497 entered Debian Sid last night.
</p>
499 <p>The package provide a C library to communicate with such cameras, a
500 command line tool to locate and update settings of (like password) the
501 cameras and a GUI tool to configure and control the units as well as
502 preview the video from the camera. Libonvif is available on Both
503 Linux and Windows and the GUI tool uses the Qt library. The main
504 competitors are non-free software, while libonvif is GNU GPL licensed.
505 I am very glad Debian users in the future can control their cameras
506 using a free software system provided by Debian. But the ONVIF world
507 is full of slightly broken firmware, where the cameras pretend to
508 follow the ONVIF specification but fail to set some configuration
509 values or refuse to provide video to more than one recipient at the
510 time, and the onvif project is quite young and might take a while
511 before it completely work with your camera. Upstream seem eager to
512 improve the library, so handling any broken camera might be just
<a
513 href=
"https://github.com/sr99622/libonvif/">a bug report away
</a>.
</p>
515 <p>The package just cleared NEW, and need a new source only upload
516 before it can enter testing. This will happen in the next few
519 <p>As usual, if you use Bitcoin and want to show your support of my
520 activities, please send Bitcoin donations to my address
521 <b><a href=
"bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b
</a></b>.
</p>
526 Tags:
<a href=
"https://people.skolelinux.org/pere/blog/tags/debian">debian
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/english">english
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/multimedia">multimedia
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/standard">standard
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/surveillance">surveillance
</a>.
531 <div class=
"padding"></div>
534 <div class=
"title"><a href=
"https://people.skolelinux.org/pere/blog/Managing_and_using_ONVIF_IP_cameras_with_Linux.html">Managing and using ONVIF IP cameras with Linux
</a></div>
535 <div class=
"date">19th October
2022</div>
536 <div class=
"body"><p>Recently I have been looking at how to control and collect data
537 from a handful IP cameras using Linux. I both wanted to change their
538 settings and to make their imagery available via a free software
539 service under my control. Here is a summary of the tools I found.
</p>
541 <p>First I had to identify the cameras and their protocols. As far as
542 I could tell, they were using some SOAP looking protocol and their
543 internal web server seem to only work with Microsoft Internet Explorer
544 with some proprietary binary plugin, which in these days of course is
545 a security disaster and also made it impossible for me to use the
546 camera web interface. Luckily I discovered that the SOAP looking
547 protocol is actually following
<a href=
"https://www.onvif.org/">the
548 ONVIF specification
</a>, which seem to be supported by a lot of IP
549 cameras these days.
</p>
551 <p>Once the protocol was identified, I was able to find what appear to
552 be the most popular way to configure ONVIF cameras, the free software
554 <a href=
"https://sourceforge.net/projects/onvifdm/">ONVIF Device
555 Manager
</a>. Lacking any other options at the time, I tried
556 unsuccessfully to get it running using Wine, but was missing a dotnet
557 40 library and I found no way around it to run it on Linux.
</p>
559 <p>The next tool I found to configure the cameras were a non-free Linux Qt
560 client
<a href=
"https://www.lingodigit.com/onvif_nvcdemo.html">ONVIF
561 Device Tool
</a>. I did not like its terms of use, so did not spend
564 <p>To collect the video and make it available in a web interface, I
565 found the Zoneminder tool in Debian. A recent version was able to
566 automatically detect and configure ONVIF devices, so I could use it to
567 set up motion detection in and collection of the camera output. I had
568 initial problems getting the ONVIF autodetection to work, as both
569 Firefox and Chromium
<a href=
"https://bugs.debian.org/1001188">refused
570 the inter-tab communication
</a> being used by the Zoneminder web
571 pages, but managed to get konqueror to work. Apparently the "Enhanced
572 Tracking Protection" in Firefox cause the problem. I ended up
573 upgrading to the Bookworm edition of Zoneminder in the process to try
574 to fix the issue, and believe the problem might be solved now.
</p>
576 <p>In the process I came across the nice Linux GUI tool
577 <a href=
"https://gitlab.com/caspermeijn/onvifviewer/">ONVIF Viewer
</a>
578 allowing me to preview the camera output and validate the login
579 passwords required. Sadly its author has grown tired of maintaining
580 the software, so it might not see any future updates. Which is sad,
581 as the viewer is sightly unstable and the picture tend to lock up.
582 Note, this lockup might be due to limitations in the cameras and not
583 the viewer implementation. I suspect the camera is only able to
584 provide pictures to one client at the time, and the Zoneminder feed
585 might interfere with the GUI viewer. I have
586 <a href=
"https://bugs.debian.org/1000820">asked for the tool to be
587 included in Debian
</a>.
</p>
589 <p>Finally, I found what appear to be very nice Linux free software
590 replacement for the Windows tool, named
591 <a href=
"https://github.com/sr99622/libonvif/">libonvif
</a>. It
592 provide a C library to talk to ONVIF devices as well as a command line
593 and GUI tool using the library. Using the GUI tool I was able to change
594 the admin passwords and update other settings of the cameras. I have
595 <a href=
"https://bugs.debian.org/1021980">asked for the package to be
596 included in Debian
</a>.
</p>
598 <p>As usual, if you use Bitcoin and want to show your support of my
599 activities, please send Bitcoin donations to my address
600 <b><a href=
"bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b
</a></b>.
</p>
602 <p><strong>Update
2022-
10-
20</strong>: Since my initial publication of
603 this text, I got several suggestions for more free software Linux
604 tools. There is
<a href=
"https://github.com/quatanium/python-onvif">a
605 ONVIF python library
</a> (already
606 <a href=
"https://bugs.debian.org/824240">requested into Debian
</a>) and
607 <a href=
"https://github.com/FalkTannhaeuser/python-onvif-zeep">a python
3
608 fork
</a> using a different SOAP dependency. There is also
609 <a href=
"https://www.home-assistant.io/integrations/onvif/">support for
610 ONVIF in Home Assistant
</a>, and there is an alternative to Zoneminder
611 called
<a href=
"https://www.shinobi.video/">Shinobi
</a>. The latter
612 two are not included in Debian either. I have not tested any of these
618 Tags:
<a href=
"https://people.skolelinux.org/pere/blog/tags/debian">debian
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/english">english
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/multimedia">multimedia
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/standard">standard
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/surveillance">surveillance
</a>.
623 <div class=
"padding"></div>
626 <div class=
"title"><a href=
"https://people.skolelinux.org/pere/blog/Time_to_translate_the_Bullseye_edition_of_the_Debian_Administrator_s_Handbook.html">Time to translate the Bullseye edition of the Debian Administrator's Handbook
</a></div>
627 <div class=
"date">12th September
2022</div>
628 <div class=
"body"><p align=
"center"><img align=
"center" src=
"http://people.skolelinux.org/pere/blog/images/2020-10-20-debian-handbook-nb-testprint.jpeg" width=
"60%"/></p>
630 <p>(The picture is of the previous edition.)
</p>
632 <p>Almost two years after the previous Norwegian Bokmål translation of
633 the "
<a href=
"https://debian-handbook.info/">The Debian Administrator's
634 Handbook
</a>" was published, a new edition is finally being prepared. The
635 english text is updated, and it is time to start working on the
636 translations. Around 37 percent of the strings have been updated, one
637 way or another, and the translations starting from a complete Debian Buster
638 edition now need to bring their translation up from 63% to 100%. The
639 complete book is licensed using a Creative Commons license, and has
640 been published in several languages over the years. The translations
641 are done by volunteers to bring Linux in their native tongue. The
642 last time I checked, it complete text was available in English,
643 Norwegian Bokmål, German, Indonesian, Brazil Portuguese and Spanish.
644 In addition, work has been started for Arabic (Morocco), Catalan,
645 Chinese (Simplified), Chinese (Traditional), Croatian, Czech, Danish,
646 Dutch, French, Greek, Italian, Japanese, Korean, Persian, Polish,
647 Romanian, Russian, Swedish, Turkish and Vietnamese.</p>
649 <p>The translation is conducted on
650 <a href="https://hosted.weblate.org/projects/debian-handbook/
">the
651 hosted weblate project page</a>. Prospective translators are
652 recommeded to subscribe to
653 <a href="http://lists.alioth.debian.org/mailman/listinfo/debian-handbook-translators
">the
654 translators mailing list</a> and should also check out
655 <a href="https://debian-handbook.info/contribute/
">the instructions for
656 contributors</a>.</p>
658 <p>I am one of the Norwegian Bokmål translators of this book, and we
659 have just started. Your contribution is most welcome.</p>
661 <p>As usual, if you use Bitcoin and want to show your support of my
662 activities, please send Bitcoin donations to my address
663 <b><a href="bitcoin:
15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b
">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b</a></b>.</p>
668 Tags: <a href="https://people.skolelinux.org/pere/blog/tags/debian
">debian</a>, <a href="https://people.skolelinux.org/pere/blog/tags/debian-handbook
">debian-handbook</a>, <a href="https://people.skolelinux.org/pere/blog/tags/english
">english</a>.
673 <div class="padding
"></div>
676 <div class="title
"><a href="https://people.skolelinux.org/pere/blog/Automatic_LinuxCNC_servo_PID_tuning_.html
">Automatic LinuxCNC servo PID tuning?</a></div>
677 <div class="date
">16th July 2022</div>
678 <div class="body
"><p>While working on a CNC with servo motors controlled by the
679 <a href="https://en.wikipedia.org/wiki/LinuxCNC
">LinuxCNC</a>
680 <a href="https://en.wikipedia.org/wiki/PID_controller
">PID
681 controller</a>, I recently had to learn how to tune the collection of values
682 that control such mathematical machinery that a PID controller is. It
683 proved to be a lot harder than I hoped, and I still have not succeeded
684 in getting the Z PID controller to successfully defy gravity, nor X
685 and Y to move accurately and reliably. But while climbing up this
686 rather steep learning curve, I discovered that some motor control
687 systems are able to tune their PID controllers. I got the impression
688 from the documentation that LinuxCNC were not. This proved to be not
692 <a href="http://linuxcnc.org/docs/html/man/man9/pid
.9.html
">pid
693 component</a> is the recommended PID controller to use. It uses eight
694 constants <tt>Pgain</tt>, <tt>Igain</tt>, <tt>Dgain</tt>,
695 <tt>bias</tt>, <tt>FF0</tt>, <tt>FF1</tt>, <tt>FF2</tt> and
696 <tt>FF3</tt> to calculate the output value based on current and wanted
697 state, and all of these need to have a sensible value for the
698 controller to behave properly. Note, there are even more values
699 involved, theser are just the most important ones. In my case I need
700 the X, Y and Z axes to follow the requested path with little error.
701 This has proved quite a challenge for someone who have never tuned a
702 PID controller before, but there is at least some help to be found.
704 <p>I discovered that included in LinuxCNC was this old PID component
705 at_pid claiming to have auto tuning capabilities. Sadly it had been
706 neglected since 2011, and could not be used as a plug in replacement
707 for the default pid component. One would have to rewriting the
708 LinuxCNC HAL setup to test at_pid. This was rather sad, when I wanted
709 to quickly test auto tuning to see if it did a better job than me at
710 figuring out good P, I and D values to use.</p>
712 <p>I decided to have a look if the situation could be improved. This
713 involved trying to understand the code and history of the pid and
714 at_pid components. Apparently they had a common ancestor, as code
715 structure, comments and variable names were quite close to each other.
716 Sadly this was not reflected in the git history, making it hard to
717 figure out what really happened. My guess is that the author of
718 <a href="https://github.com/LinuxCNC/linuxcnc/blob/master/src/hal/components/at_pid.c
">at_pid.c</a>
720 <a href="https://github.com/LinuxCNC/linuxcnc/blob/master/src/hal/components/pid.c
">pid.c</a>,
721 rewrote it to follow the structure he wished pid.c to have, then added
722 support for auto tuning and finally got it included into the LinuxCNC
723 repository. The restructuring and lack of early history made it
724 harder to figure out which part of the code were relevant to the auto
725 tuning, and which part of the code needed to be updated to work the
726 same way as the current pid.c implementation. I started by trying to
727 isolate relevant changes in pid.c, and applying them to at_pid.c. My
728 aim was to make sure the at_pid component could replace the pid
729 component with a simple change in the HAL setup loadrt line, without
730 having to "rewire" the rest of the HAL configuration. After a few
731 hours following this approach, I had learned quite a lot about the
732 code structure of both components, while concluding I was heading down
733 the wrong rabbit hole, and should get back to the surface and find a
736 <p>For the second attempt, I decided to throw away all the PID control
737 related part of the original at_pid.c, and instead isolate and lift
738 the auto tuning part of the code and inject it into a copy of pid.c.
739 This ensured compatibility with the current pid component, while
740 adding auto tuning as a run time option. To make it easier to identify
741 the relevant parts in the future, I wrapped all the auto tuning code
742 with '#ifdef AUTO_TUNER'. The end result behave just like the current
743 pid component by default, as that part of the code is identical. The
744 <a href=
"https://github.com/LinuxCNC/linuxcnc/pull/1820">end result
745 entered the LinuxCNC master branch
</a> a few days ago.
</p>
747 <p>To enable auto tuning, one need to set a few HAL pins in the PID
748 component. The most important ones are
<tt>tune-effort
</tt>,
749 <tt>tune-mode
</tt> and
<tt>tune-start
</tt>. But lets take a step
750 back, and see what the auto tuning code will do. I do not know the
751 mathematical foundation of the at_pid algorithm, but from observation
752 I can tell that the algorithm will, when enabled, produce a square
753 wave pattern centered around the
<tt>bias
</tt> value on the output pin
754 of the PID controller. This can be seen using the HAL Scope provided
755 by LinuxCNC. In my case, this is translated into voltage (+-
10V) sent
756 to the motor controller, which in turn is translated into motor speed.
757 So at_pid will ask the motor to move the axis back and forth. The
758 number of cycles in the pattern is controlled by the
759 <tt>tune-cycles
</tt> pin, and the extremes of the wave pattern is
760 controlled by the
<tt>tune-effort
</tt> pin. Of course, trying to
761 change the direction of a physical object instantly (as in going
762 directly from a positive voltage to the equivalent negative voltage)
763 do not change velocity instantly, and it take some time for the object
764 to slow down and move in the opposite direction. This result in a
765 more smooth movement wave form, as the axis in question were vibrating
766 back and forth. When the axis reached the target speed in the
767 opposing direction, the auto tuner change direction again. After
768 several of these changes, the average time delay between the 'peaks'
769 and 'valleys' of this movement graph is then used to calculate
770 proposed values for Pgain, Igain and Dgain, and insert them into the
771 HAL model to use by the pid controller. The auto tuned settings are
772 not great, but htye work a lot better than the values I had been able
773 to cook up on my own, at least for the horizontal X and Y axis. But I
774 had to use very small
<tt>tune-effort
<tt> values, as my motor
775 controllers error out if the voltage change too quickly. I've been
776 less lucky with the Z axis, which is moving a heavy object up and
777 down, and seem to confuse the algorithm. The Z axis movement became a
778 lot better when I introduced a
<tt>bias
</tt> value to counter the
779 gravitational drag, but I will have to work a lot more on the Z axis
782 <p>Armed with this knowledge, it is time to look at how to do the
783 tuning. Lets say the HAL configuration in question load the PID
784 component for X, Y and Z like this:
</p>
787 loadrt pid names=pid.x,pid.y,pid.z
790 <p>Armed with the new and improved at_pid component, the new line will
794 loadrt at_pid names=pid.x,pid.y,pid.z
797 <p>The rest of the HAL setup can stay the same. This work because the
798 components are referenced by name. If the component had used count=
3
799 instead, all use of pid.# had to be changed to at_pid.#.
</p>
801 <p>To start tuning the X axis, move the axis to the middle of its
802 range, to make sure it do not hit anything when it start moving back
803 and forth. Next, set the
<tt>tune-effort
</tt> to a low number in the
804 output range. I used
0.1 as my initial value. Next, assign
1 to the
805 <tt>tune-mode
</tt> value. Note, this will disable the pid controlling
806 part and feed
0 to the output pin, which in my case initially caused a
807 lot of drift. In my case it proved to be a good idea with X and Y to
808 tune the motor driver to make sure
0 voltage stopped the motor
809 rotation. On the other hand, for the Z axis this proved to be a bad
810 idea, so it will depend on your setup. It might help to set the
811 <tt>bias
</tt> value to a output value that reduce or eliminate the
812 axis drift. Finally, after setting
<tt>tune-mode
</tt>, set
813 <tt>tune-start
</tt> to
1 to activate the auto tuning. If all go well,
814 your axis will vibrate for a few seconds and when it is done, new
815 values for Pgain, Igain and Dgain will be active. To test them,
816 change
<tt>tune-mode
</tt> back to
0. Note that this might cause the
817 machine to suddenly jerk as it bring the axis back to its commanded
818 position, which it might have drifted away from during tuning. To
819 summarize with some halcmd lines:
</p>
822 setp pid.x.tune-effort
0.1
823 setp pid.x.tune-mode
1
824 setp pid.x.tune-start
1
825 # wait for the tuning to complete
826 setp pid.x.tune-mode
0
829 <p>After doing this task quite a few times while trying to figure out
830 how to properly tune the PID controllers on the machine in, I decided
831 to figure out if this process could be automated, and wrote a script
832 to do the entire tuning process from power on. The end result will
833 ensure the machine is powered on and ready to run, home all axis if it
834 is not already done, check that the extra tuning pins are available,
835 move the axis to its mid point, run the auto tuning and re-enable the
836 pid controller when it is done. It can be run several times. Check
838 <a href=
"https://github.com/SebKuzminsky/MazakVQC1540/blob/bon-dev/scripts/run-auto-pid-tuner">run-auto-pid-tuner
</a>
839 script on github if you want to learn how it is done.
</p>
841 <p>My hope is that this little adventure can inspire someone who know
842 more about motor PID controller tuning can implement even better
843 algorithms for automatic PID tuning in LinuxCNC, making life easier
844 for both me and all the others that want to use LinuxCNC but lack the
845 in depth knowledge needed to tune PID controllers well.
</p>
847 <p>As usual, if you use Bitcoin and want to show your support of my
848 activities, please send Bitcoin donations to my address
849 <b><a href=
"bitcoin:15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b">15oWEoG9dUPovwmUL9KWAnYRtNJEkP1u1b
</a></b>.
</p>
854 Tags:
<a href=
"https://people.skolelinux.org/pere/blog/tags/3d-printer">3d-printer
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/debian">debian
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/english">english
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/linuxcnc">linuxcnc
</a>,
<a href=
"https://people.skolelinux.org/pere/blog/tags/robot">robot
</a>.
859 <div class=
"padding"></div>
861 <p style=
"text-align: right;"><a href=
"index.rss"><img src=
"https://people.skolelinux.org/pere/blog/xml.gif" alt=
"RSS feed" width=
"36" height=
"14" /></a></p>
872 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2023/01/">January (
3)
</a></li>
874 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2023/02/">February (
1)
</a></li>
876 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2023/04/">April (
2)
</a></li>
883 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2022/02/">February (
1)
</a></li>
885 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2022/03/">March (
3)
</a></li>
887 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2022/04/">April (
2)
</a></li>
889 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2022/06/">June (
2)
</a></li>
891 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2022/07/">July (
1)
</a></li>
893 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2022/09/">September (
1)
</a></li>
895 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2022/10/">October (
1)
</a></li>
897 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2022/12/">December (
1)
</a></li>
904 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2021/01/">January (
2)
</a></li>
906 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2021/02/">February (
1)
</a></li>
908 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2021/05/">May (
1)
</a></li>
910 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2021/06/">June (
1)
</a></li>
912 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2021/07/">July (
3)
</a></li>
914 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2021/08/">August (
1)
</a></li>
916 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2021/09/">September (
1)
</a></li>
918 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2021/10/">October (
1)
</a></li>
920 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2021/12/">December (
1)
</a></li>
927 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2020/02/">February (
2)
</a></li>
929 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2020/03/">March (
2)
</a></li>
931 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2020/04/">April (
2)
</a></li>
933 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2020/05/">May (
3)
</a></li>
935 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2020/06/">June (
2)
</a></li>
937 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2020/07/">July (
1)
</a></li>
939 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2020/09/">September (
1)
</a></li>
941 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2020/10/">October (
1)
</a></li>
943 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2020/11/">November (
1)
</a></li>
950 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2019/01/">January (
4)
</a></li>
952 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2019/02/">February (
3)
</a></li>
954 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2019/03/">March (
3)
</a></li>
956 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2019/05/">May (
2)
</a></li>
958 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2019/06/">June (
5)
</a></li>
960 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2019/07/">July (
2)
</a></li>
962 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2019/08/">August (
1)
</a></li>
964 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2019/09/">September (
1)
</a></li>
966 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2019/11/">November (
1)
</a></li>
968 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2019/12/">December (
4)
</a></li>
975 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2018/01/">January (
1)
</a></li>
977 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2018/02/">February (
5)
</a></li>
979 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2018/03/">March (
5)
</a></li>
981 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2018/04/">April (
3)
</a></li>
983 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2018/06/">June (
2)
</a></li>
985 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2018/07/">July (
5)
</a></li>
987 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2018/08/">August (
3)
</a></li>
989 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2018/09/">September (
3)
</a></li>
991 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2018/10/">October (
5)
</a></li>
993 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2018/11/">November (
2)
</a></li>
995 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2018/12/">December (
4)
</a></li>
1002 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2017/01/">January (
4)
</a></li>
1004 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2017/02/">February (
3)
</a></li>
1006 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2017/03/">March (
5)
</a></li>
1008 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2017/04/">April (
2)
</a></li>
1010 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2017/06/">June (
5)
</a></li>
1012 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2017/07/">July (
1)
</a></li>
1014 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2017/08/">August (
1)
</a></li>
1016 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2017/09/">September (
3)
</a></li>
1018 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2017/10/">October (
5)
</a></li>
1020 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2017/11/">November (
3)
</a></li>
1022 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2017/12/">December (
4)
</a></li>
1029 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2016/01/">January (
3)
</a></li>
1031 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2016/02/">February (
2)
</a></li>
1033 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2016/03/">March (
3)
</a></li>
1035 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2016/04/">April (
8)
</a></li>
1037 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2016/05/">May (
8)
</a></li>
1039 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2016/06/">June (
2)
</a></li>
1041 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2016/07/">July (
2)
</a></li>
1043 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2016/08/">August (
5)
</a></li>
1045 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2016/09/">September (
2)
</a></li>
1047 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2016/10/">October (
3)
</a></li>
1049 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2016/11/">November (
8)
</a></li>
1051 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2016/12/">December (
5)
</a></li>
1058 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2015/01/">January (
7)
</a></li>
1060 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2015/02/">February (
6)
</a></li>
1062 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2015/03/">March (
1)
</a></li>
1064 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2015/04/">April (
4)
</a></li>
1066 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2015/05/">May (
3)
</a></li>
1068 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2015/06/">June (
4)
</a></li>
1070 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2015/07/">July (
6)
</a></li>
1072 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2015/08/">August (
2)
</a></li>
1074 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2015/09/">September (
2)
</a></li>
1076 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2015/10/">October (
9)
</a></li>
1078 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2015/11/">November (
6)
</a></li>
1080 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2015/12/">December (
3)
</a></li>
1087 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2014/01/">January (
2)
</a></li>
1089 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2014/02/">February (
3)
</a></li>
1091 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2014/03/">March (
8)
</a></li>
1093 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2014/04/">April (
7)
</a></li>
1095 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2014/05/">May (
1)
</a></li>
1097 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2014/06/">June (
2)
</a></li>
1099 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2014/07/">July (
2)
</a></li>
1101 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2014/08/">August (
2)
</a></li>
1103 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2014/09/">September (
5)
</a></li>
1105 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2014/10/">October (
6)
</a></li>
1107 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2014/11/">November (
3)
</a></li>
1109 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2014/12/">December (
5)
</a></li>
1116 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2013/01/">January (
11)
</a></li>
1118 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2013/02/">February (
9)
</a></li>
1120 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2013/03/">March (
9)
</a></li>
1122 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2013/04/">April (
6)
</a></li>
1124 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2013/05/">May (
9)
</a></li>
1126 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2013/06/">June (
10)
</a></li>
1128 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2013/07/">July (
7)
</a></li>
1130 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2013/08/">August (
3)
</a></li>
1132 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2013/09/">September (
5)
</a></li>
1134 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2013/10/">October (
7)
</a></li>
1136 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2013/11/">November (
9)
</a></li>
1138 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2013/12/">December (
3)
</a></li>
1145 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2012/01/">January (
7)
</a></li>
1147 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2012/02/">February (
10)
</a></li>
1149 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2012/03/">March (
17)
</a></li>
1151 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2012/04/">April (
12)
</a></li>
1153 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2012/05/">May (
12)
</a></li>
1155 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2012/06/">June (
20)
</a></li>
1157 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2012/07/">July (
17)
</a></li>
1159 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2012/08/">August (
6)
</a></li>
1161 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2012/09/">September (
9)
</a></li>
1163 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2012/10/">October (
17)
</a></li>
1165 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2012/11/">November (
10)
</a></li>
1167 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2012/12/">December (
7)
</a></li>
1174 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2011/01/">January (
16)
</a></li>
1176 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2011/02/">February (
6)
</a></li>
1178 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2011/03/">March (
6)
</a></li>
1180 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2011/04/">April (
7)
</a></li>
1182 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2011/05/">May (
3)
</a></li>
1184 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2011/06/">June (
2)
</a></li>
1186 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2011/07/">July (
7)
</a></li>
1188 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2011/08/">August (
6)
</a></li>
1190 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2011/09/">September (
4)
</a></li>
1192 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2011/10/">October (
2)
</a></li>
1194 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2011/11/">November (
3)
</a></li>
1196 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2011/12/">December (
1)
</a></li>
1203 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2010/01/">January (
2)
</a></li>
1205 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2010/02/">February (
1)
</a></li>
1207 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2010/03/">March (
3)
</a></li>
1209 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2010/04/">April (
3)
</a></li>
1211 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2010/05/">May (
9)
</a></li>
1213 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2010/06/">June (
14)
</a></li>
1215 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2010/07/">July (
12)
</a></li>
1217 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2010/08/">August (
13)
</a></li>
1219 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2010/09/">September (
7)
</a></li>
1221 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2010/10/">October (
9)
</a></li>
1223 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2010/11/">November (
13)
</a></li>
1225 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2010/12/">December (
12)
</a></li>
1232 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2009/01/">January (
8)
</a></li>
1234 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2009/02/">February (
8)
</a></li>
1236 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2009/03/">March (
12)
</a></li>
1238 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2009/04/">April (
10)
</a></li>
1240 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2009/05/">May (
9)
</a></li>
1242 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2009/06/">June (
3)
</a></li>
1244 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2009/07/">July (
4)
</a></li>
1246 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2009/08/">August (
3)
</a></li>
1248 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2009/09/">September (
1)
</a></li>
1250 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2009/10/">October (
2)
</a></li>
1252 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2009/11/">November (
3)
</a></li>
1254 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2009/12/">December (
3)
</a></li>
1261 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2008/11/">November (
5)
</a></li>
1263 <li><a href=
"https://people.skolelinux.org/pere/blog/archive/2008/12/">December (
7)
</a></li>
1274 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/3d-printer">3d-printer (
19)
</a></li>
1276 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/amiga">amiga (
1)
</a></li>
1278 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/aros">aros (
1)
</a></li>
1280 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/bankid">bankid (
4)
</a></li>
1282 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/betalkontant">betalkontant (
9)
</a></li>
1284 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/bitcoin">bitcoin (
12)
</a></li>
1286 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/bootsystem">bootsystem (
17)
</a></li>
1288 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/bsa">bsa (
2)
</a></li>
1290 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/chrpath">chrpath (
2)
</a></li>
1292 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/debian">debian (
190)
</a></li>
1294 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/debian edu">debian edu (
159)
</a></li>
1296 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/debian-handbook">debian-handbook (
9)
</a></li>
1298 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/digistan">digistan (
11)
</a></li>
1300 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/dld">dld (
18)
</a></li>
1302 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/docbook">docbook (
30)
</a></li>
1304 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/drivstoffpriser">drivstoffpriser (
4)
</a></li>
1306 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/english">english (
446)
</a></li>
1308 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/fiksgatami">fiksgatami (
23)
</a></li>
1310 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/fildeling">fildeling (
14)
</a></li>
1312 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/freeculture">freeculture (
34)
</a></li>
1314 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/freedombox">freedombox (
9)
</a></li>
1316 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/frikanalen">frikanalen (
20)
</a></li>
1318 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/h264">h264 (
20)
</a></li>
1320 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/intervju">intervju (
43)
</a></li>
1322 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/isenkram">isenkram (
16)
</a></li>
1324 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/kart">kart (
23)
</a></li>
1326 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/kodi">kodi (
4)
</a></li>
1328 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/ldap">ldap (
9)
</a></li>
1330 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/lego">lego (
5)
</a></li>
1332 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/lenker">lenker (
8)
</a></li>
1334 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/linuxcnc">linuxcnc (
4)
</a></li>
1336 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/lsdvd">lsdvd (
2)
</a></li>
1338 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/ltsp">ltsp (
1)
</a></li>
1340 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/madewithcc">madewithcc (
3)
</a></li>
1342 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/mesh network">mesh network (
8)
</a></li>
1344 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/multimedia">multimedia (
45)
</a></li>
1346 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/nice free software">nice free software (
14)
</a></li>
1348 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/noark5">noark5 (
23)
</a></li>
1350 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/norsk">norsk (
320)
</a></li>
1352 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/nuug">nuug (
198)
</a></li>
1354 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/offentlig innsyn">offentlig innsyn (
40)
</a></li>
1356 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/open311">open311 (
2)
</a></li>
1358 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/opphavsrett">opphavsrett (
75)
</a></li>
1360 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/personvern">personvern (
114)
</a></li>
1362 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/raid">raid (
2)
</a></li>
1364 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/reactos">reactos (
1)
</a></li>
1366 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/reprap">reprap (
11)
</a></li>
1368 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/rfid">rfid (
3)
</a></li>
1370 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/robot">robot (
17)
</a></li>
1372 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/rss">rss (
1)
</a></li>
1374 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/ruter">ruter (
7)
</a></li>
1376 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/scraperwiki">scraperwiki (
2)
</a></li>
1378 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/sikkerhet">sikkerhet (
59)
</a></li>
1380 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/sitesummary">sitesummary (
4)
</a></li>
1382 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/skepsis">skepsis (
5)
</a></li>
1384 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/standard">standard (
74)
</a></li>
1386 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/stavekontroll">stavekontroll (
7)
</a></li>
1388 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/stortinget">stortinget (
14)
</a></li>
1390 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/surveillance">surveillance (
64)
</a></li>
1392 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/sysadmin">sysadmin (
5)
</a></li>
1394 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/usenix">usenix (
2)
</a></li>
1396 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/valg">valg (
9)
</a></li>
1398 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/verkidetfri">verkidetfri (
20)
</a></li>
1400 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/video">video (
78)
</a></li>
1402 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/vitenskap">vitenskap (
4)
</a></li>
1404 <li><a href=
"https://people.skolelinux.org/pere/blog/tags/web">web (
42)
</a></li>
1410 <p style=
"text-align: right">
1411 Created by
<a href=
"http://steve.org.uk/Software/chronicle">Chronicle v4.6
</a>