]> pere.pagekite.me Git - homepage.git/blob - blog/index.html
Generated.
[homepage.git] / blog / index.html
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">
4 <head>
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" />
10 </head>
11 <body>
12 <div class="title">
13 <h1>
14 <a href="https://people.skolelinux.org/pere/blog/">Petter Reinholdtsen</a>
15
16 </h1>
17
18 </div>
19
20
21
22 <div class="entry">
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
46 CPU.</p>
47
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
58 I also believed
59 <a href="https://bugs.debian.org/1034286">ffmpeg-python</a> was
60 needed, but as its
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>
72
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>
84
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>
105
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>
120
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>
127
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>
133
134 <p><pre>
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 &lt;&lt;EOF
139 deb https://geekbay.nuug.no/~pere/openai-whisper/ bookworm main
140 deb-src https://geekbay.nuug.no/~pere/openai-whisper/ bookworm main
141 EOF
142 apt update
143 apt install openai-whisper
144 </pre></p>
145
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>
155
156 <p>Now I can start on the audio recording part of this project.</p>
157
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>
161 </div>
162 <div class="tags">
163
164
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>.
166
167
168 </div>
169 </div>
170 <div class="padding"></div>
171
172 <div class="entry">
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>
189 and
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
194 installation.</p>
195
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>
204
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>
206
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>
210
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>
215
216 <pre>
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'
229 </pre>
230
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>
234 </div>
235 <div class="tags">
236
237
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>.
239
240
241 </div>
242 </div>
243 <div class="padding"></div>
244
245 <div class="entry">
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>
253
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
262 use the network.</p>
263
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>
271
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
285 kernel source.</p>
286
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>
290 </div>
291 <div class="tags">
292
293
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>.
295
296
297 </div>
298 </div>
299 <div class="padding"></div>
300
301 <div class="entry">
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>
314
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>
321
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>
327
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>
332
333 <pre>
334 #!/bin/sh
335 #
336 # Author: Petter Reinholdtsen
337 # License: GPL v2 or later at your choice.
338 #
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.
342
343 retval=0
344
345 mimetype="application/vnd.openmotor+yaml"
346 testfile="test/data/real/o3100/motor.ric"
347 mydesktopfile="openmotor.desktop"
348
349 filemime="$(xdg-mime query filetype "$testfile")"
350
351 if [ "$mimetype" != "$filemime" ] ; then
352 retval=1
353 echo "error: xdg-mime claim motor file MIME type is $filemine, not $mimetype"
354 else
355 echo "success: xdg-mime report correct mime type $mimetype for motor file"
356 fi
357
358 desktop=$(xdg-mime query default "$mimetype")
359
360 if [ "$mydesktopfile" != "$desktop" ]; then
361 retval=1
362 echo "error: xdg-mime claim motor file should be handled by $desktop, not $mydesktopfile"
363 else
364 echo "success: xdg-mime agree motor file should be handled by $mydesktopfile"
365 fi
366
367 exit $retval
368 </pre>
369
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>
372
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>
376 </div>
377 <div class="tags">
378
379
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>.
381
382
383 </div>
384 </div>
385 <div class="padding"></div>
386
387 <div class="entry">
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>
398
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
406 discover that
407 <a href="https://github.com/evilsocket/opensnitch/issues/304">upstream
408 want a Debian package too</a>.</p>
409
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
416 release?</p>
417
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>
421 </div>
422 <div class="tags">
423
424
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>.
426
427
428 </div>
429 </div>
430 <div class="padding"></div>
431
432 <div class="entry">
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>
444
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
455 available.</p>
456
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>
465
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>
473
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>
477 </div>
478 <div class="tags">
479
480
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>.
482
483
484 </div>
485 </div>
486 <div class="padding"></div>
487
488 <div class="entry">
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>
498
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>
514
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
517 days.</p>
518
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>
522 </div>
523 <div class="tags">
524
525
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>.
527
528
529 </div>
530 </div>
531 <div class="padding"></div>
532
533 <div class="entry">
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>
540
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>
550
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
553 Windows tool named
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>
558
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
562 much time on it.</p>
563
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>
575
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>
588
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>
597
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>
601
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
613 so far.</p>
614 </div>
615 <div class="tags">
616
617
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>.
619
620
621 </div>
622 </div>
623 <div class="padding"></div>
624
625 <div class="entry">
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>
629
630 <p>(The picture is of the previous edition.)</p>
631
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>
648
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>
657
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>
660
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>
664 </div>
665 <div class="tags">
666
667
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>.
669
670
671 </div>
672 </div>
673 <div class="padding"></div>
674
675 <div class="entry">
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
689 true.</p>
690
691 <p>The LinuxCNC
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.
703
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>
711
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>
719 took a version of
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
734 different path.</p>
735
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>
746
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
780 PID values.</p>
781
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>
785
786 <blockquote><pre>
787 loadrt pid names=pid.x,pid.y,pid.z
788 </pre></blockquote>
789
790 <p>Armed with the new and improved at_pid component, the new line will
791 look like this:</p>
792
793 <blockquote><pre>
794 loadrt at_pid names=pid.x,pid.y,pid.z
795 </pre></blockquote>
796
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>
800
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>
820
821 <blockquote><pre>
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
827 </pre></blockquote>
828
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
837 out the
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>
840
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>
846
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>
850 </div>
851 <div class="tags">
852
853
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>.
855
856
857 </div>
858 </div>
859 <div class="padding"></div>
860
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>
862 <div id="sidebar">
863
864
865
866 <h2>Archive</h2>
867 <ul>
868
869 <li>2023
870 <ul>
871
872 <li><a href="https://people.skolelinux.org/pere/blog/archive/2023/01/">January (3)</a></li>
873
874 <li><a href="https://people.skolelinux.org/pere/blog/archive/2023/02/">February (1)</a></li>
875
876 <li><a href="https://people.skolelinux.org/pere/blog/archive/2023/04/">April (2)</a></li>
877
878 </ul></li>
879
880 <li>2022
881 <ul>
882
883 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/02/">February (1)</a></li>
884
885 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/03/">March (3)</a></li>
886
887 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/04/">April (2)</a></li>
888
889 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/06/">June (2)</a></li>
890
891 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/07/">July (1)</a></li>
892
893 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/09/">September (1)</a></li>
894
895 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/10/">October (1)</a></li>
896
897 <li><a href="https://people.skolelinux.org/pere/blog/archive/2022/12/">December (1)</a></li>
898
899 </ul></li>
900
901 <li>2021
902 <ul>
903
904 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/01/">January (2)</a></li>
905
906 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/02/">February (1)</a></li>
907
908 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/05/">May (1)</a></li>
909
910 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/06/">June (1)</a></li>
911
912 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/07/">July (3)</a></li>
913
914 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/08/">August (1)</a></li>
915
916 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/09/">September (1)</a></li>
917
918 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/10/">October (1)</a></li>
919
920 <li><a href="https://people.skolelinux.org/pere/blog/archive/2021/12/">December (1)</a></li>
921
922 </ul></li>
923
924 <li>2020
925 <ul>
926
927 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/02/">February (2)</a></li>
928
929 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/03/">March (2)</a></li>
930
931 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/04/">April (2)</a></li>
932
933 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/05/">May (3)</a></li>
934
935 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/06/">June (2)</a></li>
936
937 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/07/">July (1)</a></li>
938
939 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/09/">September (1)</a></li>
940
941 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/10/">October (1)</a></li>
942
943 <li><a href="https://people.skolelinux.org/pere/blog/archive/2020/11/">November (1)</a></li>
944
945 </ul></li>
946
947 <li>2019
948 <ul>
949
950 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/01/">January (4)</a></li>
951
952 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/02/">February (3)</a></li>
953
954 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/03/">March (3)</a></li>
955
956 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/05/">May (2)</a></li>
957
958 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/06/">June (5)</a></li>
959
960 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/07/">July (2)</a></li>
961
962 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/08/">August (1)</a></li>
963
964 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/09/">September (1)</a></li>
965
966 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/11/">November (1)</a></li>
967
968 <li><a href="https://people.skolelinux.org/pere/blog/archive/2019/12/">December (4)</a></li>
969
970 </ul></li>
971
972 <li>2018
973 <ul>
974
975 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/01/">January (1)</a></li>
976
977 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/02/">February (5)</a></li>
978
979 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/03/">March (5)</a></li>
980
981 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/04/">April (3)</a></li>
982
983 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/06/">June (2)</a></li>
984
985 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/07/">July (5)</a></li>
986
987 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/08/">August (3)</a></li>
988
989 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/09/">September (3)</a></li>
990
991 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/10/">October (5)</a></li>
992
993 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/11/">November (2)</a></li>
994
995 <li><a href="https://people.skolelinux.org/pere/blog/archive/2018/12/">December (4)</a></li>
996
997 </ul></li>
998
999 <li>2017
1000 <ul>
1001
1002 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/01/">January (4)</a></li>
1003
1004 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/02/">February (3)</a></li>
1005
1006 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/03/">March (5)</a></li>
1007
1008 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/04/">April (2)</a></li>
1009
1010 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/06/">June (5)</a></li>
1011
1012 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/07/">July (1)</a></li>
1013
1014 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/08/">August (1)</a></li>
1015
1016 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/09/">September (3)</a></li>
1017
1018 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/10/">October (5)</a></li>
1019
1020 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/11/">November (3)</a></li>
1021
1022 <li><a href="https://people.skolelinux.org/pere/blog/archive/2017/12/">December (4)</a></li>
1023
1024 </ul></li>
1025
1026 <li>2016
1027 <ul>
1028
1029 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/01/">January (3)</a></li>
1030
1031 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/02/">February (2)</a></li>
1032
1033 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/03/">March (3)</a></li>
1034
1035 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/04/">April (8)</a></li>
1036
1037 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/05/">May (8)</a></li>
1038
1039 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/06/">June (2)</a></li>
1040
1041 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/07/">July (2)</a></li>
1042
1043 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/08/">August (5)</a></li>
1044
1045 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/09/">September (2)</a></li>
1046
1047 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/10/">October (3)</a></li>
1048
1049 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/11/">November (8)</a></li>
1050
1051 <li><a href="https://people.skolelinux.org/pere/blog/archive/2016/12/">December (5)</a></li>
1052
1053 </ul></li>
1054
1055 <li>2015
1056 <ul>
1057
1058 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/01/">January (7)</a></li>
1059
1060 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/02/">February (6)</a></li>
1061
1062 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/03/">March (1)</a></li>
1063
1064 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/04/">April (4)</a></li>
1065
1066 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/05/">May (3)</a></li>
1067
1068 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/06/">June (4)</a></li>
1069
1070 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/07/">July (6)</a></li>
1071
1072 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/08/">August (2)</a></li>
1073
1074 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/09/">September (2)</a></li>
1075
1076 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/10/">October (9)</a></li>
1077
1078 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/11/">November (6)</a></li>
1079
1080 <li><a href="https://people.skolelinux.org/pere/blog/archive/2015/12/">December (3)</a></li>
1081
1082 </ul></li>
1083
1084 <li>2014
1085 <ul>
1086
1087 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/01/">January (2)</a></li>
1088
1089 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/02/">February (3)</a></li>
1090
1091 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/03/">March (8)</a></li>
1092
1093 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/04/">April (7)</a></li>
1094
1095 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/05/">May (1)</a></li>
1096
1097 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/06/">June (2)</a></li>
1098
1099 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/07/">July (2)</a></li>
1100
1101 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/08/">August (2)</a></li>
1102
1103 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/09/">September (5)</a></li>
1104
1105 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/10/">October (6)</a></li>
1106
1107 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/11/">November (3)</a></li>
1108
1109 <li><a href="https://people.skolelinux.org/pere/blog/archive/2014/12/">December (5)</a></li>
1110
1111 </ul></li>
1112
1113 <li>2013
1114 <ul>
1115
1116 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/01/">January (11)</a></li>
1117
1118 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/02/">February (9)</a></li>
1119
1120 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/03/">March (9)</a></li>
1121
1122 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/04/">April (6)</a></li>
1123
1124 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/05/">May (9)</a></li>
1125
1126 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/06/">June (10)</a></li>
1127
1128 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/07/">July (7)</a></li>
1129
1130 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/08/">August (3)</a></li>
1131
1132 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/09/">September (5)</a></li>
1133
1134 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/10/">October (7)</a></li>
1135
1136 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/11/">November (9)</a></li>
1137
1138 <li><a href="https://people.skolelinux.org/pere/blog/archive/2013/12/">December (3)</a></li>
1139
1140 </ul></li>
1141
1142 <li>2012
1143 <ul>
1144
1145 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/01/">January (7)</a></li>
1146
1147 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/02/">February (10)</a></li>
1148
1149 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/03/">March (17)</a></li>
1150
1151 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/04/">April (12)</a></li>
1152
1153 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/05/">May (12)</a></li>
1154
1155 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/06/">June (20)</a></li>
1156
1157 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/07/">July (17)</a></li>
1158
1159 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/08/">August (6)</a></li>
1160
1161 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/09/">September (9)</a></li>
1162
1163 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/10/">October (17)</a></li>
1164
1165 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/11/">November (10)</a></li>
1166
1167 <li><a href="https://people.skolelinux.org/pere/blog/archive/2012/12/">December (7)</a></li>
1168
1169 </ul></li>
1170
1171 <li>2011
1172 <ul>
1173
1174 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/01/">January (16)</a></li>
1175
1176 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/02/">February (6)</a></li>
1177
1178 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/03/">March (6)</a></li>
1179
1180 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/04/">April (7)</a></li>
1181
1182 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/05/">May (3)</a></li>
1183
1184 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/06/">June (2)</a></li>
1185
1186 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/07/">July (7)</a></li>
1187
1188 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/08/">August (6)</a></li>
1189
1190 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/09/">September (4)</a></li>
1191
1192 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/10/">October (2)</a></li>
1193
1194 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/11/">November (3)</a></li>
1195
1196 <li><a href="https://people.skolelinux.org/pere/blog/archive/2011/12/">December (1)</a></li>
1197
1198 </ul></li>
1199
1200 <li>2010
1201 <ul>
1202
1203 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/01/">January (2)</a></li>
1204
1205 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/02/">February (1)</a></li>
1206
1207 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/03/">March (3)</a></li>
1208
1209 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/04/">April (3)</a></li>
1210
1211 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/05/">May (9)</a></li>
1212
1213 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/06/">June (14)</a></li>
1214
1215 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/07/">July (12)</a></li>
1216
1217 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/08/">August (13)</a></li>
1218
1219 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/09/">September (7)</a></li>
1220
1221 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/10/">October (9)</a></li>
1222
1223 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/11/">November (13)</a></li>
1224
1225 <li><a href="https://people.skolelinux.org/pere/blog/archive/2010/12/">December (12)</a></li>
1226
1227 </ul></li>
1228
1229 <li>2009
1230 <ul>
1231
1232 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/01/">January (8)</a></li>
1233
1234 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/02/">February (8)</a></li>
1235
1236 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/03/">March (12)</a></li>
1237
1238 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/04/">April (10)</a></li>
1239
1240 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/05/">May (9)</a></li>
1241
1242 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/06/">June (3)</a></li>
1243
1244 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/07/">July (4)</a></li>
1245
1246 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/08/">August (3)</a></li>
1247
1248 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/09/">September (1)</a></li>
1249
1250 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/10/">October (2)</a></li>
1251
1252 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/11/">November (3)</a></li>
1253
1254 <li><a href="https://people.skolelinux.org/pere/blog/archive/2009/12/">December (3)</a></li>
1255
1256 </ul></li>
1257
1258 <li>2008
1259 <ul>
1260
1261 <li><a href="https://people.skolelinux.org/pere/blog/archive/2008/11/">November (5)</a></li>
1262
1263 <li><a href="https://people.skolelinux.org/pere/blog/archive/2008/12/">December (7)</a></li>
1264
1265 </ul></li>
1266
1267 </ul>
1268
1269
1270
1271 <h2>Tags</h2>
1272 <ul>
1273
1274 <li><a href="https://people.skolelinux.org/pere/blog/tags/3d-printer">3d-printer (19)</a></li>
1275
1276 <li><a href="https://people.skolelinux.org/pere/blog/tags/amiga">amiga (1)</a></li>
1277
1278 <li><a href="https://people.skolelinux.org/pere/blog/tags/aros">aros (1)</a></li>
1279
1280 <li><a href="https://people.skolelinux.org/pere/blog/tags/bankid">bankid (4)</a></li>
1281
1282 <li><a href="https://people.skolelinux.org/pere/blog/tags/betalkontant">betalkontant (9)</a></li>
1283
1284 <li><a href="https://people.skolelinux.org/pere/blog/tags/bitcoin">bitcoin (12)</a></li>
1285
1286 <li><a href="https://people.skolelinux.org/pere/blog/tags/bootsystem">bootsystem (17)</a></li>
1287
1288 <li><a href="https://people.skolelinux.org/pere/blog/tags/bsa">bsa (2)</a></li>
1289
1290 <li><a href="https://people.skolelinux.org/pere/blog/tags/chrpath">chrpath (2)</a></li>
1291
1292 <li><a href="https://people.skolelinux.org/pere/blog/tags/debian">debian (190)</a></li>
1293
1294 <li><a href="https://people.skolelinux.org/pere/blog/tags/debian edu">debian edu (159)</a></li>
1295
1296 <li><a href="https://people.skolelinux.org/pere/blog/tags/debian-handbook">debian-handbook (9)</a></li>
1297
1298 <li><a href="https://people.skolelinux.org/pere/blog/tags/digistan">digistan (11)</a></li>
1299
1300 <li><a href="https://people.skolelinux.org/pere/blog/tags/dld">dld (18)</a></li>
1301
1302 <li><a href="https://people.skolelinux.org/pere/blog/tags/docbook">docbook (30)</a></li>
1303
1304 <li><a href="https://people.skolelinux.org/pere/blog/tags/drivstoffpriser">drivstoffpriser (4)</a></li>
1305
1306 <li><a href="https://people.skolelinux.org/pere/blog/tags/english">english (446)</a></li>
1307
1308 <li><a href="https://people.skolelinux.org/pere/blog/tags/fiksgatami">fiksgatami (23)</a></li>
1309
1310 <li><a href="https://people.skolelinux.org/pere/blog/tags/fildeling">fildeling (14)</a></li>
1311
1312 <li><a href="https://people.skolelinux.org/pere/blog/tags/freeculture">freeculture (34)</a></li>
1313
1314 <li><a href="https://people.skolelinux.org/pere/blog/tags/freedombox">freedombox (9)</a></li>
1315
1316 <li><a href="https://people.skolelinux.org/pere/blog/tags/frikanalen">frikanalen (20)</a></li>
1317
1318 <li><a href="https://people.skolelinux.org/pere/blog/tags/h264">h264 (20)</a></li>
1319
1320 <li><a href="https://people.skolelinux.org/pere/blog/tags/intervju">intervju (43)</a></li>
1321
1322 <li><a href="https://people.skolelinux.org/pere/blog/tags/isenkram">isenkram (16)</a></li>
1323
1324 <li><a href="https://people.skolelinux.org/pere/blog/tags/kart">kart (23)</a></li>
1325
1326 <li><a href="https://people.skolelinux.org/pere/blog/tags/kodi">kodi (4)</a></li>
1327
1328 <li><a href="https://people.skolelinux.org/pere/blog/tags/ldap">ldap (9)</a></li>
1329
1330 <li><a href="https://people.skolelinux.org/pere/blog/tags/lego">lego (5)</a></li>
1331
1332 <li><a href="https://people.skolelinux.org/pere/blog/tags/lenker">lenker (8)</a></li>
1333
1334 <li><a href="https://people.skolelinux.org/pere/blog/tags/linuxcnc">linuxcnc (4)</a></li>
1335
1336 <li><a href="https://people.skolelinux.org/pere/blog/tags/lsdvd">lsdvd (2)</a></li>
1337
1338 <li><a href="https://people.skolelinux.org/pere/blog/tags/ltsp">ltsp (1)</a></li>
1339
1340 <li><a href="https://people.skolelinux.org/pere/blog/tags/madewithcc">madewithcc (3)</a></li>
1341
1342 <li><a href="https://people.skolelinux.org/pere/blog/tags/mesh network">mesh network (8)</a></li>
1343
1344 <li><a href="https://people.skolelinux.org/pere/blog/tags/multimedia">multimedia (45)</a></li>
1345
1346 <li><a href="https://people.skolelinux.org/pere/blog/tags/nice free software">nice free software (14)</a></li>
1347
1348 <li><a href="https://people.skolelinux.org/pere/blog/tags/noark5">noark5 (23)</a></li>
1349
1350 <li><a href="https://people.skolelinux.org/pere/blog/tags/norsk">norsk (320)</a></li>
1351
1352 <li><a href="https://people.skolelinux.org/pere/blog/tags/nuug">nuug (198)</a></li>
1353
1354 <li><a href="https://people.skolelinux.org/pere/blog/tags/offentlig innsyn">offentlig innsyn (40)</a></li>
1355
1356 <li><a href="https://people.skolelinux.org/pere/blog/tags/open311">open311 (2)</a></li>
1357
1358 <li><a href="https://people.skolelinux.org/pere/blog/tags/opphavsrett">opphavsrett (75)</a></li>
1359
1360 <li><a href="https://people.skolelinux.org/pere/blog/tags/personvern">personvern (114)</a></li>
1361
1362 <li><a href="https://people.skolelinux.org/pere/blog/tags/raid">raid (2)</a></li>
1363
1364 <li><a href="https://people.skolelinux.org/pere/blog/tags/reactos">reactos (1)</a></li>
1365
1366 <li><a href="https://people.skolelinux.org/pere/blog/tags/reprap">reprap (11)</a></li>
1367
1368 <li><a href="https://people.skolelinux.org/pere/blog/tags/rfid">rfid (3)</a></li>
1369
1370 <li><a href="https://people.skolelinux.org/pere/blog/tags/robot">robot (17)</a></li>
1371
1372 <li><a href="https://people.skolelinux.org/pere/blog/tags/rss">rss (1)</a></li>
1373
1374 <li><a href="https://people.skolelinux.org/pere/blog/tags/ruter">ruter (7)</a></li>
1375
1376 <li><a href="https://people.skolelinux.org/pere/blog/tags/scraperwiki">scraperwiki (2)</a></li>
1377
1378 <li><a href="https://people.skolelinux.org/pere/blog/tags/sikkerhet">sikkerhet (59)</a></li>
1379
1380 <li><a href="https://people.skolelinux.org/pere/blog/tags/sitesummary">sitesummary (4)</a></li>
1381
1382 <li><a href="https://people.skolelinux.org/pere/blog/tags/skepsis">skepsis (5)</a></li>
1383
1384 <li><a href="https://people.skolelinux.org/pere/blog/tags/standard">standard (74)</a></li>
1385
1386 <li><a href="https://people.skolelinux.org/pere/blog/tags/stavekontroll">stavekontroll (7)</a></li>
1387
1388 <li><a href="https://people.skolelinux.org/pere/blog/tags/stortinget">stortinget (14)</a></li>
1389
1390 <li><a href="https://people.skolelinux.org/pere/blog/tags/surveillance">surveillance (64)</a></li>
1391
1392 <li><a href="https://people.skolelinux.org/pere/blog/tags/sysadmin">sysadmin (5)</a></li>
1393
1394 <li><a href="https://people.skolelinux.org/pere/blog/tags/usenix">usenix (2)</a></li>
1395
1396 <li><a href="https://people.skolelinux.org/pere/blog/tags/valg">valg (9)</a></li>
1397
1398 <li><a href="https://people.skolelinux.org/pere/blog/tags/verkidetfri">verkidetfri (20)</a></li>
1399
1400 <li><a href="https://people.skolelinux.org/pere/blog/tags/video">video (78)</a></li>
1401
1402 <li><a href="https://people.skolelinux.org/pere/blog/tags/vitenskap">vitenskap (4)</a></li>
1403
1404 <li><a href="https://people.skolelinux.org/pere/blog/tags/web">web (42)</a></li>
1405
1406 </ul>
1407
1408
1409 </div>
1410 <p style="text-align: right">
1411 Created by <a href="http://steve.org.uk/Software/chronicle">Chronicle v4.6</a>
1412 </p>
1413
1414 </body>
1415 </html>