ZigBee на Raspberry, часть 1, прошивка CC2531

Задача: научится принимать пакеты по протоколу Zigbee на устройстве Raspberry PI 3. Сама по себе, без внешних дополнительных устройств, Raspberry этого не умеет. Нужен модем, который может принимать сигналы на этой частоте. Для этого было куплено на Aliexpress устройство Zigbee CC2531. Покупателю оно приходит пустое, без прошивки, поэтому перед работой с ним, его необходимо прошить. Есть несколько вариантов, самый простой сделать это при помощи самой же RaspberryPI. Одно Но! (и даже их несколько):

  • нужно делать самому подключение проводками
  • на модеме ножки очень тонкие, и стандартные проводки от Arduino например не подойдут. Кто-то городил огород при помощи малярного скотча, а кто-то отгибал ножки и припаивался к ним на прямую.

Общая схема подключения для прошивки следующая:

После того как наколхозите этот переходник, можно начинать прошивку. Но сначала убедимся, что модем вообще виден в системе, выполнив команду lsusb. Должно выйти что-то вроде:

Если всё ок, двигаемся к следующему шагу: скачиваем утилиту для прошивки:

git clone https://github.com/jmichault/flash_cc2531.git
cd flash_cc2531
./cc_chipid

И скорее всего получим фигу вида:

root@raspberrypi:/home/donpadlo/flash_cc2531# ./cc_chipid
bash: ./cc_chipid: cannot execute: required file not found

Я подозреваю, что этой утилите не хватает библиотеки wiringPi. Установить её можно так:

git clone https://github.com/WiringPi/WiringPi.git
cd WiringPi
 ./build

И далее снова попробовать выполнить :

./cc_chipid

И я снова получил туже самую ошибку. Ну чтож..попробуем собрать банарник из исходных годов сами:

cd flash_cc2531
make

После чего, команда уже выполнится корректно:

./cc_read
ID = b534

Т.е. устройство прошивальщик теперь видит. Скачаем последнюю версию прошивки (можно прям по этой ссылке, т.к. версии более не разрабатываются для этого модема):

wget https://github.com/Koenkk/Z-Stack-firmware/raw/refs/heads/master/coordinator/Z-Stack_3.0.x/bin/CC2531_20190425.zip
unzip CC2531_20190425.zip
./cc_erase 
./cc_write CC2531ZNP-with-SBL.hex

И собственно всё. Теперь стик рабочий. Осталось научится получать с него данные. А это уже в следующих частях..

1С: таблица значений на форме

Задача: скрыть отдельную колонку или показать все колонки в таблице значений расположенной на форме.

Решение: напишем две процедуры, одна из которых скрывает текущую выбранную мышкой колонку, а другая показывает все колонки в выбранной таблице.

&НаКлиенте
Процедура СкрытьКолонку(Команда)
      ТЭ_имя_объект=ТекущийЭлемент.Имя;
      ТЭ_поле=ТекущийЭлемент.ТекущийЭлемент.имя;
      имяКолонки=СтрЗаменить( ТЭ_поле,ТЭ_имя_объект,"");	  
	  элементы[ТЭ_поле].Видимость=Ложь;
КонецПроцедуры

&НаКлиенте
Процедура ПоказатьВсеКолонки(Команда)
      ТЭ_имя_объект=ТекущийЭлемент.Имя;
      ТЭ_поле=ТекущийЭлемент.ТекущийЭлемент.имя;
      имяКолонки=СтрЗаменить( ТЭ_поле,ТЭ_имя_объект,"");
	  для каждого стр из элементы[ТЭ_имя_объект].ПодчиненныеЭлементы цикл
		  стр.Видимость=Истина;
	  конеццикла;	  
КонецПроцедуры

Функционал можно например навесить на контекстное меню

1С: Сжимаем прикрепленные файлы

Задача: есть некий справочник, к которому прикрепляются файлы. Физически они конечно хранятся в томах, но всё равно занимают места очень порядочно. Необходимо собственно каждый файлик положить в архив, заново «перекрепить» его к элементам справочника. Оригинал соответственно удалить.

Решение:

	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ ПЕРВЫЕ 1000
		|	Файлы.ВладелецФайла КАК ВладелецФайла,
		|	Файлы.Ссылка КАК Ссылка,
		|	Файлы.ПолноеНаименование КАК ПолноеНаименование,
		|	Файлы.ТекущаяВерсияПутьКФайлу КАК ПутьКФайлу,
		|	Файлы.ТекущаяВерсияТом.ПолныйПутьWindows КАК ПолныйПуть,
		|	Файлы.ДатаСоздания КАК ДатаСоздания
		|ИЗ
		|	Справочник.Файлы КАК Файлы
		|ГДЕ
		|	Файлы.ВладелецФайла ССЫЛКА Справочник.СК_ГосуслугиЛК_ВходящиеСообщения
		|	И Файлы.ПометкаУдаления = ЛОЖЬ
		|	И НЕ Файлы.ТекущаяВерсияПутьКФайлу ПОДОБНО ""%zip%""
		|	И Файлы.ДатаСоздания МЕЖДУ &ДатаС И &ДатаПо
		|
		|УПОРЯДОЧИТЬ ПО
		|	ДатаСоздания";	
	Запрос.УстановитьПараметр("ДатаС", объект.ДатаС);	
	Запрос.УстановитьПараметр("ДатаПо", объект.ДатаПо);	
	РезультатЗапроса = Запрос.Выполнить();	
	ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();	
	Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
		если СтрНайти(ВыборкаДетальныеЗаписи.ПутьКФайлу,".zip")=0 тогда
			НовыйАрхив = Новый ЗаписьZipФайла(
			        ВыборкаДетальныеЗаписи.ПолныйПуть+"tmp.zip",
			        "","",МетодСжатияZIP.Сжатие,УровеньСжатияZIP.Максимальный,МетодШифрованияZIP.Zip20					
			);			
			НовыйАрхив.Добавить(ВыборкаДетальныеЗаписи.ПолныйПуть+ВыборкаДетальныеЗаписи.ПутьКФайлу);
			НовыйАрхив.Записать();            
			//возврат 0;
			ДвоичныеДанные = Новый ДвоичныеДанные(ВыборкаДетальныеЗаписи.ПолныйПуть+"tmp.zip"); 
			АдресФайлаВХранилище = ПоместитьВоВременноеХранилище(ДвоичныеДанные);
			РаботаСФайламиВызовСервера.СоздатьФайлСВерсией(
				ВыборкаДетальныеЗаписи.ВладелецФайла,
				ВыборкаДетальныеЗаписи.ПолноеНаименование+".zip",
				"zip",
				ТекущаяДата(),
				ТекущаяДата(),
				,
				АдресФайлаВХранилище,АдресФайлаВХранилище,
				Ложь,
				,
				,
				Истина
			);						
			об=ВыборкаДетальныеЗаписи.Ссылка.ПолучитьОбъект();
			об.ПометкаУдаления=Истина;
			об.Записать();
			об.Удалить();					
			УдалитьФайлы(ВыборкаДетальныеЗаписи.ПолныйПуть+ВыборкаДетальныеЗаписи.ПутьКФайлу);						
		конецесли;		
	КонецЦикла;

Т.е. что тут делаем: выбираем элемент справочника с прикрепленным файлом, сжимаем его в архив zip, прикрепляем его и удаляем оригинал.

1С: Сортировка таблицы значений на управляемой форме

По умолчанию, не понятно почему на платформе не завезено средство сортировки таблицы значений отображаемой на форме. Поэтому выходом может быть например такое решение:

  • добавляем команды СортироватьПоКолонкеВозр и СортироватьПоКолонкеУбыв
  • добавляем их в контекстное меню
  • Код команды может быть такой:
&НаКлиенте
Процедура СортироватьПоКолонке(Команда)
      ТЭ_имя_объект=ТекущийЭлемент.Имя;
      ТЭ_поле=ТекущийЭлемент.ТекущийЭлемент.имя;
      имяКолонки=СтрЗаменить( ТЭ_поле,ТЭ_имя_объект,"");
      если команда.имя="СортироватьПоКолонкеУбыв" тогда
           СортироватьНасервере(ТЭ_имя_объект,имяКолонки,"Убыв");
	  конецесли;		   
      если команда.имя="СортироватьПоКолонкеВозр" тогда
          СортироватьНасервере(ТЭ_имя_объект,имяКолонки,"Возр");
	конецесли;
КонецПроцедуры

&НаСервере
Процедура сортироватьНасервере(имяОбъекта,имяКолонки,ВидСортировки)
    тз= РеквизитФормыВЗначение("БуферТЗ");
    тз.Сортировать(имяКолонки+" "+ВидСортировки);
    ЗначениеВРеквизитФормы(ТЗ,"БуферТЗ");
конецпроцедуры

В результате получаем что-то подобное:

Получение ExecutorGUID и orgPPAGUID

При работе с ГИС ЖКХ это первоочередные идентификаторы, которые в самой панели ГИС ЖКХ спрятаны так, что не каждый с первого раза и найдёт. Поэтому есть способ чуть попроще.

  1. Авторизуемся на ГИС ЖКХ https://portal.dom.gosuslugi.ru/
  2. В браузере нажимаем F12 и переходим на вкладку «Сеть»
  3. В правом верхнем углу нажимаем на название своей организации -> посмотреть информацию об организации, и смотрим содержимое запроса из вкладки «Сеть»

guid в «полезной нагрузке» это и есть orgPPAGUID

Для получения ExecutorGUID, точно так-же нажимаем на название своей организации -> Посмотреть информацию о представителе организации. Ничего не меняя нажимаем «Сохранить». В сетевом запросе updateinfo, видим требуемый guid:

1 2 3 4 300