20 Dec 2020 Parts:
HiLetgo DC 3-5V MAX6675 Module + K Type Thermocouple Temperature Sensor UCTRONICS 0.96 Inch OLED Module 12864 128x64 Yellow Blue SSD1306 Driver I2C ESP32 Code:
// based on the lcdthermocouple example
// also:
// https://randomnerdtutorials.com/esp32-ssd1306-oled-display-arduino-ide/
// http://www.esp32learning.com/code/esp32-and-max6675-example.php
// parts:
// * HiLetgo DC 3-5V MAX6675 Module + K Type Thermocouple Temperature Sensor
// * UCTRONICS 0.96 Inch OLED Module 12864 128x64 Yellow Blue SSD1306 Driver I2C
// * ESP32
#include <max6675.h>
#include <Wire.h>
// also requires Adafruit Bus IO Library
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
int thermoDO = 19; // SO
int thermoCS = 23;
int thermoCLK = 5; // SCK
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup() {
Serial.begin(9600);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
delay(2000);
}
void loop() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 1);
display.println("Paul's Thermometer");
display.setTextSize(5);
display.setTextColor(WHITE);
display.setCursor(0, 20);
display.print((int) thermocouple.readFahrenheit());
display.println("F");
display.display();
delay(200);
} 12 Dec 2020 Found a massive faillog/lastlog file recently and thought it was responsible for using up all my disk space. Turns out it’s actually a sparse file and doesn’t take up that much physical space: https://unix.stackexchange.com/a/530157
12 Dec 2020 Parts:
Arduino Uno 2x MAX6675 w/ thermocouple Code:
/*
* This sketch programs Ardunio to communicate with Artisan using MODBUS protocol and
* an inexpensive thermocouple amplifier.
*
* Hardware:
* Arduino UNO
* Thermocouple amplifier (MAX6675)
* K-type thermocouple
*
* Libraries needed:
* https://github.com/adafruit/MAX6675-library and;
* https://github.com/smarmengol/Modbus-Master-Slave-for-Arduino
*
* Based on:
* serialthermocouple arduino example
* https://github.com/hallgeirl/coffee-roaster/blob/4d4fa73c9831b0ff3f28752c454011ab70410de8/src/roaster/roaster.ino#L112-L136
*/
#include <max6675.h>
#include <ModbusRtu.h>
// data array for modbus network sharing:
uint16_t au16data[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 };
Modbus slave;
// declare variables for Arduino pins connected to the MAX data pins:
int thermoDO_bt = 6; // SO
int thermoCS_bt = 5;
int thermoCLK_bt = 4; // SCK
int thermoVCC_bt = 3;
int thermoGND_bt = 2;
MAX6675 thermocouple_bt(thermoCLK_bt, thermoCS_bt, thermoDO_bt);
int thermoDO_amb = 12;
int thermoCS_amb = 11;
int thermoCLK_amb = 10; // SCK
int thermoVCC_amb = 9;
int thermoGND_amb = 8;
MAX6675 thermocouple_amb(thermoCLK_amb, thermoCS_amb, thermoDO_amb);
void setup() {
// configure the pins to power MAX6675
pinMode(thermoVCC_bt, OUTPUT); digitalWrite(thermoVCC_bt, HIGH);
pinMode(thermoGND_bt, OUTPUT); digitalWrite(thermoGND_bt, LOW);
pinMode(thermoVCC_amb, OUTPUT); digitalWrite(thermoVCC_amb, HIGH);
pinMode(thermoGND_amb, OUTPUT); digitalWrite(thermoGND_amb, LOW);
slave = Modbus(1, 0, 0); // MODBUS object declaration: (1 = slave #1, 0 = RS232, 0 = RS232)
slave.begin(19200); // 19200 baud, 8-bits, none, 1-bit stop
delay(500);
}
void loop() {
au16data[2] = ((uint16_t) thermocouple_bt.readCelsius() * 100);
au16data[3] = ((uint16_t) thermocouple_amb.readCelsius() * 100);
slave.poll(au16data, 16);
// For the MAX6675 to update, you must delay AT LEAST 250ms between reads!
delay(200);
} 04 Sep 2020 Recently I worked on a bug that was causing duplicate unformatted log messages to appear in a Django app’s logs. I made a repository that demonstrates the issue: https://github.com/pawl/django_duplicate_unformatted_logs_example
The problem was caused by an accidental call to logging.info (without using logging.getLogger to get a specific logger) while the root logger isn’t already configured.
The solution ended up being to get rid of the accidental calls to logging.info and configuring the root logger to prevent it from accidentally happening again. I go into more details in that repo.
12 May 2020 Vue-custom-element seems like the best way to integrate vue into an existing application that uses server side templates.
This approach allows you to use vue components (built with the build pipeline ) in your existing html without making your entire application a SPA.
Initially I started following this guide: https://robinverton.de/blog/2018/06/22/django-vue.js-integration-as-a-widget/
Vue-custom-element turned that code into 3 lines and allowed using components like normal (without the data attributes).
This approach seems much better than: https://vsupalov.com/vue-js-in-django-template/ Which doesn’t allow for using a build pipeline for babel, linting, testing, single page components, live reload, modules with import/require, etc.
Targeting your builds for web components might do the same thing: https://cli.vuejs.org/guide/build-targets.html#web-component It says it’s not compatible with IE11, but that might not be a big deal in most situations.
06 May 2020 https://github.com/pawl/django_require_prefetch_select_related_example
I made a repository to try to figure out the best way to require prefetch_related/select_related when fetching a model’s related objects. I also want to figure out a good pattern for avoiding duplicated prefetch_related/select_related for multiple places in a codebase that need the related objects eager loaded in the same way.
29 Apr 2020 Just learned Nginx has WebDAV support: https://nginx.org/en/docs/http/ngx_http_dav_module.html
It’s a lot faster than the Python package I was using: https://github.com/mar10/wsgidav
Wsgidav is great though. It’s super customizable and the documentation is great too.
23 Apr 2020 It would be nice to know a better way to cache the ModelChoiceField’s queryset when it’s used in a form that runs is_valid() in a loop (like Formsets do). The best way I know how at the moment is by not using a ModelChoiceField at all. The solution requires using a ChoiceField, running the query for choices outside of the loop, then passing the choices into the form to override the ChoiceField choices.
Here’s an example:
# See full example: https://github.com/pawl/django_modelchoicefield_caching/blob/master/myapp/views.py#L31-L51
for song in playlist:
form_data = {'title': song["title"], 'artist': song["artist"]}
song_form = forms.SongFormWithModelChoiceField(data=form_data)
song_form.is_valid() # runs a query to get the ModelChoiceField queryset each time
print('ModelChoiceField - query count AFTER validating all songs:',
len(connection.queries)) # 5 queries
# query for choices outside of the loop to prevent unnecessary queries
artist_choices = [(artist.pk, artist.name)
for artist in models.Artist.objects.all()]
for song in playlist:
form_data = {'title': song["title"], 'artist': song["artist"]}
# pass choices into the Form
song_form = forms.SongFormWithChoiceField(
artist_choices=artist_choices,
data=form_data)
song_form.is_valid()
print('ChoiceField w/ choices passed in - query count AFTER validating all songs:',
len(connection.queries)) # 6 queries (only 1 more query!) 23 Apr 2020 Just found a really cool library for using Django’s built-in forms to validate JSON: https://github.com/Sibyx/django_api_forms
I made a small example with it to show how it works with ModelChoiceFields: https://github.com/pawl/django_api_forms_modelchoicefield_example
Seems like a more lightweight version of DRF’s serializers (but only for deserializing and validating) and with a similar API to Django’s built-in forms.
18 Apr 2020 I made a pull request asking to “remove the unused public/index.html” file from django-vue-template: https://github.com/gtalarico/django-vue-template/pull/53
Well, the author responded and it turns out it’s definitely used (by vue magic): https://cli.vuejs.org/guide/html-and-static-assets.html
Oops, definitely should have googled “vue public/index.html” before making that pull request. I made another pull request to add a link about it to the django-vue-template docs: https://github.com/gtalarico/django-vue-template/pull/54