Принципы работы и советы по интеграции
API Fontera PTL работает на базе HTTP. Основной форма передачи сообщений: JSON.
Автоматическая документация (генерация через Swagger) доступна по адресу /docs
вашего стенда. Там же отправить тестовый запрос и увидеть ответ.
Концептуальная схема отправки команд до PTL модулей
Отправка на схеме выполняется через /turn_on
, а чтение через /ptls
.
Примеры реализации
Все представленные примеры приведены исключительно в ознакомительных целях. Они не предназначены для использования в продуктивной среде без соответствующей доработки и тестирования.
Отправка зажигания, ожидание и чтение состояния модулей
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
type Command struct {
Role string `json:"role,omitempty"`
Unit int `json:"unit,omitempty"`
Number int `json:"number,omitempty"`
Sub int `json:"sub,omitempty"`
Color string `json:"color,omitempty"`
}
type ControllerCommands struct {
ControllerIP string `json:"controller_ip"`
Commands []Command `json:"commands"`
}
type PTLQuery struct {
IP string `json:"ip"`
ClearAfter bool `json:"clear_after"`
Mode string `json:"mode,omitempty"`
Role string `json:"role,omitempty"`
}
func main() {
baseURL := "http://localhost:8000" // Заменить на реальный адрес API
controllerIP := "192.168.0.100"
turnOnPayload := ControllerCommands{
ControllerIP: controllerIP,
Commands: []Command{
{
Role: "picker",
Unit: 1,
Number: 9999,
Color: "Red",
},
},
}
sendJSON(baseURL+"/turn_on", turnOnPayload)
time.Sleep(2 * time.Second)
ptlQuery := PTLQuery{
IP: controllerIP,
ClearAfter: false,
Role: "picker",
}
sendJSON(baseURL+"/ptls", ptlQuery)
}
func sendJSON(url string, data interface{}) {
payloadBytes, err := json.Marshal(data)
if err != nil {
panic(err)
}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("Response from %s:\n%s\n", url, string(body))
}
Проверка состояния конкретного модуля
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type PTLQuery struct {
IP string `json:"ip"`
ClearAfter bool `json:"clear_after"`
}
type PTLResponse struct {
Unit int `json:"unit"`
Controller string `json:"controller"`
State string `json:"state,omitempty"`
Color string `json:"color,omitempty"`
Number int `json:"number,omitempty"`
Sub int `json:"sub,omitempty"`
}
func main() {
baseURL := "http://localhost:8000" // Заменить на актуальный
controllerIP := "192.168.0.100" // Заменить на IP контроллера
targetUnit := 55
query := PTLQuery{
IP: controllerIP,
ClearAfter: false,
}
payloadBytes, err := json.Marshal(query)
if err != nil {
panic(err)
}
req, err := http.NewRequest("POST", baseURL+"/ptls", bytes.NewBuffer(payloadBytes))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var ptls []PTLResponse
err = json.Unmarshal(body, &ptls)
if err != nil {
panic(err)
}
for _, ptl := range ptls {
if ptl.Unit == targetUnit {
fmt.Printf("PTL Unit %d:\n", targetUnit)
fmt.Printf(" Controller: %s\n", ptl.Controller)
fmt.Printf(" State: %s\n", ptl.State)
fmt.Printf(" Color: %s\n", ptl.Color)
fmt.Printf(" Number: %d\n", ptl.Number)
fmt.Printf(" Sub: %d\n", ptl.Sub)
return
}
}
fmt.Printf("PTL unit %d not found.\n", targetUnit)
}
Получение всех PTL, которые в данный момент активны
Под активным модулем имеется в виду модуль, у которого горит кнопка LED.
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type PTLQuery struct {
IP string `json:"ip"`
ClearAfter bool `json:"clear_after"`
Mode string `json:"mode,omitempty"`
}
type PTLResponse struct {
Unit int `json:"unit"`
Controller string `json:"controller"`
State string `json:"state,omitempty"`
Color string `json:"color,omitempty"`
Number int `json:"number,omitempty"`
Sub int `json:"sub,omitempty"`
}
func main() {
baseURL := "http://localhost:8000" // Заменить на адрес API
controllerIP := "192.168.0.100" // Заменить на IP контроллера
query := PTLQuery{
IP: controllerIP,
ClearAfter: false,
Mode: "activated",
}
payloadBytes, err := json.Marshal(query)
if err != nil {
panic(err)
}
req, err := http.NewRequest("POST", baseURL+"/ptls", bytes.NewBuffer(payloadBytes))
if err != nil {
panic(err)
}
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var ptls []PTLResponse
err = json.Unmarshal(body, &ptls)
if err != nil {
panic(err)
}
fmt.Println("Activated PTLs:")
for _, ptl := range ptls {
fmt.Printf(" Unit: %d | Controller: %s | State: %s | Color: %s | Number: %d | Sub: %d\n",
ptl.Unit, ptl.Controller, ptl.State, ptl.Color, ptl.Number, ptl.Sub)
}
}
Отправка зажигания и цикличная обработка активных модулей
package main
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"time"
)
type Command struct {
Unit int `json:"unit"`
Number int `json:"number"`
Sub int `json:"sub"`
Color string `json:"color"`
Role string `json:"role"`
}
type ControllerCommands struct {
ControllerIP string `json:"controller_ip"`
Commands []Command `json:"commands"`
}
type PTLQuery struct {
IP string `json:"ip"`
ClearAfter bool `json:"clear_after"`
Mode string `json:"mode"`
}
type PTLResponse struct {
Unit int `json:"unit"`
}
func main() {
apiURL := "http://localhost:8000"
controllerIP := "192.168.0.100"
var allUnits []int
for i := 1; i <= 100; i++ {
allUnits = append(allUnits, i)
}
batchSize := 10
for i := 0; i < len(allUnits); i += batchSize {
end := i + batchSize
if end > len(allUnits) {
end = len(allUnits)
}
batch := allUnits[i:end]
sendTurnOn(apiURL, controllerIP, batch)
waitForDeactivation(apiURL, controllerIP)
}
}
func sendTurnOn(apiURL, controllerIP string, units []int) {
var commands []Command
for _, unit := range units {
commands = append(commands, Command{
Unit: unit,
Number: unit,
Sub: 0,
Color: "Green",
Role: "worker",
})
}
payload := ControllerCommands{
ControllerIP: controllerIP,
Commands: commands,
}
body, err := json.Marshal(payload)
if err != nil {
panic(err)
}
resp, err := http.Post(apiURL+"/turn_on", "application/json", bytes.NewReader(body))
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Printf("Turned on units: %v\n", units)
}
func waitForDeactivation(apiURL, controllerIP string) {
for {
active := getActivatedPTLs(apiURL, controllerIP)
if len(active) == 0 {
fmt.Println("All PTLs deactivated, moving to next batch.")
return
}
fmt.Printf("Waiting, %d PTLs still active...\n", len(active))
time.Sleep(2 * time.Second)
}
}
func getActivatedPTLs(apiURL, controllerIP string) []PTLResponse {
query := PTLQuery{
IP: controllerIP,
ClearAfter: false,
Mode: "activated",
}
body, err := json.Marshal(query)
if err != nil {
panic(err)
}
resp, err := http.Post(apiURL+"/ptls", "application/json", bytes.NewReader(body))
if err != nil {
panic(err)
}
defer resp.Body.Close()
respBody, _ := ioutil.ReadAll(resp.Body)
var ptls []PTLResponse
err = json.Unmarshal(respBody, &ptls)
if err != nil {
panic(err)
}
return ptls
}