Initial commit: WeConnect data collector
Adds collect.py with CLI flags for credentials (-u/-p), credential JSON file (-c), VIN, domains (-d), interval, output file, and --list-domains. Credentials file supports domains as array or string. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
.idea/
|
||||||
|
credentials/
|
||||||
|
vehicle_data.json
|
||||||
+541
@@ -0,0 +1,541 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
WeConnect vehicle data collector.
|
||||||
|
|
||||||
|
Periodically fetches selected domains from a VW WeConnect vehicle and
|
||||||
|
appends timestamped records to a JSON file. The JSON structure mirrors
|
||||||
|
the WeConnect domain hierarchy: domain → status-object → field.
|
||||||
|
|
||||||
|
Usage examples
|
||||||
|
--------------
|
||||||
|
# Credentials from env vars, all defaults:
|
||||||
|
export WC_USER=me@example.com WC_PASS=secret
|
||||||
|
python collect.py
|
||||||
|
|
||||||
|
# Credentials from a JSON file:
|
||||||
|
python collect.py -c creds.json -i 600 -o id3.json
|
||||||
|
|
||||||
|
# Custom domains, 10-minute interval:
|
||||||
|
python collect.py -u me@example.com -p secret \\
|
||||||
|
-d charging,measurements,readiness -i 600 -o id3.json
|
||||||
|
|
||||||
|
# Everything, verbose, keep last 1 000 records:
|
||||||
|
python collect.py -d all -v --max-records 1000
|
||||||
|
|
||||||
|
Available domains: charging, climatisation, measurements, readiness, parking, access
|
||||||
|
|
||||||
|
Credentials file format (JSON)
|
||||||
|
-------------------------------
|
||||||
|
{
|
||||||
|
"username": "me@example.com",
|
||||||
|
"password": "secret",
|
||||||
|
"vin": "WVWZZZE1ZMP123456",
|
||||||
|
"domains": ["charging", "measurements", "readiness"]
|
||||||
|
}
|
||||||
|
All four keys are optional; domains may also be a comma-separated string.
|
||||||
|
Explicit CLI flags and env vars take precedence.
|
||||||
|
|
||||||
|
Sample output record
|
||||||
|
--------------------
|
||||||
|
{
|
||||||
|
"ts": "2026-05-25T10:05:00+00:00",
|
||||||
|
"charging": {
|
||||||
|
"chargingStatus": { "chargingState": "readyForCharging", ... },
|
||||||
|
"batteryStatus": { "currentSOC_pct": 80, "cruisingRangeElectric_km": 295 },
|
||||||
|
"chargingSettings": { "targetSOC_pct": 80, ... },
|
||||||
|
"plugStatus": { "plugConnectionState": "disconnected", ... }
|
||||||
|
},
|
||||||
|
"measurements": {
|
||||||
|
"odometerStatus": { "odometer": 12345 },
|
||||||
|
"rangeStatus": { "electricRange": 295, "totalRange_km": 295 },
|
||||||
|
"batteryStatus": { "temperatureBatteryMax_K": 295.15,
|
||||||
|
"temperatureBatteryMin_K": 293.15 },
|
||||||
|
"temperatureOutsideStatus": { "temperatureOutside_C": 18.0 }
|
||||||
|
},
|
||||||
|
"readiness": {
|
||||||
|
"readinessStatus": {
|
||||||
|
"connectionState": { "isOnline": true, "isActive": true },
|
||||||
|
"connectionWarning": { "insufficientBatteryLevelWarning": false }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parking": {
|
||||||
|
"parkingPosition": { "lat": 52.123, "lon": 13.456 }
|
||||||
|
},
|
||||||
|
"access": {
|
||||||
|
"accessStatus": {
|
||||||
|
"overallStatus": "safe",
|
||||||
|
"doors": { "frontLeft": { "lockState": "locked", "openState": "closed" } },
|
||||||
|
"windows": { "frontLeft": { "openState": "closed" } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
try:
|
||||||
|
from weconnect import weconnect
|
||||||
|
except ImportError:
|
||||||
|
print("weconnect is not installed. Run: pip install weconnect", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
# ── helpers ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def _str(v) -> str:
|
||||||
|
"""Convert an enum-like WeConnect value to a plain string."""
|
||||||
|
return str(v.value) if hasattr(v, "value") else str(v)
|
||||||
|
|
||||||
|
|
||||||
|
# ── domain extractors ────────────────────────────────────────────────────────
|
||||||
|
# Each function returns a dict whose keys are the WeConnect status-object names
|
||||||
|
# and whose values are dicts of field-name → value — mirroring the API layout.
|
||||||
|
# Returns None when the domain is absent from the API response.
|
||||||
|
|
||||||
|
def extract_charging(vehicle) -> dict | None:
|
||||||
|
try:
|
||||||
|
d = vehicle.domains["charging"]
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
result: dict = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
cs = d["chargingStatus"]
|
||||||
|
result["chargingStatus"] = {
|
||||||
|
"chargingState": _str(cs.chargingState),
|
||||||
|
"chargePower_kW": cs.chargePower_kW.value,
|
||||||
|
"remainingChargingTimeToComplete_min": cs.remainingChargingTimeToComplete_min.value,
|
||||||
|
"chargeType": _str(cs.chargeType),
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("chargingStatus unavailable", exc_info=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
bs = d["batteryStatus"]
|
||||||
|
result["batteryStatus"] = {
|
||||||
|
"currentSOC_pct": bs.currentSOC_pct.value,
|
||||||
|
"cruisingRangeElectric_km": bs.cruisingRangeElectric_km.value,
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("charging/batteryStatus unavailable", exc_info=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
cfg = d["chargingSettings"]
|
||||||
|
result["chargingSettings"] = {
|
||||||
|
"targetSOC_pct": cfg.targetSOC_pct.value,
|
||||||
|
"maxChargeCurrentAC": _str(cfg.maxChargeCurrentAC),
|
||||||
|
"autoUnlockPlugWhenCharged": _str(cfg.autoUnlockPlugWhenCharged),
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("chargingSettings unavailable", exc_info=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
ps = d["plugStatus"]
|
||||||
|
result["plugStatus"] = {
|
||||||
|
"plugConnectionState": _str(ps.plugConnectionState),
|
||||||
|
"plugLockState": _str(ps.plugLockState),
|
||||||
|
"externalPower": _str(ps.externalPower),
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("plugStatus unavailable", exc_info=True)
|
||||||
|
|
||||||
|
return result or None
|
||||||
|
|
||||||
|
|
||||||
|
def extract_climatisation(vehicle) -> dict | None:
|
||||||
|
try:
|
||||||
|
d = vehicle.domains["climatisation"]
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
result: dict = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
cl = d["climatisationStatus"]
|
||||||
|
result["climatisationStatus"] = {
|
||||||
|
"climatisationState": _str(cl.climatisationState),
|
||||||
|
"remainingClimatisationTime_min": cl.remainingClimatisationTime_min.value,
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("climatisationStatus unavailable", exc_info=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
cs = d["climatisationSettings"]
|
||||||
|
result["climatisationSettings"] = {
|
||||||
|
"targetTemperature_C": cs.targetTemperature_C.value,
|
||||||
|
"unitInCar": _str(cs.unitInCar),
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("climatisationSettings unavailable", exc_info=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
wh = d["windowHeatingStatus"]
|
||||||
|
result["windowHeatingStatus"] = {
|
||||||
|
name: _str(win.windowHeatingState)
|
||||||
|
for name, win in wh.windows.items()
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("windowHeatingStatus unavailable", exc_info=True)
|
||||||
|
|
||||||
|
return result or None
|
||||||
|
|
||||||
|
|
||||||
|
def extract_measurements(vehicle) -> dict | None:
|
||||||
|
try:
|
||||||
|
d = vehicle.domains["measurements"]
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
result: dict = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
od = d["odometerStatus"]
|
||||||
|
result["odometerStatus"] = {"odometer": od.odometer.value}
|
||||||
|
except Exception:
|
||||||
|
log.debug("odometerStatus unavailable", exc_info=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
rs = d["rangeStatus"]
|
||||||
|
result["rangeStatus"] = {
|
||||||
|
"electricRange": rs.electricRange.value,
|
||||||
|
"totalRange_km": rs.totalRange_km.value,
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("rangeStatus unavailable", exc_info=True)
|
||||||
|
|
||||||
|
# Battery temperature — reported in Kelvin by the API
|
||||||
|
try:
|
||||||
|
bs = d["temperatureBatteryStatus"]
|
||||||
|
result["temperatureBatteryStatus"] = {
|
||||||
|
"temperatureHvBatteryMax_K": float(bs.temperatureHvBatteryMax_K.value - 273.15),
|
||||||
|
"temperatureHvBatteryMin_K": float(bs.temperatureHvBatteryMin_K.value - 273.15),
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("measurements/temperatureBatteryStatus (temperature) unavailable", exc_info=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
temp = d["temperatureOutsideStatus"]
|
||||||
|
result["temperatureOutsideStatus"] = {
|
||||||
|
"temperatureOutside_C": temp.temperatureOutside_C.value,
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("temperatureOutsideStatus unavailable", exc_info=True)
|
||||||
|
|
||||||
|
return result or None
|
||||||
|
|
||||||
|
|
||||||
|
def extract_readiness(vehicle) -> dict | None:
|
||||||
|
try:
|
||||||
|
d = vehicle.domains["readiness"]
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
result: dict = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
rs = d["readinessStatus"]
|
||||||
|
conn = rs.connectionState
|
||||||
|
warn = rs.connectionWarning
|
||||||
|
result["readinessStatus"] = {
|
||||||
|
"connectionState": {
|
||||||
|
"isOnline": conn.isOnline.value,
|
||||||
|
"isActive": conn.isActive.value,
|
||||||
|
},
|
||||||
|
"connectionWarning": {
|
||||||
|
"insufficientBatteryLevelWarning": warn.insufficientBatteryLevelWarning.value,
|
||||||
|
"insufficientBatteryLevelError": warn.insufficientBatteryLevelError.value,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("readinessStatus unavailable", exc_info=True)
|
||||||
|
|
||||||
|
return result or None
|
||||||
|
|
||||||
|
|
||||||
|
def extract_parking(vehicle) -> dict | None:
|
||||||
|
try:
|
||||||
|
d = vehicle.domains["parking"]
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
result: dict = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
pos = d["parkingPosition"]
|
||||||
|
result["parkingPosition"] = {
|
||||||
|
"lat": pos.lat.value,
|
||||||
|
"lon": pos.lon.value,
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("parkingPosition unavailable", exc_info=True)
|
||||||
|
|
||||||
|
return result or None
|
||||||
|
|
||||||
|
|
||||||
|
def extract_access(vehicle) -> dict | None:
|
||||||
|
try:
|
||||||
|
d = vehicle.domains["access"]
|
||||||
|
except KeyError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
result: dict = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
acc = d["accessStatus"]
|
||||||
|
result["accessStatus"] = {
|
||||||
|
"overallStatus": _str(acc.overallStatus),
|
||||||
|
"doors": {
|
||||||
|
name: {
|
||||||
|
"lockState": _str(door.lockState),
|
||||||
|
"openState": _str(door.openState),
|
||||||
|
}
|
||||||
|
for name, door in acc.doors.items()
|
||||||
|
},
|
||||||
|
"windows": {
|
||||||
|
name: {"openState": _str(win.openState)}
|
||||||
|
for name, win in acc.windows.items()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
except Exception:
|
||||||
|
log.debug("accessStatus unavailable", exc_info=True)
|
||||||
|
|
||||||
|
return result or None
|
||||||
|
|
||||||
|
|
||||||
|
ALL_DOMAINS: dict[str, callable] = {
|
||||||
|
"charging": extract_charging,
|
||||||
|
"climatisation": extract_climatisation,
|
||||||
|
"measurements": extract_measurements,
|
||||||
|
"readiness": extract_readiness,
|
||||||
|
"parking": extract_parking,
|
||||||
|
"access": extract_access,
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── snapshot / store helpers ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def collect_snapshot(vehicle, domains: list[str]) -> dict:
|
||||||
|
snapshot: dict = {"ts": datetime.now(timezone.utc).isoformat()}
|
||||||
|
for domain in domains:
|
||||||
|
data = ALL_DOMAINS[domain](vehicle)
|
||||||
|
if data is not None:
|
||||||
|
snapshot[domain] = data
|
||||||
|
return snapshot
|
||||||
|
|
||||||
|
|
||||||
|
def load_store(path: Path, vin: str, interval: int) -> dict:
|
||||||
|
if path.exists():
|
||||||
|
try:
|
||||||
|
data = json.loads(path.read_text())
|
||||||
|
if isinstance(data, dict) and "records" in data:
|
||||||
|
return data
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
log.warning("Output file is corrupt — starting fresh")
|
||||||
|
return {
|
||||||
|
"meta": {
|
||||||
|
"vin": vin,
|
||||||
|
"created_at": datetime.now(timezone.utc).isoformat(),
|
||||||
|
"interval_seconds": interval,
|
||||||
|
},
|
||||||
|
"records": [],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def save_store(path: Path, store: dict, max_records: int | None) -> None:
|
||||||
|
if max_records and len(store["records"]) > max_records:
|
||||||
|
store["records"] = store["records"][-max_records:]
|
||||||
|
path.write_text(json.dumps(store, indent=2, default=str))
|
||||||
|
|
||||||
|
|
||||||
|
# ── main loop ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def run(args: argparse.Namespace) -> None:
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.DEBUG if args.verbose else logging.INFO,
|
||||||
|
format="%(asctime)s %(levelname)s %(message)s",
|
||||||
|
)
|
||||||
|
|
||||||
|
raw = [d.strip() for d in args.domains.split(",")]
|
||||||
|
domains = list(ALL_DOMAINS) if raw == ["all"] else raw
|
||||||
|
unknown = [d for d in domains if d not in ALL_DOMAINS]
|
||||||
|
if unknown:
|
||||||
|
log.error("Unknown domain(s): %s. Available: %s", unknown, list(ALL_DOMAINS))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
out = Path(args.output)
|
||||||
|
|
||||||
|
log.info("Connecting to WeConnect…")
|
||||||
|
wc = weconnect.WeConnect(
|
||||||
|
username=args.username,
|
||||||
|
password=args.password,
|
||||||
|
updateAfterLogin=False,
|
||||||
|
loginOnInit=True,
|
||||||
|
)
|
||||||
|
wc.login()
|
||||||
|
wc.update()
|
||||||
|
|
||||||
|
vehicles = list(wc.vehicles.values())
|
||||||
|
if not vehicles:
|
||||||
|
log.error("No vehicles found in this WeConnect account")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if args.vin:
|
||||||
|
vehicle = next((v for v in vehicles if v.vin.value == args.vin), None)
|
||||||
|
if not vehicle:
|
||||||
|
log.error(
|
||||||
|
"VIN %s not found. Available: %s",
|
||||||
|
args.vin,
|
||||||
|
[v.vin.value for v in vehicles],
|
||||||
|
)
|
||||||
|
sys.exit(1)
|
||||||
|
else:
|
||||||
|
vehicle = vehicles[0]
|
||||||
|
|
||||||
|
vin = vehicle.vin.value
|
||||||
|
log.info("Vehicle: %s", vin)
|
||||||
|
|
||||||
|
store = load_store(out, vin, args.interval)
|
||||||
|
log.info(
|
||||||
|
"Collecting [%s] every %ds → %s (Ctrl-C to stop)",
|
||||||
|
", ".join(domains),
|
||||||
|
args.interval,
|
||||||
|
out,
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
wc.update()
|
||||||
|
snapshot = collect_snapshot(vehicle, domains)
|
||||||
|
store["records"].append(snapshot)
|
||||||
|
save_store(out, store, args.max_records)
|
||||||
|
log.info("Record #%d saved at %s", len(store["records"]), snapshot["ts"])
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise
|
||||||
|
except Exception:
|
||||||
|
log.exception("Collection failed — will retry at next interval")
|
||||||
|
|
||||||
|
time.sleep(args.interval)
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
log.info("Stopped by user. %d records in %s", len(store["records"]), out)
|
||||||
|
|
||||||
|
|
||||||
|
# ── CLI ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
p = argparse.ArgumentParser(
|
||||||
|
description=__doc__,
|
||||||
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
|
)
|
||||||
|
|
||||||
|
creds = p.add_argument_group(
|
||||||
|
"credentials (also accepted via WC_USER / WC_PASS env vars or -c FILE)"
|
||||||
|
)
|
||||||
|
creds.add_argument(
|
||||||
|
"-c", "--credentials",
|
||||||
|
metavar="FILE",
|
||||||
|
help=(
|
||||||
|
"JSON file with keys: username, password, vin, domains. "
|
||||||
|
"Values are overridden by explicit CLI flags and env vars."
|
||||||
|
),
|
||||||
|
)
|
||||||
|
creds.add_argument(
|
||||||
|
"-u", "--username",
|
||||||
|
default=os.environ.get("WC_USER"),
|
||||||
|
help="WeConnect / MyVolkswagen email",
|
||||||
|
)
|
||||||
|
creds.add_argument(
|
||||||
|
"-p", "--password",
|
||||||
|
default=os.environ.get("WC_PASS"),
|
||||||
|
help="WeConnect password",
|
||||||
|
)
|
||||||
|
|
||||||
|
p.add_argument("--vin", help="Vehicle VIN (uses first vehicle when omitted)")
|
||||||
|
p.add_argument(
|
||||||
|
"-d", "--domains",
|
||||||
|
default=None,
|
||||||
|
metavar="DOMAIN[,DOMAIN…]",
|
||||||
|
help=(
|
||||||
|
"Comma-separated domains to collect, or 'all'. "
|
||||||
|
f"Available: {', '.join(ALL_DOMAINS)}. "
|
||||||
|
"Default: charging,measurements,readiness"
|
||||||
|
),
|
||||||
|
)
|
||||||
|
p.add_argument(
|
||||||
|
"-i", "--interval",
|
||||||
|
type=int,
|
||||||
|
default=300,
|
||||||
|
metavar="SECONDS",
|
||||||
|
help="Collection interval in seconds (default: 300)",
|
||||||
|
)
|
||||||
|
p.add_argument(
|
||||||
|
"-o", "--output",
|
||||||
|
default="vehicle_data.json",
|
||||||
|
metavar="FILE",
|
||||||
|
help="Output JSON file (default: vehicle_data.json)",
|
||||||
|
)
|
||||||
|
p.add_argument(
|
||||||
|
"--max-records",
|
||||||
|
type=int,
|
||||||
|
default=None,
|
||||||
|
metavar="N",
|
||||||
|
help="Keep only the last N records in the file (default: unlimited)",
|
||||||
|
)
|
||||||
|
p.add_argument("-v", "--verbose", action="store_true", help="Enable debug logging")
|
||||||
|
p.add_argument(
|
||||||
|
"--list-domains",
|
||||||
|
action="store_true",
|
||||||
|
help="Print available domains and exit",
|
||||||
|
)
|
||||||
|
|
||||||
|
args = p.parse_args()
|
||||||
|
|
||||||
|
if args.list_domains:
|
||||||
|
print("\n".join(ALL_DOMAINS))
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if args.credentials:
|
||||||
|
creds_path = Path(args.credentials)
|
||||||
|
if not creds_path.exists():
|
||||||
|
p.error(f"Credentials file not found: {args.credentials}")
|
||||||
|
try:
|
||||||
|
creds_data = json.loads(creds_path.read_text())
|
||||||
|
except json.JSONDecodeError as exc:
|
||||||
|
p.error(f"Invalid JSON in credentials file: {exc}")
|
||||||
|
if args.username is None:
|
||||||
|
args.username = creds_data.get("username")
|
||||||
|
if args.password is None:
|
||||||
|
args.password = creds_data.get("password")
|
||||||
|
if args.vin is None:
|
||||||
|
args.vin = creds_data.get("vin")
|
||||||
|
if args.domains is None:
|
||||||
|
raw_domains = creds_data.get("domains")
|
||||||
|
if isinstance(raw_domains, list):
|
||||||
|
args.domains = ",".join(raw_domains)
|
||||||
|
else:
|
||||||
|
args.domains = raw_domains
|
||||||
|
|
||||||
|
if args.domains is None:
|
||||||
|
args.domains = "charging,measurements,readiness"
|
||||||
|
|
||||||
|
if not args.username or not args.password:
|
||||||
|
p.error(
|
||||||
|
"Username and password are required. "
|
||||||
|
"Pass them with -u/-p or set WC_USER / WC_PASS environment variables."
|
||||||
|
)
|
||||||
|
|
||||||
|
run(args)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
weconnect
|
||||||
@@ -0,0 +1,568 @@
|
|||||||
|
from copy import deepcopy
|
||||||
|
|
||||||
|
|
||||||
|
def jay_diff_rev(_old, _new):
|
||||||
|
delta = {}
|
||||||
|
for k in _new.keys():
|
||||||
|
if k in _old:
|
||||||
|
if isinstance(_new[k], dict):
|
||||||
|
res = jay_diff_rev(_old[k], _new[k])
|
||||||
|
if len(res.keys()):
|
||||||
|
delta[k] = res
|
||||||
|
else:
|
||||||
|
_old[k] = _new[k]
|
||||||
|
delta[k] = _new[k]
|
||||||
|
|
||||||
|
return delta
|
||||||
|
|
||||||
|
|
||||||
|
def jay_diff_add(_old, _new):
|
||||||
|
__old = deepcopy(_old)
|
||||||
|
delta = jay_diff_rev(__old, _new)
|
||||||
|
return delta
|
||||||
|
|
||||||
|
|
||||||
|
def jay_diff_del(_old, _new):
|
||||||
|
__new = deepcopy(_new)
|
||||||
|
delta = jay_diff_rev(__new, _old)
|
||||||
|
return delta
|
||||||
|
|
||||||
|
|
||||||
|
def jay_diff_upd(_old, _new, add_if_not_exist=False):
|
||||||
|
delta = {}
|
||||||
|
for k in _new.keys():
|
||||||
|
if k in _old:
|
||||||
|
if isinstance(_new[k], dict):
|
||||||
|
res = jay_diff_upd(_old[k], _new[k], add_if_not_exist)
|
||||||
|
if len(res.keys()):
|
||||||
|
delta[k] = res
|
||||||
|
elif _new[k] != _old[k]:
|
||||||
|
delta[k] = _new[k]
|
||||||
|
elif add_if_not_exist:
|
||||||
|
delta[k] = _new[k]
|
||||||
|
|
||||||
|
return delta
|
||||||
|
|
||||||
|
|
||||||
|
def jay_diff_upd_add(_old, _new):
|
||||||
|
return jay_diff_upd(_old, _new, add_if_not_exist=True)
|
||||||
|
|
||||||
|
|
||||||
|
def jay_diff_full(_old, _new, combine_upd_add=True):
|
||||||
|
diff = {}
|
||||||
|
if combine_upd_add:
|
||||||
|
res = jay_diff_upd_add(_old, _new)
|
||||||
|
if len(res.keys()):
|
||||||
|
diff['update_add'] = res
|
||||||
|
res = jay_diff_del(_old, _new)
|
||||||
|
if len(res.keys()):
|
||||||
|
diff['delete'] = res
|
||||||
|
else:
|
||||||
|
res = jay_diff_upd(_old, _new)
|
||||||
|
if len(res.keys()):
|
||||||
|
diff['update'] = res
|
||||||
|
res = jay_diff_add(_old, _new)
|
||||||
|
if len(res.keys()):
|
||||||
|
diff['add'] = res
|
||||||
|
res = jay_diff_del(_old, _new)
|
||||||
|
if len(res.keys()):
|
||||||
|
diff['delete'] = res
|
||||||
|
|
||||||
|
return diff
|
||||||
|
|
||||||
|
|
||||||
|
def jay_merge_update(_old, _new):
|
||||||
|
for k, v in _new.items():
|
||||||
|
if isinstance(v, dict):
|
||||||
|
r = jay_merge_update(_old.get(k, {}), v)
|
||||||
|
_old[k] = r
|
||||||
|
else:
|
||||||
|
_old[k] = _new[k]
|
||||||
|
return _old
|
||||||
|
|
||||||
|
|
||||||
|
def jay_merge_add(_old, _new):
|
||||||
|
for k, v in _new.items():
|
||||||
|
if isinstance(v, dict):
|
||||||
|
r = jay_merge_add(_old.get(k, {}), v)
|
||||||
|
if k in _old:
|
||||||
|
_old[k].update(r)
|
||||||
|
else:
|
||||||
|
_old[k] = r
|
||||||
|
else:
|
||||||
|
_old[k] = _new[k]
|
||||||
|
return _old
|
||||||
|
|
||||||
|
|
||||||
|
def jay_merge_delete(_old, _new):
|
||||||
|
for k, v in _new.items():
|
||||||
|
if isinstance(v, dict):
|
||||||
|
jay_merge_delete(_old[k], _new[k])
|
||||||
|
if len(_old[k].keys()) == 0:
|
||||||
|
del _old[k]
|
||||||
|
else:
|
||||||
|
if k in _old:
|
||||||
|
del _old[k]
|
||||||
|
|
||||||
|
return _old
|
||||||
|
|
||||||
|
|
||||||
|
def jay_merge_full(_old, _diff):
|
||||||
|
res = _old
|
||||||
|
if "update" in _diff:
|
||||||
|
res = jay_merge_update(res, _diff['update'])
|
||||||
|
if "update_add" in _diff:
|
||||||
|
res = jay_merge_update(res, _diff['update_add'])
|
||||||
|
if "add" in _diff:
|
||||||
|
res = jay_merge_add(res, _diff['add'])
|
||||||
|
if "delete" in _diff:
|
||||||
|
res = jay_merge_delete(res, _diff['delete'])
|
||||||
|
|
||||||
|
return res
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
result = jay_diff_add({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_diff_add({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'})
|
||||||
|
assert result == {}
|
||||||
|
|
||||||
|
result = jay_diff_add({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'})
|
||||||
|
assert result == {}
|
||||||
|
|
||||||
|
result = jay_diff_add({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'})
|
||||||
|
assert result == {'d':'icecream'}
|
||||||
|
|
||||||
|
result = jay_diff_add({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'})
|
||||||
|
assert result == {'b':'fries'}
|
||||||
|
|
||||||
|
result = jay_diff_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}, {'c': {'f': 'coffee'}})
|
||||||
|
assert result == {'c': {'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_diff_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}})
|
||||||
|
assert result == {}
|
||||||
|
|
||||||
|
result = jay_diff_del({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'})
|
||||||
|
assert result == {'d':'icecream'}
|
||||||
|
|
||||||
|
result = jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'})
|
||||||
|
assert result == {}
|
||||||
|
|
||||||
|
result = jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'})
|
||||||
|
assert result == {}
|
||||||
|
|
||||||
|
result = jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries'})
|
||||||
|
assert result == {'c':'pepsi'}
|
||||||
|
|
||||||
|
result = jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'})
|
||||||
|
assert result == {}
|
||||||
|
|
||||||
|
result = jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries'})
|
||||||
|
assert result == {'c': {'e': 'coke', 'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'coke'}})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_diff_del({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}})
|
||||||
|
assert result == {}
|
||||||
|
|
||||||
|
result = jay_diff_upd({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'potatoes'})
|
||||||
|
assert result == {'a':'hotdog', 'b':'potatoes'}
|
||||||
|
|
||||||
|
result = jay_diff_upd({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi'}})
|
||||||
|
assert result == {'c': {'e': 'pepsi'}}
|
||||||
|
|
||||||
|
result = jay_diff_upd({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'fries'})
|
||||||
|
assert result == {'a':'hotdog'}
|
||||||
|
|
||||||
|
result = jay_diff_upd({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'})
|
||||||
|
assert result == {'c':'coke'}
|
||||||
|
|
||||||
|
result = jay_diff_upd({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'})
|
||||||
|
assert result == {'c':'coke'}
|
||||||
|
|
||||||
|
result = jay_diff_upd({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}, {'c': {'f': 'coffee'}})
|
||||||
|
assert result == {}
|
||||||
|
|
||||||
|
result = jay_diff_upd({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}})
|
||||||
|
assert result == {'c': {'e': 'pepsi'}}
|
||||||
|
|
||||||
|
# Update/add
|
||||||
|
result = jay_diff_upd_add({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'potatoes', 'd': 'icecream'})
|
||||||
|
assert result == {'a':'hotdog', 'b':'potatoes', 'd': 'icecream'}
|
||||||
|
|
||||||
|
result = jay_diff_upd_add({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}, 'b':'potatoes'})
|
||||||
|
assert result == {'b':'potatoes', 'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}}
|
||||||
|
|
||||||
|
result = jay_diff_upd_add({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'fries'})
|
||||||
|
assert result == {'a':'hotdog'}
|
||||||
|
|
||||||
|
result = jay_diff_upd_add({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}})
|
||||||
|
assert result == {'c': {'e': 'pepsi'}}
|
||||||
|
|
||||||
|
#####################
|
||||||
|
result = jay_diff_upd_add({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'potatoes'})
|
||||||
|
assert result == {'a':'hotdog', 'b':'potatoes'}
|
||||||
|
|
||||||
|
result = jay_diff_upd_add({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi'}})
|
||||||
|
assert result == {'c': {'e': 'pepsi'}}
|
||||||
|
|
||||||
|
result = jay_diff_upd_add({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'fries'})
|
||||||
|
assert result == {'a':'hotdog'}
|
||||||
|
|
||||||
|
result = jay_diff_upd_add({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'})
|
||||||
|
assert result == {'c': 'coke', 'd': 'icecream'}
|
||||||
|
|
||||||
|
result = jay_diff_upd_add({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'})
|
||||||
|
assert result == {'b': 'fries', 'c': 'coke'}
|
||||||
|
|
||||||
|
result = jay_diff_upd_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}, {'c': {'f': 'coffee'}})
|
||||||
|
assert result == {'c': {'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_diff_upd_add({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}})
|
||||||
|
assert result == {'c': {'e': 'pepsi'}}
|
||||||
|
|
||||||
|
result = jay_diff_upd_add({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee', 'h': 'cake'}})
|
||||||
|
assert result == {'c': {'e': 'pepsi', 'h': 'cake'}}
|
||||||
|
|
||||||
|
# jay_diff_full
|
||||||
|
combine_upd_add = False
|
||||||
|
|
||||||
|
result = jay_diff_full({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, combine_upd_add)
|
||||||
|
assert result == {'add': {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, combine_upd_add)
|
||||||
|
assert result == {'update': {'c': 'coke'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'d': 'icecream'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'}, combine_upd_add)
|
||||||
|
assert result == {'add': {'d': 'icecream'}, 'delete': {'b': 'fries'}, 'update': {'c': 'coke'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, combine_upd_add)
|
||||||
|
assert result == {'add': {'b': 'fries'}, 'delete': {'d': 'icecream'}, 'update': {'c': 'coke'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}, {'c': {'f': 'coffee'}}, combine_upd_add)
|
||||||
|
assert result == {'add': {'c': {'f': 'coffee'}}, 'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, combine_upd_add)
|
||||||
|
assert result == {'add': {'b': 'fries'}, 'delete': {'d': 'icecream'}, 'update': {'c': 'coke'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, combine_upd_add)
|
||||||
|
assert result == {}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, combine_upd_add)
|
||||||
|
assert result == {'update': {'c': 'pepsi'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': 'pepsi'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, combine_upd_add)
|
||||||
|
assert result == {'update': {'c': 'coke'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': {'e': 'coke'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'coke'}}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'potatoes'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog', 'b': 'potatoes'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi'}}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, 'update': {'c': {'e': 'pepsi'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'fries'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}, combine_upd_add)
|
||||||
|
assert result == {'update': {'c': {'e': 'pepsi'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'potatoes', 'd': 'icecream'}, combine_upd_add)
|
||||||
|
assert result == {'add': {'d': 'icecream'}, 'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog', 'b': 'potatoes'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}, 'b':'potatoes'}, combine_upd_add)
|
||||||
|
assert result == {'add': {'c': {'g': 'tea', 'h': 'cake'}}, 'delete': {'a': 'hamburger', 'c': {'f': 'coffee'}}, 'update': {'b': 'potatoes', 'c': {'e': 'pepsi'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'fries'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}, combine_upd_add)
|
||||||
|
assert result == {'update': {'c': {'e': 'pepsi'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee', 'h': 'cake'}}, combine_upd_add)
|
||||||
|
assert result == {'add': {'c': {'h': 'cake'}}, 'update': {'c': {'e': 'pepsi'}}}
|
||||||
|
|
||||||
|
# ToDo: jay_diff_full
|
||||||
|
combine_upd_add = True
|
||||||
|
|
||||||
|
result = jay_diff_full({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, combine_upd_add)
|
||||||
|
assert result == {'update_add': {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, combine_upd_add)
|
||||||
|
assert result == {'update_add': {'c': 'coke'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'d': 'icecream'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'b': 'fries'}, 'update_add': {'c': 'coke', 'd': 'icecream'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'d': 'icecream'}, 'update_add': {'b': 'fries', 'c': 'coke'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}, {'c': {'f': 'coffee'}}, combine_upd_add)
|
||||||
|
assert result == {'update_add': {'c': {'f': 'coffee'}}, 'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'d': 'icecream'}, 'update_add': {'b': 'fries', 'c': 'coke'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, combine_upd_add)
|
||||||
|
assert result == {}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, combine_upd_add)
|
||||||
|
assert result == {'update_add': {'c': 'pepsi'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': 'pepsi'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, combine_upd_add)
|
||||||
|
assert result == {'update_add': {'c': 'coke'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': {'e': 'coke'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'coke'}}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'potatoes'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog', 'b': 'potatoes'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi'}}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, 'update_add': {'c': {'e': 'pepsi'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'fries'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}, combine_upd_add)
|
||||||
|
assert result == {'update_add': {'c': {'e': 'pepsi'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'potatoes', 'd': 'icecream'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog', 'b': 'potatoes', 'd': 'icecream'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}, 'b':'potatoes'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'a': 'hamburger', 'c': {'f': 'coffee'}}, 'update_add': {'b': 'potatoes', 'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hotdog', 'b':'fries'}, combine_upd_add)
|
||||||
|
assert result == {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog'}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}, combine_upd_add)
|
||||||
|
assert result == {'update_add': {'c': {'e': 'pepsi'}}}
|
||||||
|
|
||||||
|
result = jay_diff_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee', 'h': 'cake'}}, combine_upd_add)
|
||||||
|
assert result == {'update_add': {'c': {'e': 'pepsi', 'h': 'cake'}}}
|
||||||
|
|
||||||
|
# Merge
|
||||||
|
result = jay_merge_add({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'d': 'icecream'})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}, 'd':'icecream'}
|
||||||
|
|
||||||
|
result = jay_merge_add({'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, {'d': 'icecream'})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'f': 'coffee'}, 'd':'icecream'}
|
||||||
|
|
||||||
|
result = jay_merge_add({'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}, 'd': 'icecream'}, {'d': 'icecream'})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'f': 'coffee'}, 'd':'icecream'}
|
||||||
|
|
||||||
|
result = jay_merge_delete({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}, 'd': 'icecream'}, {'d': 'icecream'})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_delete({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'f': 'coffee'}})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'coke'}}
|
||||||
|
|
||||||
|
result = jay_merge_delete({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'coke'}})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'f': 'coffee'}}
|
||||||
|
|
||||||
|
# jay_merge_full
|
||||||
|
# combine_upd_add = False
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'add': {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'update': {'c': 'pepsi'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, {'delete': {'d': 'icecream'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'add': {'d': 'icecream'}, 'delete': {'b': 'fries'}, 'update': {'c': 'coke'}})
|
||||||
|
assert result == {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'add': {'b': 'fries'}, 'delete': {'d': 'icecream'}, 'update': {'c': 'coke'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}, {'add': {'c': {'f': 'coffee'}}, 'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}})
|
||||||
|
assert result == {'c': {'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'add': {'b': 'fries'}, 'delete': {'d': 'icecream'}, 'update': {'c': 'coke'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'update': {'c': 'pepsi'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'delete': {'c': 'pepsi'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'update': {'c': 'coke'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke'}}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}})
|
||||||
|
assert result == {'c': {'e': 'coke'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog', 'b': 'potatoes'}})
|
||||||
|
assert result == {'a':'hotdog', 'b':'potatoes'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, 'update': {'c': {'e': 'pepsi'}}})
|
||||||
|
assert result == {'c': {'e': 'pepsi'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog'}})
|
||||||
|
assert result == {'a':'hotdog', 'b':'fries'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'update': {'c': {'e': 'pepsi'}}})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'add': {'d': 'icecream'}, 'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog', 'b': 'potatoes'}})
|
||||||
|
assert result == {'a':'hotdog', 'b':'potatoes', 'd': 'icecream'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'add': {'c': {'g': 'tea', 'h': 'cake'}}, 'delete': {'a': 'hamburger', 'c': {'f': 'coffee'}}, 'update': {'b': 'potatoes', 'c': {'e': 'pepsi'}}})
|
||||||
|
assert result == {'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}, 'b':'potatoes'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update': {'a': 'hotdog'}})
|
||||||
|
assert result == {'a':'hotdog', 'b':'fries'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'update': {'c': {'e': 'pepsi'}}})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'add': {'c': {'h': 'cake'}}, 'update': {'c': {'e': 'pepsi'}}})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee', 'h': 'cake'}}
|
||||||
|
|
||||||
|
# ToDo: jay_merge_full
|
||||||
|
# combine_upd_add = True
|
||||||
|
|
||||||
|
result = jay_merge_full({}, {'update_add': {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'update_add': {'c': 'coke'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, {'delete': {'d': 'icecream'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'delete': {'b': 'fries'}, 'update_add': {'c': 'coke', 'd': 'icecream'}})
|
||||||
|
assert result == {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'delete': {'d': 'icecream'}, 'update_add': {'b': 'fries', 'c': 'coke'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}, {'update_add': {'c': {'f': 'coffee'}}, 'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}})
|
||||||
|
assert result == {'c': {'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'delete': {'d': 'icecream'}, 'update_add': {'b': 'fries', 'c': 'coke'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'update_add': {'c': 'pepsi'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'delete': {'c': 'pepsi'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'update_add': {'c': 'coke'}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke'}}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}})
|
||||||
|
assert result == {'c': {'e': 'coke'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog', 'b': 'potatoes'}})
|
||||||
|
assert result == {'a':'hotdog', 'b':'potatoes'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, 'update_add': {'c': {'e': 'pepsi'}}})
|
||||||
|
assert result == {'c': {'e': 'pepsi'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog'}})
|
||||||
|
assert result == {'a':'hotdog', 'b':'fries'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'update_add': {'c': {'e': 'pepsi'}}})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog', 'b': 'potatoes', 'd': 'icecream'}})
|
||||||
|
assert result == {'a':'hotdog', 'b':'potatoes', 'd': 'icecream'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'a': 'hamburger', 'c': {'f': 'coffee'}}, 'update_add': {'b': 'potatoes', 'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}}})
|
||||||
|
assert result == {'b':'potatoes', 'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'c': {'e': 'coke', 'f': 'coffee'}}, 'update_add': {'a': 'hotdog'}})
|
||||||
|
assert result == {'a':'hotdog', 'b':'fries'}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'update_add': {'c': {'e': 'pepsi'}}})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a':'hamburger', 'b':'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'update_add': {'c': {'e': 'pepsi', 'h': 'cake'}}})
|
||||||
|
assert result == {'a':'hamburger', 'b':'fries', 'c': {'e': 'pepsi', 'f': 'coffee', 'h': 'cake'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({}, {'add': {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}
|
||||||
|
|
||||||
|
result = jay_merge_full({}, {'add': {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': {'coffee': {'h': 'black'}}}}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': {'coffee': {'h': 'black'}}}}
|
||||||
|
|
||||||
|
result = jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': {'coffee': {'h': 'black'}}}}, {'add': {'c': {'f': {'coffee': {'j': 'sugar'}}}}})
|
||||||
|
assert result == {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': {'coffee': {'h': 'black', 'j': 'sugar'}}}}
|
||||||
|
|
||||||
|
old = {'charging': {
|
||||||
|
'batteryStatus': {'value': {'carCapturedTimestamp': '2024-10-19T05:34:34Z', 'cruisingRangeElectric_km': 192}},
|
||||||
|
'chargingStatus': {'value': {'carCapturedTimestamp': '2024-10-19T05:34:34Z'}},
|
||||||
|
'chargingSettings': {'value': {'carCapturedTimestamp': '2024-10-19T05:34:30Z'}},
|
||||||
|
'plugStatus': {'value': {'carCapturedTimestamp': '2024-10-19T05:34:29Z'}}}}
|
||||||
|
update = {'charging': {
|
||||||
|
'batteryStatus': {'value': {'carCapturedTimestamp': '2024-10-19T05:35:46Z', 'cruisingRangeElectric_km': 191}},
|
||||||
|
'chargingStatus': {'value': {'carCapturedTimestamp': '2024-10-19T05:35:46Z'}}}}
|
||||||
|
add = {'charging': {
|
||||||
|
'batteryStatus': {'value': {'currentSOC_pct': 55}}},
|
||||||
|
'fuelStatus': {'rangeStatus': {'value': {'primaryEngine': {'currentSOC_pct': 55}}}},
|
||||||
|
'measurements': {'fuelLevelStatus': {'value': {'currentSOC_pct': 55}}}}
|
||||||
|
|
||||||
|
delete = {'charging': {
|
||||||
|
'chargingSettings': {'value': {'carCapturedTimestamp': '2024-10-19T05:34:30Z'}},
|
||||||
|
'plugStatus': {'value': {'carCapturedTimestamp': '2024-10-19T05:34:29Z'}}}}
|
||||||
|
|
||||||
|
result = jay_merge_full(old, {'update':update, 'add':add, 'delete':delete})
|
||||||
|
assert result == old
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user