Help
RSS
API
Feed
Maltego
Contact
Domain > www.adrianwalker.org
×
More information on this domain is in
AlienVault OTX
Is this malicious?
Yes
No
DNS Resolutions
Date
IP Address
2014-06-26
74.125.198.121
(
ClassC
)
2024-07-13
142.251.211.243
(
ClassC
)
Port 80
HTTP/1.1 200 OKContent-Type: text/html; charsetUTF-8Expires: Sat, 13 Jul 2024 10:38:04 GMTDate: Sat, 13 Jul 2024 10:38:04 GMTCache-Control: private, max-age0Last-Modified: Tue, 02 Jul 2024 21:44:58 GMTX-Content-Type-Options: nosniffX-XSS-Protection: 1; modeblockServer: GSEAccept-Ranges: noneVary: Accept-EncodingTransfer-Encoding: chunked !DOCTYPE html>html dirltr xmlnshttp://www.w3.org/1999/xhtml xmlns:bhttp://www.google.com/2005/gml/b xmlns:datahttp://www.google.com/2005/gml/data xmlns:exprhttp://www.google.com/2005/gml/expr>head>link hrefhttps://www.blogger.com/static/v1/widgets/55013136-widget_css_bundle.css relstylesheet typetext/css/>link hrefhttps://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css relstylesheet typetext/css/>link hrefhttps://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeDefault.min.css relstylesheet typetext/css/>script srchttps://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js typetext/javascript>/script>script srchttps://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushJScript.min.js typetext/javascript>/script>script srchttps://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushSql.min.js typetext/javascript>/script>script srchttps://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushXml.min.js typetext/javascript>/script>script srchttps://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushJava.min.js typetext/javascript>/script>script srchttps://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPython.min.js typetext/javascript>/script>script srchttps://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushCpp.min.js typetext/javascript>/script>script srchttps://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushBash.min.js typetext/javascript>/script>script srchttps://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPlain.min.js typetext/javascript>/script>style typetext/css>.syntaxhighlighter table td.gutter .line { text-align: right !important; padding: 0 5px !important;}/style>script typetext/javascript>SyntaxHighlighter.all();/script>meta contenttext/html; charsetUTF-8 http-equivContent-Type/>meta contentblogger namegenerator/>link hrefhttp://www.adrianwalker.org/favicon.ico relicon typeimage/x-icon/>link hrefhttp://www.adrianwalker.org/ relcanonical/>link relalternate typeapplication/atom+xml titleadrianwalker.org - Atom hrefhttp://www.adrianwalker.org/feeds/posts/default />link relalternate typeapplication/rss+xml titleadrianwalker.org - RSS hrefhttp://www.adrianwalker.org/feeds/posts/default?altrss />link relservice.post typeapplication/atom+xml titleadrianwalker.org - Atom hrefhttps://www.blogger.com/feeds/3451413587413375915/posts/default />!--Cant find substitution for tag blog.ieCssRetrofitLinks-->meta contenthttp://www.adrianwalker.org/ propertyog:url/>meta contentadrianwalker.org propertyog:title/>meta contentProgramming & That propertyog:description/>title>adrianwalker.org/title>style idpage-skin-1 typetext/css>!--/*-----------------------------------------------Blogger Template StyleName: Minima StretchDate: 26 Feb 2004----------------------------------------------- *//* Variable definitionsVariable namebgcolor descriptionPage Background Colortypecolor default#fff>Variable nametextcolor descriptionText Colortypecolor default#333>Variable namelinkcolor descriptionLink Colortypecolor default#58a>Variable namepagetitlecolor descriptionBlog Title Colortypecolor default#666>Variable namedescriptioncolor descriptionBlog Description Colortypecolor default#999>Variable nametitlecolor descriptionPost Title Colortypecolor default#c60>Variable namebordercolor descriptionBorder Colortypecolor default#ccc>Variable namesidebarcolor descriptionSidebar Title Colortypecolor default#999>Variable namesidebartextcolor descriptionSidebar Text Colortypecolor default#666>Variable namevisitedlinkcolor descriptionVisited Link Colortypecolor default#999>Variable namebodyfont descriptionText Fonttypefont defaultnormal normal 100% Georgia, Serif>Variable nameheaderfont descriptionSidebar Title Fonttypefontdefaultnormal normal 78% Trebuchet MS,Trebuchet,Arial,Verdana,Sans-serif>Variable namepagetitlefont descriptionBlog Title Fonttypefontdefaultnormal normal 200% Georgia, Serif>Variable namedescriptionfont descriptionBlog Description Fonttypefontdefaultnormal normal 78% Trebuchet MS, Trebuchet, Arial, Verdana, Sans-serif>Variable namepostfooterfont descriptionPost Footer Fonttypefontdefaultnormal normal 78% Trebuchet MS, Trebuchet, Arial, Verdana, Sans-serif>Variable namestartSide descriptionStart side in blog languagetypeautomatic defaultleft>Variable nameendSide descriptionEnd side in blog languagetypeautomatic defaultright>*//* Use this with templates/template-twocol.html */body {background:#ffffff;margin:0;color:#333333;font:x-small Georgia Serif;font-size/* */:/**/small;font-size: /**/small;text-align: center;}a:link {color:#5588aa;text-decoration:none;}a:visited {color:#999999;text-decoration:none;}a:hover {color:#cc6600;text-decoration:underline;}a img {border-width:0;}/* Header-----------------------------------------------*/#header-wrapper {margin:0 2% 10px;border:1px solid #cccccc;}#header {margin: 5px;border: 1px solid #cccccc;text-align: center;color:#666666;}#header-inner {background-position: center;margin-left: auto;margin-right: auto;}#header h1 {margin:5px 5px 0;padding:15px 20px .25em;line-height:1.2em;text-transform:uppercase;letter-spacing:.2em;font: normal normal 200% Verdana, Geneva, sans-serif;}#header a {color:#666666;text-decoration:none;}#header a:hover {color:#666666;}#header .description {margin:0 5px 5px;padding:0 20px 15px;text-transform:uppercase;letter-spacing:.2em;line-height: 1.4em;font: normal normal 78% Trebuchet MS, Trebuchet, Arial, Verdana, Sans-serif;color: #999999;}#header img {margin-left: auto;margin-right: auto;}/* Outer-Wrapper----------------------------------------------- */#outer-wrapper {margin:0;padding:10px;text-align:left;font: normal normal 100% Verdana, Geneva, sans-serif;}#main-wrapper {margin-left: 2%;width: 67%;float: left;display: inline; /* fix for doubling margin in IE */word-wrap: break-word; /* fix for long text breaking sidebar float in IE */overflow: hidden; /* fix for long non-text content breaking IE sidebar float */}#sidebar-wrapper {margin-right: 2%;width: 25%;float: right;display: inline; /* fix for doubling margin in IE */word-wrap: break-word; /* fix for long text breaking sidebar float in IE */overflow: hidden; /* fix for long non-text content breaking IE sidebar float */}/* Headings----------------------------------------------- */h2 {margin:1.5em 0 .75em;font:normal normal 78% Trebuchet MS,Trebuchet,Arial,Verdana,Sans-serif;line-height: 1.4em;text-transform:uppercase;letter-spacing:.2em;color:#999999;}/* Posts-----------------------------------------------*/h2.date-header {margin:1.5em 0 .5em;}.post {margin:.5em 0 1.5em;border-bottom:1px dotted #cccccc;padding-bottom:1.5em;}.post h3 {margin:.25em 0 0;padding:0 0 4px;font-size:140%;font-weight:normal;line-height:1.4em;color:#cc6600;}.post h3 a, .post h3 a:visited, .post h3 strong {display:block;text-decoration:none;color:#cc6600;font-weight:normal;}.post h3 strong, .post h3 a:hover {color:#333333;}.post-body {margin:0 0 .75em;line-height:1.6em;}.post-body blockquote {line-height:1.3em;}.post-footer {margin: .75em 0;color:#999999;text-transform:uppercase;letter-spacing:.1em;font: normal normal 78% Trebuchet MS, Trebuchet, Arial, Verdana, Sans-serif;line-height: 1.4em;}.comment-link {margin-left:.6em;}.post img, table.tr-caption-container {padding:4px;border:1px solid #cccccc;}.tr-caption-container img {border: none;padding: 0;}.post blockquote {margin:1em 20px;}.post blockquote p {margin:.75em 0;}/* Comments----------------------------------------------- */#comments h4 {margin:1em 0;font-weight: bold;line-height: 1.4em;text-transform:uppercase;letter-spacing:.2em;color: #999999;}#comments-block {margin:1em 0 1.5em;line-height:1.6em;}#comments-block .comment-author {margin:.5em 0;}#comments-block .comment-body {margin:.25em 0 0;}#comments-block .comment-footer {margin:-.25em 0 2em;line-height: 1.4em;text-transform:uppercase;letter-spacing:.1em;}#comments-block .comment-body p {margin:0 0 .75em;}.deleted-comment {font-style:italic;color:gray;}.feed-links {clear: both;line-height: 2.5em;}#blog-pager-newer-link {float: left;}#blog-pager-older-link {float: right;}#blog-pager {text-align: center;}/* Sidebar Content----------------------------------------------- */.sidebar {color: #666666;line-height: 1.5em;}.sidebar ul {list-style:none;margin:0 0 0;padding:0 0 0;}.sidebar li {margin:0;padding-top:0;padding-right:0;padding-bottom:.25em;padding-left:15px;text-indent:-15px;line-height:1.5em;}.sidebar .widget, .main .widget {border-bottom:1px dotted #cccccc;margin:0 0 1.5em;padding:0 0 1.5em;}.main .Blog {border-bottom-width: 0;}/* Profile----------------------------------------------- */.profile-img {float: left;margin-top: 0;margin-right: 5px;margin-bottom: 5px;margin-left: 0;padding: 4px;border: 1px solid #cccccc;}.profile-data {margin:0;text-transform:uppercase;letter-spacing:.1em;font: normal normal 78% Trebuchet MS, Trebuchet, Arial, Verdana, Sans-serif;color: #999999;font-weight: bold;line-height: 1.6em;}.profile-datablock {margin:.5em 0 .5em;}.profile-textblock {margin: 0.5em 0;line-height: 1.6em;}.profile-link {font: normal normal 78% Trebuchet MS, Trebuchet, Arial, Verdana, Sans-serif;text-transform: uppercase;letter-spacing: .1em;}/* Footer----------------------------------------------- */#footer {width:660px;clear:both;margin:0 auto;padding-top:15px;line-height: 1.6em;text-transform:uppercase;letter-spacing:.1em;text-align: center;}-->/style>link hrefhttps://www.blogger.com/dyn-css/authorization.css?targetBlogID3451413587413375915&zxc88da743-1386-49a2-8046-69e9f28f9987 medianone onloadif(media!'all')media'all' relstylesheet/>noscript>link hrefhttps://www.blogger.com/dyn-css/authorization.css?targetBlogID3451413587413375915&zxc88da743-1386-49a2-8046-69e9f28f9987 relstylesheet/>/noscript>meta namegoogle-adsense-platform-account contentca-host-pub-1556223355139109/>meta namegoogle-adsense-platform-domain contentblogspot.com/>/head>body>div classnavbar section idnavbar>div classwidget Navbar data-version1 idNavbar1>script typetext/javascript> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener(load, function(){ objectattribute val; }, false); } else { window.attachEvent(onload, function(){ objectattribute val; }); } } /script>div idnavbar-iframe-container>/div>script typetext/javascript srchttps://apis.google.com/js/platform.js>/script>script typetext/javascript> gapi.load(gapi.iframes:gapi.iframes.style.bubble, function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: https://www.blogger.com/navbar.g?targetBlogID\x3d3451413587413375915\x26blogName\x3dadrianwalker.org\x26publishMode\x3dPUBLISH_MODE_HOSTED\x26navbarType\x3dLIGHT\x26layoutType\x3dLAYOUTS\x26searchRoot\x3dhttp://www.adrianwalker.org/search\x26blogLocale\x3den_GB\x26v\x3d2\x26homepageUrl\x3dhttp://www.adrianwalker.org/\x26vt\x3d4891051926608193277, where: document.getElementById(navbar-iframe-container), id: navbar-iframe }); } }); /script>script typetext/javascript>(function() {var script document.createElement(script);script.type text/javascript;script.src //pagead2.googlesyndication.com/pagead/js/google_top_exp.js;var head document.getElementsByTagName(head)0;if (head) {head.appendChild(script);}})();/script>/div>/div>div idouter-wrapper>div idwrap2>!-- skip links for text browsers -->span idskiplinks styledisplay:none;>a href#main>skip to main /a> | a href#sidebar>skip to sidebar/a>/span>div idheader-wrapper>div classheader section idheader>div classwidget Header data-version1 idHeader1>div idheader-inner>div classtitlewrapper>h1 classtitle>adrianwalker.org/h1>/div>div classdescriptionwrapper>p classdescription>span>Programming & That/span>/p>/div>/div>/div>/div>/div>div idcontent-wrapper>div idcrosscol-wrapper styletext-align:center>div classcrosscol no-items section idcrosscol>/div>/div>div idmain-wrapper>div classmain section idmain>div classwidget Blog data-version1 idBlog1>div classblog-posts hfeed> div classdate-outer> h2 classdate-header>span>Sunday 5 November 2023/span>/h2> div classdate-posts> div classpost-outer>div classpost hentry uncustomized-post-template itempropblogPost itemscopeitemscope itemtypehttp://schema.org/BlogPosting>meta content3451413587413375915 itempropblogId/>meta content6251083887396656169 itemproppostId/>a name6251083887396656169>/a>h3 classpost-title entry-title itempropname>a hrefhttp://www.adrianwalker.org/2023/11/privategpt-installation-notes.html>PrivateGPT Installation Notes/a>/h3>div classpost-header>div classpost-header-line-1>/div>/div>div classpost-body entry-content idpost-body-6251083887396656169 itempropdescription articleBody>p>These notes work as of 07/11/2023 using Xubuntu 22.04 - your milage may vary./p>h3>PrivateGPT/h3>p>PrivateGPT is a production-ready AI project that allows you to ask questions about your documents using the power of Large Language Models (LLMs), even in scenarios without an Internet connection. 100% private, no data leaves your execution environment at any point./p>h3>Repo/h3>a hrefhttps://github.com/imartinez/privateGPT>https://github.com/imartinez/privateGPT/a>h3>Docs/h3>a hrefhttps://docs.privategpt.dev>https://docs.privategpt.dev/a>h3>Install/h3>a hrefhttps://docs.privategpt.dev/#section/Installation-and-Settings>https://docs.privategpt.dev/#section/Installation-and-Settings/a>h4>Install git/h4>pre classbrush:bash>sudo apt install git/pre>h4>Install python/h4>pre classbrush:bash>sudo apt install python3/pre>h4>Install pip/h4>pre classbrush:bash>sudo apt install python3-pip/pre>h4>Install pyenv/h4>pre classbrush:bash>cd ~curl https://pyenv.run | bash/pre>p>Add the commands to ~/.bashrc by running the following in your terminal:/p>pre classbrush:bash>echo export PYENV_ROOT$HOME/.pyenv >> ~/.bashrcecho command -v pyenv >/dev/null || export PATH$PYENV_ROOT/bin:$PATH >> ~/.bashrcecho eval $(pyenv init -) >> ~/.bashrc/pre>p>If you have ~/.profile, ~/.bash_profile or ~/.bash_login, add the commands there as well. If you have none of these, add them to ~/.profile:/p>pre classbrush:bash>echo export PYENV_ROOT$HOME/.pyenv >> ~/.profileecho command -v pyenv >/dev/null || export PATH$PYENV_ROOT/bin:$PATH >> ~/.profileecho eval $(pyenv init -) >> ~/.profile/pre>p>Restart your shell for the changes to take effect./p>h4>Install Python 3.11/h4>pre classbrush:bash>pyenv install 3.11pyenv local 3.11/pre>p>If you see these errors and warnings, install the required dependencies:/p>pre classbrush:bash>ModuleNotFoundError: No module named _bz2WARNING: The Python bz2 extension was not compiled. Missing the bzip2 lib?Traceback (most recent call last): File string>, line 1, in module> File /home/adrian/.pyenv/versions/3.11.6/lib/python3.11/curses/__init__.py, line 13, in module> from _curses import *ModuleNotFoundError: No module named _cursesWARNING: The Python curses extension was not compiled. Missing the ncurses lib?Traceback (most recent call last): File string>, line 1, in module> File /home/adrian/.pyenv/versions/3.11.6/lib/python3.11/ctypes/__init__.py, line 8, in module> from _ctypes import Union, Structure, ArrayModuleNotFoundError: No module named _ctypesWARNING: The Python ctypes extension was not compiled. Missing the libffi lib?Traceback (most recent call last): File string>, line 1, in module>ModuleNotFoundError: No module named readlineWARNING: The Python readline extension was not compiled. Missing the GNU readline lib?Traceback (most recent call last): File string>, line 1, in module> File /home/adrian/.pyenv/versions/3.11.6/lib/python3.11/ssl.py, line 100, in module> import _ssl # if we cant import it, let the error propagate ^^^^^^^^^^^ModuleNotFoundError: No module named _sslERROR: The Python ssl extension was not compiled. Missing the OpenSSL lib?ModuleNotFoundError: No module named _sqlite3WARNING: The Python sqlite3 extension was not compiled. Missing the SQLite3 lib?Traceback (most recent call last): File string>, line 1, in module> File /home/adrian/.pyenv/versions/3.11.6/lib/python3.11/tkinter/__init__.py, line 38, in module> import _tkinter # If this fails your Python may not be configured for Tk ^^^^^^^^^^^^^^^ModuleNotFoundError: No module named _tkinterWARNING: The Python tkinter extension was not compiled and GUI subsystem has been detected. Missing the Tk toolkit?Traceback (most recent call last): File string>, line 1, in module> File /home/adrian/.pyenv/versions/3.11.6/lib/python3.11/lzma.py, line 27, in module> from _lzma import *ModuleNotFoundError: No module named _lzmaWARNING: The Python lzma extension was not compiled. Missing the lzma lib?/pre>p>Install dependencies:/p>pre classbrush:bash>sudo apt updatesudo apt install libbz2-devsudo apt install libncurses-devsudo apt install libffi-devsudo apt install libreadline-devsudo apt install libssl-devsudo apt install libsqlite3-devsudo apt install tk-devsudo apt install liblzma-dev/pre>p>Try installing Python 3.11 again:/p>pre classbrush:bash>pyenv install 3.11pyenv local 3.11/pre>h4>Install pipx/h4>pre classbrush:bash>python3 -m pip install --user pipxpython3 -m pipx ensurepath/pre>p>Restart your shell for the changes to take effect./p>h4>Install poetry/h4>pre classbrush:bash>pipx install poetry/pre>h4>Clone the privateGPT repo/h4>pre classbrush:bash>cd ~git clone https://github.com/imartinez/privateGPTcd privateGPT/pre>h4>Install dependencies/h4>pre classbrush:bash>poetry install --with ui,local/pre>h4>Download Embedding and LLM models/h4>pre classbrush:bash>poetry run python scripts/setup/pre>h4>Run the local server/h4>pre classbrush:bash>PGPT_PROFILESlocal make run/pre>h4>Navigate to the UI/h4>a hrefhttp://localhost:8001/>http://localhost:8001//a>h4>Shutdown/h4>pre classbrush:bash>ctrl-c/pre>h3>GPU Acceleration/h3>h4>Verify the machine has a CUDA-Capable GPU/h4>pre classbrush:bash>lspci | grep -i nvidia/pre>h4>Install the NVIDIA CUDA Toolkit/h4>pre classbrush:bash>sudo apt updatesudo apt upgradesudo apt install nvidia-cuda-toolkit/pre>h4>Verify installation/h4>pre classbrush:bash>nvcc --versionnvidia-smi/pre>h4>Install llama.cpp with GPU support/h4>p>Find your version of llama_cpp_python:/p>pre classbrush:bash>poetry run pip list | grep llama_cpp_python/pre>p>Substitue the version in the next command:/p>pre classbrush:bash>cd ~/privateGPTCMAKE_ARGS-DLLAMA_CUBLASon poetry run pip install --force-reinstall --no-cache-dir llama-cpp-python0.2.13/pre>p>If you see an error like this, try specifitying the location of i>nvcc:/i>/p>pre classbrush:bash>Building wheels for collected packages: llama-cpp-python Building wheel for llama-cpp-python (pyproject.toml) ... error error: subprocess-exited-with-error × Building wheel for llama-cpp-python (pyproject.toml) did not run successfully. │ exit code: 1 ╰─> 35 lines of output *** scikit-build-core 0.6.0 using CMake 3.27.7 (wheel) *** Configuring CMake... loading initial cache file /tmp/tmp591ifmq4/build/CMakeInit.txt -- The C compiler identification is GNU 11.4.0 -- The CXX compiler identification is GNU 11.4.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Performing Test CMAKE_HAVE_LIBC_PTHREAD -- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success -- Found Threads: TRUE -- Found CUDAToolkit: /usr/local/cuda/include (found version 12.3.52) -- cuBLAS found -- The CUDA compiler identification is unknown CMake Error at /tmp/pip-build-env-h3vy91ne/normal/lib/python3.11/site-packages/cmake/data/share/cmake-3.27/Modules/CMakeDetermineCUDACompiler.cmake:603 (message): Failed to detect a default CUDA architecture. Compiler output: Call Stack (most recent call first): vendor/llama.cpp/CMakeLists.txt:258 (enable_language) -- Configuring incomplete, errors occurred! *** CMake configuration failed end of output note: This error originates from a subprocess, and is likely not a problem with pip. ERROR: Failed building wheel for llama-cpp-pythonFailed to build llama-cpp-pythonERROR: Could not build wheels for llama-cpp-python, which is required to install pyproject.toml-based projects/pre>p>Build with the location of i>nvcc:/i>/p>pre classbrush:bash>CUDACXX/usr/local/cuda-12/bin/nvcc CMAKE_ARGS-DLLAMA_CUBLASon poetry run pip install --force-reinstall --no-cache-dir llama-cpp-python0.2.13/pre>h4>Start the server/h4>pre classbrush:bash>cd ~/privateGPTpyenv local 3.11PGPT_PROFILESlocal make run/pre>p>If you see this error, configure the number of layers offloaded to VRAM:/p>pre classbrush:bash>CUDA error 2 at /tmp/pip-install-pqg0kmzj/llama-cpp-python_a94e4e69cdce4224adec44b01749f74a/vendor/llama.cpp/ggml-cuda.cu:7636: out of memorycurrent device: 0make: *** Makefile:36: run Error 1/pre>p>Configure the number of layers offloaded to VRAM:/p>pre classbrush:bash>cp ~/privateGPT/private_gpt/components/llm/llm_component.py ~/privateGPT/private_gpt/components/llm/llm_component.py.backupvim ~/privateGPT/private_gpt/components/llm/llm_component.py/pre>p>change:/p>pre classbrush:python>model_kwargs{n_gpu_layers: -1},/pre>p>to:/p>pre classbrush:python>model_kwargs{n_gpu_layers: 10},/pre>p>Try to start the server again:/p>pre classbrush:bash>cd ~/privateGPTpyenv local 3.11PGPT_PROFILESlocal make run/pre>p>If the server is using the GPU you will see something like this in the output:/p>pre classbrush:bash>...ggml_init_cublas: GGML_CUDA_FORCE_MMQ: noggml_init_cublas: CUDA_USE_TENSOR_CORES: yesggml_init_cublas: found 1 CUDA devices: Device 0: NVIDIA RTX A1000 Laptop GPU, compute capability 8.6...llm_load_tensors: ggml ctx size 0.11 MBllm_load_tensors: using CUDA for GPU accelerationllm_load_tensors: mem required 2902.35 MBllm_load_tensors: offloading 10 repeating layers to GPUllm_load_tensors: offloaded 10/35 layers to GPUllm_load_tensors: VRAM used: 1263.12 MB...............................................................................................llama_new_context_with_model: n_ctx 3900llama_new_context_with_model: freq_base 10000.0llama_new_context_with_model: freq_scale 1llama_new_context_with_model: kv self size 487.50 MBllama_build_graph: non-view tensors processed: 740/740llama_new_context_with_model: compute buffer total size 282.00 MBllama_new_context_with_model: VRAM scratch buffer: 275.37 MBllama_new_context_with_model: total VRAM used: 1538.50 MB (model: 1263.12 MB, context: 275.37 MB)AVX 1 | AVX2 1 | AVX512 0 | AVX512_VBMI 0 | AVX512_VNNI 0 | FMA 1 | NEON 0 | ARM_FMA 0 | F16C 1 | FP16_VA 0 | WASM_SIMD 0 | BLAS 1 | SSE3 1 | SSSE3 1 | VSX 0 | .../pre>h3>Ingest/h3>For example, to download and ingest an html copy of a hrefhttps://github.com/basho-labs/little_riak_book>A Little Riak Book/a>:pre classbrush:bash>cd ~/privateGPTmkdir ${PWD}/ingestwget -P ${PWD}/ingest https://raw.githubusercontent.com/basho-labs/little_riak_book/master/rendered/riaklil-en.htmlpoetry run python scripts/ingest_folder.py ${PWD}/ingest/pre>h3>Configure Temperature/h3>pre classbrush:bash>cp ~/privateGPT/private_gpt/components/llm/llm_component.py ~/privateGPT/private_gpt/components/llm/llm_component.py.backupvim ~/privateGPT/private_gpt/components/llm/llm_component.py/pre>p>change:/p>pre classbrush:python>temperature0.1/pre>p>to:/p>pre classbrush:python>temperature0.2/pre>p>Restart the server/p>pre classbrush:bash>crtl+ccd ~/privateGPTpyenv local 3.11PGPT_PROFILESlocal make run/pre>div styleclear: both;>/div>/div>div classpost-footer>div classpost-footer-line post-footer-line-1>span classpost-author vcard>Posted byspan classfn itempropauthor itemscopeitemscope itemtypehttp://schema.org/Person>span itempropname>Adrian Walker/span>/span>/span>span classpost-timestamp>atmeta contenthttp://www.adrianwalker.org/2023/11/privategpt-installation-notes.html itempropurl/>a classtimestamp-link hrefhttp://www.adrianwalker.org/2023/11/privategpt-installation-notes.html relbookmark titlepermanent link>abbr classpublished itempropdatePublished title2023-11-05T20:12:00Z>8:12 pm/abbr>/a>/span>span classpost-comment-link>/span>span classpost-icons>span classitem-control blog-admin pid-255443665>a hrefhttps://www.blogger.com/post-edit.g?blogID3451413587413375915&postID6251083887396656169&frompencil titleEdit Post>img alt classicon-action height18 srchttps://resources.blogblog.com/img/icon18_edit_allbkg.gif width18/>/a>/span>/span>div classpost-share-buttons goog-inline-block>/div>/div>div classpost-footer-line post-footer-line-2>span classpost-labels>/span>/div>div classpost-footer-line post-footer-line-3>span classpost-location>/span>/div>/div>/div>/div> /div>/div> div classdate-outer> h2 classdate-header>span>Sunday 10 September 2023/span>/h2> div classdate-posts> div classpost-outer>div classpost hentry uncustomized-post-template itempropblogPost itemscopeitemscope itemtypehttp://schema.org/BlogPosting>meta content3451413587413375915 itempropblogId/>meta content3611889656936525904 itemproppostId/>a name3611889656936525904>/a>h3 classpost-title entry-title itempropname>a hrefhttp://www.adrianwalker.org/2023/09/riak-like-secondary-index-queries-for-s3.html>Riak-like secondary index queries for S3/a>/h3>div classpost-header>div classpost-header-line-1>/div>/div>div classpost-body entry-content idpost-body-3611889656936525904 itempropdescription articleBody>p>This is an idea for how to provide a hrefhttps://en.wikipedia.org/wiki/Database_index#Secondary_index>secondary index queries/a>, similar to a hrefhttps://docs.riak.com/riak/kv/latest/developing/usage/secondary-indexes/index.html>Riak 2i/a>, on top of a hrefhttps://aws.amazon.com/s3/>Amazon S3/a>, using nothing but S3, a hrefhttps://boto3.amazonaws.com/v1/documentation/api/latest/index.html>boto3/a> and some Python./p>p>This code hasnt been anywhere near a production environment, never benchmarked, only processed trivial amounts of data and tested only against a hrefhttps://localstack.cloud/>localstack/a>. Its not even commented. As such, it should not be used by anybody for any reason - ever./p>p>If you do give it a try, let me know how it went./p>h4>s32i.sh/h4>pre classbrush:python>from concurrent.futures.thread import ThreadPoolExecutorimport refrom botocore.exceptions import ClientErrorclass S32iDatastore(): __EXECUTOR ThreadPoolExecutor(max_workersos. cpu_count() - 1) INDEXES_FOLDER indexes LIST_OBJECTS list_objects_v2 def __init__(self, s3_resource, bucket_name): self.s3_resource s3_resource self.bucket_name bucket_name def __run_in_thread(self, fn, *args): return self.__EXECUTOR.submit(fn, *args) def get(self, key): record self.s3_resource.Object(self.bucket_name, key).get() indexes recordMetadata data recordBody.read() return data, indexes def head(self, key): record self.s3_resource.meta.client.head_object(Bucketself.bucket_name, Keykey) return recordMetadata def exists(self, key): try: self.head(key) return True except ClientError: return False def put(self, key, data, indexes{}): self.__run_in_thread(self.create_secondary_indexes, key, indexes) return self.s3_resource.Object(self.bucket_name, key).put( Bodydata, Metadataindexes) def delete(self, key): self.__run_in_thread(self.remove_secondary_indexes, key, self.head(key)) return self.s3_resource.Object(self.bucket_name, key).delete() def create_secondary_indexes(self, key, indexes): for index, values in indexes.items(): for value in values.split(,): self.put(f{self.INDEXES_FOLDER}/{index}/{value}/{key}) def remove_secondary_indexes(self, key, indexes): for index, values in indexes.items(): for value in values.split(,): self.s3_resource.Object(self.bucket_name, f{self.INDEXES_FOLDER}/{index}/{value}/{key}).delete() def secondary_index_range_query(self, index, start, endNone, page_size1000, max_results10000, term_regexNone, return_termsFalse): if end is None: end start if term_regex: pattern re.compile(f^{self.INDEXES_FOLDER}/{index}/{term_regex}$) start_key f{self.INDEXES_FOLDER}/{index}/{start} end_key f{self.INDEXES_FOLDER}/{index}/{end} paginator self.s3_resource.meta.client.get_paginator(self.LIST_OBJECTS) pages paginator.paginate( Bucketself.bucket_name, StartAfterstart_key, PaginationConfig{ MaxItems: max_results, PageSize: page_size}) for page in pages: for result in pageContents: result_key resultKey if result_key0:len(end_key) > end_key: return if term_regex and not pattern.match(result_key): continue parts result_key.split(/) if return_terms: yield (parts-1, parts-2) else: yield parts-1/pre>h4>s32i_test.sh/h4>pre classbrush:python>import jsonimport unittestimport boto3from s32i import S32iDatastoreclass S32iDatastoreTest(unittest.TestCase): LOCALSTACK_ENDPOINT_URL http://localhost.localstack.cloud:4566 TEST_BUCKET s32idatastore-test-bucket @classmethod def setUpClass(cls): cls.s3_resource cls.create_s3_resource() cls.bucket cls.create_bucket(cls.TEST_BUCKET) cls.datastore S32iDatastore(cls.s3_resource, cls.TEST_BUCKET) cls.create_test_data() @classmethod def tearDownClass(cls): cls.delete_bucket() @classmethod def create_s3_resource(cls, endpoint_urlLOCALSTACK_ENDPOINT_URL): return boto3.resource( s3, endpoint_urlendpoint_url) @classmethod def create_bucket(cls, bucket_name): return cls.s3_resource.create_bucket(Bucketbucket_name) @classmethod def delete_bucket(cls): cls.bucket.objects.all().delete() @classmethod def create_test_data(cls): cls.datastore.put( KEY0001, json.dumps({name: Alice, dob: 19700101, gender: 2}), {idx-gender-dob: 2|19700101}) cls.datastore.put( KEY0002, json.dumps({name: Bob, dob: 19800101, gender: 1}), {idx-gender-dob: 1|19800101}) cls.datastore.put( KEY0003, json.dumps({name: Carol, dob: 19900101, gender: 2}), {idx-gender-dob: 2|19900101}) cls.datastore.put( KEY0004, json.dumps({name: Dan, dob: 20000101, gender: 1}), {idx-gender-dob: 1|20000101}) cls.datastore.put( KEY0005, json.dumps({name: Eve, dob: 20100101, gender: 2}), {idx-gender-dob: 2|20100101}) cls.datastore.put( KEY0006, json.dumps({name: Faythe, Grace, dob: 20200101, gender: 2}), {idx-gender-dob: 2|20200101, idx-name: Faythe,Grace}) cls.datastore.put(KEY0007, indexes{idx-same: same}) cls.datastore.put(KEY0008, indexes{idx-same: same}) cls.datastore.put(KEY0009, indexes{idx-same: same}) cls.datastore.put( KEY9999, json.dumps({name: DELETE ME, dob: 99999999, gender: 9}), {idx-gender-dob: 9|99999999}) def test_get_record(self): data, indexes self.datastore.get(KEY0001) self.assertDictEqual({name: Alice, dob: 19700101, gender: 2}, json.loads(data)) self.assertDictEqual({idx-gender-dob: 2|19700101}, indexes) def test_head_record(self): indexes self.datastore.head(KEY0002) self.assertDictEqual({idx-gender-dob: 1|19800101}, indexes) def test_2i_no_results(self): keys self.datastore.secondary_index_range_query(idx-gender-dob, 3|30100101) self.assertListEqual(, list(keys)) def test_2i_index_does_not_exist(self): keys self.datastore.secondary_index_range_query(idx-does-not-exist, 3|30100101) self.assertListEqual(, list(keys)) def test_2i_exact_value(self): keys self.datastore.secondary_index_range_query(idx-gender-dob, 2|20100101) self.assertListEqual(KEY0005, list(keys)) def test_2i_gender_2(self): keys self.datastore.secondary_index_range_query(idx-gender-dob, 2|) self.assertListEqual(KEY0001, KEY0003, KEY0005, KEY0006, sorted(list(keys))) def test_2i_gender_2_max_results_2(self): keys self.datastore.secondary_index_range_query(idx-gender-dob, 2|, max_results2) self.assertListEqual(KEY0001, KEY0003, sorted(list(keys))) def test_2i_gender_1_dob_19(self): keys self.datastore.secondary_index_range_query(idx-gender-dob, 1|19) self.assertListEqual(KEY0002, list(keys)) def test_2i_gender_2_dob_19(self): keys self.datastore.secondary_index_range_query(idx-gender-dob, 2|19) self.assertListEqual(KEY0001, KEY0003, sorted(list(keys))) def test_2i_gender_2_dob_1990_2000(self): keys self.datastore.secondary_index_range_query(idx-gender-dob, 2|1990, 2|2000) self.assertListEqual(KEY0003, list(keys)) def test_2i_term_regex(self): keys self.datastore.secondary_index_range_query(idx-gender-dob, 1|, 2|, term_regex1|2\|201|20.*) self.assertListEqual(KEY0005, KEY0006, list(keys)) def test_2i_return_terms(self): key_terms self.datastore.secondary_index_range_query( idx-gender-dob, 1|, 2|, return_termsTrue) self.assertListEqual( (KEY0001, 2|19700101), (KEY0002, 1|19800101), (KEY0003, 2|19900101), (KEY0004, 1|20000101), (KEY0005, 2|20100101), (KEY0006, 2|20200101), sorted(list(key_terms))) def test_2i_term_regex_return_terms(self): key_terms self.datastore.secondary_index_range_query( idx-gender-dob, 1|, 2|, term_regex1|2\|201|20.*, return_termsTrue) self.assertListEqual((KEY0005, 2|20100101), (KEY0006, 2|20200101), list(key_terms)) def test_exists(self): self.assertTrue(self.datastore.exists(KEY0001)) self.assertFalse(self.datastore.exists(1000YEK)) def test_multiple_index_values(self): indexes self.datastore.head(KEY0006) self.assertDictEqual({idx-gender-dob: 2|20200101, idx-name: Faythe,Grace}, indexes) keys self.datastore.secondary_index_range_query(idx-name, Faythe) self.assertListEqual(KEY0006, list(keys)) keys self.datastore.secondary_index_range_query(idx-name, Grace) self.assertListEqual(KEY0006, list(keys)) def test_multiple_keys_same_index(self): keys self.datastore.secondary_index_range_query(idx-same, same) self.assertListEqual(KEY0007, KEY0008, KEY0009, sorted(list(keys))) def test_delete(self): self.assertTrue(self.datastore.exists(KEY9999)) keys self.datastore.secondary_index_range_query(idx-gender-dob, 9|99999999) self.assertListEqual(KEY9999, list(keys)) self.datastore.delete(KEY9999) self.assertFalse(self.datastore.exists(KEY9999)) keys self.datastore.secondary_index_range_query(idx-gender-dob, 9|99999999) self.assertListEqual(, list(keys))/pre>div styleclear: both;>/div>/div>div classpost-footer>div classpost-footer-line post-footer-line-1>span classpost-author vcard>Posted byspan classfn itempropauthor itemscopeitemscope itemtypehttp://schema.org/Person>span itempropname>Adrian Walker/span>/span>/span>span classpost-timestamp>atmeta contenthttp://www.adrianwalker.org/2023/09/riak-like-secondary-index-queries-for-s3.html itempropurl/>a classtimestamp-link hrefhttp://www.adrianwalker.org/2023/09/riak-like-secondary-index-queries-for-s3.html relbookmark titlepermanent link>abbr classpublished itempropdatePublished title2023-09-10T21:35:00+01:00>9:35 pm/abbr>/a>/span>span classpost-comment-link>/span>span classpost-icons>span classitem-control blog-admin pid-255443665>a hrefhttps://www.blogger.com/post-edit.g?blogID3451413587413375915&postID3611889656936525904&frompencil titleEdit Post>img alt classicon-action height18 srchttps://resources.blogblog.com/img/icon18_edit_allbkg.gif width18/>/a>/span>/span>div classpost-share-buttons goog-inline-block>/div>/div>div classpost-footer-line post-footer-line-2>span classpost-labels>/span>/div>div classpost-footer-line post-footer-line-3>span classpost-location>/span>/div>/div>/div>/div> /div>/div> div classdate-outer> h2 classdate-header>span>Saturday 27 March 2021/span>/h2> div classdate-posts> div classpost-outer>div classpost hentry uncustomized-post-template itempropblogPost itemscopeitemscope itemtypehttp://schema.org/BlogPosting>meta contenthttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVhJzj_S9IiRF0Z0bw5i0OtWonjje1ADBMV6WVJHfH6KMtjdeSXmkXyDmzyQqBmGouHjOLll96pIiccIs5tOgMusNelbqOrfvLGYT8iv4C0XSlLYObwtR45XYA1jeeR-AJaDb_9j4KQ6I/s320/plato.jpg itempropimage_url/>meta content3451413587413375915 itempropblogId/>meta content8759476824716030120 itemproppostId/>a name8759476824716030120>/a>h3 classpost-title entry-title itempropname>a hrefhttp://www.adrianwalker.org/2021/03/national-statistics-postcode-lookup.html>National Statistics Postcode Lookup Radius Search With Redis/a>/h3>div classpost-header>div classpost-header-line-1>/div>/div>div classpost-body entry-content idpost-body-8759476824716030120 itempropdescription articleBody>p>Of all the questions posed by Plato, the profundity of one stands head and shoulders above the rest:/p>div classseparator styleclear: both;>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVhJzj_S9IiRF0Z0bw5i0OtWonjje1ADBMV6WVJHfH6KMtjdeSXmkXyDmzyQqBmGouHjOLll96pIiccIs5tOgMusNelbqOrfvLGYT8iv4C0XSlLYObwtR45XYA1jeeR-AJaDb_9j4KQ6I/s620/plato.jpg styledisplay: block; padding: 1em 0; text-align: center; >img alt border0 data-original-height620 data-original-width500 height320 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVhJzj_S9IiRF0Z0bw5i0OtWonjje1ADBMV6WVJHfH6KMtjdeSXmkXyDmzyQqBmGouHjOLll96pIiccIs5tOgMusNelbqOrfvLGYT8iv4C0XSlLYObwtR45XYA1jeeR-AJaDb_9j4KQ6I/s320/plato.jpg/>/a>/div>p>To answer Platos question were going need some geographic information about UK postcodes:p/>h4>National Statistics Postcode Lookup/h4>p>This data set is probably the right one for the job. Its from a reliable source, it contains longitude and lattitude for 2.6 million postcodes and best of all - its free./p>p>The data is downloadable from a hrefhttps://geoportal.statistics.gov.uk>geoportal.statistics.gov.uk/a>, first item under the Postcodes menu. The dataset appears to be released quarterly every February, May, August and November./p>div classseparator styleclear: both;>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizxNKHgt36Zqh0LTJXglgIO29-0oPfx1qs-fh_IdHjhB2pOMPgYmuDj4CeRdabPQzUFM6KVJ7hnvjI0ZCPLC_N-oiR6Oh6i55ZQEB1R3WZmeVLg_73Kff3BEFg1srcEvXMW51BEZJDtZc/s510/ons.png styledisplay: block; padding: 1em 0; text-align: center; >img alt border0 data-original-height221 data-original-width510 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizxNKHgt36Zqh0LTJXglgIO29-0oPfx1qs-fh_IdHjhB2pOMPgYmuDj4CeRdabPQzUFM6KVJ7hnvjI0ZCPLC_N-oiR6Oh6i55ZQEB1R3WZmeVLg_73Kff3BEFg1srcEvXMW51BEZJDtZc/s320/ons.png width320/>/a>/div>p>At the time of writing, the latest dowload link points to:/p>p>a hrefhttps://www.arcgis.com/sharing/rest/content/items/7606baba633d4bbca3f2510ab78acf61/data>www.arcgis.com/sharing/rest/content/items/7606baba633d4bbca3f2510ab78acf61/data/a>/p>p>Interestingly, the domain is a hrefhttps://www.arcgis.com>www.arcgis.com/a>, the website for a well known commercial Geographic Information System - ArcGIS, from a hrefhttps://www.esriuk.com/en-gb/home>Esri/a>./p>h4>Other data sets are available/h4>p>i>Code-Point Open/i>/p>p>a hrefhttps://www.ordnancesurvey.co.uk/business-government/products/code-point-open>Code-Point Open/a> from a hrefhttps://www.ordnancesurvey.co.uk>Ordnance Survey/a>, free but location information is coded as a hrefhttps://en.wikipedia.org/wiki/Grid_reference_system>Eastings and Northings/a>, not ideal for this project./p>p>i>PostZon/i>/p>p> Part of the a hrefhttps://www.poweredbypaf.com/>PAF/a> datasets from Royal Mail, mentioned in the a hrefhttps://www.poweredbypaf.com/wp-content/uploads/2017/07/Latest-Programmers_guide_Edition-7-Version-6.pdf>PAF Programmers Guide/a>, longitude and lattitude, but not much information beyond that. Non-free and was apparently leaked by Wikileaks in 2009:/p>p>a hrefhttps://www.theguardian.com/technology/2009/sep/23/post-office-database-copyright-leak>Was the leak of Royal Mails PostZon database a good or bad thing?/a>/p>p>i>UK Postcodes to Longitudes Latitudes Table/i>/p>p>Provided by a hrefhttps://www.postcodeaddressfile.co.uk/order/postcodes_longitude_latitude_table/postcodes_longitude_latitude_single_user_licence.htm>postcodeaddressfile.co.uk/a> - a Royal Mail reseller. Appears to be a combination of PAF and OS data, has longitude and lattitude data but costs £199 for an a hrefhttps://www.postcodeaddressfile.co.uk/licences/grid_references/postcode_longitude_latitude_licence_options.htm>Organisation Licence/a>./p>p>b>Geospatial Index/b>/p>p>a hrefhttps://redislabs.com/redis-best-practices/indexing-patterns/geospatial/>Redis provides geospatial indexing/a> and a a hrefhttps://redis.io/commands#geo>bunch of related commands/a>, awesome - as long as you can provide it with longitude and lattitude data:/p>p>Ideal for answering the question How many postcodes are within a given radius of a given postcode is the a hrefhttps://redis.io/commands/georadiusbymember>GEORADIUSBYMEMBER/a> command./p>h4>Data Load/h4>p>This bash script downloads the February 2021 release of National Statistics Postcode Lookup ZIP file, unzips the file we need, parses the data and formats into Redis commands which are piped to Redis./p>p>The script uses the a hrefhttp://manpages.ubuntu.com/manpages/groovy/man1/csvtool.1.html>csvtool/a> command line utility which will need to be installed if you dont already have it./p>h4>load-nspl.sh/h4>pre classbrush:bash>#!/bin/bash# Data URL from: https://geoportal.statistics.gov.uk/datasets/national-statistics-postcode-lookup-february-2021DATA_URLhttps://www.arcgis.com/sharing/rest/content/items/7606baba633d4bbca3f2510ab78acf61/dataZIP_FILE/tmp/nspl.zipCSV_FILE/tmp/nspl.csvCSV_REGEXNSPL.*UK\.csvREDIS_KEYnspl # NSPL - National Statistics Postcode LookupPOSTCODE_FIELD3 # PCDS - Unit postcode variable length versionLAT_FIELD34 # LAT - Decimal degrees latitudeLONG_FIELD35 # LONG - Decimal degrees longitudeSTART_TIME$(date -u +%s)# Download data file if it doesnt existif -f $ZIP_FILE then echo $ZIP_FILE exists, skipping downloadelse echo Downloading $ZIP_FILE wget $DATA_URL -O $ZIP_FILEfi# Unzip data if it doesnt existif -f $CSV_FILE then echo $ZIP_FILE exists, skipping unzipping else echo Unzipping data to $CSV_FILE unzip -p $ZIP_FILE $(unzip -Z1 $ZIP_FILE | grep -E $CSV_REGEX) > $CSV_FILEfi# Process data file, create Redis commands, pipe to redis-cliecho Processing data file $CSV_FILEcsvtool format GEOADD $REDIS_KEY %($LONG_FIELD) %($LAT_FIELD) \%($POSTCODE_FIELD)\\n $CSV_FILE \| redis-cli --pipe# DoneEND_TIME$(date -u +%s)ELAPSED_TIME$(($END_TIME-$START_TIME))MEMBERS$(echo zcard nspl | redis-cli | cut -f 1)echo $MEMBERS postcodes loadedecho Elapsed: $ELAPSED_TIME seconds/pre>p>Expect output from the script similar to this:/p>pre>Downloading /tmp/nspl.zip...196050K ...... 100% 47.2M54s...Unzipping data to /tmp/nspl.csvProcessing data file /tmp/nspl.csv...ERR invalid longitude,latitude pair 0.000000,99.999999...All data transferred. Waiting for the last reply...Last reply received from server.errors: 23258, replies: 26562522632994 postcodes loadedElapsed: 18 seconds/pre>/p>p>Dont worry about the errors:/p>pre>ERR invalid longitude,latitude pair 0.000000,99.999999/pre>p>There are about 23,000 entries in the data file with invalid longitude and lattitude values which Redis will reject. The NSPL User Guide (available in the downloaded ZIP file - NSPL User Guide Feb 2021.pdf) has this to say about them:/p>p>i>"Decimal degrees latitude - The postcode coordinates in degrees latitude to six decimal places; 99.999999 for postcodes in the Channel Islands and the Isle of Man, and for postcodes with no grid reference."/i>/p>p>and/p>p>i>"Decimal degrees longitude - The postcode coordinates in degrees longitude to six decimal places; 0.000000 for postcodes in the Channel Islands and the Isle of Man, and for postcodes with no grid reference."/i>/p>h4>Queries/h4>p>Once weve got a full dataset loaded we can run some queries with a hrefhttps://redis.io/topics/rediscli>redis-cli/a>:/p>pre classbrush:bash>127.0.0.1:6379> geopos nspl YO24 1AB1) 1) -1.0930296778678894 2) 53.95831391882791195127.0.0.1:6379> geopos nspl YO1 7HH1) 1) -1.0816839337348938 2) 53.96135558421912037127.0.0.1:6379> geodist nspl YO24 1AB YO1 7HH km0.8159127.0.0.1:6379> georadiusbymember nspl YO24 1AB 100 m WITHDIST1) 1) YO24 1AY 2) 29.05762) 1) YO1 6HT 2) 2.00453) 1) YO2 2AY 2) 2.00454) 1) YO24 1AB 2) 0.00005) 1) YO24 1AA 2) 69.7119127.0.0.1:6379> georadiusbymember nspl YO1 7HH 50 m WITHDIST1) 1) YO1 2HT 2) 32.65452) 1) YO1 7HT 2) 32.65453) 1) YO1 7HH 2) 0.00004) 1) YO1 2HZ 2) 40.34055) 1) YO1 2HL 2) 37.65166) 1) YO1 7HL 2) 38.9421/pre>h4>REST API/h4>p>Heres a super basic Flask based REST service to query the geographic index. Postcode, distance and units can be provided as search parameters in the request URL. Postcodes within the requested radius are returned as JSON, along with their distance from the provided postcode./p>h4>nspl-rest.py/h4>pre classbrush:python>from flask import Flask, jsonifyfrom redis import RedisREDIS_HOST localhostREDIS_PORT 6379REDIS_DB 0REDIS_KEY nsplapp Flask(__name__)r Redis(hostREDIS_HOST, portREDIS_PORT, dbREDIS_DB)@app.route(/radius/<postcode>/<distance>/<unit>, methodsGET)def radius(postcode, distance, unit): try: results r.georadiusbymember(REDIS_KEY, postcode, distance, unit, withdistTrue) except Exception as e: results {} return jsonify({ postcode: result0, distance:result1 } for result in results)app.run()/pre>h4>API Example Usage/h4>pre classbrush:javascript>$ curl localhost:5000/radius/YO24%201AB/100/m | json_pp { distance : 29.0576, postcode : YO24 1AY }, { distance : 2.0045, postcode : YO1 6HT }, { distance : 2.0045, postcode : YO2 2AY }, { distance : 0, postcode : YO24 1AB }, { distance : 69.7119, postcode : YO24 1AA }/pre>h4>Source Code/h4>p> ul> li>Code available in GitHub - a hrefhttps://github.com/adrianwalker/nspl-radis-search>nspl-radis-search/a>/li> /ul>/p>div styleclear: both;>/div>/div>div classpost-footer>div classpost-footer-line post-footer-line-1>span classpost-author vcard>Posted byspan classfn itempropauthor itemscopeitemscope itemtypehttp://schema.org/Person>span itempropname>Adrian Walker/span>/span>/span>span classpost-timestamp>atmeta contenthttp://www.adrianwalker.org/2021/03/national-statistics-postcode-lookup.html itempropurl/>a classtimestamp-link hrefhttp://www.adrianwalker.org/2021/03/national-statistics-postcode-lookup.html relbookmark titlepermanent link>abbr classpublished itempropdatePublished title2021-03-27T22:44:00Z>10:44 pm/abbr>/a>/span>span classpost-comment-link>/span>span classpost-icons>span classitem-control blog-admin pid-255443665>a hrefhttps://www.blogger.com/post-edit.g?blogID3451413587413375915&postID8759476824716030120&frompencil titleEdit Post>img alt classicon-action height18 srchttps://resources.blogblog.com/img/icon18_edit_allbkg.gif width18/>/a>/span>/span>div classpost-share-buttons goog-inline-block>/div>/div>div classpost-footer-line post-footer-line-2>span classpost-labels>/span>/div>div classpost-footer-line post-footer-line-3>span classpost-location>/span>/div>/div>/div>/div> /div>/div> div classdate-outer> h2 classdate-header>span>Saturday 3 October 2020/span>/h2> div classdate-posts> div classpost-outer>div classpost hentry uncustomized-post-template itempropblogPost itemscopeitemscope itemtypehttp://schema.org/BlogPosting>meta content3451413587413375915 itempropblogId/>meta content8221858158534382558 itemproppostId/>a name8221858158534382558>/a>h3 classpost-title entry-title itempropname>a hrefhttp://www.adrianwalker.org/2020/10/code-point-open-postcode-distance-aws.html>Code-Point Open Postcode Distance AWS Lambda/a>/h3>div classpost-header>div classpost-header-line-1>/div>/div>div classpost-body entry-content idpost-body-8221858158534382558 itempropdescription articleBody>p>Redis supports calculating distances using longitude and latitude with a hrefhttps://redis.io/commands/geodist>GEODIST/a>, but I wanted to use a hrefhttps://en.wikipedia.org/wiki/Easting_and_northing>eastings and northings/a> to calculate distance between postcodes./p>p>This project uses the a hrefhttps://www.ordnancesurvey.co.uk/business-government/products/code-point-open>Code-Point Open/a> dataset, loaded in to AWS ElastiCache (Redis) from an AWS S3 bucket, and provides an AWS Lambda REST API to query the distance between two given postcodes./p>p>The a hrefhttps://osdatahub.os.uk/downloads/open/CodePointOpen>Code-Point Open dataset/a> is available as a free download from the a hrefhttps://osdatahub.os.uk/>/a>Ordnance Survey Data Hub/a>./p>h4>Dataset/h4>p>CSV Zip Download - a hrefhttps://osdatahub.os.uk/downloads/open/CodePointOpen>Code-Point Open/a>/p>h4>Source Code/h4>p>Code available in GitHub - a hrefhttps://github.com/adrianwalker/codepoint-distance>codepoint-distance/a>/p>h4>Build and Run/h4>p>Build using Maven:br/>code>mvn clean install/code>/p>p>See the a hrefhttps://github.com/adrianwalker/codepoint-distance/blob/master/README.md>README.md/a> file on GitHub for AWS deployment instructions using the AWS Command Line Interface./p>h4>Example Usage/h4>p>The REST API takes two postcodes as URL parameters and returns the distance in meters, along with each postcodes eastings and northings./p>p>Using curl from the Linux command line:/p>pre classbrush:bash>curl -s https://77waizvyq3.execute-api.eu-west-2.amazonaws.com/Prod/codepoint/distance/YO241AB/YO17HH | json_pp{ distance : 817.743235985477, toCodePoint : { postcode : YO1 7HH, eastings : 460350, northings : 452085 }, fromCodePoint : { postcode : YO24 1AB, eastings : 459610, northings : 451737 }}/pre>div styleclear: both;>/div>/div>div classpost-footer>div classpost-footer-line post-footer-line-1>span classpost-author vcard>Posted byspan classfn itempropauthor itemscopeitemscope itemtypehttp://schema.org/Person>span itempropname>Adrian Walker/span>/span>/span>span classpost-timestamp>atmeta contenthttp://www.adrianwalker.org/2020/10/code-point-open-postcode-distance-aws.html itempropurl/>a classtimestamp-link hrefhttp://www.adrianwalker.org/2020/10/code-point-open-postcode-distance-aws.html relbookmark titlepermanent link>abbr classpublished itempropdatePublished title2020-10-03T18:45:00+01:00>6:45 pm/abbr>/a>/span>span classpost-comment-link>/span>span classpost-icons>span classitem-control blog-admin pid-255443665>a hrefhttps://www.blogger.com/post-edit.g?blogID3451413587413375915&postID8221858158534382558&frompencil titleEdit Post>img alt classicon-action height18 srchttps://resources.blogblog.com/img/icon18_edit_allbkg.gif width18/>/a>/span>/span>div classpost-share-buttons goog-inline-block>/div>/div>div classpost-footer-line post-footer-line-2>span classpost-labels>/span>/div>div classpost-footer-line post-footer-line-3>span classpost-location>/span>/div>/div>/div>/div> /div>/div> div classdate-outer> h2 classdate-header>span>Saturday 16 November 2019/span>/h2> div classdate-posts> div classpost-outer>div classpost hentry uncustomized-post-template itempropblogPost itemscopeitemscope itemtypehttp://schema.org/BlogPosting>meta contenthttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzRFvueAMFhwp9-8HHccgFFbvcdfOcOyxBqdqjqpZ5oB48KdnIAcR5Zl3AaTVK36GNfYLX_J2UBdnqdKzchFKqfLPXpL-rZ-eCR0hKEZpS1mfxuDjmLlgq_IsX-sqAuRY1S8YCkLqmdmg/s320/ststpcnt1.png itempropimage_url/>meta content3451413587413375915 itempropblogId/>meta content9014280205484151456 itemproppostId/>a name9014280205484151456>/a>h3 classpost-title entry-title itempropname>a hrefhttp://www.adrianwalker.org/2019/11/start-stop-continue.html>Start Stop Continue/a>/h3>div classpost-header>div classpost-header-line-1>/div>/div>div classpost-body entry-content idpost-body-9014280205484151456 itempropdescription articleBody>p>Start Stop Continue is a virtual post-it note board for Start / Stop / Continue style retrospectives. It is implemented using Java, jQuery, and JSON files for persistence./p>p>The project is designed for simplicity and the option for extension, rather than scalability. Even logging and error handling are secondary concerts at this point in the project./p>p>An example instance of the site is hosted here: a hrefhttp://ststpcnt.com>ststpcnt.com/a>./p>div classseparator styleclear: both; text-align: center;>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzRFvueAMFhwp9-8HHccgFFbvcdfOcOyxBqdqjqpZ5oB48KdnIAcR5Zl3AaTVK36GNfYLX_J2UBdnqdKzchFKqfLPXpL-rZ-eCR0hKEZpS1mfxuDjmLlgq_IsX-sqAuRY1S8YCkLqmdmg/s1600/ststpcnt1.png imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height704 data-original-width1366 height165 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzRFvueAMFhwp9-8HHccgFFbvcdfOcOyxBqdqjqpZ5oB48KdnIAcR5Zl3AaTVK36GNfYLX_J2UBdnqdKzchFKqfLPXpL-rZ-eCR0hKEZpS1mfxuDjmLlgq_IsX-sqAuRY1S8YCkLqmdmg/s320/ststpcnt1.png width320 />/a>/div>div classseparator styleclear: both; text-align: center;>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1UL-SI3X1LbuJ2IiZD8cfDxODsMa880PmFPyFMiIUu_0sLtlszakV2A9ZTUeOFLieYmHjiee48t7QTz_VccOuqMPJ2n6D2243m2PJ7KX2LhDHY3302OgyJNRCTShGSqg86yk8DGI8ThM/s1600/ststpcnt2.png imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height704 data-original-width1366 height165 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1UL-SI3X1LbuJ2IiZD8cfDxODsMa880PmFPyFMiIUu_0sLtlszakV2A9ZTUeOFLieYmHjiee48t7QTz_VccOuqMPJ2n6D2243m2PJ7KX2LhDHY3302OgyJNRCTShGSqg86yk8DGI8ThM/s320/ststpcnt2.png width320 />/a>/div>div classseparator styleclear: both; text-align: center;>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglmFsAlbmJAoEF1BP__KXcLczpZzU_VKJ2y3IT14vP_qrJAJ5RJz2OQP3qvnw8QcenN4HqPZhy7ot2OGWIbZ2ZTx6Xr77SI2vJxxP7BNt37n8i4TMcWUMA5gQp5tIwkuVrRq4ZiEFllqo/s1600/ststpcnt3.png imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height537 data-original-width305 height320 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglmFsAlbmJAoEF1BP__KXcLczpZzU_VKJ2y3IT14vP_qrJAJ5RJz2OQP3qvnw8QcenN4HqPZhy7ot2OGWIbZ2ZTx6Xr77SI2vJxxP7BNt37n8i4TMcWUMA5gQp5tIwkuVrRq4ZiEFllqo/s320/ststpcnt3.png width182 />/a>/div>h4>Source Code/h4>p>Code available in GitHub - a hrefhttps://github.com/adrianwalker/start-stop-continue>start-stop-continue/a>/p>h4>Setup/h4>p>This project requires a minimum of a hrefhttps://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html>Java 11 JDK/a> to build./p>h4>Build and Run/h4>p>Build using Maven:br/>code>mvn clean install/code>/p>p>Run by executing the built jar file:br/>code>java -jar start-stop-continue-jar-with-dependencies.jar/code>/p>p>Browse to:br/>code>http://localhost:8080/startstopcontinue/code>/p>p>A new post-it note board with a unique URL will be created and notes can be added, edited and deleted. If this project is deployed to a publicly available host, the URL can be shared with other retrospective participants./p>h4>Future Improvements/h4>p>Possible future improvements may include:ul>li>Add logging and more robust error handling/li>li>Integrate with a scalable datastore such as Apache Cassandra/li>li>Integrate with a scalable caching solution such as Redis/li>li>Use websockets for add/edit/delete live updates without refreshing the page/li>li>Port to AWS or other cloud based hosting provider/li>/ul>/p>div styleclear: both;>/div>/div>div classpost-footer>div classpost-footer-line post-footer-line-1>span classpost-author vcard>Posted byspan classfn itempropauthor itemscopeitemscope itemtypehttp://schema.org/Person>span itempropname>Adrian Walker/span>/span>/span>span classpost-timestamp>atmeta contenthttp://www.adrianwalker.org/2019/11/start-stop-continue.html itempropurl/>a classtimestamp-link hrefhttp://www.adrianwalker.org/2019/11/start-stop-continue.html relbookmark titlepermanent link>abbr classpublished itempropdatePublished title2019-11-16T18:52:00Z>6:52 pm/abbr>/a>/span>span classpost-comment-link>/span>span classpost-icons>span classitem-control blog-admin pid-255443665>a hrefhttps://www.blogger.com/post-edit.g?blogID3451413587413375915&postID9014280205484151456&frompencil titleEdit Post>img alt classicon-action height18 srchttps://resources.blogblog.com/img/icon18_edit_allbkg.gif width18/>/a>/span>/span>div classpost-share-buttons goog-inline-block>/div>/div>div classpost-footer-line post-footer-line-2>span classpost-labels>/span>/div>div classpost-footer-line post-footer-line-3>span classpost-location>/span>/div>/div>/div>/div> /div>/div> div classdate-outer> h2 classdate-header>span>Saturday 27 July 2019/span>/h2> div classdate-posts> div classpost-outer>div classpost hentry uncustomized-post-template itempropblogPost itemscopeitemscope itemtypehttp://schema.org/BlogPosting>meta contenthttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfRJIWvJsqeG0QadIYcp9MTrDXWq-rkVzFZfwmGKX0u8u0lklVIyVCmXBiDSqrGXw-JLawdVDbNSapSVhuM8IT8wUOh8PXsHUBCR2Uqq6mrN7qN7rFAjzfKCA6V1K3LVV7Bog3LP6O3Eg/s320/1-hole-saw.jpg itempropimage_url/>meta content3451413587413375915 itempropblogId/>meta content3013866556888166766 itemproppostId/>a name3013866556888166766>/a>h3 classpost-title entry-title itempropname>a hrefhttp://www.adrianwalker.org/2019/07/raspberry-pi-4-official-case-temperature.html>Raspberry Pi 4 Official Case Temperature /a>/h3>div classpost-header>div classpost-header-line-1>/div>/div>div classpost-body entry-content idpost-body-3013866556888166766 itempropdescription articleBody>p>My Raspberry Pi 4, running without a case, has an idle temperature of 54°C. With the official Pi 4 case the idle temperature jumps to 72°C./p>p>The official case is completely hotboxed, allowing for absolutely no airflow. Since the Pi 4 begins to throttle the CPU at 80°C, this makes the official case a design disaster and useless without the addition of active cooling./p>p>The a hrefhttps://noctua.at/en/products/fan>noctua range of fans/a> get great a hrefhttps://www.amazon.co.uk/gp/product/B071W6JZV8#customerReviews>reviews/a> and are super well made – but you pay a premium for quality; theyre pricey compared to other brands. I picked the 40mm x 20mm a hrefhttps://noctua.at/en/products/fan/nf-a4x20-5v>NF-A4x20 5v/a> for mounting on the outside of the Pi case./p>p>If you wanted a slimmer fan to mount inside the case, go for the 40mm x 10mm a hrefhttps://noctua.at/en/products/fan/nf-a4x10-5v>NF-A4x10 5v/a>./p>h4>Case Modding/h4>div classseparator styleclear: both; text-align: center;>/div>p>I cut a 38mm hole in the top part of the case with a hole saw, at the end of the case away from where the Pis USB and Ethernet ports are. Placing the fan over the hole, I marked out and drilled some screw holes for the screws provided with the fan./p>p>In the side of the Pi case base, Ive drilled 6, 2mm holes at 1cm intervals as an air inlet/exhaust./p>div classseparator styleclear: both; text-align: center;>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfRJIWvJsqeG0QadIYcp9MTrDXWq-rkVzFZfwmGKX0u8u0lklVIyVCmXBiDSqrGXw-JLawdVDbNSapSVhuM8IT8wUOh8PXsHUBCR2Uqq6mrN7qN7rFAjzfKCA6V1K3LVV7Bog3LP6O3Eg/s1600/1-hole-saw.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height921 data-original-width1465 height150 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfRJIWvJsqeG0QadIYcp9MTrDXWq-rkVzFZfwmGKX0u8u0lklVIyVCmXBiDSqrGXw-JLawdVDbNSapSVhuM8IT8wUOh8PXsHUBCR2Uqq6mrN7qN7rFAjzfKCA6V1K3LVV7Bog3LP6O3Eg/s320/1-hole-saw.jpg />/a>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWNhj8V5VeEUvXZzwMpVAs2bJ_76UCBx6laUibu_sODBUVbJBPWPbjyWvEApcO-gRmw-_A5djhlmoX04d64Us3xzghBuA3HqAypJgiY8jZnCmSeSc4j1eBY-302gYP5zZtPwV_O1pPzYc/s1600/2-case-top.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height1600 data-original-width1404 height150 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWNhj8V5VeEUvXZzwMpVAs2bJ_76UCBx6laUibu_sODBUVbJBPWPbjyWvEApcO-gRmw-_A5djhlmoX04d64Us3xzghBuA3HqAypJgiY8jZnCmSeSc4j1eBY-302gYP5zZtPwV_O1pPzYc/s320/2-case-top.jpg />/a>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLQnf7Er2mBfn59_kBO_-iz9-l5oEPEEgy4qGIJPyH1-rncHEImii8pYZF_HG6eyRC5gIxP5GgBs7GauKxeWgeT0IGUG4HDCKLEl-_xD_NVrdqOlAv0tkas9ijP-OMy3Z70ylJ7c54pSI/s1600/3-case-bottom.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height851 data-original-width1600 height150 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLQnf7Er2mBfn59_kBO_-iz9-l5oEPEEgy4qGIJPyH1-rncHEImii8pYZF_HG6eyRC5gIxP5GgBs7GauKxeWgeT0IGUG4HDCKLEl-_xD_NVrdqOlAv0tkas9ijP-OMy3Z70ylJ7c54pSI/s320/3-case-bottom.jpg />/a>/div>h4>Fan Connector Modding/h4>p>The fan comes with a big fat 3 pin connector, too big to fit on the Pis GPIO pins. The fan does come with a 2 pin adapter which you can add your own connectors to, but I chose not to use it as it would just take up space in the Pi case. Instead, I cut off the original connector, removed some of the wire insulation and crimped some new DuPont connectors./p>div classseparator styleclear: both; text-align: center;>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh06sJ4ehZ7QJqn9P3KqVALlcJB6buhPXtciWOkzoM8hDaQE8Ypzgo_lmfV5hXSpJBSj_dsg72Hp64Fz-78WWvnu2XeYqCLuERG7Uz98ssgnpsOR_-qH-nlZnPON7y_pS2yNSKqqQ-GDeg/s1600/4-dupont-connectors.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height624 data-original-width1600 height150 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh06sJ4ehZ7QJqn9P3KqVALlcJB6buhPXtciWOkzoM8hDaQE8Ypzgo_lmfV5hXSpJBSj_dsg72Hp64Fz-78WWvnu2XeYqCLuERG7Uz98ssgnpsOR_-qH-nlZnPON7y_pS2yNSKqqQ-GDeg/s320/4-dupont-connectors.jpg />/a>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikYAhc0vu5BRUs_Q_2kIyWDFk686sAd9vAnMe8sSZaYbNOC3X-dA-6PrXIMeIgvoZ9ILuhF9z2MhqyOkdzKjtul5hPimXj5kYcsIFYWVylvF6WqjrxRpy2s0-LnrEMlo3E08jwekIiz8c/s1600/5-crimp.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height1400 data-original-width1080 height150 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikYAhc0vu5BRUs_Q_2kIyWDFk686sAd9vAnMe8sSZaYbNOC3X-dA-6PrXIMeIgvoZ9ILuhF9z2MhqyOkdzKjtul5hPimXj5kYcsIFYWVylvF6WqjrxRpy2s0-LnrEMlo3E08jwekIiz8c/s320/5-crimp.jpg />/a>/div>p>The black wire connects to one of the Pis ground pins. The red wire connects to one of the Pis 5v pins. The yellow wire is not required - I crimped a connector anyway, but then just keep it out of the way with some tape./p>div classseparator styleclear: both; text-align: center;>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWWUXJOyqzUl3t_Uf-jW8Fvfa2atvZEdMyNFV3h-Fy7gtMdkx-Gz5CxWJ6ELAdostLEkcO4xarH2Ql8VPg03W9la5A1I_N44uaeXch-4MknR4KL0eUUVBNR4uIMw4p-7dm1vTYYhWKCwo/s1600/gpio.png imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height446 data-original-width1498 height119 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWWUXJOyqzUl3t_Uf-jW8Fvfa2atvZEdMyNFV3h-Fy7gtMdkx-Gz5CxWJ6ELAdostLEkcO4xarH2Ql8VPg03W9la5A1I_N44uaeXch-4MknR4KL0eUUVBNR4uIMw4p-7dm1vTYYhWKCwo/s400/gpio.png width400 />/a>/div>h4>Suck vs Blow/h4>p>Should you mount the fan to blow cooler air on to the Pi board and vent the warmer air through the side holes, or use the side holes as an inlet for cooler air and suck the warmer air away from the Pi board?/p>p>The only way to really know is to mount the fan both ways, stress test the Pi, measure the temperature and compare the results. Install the stress package on the Pi using apt with command:/p>pre>sudo apt-get install stress/pre>p>For the tests below I have used the stress command with the cpu, io, vm and hdd parameters, with 4 workers for each, running for 5 minutes (300 seconds):/p>pre>stress -c 4 -i 4 -m 4 -d 4 -t 300/pre>p>The Pis temperature can be measured with:/p>pre>vcgencmd measure_temp/pre>p>For the tests below, I sample the temperature every 5 seconds in a loop for 7 minutes (84 iterations) to record temperature rise and drop off:/p>pre>for i in {1..84}; do printf `date +%T`\t`vcgencmd measure_temp | sed s/^0-9.//g`\n; sleep 5; done/pre>p>b>Test 1 – Blow/b>/p>div classseparator styleclear: both; text-align: center;>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGA0ULf0a5DS5X5qdUz_K24RMD7WHT48Pvz5sT-KITw7E8EenGeuS0v-9a6fopcSJ5JlSXFBwCpawPxRc_FsalLLzoqUfJ2SosAPzS6SNd0vC8piFwW3EFk12EtYpK2tuhjQdFIh1ZT54/s1600/6-blow-fan.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height1600 data-original-width1529 height150 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGA0ULf0a5DS5X5qdUz_K24RMD7WHT48Pvz5sT-KITw7E8EenGeuS0v-9a6fopcSJ5JlSXFBwCpawPxRc_FsalLLzoqUfJ2SosAPzS6SNd0vC8piFwW3EFk12EtYpK2tuhjQdFIh1ZT54/s320/6-blow-fan.jpg />/a>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIugmDAGihD-bbsx8eu2l36FObUcK5HhNCMugJSCsaRmOBukjUN8GTd_uwqUlF52vmy-kX7WG4i1NCuoSMVPA6m1pVZK7uAekpgqyCicquYvHZlfk1fa-A2dIoLOSvTFX5XADL7V0IuWE/s1600/7-blow-open.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height1600 data-original-width1514 height150 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIugmDAGihD-bbsx8eu2l36FObUcK5HhNCMugJSCsaRmOBukjUN8GTd_uwqUlF52vmy-kX7WG4i1NCuoSMVPA6m1pVZK7uAekpgqyCicquYvHZlfk1fa-A2dIoLOSvTFX5XADL7V0IuWE/s320/7-blow-open.jpg />/a>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiImfsKE79oSCLDxyECq6f68URvt52c3ZX8FFyecevN0dkK_GuSSBCa7n_E-legj9WkPc1rQZurZdHspmaw6zylt5P1n5Ai7FGCFJWmbxI8TU3I0u49d2Cl73tOJt_8biIrcpB3zJdScAY/s1600/8-blow-closed.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height1151 data-original-width1596 height150 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiImfsKE79oSCLDxyECq6f68URvt52c3ZX8FFyecevN0dkK_GuSSBCa7n_E-legj9WkPc1rQZurZdHspmaw6zylt5P1n5Ai7FGCFJWmbxI8TU3I0u49d2Cl73tOJt_8biIrcpB3zJdScAY/s320/8-blow-closed.jpg />/a>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghyT6wAfmy1xbkBQFcDdtPG5-wFNTuqjztzBcGYiF6VEzcYQDLV-Zr7wg8ejPAWcxrj0tyKylLmDFdj7OvTXLxXzRnwT8K157F7yJLQDDX-imUmryv2gejsCc_L6_JBBRdggFbdDAYfqw/s1600/9-blow-closed.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height1090 data-original-width1600 height150 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghyT6wAfmy1xbkBQFcDdtPG5-wFNTuqjztzBcGYiF6VEzcYQDLV-Zr7wg8ejPAWcxrj0tyKylLmDFdj7OvTXLxXzRnwT8K157F7yJLQDDX-imUmryv2gejsCc_L6_JBBRdggFbdDAYfqw/s320/9-blow-closed.jpg />/a>/div>p>Mounting the fan with the sticker side down to blow air onto the board, connecting the power pins, closing the case and running the stress test gave the following results:/p>pre>$ stress -c 4 -i 4 -m 4 -d 4 -t 300stress: info: 1074 dispatching hogs: 4 cpu, 4 io, 4 vm, 4 hddstress: info: 1074 successful run completed in 303s/pre>pre>$ for i in {1..84}; do printf `date +%T`\t`vcgencmd measure_temp | sed s/^0-9.//g`\n; sleep 5; done10:59:42 38.010:59:47 37.010:59:52 43.010:59:57 45.011:00:02 47.011:00:07 48.011:00:12 48.011:00:17 49.011:00:22 49.011:00:27 50.011:00:32 50.011:00:37 51.011:00:42 51.011:00:48 52.011:00:53 52.011:00:58 51.011:01:03 53.011:01:08 52.011:01:13 52.011:01:18 53.011:01:23 53.011:01:28 53.011:01:34 53.011:01:42 52.011:01:48 53.011:01:55 52.011:02:00 54.011:02:05 54.011:02:10 54.011:02:15 53.011:02:20 53.011:02:25 53.011:02:30 53.011:02:35 54.011:02:41 54.011:02:46 54.011:02:51 53.011:02:56 52.011:03:01 54.011:03:06 53.011:03:11 54.011:03:16 53.011:03:21 54.011:03:26 54.011:03:31 54.011:03:36 54.011:03:41 54.011:03:46 54.011:03:51 54.011:03:56 54.011:04:01 53.011:04:06 54.011:04:11 53.011:04:16 54.011:04:21 53.011:04:26 54.011:04:31 53.011:04:37 54.011:04:42 53.011:04:47 54.011:04:52 49.011:04:57 46.011:05:02 45.011:05:07 44.011:05:12 46.011:05:17 43.011:05:22 42.011:05:27 42.011:05:32 41.011:05:37 40.011:05:42 41.011:05:47 40.011:05:52 40.011:05:57 41.011:06:02 39.011:06:07 40.011:06:12 39.011:06:17 39.011:06:22 38.011:06:27 38.011:06:32 38.011:06:37 38.011:06:42 39.011:06:47 38.0/pre>p>b>Test 2 – Suck/b>/p>div classseparator styleclear: both; text-align: center;>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjJh5dvKKoKEUTlpG7z04p5fiJlqwD_35hOShTVB2Hd_1gImIKromoICLb-SJDanoAv3Rzqs_hHEi23US7HjBeN8iOTw4aMj3x3BaYG5jM_UrZ7wLig9C_UY6wENKvx2urAklww87HEwM/s1600/10-suck-fan.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height1318 data-original-width1600 height150 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjJh5dvKKoKEUTlpG7z04p5fiJlqwD_35hOShTVB2Hd_1gImIKromoICLb-SJDanoAv3Rzqs_hHEi23US7HjBeN8iOTw4aMj3x3BaYG5jM_UrZ7wLig9C_UY6wENKvx2urAklww87HEwM/s320/10-suck-fan.jpg />/a>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicQ299WDt9krwH2LzxlFoopc1dT34QWYzGs_zVenRvACtn4hyni9-BeSk5T6RpeGrPDwj8ehRpAiKyUTRWp9OVhkafesCyhwqs81-XaUu28U12RgYCG-CABXQ5ECTPDMr6RBwKgREbOH8/s1600/11-suck-open.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height1136 data-original-width1600 height150 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicQ299WDt9krwH2LzxlFoopc1dT34QWYzGs_zVenRvACtn4hyni9-BeSk5T6RpeGrPDwj8ehRpAiKyUTRWp9OVhkafesCyhwqs81-XaUu28U12RgYCG-CABXQ5ECTPDMr6RBwKgREbOH8/s320/11-suck-open.jpg />/a>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmn7AhMnmAxXwzwa7oRtQRVGy-7SWKzSdOSaSbKMi-O2IAPvTgOVoIdg4lQ-WjwkpNsm9uQ9kxCQRRkljffORFWbxlSu_oUBmMSuJDpR9_NkSqX44S85zZ7KCv7Cy1DOo4i02D9Lgbx-U/s1600/12-suck-closed.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height1039 data-original-width1600 height150 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmn7AhMnmAxXwzwa7oRtQRVGy-7SWKzSdOSaSbKMi-O2IAPvTgOVoIdg4lQ-WjwkpNsm9uQ9kxCQRRkljffORFWbxlSu_oUBmMSuJDpR9_NkSqX44S85zZ7KCv7Cy1DOo4i02D9Lgbx-U/s320/12-suck-closed.jpg />/a>/div>p>Re-mounting the fan with the sticker side up to suck air away from the board, connecting the power pins, closing the case and running the stress test gave the following results:/p>pre>$ stress -c 4 -i 4 -m 4 -d 4 -t 300stress: info: 1041 dispatching hogs: 4 cpu, 4 io, 4 vm, 4 hddstress: info: 1041 successful run completed in 302s/pre>pre>$ for i in {1..84}; do printf `date +%T`\t`vcgencmd measure_temp | sed s/^0-9.//g`\n; sleep 5; done11:22:41 39.011:22:46 40.011:22:51 46.011:22:56 49.011:23:01 50.011:23:06 51.011:23:11 52.011:23:16 52.011:23:21 52.011:23:26 52.011:23:31 53.011:23:36 54.011:23:41 54.011:23:46 54.011:23:51 55.011:23:56 55.011:24:01 55.011:24:06 54.011:24:11 55.011:24:16 55.011:24:22 55.011:24:27 54.011:24:37 55.011:24:42 56.011:24:47 57.011:24:52 56.011:24:57 57.011:25:02 55.011:25:07 56.011:25:12 56.011:25:17 57.011:25:22 56.011:25:27 57.011:25:32 56.011:25:37 57.011:25:42 58.011:25:47 58.011:25:53 58.011:25:58 58.011:26:03 57.011:26:08 58.011:26:13 57.011:26:18 58.011:26:23 58.011:26:28 57.011:26:33 58.011:26:38 57.011:26:43 57.011:26:48 58.011:26:53 58.011:26:58 59.011:27:03 58.011:27:08 58.011:27:13 57.011:27:18 58.011:27:23 59.011:27:28 58.011:27:33 58.011:27:38 58.011:27:43 58.011:27:48 55.011:27:53 51.011:27:58 49.011:28:03 48.011:28:09 47.011:28:14 46.011:28:19 46.011:28:24 46.011:28:29 45.011:28:34 45.011:28:39 44.011:28:44 44.011:28:49 43.011:28:54 44.011:28:59 44.011:29:04 42.011:29:09 42.011:29:14 42.011:29:19 42.011:29:24 43.011:29:29 43.011:29:34 42.011:29:39 42.011:29:44 42.0/pre>h4>Comparison/h4>p>Blowing air keeps the Pi cooler than sucking air, with temperature ranges of 37°C-54°C and 39°C-59°C respectively for this fan/vent combination./p>p>When sucking air, the Pi doesnt reach the original idle temperature 2 minutes after the stress test has ended./p>div classseparator styleclear: both; text-align: center;>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghkGWmp2FtA7kN8inaDxTZ8O3XOJVbdS54bF4iFPFvYU17h0Dlh84dzzDFJS3fTUsxQRb3bW-DJP0FRlR4F9GTdcCg1G-V8H2uDqLstAuIED7FSuwss_0nsKtLyUFBcmPWrVP2jCAyXHc/s1600/13-blow-vs-suck-temp.png imageanchor1 stylemargin-left: 1em; margin-right: 1em;>img border0 data-original-height428 data-original-width728 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghkGWmp2FtA7kN8inaDxTZ8O3XOJVbdS54bF4iFPFvYU17h0Dlh84dzzDFJS3fTUsxQRb3bW-DJP0FRlR4F9GTdcCg1G-V8H2uDqLstAuIED7FSuwss_0nsKtLyUFBcmPWrVP2jCAyXHc/s1600/13-blow-vs-suck-temp.png />/a>/div>h4>Parts list and prices/h4>p>table>tr> th>Part/th> th>Price/th> th>Link/th>/tr>tr> td>38mm Hole Saw/td> td>£4.59/td> td>a hrefhttps://www.ebay.co.uk/itm/143196534863>https://www.ebay.co.uk/itm/143196534863/a>/td>/tr>tr> td>DuPont Connectors/td> td>£2.60/td> td>a hrefhttps://www.ebay.co.uk/itm/264250195674>https://www.ebay.co.uk/itm/264250195674/a>/td>/tr>tr> td>Noctua NF-A4x20 5V/td> td>£13.40/td> td>a hrefhttps://www.amazon.co.uk/gp/product/B071W6JZV8>https://www.amazon.co.uk/gp/product/B071W6JZV8/a>/td>/tr>/table>/p>div styleclear: both;>/div>/div>div classpost-footer>div classpost-footer-line post-footer-line-1>span classpost-author vcard>Posted byspan classfn itempropauthor itemscopeitemscope itemtypehttp://schema.org/Person>span itempropname>Adrian Walker/span>/span>/span>span classpost-timestamp>atmeta contenthttp://www.adrianwalker.org/2019/07/raspberry-pi-4-official-case-temperature.html itempropurl/>a classtimestamp-link hrefhttp://www.adrianwalker.org/2019/07/raspberry-pi-4-official-case-temperature.html relbookmark titlepermanent link>abbr classpublished itempropdatePublished title2019-07-27T15:35:00+01:00>3:35 pm/abbr>/a>/span>span classpost-comment-link>/span>span classpost-icons>span classitem-control blog-admin pid-255443665>a hrefhttps://www.blogger.com/post-edit.g?blogID3451413587413375915&postID3013866556888166766&frompencil titleEdit Post>img alt classicon-action height18 srchttps://resources.blogblog.com/img/icon18_edit_allbkg.gif width18/>/a>/span>/span>div classpost-share-buttons goog-inline-block>/div>/div>div classpost-footer-line post-footer-line-2>span classpost-labels>/span>/div>div classpost-footer-line post-footer-line-3>span classpost-location>/span>/div>/div>/div>/div> /div>/div> div classdate-outer> h2 classdate-header>span>Saturday 6 July 2019/span>/h2> div classdate-posts> div classpost-outer>div classpost hentry uncustomized-post-template itempropblogPost itemscopeitemscope itemtypehttp://schema.org/BlogPosting>meta contenthttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLEuRIUKoTlXWhF9pMplyMGT-XIxY_qx4892-ifuCNR0tJRvpHTtl98ISGRUfkBbemQf1bQHskdXfxSHHaQJ3WK9fmlyO6dYqm-WCSpRn964pSGQtZiLLY6365l2MhlZ0cW1gzI0S8k0g/s320/backup-server-components.jpg itempropimage_url/>meta content3451413587413375915 itempropblogId/>meta content5665429675072462254 itemproppostId/>a name5665429675072462254>/a>h3 classpost-title entry-title itempropname>a hrefhttp://www.adrianwalker.org/2019/07/raspberry-pi-backup-server.html>Raspberry Pi Backup Server/a>/h3>div classpost-header>div classpost-header-line-1>/div>/div>div classpost-body entry-content idpost-body-5665429675072462254 itempropdescription articleBody>h4>Getting Old/h4>p>Recently Ive found myself lying awake at night worrying if my documents, code and photos are backed up and recoverable. Or to put it another way - Ive officially become old :-(/p>p>With a new Raspberry Pi 4B on order its time to re-purpose the old Raspberry Pi 3B to create a backup solution./p>h4>Hardware/h4>p>I want my backup solution and backup media to be small, cheap and redundant. Speed isnt really an issue, so Ive chosen micro SD as my backup media for this project./p>p>Ive picked up an Anker 4-Port USB hub, 2 SanDisk 64 GB micro SD cards and 2 SanDisk MobileMate micro SD card readers. I ordered this kit from Amazon and the prices at the time of writing were:/p>table> tr> th>Component/th>th>Price/th> /tr> tr> td>a hrefhttps://www.amazon.co.uk/gp/product/B00Y25XFGK>Anker 4-Port USB 3.0 Ultra Slim Data Hub/a>/td> td>£10.99/td> /tr> tr> td>a hrefhttps://www.amazon.co.uk/gp/product/B073JYVKNX>SanDisk Ultra 64 GB microSDXC/a>/td> td>£11.73/td> /tr> tr> td>a hrefhttps://www.amazon.co.uk/gp/product/B07G5JV2B5>SanDisk MobileMate USB 3.0 Reader/a>/td> td>£7.50/td> /tr>/table>p>They fit together really well, with room for two more SD cards and readers if I need to expand:/p>div classseparator styleclear: both; text-align: center;>a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLEuRIUKoTlXWhF9pMplyMGT-XIxY_qx4892-ifuCNR0tJRvpHTtl98ISGRUfkBbemQf1bQHskdXfxSHHaQJ3WK9fmlyO6dYqm-WCSpRn964pSGQtZiLLY6365l2MhlZ0cW1gzI0S8k0g/s1600/backup-server-components.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;> img border0 data-original-height1279 data-original-width1600 height256 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLEuRIUKoTlXWhF9pMplyMGT-XIxY_qx4892-ifuCNR0tJRvpHTtl98ISGRUfkBbemQf1bQHskdXfxSHHaQJ3WK9fmlyO6dYqm-WCSpRn964pSGQtZiLLY6365l2MhlZ0cW1gzI0S8k0g/s320/backup-server-components.jpg width320 /> /a>/div>div classseparator styleclear: both; text-align: center;> a hrefhttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTUizbZEB2vWBIA61Y1eI07M1F6F8Tcmpm0MCK6_t16EQjRuFfhbxfGHV1W42gSltzmOVPSN-3xppyk5OJEA3yotIrgV7Y6yQLt2EfUSFYR82KAJjN7fvHHzQNwkJmRtt6X42e6ehczs0/s1600/backup-server-assembled.jpg imageanchor1 stylemargin-left: 1em; margin-right: 1em;> img border0 data-original-height1372 data-original-width1600 height274 srchttps://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTUizbZEB2vWBIA61Y1eI07M1F6F8Tcmpm0MCK6_t16EQjRuFfhbxfGHV1W42gSltzmOVPSN-3xppyk5OJEA3yotIrgV7Y6yQLt2EfUSFYR82KAJjN7fvHHzQNwkJmRtt6X42e6ehczs0/s320/backup-server-assembled.jpg width320 /> /a>/div>p>The plan is to make one of the SD cards available over the network as a share, via the Pi using a hrefhttps://www.samba.org/>SAMBA/a>. The share can be mapped as a Windows network drive and files can easily be dragged and dropped for backup. In case the first backup SD card fails, the Pi will copy the files and folders from the first SD card to the second SD card using a hrefhttps://en.wikipedia.org/wiki/Rsync>rsync/a> to create a backup of the backup./p> h4>Software/h4>p>Download and upgrade the Pi 3B to the lastest version of a hrefhttps://www.raspberrypi.org/downloads/raspbian/>Raspbian/a>. Ive chosen Rapbian Lite to save a bit of space on the Pis SD card:/p>p>a hrefhttps://downloads.raspberrypi.org/raspbian_lite_latest>https://downloads.raspberrypi.org/raspbian_lite_latest/a>/p>p>At the time of writing the lastest download was:code>2019-06-20-raspbian-buster-lite.zip/code>/p>p>Write the OS to the Pis SD card using a hrefhttps://www.balena.io/etcher/>Etcher/a>. Top tip - Etcher can write a i>.zip/i> file, but its much quicker to extract the i>.iso/i> file from the i>.zip/i> file and write that instead./p>p>Dont forget to add an empty i>ssh/i> file to the boot partition on the Pis SD card if you are going to run the Pi headless./p>p>Put the Pis SD card into the Pi, attached the USB hub and micro SD cards, and boot the Pi and login via SSH. Update and upgrade any new packages first, enable unattended security updates and install your editor of choice:/p>pre>$ sudo apt-get update$ sudo apt-get upgrade$ sudo apt-get install unattended-upgrades$ sudo apt-get install vim/pre>p>Because Ive got a Pi 4 on the way, I want to call this Pi raspberrypi3. Modify the i>/etc/hostname/i> and i>/etc/hosts/i> files:/p>pre>$ sudo vim /etc/hostnameraspberrypi3/pre>pre>$ sudo vim /etc/hosts127.0.1.1 raspberrypi3/pre>pre>$ sudo reboot/pre>p>At this point, the backup SD cards should be available to Linux as devices i>/dev/sda/i> and i>/dev/sdb/i>./p>p>I want the backup SD cards to be readable on Linux and Windows machines using the a hrefhttps://en.wikipedia.org/wiki/ExFAT>exFAT/a> file system. A good tutorial on how to do this on Linux using a hrefhttps://en.wikipedia.org/wiki/Filesystem_in_Userspace>FUSE/a> and gdisk is available here:/p>p>a hrefhttps://matthew.komputerwiz.net/2015/12/13/formatting-universal-drive.html>https://matthew.komputerwiz.net/2015/12/13/formatting-universal-drive.html/a>/p>pre>$ sudo apt-get install exfat-fuse exfat-utils$ sudo apt-get install gdisk/pre>p>Use gdisk to remove any existing partitions, create a new partition and write this to the SD cards. Make sure to create the new partition as type i>0700/i> (Microsoft basic data) when prompted:/p>pre>$ sudo gdisk /dev/sdaGPT fdisk (gdisk) version 0.8.8Partition table scan: MBR: not present BSD: not present APM: not present GPT: not presentCreating new GPT entries.Command (? for help):/pre>pre>Command (? for help): oThis option deletes all partitions and creates a new protective MBR.Proceed? (Y/N): Y/pre>pre>Command (? for help): nPartition number (1-128, default 1):First sector (34-16326462, default 2048) or {+-}size{KMGTP}:Last sector (2048-16326462, default 16326462) or {+-}size{KMGTP}:Current type is Linux filesystemHex code or GUID (L to show codes, Enter 8300): 0700Changed type of partition to Microsoft basic data/pre>pre>Command (? for help): wFinal checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTINGPARTITIONS!!Do you want to proceed? (Y/N): YOK; writing new GUID partition table (GPT) to /dev/sda.Warning: The kernel is still using the old partition table.The new table will be used at the next reboot.The operation has completed successfully./pre>p>Repeat for the second SD card:/p>pre>$ sudo gdisk /dev/sdb/pre>p>Create exFAT partitions on both SD cards and label the partitions i>PRIMARY/i> and i>SECONDARY/i>:/p>pre>$ sudo mkfs.exfat /dev/sda1$ sudo exfatlabel /dev/sda1 PRIMARY/pre>pre>$ sudo mkfs.exfat /dev/sdb1$ sudo exfatlabel /dev/sdb1 SECONDARY/pre>p>Create directories to mount the new partitions on:/p>pre>$ sudo mkdir -p /media/usb/backup/primary$ sudo mkdir -p /media/usb/backup/secondary/pre>p>Modify i>/etc/fstab/i> to mount the SD cards by partition label. This allows us to mount the correct card regardless of its device path or UUID:/p>pre>$ sudo vim /etc/fstabLABELPRIMARY /media/usb/backup/primary exfat defaults 0 0LABELSECONDARY /media/usb/backup/secondary exfat defaults 0 0/pre>p>Mount the SD cards:/p>pre>$ sudo mount /media/usb/backup/primary$ sudo mount /media/usb/backup/secondary/pre>p>Create a cron job to rsync files from the primary card to the secondary card. The following entry syncs the files every day at 4am:/p>pre>$ sudo crontab -e0 4 * * * rsync -av --delete /media/usb/backup/primary/ /media/usb/backup/secondary//pre>p>To sync files immediately, rsync can be run from the command line at any time with:/p>pre>$ sudo rsync -av --delete /media/usb/backup/primary/ /media/usb/backup/secondary//pre>p>To make the primary SD card available as a Windows share, install and configure SAMBA:/p>pre>$ sudo apt-get install samba samba-common-bin$ sudo vim /etc/samba/smb.confbackup comment Pi backup share path /media/usb/backup/primary public yes browseable yes writable yes create mask 0777 directory mask 0777$ sudo service smbd restart/pre>p>Finally, install and configure UFW firewall, allowing incoming connections for SSH and SAMBA only:/p>pre>$ sudo apt-get install ufw$ sudo ufw default deny incoming$ sudo ufw default allow outgoing$ sudo ufw allow ssh$ sudo ufw allow samba$ sudo ufw enable/pre>div styleclear: both;>/div>/div>div classpost-footer>div classpost-footer-line post-footer-line-1>span classpost-author vcard>Posted byspan classfn itempropauthor itemscopeitemscope itemtypehttp://schema.org/Person>span itempropname>Adrian Walker/span>/span>/span>span classpost-timestamp>atmeta contenthttp://www.adrianwalker.org/2019/07/raspberry-pi-backup-server.html itempropurl/>a classtimestamp-link hrefhttp://www.adrianwalker.org/2019/07/raspberry-pi-backup-server.html relbookmark titlepermanent link>abbr classpublished itempropdatePublished title2019-07-06T13:47:00+01:00>1:47 pm/abbr>/a>/span>span classpost-comment-link>/span>span classpost-icons>span classitem-control blog-admin pid-255443665>a hrefhttps://www.blogger.com/post-edit.g?blogID3451413587413375915&postID5665429675072462254&frompencil titleEdit Post>img alt classicon-action height18 srchttps://resources.blogblog.com/img/icon18_edit_allbkg.gif width18/>/a>/span>/span>div classpost-share-buttons goog-inline-block>/div>/div>div classpost-footer-line post-footer-line-2>span classpost-labels>/span>/div>div classpost-footer-line post-footer-line-3>span classpost-location>/span>/div>/div>/div>/div> /div>/div> /div>div classblog-pager idblog-pager>span idblog-pager-older-link>a classblog-pager-older-link hrefhttp://www.adrianwalker.org/search?updated-max2019-07-06T13:47:00%2B01:00&max-results7 idBlog1_blog-pager-older-link titleOlder Posts>Older Posts/a>/span>a classhome-link hrefhttp://www.adrianwalker.org/>Home/a>/div>div classclear>/div>div classblog-feeds>div classfeed-links>Subscribe to:a classfeed-link hrefhttp://www.adrianwalker.org/feeds/posts/default target_blank typeapplication/atom+xml>Posts (Atom)/a>/div>/div>/div>/div>/div>div idsidebar-wrapper>div classsidebar section idsidebar>div classwidget BlogArchive data-version1 idBlogArchive1>h2>Blog Archive/h2>div classwidget-content>div idArchiveList>div idBlogArchive1_ArchiveList>ul classhierarchy>li classarchivedate expanded>a classtoggle hrefjavascript:void(0)>span classzippy toggle-open> ▼ /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2023/>2023/a>span classpost-count dirltr>(2)/span>ul classhierarchy>li classarchivedate expanded>a classtoggle hrefjavascript:void(0)>span classzippy toggle-open> ▼ /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2023/11/>November/a>span classpost-count dirltr>(1)/span>ul classposts>li>a hrefhttp://www.adrianwalker.org/2023/11/privategpt-installation-notes.html>PrivateGPT Installation Notes/a>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2023/09/>September/a>span classpost-count dirltr>(1)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2021/>2021/a>span classpost-count dirltr>(1)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2021/03/>March/a>span classpost-count dirltr>(1)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2020/>2020/a>span classpost-count dirltr>(1)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2020/10/>October/a>span classpost-count dirltr>(1)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2019/>2019/a>span classpost-count dirltr>(4)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2019/11/>November/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2019/07/>July/a>span classpost-count dirltr>(2)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2019/03/>March/a>span classpost-count dirltr>(1)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2018/>2018/a>span classpost-count dirltr>(6)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2018/08/>August/a>span classpost-count dirltr>(2)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2018/04/>April/a>span classpost-count dirltr>(2)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2018/02/>February/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2018/01/>January/a>span classpost-count dirltr>(1)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2017/>2017/a>span classpost-count dirltr>(6)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2017/10/>October/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2017/09/>September/a>span classpost-count dirltr>(4)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2017/01/>January/a>span classpost-count dirltr>(1)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2016/>2016/a>span classpost-count dirltr>(4)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2016/08/>August/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2016/04/>April/a>span classpost-count dirltr>(3)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2015/>2015/a>span classpost-count dirltr>(4)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2015/08/>August/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2015/03/>March/a>span classpost-count dirltr>(3)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2014/>2014/a>span classpost-count dirltr>(7)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2014/12/>December/a>span classpost-count dirltr>(2)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2014/10/>October/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2014/08/>August/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2014/07/>July/a>span classpost-count dirltr>(2)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2014/06/>June/a>span classpost-count dirltr>(1)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2013/>2013/a>span classpost-count dirltr>(6)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2013/11/>November/a>span classpost-count dirltr>(2)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2013/05/>May/a>span classpost-count dirltr>(2)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2013/03/>March/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2013/02/>February/a>span classpost-count dirltr>(1)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2012/>2012/a>span classpost-count dirltr>(6)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2012/08/>August/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2012/07/>July/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2012/06/>June/a>span classpost-count dirltr>(2)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2012/04/>April/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2012/03/>March/a>span classpost-count dirltr>(1)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2011/>2011/a>span classpost-count dirltr>(8)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2011/12/>December/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2011/07/>July/a>span classpost-count dirltr>(4)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2011/06/>June/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2011/03/>March/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2011/02/>February/a>span classpost-count dirltr>(1)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2010/>2010/a>span classpost-count dirltr>(19)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2010/12/>December/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2010/08/>August/a>span classpost-count dirltr>(3)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2010/06/>June/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2010/04/>April/a>span classpost-count dirltr>(3)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2010/03/>March/a>span classpost-count dirltr>(2)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2010/02/>February/a>span classpost-count dirltr>(8)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2010/01/>January/a>span classpost-count dirltr>(1)/span>/li>/ul>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2009/>2009/a>span classpost-count dirltr>(11)/span>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2009/11/>November/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2009/09/>September/a>span classpost-count dirltr>(2)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2009/08/>August/a>span classpost-count dirltr>(1)/span>/li>/ul>ul classhierarchy>li classarchivedate collapsed>a classtoggle hrefjavascript:void(0)>span classzippy> ► /span>/a>a classpost-count-link hrefhttp://www.adrianwalker.org/2009/07/>July/a>span classpost-count dirltr>(7)/span>/li>/ul>/li>/ul>/div>/div>div classclear>/div>/div>/div>div classwidget Text data-version1 idText3>h2 classtitle>Links/h2>div classwidget-content>div>a hrefhttps://github.com/adrianwalker>GitHub/a>/div>div>a hrefhttp://taffnaid.photos/>taffnaid.photos/a>/div>div>a hrefhttp://ststpcnt.com/>ststpcnt.com/a>/div>/div>div classclear>/div>/div>div classwidget Text data-version1 idText1>h2 classtitle>Contact/h2>div classwidget-content>a hrefmailto:adrian.walker@bcs.org>adrian.walker@bcs.org/a>/div>div classclear>/div>/div>div classwidget Text data-version1 idText2>h2 classtitle>About Me/h2>div classwidget-content>a hrefhttps://github.com/adrianwalker/CV/blob/master/README.md>CV/a>br/>a hrefhttp://www.linkedin.com/in/adywalker>Linkedin Profile/a>/div>div classclear>/div>/div>div classwidget Text data-version1 idText4>h2 classtitle>License/h2>div classwidget-content>The code on adrianwalker.org is Public Domain.br/>br/>Please feel free to use, modify and distribute my code in any way you like without any restrictions.br/>br/>If you do use any of my code it would be nice to hear how you are using it, drop me an email./div>div classclear>/div>/div>div classwidget Text data-version1 idText5>h2 classtitle>Other Peoples Stuff/h2>div classwidget-content>a hrefhttp://widgetsandshit.com/teddziuba/>teddziuba.com/a>br />a hrefhttp://steve-yegge.blogspot.co.uk/>steve-yegge.blogspot.co.uk/a>br />a hrefhttps://medium.com/@steve.yegge>medium.com/@steve.yegge/a>br />a hrefhttp://zedshaw.com/>zedshaw.com/a>br />a hrefhttp://michaelochurch.wordpress.com/>michaelochurch.wordpress.com/a>br />a hrefhttp://prog21.dadgum.com/>prog21.dadgum.com/a>br />a hrefhttp://davstott.me.uk/>davstott.me.uk/a>br />a hrefhttp://stilldrinking.org/>stilldrinking.org/a>br />a hrefhttp://c2.com/cgi/wiki?SoftwareDevelopment>c2.com/a>br />a hrefhttp://norvig.com/>norvig.com/a>br />a hrefhttp://stallman.org/>stallman.org/a>br />a hrefhttp://psy-lob-saw.blogspot.co.uk/>psy-lob-saw.blogspot.co.uk/a>br />a hrefhttp://yegor256.com/>yegor256.com/a>br />a hrefhttp://scottberkun.com/blog/>scottberkun.com/a>br />a hrefhttp://tim.dreamwidth.org/>tim.dreamwidth.org/a>br />a hrefhttp://trevormckendrick.com/>trevormckendrick.com/a>br />a hrefhttps://successfulsoftware.net/articles/>successfulsoftware.net/a>br />a hrefhttp://hintjens.com/>hintjens.com/a>br />a hrefhttps://www.igorkromin.net/>igorkromin.net/a>br />a hrefhttp://www.kalzumeus.com/>kalzumeus.com/a>br />a hrefhttps://guyrobottv.wordpress.com/>guyrobottv.wordpress.com/a>br />a hrefhttp://balusc.omnifaces.org/>balusc.omnifaces.org/a>br />a hrefhttp://www.marktarver.com/>marktarver.com/a>br />a hrefhttp://yosefk.com/blog/>yosefk.com/a>/div>div classclear>/div>/div>/div>/div>!-- spacer for skins that want sidebar and main to be the same height-->div classclear> /div>/div>!-- end content-wrapper -->div idfooter-wrapper>div classfooter no-items section idfooter>/div>/div>/div>/div>!-- end outer-wrapper -->script typetext/javascript srchttps://www.blogger.com/static/v1/widgets/3298326339-widgets.js>/script>script typetext/javascript>window__wavt AOuZoY6eSh_3pSX9vFm7OeC7CeX_OxygZw:1720825054650;_WidgetManager._Init(//www.blogger.com/rearrange?blogID\x3d3451413587413375915,//www.adrianwalker.org/,3451413587413375915);_WidgetManager._SetDataContext({name: blog, data: {blogId: 3451413587413375915, title: adrianwalker.org, url: http://www.adrianwalker.org/, canonicalUrl: http://www.adrianwalker.org/, homepageUrl: http://www.adrianwalker.org/, searchUrl: http://www.adrianwalker.org/search, canonicalHomepageUrl: http://www.adrianwalker.org/, blogspotFaviconUrl: http://www.adrianwalker.org/favicon.ico, bloggerUrl: https://www.blogger.com, hasCustomDomain: true, httpsEnabled: false, enabledCommentProfileImages: true, gPlusViewType: FILTERED_POSTMOD, adultContent: false, analyticsAccountNumber: , encoding: UTF-8, locale: en-GB, localeUnderscoreDelimited: en_gb, languageDirection: ltr, isPrivate: false, isMobile: false, isMobileRequest: false, mobileClass: , isPrivateBlog: false, isDynamicViewsAvailable: true, feedLinks: \x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22adrianwalker.org - Atom\x22 href\x3d\x22http://www.adrianwalker.org/feeds/posts/default\x22 /\x3e\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/rss+xml\x22 title\x3d\x22adrianwalker.org - RSS\x22 href\x3d\x22http://www.adrianwalker.org/feeds/posts/default?alt\x3drss\x22 /\x3e\n\x3clink rel\x3d\x22service.post\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22adrianwalker.org - Atom\x22 href\x3d\x22https://www.blogger.com/feeds/3451413587413375915/posts/default\x22 /\x3e\n, meTag: , adsenseHostId: ca-host-pub-1556223355139109, adsenseHasAds: false, adsenseAutoAds: false, boqCommentIframeForm: true, loginRedirectParam: , view: , dynamicViewsCommentsSrc: //www.blogblog.com/dynamicviews/4224c15c4e7c9321/js/comments.js, dynamicViewsScriptSrc: //www.blogblog.com/dynamicviews/a6ed991e7ca0d194, plusOneApiSrc: https://apis.google.com/js/platform.js, disableGComments: true, interstitialAccepted: false, sharing: {platforms: {name: Get link, key: link, shareMessage: Get link, target: }, {name: Facebook, key: facebook, shareMessage: Share to Facebook, target: facebook}, {name: BlogThis!, key: blogThis, shareMessage: BlogThis!, target: blog}, {name: Twitter, key: twitter, shareMessage: Share to Twitter, target: twitter}, {name: Pinterest, key: pinterest, shareMessage: Share to Pinterest, target: pinterest}, {name: Email, key: email, shareMessage: Email, target: email}, disableGooglePlus: true, googlePlusShareButtonWidth: 0, googlePlusBootstrap: \x3cscript type\x3d\x22text/javascript\x22\x3ewindow.___gcfg \x3d {\x27lang\x27: \x27en_GB\x27};\x3c/script\x3e}, hasCustomJumpLinkMessage: false, jumpLinkMessage: Read more, pageType: index, pageName: , pageTitle: adrianwalker.org}}, {name: features, data: {}}, {name: messages, data: {edit: Edit, linkCopiedToClipboard: Link copied to clipboard, ok: Ok, postLink: Post link}}, {name: template, data: {name: custom, localizedName: Custom, isResponsive: false, isAlternateRendering: false, isCustom: true}}, {name: view, data: {classic: {name: classic, url: ?view\x3dclassic}, flipcard: {name: flipcard, url: ?view\x3dflipcard}, magazine: {name: magazine, url: ?view\x3dmagazine}, mosaic: {name: mosaic, url: ?view\x3dmosaic}, sidebar: {name: sidebar, url: ?view\x3dsidebar}, snapshot: {name: snapshot, url: ?view\x3dsnapshot}, timeslide: {name: timeslide, url: ?view\x3dtimeslide}, isMobile: false, title: adrianwalker.org, description: Programming \x26amp; That, url: http://www.adrianwalker.org/, type: feed, isSingleItem: false, isMultipleItems: true, isError: false, isPage: false, isPost: false, isHomepage: true, isArchive: false, isLabelSearch: false}});_WidgetManager._RegisterWidget(_NavbarView, new _WidgetInfo(Navbar1, navbar, document.getElementById(Navbar1), {}, displayModeFull));_WidgetManager._RegisterWidget(_HeaderView, new _WidgetInfo(Header1, header, document.getElementById(Header1), {}, displayModeFull));_WidgetManager._RegisterWidget(_BlogView, new _WidgetInfo(Blog1, main, document.getElementById(Blog1), {cmtInteractionsEnabled: false, lightboxEnabled: true, lightboxModuleUrl: https://www.blogger.com/static/v1/jsbin/3149704565-lbx__en_gb.js, lightboxCssUrl: https://www.blogger.com/static/v1/v-css/13464135-lightbox_bundle.css}, displayModeFull));_WidgetManager._RegisterWidget(_BlogArchiveView, new _WidgetInfo(BlogArchive1, sidebar, document.getElementById(BlogArchive1), {languageDirection: ltr, loadingMessage: Loading\x26hellip;}, displayModeFull));_WidgetManager._RegisterWidget(_TextView, new _WidgetInfo(Text3, sidebar, document.getElementById(Text3), {}, displayModeFull));_WidgetManager._RegisterWidget(_TextView, new _WidgetInfo(Text1, sidebar, document.getElementById(Text1), {}, displayModeFull));_WidgetManager._RegisterWidget(_TextView, new _WidgetInfo(Text2, sidebar, document.getElementById(Text2), {}, displayModeFull));_WidgetManager._RegisterWidget(_TextView, new _WidgetInfo(Text4, sidebar, document.getElementById(Text4), {}, displayModeFull));_WidgetManager._RegisterWidget(_TextView, new _WidgetInfo(Text5, sidebar, document.getElementById(Text5), {}, displayModeFull));/script>/body>/html>
View on OTX
|
View on ThreatMiner
Please enable JavaScript to view the
comments powered by Disqus.
Data with thanks to
AlienVault OTX
,
VirusTotal
,
Malwr
and
others
. [
Sitemap
]