I have had schettino.us hosted at Servermania for 9 years…. it was a good run, but at the end of November 2024 the VPS went offline. They tried to recover the hosting node, but in the end they declared the node dead, and all data lost.
-
-
And that’s a wrap!
It was fun (sometimes) and it was work (sometimes) and it was play (sometimes) but the absolute best part is… it’s over!
I remember (vaguely) back in highschool, 1979, taking Computer Math as an elective. I lasted two days in class, read the entire BASIC book in a week, and was promoted to just going to the lab instead of class. I was coding a space war game on a Commodore PET – I think I may still have the paper tape it is stored on. From that fall on I knew I would be able to actually have a job/career doing something I enjoyed. Very exciting time!My first year of college I was already working part time for a local consulting firm doing some fortran coding. I was introduced to CP/M, and dBaseII, and WordStar, and other amazing things, and pretty much learned more working there for a year than I would in three years in the CS program at UMD.
Went on to get a Masters in CS, and a Software Engineering specialization at George Mason – there I did learn quite a bit, sadly mostly unused in real life. Software engineering isn’t / wasn’t done much in the real world, but the skills did translate. I was able to work in R&D for about 25 years – an excellent if not lucrative area. In the late 90s through early 2000s it became important to pivot to private sector work because tech is definitely tricky to age in (ie, over 40, over 50, over 60) , so I started the transition to what ended up the end game – engineering management, in the SRE/Production Engineering side of things.
It was very energizing managing early career engineers, and working in the cutting edge spaces at Microsoft and later Facebook/Meta. Most of what I knew translated into the latest languages, OSes, buzz words, etc.
Now that I’m out (actually nearly two years ago now) I’m really enjoying doing what I want (within reason!) when I want (within reason.)
-
Munin Monitor Tesla Powerwall/Solar info using local API
Who this is for:
Tesla Solar owners with Powerwalls, with the Powerwall on your local network on a known IP address (ie reserved IP via dhcp), and your munin software also running on your local network
Get Open Weather Map API key (for cloud cover)
Get a free api key if you want to include cloud cover Pct in the graph here
Install Powerwall2PVOutput
See https://github.com/ekul135/Powerwall2PVOutput for install details. You’ll need to copy the code to your Munin plugin directory (/usr/share/munin/plugins) and edit PW_Config.py to have your local powerwall user, password, and local IP address. See this page for info.
Munin Plugin code:
#!/usr/bin/env python3 import time import sys import datetime import requests, json import PW_Helper as hlp import PW_Config as cfg ssn = None if (len(sys.argv) > 1): print('''graph_title Solar performance graph_args -u 4000 -l -4000 -r --allow-shrink --right-axis-label 'battery/clouds pct' --right-axis 0.025:0 graph_vlabel kW graph_category tesla graph_info Solar, grid loads & battery % batterypercent.label Battery Pct batterypercent.info Battery charge in percent batterypercent.colour 000000 batterypercent.draw LINE1 clouds.label Clouds Pct clouds.info Cloud cover percent clouds.colour 808080 clouds.draw LINE1 solar.label Panels solar.info kW from panels solar.colour ffa200 solar.draw AREA houseload.label House houseload.info kW to House houseload.colour 00ffff houseload.draw AREA batterypower.label Battery batterypower.info kW from/to battery (negative charging) batterypower.colour 00ff00 batterypower.draw AREA gridpower.label Grid gridpower.info kW from/to grid (negative export) gridpower.colour ff0000 gridpower.draw AREA sbatterypercent.label scaled battery sbatterypercent.colour 000000 sbatterypercent.draw LINE1 sbatterypercent.cdef batterypercent,40,* sclouds.label scaled clouds sclouds.colour 808080 sclouds.draw LINE1 sclouds.cdef clouds,40,* ''') exit(0) try: url = requests.get("https://api.openweathermap.org/data/2.5/weather?units=imperial&lat=YOUR LAT&lon=-YOU LON&appid=YOUR APP ID") text = url.text weatherdata = json.loads(text) clouds = weatherdata['clouds']['all'] ssn = hlp.getSession(cfg.PowerwallIP, cfg.PowerwallEmail, cfg.PowerwallPassword) pw=hlp.getPowerwallData(cfg.PowerwallIP, ssn) soc=hlp.getPowerwallSOCData(cfg.PowerwallIP, ssn) if (pw!=False and soc!=False): print('solar.value', float(pw['solar']['instant_power'])) print('houseload.value', float(pw['load']['instant_power'])) print('batterypower.value', float(pw['battery']['instant_power'])) print('gridpower.value', float(pw['site']['instant_power'])) print('batterypercent.value', float(soc['percentage'])) print('clouds.value', float(clouds)) except Exception as e: print('exception', e) print('solar.value', '0.0') print('houseload.value', '0.0') print('batterypower.value', '0.0') print('gridpower.value', '0.0') print('batterypercent.value', '0.0') print('clouds.value', clouds)
If all goes well, you’ll get fun graphs to watch, like these:
-
Monitoring Ioniq 5 / Kia EV6 EV SOC
If you happen to have
- A Hyundai Ioniq 5 (or, Kia EV6, change brand below to “kia”)
- An active Bluelink subscription
- Munin monitoring set up somewhere
- A need to monitor everything
- Then this post is for you!
Note!
This is a bit hacky, apologies for not making it better
Prerequisites
Install bluelinky & configure it for your Bluelink & Car info on the box where you run munin
Create script to pull data points using bluelinky – this is the hacky bit. You can poll bluelink some number of times a day – the rate limits are not entirely clear. I’m pulling the cached values, so we’re not waking the car up each time and draining the 12v battery, which also means the data could be stale. Manually refresh via the mybluelink app…
Cron job script: /usr/local/etc/ioniq5.js (change the setting values below to match your info)
const BlueLinky = require("bluelinky");
const client = new BlueLinky({
username: "YOUR USERNAME",
password: "YOUR PASSWORD",
pin: "YOUR PIN",
brand: "hyundai",
vin: "YOUR VIN",
region: 'US', // 'US', 'EU', 'CA'
});
// called when the client logs in successfully
client.on("ready", async () => {
const vehicle = client.getVehicle(vin);
const response = await vehicle.status();
console.log('{"soc": %d, "tvolt": %d}', response.evStatus.batteryStatus, response.battery.batSoc);
});Add to your root crontab
*/10 * * * * node /usr/local/etc/ioniq5.js > /usr/local/etc/ioniq5.json
This polls the cached values 144 times a day – seems to be ok for rate limits at least in the US
The Munin plugin to consume and graph this data – /usr/share/munin/plugins/ioniq5 (and you need to install bluelinky in that folder as well for the cron script above to work correctly.)
#!/usr/bin/env python3 import sys import os import requests, json import subprocess if (len(sys.argv) > 1): print('''graph_title EV SOC graph_args -u 100 -l 0 graph_vlabel battery pct graph_category Ioniq5 graph_info Current SOC for EV batt.label State Of Charge batt.info SOC in percent batt.draw LINE1 tvolt.info soc tvolt.label 12V tvolt.info SOC in percent tvolt.draw LINE1 ''') exit(0) try: f = open('/usr/local/etc/siva.json') result = json.load(f) f.close() # parse & print print('batt.value', float(result['soc'])) print('tvolt.value', float(result['tvolt'])) except Exception as e: print('exception', e) print('batterypercent.value', '0.0')
Symlink that to /etc/munin/plugins/ioniq5 and restart munin services, and you should get graphs like this
-
My God, it's full of stars
A brief note: (1) still alive and (2) working at Facebook is kinda fun, kinda nuts and (3) upgrading Ubuntu to 16.4 LTS in a VPS isn’t a great idea.