Здравствуйте.
Возможно ли в языке Wiring получить доступ к функции(т.е. вызвать функцию) из ассоциативного массива? Хотелось бы уйти от "if"-ов.
История появления вопроса :
хочу на базе esp создать устройство, которое может читать некоторые датчики и по некоторому набору правил рулить исполнительными устройствами. Правила в качества входной информации используют не только состояние датчиков, но и некоторые внутренние настройки, которые могу быть установлены из вне( по MQTT).
Структура данных и алгоритм работы мне видятся такими (далее - много текста ) :
В целом, система выглядит нормально для стационарного компа, а вот для esp у меня подозрение - поместится ли это все в нее. Реализацию мапы нашел. Сета - еще не искал, но наверное тоже есть.
С мапой можно реализовать contain(Object key), если условиться, что все реальные данные складывать начиная с индекса 1, тогда для несуществующего ключа функция indexOf(key) выдаст 0.
Если описанный "космический кораблик" на Wiring и esp не реализуем в принципе, я надеюсь, что вы мне подскажете альтернативные варианты решения проблемы)
Возможно ли в языке Wiring получить доступ к функции(т.е. вызвать функцию) из ассоциативного массива? Хотелось бы уйти от "if"-ов.
История появления вопроса :
хочу на базе esp создать устройство, которое может читать некоторые датчики и по некоторому набору правил рулить исполнительными устройствами. Правила в качества входной информации используют не только состояние датчиков, но и некоторые внутренние настройки, которые могу быть установлены из вне( по MQTT).
Структура данных и алгоритм работы мне видятся такими (далее - много текста ) :
Есть основной цикл. В нем опрашиваем RTC, смотрим сколько времени прошло с момента запуска "основой части программы". Если интервал времени не достиг еще некоторого заданного значения - уходим в начало цикла, иначе проваливаемся в ветку с основной частью.
а) Там мы запускаем процедуру, которая опрашивает датчики. Для этого есть некий список, который сопоставляет некоторую структуру данных в памяти с условным типом устройства и возможно какими-то его дополнительными характеристиками. Еще есть массив, сопоставляющий типы устройства (типа данных - String) с функцией, которая будет это устройство специфичным для него образом опрашивать. Это первое место, где понадобилось сопоставить какой-то тип данных и функцию. Результатом выполнения функции будет заполненная структура данных вида HashMap(String internalSensorName, *someDataStructure readedValue)
б) далее запускается функция, которая составляет карту значений - по какому датчику были изменения значений. Видимо для этого нужно иметь предыдущие считанные значения. На выходе ожидается что-то вроде HashSet(String internalSensorName)
в) далее дергается функция, которая читает данные, полученные на предыдущем шаге и по ассоциативному массиву вида HashMap(String internalSensorName, linkToFunction functionName) вызывает рулы, которые на базе некоторых настроек и некоторых значений датчиков обновляют внутренние переменные, которые сопоставлены с выводами контроллера, т.е. на выходе будет заполнена структура вида HashMap(String internalPinName, byte state)
г) потом дергается функция, которая пробегается по мапе из предыдущего шага и по мапе, вида HashMap(String internalPinName, byte pinNumber) и обновляет состояние выводов.
В callback функции клиента MQTT:
топики сопоставлены с переменными настроек рулов.
значение в топике - это новое значение переменной настроек.
а) смотрим все интересующие нас топики (мапа HashMap(String topicName, String internalSettingVariableName)), обновляем значения настроечных переменных.
б) определяем какие из них были изменены (на выходе - HashSet(String internalSettingVariableName))
в) смотрим мапу, в которой указаны от каких переменных какие рулы зависят:
HashMap(String internalSettingVariableName, HashSet( linkToFunction functionName)), на выходе выдаем
сет из функций рулов, которые нужно дернуть: HashSet( linkToFunction functionName)
г) пробегаемся по полученному сету, в результате обновляется HashMap(String internalPinName, byte state)
д) потом дергается функция, которая пробегается по мапе из предыдущего шага и по мапе, вида HashMap(String internalPinName, byte pinNumber) и обновляет состояние выводов.
т.е. в колбэк функции по-идее дернутся только необходимые рулы, а не все подряд. считывание состояния датчиков происходит только в основном цикле. если в топике будет запрос на получение состояние датчика, то отсылается последнее считанное. как вариант, можно еще отправлять время последнего считывания.
а) Там мы запускаем процедуру, которая опрашивает датчики. Для этого есть некий список, который сопоставляет некоторую структуру данных в памяти с условным типом устройства и возможно какими-то его дополнительными характеристиками. Еще есть массив, сопоставляющий типы устройства (типа данных - String) с функцией, которая будет это устройство специфичным для него образом опрашивать. Это первое место, где понадобилось сопоставить какой-то тип данных и функцию. Результатом выполнения функции будет заполненная структура данных вида HashMap(String internalSensorName, *someDataStructure readedValue)
б) далее запускается функция, которая составляет карту значений - по какому датчику были изменения значений. Видимо для этого нужно иметь предыдущие считанные значения. На выходе ожидается что-то вроде HashSet(String internalSensorName)
в) далее дергается функция, которая читает данные, полученные на предыдущем шаге и по ассоциативному массиву вида HashMap(String internalSensorName, linkToFunction functionName) вызывает рулы, которые на базе некоторых настроек и некоторых значений датчиков обновляют внутренние переменные, которые сопоставлены с выводами контроллера, т.е. на выходе будет заполнена структура вида HashMap(String internalPinName, byte state)
г) потом дергается функция, которая пробегается по мапе из предыдущего шага и по мапе, вида HashMap(String internalPinName, byte pinNumber) и обновляет состояние выводов.
В callback функции клиента MQTT:
топики сопоставлены с переменными настроек рулов.
значение в топике - это новое значение переменной настроек.
а) смотрим все интересующие нас топики (мапа HashMap(String topicName, String internalSettingVariableName)), обновляем значения настроечных переменных.
б) определяем какие из них были изменены (на выходе - HashSet(String internalSettingVariableName))
в) смотрим мапу, в которой указаны от каких переменных какие рулы зависят:
HashMap(String internalSettingVariableName, HashSet( linkToFunction functionName)), на выходе выдаем
сет из функций рулов, которые нужно дернуть: HashSet( linkToFunction functionName)
г) пробегаемся по полученному сету, в результате обновляется HashMap(String internalPinName, byte state)
д) потом дергается функция, которая пробегается по мапе из предыдущего шага и по мапе, вида HashMap(String internalPinName, byte pinNumber) и обновляет состояние выводов.
т.е. в колбэк функции по-идее дернутся только необходимые рулы, а не все подряд. считывание состояния датчиков происходит только в основном цикле. если в топике будет запрос на получение состояние датчика, то отсылается последнее считанное. как вариант, можно еще отправлять время последнего считывания.
В целом, система выглядит нормально для стационарного компа, а вот для esp у меня подозрение - поместится ли это все в нее. Реализацию мапы нашел. Сета - еще не искал, но наверное тоже есть.
С мапой можно реализовать contain(Object key), если условиться, что все реальные данные складывать начиная с индекса 1, тогда для несуществующего ключа функция indexOf(key) выдаст 0.
Если описанный "космический кораблик" на Wiring и esp не реализуем в принципе, я надеюсь, что вы мне подскажете альтернативные варианты решения проблемы)
Последнее редактирование: