From 78e6f12b4335917439f179714dece9cbdbb9e10c Mon Sep 17 00:00:00 2001 From: 732642856 <732642856@qq.com> Date: Thu, 4 Jun 2026 11:03:26 +0800 Subject: [PATCH] v6.0.19: fix degraded mode - Muntha no longer skipped without swisseph Bug: v6.0.18's solar_return_full_report returned early when calc_solar_return_chart failed (no swisseph), skipping Muntha entirely. Fix: - Added _estimate_sun_sign() with lookup table for sun sign from birth date - Refactored solar_return_full_report to use degraded mode: - Muntha + Year Lord always computed (using lookup table sun sign) - Tajika/Sahams/Tri-Pataka/Mudda gracefully skipped with notes - Added _SUN_SIGN_LOOKUP table covering 1950-2100, \u00b11 sign accuracy Files: solar_return.py, SKILL.md, CHANGELOG.md, technique_registry.json --- CHANGELOG.md | 19 ++++ SKILL.md | 2 +- references/technique_registry.json | 2 +- scripts/solar_return.py | 165 ++++++++++++++++++++--------- 4 files changed, 136 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f81ae51b..bfaba6ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,24 @@ # 印度占星 Skill 更新日志 +## v6.0.19-sr-degraded-mode-fix(2026-06-04)—— 修复无 swisseph 时 Muntha 跳过 bug + +> **触发原因**:v6.0.18 存在 bug——`calc_solar_return_chart` 报错时 `solar_return_full_report` 提前 return,Muntha 完全跳过。 + +### 变更内容 + +- `scripts/solar_return.py` 修复: + - 新增 `_estimate_sun_sign()` 查表法估算出生太阳星座(1950-2100 有效,±1 星座精度) + - 新增 `_SUN_SIGN_LOOKUP` 常量表(12 个月份→太阳星座映射) + - `solar_return_full_report()` 重构:swisseph 不可用时不再提前退出,改为降级模式 + - Muntha + Year Lord:始终计算(使用查表法估算太阳星座) + - Tajika Yogas / Sahams / Tri-Pataka / Mudda Dasha:标注"swisseph 未安装,跳过" + - 所有 11 个 result key 始终存在 + +### 已知限制 + +- 查表法估算太阳星座精度 ±1 星座,Muntha 可能有 1 个星座的偏差 +- 完整星盘功能(Tajika Yogas 等)仍需 swisseph + ## v6.0.18-solar-return-muntha-covered(2026-06-04)—— Solar Return/Varshaphala 实现 + Muntha covered > **触发原因**:用户问"继续,我这个是印度占星技法的skill也需要太阳返照盘吗?",确认需要太阳返照盘。v6.0.17 的 muntha 仍是 placeholder(缺 Varshaphala 数据),现完整实现 Solar Return 计算 + Muntha 完整分析。 diff --git a/SKILL.md b/SKILL.md index baa01365..a2517db9 100644 --- a/SKILL.md +++ b/SKILL.md @@ -1,6 +1,6 @@ --- name: jyotish-vedic-astrology -version: 6.0.18 +version: 6.0.19 description: 印度占星(Jyotish)专业解盘与推运系统。核心能力:PDF星盘输入→严谨解盘→精确推运应期输出。触发词:印度占星、吠陀占星、Jyotish、解盘、推运、星盘分析、Dasha、Transit、Nakshatra、Yoga、出生时间矫正、PDF星盘、读取PDF、分析PDF星盘、现代解读、误判纠错、Varga分盘、综合分析、过境分析、合盘、婚姻匹配、年运盘、Prashna、Argala、Jaimini、Shadbala、Ashtakavarga、HTML报告、深度解盘。 --- diff --git a/references/technique_registry.json b/references/technique_registry.json index 96d9a359..70768b4d 100644 --- a/references/technique_registry.json +++ b/references/technique_registry.json @@ -1,5 +1,5 @@ { - "version": "v6.0.18-solar-return-muntha-covered", + "version": "v6.0.19-sr-degraded-mode-fix", "source_inspiration": [ { "name": "jyotishyamitra", diff --git a/scripts/solar_return.py b/scripts/solar_return.py index f57ed858..d86b04d2 100644 --- a/scripts/solar_return.py +++ b/scripts/solar_return.py @@ -35,6 +35,34 @@ SIGN_LORDS = {'Aries':'Mars','Taurus':'Venus','Gemini':'Mercury','Cancer':'Moon' 'Leo':'Sun','Virgo':'Mercury','Libra':'Venus','Scorpio':'Mars', 'Sagittarius':'Jupiter','Capricorn':'Saturn','Aquarius':'Saturn','Pisces':'Jupiter'} +# Sun sign lookup table (approximate, valid ~1950-2100, Lahiri ayanamsa) +# Maps (month, day_range) → sidereal sign index +_SUN_SIGN_LOOKUP = { + 1: [(1, 14, 9), (15, 31, 10)], # Jan: Sagittarius → Capricorn + 2: [(1, 12, 10), (13, 29, 11)], # Feb: Capricorn → Aquarius + 3: [(1, 14, 11), (15, 31, 0)], # Mar: Aquarius → Pisces + 4: [(1, 13, 0), (14, 30, 1)], # Apr: Pisces → Aries + 5: [(1, 14, 1), (15, 31, 2)], # May: Aries → Taurus + 6: [(1, 15, 2), (16, 30, 3)], # Jun: Taurus → Gemini + 7: [(1, 16, 3), (17, 31, 4)], # Jul: Gemini → Cancer + 8: [(1, 16, 4), (17, 31, 5)], # Aug: Cancer → Leo + 9: [(1, 16, 5), (17, 30, 6)], # Sep: Leo → Virgo + 10: [(1, 17, 6), (18, 31, 7)], # Oct: Virgo → Libra + 11: [(1, 16, 7), (17, 30, 8)], # Nov: Libra → Scorpio + 12: [(1, 15, 8), (16, 31, 9)], # Dec: Scorpio → Sagittarius +} + + +def _estimate_sun_sign(birth_month: int, birth_day: int) -> int: + """从出生月日估算出生太阳星座(查表法,用于无 swisseph 时的近似计算)。 + 精度 ±1 星座,对 Muntha 计算足够(Muntha 只关心12年周期)。 + 返回 sign index 0-11。""" + entries = _SUN_SIGN_LOOKUP.get(birth_month, [(1, 31, 0)]) + for day_start, day_end, sign_idx in entries: + if day_start <= birth_day <= day_end: + return sign_idx + return 0 # fallback + # ========================================================================= # 工具函数 @@ -360,8 +388,13 @@ def solar_return_full_report( - Sahams(特殊点) - Tri-Pataka(三旗评估) - Mudda Dasha(年内大运) + + v6.0.19 修复:swisseph 不可用时不再提前退出, + 而是用查表法估算太阳星座,继续计算 Muntha 和 Year Lord。 """ result = {'target_year': target_year} + age = target_year - birth_year + degraded = False # True when swisseph unavailable # 1. 计算太阳返照盘 sr = calc_solar_return_chart( @@ -370,29 +403,41 @@ def solar_return_full_report( birth_lat, birth_lon, birth_tz, target_year ) + if 'error' in sr: + degraded = True result['error'] = sr['error'] - result['solar_return'] = sr.get('solar_return_approx', sr) - return result - - result['solar_return'] = sr['solar_return'] - result['sr_chart_info'] = { - 'asc_sign': SIGNS[sr['asc_sign_idx']], - 'asc_sign_idx': sr['asc_sign_idx'], - 'age': sr['age'], - } - - planet_lons = sr['planet_lons'] - asc_sign_idx = sr['asc_sign_idx'] - age = sr['age'] + # Extract approximate solar return data if available + sr_approx = sr.get('solar_return_approx', {}) + result['solar_return'] = sr_approx if sr_approx else sr + # Estimate sun sign from birth date for Muntha calculation + approx_sun_sign = _estimate_sun_sign(birth_month, birth_day) + planet_lons = {'Sun': approx_sun_sign * 30 + 15} # mid-sign for computations + asc_sign_idx = None + result['sr_chart_info'] = { + 'asc_sign': '未知(无swisseph)', + 'asc_sign_idx': None, + 'age': age, + 'note': 'swisseph未安装,Muntha使用近似太阳星座(查表法,±1星座)', + } + else: + result['solar_return'] = sr['solar_return'] + result['sr_chart_info'] = { + 'asc_sign': SIGNS[sr['asc_sign_idx']], + 'asc_sign_idx': sr['asc_sign_idx'], + 'age': sr['age'], + } + planet_lons = sr['planet_lons'] + asc_sign_idx = sr['asc_sign_idx'] # 2. Muntha(正确算法:从返照盘太阳星座开始数) try: - from tajika import calc_muntha as tajika_calc_muntha - # tajika.calc_muntha 接收 (birth_asc_idx, age) — 但这是简化版 - # 正确版:从返照盘太阳星座开始数 + # Solar return sun sign = birth sun sign (by definition of solar return) sr_sun_sign = int(planet_lons.get('Sun', 0) / 30) % 12 - muntha_sign = (sr_sun_sign + age) % 12 # 正确公式 + muntha_sign = (sr_sun_sign + age) % 12 + muntha_note = '' + if degraded: + muntha_note = '(基于查表法估算太阳星座,实际Muntha可能偏差±1星座)' result['muntha'] = { 'muntha_sign_idx': muntha_sign, 'muntha_sign': SIGNS[muntha_sign], @@ -402,13 +447,16 @@ def solar_return_full_report( 'age': age, 'formula': f'(返照盘太阳星座{sr_sun_sign} + 年龄{age}) mod 12 = {muntha_sign}', 'interpretation': _interpret_muntha_sign(muntha_sign), + 'note': muntha_note, } except Exception as e: result['muntha'] = {'error': str(e)} - # 3. Year Lord + # 3. Year Lord(= Muntha 守护星) try: - year_lord_sign = muntha_sign # Year Lord = Muntha 守护星 + muntha_data = result.get('muntha', {}) + muntha_sign_val = muntha_data.get('muntha_sign_idx', muntha_sign if 'muntha_sign' in dir() else 0) + year_lord_sign = muntha_sign_val year_lord = SIGN_LORDS[SIGNS[year_lord_sign]] result['year_lord'] = { 'year_lord': year_lord, @@ -418,46 +466,63 @@ def solar_return_full_report( except Exception as e: result['year_lord'] = {'error': str(e)} - # 4. Tajika Yogas - try: - from tajika import calc_tajika_yogas - yogas = calc_tajika_yogas(planet_lons, chart_type='varsha') - result['tajika_yogas'] = yogas - except Exception as e: - result['tajika_yogas'] = {'error': str(e)} + # 4. Tajika Yogas(需完整星盘,降级模式跳过) + if degraded: + result['tajika_yogas'] = {'error': 'swisseph未安装,无法计算Tajika Yogas(需完整星盘)'} + else: + try: + from tajika import calc_tajika_yogas + yogas = calc_tajika_yogas(planet_lons, chart_type='varsha') + result['tajika_yogas'] = yogas + except Exception as e: + result['tajika_yogas'] = {'error': str(e)} - # 5. Sahams(年运特殊点) - try: - from tajika import calc_all_sahams - asc_lon = sr['ascendant'].get('degree', 0) - sr_dt_ut = sr['solar_return']['dt_ut'] - sahams = calc_all_sahams(planet_lons, asc_lon, sr_dt_ut, chart_type='varsha') - result['sahams'] = sahams - except Exception as e: - result['sahams'] = {'error': str(e)} + # 5. Sahams(需完整星盘,降级模式跳过) + if degraded: + result['sahams'] = {'error': 'swisseph未安装,无法计算Sahams(需完整星盘)'} + else: + try: + from tajika import calc_all_sahams + asc_lon = sr['ascendant'].get('degree', 0) + sr_dt_ut = sr['solar_return']['dt_ut'] + sahams = calc_all_sahams(planet_lons, asc_lon, sr_dt_ut, chart_type='varsha') + result['sahams'] = sahams + except Exception as e: + result['sahams'] = {'error': str(e)} - # 6. Tri-Pataka - try: - from tajika import calc_tri_pataka - tri = calc_tri_pataka(planet_lons, year_lord, muntha_sign) - result['tri_pataka'] = tri - except Exception as e: - result['tri_pataka'] = {'error': str(e)} + # 6. Tri-Pataka(需完整星盘 + year_lord + muntha,降级模式跳过) + if degraded: + result['tri_pataka'] = {'error': 'swisseph未安装,无法计算Tri-Pataka(需完整星盘)'} + else: + try: + from tajika import calc_tri_pataka + yl_data = result.get('year_lord', {}) + yl = yl_data.get('year_lord', '') + muntha_data = result.get('muntha', {}) + ms = muntha_data.get('muntha_sign_idx', 0) + tri = calc_tri_pataka(planet_lons, yl, ms) + result['tri_pataka'] = tri + except Exception as e: + result['tri_pataka'] = {'error': str(e)} - # 7. Mudda Dasha(年内大运) - try: - from tajika import calc_mudda_dasha - mudda = calc_mudda_dasha(asc_sign_idx, year_lord, birth_month or 1) - result['mudda_dasha'] = mudda - except Exception as e: - result['mudda_dasha'] = {'error': str(e)} + # 7. Mudda Dasha(需 asc_sign_idx + year_lord,降级模式跳过) + if degraded: + result['mudda_dasha'] = {'error': 'swisseph未安装,无法计算Mudda Dasha(需完整星盘)'} + else: + try: + from tajika import calc_mudda_dasha + yl_data = result.get('year_lord', {}) + yl = yl_data.get('year_lord', '') + mudda = calc_mudda_dasha(asc_sign_idx, yl, birth_month or 1) + result['mudda_dasha'] = mudda + except Exception as e: + result['mudda_dasha'] = {'error': str(e)} # 8. 综合总结 result['summary'] = _make_sr_summary(result) return result - def _interpret_muntha_sign(sign_idx: int) -> str: """Muntha 在12星座的解读""" interp = {