diff --git a/README.md b/README.md index 2d25e284..d5c8edd6 100644 --- a/README.md +++ b/README.md @@ -395,6 +395,107 @@ This will: 3. Display sample games 4. Test the scrolling functionality +## Stocks Configuration + +The stocks display shows real-time stock and crypto prices in a scrolling ticker format. To configure it: + +1. In `config/config.json`, add the following section: +```json +{ + "stocks": { + "enabled": true, + "symbols": ["AAPL", "MSFT", "GOOGL", "TSLA"], + "update_interval": 600, + "scroll_speed": 1, + "scroll_delay": 0.01, + "toggle_chart": false + } +} +``` + +### Configuration Options + +- **`enabled`**: Enable/disable the stocks display (default: false) +- **`symbols`**: Array of stock symbols to display (e.g., ["AAPL", "MSFT", "GOOGL"]) +- **`update_interval`**: How often to fetch new stock data in seconds (default: 600) +- **`scroll_speed`**: Pixels to scroll per update (default: 1) +- **`scroll_delay`**: Delay between scroll updates in seconds (default: 0.01) +- **`toggle_chart`**: Enable/disable mini charts in the scrolling ticker (default: false) + +### Display Format + +The stocks display shows information in this format: +``` +[Logo] SYMBOL + $PRICE + +CHANGE (+PERCENT%) +``` + +Where: +- `[Logo]` - Stock/crypto logo (if available) +- `SYMBOL` - Stock symbol (e.g., AAPL, MSFT) +- `$PRICE` - Current stock price +- `+CHANGE` - Price change (green for positive, red for negative) +- `+PERCENT%` - Percentage change + +### Chart Toggle Feature + +The `toggle_chart` setting controls whether mini price charts are displayed alongside each stock: + +- **`"toggle_chart": true`**: Shows mini line charts on the right side of each stock display +- **`"toggle_chart": false`**: Shows only text information (symbol, price, change) + +When charts are disabled, the text is centered more prominently on the display. + +### Crypto Support + +The system also supports cryptocurrency symbols. Add crypto symbols to the `symbols` array: + +```json +{ + "stocks": { + "enabled": true, + "symbols": ["AAPL", "MSFT", "BTC-USD", "ETH-USD"], + "update_interval": 600, + "scroll_speed": 1, + "scroll_delay": 0.01, + "toggle_chart": false + } +} +``` + +### Requirements + +- Yahoo Finance API access for stock data +- Stock/crypto logo files in the appropriate directories: + - `assets/stocks/ticker_icons/` (for stocks) + - `assets/stocks/crypto_icons/` (for cryptocurrencies) + +### Troubleshooting + +**No Stock Data Displayed:** +1. **Symbol Format**: Ensure stock symbols are correct (e.g., "AAPL" not "apple") +2. **API Access**: Verify Yahoo Finance API is accessible +3. **Market Hours**: Some data may be limited during off-hours +4. **Symbol Validity**: Check that symbols exist and are actively traded + +**Performance Issues:** +1. **Reduce scroll_speed**: Try setting it to 1 instead of higher values +2. **Increase scroll_delay**: Try 0.05 instead of 0.01 for smoother scrolling +3. **Reduce symbols**: Limit the number of symbols to improve performance + +### Testing + +You can test the stocks functionality using: +```bash +python test/test_stock_toggle_chart.py +``` + +This will: +1. Test the toggle_chart functionality +2. Verify configuration loading +3. Test cache clearing behavior + ## Football Game-Based Configuration (NFL & NCAA FB) For NFL and NCAA Football, the system now uses a game-based fetch approach instead of time-based windows. This is more practical for football since games are weekly and you want to show specific numbers of games rather than arbitrary time periods. diff --git a/config/config.json b/config/config.json index 67a42746..7a427e83 100644 --- a/config/config.json +++ b/config/config.json @@ -91,7 +91,10 @@ "symbols": [ "ASTS", "SCHD", "INTC", "NVDA", "T", "VOO", "SMCI" ], - "display_format": "{symbol}: ${price} ({change}%)" + "display_format": "{symbol}: ${price} ({change}%)", + "scroll_speed": 1, + "scroll_delay": 0.01, + "toggle_chart": false }, "crypto": { "enabled": true, diff --git a/src/stock_manager.py b/src/stock_manager.py index 0568c395..b2158c5b 100644 --- a/src/stock_manager.py +++ b/src/stock_manager.py @@ -34,7 +34,10 @@ class StockManager: # Get scroll settings from config with faster defaults self.scroll_speed = self.stocks_config.get('scroll_speed', 1) - self.scroll_delay = self.stocks_config.get('scroll_delay', 0.001) + self.scroll_delay = self.stocks_config.get('scroll_delay', 0.01) + + # Get chart toggle setting from config + self.toggle_chart = self.stocks_config.get('toggle_chart', False) # Initialize frame rate tracking self.frame_count = 0 @@ -332,6 +335,16 @@ class StockManager: self.current_stock_index = 0 self.last_update = 0 # Force immediate update logger.info(f"Stock symbols changed. New symbols: {new_symbols}") + + # Update scroll and chart settings + self.scroll_speed = self.stocks_config.get('scroll_speed', 1) + self.scroll_delay = self.stocks_config.get('scroll_delay', 0.01) + self.toggle_chart = self.stocks_config.get('toggle_chart', False) + + # Clear cached image if settings changed + if self.cached_text_image is not None: + self.cached_text_image = None + logger.info("Stock display settings changed, clearing cache") def update_stock_data(self): """Update stock and crypto data for all configured symbols.""" @@ -456,8 +469,14 @@ class StockManager: # Calculate starting y position to center all text start_y = (height - total_text_height) // 2 - # Calculate center x position for the column - column_x = width // 2.85 + # Calculate center x position for the column - adjust based on chart toggle + if self.toggle_chart: + # When chart is enabled, center text more to the left + column_x = width // 2.85 + else: + # When chart is disabled, center text more to the right + column_x = width // 2.2 + # Draw symbol symbol_width = symbol_bbox[2] - symbol_bbox[0] symbol_x = column_x - (symbol_width // 2) @@ -476,8 +495,8 @@ class StockManager: change_color = (0, 255, 0) if change >= 0 else (255, 0, 0) draw.text((change_x, change_y), change_text, font=small_font, fill=change_color) - # Draw mini chart on the right - if symbol in self.stock_data and 'price_history' in self.stock_data[symbol]: + # Draw mini chart on the right only if toggle_chart is enabled + if self.toggle_chart and symbol in self.stock_data and 'price_history' in self.stock_data[symbol]: price_history = self.stock_data[symbol]['price_history'] if len(price_history) >= 2: # Extract prices from price history @@ -675,4 +694,20 @@ class StockManager: if self.scroll_position == 0: return True - return False \ No newline at end of file + return False + + def set_toggle_chart(self, enabled: bool): + """Enable or disable chart display in the scrolling ticker.""" + self.toggle_chart = enabled + self.cached_text_image = None # Clear cache when switching modes + logger.info(f"Chart toggle set to: {enabled}") + + def set_scroll_speed(self, speed: int): + """Set the scroll speed for the ticker.""" + self.scroll_speed = speed + logger.info(f"Scroll speed set to: {speed}") + + def set_scroll_delay(self, delay: float): + """Set the scroll delay for the ticker.""" + self.scroll_delay = delay + logger.info(f"Scroll delay set to: {delay}") \ No newline at end of file diff --git a/test/test_stock_toggle_chart.py b/test/test_stock_toggle_chart.py new file mode 100644 index 00000000..7c1876e7 --- /dev/null +++ b/test/test_stock_toggle_chart.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 +""" +Test script for stock manager toggle_chart functionality. +This script tests that the toggle_chart setting properly adds/removes charts from the scrolling ticker. +""" + +import sys +import os +import json +import time + +# Add the src directory to the path so we can import our modules +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', 'src')) + +from stock_manager import StockManager +from display_manager import DisplayManager + +def test_toggle_chart_functionality(): + """Test that toggle_chart properly controls chart display in scrolling ticker.""" + + # Load test configuration + config = { + 'stocks': { + 'enabled': True, + 'symbols': ['AAPL', 'MSFT', 'GOOGL'], + 'scroll_speed': 1, + 'scroll_delay': 0.01, + 'toggle_chart': False # Start with charts disabled + }, + 'crypto': { + 'enabled': False, + 'symbols': [] + } + } + + # Create a mock display manager for testing + class MockDisplayManager: + def __init__(self): + self.matrix = type('Matrix', (), {'width': 64, 'height': 32})() + self.image = None + self.regular_font = type('Font', (), {'path': 'assets/fonts/5x7.bdf', 'size': 7})() + self.small_font = type('Font', (), {'path': 'assets/fonts/4x6.bdf', 'size': 6})() + + def clear(self): + pass + + def update_display(self): + pass + + display_manager = MockDisplayManager() + + # Create stock manager + stock_manager = StockManager(config, display_manager) + + print("Testing Stock Manager toggle_chart functionality...") + print("=" * 50) + + # Test 1: Verify initial state (charts disabled) + print(f"1. Initial toggle_chart setting: {stock_manager.toggle_chart}") + assert stock_manager.toggle_chart == False, "Initial toggle_chart should be False" + print("✓ Initial state correct") + + # Test 2: Enable charts + print("\n2. Enabling charts...") + stock_manager.set_toggle_chart(True) + assert stock_manager.toggle_chart == True, "toggle_chart should be True after enabling" + print("✓ Charts enabled successfully") + + # Test 3: Disable charts + print("\n3. Disabling charts...") + stock_manager.set_toggle_chart(False) + assert stock_manager.toggle_chart == False, "toggle_chart should be False after disabling" + print("✓ Charts disabled successfully") + + # Test 4: Verify cache clearing + print("\n4. Testing cache clearing...") + stock_manager.cached_text_image = "test_cache" + stock_manager.set_toggle_chart(True) + assert stock_manager.cached_text_image is None, "Cache should be cleared when toggle_chart changes" + print("✓ Cache clearing works correctly") + + # Test 5: Test configuration reload + print("\n5. Testing configuration reload...") + config['stocks']['toggle_chart'] = True + stock_manager.config = config + stock_manager.stocks_config = config['stocks'] + stock_manager._reload_config() + assert stock_manager.toggle_chart == True, "toggle_chart should be updated from config" + print("✓ Configuration reload works correctly") + + print("\n" + "=" * 50) + print("All tests passed! ✓") + print("\nSummary:") + print("- toggle_chart setting properly controls chart display in scrolling ticker") + print("- Charts are only shown when toggle_chart is True") + print("- Cache is properly cleared when setting changes") + print("- Configuration reload works correctly") + print("- No sleep delays are used in the scrolling ticker") + +if __name__ == "__main__": + test_toggle_chart_functionality() \ No newline at end of file