diff --git a/Readme.md b/Readme.md index dad2b67..7594ffe 100644 --- a/Readme.md +++ b/Readme.md @@ -4,11 +4,11 @@ Publish fitness data from Gadgetbridge to Home Assistant via MQTT directly from ## Features -- 📊 Publishes steps, heart rate, sleep, battery, weight, and more -- 🔄 Auto-syncs with your fitness band every 5 minutes -- 🏠 Home Assistant auto-discovery via MQTT -- �� Runs entirely on your phone (no server needed) -- 🚀 Auto-starts on boot +- Publishes steps, heart rate, sleep, battery, weight, and more +- Auto-syncs with your fitness band every 5 minutes +- Home Assistant auto-discovery via MQTT +- Runs entirely on your phone (no server needed) +- Auto-starts on boot ## Quick Setup @@ -132,15 +132,3 @@ Sensors are automatically discovered via MQTT. They will appear under: - Publishes sensor data via MQTT 2. Home Assistant discovers sensors automatically via MQTT discovery - -## Files - -- `main.py` - Main MQTT publisher script -- `setup.py` - Interactive setup script -- `~/.config/gadgetbridge_mqtt/config.json` - Configuration -- `~/.termux/boot/start_gb_mqtt` - Autostart script -- `~/gb_mqtt.log` - Log file - -## License - -MIT diff --git a/setup.py b/setup.py index da0af22..82526d7 100644 --- a/setup.py +++ b/setup.py @@ -30,15 +30,27 @@ def get_input(prompt, default=None, required=True): prompt = f"{prompt} [{default}]: " else: prompt = f"{prompt}: " - - value = input(prompt).strip() - + + try: + value = input(prompt).strip() + except EOFError: + # Non-interactive environment (e.g. piped via curl | python) + # Return default when provided, otherwise raise a clear error + if default is not None: + return default + raise RuntimeError( + "No stdin available for interactive input.\n" + "Provide configuration via environment variables or run setup.py interactively.\n" + "Example (non-interactive):\n" + " MQTT_BROKER=1.2.3.4 MQTT_PORT=1883 \\n+ MQTT_USERNAME=user MQTT_PASSWORD=pass \\n+ EXPORT_DIR=/storage/emulated/0/Documents/GB_Export \\n+ PUBLISH_INTERVAL=300 \\n+ curl -sL https://git.olli.info/Oliver/GadgetbridgeMqtt/raw/branch/main/setup.py | python" + ) + if not value and default: return default if not value and required: print("This field is required!") return get_input(prompt.replace(f" [{default}]", "").replace(": ", ""), default, required) - + return value @@ -61,6 +73,26 @@ def setup_mqtt(): return config +def load_noninteractive_config_from_env(): + """Load configuration from environment variables when stdin is not a TTY. + + Required: MQTT_BROKER + Optional: MQTT_PORT, MQTT_USERNAME, MQTT_PASSWORD, EXPORT_DIR, PUBLISH_INTERVAL + """ + cfg = {} + broker = os.environ.get("MQTT_BROKER") + if not broker: + return None + + cfg["mqtt_broker"] = broker + cfg["mqtt_port"] = int(os.environ.get("MQTT_PORT", "1883")) + cfg["mqtt_username"] = os.environ.get("MQTT_USERNAME", "") + cfg["mqtt_password"] = os.environ.get("MQTT_PASSWORD", "") + cfg["export_dir"] = os.environ.get("EXPORT_DIR", DEFAULT_EXPORT_DIR) + cfg["publish_interval"] = int(os.environ.get("PUBLISH_INTERVAL", str(DEFAULT_INTERVAL))) + return cfg + + def save_config(config): """Save configuration to file""" os.makedirs(CONFIG_DIR, exist_ok=True)