aStonedSanta,

Discord was the better community imo. The Frank tank. I’d love to see something flourish here!

Today,

I couldn’t get into discord because it seemed like you had to wade through pages of crap and jokes to get to real info. Maybe I’m doing it wrong?

aStonedSanta,

That’s accurate and fair tbh.

just_vapours,

I also don’t get unwell with discord.

I have nothing against it, but the user interface just doesn’t work well with my psyche.

jadedwench,

I am still in love with my Mighty+. You can get a Titanium mouth piece that is pretty sweet, but the rubber to keep it from falling out is garbage. I wrapped a little bit of gaffers tape around it, and that works much better. Otherwise, I use the plastic one.

I am not the type to buy large collections of dry herb vapes, but ever since my state went legal, the bud must flow. 😁

Kroxx,

For sure the best session portable vape currently, the Venty might be better? I don’t own one and I probably won’t because I like my TM2, but I have heard good things about it. I wouldn’t buy it till the venty+ model releases if they do that because the venty does have some kinks currently.

jadedwench,

Yeah, I don’t have any reason to switch either. It is so stoner friendly with the little vibration reminder, USB-C PD, and you can use it plugged in if you were dumb and never charged it. I am a simple woman. I do complicated shit all day at work, so the little things that should be simple can really matter to me.

Kroxx,

Yes to both lol, the cult is toxic af but on Lemmy I think it’d be great! I’ve spent a frankly embarrassing amount on cult bud so I could contribute a shit ton to a cult community if we had one. I also try to keep up on the news for them and there would be 0 shilling here probably.

On to the vaporents side, I have a mighty+, (sadly collecting dust, I need to sell it so it gets used, great unit), a tinymight2, and I just pre-order the vapvana screwball that I am super excited for. So I could also make some OC content for that side but not nearly as much as a cult sub. Like you said that one’s dead currently and I don’t buy vapes like bud.

I suppose for now we could just do all of this on trees? I thought about it but I think long term it may be better to start these communities? Not sure TBH but I would love to see em both!

Shareni,

So start posting to vaporents instead of trying to make the 5th community on the same topic just because nobody posted in 3 months?

JTskulk,

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?

sorrybookbroke,

That is wild, now I want a volcano. I’m more into handhelds and love my crafty+ but that’s wild enough to make me think about buying one

JTskulk,

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.

liam070,

I think it’s cool, but who cares?

We do! Please open-source it, king of stoner engineering!

(I use the Plenty from time to time, but it kinda sucks)

JTskulk,

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.


<span style="color:#323232;">#!/usr/bin/env python
</span><span style="color:#323232;">"Control my various tasmota devices. Licensed under GPL v3: https://www.gnu.org/licenses/gpl-3.0.en.html#license-text"
</span><span style="color:#323232;">
</span><span style="color:#323232;">import os
</span><span style="color:#323232;">from time import sleep
</span><span style="color:#323232;">import urllib.request
</span><span style="color:#323232;">from json import loads
</span><span style="color:#323232;">from subprocess import Popen
</span><span style="color:#323232;">
</span><span style="color:#323232;">__all__ = ["Tasmota", "TasmotaWarmup", "TasmotaOffFirst", "DEVICENAMES"]
</span><span style="color:#323232;">
</span><span style="color:#323232;">class Tasmota():
</span><span style="color:#323232;">    "A tasmota device."
</span><span style="color:#323232;">    def __init__(self, ipaddress: str, name: str=None):
</span><span style="color:#323232;">        self.ipaddress = ipaddress
</span><span style="color:#323232;">        self.name = name
</span><span style="color:#323232;">
</span><span style="color:#323232;">    def __repr__(self):
</span><span style="color:#323232;">        return f"<{type(self).__name__} {self.name if self.name else self.ipaddress}>"
</span><span style="color:#323232;">
</span><span style="color:#323232;">    def _request(self, cmd: str) -> str:
</span><span style="color:#323232;">        "make an http request to the device"
</span><span style="color:#323232;">        return urllib.request.urlopen(f"http://{self.ipaddress}/cm?cmnd={cmd.replace(' ', '%20')}").read()
</span><span style="color:#323232;">
</span><span style="color:#323232;">    def on(self) -> bool:
</span><span style="color:#323232;">        "Turn the device on. return True if successful"
</span><span style="color:#323232;">        return b"ON" in self._request("Power On")
</span><span style="color:#323232;">
</span><span style="color:#323232;">    def off(self) -> bool:
</span><span style="color:#323232;">        "Turn the device off. return True if successful"
</span><span style="color:#323232;">        return b"OFF" in self._request("Power Off")
</span><span style="color:#323232;">
</span><span style="color:#323232;">    def toggle(self) -> bool:
</span><span style="color:#323232;">        "Toggle the device power. return True if power is now on, False if it's off"
</span><span style="color:#323232;">        return b"ON" in self._request("Power Toggle")
</span><span style="color:#323232;">
</span><span style="color:#323232;">    def status(self) -> bool:
</span><span style="color:#323232;">        "return True if the device is on, False if it is off"
</span><span style="color:#323232;">        return bool(loads(self._request("Status"))["Status"]["Power"])
</span><span style="color:#323232;">
</span><span style="color:#323232;">class TasmotaWarmup(Tasmota):
</span><span style="color:#323232;">    "Plays a sound when started, plays a sound after a waiting period."
</span><span style="color:#323232;">    def __init__(self, ipaddress: str, name: str=None, warmup_time: int=None, on_sound: str=None, ready_sound: str=None):
</span><span style="color:#323232;">        "warmup_time is seconds, on/ready_sound is the path to the audio file to play"
</span><span style="color:#323232;">        super().__init__(ipaddress, name)
</span><span style="color:#323232;">        self.warmup_time = warmup_time
</span><span style="color:#323232;">        self.on_sound = on_sound
</span><span style="color:#323232;">        self.ready_sound = ready_sound
</span><span style="color:#323232;">
</span><span style="color:#323232;">    def _playSound(self, sound: str) -> None:
</span><span style="color:#323232;">        "play a sound"
</span><span style="color:#323232;">        Popen(["mpv", "--no-terminal", "--volume=60", sound])
</span><span style="color:#323232;">
</span><span style="color:#323232;">    def _beginPowerOnSounds(self) -> None:
</span><span style="color:#323232;">        "Play a sound when turning on and another sound when ready"
</span><span style="color:#323232;">        if self.on_sound:
</span><span style="color:#323232;">                self._playSound(self.on_sound)
</span><span style="color:#323232;">        if self.warmup_time and self.ready_sound:
</span><span style="color:#323232;">            if __name__ == "__main__": # using this as a script, fork to background and return terminal
</span><span style="color:#323232;">                if os.fork() == 0: # wait in the background for the warmup_time
</span><span style="color:#323232;">                    self._sleepAndPlay()
</span><span style="color:#323232;">                    raise SystemExit
</span><span style="color:#323232;">            else:
</span><span style="color:#323232;">                Thread(target=self._sleepAndPlay).start()
</span><span style="color:#323232;">
</span><span style="color:#323232;">    def _sleepAndPlay(self) -> None:
</span><span style="color:#323232;">        "The actual sleeping and playing, to be run in a thread if needed."
</span><span style="color:#323232;">        sleep(self.warmup_time)
</span><span style="color:#323232;">        if self.status(): # if device is still on
</span><span style="color:#323232;">            self._playSound(self.ready_sound)
</span><span style="color:#323232;">
</span><span style="color:#323232;">    def on(self) -> bool:
</span><span style="color:#323232;">        "Turn the device on and play sounds"
</span><span style="color:#323232;">        if super().on():
</span><span style="color:#323232;">            self._beginPowerOnSounds()
</span><span style="color:#323232;">            return True
</span><span style="color:#323232;">        return False
</span><span style="color:#323232;">
</span><span style="color:#323232;">    def toggle(self) -> bool:
</span><span style="color:#323232;">        "toggle the status and play sounds if we're turning it on"
</span><span style="color:#323232;">        if super().toggle():
</span><span style="color:#323232;">            self._beginPowerOnSounds()
</span><span style="color:#323232;">            return True
</span><span style="color:#323232;">        return False
</span><span style="color:#323232;">
</span><span style="color:#323232;">class TasmotaOffFirst(TasmotaWarmup):
</span><span style="color:#323232;">    "A Tasmota object that turns the device off first before turning it on"
</span><span style="color:#323232;">    def _turn_off_before_on(self) -> bool:
</span><span style="color:#323232;">        "Turn this device off first if it's already on when it's switched on"
</span><span style="color:#323232;">        if not super().toggle(): # if toggling turned it off
</span><span style="color:#323232;">            super().on()
</span><span style="color:#323232;">        return True
</span><span style="color:#323232;">
</span><span style="color:#323232;">    def on(self) -> bool:
</span><span style="color:#323232;">        return self._turn_off_before_on()
</span><span style="color:#323232;">
</span><span style="color:#323232;">class TasmotaAlwaysOn(TasmotaOffFirst):
</span><span style="color:#323232;">    "This Tasmota class is always on; toggling it will turn it off briefly and then back on"
</span><span style="color:#323232;">    def toggle(self) -> bool:
</span><span style="color:#323232;">        "toggle this device off and then back on again"
</span><span style="color:#323232;">        return self._turn_off_before_on()
</span><span style="color:#323232;">
</span><span style="color:#323232;">DEVICENAMES = {"volcano": TasmotaWarmup("192.168.1.152", "Volcano", 355, "/home/jt/.sounds/hold up hey.ogg",
</span><span style="color:#323232;">                                        "/home/jt/.sounds/fill that bag up right now2.flac"),
</span><span style="color:#323232;">                   "towel": TasmotaOffFirst("192.168.1.153", "Towel Warmer", warmup_time=(20*60)+30,
</span><span style="color:#323232;">                                            ready_sound="/home/jt/.sounds/yayeah.ogg"),
</span><span style="color:#323232;">                   "radiator": Tasmota("192.168.1.166", "Radiator"),
</span><span style="color:#323232;">                   "taco": TasmotaAlwaysOn("192.168.1.156", "Taco")
</span><span style="color:#323232;">                   }
</span><span style="color:#323232;">
</span><span style="color:#323232;">if __name__ != "__main__":
</span><span style="color:#323232;">    from threading import Thread # only needed when importing this module
</span><span style="color:#323232;">else:
</span><span style="color:#323232;">    import sys, argparse
</span><span style="color:#323232;">    parser = argparse.ArgumentParser(description="Control Tasmota wifi power plugs")
</span><span style="color:#323232;">    parser.add_argument("devices", help="device(s)", action="store", nargs="*")
</span><span style="color:#323232;">    operation_group = parser.add_mutually_exclusive_group()
</span><span style="color:#323232;">    operation_group.add_argument('--on', '-n', help="power on device", action="store_true")
</span><span style="color:#323232;">    operation_group.add_argument('--off', '-f', help="power off device", action="store_true")
</span><span style="color:#323232;">    operation_group.add_argument('--toggle', '-t', help="toggle device power", action="store_true")
</span><span style="color:#323232;">    operation_group.add_argument('--status', '-s', help="get status of device", action="store_true")
</span><span style="color:#323232;">    args = parser.parse_args()
</span><span style="color:#323232;">
</span><span style="color:#323232;">    # Sanity checks
</span><span style="color:#323232;">    if not args.devices:
</span><span style="color:#323232;">        print(f"No device specified. Available devices are: {' '.join(DEVICENAMES.keys())}", file=sys.stderr)
</span><span style="color:#323232;">        parser.print_help()
</span><span style="color:#323232;">        sys.exit(1)
</span><span style="color:#323232;">    invalid = []
</span><span style="color:#323232;">    for d in args.devices:
</span><span style="color:#323232;">        if not DEVICENAMES.get(d):
</span><span style="color:#323232;">            invalid.append(d)
</span><span style="color:#323232;">    if invalid:
</span><span style="color:#323232;">        print(f"Invalid device{'s' if len(invalid) > 1 else ''}: {' '.join(invalid)}", file=sys.stderr)
</span><span style="color:#323232;">        print(f"Available devices are: {' '.join(DEVICENAMES.keys())}", file=sys.stderr)
</span><span style="color:#323232;">        sys.exit(3)
</span><span style="color:#323232;">    for d in args.devices: # gogo
</span><span style="color:#323232;">        t = DEVICENAMES[d]
</span><span style="color:#323232;">        if args.on:
</span><span style="color:#323232;">            if t.on():
</span><span style="color:#323232;">                print(f"{t.name} turned on")
</span><span style="color:#323232;">            else:
</span><span style="color:#323232;">                print(f"Failed to turn on {t.name}", file=sys.stderr)
</span><span style="color:#323232;">        elif args.off:
</span><span style="color:#323232;">            if t.off():
</span><span style="color:#323232;">                print(f"{t.name} turned off")
</span><span style="color:#323232;">            else:
</span><span style="color:#323232;">                print(f"Failed to turn off {t.name}", file=sys.stderr)
</span><span style="color:#323232;">        elif args.toggle:
</span><span style="color:#323232;">            print(f"{t.name} turned {'on' if t.toggle() else 'off'}")
</span><span style="color:#323232;">        elif args.status:
</span><span style="color:#323232;">            print(f"{t.name} is {'on' if t.status() else 'off'}")
</span>
liam070,
Today,

That’s crazy cool! Wouldn’t mind seeing a pic or video.

JTskulk,

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)

My dinky menu I use for it sometimes

Shareni,

I can turn it on from anywhere in the world. I think it’s cool, but who cares?

Inb4 burglars care because it can be used to track when you’re at home and when you’re away on a holiday

I know the chances are far lower for custom stuff when compared to cheap IP cameras, but having anything open to the internet should leave you extra paranoid.

JTskulk,

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.

crawancon,

deleted_by_author

  • Loading...
  • Today,

    I can’t do discord and i don’t want to do r/. Have you bought anything good lately? I do the hoku subscription, but I have a pile of packages that I haven’t even opened. I got a few things from eight horses recently and I’ve been getting the disposable vapes from secret nature.

    Jake_Farm,
    @Jake_Farm@sopuli.xyz avatar

    I got some altcan edibles from vivimu and they seem to work pretty good. They shipped it right to me even though I live in a grey area law wise.

    Today,

    I got some gummies from secret nature last week. They’re pretty good. I had a coupon so it was $20 for 5 - 20mg gummies.

    I’m in Texas and have never had an issue with shipments. A few years ago i bought 5# of cbd/cbg flower and it showed up in trash bags inside two big boxes on my porch.

    Today,

    I bought some thcv isolate from vivimu last year. I didn’t know if they were reputable or scammy, but my order went fine.

    Jake_Farm,
    @Jake_Farm@sopuli.xyz avatar

    What are the Old old cult and Franklin?

    Today,

    The thca subs from r/. 40% reviews and sales and 60% shit talking.

    Kroxx,

    Damn accurate description

  • All
  • Subscribed
  • Moderated
  • Favorites
  • trees@lemmy.world
  • tacticalgear
  • thenastyranch
  • ethstaker
  • everett
  • Durango
  • rosin
  • InstantRegret
  • DreamBathrooms
  • magazineikmin
  • Youngstown
  • mdbf
  • slotface
  • GTA5RPClips
  • kavyap
  • megavids
  • modclub
  • cisconetworking
  • cubers
  • ngwrru68w68
  • khanakhh
  • tester
  • anitta
  • normalnudes
  • Leos
  • osvaldo12
  • provamag3
  • JUstTest
  • lostlight
  • All magazines