PHPackages                             ekstremedia/laravel-netatmo-weather - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. ekstremedia/laravel-netatmo-weather

ActiveLibrary[API Development](/categories/api)

ekstremedia/laravel-netatmo-weather
===================================

A Laravel package for integrating Netatmo Weather Station API with your Laravel application

v1.2.5(4mo ago)0772MITPHPPHP ^8.2CI passing

Since Aug 10Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/ekstremedia/laravel-netatmo-weather)[ Packagist](https://packagist.org/packages/ekstremedia/laravel-netatmo-weather)[ RSS](/packages/ekstremedia-laravel-netatmo-weather/feed)WikiDiscussions main Synced today

READMEChangelog (7)Dependencies (7)Versions (15)Used By (0)

Laravel Netatmo Weather
=======================

[](#laravel-netatmo-weather)

[![Latest Version](https://camo.githubusercontent.com/3cc19a6599d45412e93d3670558afdd3b7a1743fe1e4f8577b1d8462a944ea20/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f656b737472656d656469612f6c61726176656c2d6e657461746d6f2d77656174686572)](https://packagist.org/packages/ekstremedia/laravel-netatmo-weather)[![Total Downloads](https://camo.githubusercontent.com/b6398d1d8d38b2d9a2b22ff72670d0b50c6bcbbba826d8f121f3da8ecc843979/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f656b737472656d656469612f6c61726176656c2d6e657461746d6f2d77656174686572)](https://packagist.org/packages/ekstremedia/laravel-netatmo-weather)[![Tests](https://github.com/ekstremedia/laravel-netatmo-weather/workflows/Tests/badge.svg)](https://github.com/ekstremedia/laravel-netatmo-weather/actions)[![codecov](https://camo.githubusercontent.com/91d0688267061a57f130ae6efdae9587f663f3ed92d602431ebdf59075cbe28c/68747470733a2f2f636f6465636f762e696f2f67682f656b737472656d656469612f6c61726176656c2d6e657461746d6f2d776561746865722f6272616e63682f6d61696e2f67726170682f62616467652e737667)](https://codecov.io/gh/ekstremedia/laravel-netatmo-weather)[![PHP Version](https://camo.githubusercontent.com/d3a0b17ef7748a34c74260682f9e71542545955adfe4cd578c08df23c899ba28/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f656b737472656d656469612f6c61726176656c2d6e657461746d6f2d77656174686572)](https://packagist.org/packages/ekstremedia/laravel-netatmo-weather)[![Laravel Version](https://camo.githubusercontent.com/6700a462e1c28081bfde592c85267b91041cd55730b0449cd8d53f631ce57486/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31312e7825323025374325323031322e782d6f72616e6765)](https://laravel.com)[![License](https://camo.githubusercontent.com/dafaf168215d2866cd2374c3ef5973044ebecc495d582daa1324e16e53eae19e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f656b737472656d656469612f6c61726176656c2d6e657461746d6f2d77656174686572)](https://github.com/ekstremedia/laravel-netatmo-weather/blob/main/LICENSE)

A Laravel package for integrating Netatmo Weather Station API with your Laravel application. This package provides an easy-to-use interface for authenticating with Netatmo, fetching weather data, and storing it in your database.

Features
--------

[](#features)

- OAuth2 authentication with Netatmo API
- Automatic token refresh
- Fetch and store weather station data
- Support for multiple weather stations per user
- **Device selection** - Manage multiple Netatmo devices with manual device selection for each configuration
- **Module lifecycle management** - Automatic archiving of disconnected/removed modules with manual deletion
- **Public sharing** - Share weather data publicly with customizable per-station access
- Built-in database models and migrations
- Encrypted storage of sensitive credentials
- Configurable caching of weather data
- Full UI scaffolding (optional)

Requirements
------------

[](#requirements)

- PHP 8.2 or higher
- Laravel 11.0 or 12.0
- A Netatmo Weather Station
- Netatmo API credentials (Client ID and Client Secret)

Installation
------------

[](#installation)

### 1. Install the package via Composer

[](#1-install-the-package-via-composer)

```
composer require ekstremedia/laravel-netatmo-weather
```

### 2. Publish the configuration file

[](#2-publish-the-configuration-file)

```
php artisan vendor:publish --tag=config --provider="Ekstremedia\NetatmoWeather\NetatmoWeatherServiceProvider"
```

### 3. Publish the public assets (optional, if using the included UI)

[](#3-publish-the-public-assets-optional-if-using-the-included-ui)

```
php artisan vendor:publish --tag=public --provider="Ekstremedia\NetatmoWeather\NetatmoWeatherServiceProvider"
```

### 4. Run the migrations

[](#4-run-the-migrations)

```
php artisan migrate
```

Configuration
-------------

[](#configuration)

### 1. Get Netatmo API Credentials

[](#1-get-netatmo-api-credentials)

1. Go to [Netatmo Developer Portal](https://dev.netatmo.com/)
2. Create an app or use an existing one
3. Copy your Client ID and Client Secret

### 2. Configure your environment

[](#2-configure-your-environment)

Add the following to your `.env` file:

```
NETATMO_AUTH_URL=https://api.netatmo.com/oauth2/authorize
NETATMO_TOKEN_URL=https://api.netatmo.com/oauth2/token
NETATMO_API_URL=https://api.netatmo.com/api

# Optional: Customize the User model
# NETATMO_USER_MODEL=App\Models\User
```

### 3. Configure the package

[](#3-configure-the-package)

The configuration file `config/netatmo-weather.php` contains:

```
return [
    'name' => 'Laravel Netatmo Weather',

    // The User model that will be used to associate with Netatmo stations
    'user_model' => env('NETATMO_USER_MODEL', 'App\Models\User'),

    // Netatmo API URLs
    'netatmo_auth_url' => env('NETATMO_AUTH_URL', 'https://api.netatmo.com/oauth2/authorize'),
    'netatmo_token_url' => env('NETATMO_TOKEN_URL', 'https://api.netatmo.com/oauth2/token'),
    'netatmo_api_url' => env('NETATMO_API_URL', 'https://api.netatmo.com/api'),
];
```

Usage
-----

[](#usage)

### Using the Service

[](#using-the-service)

```
use Ekstremedia\NetatmoWeather\Services\NetatmoService;
use Ekstremedia\NetatmoWeather\Models\NetatmoStation;

// Get the service instance
$netatmoService = app(NetatmoService::class);

// Find a weather station
$weatherStation = NetatmoStation::first();

// Fetch data from Netatmo API
// This will automatically cache data for 10 minutes
$data = $netatmoService->getStationData($weatherStation);
```

### Using the Models

[](#using-the-models)

```
use Ekstremedia\NetatmoWeather\Models\NetatmoStation;
use Ekstremedia\NetatmoWeather\Models\NetatmoModule;
use Ekstremedia\NetatmoWeather\Models\NetatmoToken;

// Get all weather stations
$stations = NetatmoStation::all();

// Get a station with its modules
$station = NetatmoStation::with('modules')->first();

// Check if token is valid
if ($station->token->hasValidToken()) {
    echo "Token is valid!";
}

// Manually refresh token
$station->token->refreshToken();

// Access module data
foreach ($station->modules as $module) {
    echo "Module: {$module->module_name}\n";
    echo "Type: {$module->type}\n";
    echo "Battery: {$module->battery_percent}%\n";
}
```

### Using the UI (Optional)

[](#using-the-ui-optional)

If you want to use the included UI scaffolding, the package provides routes and controllers:

```
// In your routes/web.php or through the package routes
// The following routes are automatically registered:

Route::get('/netatmo', [NetatmoStationController::class, 'index'])->name('netatmo.index');
Route::get('/netatmo/create', [NetatmoStationController::class, 'create'])->name('netatmo.create');
Route::post('/netatmo', [NetatmoStationController::class, 'store'])->name('netatmo.store');
Route::get('/netatmo/{weatherstation}', [NetatmoStationController::class, 'show'])->name('netatmo.show');
Route::get('/netatmo/{weatherstation}/edit', [NetatmoStationController::class, 'edit'])->name('netatmo.edit');
Route::put('/netatmo/{weatherstation}', [NetatmoStationController::class, 'update'])->name('netatmo.update');
Route::delete('/netatmo/{weatherstation}', [NetatmoStationController::class, 'destroy'])->name('netatmo.destroy');
```

Visit `/netatmo` in your browser to manage your weather stations.

Public Sharing
--------------

[](#public-sharing)

The package supports public sharing of weather station data. Each station can be individually configured for public access:

### Enabling Public Access

[](#enabling-public-access)

**Via the UI:**

1. Navigate to your weather station detail page
2. Use the toggle switch in the "Public Access" section
3. Copy the generated public URL to share

**Or in the edit form:**

1. Check the "Make this station publicly accessible" checkbox when creating or editing a station

**Programmatically:**

```
$station = NetatmoStation::find($id);
$station->update(['is_public' => true]);
```

### Public Route

[](#public-route)

Once enabled, your weather station data will be accessible at:

```
/netatmo/public/{station-uuid}

```

This route:

- Does not require authentication
- Shows a clean, minimal view with only weather widgets
- Returns 404 if the station is not marked as public
- Returns 503 if data is temporarily unavailable

### Security

[](#security)

- Only stations explicitly marked as `is_public = true` are accessible
- OAuth tokens and credentials are never exposed
- Station owners maintain full control over public access
- Public URLs use UUIDs for non-sequential identification

Device Selection
----------------

[](#device-selection)

If your Netatmo account has access to multiple weather stations, the package will prompt you to select which physical device each configuration should display data from.

### Multiple Weather Stations: Two Approaches

[](#multiple-weather-stations-two-approaches)

**Option 1: Shared Access (Recommended)**

- Have others share their weather stations with your Netatmo account
- Use your single account credentials for all configurations
- Use device selection to choose which physical station each configuration displays
- Simpler management, single authentication

**Option 2: Separate Credentials (Fully Independent)**

- Each station configuration uses **completely different** Netatmo account credentials
- Each station authenticates separately with its own account
- Each station fetches data using its own OAuth token
- Each station is 100% isolated - no shared state
- Useful when:
    - Sharing is not possible or desired
    - You want complete independence between stations
    - Different people manage different weather stations
    - You need to display weather from multiple Netatmo accounts

### Setting Up Shared Access (Option 1)

[](#setting-up-shared-access-option-1)

To display weather stations owned by others (family, friends, other locations):

1. **Have the station owner share access:**

    - They log into the Netatmo mobile app
    - Go to Settings → Manage my Home
    - Add you as a guest/user with access to their weather station
2. **Your account now sees multiple devices:**

    - After sharing, your Netatmo account has access to both stations
    - When you authenticate a configuration, you'll see all available devices
    - Select which physical device each configuration should display
3. **Example Setup:**

    - Configuration "My Home" → Select your weather station
    - Configuration "Parents' House" → Select parents' weather station
    - Both use your credentials, different device\_id values

### Setting Up Separate Credentials (Option 2)

[](#setting-up-separate-credentials-option-2)

To use completely independent Netatmo accounts for different stations:

1. **Get API credentials for each Netatmo account:**

    - Account A (yours): Go to  → Create App → Get Client ID + Secret
    - Account B (parents'): They do the same → Get their Client ID + Secret
2. **Create station configurations with different credentials:**

    - Create Station 1: Use Account A credentials
    - Create Station 2: Use Account B credentials
    - Each station stores its credentials separately (encrypted)
3. **Authenticate each station independently:**

    - Visit `/netatmo/authenticate/{station-1}` → Login with Account A
    - Visit `/netatmo/authenticate/{station-2}` → Login with Account B
    - Each gets its own OAuth token
4. **Each station operates independently:**

    - Station 1 fetches data using Account A's token
    - Station 2 fetches data using Account B's token
    - No shared state, complete isolation

**Visual Indicators:**

- The UI shows masked Client ID for each station (e.g., `66c3d88a••••`)
- Different Client IDs confirm different accounts are being used
- Token status is tracked separately per station

### How It Works

[](#how-it-works)

1. **Single Device**: If you only have one weather station, the device is automatically selected
2. **Multiple Devices**: When you have multiple weather stations (owned or shared), you'll be redirected to a device selection page after authentication
3. **Manual Selection**: Choose which Netatmo device this configuration should use from a list showing:
    - Station name
    - Number of modules
    - Device ID (MAC address)

### Changing Device Selection

[](#changing-device-selection)

You can change which device a configuration uses at any time by visiting:

```
/netatmo/{station}/select-device

```

This is useful if you want to:

- Reassign a configuration to a different physical device
- Fix incorrect device assignments
- Manage multiple locations with similar setups

### Technical Details

[](#technical-details)

- Device IDs are Netatmo MAC addresses (e.g., `70:ee:50:5e:db:30`)
- The same physical device can be used by multiple configurations
- Different configurations can display data from different devices
- Device selection is stored in the `device_id` column

Module Lifecycle Management
---------------------------

[](#module-lifecycle-management)

The package automatically tracks which modules are active and archives modules that are no longer detected by the Netatmo API.

### How It Works

[](#how-it-works-1)

1. **Active Modules**: Modules currently detected in the Netatmo API response are marked as active and displayed normally
2. **Automatic Archiving**: When a module is no longer in the API response (removed, dead battery, lost connection), it's automatically marked as inactive
3. **Archived Section**: Inactive modules appear in a collapsible "Archived Modules" section on the station detail page
4. **Manual Deletion**: You can permanently delete archived modules if they're no longer needed

### Common Scenarios

[](#common-scenarios)

**Lost Module:**

- Battery dies on outdoor module
- Next data refresh marks it as inactive
- Module appears in Archived Modules section
- Replace battery → module automatically reactivates on next refresh

**Removed Module:**

- You remove a rain gauge from your station
- Module is automatically archived
- You can delete it permanently from the archived section

**Different Station Configurations:**

- Your home has outdoor + wind modules
- Your cabin has only the main module
- Each configuration only shows its own active modules

### Benefits

[](#benefits)

- No stale data displayed from disconnected modules
- Historical data preserved for inactive modules
- Clean interface showing only current setup
- Easy cleanup of permanently removed modules

Authentication Flow
-------------------

[](#authentication-flow)

1. Create a weather station record with your Client ID, Client Secret, and Redirect URI
2. Navigate to the authentication route: `/netatmo/{station}/authenticate`
3. You'll be redirected to Netatmo to authorize the app
4. After authorization, you'll be redirected back with access tokens
5. If your Netatmo account has multiple weather stations, you'll be prompted to select which device this configuration should use
6. The package automatically stores and refreshes tokens as needed

Data Structure
--------------

[](#data-structure)

### NetatmoStation

[](#netatmostation)

- `id` - Primary key
- `uuid` - UUID for public routing
- `user_id` - Associated user
- `station_name` - Name of the station
- `device_id` - Netatmo device MAC address (selected during setup if multiple devices exist, or auto-populated if only one device)
- `is_public` - Boolean flag for public access (default: false)
- `client_id` - Encrypted Netatmo Client ID
- `client_secret` - Encrypted Netatmo Client Secret
- `redirect_uri` - OAuth redirect URI
- `webhook_uri` - Webhook URI (optional)

### NetatmoModule

[](#netatmomodule)

Stores data for each module (base station and add-on modules):

- Module identification (module\_id, module\_name, type)
- Battery status
- Connection status (wifi\_status, rf\_status, reachable)
- Dashboard data (stored as JSON)
- `is_active` - Boolean flag indicating if module is currently detected (default: true)

### NetatmoToken

[](#netatmotoken)

- `access_token` - Current access token
- `refresh_token` - Refresh token
- `expires_at` - Token expiration timestamp

Supported Module Types
----------------------

[](#supported-module-types)

- `NAMain` - Main indoor module
- `NAModule1` - Outdoor module
- `NAModule2` - Wind gauge
- `NAModule3` - Rain gauge
- `NAModule4` - Additional indoor module

Caching
-------

[](#caching)

The package automatically caches weather data for 10 minutes to reduce API calls. You can modify this behavior in the `NetatmoService` class.

Security
--------

[](#security-1)

- Client ID and Client Secret are automatically encrypted in the database
- Tokens are securely stored and automatically refreshed
- All API communications use HTTPS

Testing
-------

[](#testing)

The package includes comprehensive test coverage using **Pest PHP**:

```
# Run all tests
composer test

# Run tests with coverage report
composer test-coverage

# Run specific test suite
vendor/bin/pest --testsuite Unit
vendor/bin/pest --testsuite Feature

# Run tests in parallel
vendor/bin/pest --parallel

# Check code style
composer format
vendor/bin/pint --test
```

### Test Coverage

[](#test-coverage)

**Unit Tests (14 tests):**

- Model functionality (NetatmoStation, NetatmoToken, NetatmoModule)
- Encryption and UUID generation
- Relationships and cascade deletes
- Token validation and expiration
- JSON field casting

**Feature Tests (13 tests):**

- CRUD operations for weather stations
- Authentication flow and redirects
- API integration with HTTP mocking
- Data caching (10-minute strategy)
- Module updates without duplication

### Why Pest?

[](#why-pest)

Pest provides a more elegant and expressive testing syntax:

```
it('can create a netatmo station', function () {
    $station = NetatmoStation::create([...]);
    expect($station->uuid)->not->toBeNull();
});
```

### CI/CD

[](#cicd)

The package uses GitHub Actions for continuous integration:

- Tests against PHP 8.2 &amp; 8.3
- Tests against Laravel 11.x &amp; 12.x
- Uses Pest for elegant test execution
- Code style checks with Laravel Pint
- Runs on every push and pull request

Contributing
------------

[](#contributing)

Contributions are welcome! Please feel free to submit a Pull Request.

License
-------

[](#license)

This package is open-sourced software licensed under the MIT license.

Credits
-------

[](#credits)

- [Terje Nesthus](https://github.com/ekstremedia)
- [All Contributors](../../contributors)

Support
-------

[](#support)

If you discover any security-related issues, please email  instead of using the issue tracker.

Links
-----

[](#links)

- [Netatmo API Documentation](https://dev.netatmo.com/apidocumentation/weather)
- [Netatmo Developer Portal](https://dev.netatmo.com/)

###  Health Score

43

—

FairBetter than 89% of packages

Maintenance76

Regular maintenance activity

Popularity16

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor1

Top contributor holds 98.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~70 days

Recently: every ~26 days

Total

9

Last Release

135d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/81c14fb7d455e136320a619693165f18eb4f220301b44512cdc083fa9b599bf7?d=identicon)[terjenesthus](/maintainers/terjenesthus)

---

Top Contributors

[![ekstremedia](https://avatars.githubusercontent.com/u/10083373?v=4)](https://github.com/ekstremedia "ekstremedia (85 commits)")[![FdvTerje](https://avatars.githubusercontent.com/u/125031387?v=4)](https://github.com/FdvTerje "FdvTerje (1 commits)")

---

Tags

apilaravelnetatmopackageweatherapilaravelweathernetatmoweather-station

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/ekstremedia-laravel-netatmo-weather/health.svg)

```
[![Health](https://phpackages.com/badges/ekstremedia-laravel-netatmo-weather/health.svg)](https://phpackages.com/packages/ekstremedia-laravel-netatmo-weather)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[api-platform/laravel

API Platform support for Laravel

58171.6k14](/packages/api-platform-laravel)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5022.0k](/packages/simplestats-io-laravel-client)[defstudio/telegraph

A laravel facade to interact with Telegram Bots

816333.9k3](/packages/defstudio-telegraph)[essa/api-tool-kit

set of tools to build an api with laravel

53390.1k](/packages/essa-api-tool-kit)[hasinhayder/tyro

Tyro - The ultimate Authentication, Authorization, and Role &amp; Privilege Management solution for Laravel 12 &amp; 13

6804.7k6](/packages/hasinhayder-tyro)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
