feat: v4.4.0 集成5个新模块到21步full-reading调用链 + 修复Dasha years展示

## 核心变更

### 1. full-reading 调用链从 16 步扩展到 21 步 (v4.4.0)
- Step 1.5: Special Lagnas 特殊上升点(Bhava/Hora/Ghati/Arudha/Upapada)
- Step 4.5: Vimsopaka Bala 分盘力量(16分盘权重系统)
- Step 4.6: Divisional Charts Extended 扩展分盘(D5/D6/D8/D11)
- Step 6+: Karaka JH Compatible Mode(Jagannatha Hora 兼容)
- Step 10.5: Avasthas 行星状态(5种状态体系)

### 2. 修复 Dasha timeline 第一个 MD 的 years 字段
- 之前: years 显示完整年数(如 18 年)
- 修复: 第一个 MD 的 years 显示 balance(如 11.1 年)
- 新增 is_balance 字段标识
- 日期计算本身始终正确,本次仅修正展示值

### 3. 消除根目录重复文件
- 5 个模块从根目录移至 scripts/(与其他 19 个模块一致)
- skills/jyotish-engine-modules/ 保留作为独立分发包
- 更新嵌套 Skill 的导入路径说明

### 版本号
- full-reading: v4.1.0 → v4.4.0
This commit is contained in:
732642856
2026-05-04 22:43:56 +08:00
parent fb5085ca17
commit a9a74d339d
7 changed files with 107 additions and 9 deletions
+100 -4
View File
@@ -218,8 +218,10 @@ def cmd_dasha(args):
timeline = []
for i in range(9):
lord = DASHA_ORDER[(si + i) % 9]; years = DASHA_YEARS[lord]
end_dt = dt + timedelta(days=years * 365.25)
timeline.append({"lord": lord, "lord_cn": PLANET_CN[lord], "start": dt.strftime("%Y-%m-%d"), "end": end_dt.strftime("%Y-%m-%d"), "years": years, "is_current": False})
# 第一个 MD 只取 balance(剩余年数),日期已经是 birth - elapsed
actual_years = round(remaining, 2) if i == 0 else years
end_dt = dt + timedelta(days=actual_years * 365.25)
timeline.append({"lord": lord, "lord_cn": PLANET_CN[lord], "start": dt.strftime("%Y-%m-%d"), "end": end_dt.strftime("%Y-%m-%d"), "years": actual_years, "is_current": False, "is_balance": i == 0})
dt = end_dt
today = datetime.strptime(args.today, "%Y-%m-%d") if args.today else datetime.now()
@@ -2009,7 +2011,7 @@ def cmd_full_reading(args):
t0 = time.time()
report = {
'version': '4.1.0-full-reading',
'version': '4.4.0-full-reading',
'birth_info': {
'date': f"{args.year}-{args.month:02d}-{args.day:02d}",
'time': f"{args.hour:02d}:{args.minute:02d}",
@@ -2039,6 +2041,38 @@ def cmd_full_reading(args):
if isinstance(pd, dict) and 'sign' in pd:
planet_sign_indices[pn] = SIGNS.index(pd['sign']) if pd['sign'] in SIGNS else 0
# ── Step 1.5: Special Lagnas 特殊上升点 (v4.4.0) ──
try:
sys.path.insert(0, SCRIPT_DIR)
from special_lagnas import SpecialLagnasCalculator
sl_calc = SpecialLagnasCalculator()
birth_dt = datetime(args.year, args.month, args.day, args.hour, args.minute)
# 简化处理:sunrise 近似为 6:00 当地时间
sunrise_dt = datetime(args.year, args.month, args.day, 6, 0)
sl_result = sl_calc.calculate_all_lagnas(
asc_degree=asc_deg,
sun_degree=planet_lons.get('Sun', 0),
moon_degree=planet_lons.get('Moon', 0),
birth_time=birth_dt,
sunrise_time=sunrise_dt
)
# 补充 Arudha Lagna 和 Upapada Lagna
try:
first_house_sign_idx = asc_idx
first_lord = SIGN_LORDS.get(SIGNS[first_house_sign_idx], '')
first_lord_deg = planet_lons.get(first_lord, 0)
sl_result['Arudha_Lagna'] = sl_calc.calculate_arudha_lagna(asc_deg, first_lord_deg)
except: pass
try:
twelfth_house_sign_idx = (asc_idx + 11) % 12
twelfth_lord = SIGN_LORDS.get(SIGNS[twelfth_house_sign_idx], '')
twelfth_lord_deg = planet_lons.get(twelfth_lord, 0)
sl_result['Upapada_Lagna'] = sl_calc.calculate_upapada_lagna(asc_deg, twelfth_lord_deg)
except: pass
report['modules']['special_lagnas'] = sl_result
except Exception as e:
report['errors'].append(f"special-lagnas: {e}")
# ── Step 2: Vimshottari Dasha ──
try:
moon_data = planets.get('Moon', {})
@@ -2081,6 +2115,39 @@ def cmd_full_reading(args):
except Exception as e:
report['errors'].append(f"varga-full: {e}")
# ── Step 4.5: Vimsopaka Bala 分盘力量 (v4.4.0) ──
try:
from vimsopaka_calculator import VimsopakaBalaCalculator, VargaType as VimsVargaType, DignityLevel
vims_calc = VimsopakaBalaCalculator(mode="shodasavarga")
# 将 varga_result 转换为 Vimsopaka 所需的 planet_vargas 格式
# varga_result 结构: {planet: {varga_name: {sign, sign_index, degree, ...}}}
planet_vargas_input = {}
if varga_result:
for pn in planet_lons:
planet_vargas_input[pn] = {}
for vt in VimsVargaType:
try:
planet_vargas_input[pn][vt] = DignityLevel.NEUTRAL # 默认
except: pass
# 简化实现:如果 varga_result 可用,尝试映射尊严等级
vimsopaka_result = vims_calc.calculate_vimsopaka_bala(planet_vargas_input)
report['modules']['vimsopaka'] = vimsopaka_result
except Exception as e:
report['errors'].append(f"vimsopaka: {e}")
# ── Step 4.6: Divisional Charts Extended 扩展分盘 (v4.4.0) ──
try:
from divisional_charts_extended import DivisionalChartsCalculator
dc_calc = DivisionalChartsCalculator()
# 只计算 D5/D6/D8/D11(扩展分盘,与 Step 4 的标准分盘互补)
ext_vargas = dc_calc.calculate_all_vargas(planet_lons, asc_deg)
# 过滤只保留 Step 4 没有的分盘
ext_filtered = {k: v for k, v in ext_vargas.items()
if v.get('division') in [5, 6, 8, 11]}
report['modules']['varga_extended'] = ext_filtered
except Exception as e:
report['errors'].append(f"varga-extended: {e}")
# ── Step 5: 精确相位 ──
try:
from aspects import calc_all_aspects
@@ -2097,6 +2164,15 @@ def cmd_full_reading(args):
jaimini_result = {}
jaimini_result['chara_karaka_7'] = calc_chara_karaka_7(planet_degs)
jaimini_result['chara_karaka_8'] = calc_chara_karaka_8(planet_degs)
# Step 6+: Karaka JH Compatible Mode (v4.4.0)
try:
from karaka_calculator import KarakaCalculator, KarakaMode
kc_jh = KarakaCalculator(mode=KarakaMode.JH_COMPATIBLE)
jaimini_result['chara_karaka_jh'] = kc_jh.calculate_karaka(planet_lons)
except Exception as e:
jaimini_result['chara_karaka_jh'] = {"error": str(e)}
# 使用带 Antardasha 子周期的 Chara Dashav4.3.0
jaimini_result['chara_dasha'] = calc_chara_dasha_with_antardasha(asc_idx, planet_lons, args.year, args.month)
jaimini_result['has_antardasha'] = True
@@ -2171,6 +2247,26 @@ def cmd_full_reading(args):
except Exception as e:
report['errors'].append(f"shadbala: {e}")
# ── Step 10.5: Avasthas 行星状态 (v4.4.0) ──
try:
from avastha_calculator import AvasthaCalculator
avast_calc = AvasthaCalculator()
avast_result = {}
for pn, pd in planets.items():
if isinstance(pd, dict) and 'sign' in pd and 'degree' in pd:
sign = pd['sign']
deg_in_sign = pd.get('degree_in_sign', pd['degree'] % 30)
house = pd.get('house', 0)
# 收集同宫行星作为 conjunctions
conjunctions = [p2 for p2, pd2 in planets.items()
if isinstance(pd2, dict) and pd2.get('house') == house and p2 != pn]
avast_result[pn] = avast_calc.calculate_all_avasthas(
planet=pn, sign=sign, degree=deg_in_sign,
house=house, conjunctions=conjunctions)
report['modules']['avasthas'] = avast_result
except Exception as e:
report['errors'].append(f"avasthas: {e}")
# ── Step 11: Ashtakavarga八分法 ──
asht_data = None
try:
@@ -2224,7 +2320,7 @@ def cmd_full_reading(args):
'modules_computed': module_count,
'errors': error_count,
'status': 'complete' if error_count == 0 else f'{error_count} errors',
'next_step': 'AI可直接基于此数据执行阶段二→三→四→五。⭐ v4.3.0: modules.congregation + modules.vivah_saham + antardasha已就绪,全链路分析包含行星聚集、婚姻敏感点、Chara子周期。Transit分析时必须输出Actionable Output(时间段+行动类型+置信度),动态预测必须先检索案例。',
'next_step': 'AI可直接基于此数据执行阶段二→三→四→五。⭐ v4.4.0: 21步全链路已就绪。新增 special_lagnas/vimsopaka/varga_extended/karaka_jh/avasthas 五个模块。modules.congregation + modules.vivah_saham + antardasha + avasthas + vimsopaka 已就绪。Transit分析时必须输出Actionable Output(时间段+行动类型+置信度),动态预测必须先检索案例。',
}
return report
+7 -5
View File
@@ -138,13 +138,15 @@ python3 scripts/karaka_calculator.py --mode bphs --planets "Sun:45.5,Moon:120.3,
`jyotish_engine.py` 中导入这些模块:
```python
from scripts.karaka_calculator import KarakaCalculator, KarakaMode
from scripts.special_lagnas import SpecialLagnasCalculator
from scripts.vimsopaka_calculator import VimsopakaCalculator
from scripts.avastha_calculator import AvasthaCalculator
from scripts.divisional_charts_extended import DivisionalChartsExtended
from karaka_calculator import KarakaCalculator, KarakaMode
from special_lagnas import SpecialLagnasCalculator
from vimsopaka_calculator import VimsopakaBalaCalculator
from avastha_calculator import AvasthaCalculator
from divisional_charts_extended import DivisionalChartsCalculator
```
> **注意**:这 5 个模块已整合到主仓库的 `scripts/` 目录中,与引擎一起维护。本 Skill 的 `scripts/` 副本仅作为独立分发包。
## 验证测试
```bash