I am no longer short on liquid pie. Last week I spotted a marketplace dealer whose price on Gevalia Mocha Latte k-cups was sensible, and today my monthly subscription arrived on schedule and without a surprise cancellation, so I’ve got nearly a three-month supply, with the earliest expiration date in November. I still haven’t seen it in stores, but Corona-chan was bad for variety in a lot of areas, and I think big-chain buyers are still playing it safe.
Usually I limit myself to one of these per day, and with the supply uncertain, sometimes less, but now the only thing holding me back is the calorie count. Which is reasonable (110, with two Mini-Moos), but still adds up during cold* weather.
(* for the California coast)
Continuing with my recent trend of Amazon shipping fails, one of the 36 k-cups in this shipment somehow managed to burst, spilling finely-ground coffee everywhere. Fortunately the boxes were in a sealed outer bag, but I had to open them all up and wipe down every k-cup and froth packet. There was no sign of rough handling, so I’m inclined to believe it was that way before it left the warehouse, and whatever human or robot did the packing didn’t notice or care.
Despite money burning a hole in my pocket, I managed to keep myself to only one new toy, a Nespresso Essenza Mini espresso machine. I worked my way through the supplied variety pack of coffees, and, taken straight, I honestly can’t tell the difference between most of them. Maybe it’s just that they all seem to be darker roasts, but the high-pressure extraction method produces less-distinguishable flavors than my Aeropress.
So far they’ve all responded well to Splenda and Mini-Moos, though, and their “Fortissio Lungo” topped off with whole milk turned out quite nicely. I don’t have a milk frother or steamer, and I don’t plan to buy one any time soon; that just seems like work. I usually only buy milk for cooking and baking, and for the past year I’ve gotten into the habit of buying UHT whole milk in 8-ounce lunch-packs, to avoid supply-chain disruptions while keeping it from going bad on me.
I didn’t have any actual demitasse cups in the house, but a saké ochoko will hold an espresso shot, and the larger thick-walled ceramic guinomi set I picked up cheap at Daiso has room left over for a Moo, and holds the heat nicely.
After having lived with k-cups for a number of years, the biggest surprise with the Nespresso machine is how much, and for how long, liquid drips into its two drip pans afterwards. I’ve never had to empty a k-cup drip pan, only give it a quick rinse when I’m cleaning the kitchen.
Coming back from a trip to the Nob Hill south of town, I was pleasantly surprised to see nearly-completed new construction at the local mall. I hadn’t known that Chik-Fil-A was coming to town, but I’d expected it to happen eventually. The hate-fueled campaign to destroy them backfired big-time, and they’ve greatly expanded their presence in California since then. They’ve been putting in stores north, south, and east of me, so it was only a matter of time before Salinas got one.
Interesting that they skipped Morgan Hill and Gilroy, especially with the big outlet mall, but maybe the timing just lined up better with the construction at my mall.
I’m still idly watching That Spider Show, and episode 7 was the first time I didn’t actively hate the crew of the B Ark. Well, some of them, anyway. For a few minutes.
The 3D printer nozzle that arrived yesterday was for an experiment that I can’t really start yet. I’ve built up a pretty solid Cura profile for the Dremel 3D45 with the standard 0.4mm nozzle, and I thought I’d come to understand its inheritance system, but I just can’t get the damn thing to locate the correct quality profiles when I add variant nozzle sizes into the mix.
It seems to require a config file for each (material, nozzle, quality) tuple, but when I generate them with a script, it can’t find a match, and the log messages are not helpful. The only good thing is that it’s not complaining that they’re corrupt and asking to reset everything to defaults.
It would be significantly less work to just generate a completely separate config for a “3D45-0.8” model printer.
I officially no longer owe AT&T for the DirecTV equipment that I immediately returned after canceling my account. The proof is that they sent me the money I’ve been owed since November. On an $8.79 prepaid Mastercard debit card that I have to figure out a use for.
I’m just going to leave this here:
“…the malicious package is said to leverage the macOS Installer JavaScript API”
I find this approximately as comforting as if they’d said, “the Installer’s PHP-based SQL interface”.
Went through the first pass on my taxes last night, and came out better than expected. That is, the two different employers, large severance check, and stock sales (options, ESPP, RSU) were effectively balanced by the extra amount I had withheld and the amount my new job over-withheld for Social Security, etc, leaving me with my usual close-to-breaking-even little refund checks. I’ll let it bake a week in case some late paperwork or surprise changes arrive, but it looks like the money I carefully saved for potential tax payments goes into my pocket instead. And there’s a semi-annual bonus on the way.
But I’ve already said that I’m not buying a new car this year, or a new computer, or a new camera, no matter how Sony tempts me. Oh, my. Wait, this one has gigabit ethernet?!?
We haven’t finalized the dates on the re-re-re-rescheduled Japan trip, but it’s currently “three weeks in November”, with enough time in Tokyo for me to spend way too much money. Probably not on camera gear, unless I find myself in a shop full of classic Minolta lenses…
Maybe this will be the trip where we take a few overnight trips off the beaten path. I’ve already penciled in a day trip to Kamakura and a whistle-stop tour of Nagoya (mostly for the Totoro House) on the way from Tokyo to Kyoto, but Nikko and Amanohashidate would benefit from full days, and a return visit to Ise would be cool, too. My sister’s not a big fan of cable-car rides, but she might go for an overnight stay at one of the many temples on Mt. Koya.
File under peculiar the fact that the first half of the Solo Leveling light novel is out today in paperback only. No Kindle edition listed at all. I’d have to wait an entire day before I could start reading it. I think I’ll hold off for a week or so to see if the ebook turns up.
Which reminds me to check up on the online comic, which was supposed to start back up this year.
Lacking anything else to watch, I made it most of the way through the first season of How Not To Summon A Demon Lord. The main elf girl has ridiculous gag boobs made of pudding while the main catgirl is pure AAA-cup angst, but most of the other females are somewhere in between, which is refreshing after Highschool DxD.
It’s better than those other fan-service comedies I’ve attempted to watch recently, although Our Demon Lord’s social-anxiety freakouts get old fast. It seems to run at the usual light-novel adaptation pace of four episodes per book, which is too fast if the cast is large and there’s any non-trivial world-building. In this case it only feels slightly rushed and sparse, as if the original author hadn’t gotten around to doing those things yet in the first three books.
Note that the original title is a bit more direct: 異世界魔王と召喚少 女の奴隷魔術 = “other world demon lord and summoning-girl slave magic”. Pretty much what it says on the tin, although the Crunchyroll version restricts itself to pokies and not-quite-sexual climaxes. That said, the flatcat girl did take an offscreen finger in the last episode I watched.
Season 2 coming in April.
When I switched back from PETG to PLA and tried to print the mini traffic cone that was filled with spiders, I still got some spider-webs. Fortunately, I’ve been keeping my WIP Dremel configs in source control, and determined that I’d inadvertently deleted an important option from my top-level definition file:
"infill_before_walls": { "default_value": false }
The default inherited from fdmprinter.def.json
is true, and a cone
is pretty much the worst-case scenario for this, cutting across the
circle from the end position of one layer to the start of the next,
smaller layer. Adding this back eliminated every single bit of
stringing inside the cone.
Tarball
updated. Several times, actually; among other things,
retraction_extra_prime_amount
is something that can’t be overridden
on a per-filament basis. You have to create a whole set of
filament-specific quality overrides, which I generated with a script,
because I’m up to 10 quality settings now. Each one contains a dozen
lines of boilerplate and one actual setting line.
Which reminds me that I’m due for a rant on the fact that Cura uses
three completely different file formats to store configuration
information: XML, JSON, and Python’s ConfigParser (which is
more-or-less Microsoft Windows INI format). Machine and extruder
definitions are in JSON, quality settings and variants (like different
nozzle sizes) are ConfigParser, and filament definitions are in XML.
Some settings are valid in any file, some only in specific ones, and
the only documentation is some help strings in fdmprinter.def.json
.
If there’s any good documentation, it’s not on Ultimaker’s support
site or Github repo wikis.
Then there are settings that I couldn’t find in any file, including some that caused Cura to decide that all my configs had been corrupted and needed to be wiped, after I added or removed things from its directory. I let it do the reset once, to clean out a bunch of cruft; downloading filament profiles from their marketplace was a mistake, and saved custom settings are “messy”, to put it gently. Since then, I’ve kept tarball snapshots as I tinker.
Note that their contribution policy is to only accept new printer definitions from the actual manufacturer, so even if I (or the other guy) produce really awesome config files for the Dremel, they won’t merge a pull request.
RawMouse: enables support for 3DConnexion 3D controllers. I’ve been using mine extensively with PrusaSlicer, and kinda-sorta with OpenSCAD (where it doesn’t work very well). 3d mice are worth every penny, if all your core apps support them. Cura doesn’t, and doesn’t offer a plugin in the marketplace, so this one’s on Github.
Z Offset Setting: tweak the Gcode output up or down to compensate for nozzle height and material differences.
Auto Orientation: try to orient models to reduce the amount of support needed to print them.
Custom Printjob Naming: simple, flexible way to embed useful information in Gcode file names.
Startup Optimizer: hide the cruft (dozens of printers and materials you don’t have) so Cura doesn’t try to load it all.
Setting Visibility Set Creator: lets you override the standard basic/expert/advanced modes to expose only the settings you actually tinker with.
Export HTML Cura Settings: only useful for A/B testing, but really useful for that. This is how I diffed two sets of Dremel configs.
Barbarian Units: most STL files use millimeters as units, but every once in a while some application gives you Love American Style.
With all the testing I’ve been doing, I’m finally running low on the Hatchbox Grey PLA, so I started to order some more, and then remembered that I’ve got five spools of Dremel PLA in assorted colors. I do need some more neutral gray for babydai koma at some point (good contrast against most thread colors), but that’s to make sets for other people; I’ve got mine.
Unless you work with embroidery floss or other fine thread, you won’t have any practical use for this floss bobbin STL file. It is, however, small, flat, and requires only 1.5 grams of filament to print, making it an excellent choice for testing adhesion, elephant’s foot compensation, and top/bottom quality.
The English word raster pretty much only refers to converting vectors to bitmaps (displaying text/graphics on a monitor, etc). The German word raster means “grid”, which leads to some confusion when someone says their 3D model is rasterized. I always interpret it as “has blocky pixels like Minecraft”, but they mean “sized to a specific X/Y/Z grid”.
Does this picture of Mayumi Yamanaka count as Tenga cosplay?
(raise shields and disable javascript before clicking on the picture)
I’ve received email and a text message informing me that DirecTV has finally acknowledged that I returned their equipment over two months ago, and it’s no longer being charged to my account. I won’t really believe it until it shows up on paper, and even then, I doubt they’ll ever send the $8 they owe me.
Instead of incorporating any of the existing methods of fixing their long-standing problem with poor strain relief on cables, Apple patented a new one.
In other DifferentThink news, Apple has declared the word ’Asian’ out of bounds for kid-safe browsing on iPads and iPhones. No, seriously.
It’s a clone of a well-known and much-copied commercial product, but this folding pipe holder is correctly and cleanly adapted to 3D printing. No supports required, and the print-in-place hinge didn’t even require any break-in to work.
(and with the revised acceleration/jerk settings I mentioned yesterday, the actual print time was 99.5% of the slicer’s estimate)
I don’t currently have any fancy filament that would look cool for showing off some of my dad’s pipes, but it was refreshing to see someone do the job right.
Unlike the item I was looking at yesterday that had all kinds of curves and angles and overhangs running in all directions, forcing you to add 50% to the time and materials to support it all. It’s a complete replacement for an injection-molded part, with bits added to partially solve a problem that doesn’t come up that often. It would have been faster and easier to design something that attached to the existing part rather than replacing it, and the result would have been easier to print. Sigh.
(script significantly updated and reformatted)
#!/usr/bin/env python3
"""
Connect to a networked Dremel 3D45 to manage print jobs and query
for job status and printer information.
Commands:
info, status, preheat, print, cancel, pause, resume
"""
import sys
import os
import argparse
import configparser
import datetime
import requests
COMMAND = "http://%s/command"
UPLOAD = "http://%s/print_file_uploads"
WEBCAM = "http://%s:10123/?action=stream"
IPADDR = "192.168.0.1"
def api_cmd(command):
try:
r = requests.post(COMMAND % IPADDR, data=command, timeout=5)
r.raise_for_status()
except requests.exceptions.HTTPError as http_err:
sys.exit("Printer %s (%s): %s" % (PRINTERNAME, IPADDR, http_err))
except Exception as err:
sys.exit("Printer %s (%s) offline or unhappy: %s" % (PRINTERNAME, IPADDR, err))
return r.json()
def api_upload(file, jobname):
try:
gcode = {"print_file": (jobname, open(file, "rb").read())}
except Exception as err:
sys.exit("Printer %s (%s): %s" % (PRINTERNAME, IPADDR, err))
try:
r = requests.post(UPLOAD % IPADDR, files=gcode, timeout=300)
r.raise_for_status()
except HTTPError as http_err:
sys.exit("Printer %s (%s): %s" % (PRINTERNAME, IPADDR, http_err))
except Exception as err:
sys.exit("Printer %s (%s) offline or unhappy: %s" % (PRINTERNAME, IPADDR, err))
return r.json()
parser = argparse.ArgumentParser(
description="Network utility for Dremel 3D45 printers",
formatter_class=argparse.RawTextHelpFormatter,
epilog="""
Requires a file ~/.pydremel containing at least one entry like this:
[default]
name=Autobot
[Autobot]
ip_address=192.168.0.200
(or you can change IPADDR at the top of the script)
* If you print the same filename twice in a row with different
contents, the printer will remember some metadata from the first
job, and calculate completion progress incorrectly.
""",
)
parser.add_argument(
"-p",
"--printer",
default="default",
help="named printer in your .pydremel config file",
)
parser.add_argument(
"-r",
"--raw",
action="store_true",
help="print raw JSON for info or status output",
)
parser.add_argument(
"command",
choices=["info", "status", "preheat", "print", "cancel", "pause", "resume"],
)
parser.add_argument("filename", nargs="?", help="gcode file to be printed")
args = parser.parse_args()
# load printer info from config unless user edited the script
if IPADDR == "192.168.0.1":
config = configparser.RawConfigParser()
config_file = os.path.join(os.path.expanduser("~"), ".pydremel")
try:
config.read(config_file)
except:
sys.exit("No config file ~/.pydremel")
if args.printer == "default":
if config.has_section("default"):
PRINTERNAME = config.get("default", "name")
else:
sys.exit("No default printer in ~/.pydremel")
else:
PRINTERNAME = args.printer
if config.has_section(PRINTERNAME):
IPADDR = config.get(PRINTERNAME, "ip_address")
else:
sys.exit("No IP address for printer %s" % PRINTERNAME)
else:
PRINTERNAME = "3D45"
if args.command == "info":
s = api_cmd("GETPRINTERINFO")
if args.raw:
print(str(s).replace("'", '"'))
else:
print("%s" % s["machine_type"])
print(
"(SN=%s, firmware=%s, API=%s)"
% (s["SN"], s["firmware_version"], s["api_version"])
)
if s["ethernet_connected"] == 1:
print("IP Address %s (wired)" % s["ethernet_ip"])
if s["wifi_connected"] == 1:
print("IP Address %s (wireless)" % s["wifi_ip"])
elif args.command == "status":
# note that 'layer' and 'fanSpeed' do not contain valid data
s = api_cmd("GETPRINTERSTATUS")
if args.raw:
print(str(s).replace("'", '"'))
else:
if s["message"] == "success":
print(
"%.1f%% %s %s\n %s/%s; %d°/%d° (chamber %d°)"
% (
s["progress"],
datetime.timedelta(seconds=s["remaining"]),
s["jobname"],
s["status"],
s["jobstatus"],
s["temperature"],
s["platform_temperature"],
s["chamber_temperature"],
)
)
# 'elaspedtime' (sic) starts counting when the nozzle
# reaches temperature and moves to start printing, and
# stops when jobstatus == 'completed'
if s["totalTime"] > 0 and s["jobstatus"] == "completed":
delta = s["elaspedtime"] - s["totalTime"]
if abs(delta) > s["totalTime"] * 0.01:
print(
" (estimate %s, actual %s%s (%.1f%%))"
% (
datetime.timedelta(seconds=s["totalTime"]),
"+" if delta > 0 else "-",
datetime.timedelta(seconds=abs(delta)),
abs(delta) / s["totalTime"] * 100
)
)
# there's no point in preheating the nozzle, since it will cool
# down by the time the auto-leveling is finished.
elif args.command == "preheat":
s = api_cmd("PLATEHEAT")
if s["message"] == "success":
print("Bed heating to preset temperature (printer will beep twice)")
# jobname passed to printer cannot contain path or space characters
# and must end in '.gcode'
elif args.command == "print":
if not args.filename:
sys.exit("usage: %s print filename.gcode" % sys.argv[0])
filename = args.filename
if not os.path.isfile(filename):
sys.exit("Error: file '%s' not found" % filename)
jobname = os.path.basename(filename).replace(" ", "_")
if os.path.isfile(filename):
s = api_upload(filename, jobname)
if s["message"] == "success":
s = api_cmd("PRINT=%s" % jobname)
if s["message"] == "success":
print("Success! Watch your job print at:")
print(WEBCAM % IPADDR)
else:
sys.exit("Error: couldn't print '%s': %s" % (filename, s["message"]))
# cancel will not take effect until after auto-leveling completes
elif args.command == "cancel":
s = api_cmd("GETJOBSTATUS")
if s["message"] == "success":
jobname = s["jobname"]
if jobname == "":
print("No active job")
else:
s = api_cmd("CANCEL=%s" % jobname)
if s["message"] == "success":
print("Print job %s canceled" % jobname)
else:
print("Cancel failed: %s" % s["message"])
elif args.command == "pause":
s = api_cmd("GETJOBSTATUS")
if s["message"] == "success":
jobname = s["jobname"]
if jobname == "":
print("No active job")
else:
s = api_cmd("PAUSE=%s" % jobname)
if s["message"] == "success":
print("Print job %s paused" % jobname)
else:
print("Pause failed: %s" % s["message"])
elif args.command == "resume":
s = api_cmd("GETJOBSTATUS")
if s["message"] == "success":
jobname = s["jobname"]
if jobname == "":
print("No active job")
else:
s = api_cmd("RESUME=%s" % jobname)
if s["message"] == "success":
print("Print job %s resumed" % jobname)
else:
print("Resume failed: %s" % s["message"])
Dear Dems, either they’re facts or they’re allegations. Calling them “factual allegations” kind of makes Trump’s point that you’re just blowing smoke up our asses.
Pretty sure there’s no tactics involved in opening a beer.
Wow, Japan was really ahead of the curve in getting women into STEM!
Yes, my Kindle recommendations are currently filled with old samurai and ninja books, randomly categorized.
It’s all fun and games until someone beats the weft.
I’ve always suspected Javascript was an Aberration…
Actual headline:
DNA sample optional.
After tinkering with acceleration and jerk settings in both Cura and PrusaSlicer (dropping them to 1000 and 5, respectively), I kicked off a job with an estimated runtime of 22,873 seconds. Actual completion time: 23,478 seconds. 2.6% over is plenty good enough for me, so hopefully it will be pretty consistent from now on.
(the actual before/after print times were almost identical in my testing, so this is just adjusting the slicer to match the actual behavior of the printer; next step: tweaking overall speed up and down, to see if the new estimates are still in the ballpark)
It’s extremely common for “on-the-scene” reports of an event to be false or misleading, and the few surviving serious journalists know this, but the convenient lie will always get more coverage than the pedestrian truth. It must have sickened a CNN “journalist” to print these words about Teh Insurrection:
“Medical examiners did not find signs that the officer sustained any blunt force trauma, so investigators believe that early reports that he was fatally struck by a fire extinguisher are not true.”
Still no word on why Ashli Babbitt was shot dead by a cop.
I made it farther (5 episodes) than I did with Senran Kagura (2/3), only because the fan-service was so overwhelming and badly done that it was funny, particularly the completely out-of-character stripperific ED animation. Unfortunately, that’s not enough to make the show watchable, especially given how annoying Our Hero is. But what really killed it for me was Sailor Goon showing up in episode 6; pick a direction, guys.
They’re really working hard to make Microsoft look like a well-run company with a solid operating system and decent QA. Surprisingly, so is Microsoft.
The masks coming off, and I don’t mean the sneeze-guards people have been forced to wear for most of the past year.
Well, they’re not serial killers. Pretty Sure. Okay, kinda sure. Maybe?
They haven’t completely lost focus on being a professional networking tool, although they sure have buried it under a mountain of irrelevant social-network/data-harvesting/certification bullshit. And they accidentally helped a new job get me last year.
Their efforts to fraudulently extract money from former customers probably aren’t felonious. If only because they have really good contract lawyers.
They’re not all career criminals. I mean, there’s Tulsi Gabbard, who I disagree with on almost every issue but am willing to trust when it counts because she actually likes America.
And, um, give me a minute, I’m sure I’ll think of another one.
Corona-chan apparently took down the local Pizza Hut a few weeks ago. Permanently? Still showed as closed on Friday night at dinnertime. If I wanted good pizza I’d make it myself, but first I’d have to go buy pepperoni and cheese. I tend to order from PH if I don’t want to go out, because it’s better than Domino’s, half the price of Round Table, and won’t make me sick like Mountain Mike’s does.
The local chain haircut joint was shut down by the governor (again) at the beginning of December, and despite him opening things back up a little in a likely-futile effort to stop the petition to shitcan his l’il-dictator ass, they haven’t reopened yet. It looks like their location in Seaside is back online, and I know the folks from the Salinas shop were working shifts over there, so maybe I’ll make the 20-mile drive today or tomorrow.
Episode 4 of That Spider Show was a bit more interesting, because it
didn’t advance the B ArkArc.
(spider is unrelated)
I haven’t found anything else worth watching for days. Last thing I managed to make it through was Matt Smith’s final arc in Doctor Who.