thresholdfloor 0.3.2__tar.gz → 0.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {thresholdfloor-0.3.2/src/thresholdfloor.egg-info → thresholdfloor-0.3.4}/PKG-INFO +1 -1
  2. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/pyproject.toml +1 -1
  3. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/floor_sigil.py +235 -52
  4. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/threshold_floor.py +70 -10
  5. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4/src/thresholdfloor.egg-info}/PKG-INFO +1 -1
  6. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/LICENSE +0 -0
  7. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/MANIFEST.in +0 -0
  8. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/README.md +0 -0
  9. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/setup.cfg +0 -0
  10. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/__init__.py +0 -0
  11. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/aether_thresher.py +0 -0
  12. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/assets_bundle.pkl +0 -0
  13. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/bundle.py +0 -0
  14. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/elevation.py +0 -0
  15. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/shadow_calibration.py +0 -0
  16. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/shadow_simulation.py +0 -0
  17. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/tests/__init__.py +0 -0
  18. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/tests/test_geometric.py +0 -0
  19. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/tests/test_solar.py +0 -0
  20. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor/tests/test_threshold.py +0 -0
  21. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor.egg-info/SOURCES.txt +0 -0
  22. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor.egg-info/dependency_links.txt +0 -0
  23. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor.egg-info/requires.txt +0 -0
  24. {thresholdfloor-0.3.2 → thresholdfloor-0.3.4}/src/thresholdfloor.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: thresholdfloor
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: A floor below for tuning to what's above
5
5
  Author: WitchMithras
6
6
  License: Proprietary (staging)
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "thresholdfloor"
7
- version = "0.3.2"
7
+ version = "0.3.4"
8
8
  description = "A floor below for tuning to what's above"
9
9
  requires-python = ">=3.11"
10
10
  dependencies = [
@@ -17,11 +17,63 @@ try:
17
17
  except Exception:
18
18
  pass
19
19
  try:
20
- from PIL import Image, ImageChops, ImageOps, ImageFilter, ImageDraw, ImageFont, ImageTk, ImageEnhance
20
+ from PIL import Image, ImageOps, ImageChops, ImageOps, ImageFilter, ImageDraw, ImageFont, ImageTk, ImageEnhance, ImageColor
21
21
  PIL_EXISTS = True
22
22
  except Exception:
23
23
  pass
24
24
 
25
+ DEFAULT_OUTER_RING_COLOR = (180, 150, 255, 180)
26
+ PHASE_COLOR_RGBA = {
27
+ "black": (0, 0, 0, 90),
28
+ "white": (170, 170, 170, 170),
29
+ "yellow-gold": (170, 100, 40, 90),
30
+ "crimson-red": (190, 12, 20, 90),
31
+ }
32
+
33
+
34
+ def _coerce_ring_color(color, default=DEFAULT_OUTER_RING_COLOR):
35
+ if isinstance(color, str):
36
+ keyed = color.strip().lower().replace("_", "-").replace(" ", "-")
37
+ if keyed in PHASE_COLOR_RGBA:
38
+ return PHASE_COLOR_RGBA[keyed]
39
+
40
+ image_color = globals().get("ImageColor")
41
+ if image_color is not None:
42
+ try:
43
+ r, g, b = image_color.getrgb(color)
44
+ return (r, g, b, default[3])
45
+ except ValueError:
46
+ return default
47
+
48
+ if isinstance(color, (tuple, list)) and len(color) in (3, 4):
49
+ values = tuple(int(c) for c in color)
50
+ if len(values) == 3:
51
+ return (*values, default[3])
52
+ return values
53
+
54
+ return default
55
+
56
+
57
+ def _phase_outer_ring_color(floor, default=DEFAULT_OUTER_RING_COLOR):
58
+ phase = getattr(floor, "current_phase", None)
59
+ if not phase and hasattr(floor, "get_phase"):
60
+ try:
61
+ phase = floor.get_phase()
62
+ except Exception:
63
+ phase = None
64
+
65
+ if not phase:
66
+ return default
67
+
68
+ COLORS = {
69
+ "Nigredo": "black",
70
+ "Albedo": "white",
71
+ "Citrinitas": "yellow-gold",
72
+ "Rubedo": "crimson-red",
73
+ }
74
+
75
+ return _coerce_ring_color(COLORS.get(phase), default)
76
+
25
77
  SIGNS = {
26
78
  '♈': 'Aries',
27
79
  '♉': 'Taurus',
@@ -151,7 +203,6 @@ sprite_lookup = {
151
203
  }
152
204
 
153
205
  def overlay_shadow_tree(base_img, rune, cx, cy, azimuth, altitude, size=64):
154
- from PIL import Image, ImageEnhance, ImageFilter, ImageOps
155
206
  import math
156
207
  #cx, cy = cx + size, cy + size
157
208
  sprite_key = sprite_lookup.get(rune)
@@ -285,6 +336,8 @@ def overlay_tree_sprite(base_img, rune, position=None, size=48):
285
336
  else:
286
337
  return base_img
287
338
 
339
+ sprite = ImageEnhance.Brightness(sprite).enhance(0.6)
340
+
288
341
  sprite = sprite.resize((size, size), Image.LANCZOS)
289
342
  if position is None:
290
343
  x = base_img.width - size - 10
@@ -396,7 +449,10 @@ def _draw_sigil_glyphs(img, floor, font, cx, cy, r, observed_at):
396
449
  #color = tuple(int(c * 0.4) for c in COLOR_PALLET.get(sign, (200, 200, 255, 240)))
397
450
 
398
451
  # All bright
399
- color = COLOR_PALLET.get(sign, (200, 200, 255, 240))
452
+ #color = COLOR_PALLET.get(sign, (200, 200, 255, 240))
453
+
454
+ # All dark
455
+ color = tuple(int(c * 0.4) for c in COLOR_PALLET.get(sign, (200, 200, 255, 240)))
400
456
 
401
457
  glyph_img = Image.new("RGBA", (64, 64), (0, 0, 0, 0))
402
458
  glyph_draw = ImageDraw.Draw(glyph_img)
@@ -442,6 +498,75 @@ def _draw_sigil_shadow(img, cx, cy, alt, az, size=82):
442
498
  )
443
499
  return img
444
500
 
501
+ def _polar(cx, cy, radius, angle_deg):
502
+ theta = math.radians(angle_deg)
503
+ return (
504
+ cx + radius * -math.sin(theta),
505
+ cy + radius * math.cos(theta),
506
+ )
507
+
508
+
509
+ def _draw_sigil_ticks(img, cx, cy, r, every=5, major_every=30):
510
+ draw = ImageDraw.Draw(img)
511
+
512
+ outer = r * 1.33
513
+ minor_len = r * 0.025
514
+ major_len = r * 0.055
515
+
516
+ for deg in range(0, 360, every):
517
+ is_major = deg % major_every == 0
518
+ length = major_len if is_major else minor_len
519
+ width = 2 if is_major else 1
520
+
521
+ x1, y1 = _polar(cx, cy, outer - length, deg)
522
+ x2, y2 = _polar(cx, cy, outer, deg)
523
+
524
+ draw.line(
525
+ (x1, y1, x2, y2),
526
+ fill=(150, 115, 70, 150),
527
+ width=width,
528
+ )
529
+
530
+ return img
531
+
532
+
533
+ def _draw_diamond(img, cx, cy, radius, angle_deg, scale=4, fill=(210, 165, 90, 210)):
534
+ draw = ImageDraw.Draw(img)
535
+ x, y = _polar(cx, cy, radius, angle_deg)
536
+
537
+ pts = [
538
+ (x, y - scale),
539
+ (x + scale, y),
540
+ (x, y + scale),
541
+ (x - scale, y),
542
+ ]
543
+
544
+ draw.line(pts + [pts[0]], fill=fill, width=1)
545
+ return img
546
+
547
+
548
+ def _draw_motto_brackets(img, cx, cy, r):
549
+ ornament_r = r * 0.84
550
+
551
+ # Bracket ornaments around TEMPUS FUGIT
552
+ _draw_diamond(img, cx, cy, ornament_r, 38, scale=3)
553
+ _draw_diamond(img, cx, cy, ornament_r, 52, scale=3)
554
+
555
+ # Bracket ornaments around FESTINA LENTE
556
+ _draw_diamond(img, cx, cy, ornament_r, 310, scale=3)
557
+ _draw_diamond(img, cx, cy, ornament_r, 320, scale=3)
558
+
559
+ # Small keel mark at bottom center
560
+ _draw_diamond(img, cx, cy, ornament_r, 0, scale=4)
561
+
562
+ return img
563
+
564
+
565
+ def _draw_sigil_ornaments(img, cx, cy, size, r):
566
+ _draw_sigil_ticks(img, cx, cy, r)
567
+ _draw_motto_brackets(img, cx, cy, r)
568
+ return img
569
+
445
570
  def _draw_curved_text(
446
571
  img,
447
572
  cx,
@@ -531,11 +656,14 @@ def _draw_curved_text(
531
656
 
532
657
  # Your current setup seems to like this orientation.
533
658
  # If letters face inward/upside-down, set rotation_offset=180.
659
+
534
660
  glyph = glyph.rotate(
535
661
  -angle_deg + rotation_offset,
536
662
  resample=Image.BICUBIC,
537
663
  expand=True,
538
664
  )
665
+ #if reverse:
666
+ #glyph = ImageOps.mirror(glyph)
539
667
 
540
668
  ww, hh = glyph.size
541
669
  img.alpha_composite(glyph, (int(x - ww / 2), int(y - hh / 2)))
@@ -547,8 +675,11 @@ def _draw_sigil_inscribe(img, cx, cy, size, r):
547
675
  motto_font = _load_motto_font(max(8, int(size * 12 / 400)))
548
676
  motto_r = r * 0.72
549
677
  tracking_deg=1.8
550
- latin_take = "FESTINA LENTE"
551
- latin_late = "SERIUS EST"
678
+ latin_take = "LENTE"
679
+ latin_late = "FESTINA"
680
+ #latin_take = "FESTINA LENTE"
681
+ #latin_late = "TEMPUS FUGIT"
682
+ #latin_late = "SERIUS EST"
552
683
  # Bottom-right-ish
553
684
  _draw_curved_text(
554
685
  img,
@@ -563,6 +694,7 @@ def _draw_sigil_inscribe(img, cx, cy, size, r):
563
694
  stroke_fill=(20, 15, 10, 210),
564
695
  reverse=True,
565
696
  tracking_deg=tracking_deg,
697
+ rotation_offset=0
566
698
  )
567
699
  # Southwest
568
700
  _draw_curved_text(
@@ -578,6 +710,7 @@ def _draw_sigil_inscribe(img, cx, cy, size, r):
578
710
  stroke_fill=(20, 15, 10, 210),
579
711
  reverse=True,
580
712
  tracking_deg=tracking_deg,
713
+ rotation_offset=0
581
714
  )
582
715
 
583
716
  return img
@@ -586,21 +719,111 @@ def _draw_sigil_inscribe(img, cx, cy, size, r):
586
719
  print(e)
587
720
  return img
588
721
 
722
+ def _draw_vestal_ring(
723
+ img,
724
+ cx,
725
+ cy,
726
+ phase,
727
+ waxing=True,
728
+ r=100,
729
+ color=(180, 150, 255, 180),
730
+ width=3,
731
+ ):
732
+ """
733
+ Draw a lunar phase ring.
734
+
735
+ phase:
736
+ 0.0 = new moon
737
+ 1.0 = full moon
738
+
739
+ waxing:
740
+ True = right-side illumination
741
+ False = left-side illumination
742
+ """
743
+
744
+ draw = ImageDraw.Draw(img)
745
+
746
+ # Convert phase into angular sweep.
747
+ sweep = max(0.0, min(1.0, phase)) * 180.0
589
748
 
590
- def _render_clock_sigil_frame(floor, observed_at, size=512):
749
+ if waxing:
750
+ # Right side grows upward/downward from south.
751
+ start = 0 - sweep
752
+ end = 0 + sweep
753
+
754
+ else:
755
+ # Left side.
756
+ start = 180 - sweep
757
+ end = 180 + sweep
758
+
759
+ bbox = (
760
+ cx - r,
761
+ cy - r,
762
+ cx + r,
763
+ cy + r,
764
+ )
765
+
766
+ draw.arc(
767
+ bbox,
768
+ start=start,
769
+ end=end,
770
+ fill=color,
771
+ width=width,
772
+ )
773
+
774
+ return img
775
+
776
+ def _render_clock_sigil_frame(floor, observed_at, size=512, ornaments=True, inscription=True, glyph=True, tree=True, shadow=True, vestal=False):
591
777
  try:
592
778
  img = _draw_sigil_background(size)
593
779
  cx, cy = size // 2, size // 2
594
780
  tree_size = max(1, int(size * (82 / 400)))
595
- _draw_sigil_tree_axis(img, cx, cy, size=tree_size)
596
781
  font = _load_sigil_font(max(1, int(size * (36 / 400))))
597
782
  r = int((size // 2) * 0.75)
598
- alt, az = _draw_sigil_glyphs(img, floor, font, cx, cy, r, observed_at)
599
783
 
600
- _draw_sigil_shadow(img, cx, cy, alt, az, size=tree_size)
601
-
602
- _draw_sigil_inscribe(img, cx, cy, size=size, r=r)
784
+ alt, az = _draw_sigil_glyphs(img, floor, font, cx, cy, r, observed_at)
785
+ if shadow:
786
+ _draw_sigil_shadow(img, cx, cy, alt, az, size=tree_size)
787
+ if tree:
788
+ _draw_sigil_tree_axis(img, cx, cy, size=tree_size)
789
+
790
+ if ornaments:
791
+ _draw_sigil_ornaments(img, cx, cy, size, r)
792
+ if inscription:
793
+ _draw_sigil_inscribe(img, cx, cy, size=size, r=r)
794
+ if vestal:
795
+ mt = floor.now_mt()
796
+ def infer_waxing() -> bool | None:
797
+ phase = getattr(mt, "moon_phase", None) or ""
798
+ p = str(phase).lower()
799
+ if p.startswith("wax"):
800
+ return True
801
+ if p.startswith("wan"):
802
+ return False
803
+ if "first quarter" in p:
804
+ return True
805
+ if "last quarter" in p:
806
+ return False
807
+ return None
808
+
809
+ waxing = infer_waxing()
810
+ illum_raw = mt.moon_illum / 100
811
+
812
+ if illum_raw > 100:
813
+ illum = illum_raw / 1000.0
814
+ else:
815
+ illum = illum_raw / 100.0
816
+ moon_phase_fraction = max(0.0, min(1.0, float(illum)))
603
817
 
818
+ _draw_vestal_ring(
819
+ img,
820
+ cx,
821
+ cy,
822
+ r=r * 1.15,
823
+ color=_phase_outer_ring_color(floor),
824
+ phase=moon_phase_fraction,
825
+ waxing=waxing
826
+ )
604
827
 
605
828
  return img
606
829
  except Exception as e:
@@ -734,47 +957,7 @@ def tf_sigil(floor, size=400):
734
957
 
735
958
  img.paste(glyph_img, (int(px), int(py)), glyph_img)
736
959
  lon += 30
737
- # 🌙 Add Latin mottos inside the zodiac band
738
- # 🌙 Big readable Latin mottos inside the zodiac band
739
- try:
740
- motto_font = _load_motto_font(max(14, int(size * 28 / 400)))
741
- motto_r = r * 0.67
742
- latin_take = "ACCIPE TEMPUS TUUM"
743
- latin_late = "SERIUS EST QUAM COGITAS"
744
-
745
- def _draw_motto(text, angle_deg):
746
- theta_m = math.radians(angle_deg)
747
-
748
- mx = cx + motto_r * -math.sin(theta_m)
749
- my = cy + motto_r * math.cos(theta_m)
750
-
751
- bb = motto_font.getbbox(text)
752
- mw, mh = bb[2] - bb[0], bb[3] - bb[1]
753
-
754
- # Simple shadow stroke so blind little society gremlins can see it
755
- for ox, oy in [(-2, 0), (2, 0), (0, -2), (0, 2)]:
756
- draw.text(
757
- (mx - mw / 2 + ox, my - mh / 2 + oy),
758
- text,
759
- font=motto_font,
760
- fill=(20, 15, 10, 230),
761
- )
762
-
763
- draw.text(
764
- (mx - mw / 2, my - mh / 2),
765
- text,
766
- font=motto_font,
767
- fill=(235, 205, 150, 255),
768
- )
769
-
770
- # Bottom-right-ish: Take your time
771
- _draw_motto(latin_take, 315)
772
-
773
- # Southwest in your reversed/south-facing setup
774
- _draw_motto(latin_late, 45)
775
960
 
776
- except Exception as e:
777
- print(e)
778
961
  except Exception as e:
779
962
  print(e)
780
963
  # 🌳 Tree (axis)
@@ -916,7 +1099,7 @@ def animate_sigil(canvas, base_image_path, duration=4, floor=None, frame_count=2
916
1099
 
917
1100
  for i in range(frame_count):
918
1101
  observed_at = start + (tick * i)
919
- frame = _render_clock_sigil_frame(floor, observed_at, size=512)
1102
+ frame = _render_clock_sigil_frame(floor, observed_at, size=512, ornaments=True, inscription=True, glyph=True, tree=True, shadow=True, vestal=True)
920
1103
  #frames.append(frame.copy())
921
1104
 
922
1105
  frames.append(glow_layer(frame.copy(), passes=1))
@@ -381,6 +381,9 @@ class ThresholdFloor:
381
381
  self.visual_state = "idle"
382
382
  self.mode = "threshing"
383
383
  self.current_phase = None
384
+ self._direction = None
385
+ self._warm_side = None
386
+ self._position_label = None
384
387
  self.water_level = 0.0
385
388
  self.blood_level = 0.0
386
389
  self.wine_level = 0.0
@@ -493,7 +496,7 @@ class ThresholdFloor:
493
496
  max_length=getattr(self, "max_shadow_length", None),
494
497
  )
495
498
 
496
- def shade_voice(self, timestamp: str | None = None) -> str:
499
+ def shade_voice(self, timestamp: str | None = None, prompt: str | None = None) -> str:
497
500
  """
498
501
  Return a simple textual cue based on the current shadow's azimuth.
499
502
 
@@ -514,18 +517,23 @@ class ThresholdFloor:
514
517
  """
515
518
  shadow = self.simulate_shadow(timestamp=timestamp)
516
519
  if shadow is None:
517
- return None
520
+ return ""
521
+ if prompt:
522
+ if prompt.lower() == "who are you?":
523
+ return "Umbra sumus." # I am shade
518
524
 
519
525
  az = getattr(shadow, "shadow_azimuth_deg", None)
520
526
  if az is None:
521
- return None
527
+ return "Utere, non numera" # Use the hours, do not count them.
522
528
 
523
529
  az = float(az) % 360.0
524
530
  if 20.0 <= az <= 160.0:
525
- return "Take your time."
531
+ return "Carpe diem." # Sieze the day
526
532
  if 200.0 <= az <= 350.0:
527
- return "It's later than you think."
528
- return None
533
+ return "Serius est quam cogitas." # It is later than you think.
534
+ if az > 350.0:
535
+ return "Mox nox." # Soon it is night.
536
+ return "Si sol deficit, respicit me nemo." # If the sun is gone, nobody will look at me
529
537
 
530
538
  def add_shadow_mark_from_simulation(
531
539
  self,
@@ -626,6 +634,51 @@ class ThresholdFloor:
626
634
  def get_phase(self):
627
635
  return self.alchemy_phase()["phase"]
628
636
 
637
+ @property
638
+ def direction(self):
639
+ if getattr(self, "_direction", None) is None:
640
+ self.alchemy_phase()
641
+
642
+ return self._direction
643
+
644
+ @property
645
+ def hemisphere(self):
646
+ if getattr(self, "_hemisphere", None) is None:
647
+ self.alchemy_phase()
648
+
649
+ return self._hemisphere
650
+
651
+ @property
652
+ def warm_side(self):
653
+ if getattr(self, "_warm_side", None) is None:
654
+ self.alchemy_phase()
655
+
656
+ return self._warm_side
657
+
658
+ @property
659
+ def position_label(self):
660
+ if getattr(self, "_position_label", None) is None:
661
+ self.alchemy_phase()
662
+
663
+ return self._position_label
664
+
665
+ def get_job(self):
666
+ if self.current_phase is None:
667
+ self.alchemy_phase()
668
+
669
+ return FIELD_JOBS.get(self.current_phase)
670
+
671
+ def get_migration_state(self):
672
+ if self.current_phase is None:
673
+ self.alchemy_phase()
674
+
675
+ return {
676
+ "direction": self.direction,
677
+ "phase": self.current_phase,
678
+ "warm_side": self.warm_side,
679
+ "position": self.position_label,
680
+ }
681
+
629
682
  def alchemy_phase(self) -> Dict[str, Any]:
630
683
  """Discern alchemical phase from prior-day sunrise movement and position.
631
684
 
@@ -648,7 +701,7 @@ class ThresholdFloor:
648
701
  row = self
649
702
  tz = row.tz or os.getenv('TZ') or 'UTC'
650
703
  lat, _lon = row.latitude, row.longitude
651
- hemisphere = 'north' if _lon >= 0.001 else 'south'
704
+ hemisphere = 'north' if lat >= 0.001 else 'south'
652
705
  east_arch = getattr(self, "arch_bearing_deg", 90.0)
653
706
  # Seed yesterday's azimuth and direction if missing
654
707
  today = _date_cls.today()
@@ -707,7 +760,14 @@ class ThresholdFloor:
707
760
  phase = 'Nigredo' if hemisphere == 'north' else 'Citrinitas'
708
761
  else:
709
762
  phase = 'Rubedo' if warm_side else 'Nigredo' if hemisphere == 'north' else 'Nigredo' if warm_side else 'Rubedo'
710
- self.phase = phase
763
+ self.current_phase = phase
764
+ if heading == hemisphere:
765
+ self._direction = 'ascending'
766
+ else:
767
+ self._direction = 'descending'
768
+ self._hemisphere = hemisphere
769
+ self._warm_side = warm_side
770
+ self._position_label = position_label
711
771
  return {
712
772
  'phase': phase,
713
773
  'heading': heading,
@@ -717,6 +777,7 @@ class ThresholdFloor:
717
777
  'east_arch': east_arch,
718
778
  }
719
779
 
780
+
720
781
  def sun_delay(self) -> Dict[str, Any]:
721
782
  angle = scan_vector(self.latitude, self.longitude, self.get_sunrise())
722
783
  delay = estimate_sun_delay(angle)
@@ -786,8 +847,7 @@ class ThresholdFloor:
786
847
  return datetime.now(tzinfo)
787
848
 
788
849
  def now_mt(self) -> datetime:
789
- MoonTime.from_dt(self.now())
790
- return MoonTime.from_dt(self.now())
850
+ return MoonTime.from_datetime(self.now())
791
851
 
792
852
  def weather(self) -> str:
793
853
  if not WEATHER_EXISTS:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: thresholdfloor
3
- Version: 0.3.2
3
+ Version: 0.3.4
4
4
  Summary: A floor below for tuning to what's above
5
5
  Author: WitchMithras
6
6
  License: Proprietary (staging)
File without changes
File without changes
File without changes