#!/usr/bin/env python3
import os
from dataclasses import dataclass

MY_EXTERNAL_IP="1234"
SECONDS_IN_DAY = 86400

# Directories
HOME = os.environ['HOME']
LOGGING_DIR = "{}/logs".format(HOME)
TUYA_LOG_BASE = '{}/tuya_logs/tuya_logs.csv'.format(HOME)
JSON_SUMMARY_FILE = '{}/tuya_logs/summary.json'.format(HOME)
JSON_SUMMARY_PATCH_FILE = '{}/tuya_logs/summary.json'.format(HOME) # When debugging, use a different name
JSON_PUMPRATES_FILE = '{}/tuya_logs/pump_rates.json'.format(HOME)

# Mailer.py
EMAIL_FROM = 'user_from@gmail.com'
EMAIL_TO = 'user_to@gmail.com'
ALWAYS_EMAIL = False
GMAIL_USERNAME = 'user_from'
GMAIL_PASSWORD = 'XXX'



# Twilio SMS
TWILIO_SID = 'sid'
AUTH_TOKEN = 'token'
SMS_FROM = '+18001234567'

# WaterMonitor: Processing
MAX_ZONES = 16
MAX_NEW_FILES = 2 # Number of recent raw log files that are reprocessed into summary json
LOGROTATE_PER_DAY = 4
DAYS_LOOKBACK = 90 # Days of data to store in the pumprates file. Perf penalty if too large
START_FROM_EPOCH = 1539161991 # 2018-10-10-01-59-51 # Data prior in summary file, but is very corrupt

# WaterMonitor: Alerting
DAYS_EMAIL_REPORT = 14
MIN_DRIP_ZONE_ALERT_TIME = 1800
MIN_DRIP_PLOT_TIME = 189
MIN_MISC_ZONE_ALERT_TIME = SECONDS_IN_DAY
MIN_SPRINKLER_ZONE_ALERT_TIME = 600
ALERT_THRESH = 1.18 # ie: 18% higher than average
PUMP_ALERT = 22 # If pump cycles off faster than this in seconds, then alert.
PUMP_TOGGLES_COUNT = 25

# Nodes
FOSCAM_NODES={'Frontyard':    "192.168.1.A",
              'Garage' :      "192.168.1.B"}
FOSCAM_USERNAME="user_from"
FOSCAM_PASSWORD="YYY"

WINDOWS_NODES={'Alpha': "192.168.1.C"}
WINDOWS_USERNAME="user_from"
WINDOWS_PASSWORD="YYY"

# Network Check
MIN_DL_BW = 150  # Mbps
MIN_UL_BW = 4    # Mbps

# Info on all nodes.
# Note: sms_inform and histfile is only used by BrowserAlert
# TODO: Still need to move all other nodes to this new canonical config
NODES={
  "node1": {
     "ip": "192.168.1.D",
     "username": "XYZA",
     "password": None,
     "histfile": '/Users/user1/Library/Application\ Support/Google/Chrome/Default/History',
     "sms_inform": ['+1408-------'],
     "whitelist": "kahoot", # Full python regex
   },
   "node2": {
     "ip": "192.168.1.E",
     "username": "XYZA",
     "password": None,
     "histfile": '/Users/user2/Library/Application\ Support/Google/Chrome/Default/History',
     "sms_inform": ['+1408-------'],
   },
}

# Browser Alert
REFRESH_DELAY = 30     # In seconds, how soon should we check?
MIN_REPORTING_GAP = 6  # If we already got an alert, then don't need a followup right away
HR_START_MONITORING = 2 # When do the SMSs start firing
HR_STOP_MONITORING = 23 # 13
HR_EMAIL = 19
BLACKLIST=[
  "pokemon",
  "surviv",
  "dragapult",
]

# Tesla Powerwall
POWERWALL_IP="192.168.X.Y"
POWERWALL_EMAIL="a@aa.aa"
POWERWALL_PASSWORD="XYZA"
POWERWALL_SMS_RCPT = '+18001234567'
POWERWALL_POLL_TIME = 180

TESLA_EMAIL="a@aa.aa"
TESLA_PASSWORD="XTZA"

@dataclass
class OpModeConfig:
  time_start: int
  time_end: int
  pct_gradient_per_hr: int
  pct_thresh: int
  iff_higher: bool
  pct_min: int
  pct_min_trail_stop: int
  op_mode: str
  reason: str

# How this works: Tesla interprets both flags "customer_preferred_export_rule",
# "allow_charge_from_grid_with_solar_installed" as False in "self_consumption" mode,
# So we permanently set these to True in the tesla app, then simply toggle the
# self_consumption mode at the right time.
# -- Set the min battery (pct_min) per your convenience. The last 5% cannot be extracted, so at 20%
# threshold, I have just about 2 hours of power reserves - Scary, so we will charge back up to 30%
# as soon as rates drop, then go back to self_consumption. Other exception:
# -- For rainy days, we want to charge from grid just before peak rates, iff solar will not cut it.
# -- We dump powerwall to grid twice. Once, before peak rate ends, but keep enough for shoulder. And
# then everything left before end of shoulder.
# Recall: 1% is 0.135kWh ==> base drain rate of 0.5kWh is 3.5%/hr
POWERWALL_DECISION_POINTS = [
  OpModeConfig( 000,  100,   0,  28, False, 30,  0, "autonomous", "Prep for midnight recharge.."),
  OpModeConfig(1300, 1455,  35, 100, False, 20,  0, "autonomous", "Solar recharge insufficient. Drawdown before shoulder.."),
  OpModeConfig(1455, 1900,   0,   0,  True, 20,  0, "self_consumption", "In Peak. Discharge.."),
  OpModeConfig( 000, 1500,   0,   0,  True, 30, 15, "self_consumption", "Nightly reserves rebuilt. Solar charge only.."),
  OpModeConfig(1900, 2359,  -7,  20, False, 20,  0, "self_consumption", "Reserve for rest of shoulder. No dump."),
  OpModeConfig(1900, 2100, -35,  38,  True, 20,  0, "autonomous", "Dump surplus before end of peak."),
  OpModeConfig(2345, 2359, -35,  20,  True, 20,  0, "autonomous", "Dump residuals before end of shoulder"),
]

