fanucService

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 23, 2026 License: MIT Imports: 10 Imported by: 0

README

Fanuc Focas Service

alt text alt text alt text alt text alt text alt text

Сервис для сбора данных со станков Fanuc по протоколу Focas, отправки в Apache Kafka и управления через REST API

✨ Ключевые возможности
  • 🚀 Потоковая передача в Kafka: Данные в реальном времени отправляются в топик Apache Kafka.
  • 🔐 Безопасность: Доступ к API защищен с помощью X-API-Key.
  • 🕹️ Управляемый опрос: Запуск и остановка мониторинга для каждого станка через API.
  • 💾 Персистентность: Состояния подключений сохраняются в PostgreSQL для автоматического восстановления после перезагрузки.
  • 🏭 Fanuc Focas Integration: Использование обертки над библиотекой Fanuc (Fwlib).
  • 🐳 Простота развертывания: Готовая конфигурация docker-compose.

🏗️ Архитектура

┌─────────────────┐      ┌─────────────────┐      ┌──────────────────┐
│   Управляющий   ├─────▸│     Сервис      │◂─────┤    Fanuc CNC     │
│    REST API     │      │  fanucService   │      │     Adapter      │
│   (Gin-Gonic)   │      │    (Go App)     │      │     (Focas)      │
└─────────────────┘      └───────┬───┬─────┘      └──────────────────┘
        ▴                        │   │      (Polling)
        │                        │   └─────────────────────┐
        │                        ▾                         ▾
┌───────┴─────────┐      ┌─────────────────┐      ┌──────────────────┐
│  Пользователь / │      │   PostgreSQL    │      │   Apache Kafka   │
│     Система     │      │   (Состояния    │      │   (Потоковая     │
│   (Управление)  │      │   Подключений)  │      │   обработка)     │
└─────────────────┘      └─────────────────┘      └──────────────────┘

📦 Установка

1️⃣ Клонирование репозитория

git clone https://github.com/iwtcode/fanucService.git
cd fanucService

2️⃣ Конфигурация приложения

Откройте файл .env и при необходимости измените его

# App
APP_PORT=8080
GIN_MODE=debug
API_KEY=secret_key

# Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=1234
DB_NAME=fanuc_db

# Kafka
KAFKA_BROKER=localhost:9092
KAFKA_TOPIC=fanuc_data

# Logger
ADAPTER_LOG_LEVEL=error
SERVICE_LOG_LEVEL=info

3️⃣ Запуск Apache Kafka

docker compose up -d

4️⃣ Запуск приложения

# Golang
go run cmd/app/main.go

🧪 Тестирование

go test -v -count=1 ./tests

🔌 API

🔒 Аутентификация: Все запросы должны содержать заголовок X-API-Key.

Создание подключения

POST /api/v1/connect
curl -X 'POST' \
  'http://localhost:8080/api/v1/connect' \
  -H 'accept: application/json' \
  -H 'X-API-Key: secret_key' \
  -H 'Content-Type: application/json' \
  -d '{
    "endpoint": "10.0.0.1:8193",
    "timeout": 5000,
    "model": "FS0i-D",
    "series": "0i"
}'
{
  "status": "ok",
  "data": {
    "id": "90e09ee9-7d39-4a15-8a00-b7fb351b27ee",
    "endpoint": "10.0.0.1:8193",
    "timeout": 5000,
    "model": "FS0i-D",
    "series": "0i",
    "interval": 0,
    "status": "connected",
    "mode": "static",
    "created_at": "2025-11-22T21:40:17.465186444+03:00",
    "updated_at": "2025-11-22T21:40:17.465186629+03:00"
  }
}

Получение списка подключений и проверка их актуальности

GET /api/v1/connect
curl -X 'GET' \
  'http://localhost:8080/api/v1/connect' \
  -H 'accept: application/json' \
  -H 'X-API-Key: secret_key'
{
  "status": "ok",
  "data": [
    {
      "id": "90e09ee9-7d39-4a15-8a00-b7fb351b27ee",
      "endpoint": "10.0.0.1:8193",
      "timeout": 5000,
      "model": "FS0i-D",
      "series": "0i",
      "interval": 0,
      "status": "connected",
      "mode": "static",
      "created_at": "2025-11-22T21:40:17.465186+03:00",
      "updated_at": "2025-11-22T21:40:17.465186+03:00"
    },
    {
      "id": "667204be-5e3c-433f-9700-ea931ee14f63",
      "endpoint": "10.0.0.2:8194",
      "timeout": 5000,
      "model": "FS30i-D",
      "series": "30i",
      "interval": 0,
      "status": "reconnecting",
      "mode": "polled",
      "created_at": "2025-11-22T21:48:17.087876+03:00",
      "updated_at": "2025-11-22T21:48:17.087876+03:00"
    }
  ]
}

Получение конкретного подключения и проверка его актуальности

GET /api/v1/connect?id={uuid}
curl -X 'GET' \
  'http://localhost:8080/api/v1/connect?id=90e09ee9-7d39-4a15-8a00-b7fb351b27ee' \
  -H 'accept: application/json' \
  -H 'X-API-Key: secret_key'
{
  "status": "ok",
  "data": {
    "id": "90e09ee9-7d39-4a15-8a00-b7fb351b27ee",
    "endpoint": "10.0.0.1:8193",
    "timeout": 5000,
    "model": "FS0i-D",
    "series": "0i",
    "interval": 0,
    "status": "connected",
    "mode": "static",
    "created_at": "2025-11-22T21:40:17.465186+03:00",
    "updated_at": "2025-11-22T21:40:17.465186+03:00"
  }
}

Запуск сбора данных

POST /api/v1/polling/start
curl -X 'POST' \
  'http://localhost:8080/api/v1/polling/start' \
  -H 'accept: application/json' \
  -H 'X-API-Key: secret_key' \
  -H 'Content-Type: application/json' \
  -d '{
  "id": "90e09ee9-7d39-4a15-8a00-b7fb351b27ee",
  "interval": 10000
}'
{
  "status": "ok",
  "message": "Polling started for session 90e09ee9-7d39-4a15-8a00-b7fb351b27ee"
}

Остановка сбора данных

POST /api/v1/polling/stop
curl -X 'POST' \
  'http://localhost:8080/api/v1/polling/stop' \
  -H 'accept: application/json' \
  -H 'X-API-Key: secret_key' \
  -H 'Content-Type: application/json' \
  -d '{
  "id": "90e09ee9-7d39-4a15-8a00-b7fb351b27ee"
}'
{
  "status": "ok",
  "message": "Polling stopped for session 90e09ee9-7d39-4a15-8a00-b7fb351b27ee"
}

Получение управляющей программы

GET /api/v1/program?id={uuid}
curl -X 'GET' \
  'http://localhost:8080/api/v1/program?id=90e09ee9-7d39-4a15-8a00-b7fb351b27ee' \
  -H 'accept: text/plain' \
  -H 'X-API-Key: secret_key'
%
O1(ROUGH)(TOOL=D12FEM) 
T1M06
G92X0.Y0.Z0. 
G91G00X-33.023Y47.94 
...
M30
%

Удаление подключения

DELETE /api/v1/connect?id={uuid}
curl -X 'DELETE' \
  'http://localhost:8080/api/v1/connect?id=90e09ee9-7d39-4a15-8a00-b7fb351b27ee' \
  -H 'accept: application/json' \
  -H 'X-API-Key: secret_key'
{
  "status": "ok",
  "message": "Session 90e09ee9-7d39-4a15-8a00-b7fb351b27ee successfully deleted"
}

🛠️ Использование Go Client SDK

Установка
go get github.com/iwtcode/fanucService
Пример использования
package main

import (
	"context"
	"fmt"
	"log"
	
	"github.com/iwtcode/fanucService"
)

func main() {
	// 1. Инициализация
	client := fanucService.NewClient("http://localhost:8080", "secret_key")
	ctx := context.Background()

	// 2. Создание подключения
	req := fanucService.ConnectionRequest{
		Endpoint: "10.0.0.1:8193",
		Timeout:  5000,
		Model:    "FS0i-D",
		Series:   "0i",
	}
	machine, err := client.CreateConnection(ctx, req)
	if err != nil {
		log.Fatalf("Ошибка подключения: %v", err)
	}
	fmt.Printf("ID станка: %s\n", machine.ID)

	// 3. Получение программы
	gcode, err := client.GetControlProgram(ctx, machine.ID)
	if err != nil {
		log.Printf("Ошибка получения программы: %v", err)
	} else {
		fmt.Printf("G-код:\n%s\n", gcode)
	}

	// 4. Управление опросом
	_ = client.StartPolling(ctx, machine.ID, 2000)
}

🔧 Структура проекта

fanucService/
├── cmd/
│   └── app/                # Точка входа в приложение
├── internal/               # Приватный код приложения
│   ├── app/                # Сборка зависимостей
│   ├── domain/             # Основные сущности и модели данных
│   │   ├── entities/       # Структуры базы данных
│   │   └── models/         # DTO для API и ошибки
│   ├── handlers/           # HTTP слой
│   ├── interfaces/         # Абстракции для развязывания слоев
│   ├── middleware/         # Обёртки над функциями
│   ├── repository/         # Слой доступа к базе данных
│   ├── services/           # Инфраструктурные сервисы и логика работы с оборудованием
│   │   ├── fanuc/          # Логика соединения со станками и опроса
│   │   └── kafka/          # Логика отправки данных в Kafka
│   └── usecases/           # Бизнес-логика
├── .env                    # Конфигурация переменных окружения
├── client.go               # SDK для взаимодействия с этим сервисом
├── config.go               # Загрузка конфигурации приложения
├── models.go               # Общие модели, экспортируемые для клиента SDK
└── docker-compose.yml      # Запуск Kafka-UI

🆘 Поддержка

📝 Лицензия

Проект распространяется под лицензией MIT

Copyright (c) 2025 iwtcode

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AppConfig added in v1.0.7

type AppConfig struct {
	Port    string
	GinMode string
	APIKey  string
}

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client реализует ClientAPI.

func NewClient added in v1.0.7

func NewClient(baseURL, apiKey string) *Client

NewClient создает новый экземпляр клиента.

func (*Client) CheckConnection added in v1.0.7

func (c *Client) CheckConnection(ctx context.Context, machineID string) (*MachineDTO, error)

func (*Client) CreateConnection added in v1.0.7

func (c *Client) CreateConnection(ctx context.Context, req ConnectionRequest) (*MachineDTO, error)

func (*Client) DeleteConnection added in v1.0.7

func (c *Client) DeleteConnection(ctx context.Context, machineID string) error

func (*Client) GetConnections added in v1.0.7

func (c *Client) GetConnections(ctx context.Context) ([]MachineDTO, error)

func (*Client) GetControlProgram

func (c *Client) GetControlProgram(ctx context.Context, machineID string) (string, error)

func (*Client) StartPolling added in v1.0.7

func (c *Client) StartPolling(ctx context.Context, machineID string, intervalMs int) error

func (*Client) StopPolling added in v1.0.7

func (c *Client) StopPolling(ctx context.Context, machineID string) error

type ClientAPI added in v1.0.7

type ClientAPI interface {
	// Connection methods
	CreateConnection(ctx context.Context, req ConnectionRequest) (*MachineDTO, error)
	GetConnections(ctx context.Context) ([]MachineDTO, error)
	CheckConnection(ctx context.Context, machineID string) (*MachineDTO, error)
	DeleteConnection(ctx context.Context, machineID string) error

	// Polling methods
	StartPolling(ctx context.Context, machineID string, intervalMs int) error
	StopPolling(ctx context.Context, machineID string) error

	// Program methods
	GetControlProgram(ctx context.Context, machineID string) (string, error)
}

type Config

type Config struct {
	App      AppConfig
	Database DatabaseConfig
	Kafka    KafkaConfig
	Logger   LoggerConfig
}

func LoadConfig added in v1.0.7

func LoadConfig() *Config

type ConnectionRequest added in v1.0.7

type ConnectionRequest struct {
	Endpoint string `json:"endpoint" binding:"required"` // ip:port
	Timeout  int    `json:"timeout"`                     // ms, default 5000
	Model    string `json:"model"`                       // Human readable name, default "Unknown"
	Series   string `json:"series"`                      // "0i", "31i", default "Unknown"
}

ConnectionRequest payload to create a connection

type ConnectionResponse added in v1.0.7

type ConnectionResponse struct {
	Status  string      `json:"status"`
	Message string      `json:"message,omitempty"`
	Data    interface{} `json:"data,omitempty"`
}

ConnectionResponse represents a generic response wrapper

type DatabaseConfig added in v1.0.7

type DatabaseConfig struct {
	Host     string
	Port     string
	User     string
	Password string
	Name     string
}

type KafkaConfig added in v1.0.7

type KafkaConfig struct {
	Broker string
	Topic  string
}

type LoggerConfig added in v1.0.7

type LoggerConfig struct {
	AdapterLevel string
	ServiceLevel string
}

type MachineDTO added in v1.0.7

type MachineDTO struct {
	ID        string    `json:"id"`
	Endpoint  string    `json:"endpoint"`
	Timeout   int       `json:"timeout"`
	Model     string    `json:"model"`
	Series    string    `json:"series"`
	Interval  int       `json:"interval"`
	Status    string    `json:"status"`
	Mode      string    `json:"mode"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

MachineDTO represents the machine data sent to clients

type StartPollingRequest added in v1.0.7

type StartPollingRequest struct {
	ID       string `json:"id" binding:"required"`
	Interval int    `json:"interval"` // ms, default 5000
}

StartPollingRequest payload to start polling

type StopPollingRequest added in v1.0.7

type StopPollingRequest struct {
	ID string `json:"id" binding:"required"`
}

StopPollingRequest payload to stop polling

Directories

Path Synopsis
cmd
app command
Package docs Code generated by swaggo/swag.
Package docs Code generated by swaggo/swag.
internal
app

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL