Appearance
@xcons/cli-thingsboard - Widget Create Kılavuzu
Bu dokümantasyon, XCONS ThingsBoard CLI ile widget projesi oluşturma işlemlerini detaylı olarak açıklar.
Widget Create Komutu
bash
xcons-thingsboard widget create [name] [options]Parametreler
- name (isteğe bağlı): Widget proje adı
Seçenekler
-n, --name <name>: Widget adı-t, --type <type>: Widget türü (timeseries,latest,latest-values,rpc,static)-d, --description <desc>: Widget açıklaması--no-interaction: İnteraktif sorları atla
Widget Türleri
TimeSeries Widgets
Zaman serisi verilerini görüntülemek için kullanılır.
bash
# TimeSeries widget oluştur
xcons-thingsboard widget create temperature-monitor --type timeseries
# Açıklamalı TimeSeries widget
xcons-thingsboard widget create sensor-dashboard \
--type timeseries \
--description "Real-time sensor data monitoring dashboard"Kullanım Alanları:
- Sıcaklık, nem, basınç grafikleri
- Güç tüketimi izleme
- Sensör veri trendleri
- Zaman bazlı analitik dashboardlar
Latest Values Widgets
Güncel telemetri değerlerini göstermek için kullanılır.
bash
# Latest values widget oluştur
xcons-thingsboard widget create device-status --type latest
# Latest-values alias'ı ile
xcons-thingsboard widget create current-readings --type latest-valuesKullanım Alanları:
- Cihaz durumu göstergeleri
- Son sensör okumaları
- Anlık değer panelleri
- Status indicator'ları
RPC Control Widgets
Cihaz kontrolü ve RPC komutları için kullanılır.
bash
# RPC control widget oluştur
xcons-thingsboard widget create device-controller --type rpc
# Control alias'ı ile
xcons-thingsboard widget create pump-control --type controlKullanım Alanları:
- Cihaz açma/kapama kontrolleri
- Motor hız kontrolü
- Valve pozisyon ayarları
- Uzaktan komut panelleri
Static Widgets
Statik HTML içeriği için kullanılır.
bash
# Static widget oluştur
xcons-thingsboard widget create info-panel --type static
# Açıklamalı static widget
xcons-thingsboard widget create company-logo \
--type static \
--description "Company branding and information panel"Kullanım Alanları:
- Bilgilendirme panelleri
- Logo ve branding
- Statik dokümantasyon
- HTML tabanlı içerikler
Temel Kullanım
İnteraktif Widget Oluşturma
bash
# Tüm parametreler interaktif sorulur
xcons-thingsboard widget create
# İsim belirtilip diğerleri interaktif sorulur
xcons-thingsboard widget create my-awesome-widgetİnteraktif Soru Sırası:
? Widget name: temperature-sensor
? Select widget type:
❯ Time Series - For displaying time series data
Latest Values - For showing current telemetry values
RPC Control - For device control via RPC
Static - Static HTML content
? Widget description: Temperature monitoring sensor widgetParametreli Widget Oluşturma
bash
# Tüm parametrelerle widget oluştur
xcons-thingsboard widget create temperature-dashboard \
--type timeseries \
--description "Advanced temperature monitoring dashboard with charts"
# İnteraktif soruları atla
xcons-thingsboard widget create simple-widget \
--type latest \
--no-interactionProje Yapısı
Oluşturulan widget projesi şu yapıya sahiptir:
my-widget/
├── .xcon/
│ └── config.json # XCONS widget konfigürasyonu
├── .idea/ # IntelliJ IDEA konfigürasyonu
│ ├── modules.xml
│ ├── my-widget.iml
│ └── workspace.xml
├── src/
│ ├── index.ts # Ana widget TypeScript kodu
│ ├── index.html # Widget HTML template
│ └── style.css # Widget CSS stilleri
├── dist/ # Derlenmiş widget dosyaları (build sonrası)
├── package.json # NPM bağımlılıkları ve scriptleri
├── tsconfig.json # TypeScript konfigürasyonu
└── README.md # Widget dokümantasyonu.xcon/config.json
json
{
"configurations": {
"provider": "thingsboard",
"id": "",
"type": "timeseries"
},
"projectType": "widget",
"version": "1.0"
}src/index.ts (Ana Widget Kodu)
typescript
import { Widget, property, computed } from '@xcons/widget';
@Widget({
widgetName: 'My Awesome Widget',
widgetDescription: 'Description of my widget functionality',
widgetVersion: '1.0.0',
templateUrl: './index.html',
styleUrls: ['./style.css'],
resources: [
{
type: 'js',
url: 'https://cdn.jsdelivr.net/npm/chart.js',
name: 'Chart.js Library'
}
],
selector: 'tb-my-widget'
})
export default class MyWidget {
@property()
public data: any[] = [];
@property()
public title: string = 'My Widget';
@property()
public isLoading: boolean = false;
@computed()
get hasData(): boolean {
return this.data && this.data.length > 0;
}
onInit() {
console.log('Widget initialized:', this.title);
this.initializeComponents();
}
onDataUpdated() {
console.log('Data updated:', this.data);
this.processData();
}
onResize() {
console.log('Widget resized');
this.adjustLayout();
}
private initializeComponents() {
// Widget bileşenlerini başlat
}
private processData() {
// Veri işleme mantığı
if (this.hasData) {
this.updateDisplay();
}
}
private adjustLayout() {
// Layout ayarlama mantığı
}
private updateDisplay() {
// Görüntü güncelleme mantığı
}
onDestroy() {
console.log('Widget destroyed');
this.cleanup();
}
private cleanup() {
// Temizlik işlemleri
}
}src/index.html (HTML Template)
html
<div class="widget-container">
<!-- Widget Header -->
<div class="widget-header">
<h3 class="widget-title" x:text="title"></h3>
<div class="widget-actions">
<button x:on:click="refreshData" x:attr:disabled="isLoading">
<span x:text="isLoading ? 'Loading...' : 'Refresh'"></span>
</button>
</div>
</div>
<!-- Widget Content -->
<div class="widget-content" x:show="hasData">
<div class="data-display">
<!-- Veri gösterimi alanı -->
<div class="chart-container">
<canvas id="dataChart"></canvas>
</div>
<div class="stats-panel">
<div class="stat-item">
<span class="stat-label">Total Records:</span>
<span class="stat-value" x:text="data.length"></span>
</div>
</div>
</div>
</div>
<!-- Empty State -->
<div class="empty-state" x:show="!hasData && !isLoading">
<div class="empty-icon">📊</div>
<h4>No Data Available</h4>
<p>Widget is waiting for data to display.</p>
</div>
<!-- Loading State -->
<div class="loading-state" x:show="isLoading">
<div class="spinner"></div>
<p>Loading data...</p>
</div>
</div>src/style.css (CSS Stilleri)
css
.widget-container {
padding: 16px;
height: 100%;
display: flex;
flex-direction: column;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.widget-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid #e0e0e0;
}
.widget-title {
margin: 0;
font-size: 18px;
font-weight: 600;
color: #333;
}
.widget-actions button {
padding: 8px 16px;
border: 1px solid #ddd;
border-radius: 4px;
background-color: #fff;
cursor: pointer;
font-size: 14px;
transition: all 0.2s ease;
}
.widget-actions button:hover:not(:disabled) {
background-color: #f8f9fa;
border-color: #007bff;
color: #007bff;
}
.widget-actions button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.widget-content {
flex: 1;
display: flex;
flex-direction: column;
}
.data-display {
flex: 1;
display: flex;
flex-direction: column;
}
.chart-container {
flex: 1;
position: relative;
margin-bottom: 16px;
min-height: 200px;
}
.stats-panel {
display: flex;
flex-wrap: wrap;
gap: 16px;
padding: 12px;
background-color: #f8f9fa;
border-radius: 4px;
}
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
}
.stat-label {
font-size: 12px;
color: #666;
margin-bottom: 4px;
}
.stat-value {
font-size: 18px;
font-weight: 600;
color: #333;
}
.empty-state, .loading-state {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
color: #666;
}
.empty-icon {
font-size: 48px;
margin-bottom: 16px;
opacity: 0.5;
}
.empty-state h4 {
margin: 8px 0;
color: #333;
}
.empty-state p {
margin: 0;
font-size: 14px;
}
.loading-state .spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #007bff;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 16px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* Responsive tasarım */
@media (max-width: 768px) {
.widget-container {
padding: 12px;
}
.widget-header {
flex-direction: column;
gap: 12px;
align-items: flex-start;
}
.stats-panel {
flex-direction: column;
gap: 8px;
}
}package.json
json
{
"name": "my-widget",
"version": "1.0.0",
"description": "My ThingsBoard Widget",
"main": "dist/widget.js",
"scripts": {
"build": "xcons-thingsboard widget build",
"build:prod": "xcons-thingsboard widget build --production",
"build:debug": "xcons-thingsboard widget build --debug",
"install:server": "xcons-thingsboard widget install",
"install:debug": "xcons-thingsboard widget install --debug"
},
"dependencies": {
"@xcons/widget": "^1.0.0",
"chart.js": "^4.0.0"
},
"devDependencies": {
"@types/node": "^20.0.0",
"typescript": "^5.0.0"
},
"keywords": [
"thingsboard",
"widget",
"iot",
"dashboard"
],
"author": "Your Name",
"license": "MIT"
}Geliştirme İş Akışı
1. Widget Oluşturma
bash
# Widget projesi oluştur
xcons-thingsboard widget create temperature-monitor --type timeseries
# Proje dizinine geç
cd temperature-monitor2. Bağımlılık Kurulumu
bash
# Otomatik (create sırasında sorulur)
# veya manuel kurulum
npm install3. Geliştirme
bash
# Widget kodunu düzenle
# src/index.ts - Ana widget mantığı
# src/index.html - HTML template
# src/style.css - Stiller
# Build ve test
npm run build:debug4. ThingsBoard'a Yükleme
bash
# Widget'ı sunucuya yükle
npm run install:server
# veya debug modu ile
npm run install:debugWidget Type Örnekleri
TimeSeries Widget Örneği
bash
xcons-thingsboard widget create energy-consumption --type timeseriesKullanım Senaryosu:
- Enerji tüketimi grafiği
- Zaman serisi veri görselleştirme
- Trend analizi
Latest Values Widget Örneği
bash
xcons-thingsboard widget create device-overview --type latestKullanım Senaryosu:
- Cihaz durumu paneli
- Son sensör değerleri
- Anlık durum göstergesi
RPC Control Widget Örneği
bash
xcons-thingsboard widget create motor-controller --type rpcKullanım Senaryosu:
- Motor start/stop kontrolü
- Hız ayarlama
- Uzaktan cihaz yönetimi
Static Widget Örneği
bash
xcons-thingsboard widget create help-documentation --type staticKullanım Senaryosu:
- Yardım dokümantasyonu
- Kullanım talimatları
- Statik bilgilendirme
Template Özelleştirmesi
GitHub Template İndirme
CLI otomatik olarak GitHub'dan template indirir:
Source: https://github.com/xcon-studio/xcon-web-widget-template-basic-thingsboard
Branch: mainTemplate İçeriği
- TypeScript Desteği: Modern ES2020+ özellikleri
- XCONS Decorators: @Widget, @property, @computed
- HTML Template Binding: x:text, x:show, x🔛click
- CSS Framework: Responsive tasarım ve modern stiller
- Build System: XCONS Build Engine entegrasyonu
- IDE Support: IntelliJ IDEA konfigürasyonları
Pratik Örnekler
IoT Sensor Dashboard
bash
xcons-thingsboard widget create iot-sensor-dashboard \
--type timeseries \
--description "Comprehensive IoT sensor data visualization dashboard"
cd iot-sensor-dashboard
npm installDevice Control Panel
bash
xcons-thingsboard widget create device-control-panel \
--type rpc \
--description "Remote device control and monitoring panel"
cd device-control-panel
npm installStatus Indicator Widget
bash
xcons-thingsboard widget create status-indicator \
--type latest \
--description "Real-time device status and health indicator"
cd status-indicator
npm installInformation Display
bash
xcons-thingsboard widget create info-display \
--type static \
--description "Static information and documentation display panel"
cd info-display
npm installToplu Widget Oluşturma
Script ile Çoklu Widget
bash
#!/bin/bash
# Widget tanımları
widgets=(
"temperature-monitor:timeseries:Temperature monitoring and trending"
"humidity-tracker:timeseries:Humidity level tracking over time"
"device-controller:rpc:Remote device control interface"
"status-panel:latest:Current device status display"
"help-guide:static:User help and documentation"
)
# Widget'ları oluştur
for widget_def in "${widgets[@]}"; do
IFS=':' read -r name type desc <<< "$widget_def"
echo "Creating widget: $name ($type)"
xcons-thingsboard widget create "$name" \
--type "$type" \
--description "$desc" \
--no-interaction
# Bağımlılıkları kur
cd "$name"
npm install
cd ..
echo "Widget '$name' created successfully"
echo "---"
done
echo "All widgets created successfully!"Departman Bazlı Widget'lar
bash
# Engineering widgets
engineering_widgets=("power-analysis:timeseries" "load-controller:rpc" "system-status:latest")
# Production widgets
production_widgets=("quality-metrics:timeseries" "machine-control:rpc" "production-status:latest")
# Operations widgets
operations_widgets=("operational-kpis:timeseries" "facility-control:rpc" "ops-dashboard:latest")
create_department_widgets() {
local dept=$1
shift
local widgets=("$@")
mkdir -p "$dept-widgets"
cd "$dept-widgets"
for widget in "${widgets[@]}"; do
IFS=':' read -r name type <<< "$widget"
xcons-thingsboard widget create "$name" \
--type "$type" \
--description "$dept department $name widget" \
--no-interaction
done
cd ..
}
# Departman widget'larını oluştur
create_department_widgets "engineering" "${engineering_widgets[@]}"
create_department_widgets "production" "${production_widgets[@]}"
create_department_widgets "operations" "${operations_widgets[@]}"Troubleshooting
Template İndirme Hataları
Hata: Failed to download template: ETIMEDOUT
Çözüm:
bash
# Ağ bağlantısını kontrol et
ping github.com
# Proxy ayarları (gerekirse)
npm config set proxy http://proxy:8080
npm config set https-proxy http://proxy:8080
# Tekrar dene
xcons-thingsboard widget create my-widget --type timeseriesNPM Install Hataları
Hata: npm install failed with exit code: 1
Çözüm:
bash
# Manuel npm install
cd my-widget
npm cache clean --force
npm install
# Node.js sürümünü kontrol et
node --version # 18+ gerekli
# NPM sürümünü kontrol et
npm --version # 9+ gerekliDizin Çakışması
Hata: Directory 'my-widget' already exists and is not empty
Çözüm:
bash
# Mevcut dizini sil
rm -rf my-widget
# Veya farklı isim kullan
xcons-thingsboard widget create my-widget-v2 --type timeseries
# Veya mevcut dizini taşı
mv my-widget my-widget-backupIntelliJ IDEA Konfigürasyon Hataları
Hata: .idea dosyalarında sorun
Çözüm:
bash
# .idea dizinini sil ve yeniden oluştur
rm -rf .idea
# IntelliJ IDEA'da projeyi yeniden aç
# File → Open → Proje dizini seçGelişmiş Kullanım
Custom Template Kullanımı
bash
# Farklı template branch'i (gelecek özellik)
# xcons-thingsboard widget create my-widget --template advanced
# Manuel template özelleştirmesi
xcons-thingsboard widget create my-widget --type timeseries
cd my-widget
# src/index.ts dosyasını özelleştir
# Harici kütüphaneler ekle
# Template binding'leri genişletIDE Entegrasyonu
bash
# VS Code için
code my-widget
# IntelliJ IDEA için (otomatik konfigürasyon mevcut)
idea my-widget
# WebStorm için
webstorm my-widgetSonraki Adımlar
Widget oluşturduktan sonra:
- Widget Build - Widget'ı derleme
- Widget Install - Widget'ı ThingsBoard'a yükleme
- Konfigürasyon - İleri seviye konfigürasyon
Widget projesi başarıyla oluşturuldu! Geliştirmeye başlayabilirsiniz.