I don’t understand all 3 :)
I don’t understand all 3 :)
The web interface is great and easy to use. I liked just dragging and dropping updated files to it, very simple.
I’m not an engineer and I am employed, I do a little scripting for fun. Software developers should learn how to use git but I’m not one :)
I hope they copy the web interface too. I stopped using GitHub for my dumb little projects when Microsoft bought them and I can’t be bothered to learn git. I will gladly host my future projects there if it’s good.
If startx and everything else works fine, my guess is that sddm or whatever login manager you’re using is messed up. Maybe reinstall/reset its configuration files and go from there.
My company banned CCleaner from our computers because they got hacked once and didn’t know about it. Microsoft is guilty of the same negligence with an added twist of corruption and greed! Think they’ll ban all Microsoft software too?
The investors are the ones being grifted upon. Website looks healthy and able to make money, investors buy it or invest money, shitbags that run website get paid.
The spacing looks fine here, I copied and pasted it into Kate and it worked fine, maybe you’re on a phone or something. Here’s a link to my latest version:
DevilsPie is the name of the software I couldn’t remember.
I did a workaround by editing a script I found and don’t understand using xprop, xwininfo, and xdotool. I probably should have mentioned that I’m using X, most of this stuff doesn’t work on Wayland. Here’s my script so far:
#!/bin/bash
xprop -spy -root _NET_ACTIVE_WINDOW | grep --line-buffered -o '0[xX][a-zA-Z0-9]\{7\}' |
while read -r id; do
class="`xprop -id $id WM_CLASS 2> /dev/null | grep TeamViewer`"
if [ -n "$class" ]; then
if xprop -id "$id" | grep -q 'WM_NAME(STRING) = "TeamViewer Authentication"'; then
echo "key Tab
key space
key shift+Tab
key shift+Tab
key Down
key Tab
type {my.username}
key Tab
key ctrl+u"| xdotool -
# wait for the window to be closed
xprop -spy -id $id > /dev/null 2>&1
fi
fi
done
It spits out errors after the window closes because I think it’s trying to get windows properties from the now closed window, but it gets the job done!
Edit: changed the script to be much smaller and not show errors.
Why does the headline say “Crypto” but then snippet says “cryptocurrencies”? Do people not realize these are not the same thing? The inventor of Linux does believe in crypto, that’s why it’s in Linux!
There’s not much to see. I made this cool mollyguard for the power button out of a clear bud capsule. This way nobody flips the switch when I expect it to stay on all the time and I can see the power light through it.
Lemmy is failing to upload my images, so here’s 2 links:
Volcano (excuse the mess, I found I spilled some inside last night and tried to clean it lol)
It’s actually not open on the internet, it’s only on my LAN. I ssh in to access it if I’m out which is rare so it’s very safe. These Tasmota plugs are great because they use Free software firmware (which I updated from the web, not the manufacturer), I trust them a lot more than any other IOT device.
Dude honestly the Volcano rules. I’ve had mine almost 20 years now and I’ve had a screw rattle loose and the plastic airflow button broke ($10 part) and that’s it. I also bought a Crafty+ and I hardly ever use it. The Volcano is definitely smoother and I think hits harder. Plus you can see how heavy your dose is about to be as the bag fills. The power plugs I bought came out to like $10 each I think for a pack of 4.
Ask and ye shall receive! I’m tacking a GPL 3 license to it. The plugs that play a sound after a delay won’t work on Windows because I use fork(), but I don’t use Windows because fuck Windows. It uses mpv to play sounds, but that is easily changed. AMA.
#!/usr/bin/env python
"Control my various tasmota devices. Licensed under GPL v3: https://www.gnu.org/licenses/gpl-3.0.en.html#license-text"
import os
from time import sleep
import urllib.request
from json import loads
from subprocess import Popen
__all__ = ["Tasmota", "TasmotaWarmup", "TasmotaOffFirst", "DEVICENAMES"]
class Tasmota():
"A tasmota device."
def __init__(self, ipaddress: str, name: str=None):
self.ipaddress = ipaddress
self.name = name
def __repr__(self):
return f"<{type(self).__name__} {self.name if self.name else self.ipaddress}>"
def _request(self, cmd: str) -> str:
"make an http request to the device"
return urllib.request.urlopen(f"http://{self.ipaddress}/cm?cmnd={cmd.replace(' ', '%20')}").read()
def on(self) -> bool:
"Turn the device on. return True if successful"
return b"ON" in self._request("Power On")
def off(self) -> bool:
"Turn the device off. return True if successful"
return b"OFF" in self._request("Power Off")
def toggle(self) -> bool:
"Toggle the device power. return True if power is now on, False if it's off"
return b"ON" in self._request("Power Toggle")
def status(self) -> bool:
"return True if the device is on, False if it is off"
return bool(loads(self._request("Status"))["Status"]["Power"])
class TasmotaWarmup(Tasmota):
"Plays a sound when started, plays a sound after a waiting period."
def __init__(self, ipaddress: str, name: str=None, warmup_time: int=None, on_sound: str=None, ready_sound: str=None):
"warmup_time is seconds, on/ready_sound is the path to the audio file to play"
super().__init__(ipaddress, name)
self.warmup_time = warmup_time
self.on_sound = on_sound
self.ready_sound = ready_sound
def _playSound(self, sound: str) -> None:
"play a sound"
Popen(["mpv", "--no-terminal", "--volume=60", sound])
def _beginPowerOnSounds(self) -> None:
"Play a sound when turning on and another sound when ready"
if self.on_sound:
self._playSound(self.on_sound)
if self.warmup_time and self.ready_sound:
if __name__ == "__main__": # using this as a script, fork to background and return terminal
if os.fork() == 0: # wait in the background for the warmup_time
self._sleepAndPlay()
raise SystemExit
else:
Thread(target=self._sleepAndPlay).start()
def _sleepAndPlay(self) -> None:
"The actual sleeping and playing, to be run in a thread if needed."
sleep(self.warmup_time)
if self.status(): # if device is still on
self._playSound(self.ready_sound)
def on(self) -> bool:
"Turn the device on and play sounds"
if super().on():
self._beginPowerOnSounds()
return True
return False
def toggle(self) -> bool:
"toggle the status and play sounds if we're turning it on"
if super().toggle():
self._beginPowerOnSounds()
return True
return False
class TasmotaOffFirst(TasmotaWarmup):
"A Tasmota object that turns the device off first before turning it on"
def _turn_off_before_on(self) -> bool:
"Turn this device off first if it's already on when it's switched on"
if not super().toggle(): # if toggling turned it off
super().on()
return True
def on(self) -> bool:
return self._turn_off_before_on()
class TasmotaAlwaysOn(TasmotaOffFirst):
"This Tasmota class is always on; toggling it will turn it off briefly and then back on"
def toggle(self) -> bool:
"toggle this device off and then back on again"
return self._turn_off_before_on()
DEVICENAMES = {"volcano": TasmotaWarmup("192.168.1.152", "Volcano", 355, "/home/jt/.sounds/hold up hey.ogg",
"/home/jt/.sounds/fill that bag up right now2.flac"),
"towel": TasmotaOffFirst("192.168.1.153", "Towel Warmer", warmup_time=(20*60)+30,
ready_sound="/home/jt/.sounds/yayeah.ogg"),
"radiator": Tasmota("192.168.1.166", "Radiator"),
"taco": TasmotaAlwaysOn("192.168.1.156", "Taco")
}
if __name__ != "__main__":
from threading import Thread # only needed when importing this module
else:
import sys, argparse
parser = argparse.ArgumentParser(description="Control Tasmota wifi power plugs")
parser.add_argument("devices", help="device(s)", action="store", nargs="*")
operation_group = parser.add_mutually_exclusive_group()
operation_group.add_argument('--on', '-n', help="power on device", action="store_true")
operation_group.add_argument('--off', '-f', help="power off device", action="store_true")
operation_group.add_argument('--toggle', '-t', help="toggle device power", action="store_true")
operation_group.add_argument('--status', '-s', help="get status of device", action="store_true")
args = parser.parse_args()
# Sanity checks
if not args.devices:
print(f"No device specified. Available devices are: {' '.join(DEVICENAMES.keys())}", file=sys.stderr)
parser.print_help()
sys.exit(1)
invalid = []
for d in args.devices:
if not DEVICENAMES.get(d):
invalid.append(d)
if invalid:
print(f"Invalid device{'s' if len(invalid) > 1 else ''}: {' '.join(invalid)}", file=sys.stderr)
print(f"Available devices are: {' '.join(DEVICENAMES.keys())}", file=sys.stderr)
sys.exit(3)
for d in args.devices: # gogo
t = DEVICENAMES[d]
if args.on:
if t.on():
print(f"{t.name} turned on")
else:
print(f"Failed to turn on {t.name}", file=sys.stderr)
elif args.off:
if t.off():
print(f"{t.name} turned off")
else:
print(f"Failed to turn off {t.name}", file=sys.stderr)
elif args.toggle:
print(f"{t.name} turned {'on' if t.toggle() else 'off'}")
elif args.status:
print(f"{t.name} is {'on' if t.status() else 'off'}")
I have a volcano and a script I wrote to control it via a tasmota power plug. Now my computer plays a clip of snoop dogg when I turn it on and when it’s fully heated up. And it automatically turns it off at night if I forget to. I can turn it on from anywhere in the world. I think it’s cool, but who cares?
I’m doing my part!
California is a big place.
Look at the top left:
You don’t know what my KDE looks and acts like. I know exactly what your Gnome looks like because it’s not as customizable, they’re all extremely similar.
According to my company, yes: https://thehackernews.com/2018/04/ccleaner-malware-attack.html