Nvidia Optimus, Clevo, and power management

2019-08-21 15:11 +0200

I've had a PC Specialist Optimus IX (Clevo N850EP6) laptop for a while, dual booting Debian testing (with kernel 4.19) and Windows 10. This laptop has a hybrid graphics system with an integrated Intel UHD 630 and a dedicated NVIDIA GTX 1060 and, while it works pretty well for the most part, there have been several issues regarding power management, freezes (looking at you lspci!) and other malfunctions.

"Luckily" I am not the only one who has had these issues, so I finally could find a good solution for my case.

Dynamic fields with Flask-WTF

2019-03-02 14:53 +0100

Lately I've been working on a side project that requires dynamically adding or removing fields to a form: ideally, I should be able to add any number of fields and the server should receive the data correctly.

While a combination of FieldList and FormField works great when adding fields in the backend, I wanted to dynamically add and remove fields in the client (through Javascript) without having to send requests to the server until finally submitting the form with all the dynamic fields. Here's how that went.

TL;DR: Example code is available at https://gist.github.com/rmed/def5069419134e9da0713797ccc2cb29.

Using RPi Zero as a Keyboard Part 1: Setup and device definition

2017-06-26 16:40 +0200

The Raspberry Pi Zero is a cool little piece of hardware with many possibilities. One of them is that it can work as a USB host OR as a USB gadget, meaning that it is possible to implement different types of devices such as ethernet, HID (keyboard, mouse, gamepad, etc.), audio, mass storage, etc. In this 3-part series of post we'll see how to configure and use a simple and generic keyboard gadget to send keys to the connected host.

In this part I'll go over the process of defining the gadget, breaking down what each different configuration files is used for and giving example values.

Bridge? wat-bridge?

2016-10-13 19:27 +0200

Instant messaging services are very common nowadays. For instance, I use Telegram, while many people I know use WhatsApp, and that's cool. This, however, leads to a question I am asked often: "why don't you install WhatsApp?". The answer to that can be summarized in two main points: "because I don't want to" and "because I cannot install WhatsApp on my phone". But then again, it is interesting to see the user fragmentation between different services, so the Telegram bot API got me thinking about creating a "bridge" between WhatsApp and Telegram, just for fun.

TL;DR: source code available at https://github.com/rmed/wat-bridge

Using Selenium to parse a timetable

2016-09-27 17:31 +0200

The University of Greenwich portal offers a link to view your own timetable for any week or term. Even though it is useful, it would have been even more useful if it had a way of downloading the full timetable as an iCalendar file to import in calendar applications such as Google Calendar (other apps are available). I like being able to quickly access my calendar from my phone, but I am too lazy to copy the timetable to a piece of paper (which is what a friend suggested), therefore I wanted to try implementing a script to automatically convert the timetable to a .ics file.

Using acme.sh with nginx

2016-08-10 16:30 +0200

acme.sh is a script utility for the ACME spec used by Let's Encrypt. It is pretty simple and has no requirements, so I wanted to try using that in the server to issue and renew certificates rather than doing the process in my local machine and then copying the required files. It supports several modes for issuing the certificates, such as the Apache mode which I have used before, although there is no specific mode for nginx, so it is not possible to have completely automatic configuration if you use that server.

After installation we are now able to issue certificates, but there is a single problem: how should the challenge be solved? While it would be possible to stop nginx and have a local web server run on port 80, this might not be a good practice for production server. In my case, I cannot use another port (say, port 88) because that would require modifying some firewall rules, and that's kind of a bummer :)

So what are we going to do? Simple: use the webroot method and configure nginx to serve the challenges so that applications don't actually care about the challenge endpoint.

Migration system for Zoe microservices

2016-08-03 16:42 +0200

This is the title of my Bachelor Thesis, which focused on the development of an addition to the Zoe virtual assistant that enabled live migration of Zoe agents during runtime. Rather than modifying the original system or employing solutions such as virtualization or containers, which may have been a little too overkill for this scenario, I designed and implemented a software-based solution with the help of my supervisor, Professor David ExpĆ³sito from UC3M.

Wrapper for EMT Madrid API

2016-05-28 13:36 +0200

EMT Madrid, (the organization that operates the buses in Madrid), offers a public API with information such as waiting times, stop locations, etc.

I used this API some time ago to develop the madtrans Zoe agent: I performed the requests manually and parsed the data accordingly, although I only implemented some of the endpoints offered by the API. After a while I thought about creating a wrapper for the API in order to use it to improve the agent.

With the documentation available, I started developing the wrapper. I am not ashamed to admit that this development lasted less than a week: I got somewhat frustrated with some particular things of the API and put the project aside. Some weeks ago, however, I decided to continue developing the wrapper because of another project of which I will not talk about just yet.

The result is the pyemtmad wrapper for Python! It is definitely not perfect, but at least simplifies things greatly for me and kind of works. In order to use it, you just need credentials to access the API and instantiate a Wrapper as follows:

from pyemtmad import Wrapper

wrapper = Wrapper('MY_ID', 'MY_PASSWORD')

All the endpoints are then available through attributes of the wrapper object. Parameters and further details are available in the documentation.

Hope it is useful for someone!