[{"content":"","date":null,"permalink":"https://al-phillips.co.uk/","section":"","summary":"","title":""},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/blog/","section":"Blog","summary":"","title":"Blog"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/home-automation/","section":"Tags","summary":"","title":"Home Automation"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/lirc/","section":"Tags","summary":"","title":"Lirc"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/raspberry-pi/","section":"Tags","summary":"","title":"Raspberry Pi"},{"content":"Quick update for the RaspIR post I made a while back.\nAfter updating the Linux kernel on my Raspberry Pi a few days ago and rebooting, I was met with the unfortunate scenario of being unable to turn my lights on and off. After a few hours of furious Googling, it turns out that the lirc-rpi module hasn\u0026rsquo;t made it into 4.19, instead gpio-ir and gpio-ir-tx are recommended to replace it.\nThis necessitates a very small change to get it working again, altering /boot/config.txt:\ndtoverlay=gpio-ir-tx,gpio_pin=27 Unfortunately this only enables a single device for sending (/dev/lirc0). I\u0026rsquo;m still investigating how best to re-enable receiving IR input. By the sounds of things (see here), more work is required to maintain compatibility with LIRC\u0026rsquo;s irrecord and gpio-ir. Hence, I think I may have to do a complete rewrite without using LIRC and using e.g. ir-ctl and ir-keytable. But that\u0026rsquo;s something for another day.\n","date":"9 June 2019","permalink":"https://al-phillips.co.uk/blog/raspir-update/","section":"Blog","summary":"","title":"RaspIR Update for Linux Kernel 4.19"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/","section":"Tags","summary":"","title":"Tags"},{"content":" This post comes as a result of a comment a friend made about what he thought was a good idea for a /r/dataisbeautiful post: \u0026ldquo;Some kind of graph showing the correlation between the population of a country and the number of people that answered it in the countries of the world sporcle quiz.\u0026rdquo; he said in a WhatsApp message. I think he knew exactly what would happen once I saw that suggestion\u0026hellip;\nMy grandfather used to work as a painter in a car garage. I remember him telling me that the sorts of people he worked with, mechanics and engineery types, had this quirk where if you were stuck with something, you simply had to stand in the middle of the shop looking puzzled. \u0026ldquo;What\u0026rsquo;s that you\u0026rsquo;ve got there? Oh let me have a look. Ah yeah, you see, what you need there\u0026hellip;\u0026rdquo; And solutions to your problem would be offered up by these inquisitive minds.\nApparently, I suffer from the same problem, except with data.\nAnyway\u0026hellip;\nSporcle gives you access to the global results at the end of the quiz (I got 124 out of 197, managing to forget that Afghanistan and Colombia exist along the way). I\u0026rsquo;m well aware that this isn\u0026rsquo;t a representative sample of the global population. Judging by the Alexa results, Sporcle\u0026rsquo;s users are mainly in English-speaking countries like the UK, USA and Australia, so if anything this is a look at how well the English-speaking world knows the rest.\nNext, population data: Wikipedia was my starting point. I headed on over to the List of countries by population (United Nations) article, and then converted the table to a CSV with this handy tool. There\u0026rsquo;s a couple of different articles with similar titles, but this one also includes labels of UN continental region and UN statistical region which will be useful later on when looking for regional effects on the \u0026ldquo;memorability\u0026rdquo; of a country.\nAfter a bit of manual cleaning up of the data - things like removing British Overseas Territories and Crown Dependencies, adding Kosovo, renaming \u0026ldquo;Côte d’Ivoire\u0026rdquo; and \u0026ldquo;Macedonia\u0026rdquo; to \u0026ldquo;Ivory Coast\u0026rdquo; and \u0026ldquo;Republic of Macedonia\u0026rdquo; for consistency etc. - it was a simple case of joining the two tables together in R and outputting to a CSV file.\nHere\u0026rsquo;s a sample:\nCountry Percentage Answered UN continental region UN statistical region Population2017 Afghanistan 79.5% Asia Southern Asia 35530081 Albania 64.5% Europe Southern Europe 2930187 Algeria 71.6% Africa Northern Africa 41318142 Andorra 66.2% Europe Southern Europe 76965 Angola 58.9% Africa Middle Africa 29784193 Full table is available here.\nAnd finally some plots:\nJust the points Some points labelled Just text labels These are the same plots with differing labels.\nThe grey lines are a linear-regression of \u0026ldquo;Memorability\u0026rdquo; against population: countries above the line are more memorable than their population would predict, countries below the line, less memorable.\nNo real surprises here, the upper right region is dominated by the G20 countries with the bizarre outlier that is the Vatican over on the top left, and then the African states that apparently people forget exist.\nI posted these to /r/dataisbeautiful, where another user suggested that using GDP in place of population might yield some interesting results. I tried it out. Here\u0026rsquo;s the same plots as above but with Nominal GDP on the X-axis:\nJust the points Some points labelled Just text labels There\u0026rsquo;s a lot less spread here which suggets that GDP makes for a better predictor than population. Another user suggested that the reason for this is that Nominal GDP is relevant for international trade.\nThe R scripts for the two above sets of plots are here:\nSporcle-population.R\nSporcle-GDP.R\nFinally, I did a bit of simple modelling in Stan to determine what the continent-level effects were, just a fixed-effects model with a Student-T residual:\n$$ \\text{Percentage Answered} \\sim \\text{Student}(\\nu, \\beta^\\text{Continent} + \\beta^\\text{Population} \\cdot log(\\text{Population}), \\sigma) $$And similarly, using Nominal GDP:\n$$ \\text{Percentage Answered} \\sim \\text{Student}(\\nu, \\beta^\\text{Continent} + \\beta^\\text{GDP} \\cdot log(\\text{Nominal GDP}), \\sigma) $$The Stan model file is here for interested parties, it\u0026rsquo;s the same for both models but with differing input data.\nWhat\u0026rsquo;s important is the results. First, with population:\nViolin plots for estimated Effect Size in percentage points, with fixed effects for log(Population) and each UN statistical region, geographic effects grouped and coloured by Continent. Mean effect denoted by solid line, 95% Highest Posterior Density Interval (HPDI) denoted by dashed lines. Here general geographic effects are evident, negative effects for Africa, positive effects for Europe and North America.\nAnd then with GDP: Violin plots for estimated Effect Size in percentage points, with fixed effects for log(Nominal GDP) and each UN statistical region, geographic effects grouped and coloured by Continent. Mean effect denoted by solid line, 95% Highest Posterior Density Interval (HPDI) denoted by dashed lines. Arguably these results are more interesting: once the effect of GDP is removed, there\u0026rsquo;s not an awful lot of distance between geographic regions.\nFinally, R scripts for doing the Stan analysis and plots are here:\nSporcle-stan-population.R\nSporcle-stan-GDP.R\nI originally did this all back in June, but only just bothered to write it up.\n","date":"19 December 2018","permalink":"https://al-phillips.co.uk/blog/sporcle/","section":"Blog","summary":"","title":"Countries of the World - an Analysis of Sporcle Quiz Data"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/ggplot/","section":"Tags","summary":"","title":"Ggplot"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/r/","section":"Tags","summary":"","title":"R"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/stan/","section":"Tags","summary":"","title":"Stan"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/linux/","section":"Tags","summary":"","title":"Linux"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/refind/","section":"Tags","summary":"","title":"REFInd"},{"content":"I\u0026rsquo;ve recently been doing lots of switching between Linux (i run arch btw) and Windows on my home PC. However, I also do a lot of things remotely. This is fine when you\u0026rsquo;ve got a pure Linux box, but dual-booting on consumer hardware leaves much to be desired.\nGRUB allows you to specify which boot option to select as default on your next boot (and only the next boot), which back-in-the-day I used to use to, in a slightly convoluted manner, reboot to Windows after defaulting to my Linux install. But I now use rEFInd as my bootloader, partly for the UEFI support, partly for the eye candy for the occassions that I am at my desk (or if someone else needs to use my PC, it\u0026rsquo;s much easier to get them to select the big Windows icon than scan through a list of boot options in the five second window they have before the default boots). rEFInd unfortunately doesn\u0026rsquo;t have this \u0026ldquo;next boot only\u0026rdquo; option.\nI\u0026rsquo;ve recently come across an invaluable little github gist that gives a pair of scripts that will set the \u0026ldquo;PreviousBoot\u0026rdquo; EFI variable which rEFInd uses as the default boot option. So it\u0026rsquo;s simply a case of running these to reboot to the OS of your choice!\nAs the post suggests, the most difficult bit of this is to compile the C++ script on Windows.\nI\u0026rsquo;ve also written a short powershell script to get the EFI variable change and the subsequent reboot into a single call:\nWrite-Host \u0026#34;Setting refind parameters...\u0026#34; $Command = \u0026#34;C:\\Scripts\\refind-next-boot.exe\u0026#34; $Params = \u0026#34;`\u0026#34;linux`\u0026#34;\u0026#34; \u0026amp; $Command $Params Write-Host \u0026#34;Done.\u0026#34; Write-Host \u0026#34;Rebooting to Linux...\u0026#34; \u0026amp; shutdown -t 0 -r Note the (frankly bizarre) way in which I needed to escape the quotes in the parameters being passed to the executable.\nAt some point in the future I hope this will become obsolete when I can totally virtualise my Windows install, but for now this is great.\n","date":"6 June 2018","permalink":"https://al-phillips.co.uk/blog/refindreboot/","section":"Blog","summary":"","title":"Remotely switching OS with rEFInd"},{"content":"If your site doesn\u0026rsquo;t support HTTPS, better hurry up. Google already uses HTTPS as a ranking factor, but from July 2018, Google Chrome will label non-HTTPS sites as not-secure. The following setup is so simple that there\u0026rsquo;s basically no excuse for your site to not be HTTPS compliant.\nThese instructions assume you\u0026rsquo;ve followed the mish-mash of a guide I posted for the starting setup.\nFirst of all, head on over to letencrypt.org and find the certbot installation instructions relevant for your webhost. In my case, that\u0026rsquo;s nginx on Ubuntu 16.04.\nInstall certbot from the certbot ppa:\n$ sudo apt-get update $ sudo apt-get install software-properties-common $ sudo add-apt-repository ppa:certbot/certbot $ sudo apt-get update $ sudo apt-get install python-certbot-nginx Then apply the nginx specific settings automatically:\n$ sudo certbot --nginx All that remains is to modify you Hugo config to use HTTPS:\nconfig.toml:\nbaseURL = \u0026#34;https://mydomain.com/\u0026#34; And don\u0026rsquo;t forget to update the url in your post-receive git hooks script:\n/usr/local/bin/hugo -s $WORKING_DIRECTORY -d $PUBLIC_WWW -b \u0026#34;https://${MY_DOMAIN}\u0026#34; And that\u0026rsquo;s it! The certbot even adds a cron job to periodically renew the certificates.\n","date":"3 June 2018","permalink":"https://al-phillips.co.uk/blog/letsencrypt/","section":"Blog","summary":"","title":"Adding HTTPS support to an nginx/Hugo site using letsencrypt"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/git/","section":"Tags","summary":"","title":"Git"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/hugo/","section":"Tags","summary":"","title":"Hugo"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/web-development/","section":"Tags","summary":"","title":"Web Development"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/nginx/","section":"Tags","summary":"","title":"Nginx"},{"content":"What follows is something of a personal reminder of how I got this webserver set up, using nginx to serve a static website which is generated by Hugo using git-hooks to deploy with a simple git push. I had to read several different tutorials to figure it out; those that I can remember I have linked at relevant points.\nA while later, I added HTTPS support using letsencrypt, but I\u0026rsquo;ll save that for another post since it required some more fiddling.\nHugo and nginx #DigitalOcean Tutorial\nInstall nginx #sudo apt install nginx Install Hugo #Grab the latest Hugo release from their github repo.\nwget https://github.com/gohugoio/hugo/releases/download/v0.32.3/hugo_0.32.3_Linux-32bit.deb sudo dpkg -i hugo*.deb Install themes and Pygments #Clone the Hugo themes. Bit lazy, really you should just clone the ones you need.\ngit clone --recursive https://github.com/spf13/hugoThemes ~/themes sudo pip install Pygments nginx setup #Create the vhost file for the site:\ncd /etc/nginx sudo nano sites-available/web #/etc/nginx/sites-available/web server { listen 80; server_name mydomain.com; location / { alias /home/username/public_html/; autoindex on; } } And \u0026ldquo;enable\u0026rdquo; it by symlinking the file in the sites-enabled directory (removing the default vhost while we\u0026rsquo;re here):\ncd sites-enabled rm default ln -s ../sites-available/web web Clone git repo of site #cd ~ git clone --bare http://www.example.com/mysite.git mysite.git mkdir public_html mkdir backup_html #In case things go wrong! Deployment Setup #DigitalOcean Tutorial\nThe git-hooks script post-receive is triggered when the repo is pushed to. We\u0026rsquo;ll use this to automatically build and deploy the site when we push changes to the production server.\ncd ~/mysite.git/hooks nano post-receive #!/bin/bash #~/mysite.git/hooks/post-receive GIT_REPO=$HOME/mysite.git WORKING_DIRECTORY=$HOME/my-domain-working PUBLIC_WWW=$HOME/public_html BACKUP_WWW=$HOME/backup_html MY_DOMAIN=mydomain.com set -e rm -rf $WORKING_DIRECTORY rsync -aqz $PUBLIC_WWW/ $BACKUP_WWW trap \u0026#34;echo \u0026#39;A problem occurred. Reverting to backup.\u0026#39;; rsync -aqz --del $BACKUP_WWW/ $PUBLIC_WWW; rm -rf $WORKING_DIRECTORY\u0026#34; EXIT git clone $GIT_REPO $WORKING_DIRECTORY rm -rf $PUBLIC_WWW/* /usr/local/bin/hugo -s $WORKING_DIRECTORY -d $PUBLIC_WWW -b \u0026#34;http://${MY_DOMAIN}\u0026#34; rm -rf $WORKING_DIRECTORY trap - EXIT Finally, don\u0026rsquo;t forget to chown +x the post-receive script, else nothing will happen when you push to it.\nThen on your development machine, add the bare repo as a remote like so:\ndev-system\u0026gt; git remote add prod username@mydomain.com:mysite.git Then it\u0026rsquo;s simply a case of\ndev-system\u0026gt; git push prod master And your changes are (hopefully) live!\n","date":"10 January 2018","permalink":"https://al-phillips.co.uk/blog/webserversetup/","section":"Blog","summary":"","title":"Setting up an nginx/Hugo Site"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/code/","section":"Tags","summary":"","title":"Code"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/electronics/","section":"Tags","summary":"","title":"Electronics"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/python/","section":"Tags","summary":"","title":"Python"},{"content":"I can now turn my lights on and off from my phone\nShort update to keep this half-working with Linux Kernel 4.19 here\nI forget exactly what drove me to do this, probably sheer laziness; I was getting tired of getting out of bed to turn the lights in my bedroom on and off. In the age of the smartphone and internet of things, it seemed obvious to try some sort of internet-enabled solution, just in case I was ever on the other side of the planet and wanted to turn my lights on. Looking around online it seemed that the only out-of-the-box solutions were either prohibitively expensive and/or required bulbs controlled through a wifi-connected RF base station. Besides, doing that kind of thing would really damage what little hacker cred I have to begin with.\nThen it occurred to me that with a cheap (~£10) IR-controlled lightbulb and some IR LEDs, I could probably hack something together using a Raspberry Pi. Thankfully, I already had one of those lying around (it sits on my desk and wakes my desktop up when I throw TCP packets at it).\nAn additional bonus was that it gave me an excuse to try out Flutter, Google\u0026rsquo;s new app development framework for Android and iOS.\nBefore I begin, I have to disclose that large parts of this were informed by a tutorial on alexba.in. Without that tutorial I probably would never have managed this.\nI\u0026rsquo;ve been meaning to write this up for a while now, mainly just as a reminder to myself on how I glued everything together!\nParts #Electronics-wise this is quite a simple project:\nInfrared LEDs (I used two, because why not) 10kΩ resistor NPN transistor (e.g. 2N2222) TSOP38238 Infrared Receiver Discounting minimum quantities, I think that amounts to about £0.70 in parts. The PCBs I had fabbed (more on that later) cost more than that.\nLIRC #The actual sending and receiving of IR data is performed with LIRC, a Linux package, installed on the Raspberry Pi with:\nsudo apt-get install lirc We then have to tell LIRC which pins to use for sending and receiving data.\nAdd the following to /etc/modules:\nlirc_dev lirc_rpi gpio_in_pin=17 gpio_out_pin=27 And add the following to /boot/config.txt:\ndtoverlay=lirc-rpi,gpio_in_pin=17,gpio_out_pin=27 Finally, modify /etc/lirc/lirc_options.conf:\ndriver = default The Circuits #Below is the basic circuit diagram. Circuit Diagram: The 2x8 connector at top right corresponds to pins 1 through 16 of a raspberry pi. D1 and D2 are the infrared LEDs, R1 is a 10k ohm pull-down resisitor, and Q1 is the 2N222 transistor. Note that the LEDs are connected to the 5V rail, but the TSOP38238 is on the 3.3V rail. Created in KiCad. This was all assembled on a breadboard that lived on my desk, with jumper cables galore. Sadly, I have no pictures of the monstrosity.\nKiCad #Eventually, I grew tired of the rat\u0026rsquo;s nest of wires sat on my desk and set about designing a two-layer PCB to replace it, which I designed in KiCad.\nPCB Layout: Blue is front silkscreen, yellow is the board edge. Red is the top layer of copper, green is the bottom. I\u0026rsquo;m impressed with KiCad; for someone who before this had never really done any PCB design, this was pretty painless, finding footprints for each part was probably the most irritating bit.\nThe board measures less than an inch square, 0.95\u0026quot; x 0.75\u0026quot;. Originally I was going to use a full length 2x20 connector for the Raspberry Pi, but the overall footprint of these parts was so small that it simply wasn\u0026rsquo;t worth the extra cost of fabbing a board that size, hence the 2x8.\nI sent these plans to OSH Park and got three copies of the board for $3.60 with free postage. Nice purple boards, bit of a wait but for a hobbyist who just wants a couple of copies to mess about with, it doesn\u0026rsquo;t really matter.\nHere\u0026rsquo;s a glamour shot of the board: The Finished Board: Please ignore that dodgy soldering on the PCB header. And attached to the Raspberry Pi for scale: The Board In Situ: The footprint is small enough that you could get away with using a Pi Zero Learning IR Codes #Even this was quite simple.\nsudo irrecord -d /dev/lirc0 /etc/lirc/lircd.conf.d/my_remote.conf And follow the instructions on screen to learn each of the buttons on your remote.\nThen if you take a peek at /etc/lirc/lircd.conf.d/my_remote.conf:\nalecks@rp3\u0026gt; cat /etc/lirc/lircd.conf.d/my_remote.conf # Please make this file available to others # by sending it to \u0026lt;lirc@bartelmus.de\u0026gt; # # this config file was automatically generated # using lirc-0.9.0-pre1(default) on Tue Jul 25 20:14:01 2017 # # contributed by # # brand: # model no. of remote control: # devices being controlled by this remote: # begin remote name AURAGLOW bits 16 flags SPACE_ENC|CONST_LENGTH eps 30 aeps 100 header 9067 4477 one 579 1660 zero 579 555 ptrail 579 repeat 9070 2212 pre_data_bits 16 pre_data 0xF7 gap 107975 toggle_bit_mask 0x0 begin codes brightness_up 0x00FF brightness_down 0x807F off 0x40BF on 0xC03F red 0x20DF green 0xA05F blue 0x609F white 0xE01F r1 0x10EF g1 0x906F b1 0x50AF flash 0xD02F r2 0x30CF g2 0xB04F b2 0x708F r3 0x08F7 b3 0x8877 b3 0x48B7 g3 0x8877 r4 0x28D7 g4 0xA857 b4 0x6897 strobe 0xF00F fade 0xC837 smooth 0xE817 end codes end remote The brand of this particular remote controlled bulb is \u0026ldquo;Auraglow\u0026rdquo;, by the way. It\u0026rsquo;s got lots of pretty colours and strobey functions.\nYou can test each of the buttons with:\nirsend SEND_ONCE \u0026lt;REMOTE_NAME\u0026gt; \u0026lt;CODE\u0026gt; For example, in my case:\nirsend SEND_ONCE AURAGLOW red Sets the lights to red.\nControlling over the network #The next thing I wanted to be able to do was to trigger the sending of these IR signals remotely. There\u0026rsquo;s probably a simpler way of doing this, but I chose good old Python.\nimport socket import sys import re #Added in edit, see below from subprocess import call UDP_PORT = 5006 UDP_IP = \u0026#34;0.0.0.0\u0026#34; if len(sys.argv) \u0026gt; 0: UDP_PORT = int(sys.argv[1]) sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # Internet,UDP sock.bind((UDP_IP, UDP_PORT)) print(\u0026#34;Listening on : \u0026#34;+str(UDP_IP)+\u0026#34;:\u0026#34;+str(UDP_PORT)+\u0026#34;...\u0026#34;) while True: data = b\u0026#39;\u0026#39; addr = \u0026#34;\u0026#34; data, addr = sock.recvfrom(1024) print(\u0026#34;received message: \u0026#34;, data, \u0026#34; from: \u0026#34;, addr) print(\u0026#34;length: \u0026#34;, len(data)) print(\u0026#34;decode: \u0026#34;, data.decode()) m = data.decode() m = re.split(\u0026#34;[^a-zA-Z0-9 _]\u0026#34;, m)[0] #Edit: This line prevents shell injection! call(\u0026#34;irsend SEND_ONCE \u0026#34; + m,shell=True) Code also available in this github repo.\nThis script listens on UDP port 5006 for a string that it can tack onto the end of irsend SEND_ONCE to form a command. So I just send AURAGLOW strobe to that port and it\u0026rsquo;s time for a rave.\nIs it secure? Probably not. But it works. Remember, this is being driven by laziness. Edit: It\u0026rsquo;s definitely not secure, like \u0026lsquo;vulnerable to shell injection\u0026rsquo; not secure. Since we need shell=True in the call command, we have to do some input sanitisation instead. I don\u0026rsquo;t think this is necessarily best practice (i.e. I think best practice would be to quote the command, but I couldn\u0026rsquo;t get that to work).\nAdding this line: m = re.split(\u0026quot;[^a-zA-Z0-9 _]\u0026quot;, m)[0] (the second to last one) stops any funny business.\nSet this is run at boot with a systemd service file, /etc/systemd/system/lirclistener.service:\n[Unit] Description=Python script processing lirc requests Want=network.target After=network.target [Service] User=root Group=root WorkingDirectory=/home/alecks/git/lircListener ExecStart=/usr/bin/python3 lircListener.py 5006 Restart=always RestartSec=5 [Install] WantedBy=multi-user.target And then enable and start it with:\nsudo systemctl enable lirclistener.service sudo systemctl start lirclistener.service Android App #I wrote a very quick and dirty app using Flutter. I\u0026rsquo;m very ashamed of this code. I will not be sharing it until I have made it look sane. Put it this way, at the moment each button calls a different method. Not the same method with different arguments, different methods with different names like so:\nvoid _sendBrightnessUp() { setState(() { LircClient.sendCommand(address,port,\u0026#34;AURAGLOW brightness_up\u0026#34;); }); } Then the button itself:\nnew RaisedButton( child: new Icon(Icons.brightness_high), onPressed: _sendBrightnessUp, ) Disturbing, no? I couldn\u0026rsquo;t for the life of me figure out how to generalise that function to a general string, since onPressed requires a function with no arguments; I\u0026rsquo;m very clearly missing a trick here. But I wrote this at 2am, and clearly, didn\u0026rsquo;t care, I wanted to be able to turn the lights off and go to bed. Rather, go to bed and turn the lights off from my phone.\nThe secret with sending packets of data like this turned out to be DatagramSockets; Android doesn\u0026rsquo;t like to let you open a TCP/UDP socket and just leave it open for you to use later.\nAnyway, here\u0026rsquo;s a screenshot:\nFlutter App: For what effectively amounts to less than 100 lines of code (in a single dart file as well), this is surprisingly nice. All in all, I think this is a horrid, hacky way to it. If there\u0026rsquo;s any home automation people reading this, they\u0026rsquo;re deffo gesticulating furiously.\n","date":"23 October 2017","permalink":"https://al-phillips.co.uk/blog/raspir/","section":"Blog","summary":"","title":"RaspIR"},{"content":"I\u0026rsquo;m not really one for taking many photos, I find it detracts from the experience of being in places. Better to have a couple of photos to jog the memory than take a hundred and not remember what was going on when you took \u0026rsquo;em.\nClifford\u0026#39;s Tower: A now empty shell, this is what remains of the Norman York castle. It was raining when we were at the top. All around the hill the tower sits on were geese. York is apparently swarming with geese. Ooh ain\u0026#39;t it quaint: This isn\u0026rsquo;t the famous Shambles. I actually didn\u0026rsquo;t take any photos down there because I was so overcome with wonderment. York Minster: Absolutely stunning example of a Gothic cathedral. For a rather non-religious person, I don\u0026rsquo;t half love religious buildings. I take some sort of bizarre pleasure from hearing American tourists in cities like York, especially in places like pubs, marvelling at how old everything is. We overheard an American woman in the Jorvik museum asking one of the staff whether there were many Roman remains in York. His response? \u0026ldquo;Yeah, loads\u0026rdquo;. She sounded amazed. I\u0026rsquo;ve clearly been spoiled living so near to Chester. Roman walls and ampitheatre? Meh.\n","date":"27 July 2017","permalink":"https://al-phillips.co.uk/blog/york/","section":"Blog","summary":"","title":"I went to York a couple of weeks ago"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/photos/","section":"Tags","summary":"","title":"Photos"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/travel/","section":"Tags","summary":"","title":"Travel"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/york/","section":"Tags","summary":"","title":"York"},{"content":"In case you haven\u0026rsquo;t noticed, this page is Powered By Hugo ©️. Hugo is a very nice static website engine, taking your neatly arranged directories full of Markdown files and converting it into a pretty website. I had tried to do something similar with Flask but the process of getting a kind of \u0026ldquo;dynamically-static\u0026rdquo; site running where I could just drop in new files was too much of a faff. Then a friend recommended Hugo which, after a couple of days of messing about, seems perfect for my use case. It\u0026rsquo;s taken me a little bit of time to get configured the way I want and to get nginx to play nicely with it. Along the way I\u0026rsquo;ve learnt a few lessons:\nDon\u0026rsquo;t code when you\u0026rsquo;re tired Don\u0026rsquo;t code after a few beers For heaven\u0026rsquo;s sake, test your code Otherwise you end up with git commit messages such as:\nCanonifying URLs (this should fix things, surely?)\nFollowed closely by:\nOh ffs come on\nand:\nHelp\nAnd finally:\nProblem was a typo on production server. Derp.\nThe typo in question was my misspelling \u0026ldquo;DOMAIN\u0026rdquo; as \u0026ldquo;DOMIAN\u0026rdquo; in a git hook script. That\u0026rsquo;s what I\u0026rsquo;m going to name my firstborn.\nSad thing is, I\u0026rsquo;ll probably go through a similar sort of thing when I try to replicate this setup on another server; I\u0026rsquo;m going to properly document things like this in future, I swear.\n","date":"25 June 2017","permalink":"https://al-phillips.co.uk/blog/first/","section":"Blog","summary":"","title":"First"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/tags/programming/","section":"Tags","summary":"","title":"Programming"},{"content":" Alex Phillips I\u0026rsquo;m Alex, better known by some friends and sometimes in academic circles as \u0026ldquo;Al\u0026rdquo;. Never Alexander. I\u0026rsquo;m a maths graduate who spent most of his undergraduate degree at the University of Liverpool dabbling in programming.\nBetween 2015 and 2019 I studied for a PhD in Electrical Engineering (also at the University of Liverpool), and I successfully defended my thesis in January 2020. My PhD revolved around developing Bayesian methods for protein quantification in mass spectrometry proteomics. Mostly this involved me writing models in Stan via Julia. You can read my thesis here.\nSince October 2019 I\u0026rsquo;ve been working in the Signal Processing Group in the Department of Electrical Engineering and Electronics at the University of Liverpool, first as a Research Associate and now as a Senior Data Scientist. My role sees me working on various projects under that umbrella including: developing software for navigation systems, using Kalman filters and particle filters for sensor fusion; gravity gradient modelling for navigation; annotating radar data for machine learning with active learning; translating epidemiological models for surveillance of the COVID-19 pandemic into Stan.\nFrom October 2019 to September 2020 I worked as a Research Software Engineer at the University of Manchester developing software for analysis of quantitative mass spectrometry data, mainly applying MCMC to perform differential expression analysis.\nBetween October 2020 and September 2021 I also worked as a Data Scientist in the Computational Biology Facility at the University of Liverpool. There I helped to develop an analysis pipeline to identify biomarkers for severity of COVID-19 infections.\nI also undertook a secondment with the UK Health Security Agency from November 2023 to May 2024, joining the Infectious Disease Modelling team to work on statistical modelling as part of the Winter Coronavirus Infection Study.\nWhen I\u0026rsquo;m not doing the above, I tend to either be playing instruments (badly), or video games (also badly), or fiddling about with computers.\nYou can find a list of my publications here.\nI exist in several places dotted across the web:\n- University of Liverpool Profile - Twitter X - Mastodon - Bluesky - GitHub - LinkedIn ","date":"1 January 0001","permalink":"https://al-phillips.co.uk/about/","section":"","summary":"","title":"About"},{"content":"","date":null,"permalink":"https://al-phillips.co.uk/categories/","section":"Categories","summary":"","title":"Categories"},{"content":"This site collects some Personal Data for the following purposes:\nGoogle Analytics with anonymized IP - cookies and usage data IP addresses in temporary HTTP access logs - security monitoring Being for personal use, this site is GDPR compliant.\nFor queries, contact: privacy@al-phillips.co.uk\n","date":"1 January 0001","permalink":"https://al-phillips.co.uk/privacy/","section":"","summary":"","title":"Privacy"},{"content":"Below is a list of my publications:\nJournal Articles # Martyn Fyles, Jonathon Mellor, Robert S. Paton, Christopher E. Overton, Alexander M. Phillips, Alex Glaser and Thomas Ward, 2026. \"Estimating COVID-19 incidence and prevalence using lateral flow tests in England and Scotland, 2023-2024.\" Nature Communications, 17(1). DOI link Jonathon Mellor, Martyn Fyles, Robert S. Paton, Alexander Phillips, Christopher E. Overton and Thomas Ward, 2025. \"Assessing the impact of SARS-CoV-2 on influenza-like illness surveillance trends in the community during the 2023/2024 winter in England.\" International Journal of Infectious Diseases, 150. DOI link Efthyvoulos Drousiotis, Alessandro Varsi, Alexander M. Phillips, Simon Maskell and Paul G. Spirakis, 2025. \"A Massively Parallel SMC Sampler for Decision Trees.\" Algorithms, 18(1). DOI link Benjamin Mawdsley, Sam Dorkings, Simon Maskell, David Pickup, Samantha Chong, Thomas Farrell and Alexander Phillips, 2025. \"Probabilistic modelling to account for uncertainty in portable energy dispersive X-ray diffraction measurements.\" Nuclear Instruments and Methods in Physics Research Section A: Accelerators, Spectrometers, Detectors and Associated Equipment, 1075. DOI link Aseel Sharaireh, Marta Guevara-Ferrer, Anna M. Ludlaim, Jonathan D. Humphries, Alexander M. Phillips, Andrew W. Dowsey, Zehan Zhang, John R. Counsell, Richard D. Unwin, Sara E. Mole, Ahad A. Rahim and Tristan R. McKay, 2025. \"CLN7 protein functions at the interface between endolysosomes and stress granules to promote cell survival.\" Cell Death \u0026amp; Disease, 16(1). DOI link Christopher E. Overton, Martyn Fyles, Jonathon Mellor, Robert S. Paton, Alexander M. Phillips, Alex Glaser, Andre Charlett and Thomas Ward, 2025. \"SARS-CoV-2 test sensitivity and duration of positivity in the UK during the 2023/2024 Winter: A prospective cohort study based on self-reported data.\" Journal of Infection, 90(6). DOI link Jiahe Lu, Alisa Veler, Boris Simonetti, Timsse Raj, Po Han Chou, Stephen J. Cross, Alexander M. Phillips, Xiongtao Ruan, Lan Huynh, Andrew W. Dowsey, Dingwei Ye, Robert F. Murphy, Paul Verkade, Peter J. Cullen and Christoph Wülfing, 2023. \"Five Inhibitory Receptors Display Distinct Vesicular Distributions in Murine T Cells.\" Cells, 12(21). DOI link Alexander M. Phillips, Michael J. Wright, Isabelle Riou, Stephen Maddox, Simon Maskell and Jason F. Ralph, 2022. \"Position fixing with cold atom gravity gradiometers.\" AVS Quantum Science, 4(2). DOI link preprint highlight Selina Mcharg, Laura Booth, Rahat Perveen, Isabel Riba Garcia, Nicole Brace, Nadhim Bayatti, Panagiotis I. Sergouniotis, Alexander M. Phillips, Anthony J. Day, Graeme C. M. Black, Simon J. Clark, Andrew W. Dowsey, Richard D. Unwin and Paul N. Bishop, 2022. \"Mast cell infiltration of the choroid and protease release are early events in age-related macular degeneration associated with genetic risk at both chromosomes 1q32 and 10q26.\" Proceedings of the National Academy of Sciences, 119(20). DOI link Michael J. Wright, Luke Anastassiou, Chinmaya Mishra, James M. Davies, Alexander M. Phillips, Simon Maskell and Jason F. Ralph, 2022. \"Cold atom inertial sensors for navigation applications.\" Frontiers in Physics, 10. DOI link Fiona K. Jones, Alexander M. Phillips, Andrew R. Jones and Addolorata Pisconti, 2022. \"The INSR/AKT/mTOR pathway regulates the pace of myogenesis in a syndecan-3-dependent manner.\" Matrix Biology, 113. DOI link Jingshu Xu, Stefano Patassini, Nitin Rustogi, Isabel Riba-Garcia, Benjamin D. Hale, Alexander M. Phillips, Henry Waldvogel, Robert Haines, Phil Bradbury, Adam Stevens, Richard L. M. Faull, Andrew W. Dowsey, Garth J. S. Cooper and Richard D. Unwin, 2019. \"Regional protein expression in human Alzheimer’s brain correlates with disease severity.\" Communications Biology, 2(1). DOI link Sarah Kassab, Paul Begley, Stephanie J. Church, Sanziana M. Rotariu, Cleo Chevalier-Riffard, Andrew W. Dowsey, Alexander M. Phillips, Leo A. H. Zeef, Ben Grayson, Joanna C. Neill, Garth J. S. Cooper, Richard D. Unwin and Natalie J. Gardiner, 2019. \"Cognitive dysfunction in diabetic rats is prevented by pyridoxamine treatment. A multidisciplinary investigation.\" Molecular Metabolism DOI link Conference Papers # Elias J. Griffith, Alexander M. Phillips, Liam Mai, Simon Maskell and Jason F. Ralph, 2024. \"Target tracking in a complex simulated world.\" In Electro-Optical and Infrared Systems: Technology and Applications XXI, 13200:131–142. DOI link Efthyvoulos Drousiotis, Alexander M. Phillips, Paul G. Spirakis and Simon Maskell, 2023. \"Bayesian Decision Trees Inspired from Evolutionary Algorithms.\" In Learning and Intelligent Optimization, :318–331. DOI Alexander M. Phillips, Michael J. Wright, Marton Kiss-Toth, Iain Read, Isabelle Riou, Stephen Maddox, Simon Maskell and Jason F. Ralph, 2020. \"Augmented inertial navigation using cold atom sensing.\" In Cold Atoms for Quantum Technologies, 11578:115780C. DOI link Book Chapters # Alexander M. Phillips, Richard D. Unwin, Simon J. Hubbard and Andrew W. Dowsey, 2023. \"Uncertainty-Aware Protein-Level Quantification and Differential Expression Analysis of Proteomics Data with seaMass.\" In Statistical Analysis of Proteomic Data: Methods and Tools, 141–162. Springer US. DOI link Hanqing Liao, Alexander Phillips, Andris Jankevics and Andrew W. Dowsey, 2017. \"Chapter 7 Algorithms for MS1-Based Quantitation.\" In Proteome Informatics, 133–154. The Royal Society of Chemistry. DOI link Last updated: 2026-07-18\n","date":"1 January 0001","permalink":"https://al-phillips.co.uk/publications/","section":"","summary":"","title":"Publications"}]