Пример работы с package uniset
Есть два насоса, один наполняет бак, другой опустошает. Как только бак наполнился, наполнявший насос должен отключиться, а второй (опустошающий) должен включиться. Как только бак пустой опять включается наполнящий насос (а-ля "пинг-понг") Задача написать логику реализующую это взаимодействие, через uniset-датчики.
Рассчитан на тех, кто знаком с uniset
- libUniSet2
- libUniSet2Extensions
- libUniSet2GO
- uniset2-codegen-go
make
- Создать репозиторий
cd Services/Administrator; ./create
- Запустить SM
cd Services/SM; ./start_fg.sh
- Запускаем
start_fg.sh
Реализация использует "стандартный" для uniset-систем подход. Для каждого объекта создаётся специальный xml-файл с описанием входов, выходов и параметров. По этому файлу при помощи утилиты uniset2-codegen-go генерируется sk-файл (skeleton) содержащий всё необходимое для реализации логики (списки входов и выходов, in/out переменные содержащие текущее значение датчиков, функцию инициализации привязок к датчиком из конфигурационного файла). А дальше уже реализуются функции обработки событий по изменению датчиков и таймеров. В общем случае объекты реализуют логику в отдельной go-рутине, которая в цикле делает
- обновление состояния входов
- выполнение шага алгоритма
- обработка таймеров (если есть)
- обновление состояния выходов
Каждый объект который хочет получать уведомления об изменении датчиков, должен реализовать интерфейс UObject.
В данном примере реализованы два "класса" Pump и Imitator. Пример xml-файла описывающего imitator
<?xml version="1.0" encoding="utf-8"?>
<!--
name - название класса
type
====
in - входные регистры (только для чтения)
out - выходные регистры (запись)
-->
<Imitator>
<settings>
<set name="class-name" val="Imitator"/>
</settings>
<variables>
<item name="step" type="long" default="5"/>
<item name="min" type="long" default="0"/>
<item name="max" type="long" default="100"/>
</variables>
<smap>
<item name="level_s" iotype="AI" vartype="out" comment="уровень в цистерне"/>
<item name="cmdLoad_c" iotype="DO" vartype="in" omment="наполнять"/>
<item name="cmdUnLoad_c" iotype="DO" vartype="in" omment="опустошать"/>
</smap>
<msgmap>
</msgmap>
</Imitator>
На основе него генерируется файл imitator_sk.go
// DO NOT EDIT THIS FILE. IT IS AUTOGENERATED FILE.
// ALL YOUR CHANGES WILL BE LOST.
//
// НЕ РЕДАКТИРУЙТЕ ЭТОТ ФАЙЛ. ЭТОТ ФАЙЛ СОЗДАН АВТОМАТИЧЕСКИ.
// ВСЕ ВАШИ ИЗМЕНЕНИЯ БУДУТ ПОТЕРЯНЫ
package main
import (
"fmt"
"time"
"uniset"
)
// ----------------------------------------------------------------------------------
type Imitator_SK struct {
// ID
level_s uniset.ObjectID
cmdLoad_c uniset.ObjectID
cmdUnLoad_c uniset.ObjectID
// i/o
out_level_s int64
in_cmdLoad_c int64
in_cmdUnLoad_c int64
// variables
step int64 /*!< */
min int64 /*!< */
max int64 /*!< */
ins []*uniset.Int64Value // список входов
outs []*uniset.Int64Value // список выходов
myname string
id uniset.ObjectID
sleep_msec time.Duration
}
// ----------------------------------------------------------------------------------
func Init_Imitator(sk *Imitator, name string, section string) {
sk.myname = name
cfg, err := uniset.GetConfigParamsByName(name, section)
if err != nil {
panic(fmt.Sprintf("(Init_Imitator): error: %s", err))
}
sk.id = uniset.InitObjectID(cfg, "", name)
sk.sleep_msec = time.Duration(200 * time.Millisecond)
sk.step = uniset.InitInt64(cfg, "step", "5")
sk.min = uniset.InitInt64(cfg, "min", "0")
sk.max = uniset.InitInt64(cfg, "max", "100")
sk.level_s = uniset.InitSensorID(cfg, "level_s", "")
sk.cmdLoad_c = uniset.InitSensorID(cfg, "cmdLoad_c", "")
sk.cmdUnLoad_c = uniset.InitSensorID(cfg, "cmdUnLoad_c", "")
if sk.level_s == uniset.DefaultObjectID {
panic(fmt.Sprintf("%s(Init_Imitator): Unknown ID for level_s\n", sk.myname))
}
if sk.cmdLoad_c == uniset.DefaultObjectID {
panic(fmt.Sprintf("%s(Init_Imitator): Unknown ID for cmdLoad_c\n", sk.myname))
}
if sk.cmdUnLoad_c == uniset.DefaultObjectID {
panic(fmt.Sprintf("%s(Init_Imitator): Unknown ID for cmdUnLoad_c\n", sk.myname))
}
sk.ins = []*uniset.Int64Value{
uniset.NewInt64Value(&sk.cmdLoad_c, &sk.in_cmdLoad_c),
uniset.NewInt64Value(&sk.cmdUnLoad_c, &sk.in_cmdUnLoad_c),
}
sk.outs = []*uniset.Int64Value{
uniset.NewInt64Value(&sk.level_s, &sk.out_level_s),
}
}
// ----------------------------------------------------------------------------------